From e800ba5996bb90654645afac37f92e6c4737160e Mon Sep 17 00:00:00 2001 From: fhackett Date: Wed, 21 Apr 2021 12:12:41 -0700 Subject: [PATCH 01/27] initial rewrite, WIP --- .gitignore | 1 + dev-lib/hamcrest-all-1.3.jar | Bin 306578 -> 0 bytes dev-lib/junit-4.12.jar | Bin 314932 -> 0 bytes lib/json.jar | Bin 61749 -> 0 bytes lib/plume.jar | Bin 4494513 -> 0 bytes pgo-code-style.epf | 336 ---- pgo.sh | 6 - src/pgo/InternalCompilerError.java | 11 - src/pgo/PGo.scala | 145 ++ src/pgo/PGoConstantDef.scala | 5 - src/pgo/PGoConstantDefs.java | 31 - src/pgo/PGoException.java | 38 - src/pgo/PGoMain.java | 375 ---- src/pgo/PGoNetOptions.java | 133 -- src/pgo/PGoOptionException.java | 9 - src/pgo/PGoOptions.java | 107 -- src/pgo/TODO.java | 7 - src/pgo/Unreachable.java | 11 - src/pgo/errors/Context.java | 7 - src/pgo/errors/ContextVisitor.java | 11 - src/pgo/errors/Issue.java | 37 - src/pgo/errors/IssueContext.java | 12 - src/pgo/errors/IssueVisitor.java | 45 - src/pgo/errors/IssueWithContext.java | 24 - src/pgo/errors/NestedIssueContext.java | 23 - src/pgo/errors/TopLevelIssueContext.java | 57 - .../formatters/ContextFormattingVisitor.java | 35 - .../formatters/DerivedFormattingVisitor.java | 81 - src/pgo/formatters/FormattingTools.java | 25 - .../formatters/GoBinopFormattingVisitor.java | 248 --- .../GoDeclarationFormattingVisitor.java | 64 - .../GoExpressionFormattingVisitor.java | 206 --- .../formatters/GoNodeFormattingVisitor.java | 117 -- .../GoStatementFormattingVisitor.java | 238 --- .../formatters/GoTypeFormattingVisitor.java | 99 - src/pgo/formatters/IndentingWriter.java | 122 -- .../formatters/IssueFormattingVisitor.java | 303 ---- .../formatters/OriginFormattingVisitor.java | 34 - .../PlusCalNodeFormattingVisitor.java | 226 --- .../PlusCalStatementFormattingVisitor.java | 208 --- .../TLAExpressionFormattingVisitor.java | 383 ---- .../formatters/TLANodeFormattingVisitor.java | 170 -- .../formatters/TLAUnitFormattingVisitor.java | 144 -- src/pgo/formatters/TypeFormattingVisitor.java | 155 -- src/pgo/model/Definitions.scala | 42 + src/pgo/model/PGoError.scala | 21 + src/pgo/model/RefersTo.scala | 100 ++ src/pgo/model/Rewritable.scala | 111 ++ src/pgo/model/SourceLocatable.scala | 12 + src/pgo/model/SourceLocation.scala | 152 ++ src/pgo/model/Visitable.scala | 63 + src/pgo/model/golang/GoAnonymousFunction.java | 53 - .../model/golang/GoAssignmentStatement.java | 57 - src/pgo/model/golang/GoBinop.java | 75 - src/pgo/model/golang/GoBlock.java | 36 - src/pgo/model/golang/GoBreak.java | 20 - src/pgo/model/golang/GoBuiltins.java | 82 - src/pgo/model/golang/GoCall.java | 53 - src/pgo/model/golang/GoComment.java | 38 - src/pgo/model/golang/GoContinue.java | 19 - src/pgo/model/golang/GoDeclaration.java | 12 - .../model/golang/GoDeclarationVisitor.java | 9 - src/pgo/model/golang/GoDefer.java | 34 - src/pgo/model/golang/GoExpression.java | 16 - .../model/golang/GoExpressionStatement.java | 35 - src/pgo/model/golang/GoExpressionVisitor.java | 21 - src/pgo/model/golang/GoFor.java | 61 - src/pgo/model/golang/GoForRange.java | 60 - .../model/golang/GoFunctionDeclaration.java | 67 - src/pgo/model/golang/GoFunctionParameter.java | 43 - src/pgo/model/golang/GoIf.java | 67 - src/pgo/model/golang/GoIfBuilder.java | 74 - src/pgo/model/golang/GoIncDec.java | 42 - src/pgo/model/golang/GoIndexExpression.java | 42 - src/pgo/model/golang/GoIntLiteral.java | 35 - src/pgo/model/golang/GoLabel.java | 39 - src/pgo/model/golang/GoLabelName.java | 35 - src/pgo/model/golang/GoMakeExpression.java | 55 - src/pgo/model/golang/GoMapLiteral.java | 52 - src/pgo/model/golang/GoModule.java | 56 - src/pgo/model/golang/GoNode.java | 31 - src/pgo/model/golang/GoNodeVisitor.java | 21 - src/pgo/model/golang/GoPtrType.java | 44 - src/pgo/model/golang/GoReturn.java | 41 - src/pgo/model/golang/GoRoutineStatement.java | 34 - src/pgo/model/golang/GoSelect.java | 39 - src/pgo/model/golang/GoSelectCase.java | 44 - .../model/golang/GoSelectorExpression.java | 42 - src/pgo/model/golang/GoSliceLiteral.java | 44 - src/pgo/model/golang/GoSliceOperator.java | 56 - src/pgo/model/golang/GoStatement.java | 16 - src/pgo/model/golang/GoStatementVisitor.java | 24 - src/pgo/model/golang/GoStringLiteral.java | 35 - src/pgo/model/golang/GoStructLiteral.java | 50 - .../model/golang/GoStructLiteralField.java | 42 - src/pgo/model/golang/GoSwitch.java | 64 - src/pgo/model/golang/GoSwitchCase.java | 62 - src/pgo/model/golang/GoTo.java | 39 - src/pgo/model/golang/GoTypeAssertion.java | 50 - src/pgo/model/golang/GoTypeCast.java | 46 - src/pgo/model/golang/GoTypeDeclaration.java | 45 - src/pgo/model/golang/GoUnary.java | 52 - .../model/golang/GoVariableDeclaration.java | 51 - .../GoVariableDeclarationStatement.java | 37 - src/pgo/model/golang/GoVariableName.java | 35 - .../model/golang/builder/GoASTBuilder.java | 28 - .../builder/GoAnonymousFunctionBuilder.java | 50 - .../model/golang/builder/GoBlockBuilder.java | 223 --- src/pgo/model/golang/builder/GoBuilder.java | 51 - .../golang/builder/GoForRangeBuilder.java | 46 - .../builder/GoForStatementClauseBuilder.java | 54 - .../builder/GoFunctionDeclarationBuilder.java | 64 - .../model/golang/builder/GoModuleBuilder.java | 108 -- .../model/golang/builder/GoSwitchBuilder.java | 51 - .../GoArchetypeResourceCollectionType.java | 49 - .../golang/type/GoArchetypeResourceType.java | 43 - src/pgo/model/golang/type/GoChanType.java | 41 - .../model/golang/type/GoInterfaceType.java | 44 - .../golang/type/GoInterfaceTypeField.java | 54 - src/pgo/model/golang/type/GoMapType.java | 61 - src/pgo/model/golang/type/GoSliceType.java | 42 - src/pgo/model/golang/type/GoStructType.java | 44 - .../model/golang/type/GoStructTypeField.java | 44 - src/pgo/model/golang/type/GoType.java | 21 - src/pgo/model/golang/type/GoTypeName.java | 54 - src/pgo/model/golang/type/GoTypeVisitor.java | 15 - src/pgo/model/mpcal/AST.scala | 133 ++ .../model/mpcal/ModularPlusCalArchetype.java | 99 - src/pgo/model/mpcal/ModularPlusCalBlock.scala | 81 - .../mpcal/ModularPlusCalBlockVisitor.java | 16 - .../model/mpcal/ModularPlusCalBuilder.java | 74 - .../model/mpcal/ModularPlusCalInstance.java | 96 - .../model/mpcal/ModularPlusCalMapping.java | 57 - .../mpcal/ModularPlusCalMappingMacro.java | 107 -- .../mpcal/ModularPlusCalMappingTarget.java | 31 - .../mpcal/ModularPlusCalMappingVariable.java | 50 - .../ModularPlusCalMappingVariableName.java | 46 - ...ModularPlusCalMappingVariablePosition.java | 45 - src/pgo/model/mpcal/ModularPlusCalNode.java | 52 - .../ModularPlusCalNodeFormattingVisitor.java | 188 -- .../mpcal/ModularPlusCalNodeVisitor.java | 8 - src/pgo/model/mpcal/ModularPlusCalParam.scala | 61 - src/pgo/model/mpcal/ModularPlusCalUnit.java | 9 - src/pgo/model/mpcal/ModularPlusCalUtils.scala | 67 - src/pgo/model/mpcal/ModularPlusCalYield.java | 55 - src/pgo/model/pcal/AST.scala | 175 ++ src/pgo/model/pcal/PlusCalAlgorithm.java | 98 - src/pgo/model/pcal/PlusCalAssert.java | 51 - src/pgo/model/pcal/PlusCalAssignment.java | 53 - src/pgo/model/pcal/PlusCalAssignmentPair.java | 63 - src/pgo/model/pcal/PlusCalAwait.java | 51 - src/pgo/model/pcal/PlusCalBuilder.java | 133 -- src/pgo/model/pcal/PlusCalCall.java | 65 - src/pgo/model/pcal/PlusCalEither.java | 60 - src/pgo/model/pcal/PlusCalFairness.java | 7 - src/pgo/model/pcal/PlusCalGoto.java | 50 - src/pgo/model/pcal/PlusCalIf.java | 80 - src/pgo/model/pcal/PlusCalLabel.java | 63 - .../model/pcal/PlusCalLabeledStatements.java | 65 - src/pgo/model/pcal/PlusCalMacro.java | 93 - src/pgo/model/pcal/PlusCalMacroCall.java | 65 - src/pgo/model/pcal/PlusCalMultiProcess.java | 58 - src/pgo/model/pcal/PlusCalNode.java | 55 - src/pgo/model/pcal/PlusCalNodeVisitor.java | 15 - src/pgo/model/pcal/PlusCalPrint.java | 50 - src/pgo/model/pcal/PlusCalProcedure.java | 97 - src/pgo/model/pcal/PlusCalProcess.java | 67 - src/pgo/model/pcal/PlusCalProcesses.java | 21 - .../model/pcal/PlusCalProcessesVisitor.java | 6 - src/pgo/model/pcal/PlusCalReturn.java | 29 - src/pgo/model/pcal/PlusCalSingleProcess.java | 51 - src/pgo/model/pcal/PlusCalSkip.java | 31 - src/pgo/model/pcal/PlusCalStatement.java | 19 - .../model/pcal/PlusCalStatementVisitor.java | 21 - src/pgo/model/pcal/PlusCalUtils.scala | 66 - .../pcal/PlusCalVariableDeclaration.java | 96 - src/pgo/model/pcal/PlusCalWhile.java | 65 - src/pgo/model/pcal/PlusCalWith.java | 54 - src/pgo/model/tla/AST.scala | 465 +++++ src/pgo/model/tla/BuiltinModules.scala | 190 ++ .../model/tla/PlusCalDefaultInitValue.java | 31 - src/pgo/model/tla/TLAAssumption.java | 57 - src/pgo/model/tla/TLABinOp.java | 105 -- src/pgo/model/tla/TLABool.java | 48 - src/pgo/model/tla/TLABuilder.java | 245 --- src/pgo/model/tla/TLABuiltinModules.scala | 194 -- src/pgo/model/tla/TLACase.java | 78 - src/pgo/model/tla/TLACaseArm.java | 62 - .../model/tla/TLAConstantDeclaration.scala | 29 - src/pgo/model/tla/TLADot.java | 52 - src/pgo/model/tla/TLAExistential.java | 73 - src/pgo/model/tla/TLAExpression.java | 25 - src/pgo/model/tla/TLAExpressionVisitor.java | 36 - src/pgo/model/tla/TLAFairness.java | 61 - src/pgo/model/tla/TLAFunction.java | 72 - src/pgo/model/tla/TLAFunctionCall.java | 73 - src/pgo/model/tla/TLAFunctionDefinition.java | 96 - src/pgo/model/tla/TLAFunctionSet.java | 72 - .../model/tla/TLAFunctionSubstitution.java | 72 - .../tla/TLAFunctionSubstitutionPair.java | 65 - src/pgo/model/tla/TLAGeneralIdentifier.scala | 50 - .../model/tla/TLAGeneralIdentifierPart.java | 68 - src/pgo/model/tla/TLAIdentifier.java | 78 - src/pgo/model/tla/TLAIdentifierOrTuple.java | 93 - src/pgo/model/tla/TLAIf.java | 81 - src/pgo/model/tla/TLAInstance.scala | 74 - src/pgo/model/tla/TLALet.java | 77 - src/pgo/model/tla/TLAMaybeAction.java | 69 - src/pgo/model/tla/TLAModule.scala | 46 - src/pgo/model/tla/TLAModuleDefinition.scala | 55 - src/pgo/model/tla/TLAModuleExtends.scala | 16 - src/pgo/model/tla/TLANode.java | 60 - src/pgo/model/tla/TLANodeVisitor.java | 18 - src/pgo/model/tla/TLANumber.java | 64 - src/pgo/model/tla/TLAOpDecl.java | 137 -- src/pgo/model/tla/TLAOperatorCall.java | 86 - src/pgo/model/tla/TLAOperatorDefinition.scala | 44 - .../model/tla/TLAQuantifiedExistential.java | 72 - src/pgo/model/tla/TLAQuantifiedUniversal.java | 72 - src/pgo/model/tla/TLAQuantifierBound.scala | 49 - src/pgo/model/tla/TLARecordConstructor.java | 110 -- src/pgo/model/tla/TLARecordSet.java | 113 -- src/pgo/model/tla/TLARef.java | 54 - src/pgo/model/tla/TLARequiredAction.java | 69 - src/pgo/model/tla/TLASetComprehension.java | 72 - src/pgo/model/tla/TLASetConstructor.java | 60 - src/pgo/model/tla/TLASetRefinement.java | 66 - .../model/tla/TLASpecialVariableValue.java | 29 - .../model/tla/TLASpecialVariableVariable.java | 29 - src/pgo/model/tla/TLAString.java | 54 - src/pgo/model/tla/TLASubstitutionKey.java | 60 - src/pgo/model/tla/TLASymbol.java | 57 - src/pgo/model/tla/TLATheorem.java | 57 - src/pgo/model/tla/TLATuple.java | 60 - src/pgo/model/tla/TLAUnary.java | 90 - src/pgo/model/tla/TLAUnit.scala | 25 - src/pgo/model/tla/TLAUnitVisitor.java | 13 - .../model/tla/TLAUnitVisitorThrowsHack.java | 9 - src/pgo/model/tla/TLAUniversal.java | 73 - src/pgo/model/tla/TLAUtils.scala | 239 --- .../model/tla/TLAVariableDeclaration.scala | 29 - src/pgo/model/type/AbstractRecordType.java | 34 - .../type/ArchetypeResourceCollectionType.java | 71 - src/pgo/model/type/ArchetypeResourceType.java | 59 - .../model/type/BacktrackingFailureIssue.java | 22 - src/pgo/model/type/BoolType.java | 29 - src/pgo/model/type/ChanType.java | 32 - src/pgo/model/type/FunctionType.java | 55 - src/pgo/model/type/InfiniteTypeIssue.java | 27 - src/pgo/model/type/IntType.java | 29 - src/pgo/model/type/InterfaceType.java | 29 - src/pgo/model/type/MapType.java | 55 - src/pgo/model/type/NoMatchingFieldIssue.java | 28 - src/pgo/model/type/NonEnumerableSetType.java | 32 - src/pgo/model/type/ProcedureType.java | 44 - src/pgo/model/type/RealType.java | 29 - src/pgo/model/type/RecordType.java | 83 - src/pgo/model/type/RecordTypeEntry.java | 149 -- src/pgo/model/type/SetType.java | 32 - src/pgo/model/type/SimpleContainerType.java | 38 - src/pgo/model/type/SliceType.java | 32 - src/pgo/model/type/StringType.java | 29 - src/pgo/model/type/TupleType.java | 44 - src/pgo/model/type/Type.java | 44 - src/pgo/model/type/TypeCopyVisitor.java | 118 -- src/pgo/model/type/TypeGenerator.java | 28 - .../model/type/TypeHasVariableVisitor.java | 102 -- src/pgo/model/type/TypeSolver.java | 451 ----- src/pgo/model/type/TypeSubstitution.java | 27 - src/pgo/model/type/TypeVariable.java | 41 - ...ableAbstractRecordSubstitutionVisitor.java | 25 - .../type/TypeVariableCollectionVisitor.java | 132 -- .../type/TypeVariableSubstitutionVisitor.java | 130 -- src/pgo/model/type/TypeVisitor.java | 22 - src/pgo/model/type/UnificationException.java | 15 - .../type/UnsatisfiableConstraintIssue.java | 27 - .../type/constraint/BasicConstraint.java | 8 - src/pgo/model/type/constraint/Constraint.java | 11 - .../type/constraint/EqualityConstraint.java | 36 - .../type/constraint/HasFieldConstraint.java | 47 - .../constraint/MonomorphicConstraint.java | 52 - .../constraint/PolymorphicConstraint.java | 85 - ....scala => LineColumnAwareCharReader.scala} | 14 +- src/pgo/parser/MPCalParser.scala | 282 +++ src/pgo/parser/MPCalParserContext.scala | 24 + src/pgo/parser/ModularPlusCalParser.scala | 196 -- src/pgo/parser/PCalParser.scala | 435 +++++ src/pgo/parser/PCalParserContext.scala | 23 + src/pgo/parser/ParsingErrors.scala | 64 +- src/pgo/parser/ParsingUtils.scala | 8 +- src/pgo/parser/PlusCalParser.scala | 420 ----- src/pgo/parser/TLAParser.scala | 839 ++++----- src/pgo/parser/TLAParserContext.scala | 62 + src/pgo/scope/ChainMap.java | 104 -- src/pgo/scope/ChainSet.java | 70 - src/pgo/scope/Context.java | 76 - src/pgo/scope/UID.java | 29 - src/pgo/trans/MPCalGoCodegenPass.scala | 10 + src/pgo/trans/MPCalNormalizePass.scala | 77 + src/pgo/trans/MPCalPCalCodegenPass.scala | 11 + src/pgo/trans/MPCalSemanticCheckPass.scala | 373 ++++ src/pgo/trans/PCalRenderPass.scala | 8 + src/pgo/trans/PGoTransException.java | 22 - src/pgo/trans/PGoUnsupportedException.java | 13 - src/pgo/trans/PlusCalCodeGenPassS.txt | 760 ++++++++ src/pgo/trans/intermediate/BuiltinModule.java | 35 - .../trans/intermediate/BuiltinOperator.java | 61 - .../trans/intermediate/CheckOptionsPass.java | 38 - .../CompiledOperatorAccessor.java | 112 -- .../intermediate/DefinitionRegistry.java | 267 --- src/pgo/trans/intermediate/IOErrorIssue.java | 26 - .../trans/intermediate/OperatorAccessor.java | 37 - src/pgo/trans/intermediate/QualifiedName.java | 70 - src/pgo/trans/intermediate/TLABuiltins.java | 809 --------- .../intermediate/TypelessBuiltinOperator.java | 42 - .../intermediate/UnsupportedFeatureIssue.java | 24 - .../trans/intermediate/WhileLoadingUnit.java | 24 - .../atomicity/AtomicityInferencePass.java | 98 - .../ModularPlusCalAtomicityInferencePass.java | 140 -- ...CalStatementAtomicityInferenceVisitor.java | 131 -- ...xpressionLHSAtomicityInferenceVisitor.java | 184 -- ...ressionValueAtomicityInferenceVisitor.java | 215 --- .../TLAUnitAtomicityInferenceVisitor.java | 59 - src/pgo/trans/passes/codegen/NameCleaner.java | 46 - src/pgo/trans/passes/codegen/Recycling.java | 78 - ...hetypeResourcesGlobalVariableStrategy.java | 471 ----- .../trans/passes/codegen/go/CodeGenUtil.java | 45 - .../trans/passes/codegen/go/CopyVisitor.java | 122 -- .../passes/codegen/go/CriticalSection.java | 11 - .../codegen/go/CriticalSectionTracker.java | 118 -- .../go/DefaultLocalVariableStrategy.java | 37 - .../passes/codegen/go/EqCodeGenVisitor.java | 96 - .../go/EtcdGlobalVariableStrategy.java | 208 --- .../codegen/go/GlobalVariableStrategy.java | 79 - .../go/GoCommandLineArgumentParser.java | 62 - .../go/GoExpressionIsConstantVisitor.java | 96 - .../GoExpressionStaticComparisonVisitor.java | 143 -- .../codegen/go/LessThanCodeGenVisitor.java | 192 -- .../codegen/go/LocalVariableStrategy.java | 13 - .../go/ModularPlusCalGoCodeGenPass.java | 284 --- ...threadedProcessGlobalVariableStrategy.java | 149 -- .../codegen/go/PlusCalGoCodeGenPass.java | 49 - .../go/PlusCalProcessesCodeGenVisitor.java | 176 -- .../go/PlusCalStatementCodeGenVisitor.java | 402 ----- .../PlusCalStatementContainsAwaitVisitor.java | 97 - .../PlusCalStatementContainsLabelVisitor.java | 111 -- ...ThreadedProcessGlobalVariableStrategy.java | 66 - .../go/SnapshottingLocalVariableStrategy.java | 78 - .../go/StateServerGlobalVariableStrategy.java | 284 --- ...ExpressionAssignmentLHSCodeGenVisitor.java | 231 --- .../go/TLAExpressionCodeGenVisitor.java | 560 ------ .../codegen/go/TLATupleCodeGenVisitor.java | 67 - .../codegen/go/TypeConversionVisitor.java | 134 -- .../codegen/go/TypeDefaultValueVisitor.java | 102 -- .../pluscal/ExpandedProcedureMatch.java | 56 - .../pluscal/ModularPlusCalCodeGenVisitor.java | 401 ----- ...acroFunctionCallWriteExpansionVisitor.java | 58 - ...usCalMappingMacroReadExpansionVisitor.java | 189 -- ...ingMacroVariableWriteExpansionVisitor.java | 46 - .../codegen/pluscal/PlusCalCodeGenPass.java | 198 -- .../PlusCalStatementNameCollectorVisitor.java | 106 -- .../codegen/pluscal/ProcedureExpander.java | 160 -- .../codegen/pluscal/RefMismatchIssue.java | 29 - ...ssionMappingMacroReadExpansionVisitor.java | 87 - ...sionMappingMacroWriteExpansionVisitor.java | 43 - ...TLAExpressionParamsAccessCheckVisitor.java | 204 --- .../TLAExpressionPlusCalCodeGenVisitor.java | 445 ----- .../codegen/pluscal/TemporaryBinding.java | 136 -- .../pluscal/WriteBackInsertionVisitor.java | 171 -- .../ConstantDefinitionParsingPass.scala | 29 - .../desugar/mpcal/GotoInsertionVisitor.java | 149 -- .../mpcal/ModularPlusCalDesugarPass.java | 58 - .../mpcal/ModularPlusCalDesugarVisitor.java | 168 -- .../CircularModuleReferenceIssue.java | 24 - .../passes/expansion/ExpandingMacroCall.java | 24 - .../InstanceArgumentCountMismatchIssue.java | 30 - .../MacroArgumentCountMismatchIssue.java | 31 - .../MacroArgumentInnerScopeConflictIssue.java | 24 - .../expansion/MacroNameConflictIssue.java | 28 - .../ModularPlusCalMacroExpansionPass.java | 79 - .../PlusCalMacroExpansionVisitor.java | 171 -- ...PlusCalProcessesMacroExpansionVisitor.java | 47 - .../expansion/RecursiveMacroCallIssue.java | 24 - ...TLAExpressionMacroSubstitutionVisitor.java | 292 --- .../expansion/UnresolvableMacroCallIssue.java | 24 - .../normalising/CodeNormalisingPass.java | 21 - .../GoDeclarationNormalisingVisitor.java | 33 - .../GoStatementFindUsedLabelsVisitor.java | 127 -- .../GoStatementRemoveUnusedLabelsVisitor.java | 145 -- src/pgo/trans/passes/parse/ParsingIssue.java | 28 - .../mpcal/ModularPlusCalParsingPass.scala | 15 - .../parse/option/OptionParserIssue.java | 21 - .../parse/option/OptionParsingPass.java | 30 - .../passes/parse/pcal/PlusCalParserIssue.java | 21 - .../passes/parse/pcal/PlusCalParsingPass.java | 22 - .../passes/parse/tla/TLAParsingPass.java | 21 - ...peBodyExpressionTypeConstraintVisitor.java | 66 - ...odyLHSExpressionTypeConstraintVisitor.java | 66 - ...ypeBodyStatementTypeConstraintVisitor.java | 36 - ...PlusCalStatementTypeConstraintVisitor.java | 160 -- .../TLAExpressionTypeConstraintVisitor.java | 466 ----- .../type/TLAUnitTypeConstraintVisitor.java | 93 - .../type/TypeInferenceFailureIssue.java | 29 - .../trans/passes/type/TypeInferencePass.java | 220 --- .../InconsistentInstantiationIssue.java | 65 - .../InvalidArchetypeResourceUsageIssue.java | 61 - .../validation/LabelNotAllowedIssue.java | 57 - .../passes/validation/MissingLabelIssue.java | 57 - .../ModularPlusCalLabelingRulesVisitor.java | 430 ----- ...rPlusCalModificationValidationVisitor.java | 125 -- ...ularPlusCalStatementValidationVisitor.java | 128 -- ...PlusCalTLAExpressionValidationVisitor.java | 236 --- .../ModularPlusCalValidationVisitor.java | 168 -- ...onModularPlusCalNodeValidationVisitor.java | 78 - ...ularPlusCalStatementValidationVisitor.java | 102 -- ...PlusCalTLAExpressionValidationVisitor.java | 184 -- .../validation/NonRefParamModification.java | 22 - .../PlusCalStatementRejectionVisitor.java | 179 -- .../validation/ReservedLabelNameIssue.java | 57 - .../validation/StatementNotAllowedIssue.java | 57 - ...ssionLHSModificationValidationVisitor.java | 196 -- .../passes/validation/ValidationPass.java | 101 -- .../VariableMappedMultipleTimesIssue.java | 29 - src/pgo/util/ConsList.java | 53 - src/pgo/util/Derived.java | 35 - src/pgo/util/DerivedVisitor.java | 15 - src/pgo/util/Description.scala | 147 ++ src/pgo/util/EmptyHeterogenousList.java | 24 - src/pgo/util/HeterogenousList.java | 47 - src/pgo/util/IdMap.scala | 55 + src/pgo/util/IdSet.scala | 56 + src/pgo/util/MPCalPassUtils.scala | 163 ++ src/pgo/util/Mutator.java | 33 - src/pgo/util/NameCleaner.scala | 31 + src/pgo/util/Origin.java | 13 - src/pgo/util/OriginVisitor.java | 6 - src/pgo/util/SourceLocatable.java | 21 - src/pgo/util/SourceLocation.java | 259 --- src/pgo/util/UnionFind.java | 66 - test/files/semantics/AssignmentRules.tla | 61 + test/files/semantics/CallLabelingRules.tla | 36 + .../files/semantics/IfEitherLabelingRules.tla | 47 + test/files/semantics/LabelBeforeWhile.tla | 31 + test/files/semantics/LabelNotDefined.tla | 20 + test/files/semantics/MPCalKindMatching.tla | 23 + test/files/semantics/MacroRules.tla | 18 + .../semantics/MappingMacroWithCallGoto.tla | 31 + test/files/semantics/MappingWithLabels.tla | 20 + test/files/semantics/NoFirstLabel.tla | 25 + test/files/semantics/RecursiveMacroRules.tla | 27 + test/files/semantics/ReservedLabels.tla | 17 + .../semantics/ReturnGotoLabelingRules.tla | 31 + test/files/semantics/WithRules.tla | 25 + test/pgo/ExampleCodegenRunTest.scala | 172 -- .../pgo/ExpressionCodeGenRunFailureTest.scala | 22 - test/pgo/ExpressionCodeGenRunTest.scala | 291 --- test/pgo/FileTestSuite.scala | 97 + test/pgo/GoGenFileTests.scala | 19 + test/pgo/IntegrationTestingUtils.java | 374 ---- test/pgo/MPCalCodeGenRunTest.scala | 287 --- test/pgo/PCalGenFileTests.scala | 19 + test/pgo/PGoNetOptionsTest.scala | 119 -- test/pgo/PlusCalCodeGenPassTest.scala | 1593 ----------------- test/pgo/TestCodeGenRunTest.scala | 115 -- test/pgo/TestingUtils.scala | 48 - .../TLANodePrintEquivalenceTest.scala | 37 - test/pgo/model/type/TypeSolverTest.scala | 205 --- .../pgo/parser/ModularPlusCalParserTest.scala | 103 -- .../parser/ModularPlusCalUnitParserTest.scala | 265 --- test/pgo/parser/ParserTestingUtils.scala | 12 - test/pgo/parser/PlusCalParserSmokeTest.scala | 39 - test/pgo/parser/TLAExpressionParseTest.scala | 382 ---- test/pgo/parser/TLAParserSmokeTest.scala | 46 - test/pgo/parser/TLAUnitParseTest.scala | 229 --- ...ModularPlusCalMacroExpansionPassTest.scala | 58 - .../PostScopingValidationTest.scala | 251 --- .../validation/ValidationPassTest.scala | 490 ----- test/tla/tokens/AltBitProtocol.tokens | 590 ------ test/tla/tokens/Euclid.tokens | 227 --- test/tla/tokens/TwoPhaseCommit.tokens | 1023 ----------- 480 files changed, 5120 insertions(+), 40629 deletions(-) delete mode 100644 dev-lib/hamcrest-all-1.3.jar delete mode 100644 dev-lib/junit-4.12.jar delete mode 100644 lib/json.jar delete mode 100644 lib/plume.jar delete mode 100644 pgo-code-style.epf delete mode 100755 pgo.sh delete mode 100644 src/pgo/InternalCompilerError.java create mode 100644 src/pgo/PGo.scala delete mode 100644 src/pgo/PGoConstantDef.scala delete mode 100644 src/pgo/PGoConstantDefs.java delete mode 100644 src/pgo/PGoException.java delete mode 100644 src/pgo/PGoMain.java delete mode 100644 src/pgo/PGoNetOptions.java delete mode 100644 src/pgo/PGoOptionException.java delete mode 100644 src/pgo/PGoOptions.java delete mode 100644 src/pgo/TODO.java delete mode 100644 src/pgo/Unreachable.java delete mode 100644 src/pgo/errors/Context.java delete mode 100644 src/pgo/errors/ContextVisitor.java delete mode 100644 src/pgo/errors/Issue.java delete mode 100644 src/pgo/errors/IssueContext.java delete mode 100644 src/pgo/errors/IssueVisitor.java delete mode 100644 src/pgo/errors/IssueWithContext.java delete mode 100644 src/pgo/errors/NestedIssueContext.java delete mode 100644 src/pgo/errors/TopLevelIssueContext.java delete mode 100644 src/pgo/formatters/ContextFormattingVisitor.java delete mode 100644 src/pgo/formatters/DerivedFormattingVisitor.java delete mode 100644 src/pgo/formatters/FormattingTools.java delete mode 100644 src/pgo/formatters/GoBinopFormattingVisitor.java delete mode 100644 src/pgo/formatters/GoDeclarationFormattingVisitor.java delete mode 100644 src/pgo/formatters/GoExpressionFormattingVisitor.java delete mode 100644 src/pgo/formatters/GoNodeFormattingVisitor.java delete mode 100644 src/pgo/formatters/GoStatementFormattingVisitor.java delete mode 100644 src/pgo/formatters/GoTypeFormattingVisitor.java delete mode 100644 src/pgo/formatters/IndentingWriter.java delete mode 100644 src/pgo/formatters/IssueFormattingVisitor.java delete mode 100644 src/pgo/formatters/OriginFormattingVisitor.java delete mode 100644 src/pgo/formatters/PlusCalNodeFormattingVisitor.java delete mode 100644 src/pgo/formatters/PlusCalStatementFormattingVisitor.java delete mode 100644 src/pgo/formatters/TLAExpressionFormattingVisitor.java delete mode 100644 src/pgo/formatters/TLANodeFormattingVisitor.java delete mode 100644 src/pgo/formatters/TLAUnitFormattingVisitor.java delete mode 100644 src/pgo/formatters/TypeFormattingVisitor.java create mode 100644 src/pgo/model/Definitions.scala create mode 100644 src/pgo/model/PGoError.scala create mode 100644 src/pgo/model/RefersTo.scala create mode 100644 src/pgo/model/Rewritable.scala create mode 100644 src/pgo/model/SourceLocatable.scala create mode 100644 src/pgo/model/SourceLocation.scala create mode 100644 src/pgo/model/Visitable.scala delete mode 100644 src/pgo/model/golang/GoAnonymousFunction.java delete mode 100644 src/pgo/model/golang/GoAssignmentStatement.java delete mode 100644 src/pgo/model/golang/GoBinop.java delete mode 100644 src/pgo/model/golang/GoBlock.java delete mode 100644 src/pgo/model/golang/GoBreak.java delete mode 100644 src/pgo/model/golang/GoBuiltins.java delete mode 100644 src/pgo/model/golang/GoCall.java delete mode 100644 src/pgo/model/golang/GoComment.java delete mode 100644 src/pgo/model/golang/GoContinue.java delete mode 100644 src/pgo/model/golang/GoDeclaration.java delete mode 100644 src/pgo/model/golang/GoDeclarationVisitor.java delete mode 100644 src/pgo/model/golang/GoDefer.java delete mode 100644 src/pgo/model/golang/GoExpression.java delete mode 100644 src/pgo/model/golang/GoExpressionStatement.java delete mode 100644 src/pgo/model/golang/GoExpressionVisitor.java delete mode 100644 src/pgo/model/golang/GoFor.java delete mode 100644 src/pgo/model/golang/GoForRange.java delete mode 100644 src/pgo/model/golang/GoFunctionDeclaration.java delete mode 100644 src/pgo/model/golang/GoFunctionParameter.java delete mode 100644 src/pgo/model/golang/GoIf.java delete mode 100644 src/pgo/model/golang/GoIfBuilder.java delete mode 100644 src/pgo/model/golang/GoIncDec.java delete mode 100644 src/pgo/model/golang/GoIndexExpression.java delete mode 100644 src/pgo/model/golang/GoIntLiteral.java delete mode 100644 src/pgo/model/golang/GoLabel.java delete mode 100644 src/pgo/model/golang/GoLabelName.java delete mode 100644 src/pgo/model/golang/GoMakeExpression.java delete mode 100644 src/pgo/model/golang/GoMapLiteral.java delete mode 100644 src/pgo/model/golang/GoModule.java delete mode 100644 src/pgo/model/golang/GoNode.java delete mode 100644 src/pgo/model/golang/GoNodeVisitor.java delete mode 100644 src/pgo/model/golang/GoPtrType.java delete mode 100644 src/pgo/model/golang/GoReturn.java delete mode 100644 src/pgo/model/golang/GoRoutineStatement.java delete mode 100644 src/pgo/model/golang/GoSelect.java delete mode 100644 src/pgo/model/golang/GoSelectCase.java delete mode 100644 src/pgo/model/golang/GoSelectorExpression.java delete mode 100644 src/pgo/model/golang/GoSliceLiteral.java delete mode 100644 src/pgo/model/golang/GoSliceOperator.java delete mode 100644 src/pgo/model/golang/GoStatement.java delete mode 100644 src/pgo/model/golang/GoStatementVisitor.java delete mode 100644 src/pgo/model/golang/GoStringLiteral.java delete mode 100644 src/pgo/model/golang/GoStructLiteral.java delete mode 100644 src/pgo/model/golang/GoStructLiteralField.java delete mode 100644 src/pgo/model/golang/GoSwitch.java delete mode 100644 src/pgo/model/golang/GoSwitchCase.java delete mode 100644 src/pgo/model/golang/GoTo.java delete mode 100644 src/pgo/model/golang/GoTypeAssertion.java delete mode 100644 src/pgo/model/golang/GoTypeCast.java delete mode 100644 src/pgo/model/golang/GoTypeDeclaration.java delete mode 100644 src/pgo/model/golang/GoUnary.java delete mode 100644 src/pgo/model/golang/GoVariableDeclaration.java delete mode 100644 src/pgo/model/golang/GoVariableDeclarationStatement.java delete mode 100644 src/pgo/model/golang/GoVariableName.java delete mode 100644 src/pgo/model/golang/builder/GoASTBuilder.java delete mode 100644 src/pgo/model/golang/builder/GoAnonymousFunctionBuilder.java delete mode 100644 src/pgo/model/golang/builder/GoBlockBuilder.java delete mode 100644 src/pgo/model/golang/builder/GoBuilder.java delete mode 100644 src/pgo/model/golang/builder/GoForRangeBuilder.java delete mode 100644 src/pgo/model/golang/builder/GoForStatementClauseBuilder.java delete mode 100644 src/pgo/model/golang/builder/GoFunctionDeclarationBuilder.java delete mode 100644 src/pgo/model/golang/builder/GoModuleBuilder.java delete mode 100644 src/pgo/model/golang/builder/GoSwitchBuilder.java delete mode 100644 src/pgo/model/golang/type/GoArchetypeResourceCollectionType.java delete mode 100644 src/pgo/model/golang/type/GoArchetypeResourceType.java delete mode 100644 src/pgo/model/golang/type/GoChanType.java delete mode 100644 src/pgo/model/golang/type/GoInterfaceType.java delete mode 100644 src/pgo/model/golang/type/GoInterfaceTypeField.java delete mode 100644 src/pgo/model/golang/type/GoMapType.java delete mode 100644 src/pgo/model/golang/type/GoSliceType.java delete mode 100644 src/pgo/model/golang/type/GoStructType.java delete mode 100644 src/pgo/model/golang/type/GoStructTypeField.java delete mode 100644 src/pgo/model/golang/type/GoType.java delete mode 100644 src/pgo/model/golang/type/GoTypeName.java delete mode 100644 src/pgo/model/golang/type/GoTypeVisitor.java create mode 100644 src/pgo/model/mpcal/AST.scala delete mode 100644 src/pgo/model/mpcal/ModularPlusCalArchetype.java delete mode 100644 src/pgo/model/mpcal/ModularPlusCalBlock.scala delete mode 100644 src/pgo/model/mpcal/ModularPlusCalBlockVisitor.java delete mode 100644 src/pgo/model/mpcal/ModularPlusCalBuilder.java delete mode 100644 src/pgo/model/mpcal/ModularPlusCalInstance.java delete mode 100644 src/pgo/model/mpcal/ModularPlusCalMapping.java delete mode 100644 src/pgo/model/mpcal/ModularPlusCalMappingMacro.java delete mode 100644 src/pgo/model/mpcal/ModularPlusCalMappingTarget.java delete mode 100644 src/pgo/model/mpcal/ModularPlusCalMappingVariable.java delete mode 100644 src/pgo/model/mpcal/ModularPlusCalMappingVariableName.java delete mode 100644 src/pgo/model/mpcal/ModularPlusCalMappingVariablePosition.java delete mode 100644 src/pgo/model/mpcal/ModularPlusCalNode.java delete mode 100644 src/pgo/model/mpcal/ModularPlusCalNodeFormattingVisitor.java delete mode 100644 src/pgo/model/mpcal/ModularPlusCalNodeVisitor.java delete mode 100644 src/pgo/model/mpcal/ModularPlusCalParam.scala delete mode 100644 src/pgo/model/mpcal/ModularPlusCalUnit.java delete mode 100644 src/pgo/model/mpcal/ModularPlusCalUtils.scala delete mode 100644 src/pgo/model/mpcal/ModularPlusCalYield.java create mode 100644 src/pgo/model/pcal/AST.scala delete mode 100644 src/pgo/model/pcal/PlusCalAlgorithm.java delete mode 100644 src/pgo/model/pcal/PlusCalAssert.java delete mode 100644 src/pgo/model/pcal/PlusCalAssignment.java delete mode 100644 src/pgo/model/pcal/PlusCalAssignmentPair.java delete mode 100644 src/pgo/model/pcal/PlusCalAwait.java delete mode 100644 src/pgo/model/pcal/PlusCalBuilder.java delete mode 100644 src/pgo/model/pcal/PlusCalCall.java delete mode 100644 src/pgo/model/pcal/PlusCalEither.java delete mode 100644 src/pgo/model/pcal/PlusCalFairness.java delete mode 100644 src/pgo/model/pcal/PlusCalGoto.java delete mode 100644 src/pgo/model/pcal/PlusCalIf.java delete mode 100644 src/pgo/model/pcal/PlusCalLabel.java delete mode 100644 src/pgo/model/pcal/PlusCalLabeledStatements.java delete mode 100644 src/pgo/model/pcal/PlusCalMacro.java delete mode 100644 src/pgo/model/pcal/PlusCalMacroCall.java delete mode 100644 src/pgo/model/pcal/PlusCalMultiProcess.java delete mode 100644 src/pgo/model/pcal/PlusCalNode.java delete mode 100644 src/pgo/model/pcal/PlusCalNodeVisitor.java delete mode 100644 src/pgo/model/pcal/PlusCalPrint.java delete mode 100644 src/pgo/model/pcal/PlusCalProcedure.java delete mode 100644 src/pgo/model/pcal/PlusCalProcess.java delete mode 100644 src/pgo/model/pcal/PlusCalProcesses.java delete mode 100644 src/pgo/model/pcal/PlusCalProcessesVisitor.java delete mode 100644 src/pgo/model/pcal/PlusCalReturn.java delete mode 100644 src/pgo/model/pcal/PlusCalSingleProcess.java delete mode 100644 src/pgo/model/pcal/PlusCalSkip.java delete mode 100644 src/pgo/model/pcal/PlusCalStatement.java delete mode 100644 src/pgo/model/pcal/PlusCalStatementVisitor.java delete mode 100644 src/pgo/model/pcal/PlusCalUtils.scala delete mode 100644 src/pgo/model/pcal/PlusCalVariableDeclaration.java delete mode 100644 src/pgo/model/pcal/PlusCalWhile.java delete mode 100644 src/pgo/model/pcal/PlusCalWith.java create mode 100644 src/pgo/model/tla/AST.scala create mode 100644 src/pgo/model/tla/BuiltinModules.scala delete mode 100644 src/pgo/model/tla/PlusCalDefaultInitValue.java delete mode 100644 src/pgo/model/tla/TLAAssumption.java delete mode 100644 src/pgo/model/tla/TLABinOp.java delete mode 100644 src/pgo/model/tla/TLABool.java delete mode 100644 src/pgo/model/tla/TLABuilder.java delete mode 100644 src/pgo/model/tla/TLABuiltinModules.scala delete mode 100644 src/pgo/model/tla/TLACase.java delete mode 100644 src/pgo/model/tla/TLACaseArm.java delete mode 100644 src/pgo/model/tla/TLAConstantDeclaration.scala delete mode 100644 src/pgo/model/tla/TLADot.java delete mode 100644 src/pgo/model/tla/TLAExistential.java delete mode 100644 src/pgo/model/tla/TLAExpression.java delete mode 100644 src/pgo/model/tla/TLAExpressionVisitor.java delete mode 100644 src/pgo/model/tla/TLAFairness.java delete mode 100644 src/pgo/model/tla/TLAFunction.java delete mode 100644 src/pgo/model/tla/TLAFunctionCall.java delete mode 100644 src/pgo/model/tla/TLAFunctionDefinition.java delete mode 100644 src/pgo/model/tla/TLAFunctionSet.java delete mode 100644 src/pgo/model/tla/TLAFunctionSubstitution.java delete mode 100644 src/pgo/model/tla/TLAFunctionSubstitutionPair.java delete mode 100644 src/pgo/model/tla/TLAGeneralIdentifier.scala delete mode 100644 src/pgo/model/tla/TLAGeneralIdentifierPart.java delete mode 100644 src/pgo/model/tla/TLAIdentifier.java delete mode 100644 src/pgo/model/tla/TLAIdentifierOrTuple.java delete mode 100644 src/pgo/model/tla/TLAIf.java delete mode 100644 src/pgo/model/tla/TLAInstance.scala delete mode 100644 src/pgo/model/tla/TLALet.java delete mode 100644 src/pgo/model/tla/TLAMaybeAction.java delete mode 100644 src/pgo/model/tla/TLAModule.scala delete mode 100644 src/pgo/model/tla/TLAModuleDefinition.scala delete mode 100644 src/pgo/model/tla/TLAModuleExtends.scala delete mode 100644 src/pgo/model/tla/TLANode.java delete mode 100644 src/pgo/model/tla/TLANodeVisitor.java delete mode 100644 src/pgo/model/tla/TLANumber.java delete mode 100644 src/pgo/model/tla/TLAOpDecl.java delete mode 100644 src/pgo/model/tla/TLAOperatorCall.java delete mode 100644 src/pgo/model/tla/TLAOperatorDefinition.scala delete mode 100644 src/pgo/model/tla/TLAQuantifiedExistential.java delete mode 100644 src/pgo/model/tla/TLAQuantifiedUniversal.java delete mode 100644 src/pgo/model/tla/TLAQuantifierBound.scala delete mode 100644 src/pgo/model/tla/TLARecordConstructor.java delete mode 100644 src/pgo/model/tla/TLARecordSet.java delete mode 100644 src/pgo/model/tla/TLARef.java delete mode 100644 src/pgo/model/tla/TLARequiredAction.java delete mode 100644 src/pgo/model/tla/TLASetComprehension.java delete mode 100644 src/pgo/model/tla/TLASetConstructor.java delete mode 100644 src/pgo/model/tla/TLASetRefinement.java delete mode 100644 src/pgo/model/tla/TLASpecialVariableValue.java delete mode 100644 src/pgo/model/tla/TLASpecialVariableVariable.java delete mode 100644 src/pgo/model/tla/TLAString.java delete mode 100644 src/pgo/model/tla/TLASubstitutionKey.java delete mode 100644 src/pgo/model/tla/TLASymbol.java delete mode 100644 src/pgo/model/tla/TLATheorem.java delete mode 100644 src/pgo/model/tla/TLATuple.java delete mode 100644 src/pgo/model/tla/TLAUnary.java delete mode 100644 src/pgo/model/tla/TLAUnit.scala delete mode 100644 src/pgo/model/tla/TLAUnitVisitor.java delete mode 100644 src/pgo/model/tla/TLAUnitVisitorThrowsHack.java delete mode 100644 src/pgo/model/tla/TLAUniversal.java delete mode 100644 src/pgo/model/tla/TLAUtils.scala delete mode 100644 src/pgo/model/tla/TLAVariableDeclaration.scala delete mode 100644 src/pgo/model/type/AbstractRecordType.java delete mode 100644 src/pgo/model/type/ArchetypeResourceCollectionType.java delete mode 100644 src/pgo/model/type/ArchetypeResourceType.java delete mode 100644 src/pgo/model/type/BacktrackingFailureIssue.java delete mode 100644 src/pgo/model/type/BoolType.java delete mode 100644 src/pgo/model/type/ChanType.java delete mode 100644 src/pgo/model/type/FunctionType.java delete mode 100644 src/pgo/model/type/InfiniteTypeIssue.java delete mode 100644 src/pgo/model/type/IntType.java delete mode 100644 src/pgo/model/type/InterfaceType.java delete mode 100644 src/pgo/model/type/MapType.java delete mode 100644 src/pgo/model/type/NoMatchingFieldIssue.java delete mode 100644 src/pgo/model/type/NonEnumerableSetType.java delete mode 100644 src/pgo/model/type/ProcedureType.java delete mode 100644 src/pgo/model/type/RealType.java delete mode 100644 src/pgo/model/type/RecordType.java delete mode 100644 src/pgo/model/type/RecordTypeEntry.java delete mode 100644 src/pgo/model/type/SetType.java delete mode 100644 src/pgo/model/type/SimpleContainerType.java delete mode 100644 src/pgo/model/type/SliceType.java delete mode 100644 src/pgo/model/type/StringType.java delete mode 100644 src/pgo/model/type/TupleType.java delete mode 100644 src/pgo/model/type/Type.java delete mode 100644 src/pgo/model/type/TypeCopyVisitor.java delete mode 100644 src/pgo/model/type/TypeGenerator.java delete mode 100644 src/pgo/model/type/TypeHasVariableVisitor.java delete mode 100644 src/pgo/model/type/TypeSolver.java delete mode 100644 src/pgo/model/type/TypeSubstitution.java delete mode 100644 src/pgo/model/type/TypeVariable.java delete mode 100644 src/pgo/model/type/TypeVariableAbstractRecordSubstitutionVisitor.java delete mode 100644 src/pgo/model/type/TypeVariableCollectionVisitor.java delete mode 100644 src/pgo/model/type/TypeVariableSubstitutionVisitor.java delete mode 100644 src/pgo/model/type/TypeVisitor.java delete mode 100644 src/pgo/model/type/UnificationException.java delete mode 100644 src/pgo/model/type/UnsatisfiableConstraintIssue.java delete mode 100644 src/pgo/model/type/constraint/BasicConstraint.java delete mode 100644 src/pgo/model/type/constraint/Constraint.java delete mode 100644 src/pgo/model/type/constraint/EqualityConstraint.java delete mode 100644 src/pgo/model/type/constraint/HasFieldConstraint.java delete mode 100644 src/pgo/model/type/constraint/MonomorphicConstraint.java delete mode 100644 src/pgo/model/type/constraint/PolymorphicConstraint.java rename src/pgo/parser/{LineColumnAwareReader.scala => LineColumnAwareCharReader.scala} (71%) create mode 100644 src/pgo/parser/MPCalParser.scala create mode 100644 src/pgo/parser/MPCalParserContext.scala delete mode 100644 src/pgo/parser/ModularPlusCalParser.scala create mode 100644 src/pgo/parser/PCalParser.scala create mode 100644 src/pgo/parser/PCalParserContext.scala delete mode 100644 src/pgo/parser/PlusCalParser.scala create mode 100644 src/pgo/parser/TLAParserContext.scala delete mode 100644 src/pgo/scope/ChainMap.java delete mode 100644 src/pgo/scope/ChainSet.java delete mode 100644 src/pgo/scope/Context.java delete mode 100644 src/pgo/scope/UID.java create mode 100644 src/pgo/trans/MPCalGoCodegenPass.scala create mode 100644 src/pgo/trans/MPCalNormalizePass.scala create mode 100644 src/pgo/trans/MPCalPCalCodegenPass.scala create mode 100644 src/pgo/trans/MPCalSemanticCheckPass.scala create mode 100644 src/pgo/trans/PCalRenderPass.scala delete mode 100644 src/pgo/trans/PGoTransException.java delete mode 100644 src/pgo/trans/PGoUnsupportedException.java create mode 100644 src/pgo/trans/PlusCalCodeGenPassS.txt delete mode 100644 src/pgo/trans/intermediate/BuiltinModule.java delete mode 100644 src/pgo/trans/intermediate/BuiltinOperator.java delete mode 100644 src/pgo/trans/intermediate/CheckOptionsPass.java delete mode 100644 src/pgo/trans/intermediate/CompiledOperatorAccessor.java delete mode 100644 src/pgo/trans/intermediate/DefinitionRegistry.java delete mode 100644 src/pgo/trans/intermediate/IOErrorIssue.java delete mode 100644 src/pgo/trans/intermediate/OperatorAccessor.java delete mode 100644 src/pgo/trans/intermediate/QualifiedName.java delete mode 100644 src/pgo/trans/intermediate/TLABuiltins.java delete mode 100644 src/pgo/trans/intermediate/TypelessBuiltinOperator.java delete mode 100644 src/pgo/trans/intermediate/UnsupportedFeatureIssue.java delete mode 100644 src/pgo/trans/intermediate/WhileLoadingUnit.java delete mode 100644 src/pgo/trans/passes/atomicity/AtomicityInferencePass.java delete mode 100644 src/pgo/trans/passes/atomicity/ModularPlusCalAtomicityInferencePass.java delete mode 100644 src/pgo/trans/passes/atomicity/PlusCalStatementAtomicityInferenceVisitor.java delete mode 100644 src/pgo/trans/passes/atomicity/TLAExpressionLHSAtomicityInferenceVisitor.java delete mode 100644 src/pgo/trans/passes/atomicity/TLAExpressionValueAtomicityInferenceVisitor.java delete mode 100644 src/pgo/trans/passes/atomicity/TLAUnitAtomicityInferenceVisitor.java delete mode 100644 src/pgo/trans/passes/codegen/NameCleaner.java delete mode 100644 src/pgo/trans/passes/codegen/Recycling.java delete mode 100644 src/pgo/trans/passes/codegen/go/ArchetypeResourcesGlobalVariableStrategy.java delete mode 100644 src/pgo/trans/passes/codegen/go/CodeGenUtil.java delete mode 100644 src/pgo/trans/passes/codegen/go/CopyVisitor.java delete mode 100644 src/pgo/trans/passes/codegen/go/CriticalSection.java delete mode 100644 src/pgo/trans/passes/codegen/go/CriticalSectionTracker.java delete mode 100644 src/pgo/trans/passes/codegen/go/DefaultLocalVariableStrategy.java delete mode 100644 src/pgo/trans/passes/codegen/go/EqCodeGenVisitor.java delete mode 100644 src/pgo/trans/passes/codegen/go/EtcdGlobalVariableStrategy.java delete mode 100644 src/pgo/trans/passes/codegen/go/GlobalVariableStrategy.java delete mode 100644 src/pgo/trans/passes/codegen/go/GoCommandLineArgumentParser.java delete mode 100644 src/pgo/trans/passes/codegen/go/GoExpressionIsConstantVisitor.java delete mode 100644 src/pgo/trans/passes/codegen/go/GoExpressionStaticComparisonVisitor.java delete mode 100644 src/pgo/trans/passes/codegen/go/LessThanCodeGenVisitor.java delete mode 100644 src/pgo/trans/passes/codegen/go/LocalVariableStrategy.java delete mode 100644 src/pgo/trans/passes/codegen/go/ModularPlusCalGoCodeGenPass.java delete mode 100644 src/pgo/trans/passes/codegen/go/MultithreadedProcessGlobalVariableStrategy.java delete mode 100644 src/pgo/trans/passes/codegen/go/PlusCalGoCodeGenPass.java delete mode 100644 src/pgo/trans/passes/codegen/go/PlusCalProcessesCodeGenVisitor.java delete mode 100644 src/pgo/trans/passes/codegen/go/PlusCalStatementCodeGenVisitor.java delete mode 100644 src/pgo/trans/passes/codegen/go/PlusCalStatementContainsAwaitVisitor.java delete mode 100644 src/pgo/trans/passes/codegen/go/PlusCalStatementContainsLabelVisitor.java delete mode 100644 src/pgo/trans/passes/codegen/go/SingleThreadedProcessGlobalVariableStrategy.java delete mode 100644 src/pgo/trans/passes/codegen/go/SnapshottingLocalVariableStrategy.java delete mode 100644 src/pgo/trans/passes/codegen/go/StateServerGlobalVariableStrategy.java delete mode 100644 src/pgo/trans/passes/codegen/go/TLAExpressionAssignmentLHSCodeGenVisitor.java delete mode 100644 src/pgo/trans/passes/codegen/go/TLAExpressionCodeGenVisitor.java delete mode 100644 src/pgo/trans/passes/codegen/go/TLATupleCodeGenVisitor.java delete mode 100644 src/pgo/trans/passes/codegen/go/TypeConversionVisitor.java delete mode 100644 src/pgo/trans/passes/codegen/go/TypeDefaultValueVisitor.java delete mode 100644 src/pgo/trans/passes/codegen/pluscal/ExpandedProcedureMatch.java delete mode 100644 src/pgo/trans/passes/codegen/pluscal/ModularPlusCalCodeGenVisitor.java delete mode 100644 src/pgo/trans/passes/codegen/pluscal/ModularPlusCalMappingMacroFunctionCallWriteExpansionVisitor.java delete mode 100644 src/pgo/trans/passes/codegen/pluscal/ModularPlusCalMappingMacroReadExpansionVisitor.java delete mode 100644 src/pgo/trans/passes/codegen/pluscal/ModularPlusCalMappingMacroVariableWriteExpansionVisitor.java delete mode 100644 src/pgo/trans/passes/codegen/pluscal/PlusCalCodeGenPass.java delete mode 100644 src/pgo/trans/passes/codegen/pluscal/PlusCalStatementNameCollectorVisitor.java delete mode 100644 src/pgo/trans/passes/codegen/pluscal/ProcedureExpander.java delete mode 100644 src/pgo/trans/passes/codegen/pluscal/RefMismatchIssue.java delete mode 100644 src/pgo/trans/passes/codegen/pluscal/TLAExpressionMappingMacroReadExpansionVisitor.java delete mode 100644 src/pgo/trans/passes/codegen/pluscal/TLAExpressionMappingMacroWriteExpansionVisitor.java delete mode 100644 src/pgo/trans/passes/codegen/pluscal/TLAExpressionParamsAccessCheckVisitor.java delete mode 100644 src/pgo/trans/passes/codegen/pluscal/TLAExpressionPlusCalCodeGenVisitor.java delete mode 100644 src/pgo/trans/passes/codegen/pluscal/TemporaryBinding.java delete mode 100644 src/pgo/trans/passes/codegen/pluscal/WriteBackInsertionVisitor.java delete mode 100644 src/pgo/trans/passes/constdef/ConstantDefinitionParsingPass.scala delete mode 100644 src/pgo/trans/passes/desugar/mpcal/GotoInsertionVisitor.java delete mode 100644 src/pgo/trans/passes/desugar/mpcal/ModularPlusCalDesugarPass.java delete mode 100644 src/pgo/trans/passes/desugar/mpcal/ModularPlusCalDesugarVisitor.java delete mode 100644 src/pgo/trans/passes/expansion/CircularModuleReferenceIssue.java delete mode 100644 src/pgo/trans/passes/expansion/ExpandingMacroCall.java delete mode 100644 src/pgo/trans/passes/expansion/InstanceArgumentCountMismatchIssue.java delete mode 100644 src/pgo/trans/passes/expansion/MacroArgumentCountMismatchIssue.java delete mode 100644 src/pgo/trans/passes/expansion/MacroArgumentInnerScopeConflictIssue.java delete mode 100644 src/pgo/trans/passes/expansion/MacroNameConflictIssue.java delete mode 100644 src/pgo/trans/passes/expansion/ModularPlusCalMacroExpansionPass.java delete mode 100644 src/pgo/trans/passes/expansion/PlusCalMacroExpansionVisitor.java delete mode 100644 src/pgo/trans/passes/expansion/PlusCalProcessesMacroExpansionVisitor.java delete mode 100644 src/pgo/trans/passes/expansion/RecursiveMacroCallIssue.java delete mode 100644 src/pgo/trans/passes/expansion/TLAExpressionMacroSubstitutionVisitor.java delete mode 100644 src/pgo/trans/passes/expansion/UnresolvableMacroCallIssue.java delete mode 100644 src/pgo/trans/passes/normalising/CodeNormalisingPass.java delete mode 100644 src/pgo/trans/passes/normalising/GoDeclarationNormalisingVisitor.java delete mode 100644 src/pgo/trans/passes/normalising/GoStatementFindUsedLabelsVisitor.java delete mode 100644 src/pgo/trans/passes/normalising/GoStatementRemoveUnusedLabelsVisitor.java delete mode 100644 src/pgo/trans/passes/parse/ParsingIssue.java delete mode 100644 src/pgo/trans/passes/parse/mpcal/ModularPlusCalParsingPass.scala delete mode 100644 src/pgo/trans/passes/parse/option/OptionParserIssue.java delete mode 100644 src/pgo/trans/passes/parse/option/OptionParsingPass.java delete mode 100644 src/pgo/trans/passes/parse/pcal/PlusCalParserIssue.java delete mode 100644 src/pgo/trans/passes/parse/pcal/PlusCalParsingPass.java delete mode 100644 src/pgo/trans/passes/parse/tla/TLAParsingPass.java delete mode 100644 src/pgo/trans/passes/type/ArchetypeBodyExpressionTypeConstraintVisitor.java delete mode 100644 src/pgo/trans/passes/type/ArchetypeBodyLHSExpressionTypeConstraintVisitor.java delete mode 100644 src/pgo/trans/passes/type/ArchetypeBodyStatementTypeConstraintVisitor.java delete mode 100644 src/pgo/trans/passes/type/PlusCalStatementTypeConstraintVisitor.java delete mode 100644 src/pgo/trans/passes/type/TLAExpressionTypeConstraintVisitor.java delete mode 100644 src/pgo/trans/passes/type/TLAUnitTypeConstraintVisitor.java delete mode 100644 src/pgo/trans/passes/type/TypeInferenceFailureIssue.java delete mode 100644 src/pgo/trans/passes/type/TypeInferencePass.java delete mode 100644 src/pgo/trans/passes/validation/InconsistentInstantiationIssue.java delete mode 100644 src/pgo/trans/passes/validation/InvalidArchetypeResourceUsageIssue.java delete mode 100644 src/pgo/trans/passes/validation/LabelNotAllowedIssue.java delete mode 100644 src/pgo/trans/passes/validation/MissingLabelIssue.java delete mode 100644 src/pgo/trans/passes/validation/ModularPlusCalLabelingRulesVisitor.java delete mode 100644 src/pgo/trans/passes/validation/ModularPlusCalModificationValidationVisitor.java delete mode 100644 src/pgo/trans/passes/validation/ModularPlusCalStatementValidationVisitor.java delete mode 100644 src/pgo/trans/passes/validation/ModularPlusCalTLAExpressionValidationVisitor.java delete mode 100644 src/pgo/trans/passes/validation/ModularPlusCalValidationVisitor.java delete mode 100644 src/pgo/trans/passes/validation/NonModularPlusCalNodeValidationVisitor.java delete mode 100644 src/pgo/trans/passes/validation/NonModularPlusCalStatementValidationVisitor.java delete mode 100644 src/pgo/trans/passes/validation/NonModularPlusCalTLAExpressionValidationVisitor.java delete mode 100644 src/pgo/trans/passes/validation/NonRefParamModification.java delete mode 100644 src/pgo/trans/passes/validation/PlusCalStatementRejectionVisitor.java delete mode 100644 src/pgo/trans/passes/validation/ReservedLabelNameIssue.java delete mode 100644 src/pgo/trans/passes/validation/StatementNotAllowedIssue.java delete mode 100644 src/pgo/trans/passes/validation/TLAExpressionLHSModificationValidationVisitor.java delete mode 100644 src/pgo/trans/passes/validation/ValidationPass.java delete mode 100644 src/pgo/trans/passes/validation/VariableMappedMultipleTimesIssue.java delete mode 100644 src/pgo/util/ConsList.java delete mode 100644 src/pgo/util/Derived.java delete mode 100644 src/pgo/util/DerivedVisitor.java create mode 100644 src/pgo/util/Description.scala delete mode 100644 src/pgo/util/EmptyHeterogenousList.java delete mode 100644 src/pgo/util/HeterogenousList.java create mode 100644 src/pgo/util/IdMap.scala create mode 100644 src/pgo/util/IdSet.scala create mode 100644 src/pgo/util/MPCalPassUtils.scala delete mode 100644 src/pgo/util/Mutator.java create mode 100644 src/pgo/util/NameCleaner.scala delete mode 100644 src/pgo/util/Origin.java delete mode 100644 src/pgo/util/OriginVisitor.java delete mode 100644 src/pgo/util/SourceLocatable.java delete mode 100644 src/pgo/util/SourceLocation.java delete mode 100644 src/pgo/util/UnionFind.java create mode 100644 test/files/semantics/AssignmentRules.tla create mode 100644 test/files/semantics/CallLabelingRules.tla create mode 100644 test/files/semantics/IfEitherLabelingRules.tla create mode 100644 test/files/semantics/LabelBeforeWhile.tla create mode 100644 test/files/semantics/LabelNotDefined.tla create mode 100644 test/files/semantics/MPCalKindMatching.tla create mode 100644 test/files/semantics/MacroRules.tla create mode 100644 test/files/semantics/MappingMacroWithCallGoto.tla create mode 100644 test/files/semantics/MappingWithLabels.tla create mode 100644 test/files/semantics/NoFirstLabel.tla create mode 100644 test/files/semantics/RecursiveMacroRules.tla create mode 100644 test/files/semantics/ReservedLabels.tla create mode 100644 test/files/semantics/ReturnGotoLabelingRules.tla create mode 100644 test/files/semantics/WithRules.tla delete mode 100644 test/pgo/ExampleCodegenRunTest.scala delete mode 100644 test/pgo/ExpressionCodeGenRunFailureTest.scala delete mode 100644 test/pgo/ExpressionCodeGenRunTest.scala create mode 100644 test/pgo/FileTestSuite.scala create mode 100644 test/pgo/GoGenFileTests.scala delete mode 100644 test/pgo/IntegrationTestingUtils.java delete mode 100644 test/pgo/MPCalCodeGenRunTest.scala create mode 100644 test/pgo/PCalGenFileTests.scala delete mode 100644 test/pgo/PGoNetOptionsTest.scala delete mode 100644 test/pgo/PlusCalCodeGenPassTest.scala delete mode 100644 test/pgo/TestCodeGenRunTest.scala delete mode 100644 test/pgo/TestingUtils.scala delete mode 100644 test/pgo/formatters/TLANodePrintEquivalenceTest.scala delete mode 100644 test/pgo/model/type/TypeSolverTest.scala delete mode 100644 test/pgo/parser/ModularPlusCalParserTest.scala delete mode 100644 test/pgo/parser/ModularPlusCalUnitParserTest.scala delete mode 100644 test/pgo/parser/ParserTestingUtils.scala delete mode 100644 test/pgo/parser/PlusCalParserSmokeTest.scala delete mode 100644 test/pgo/parser/TLAExpressionParseTest.scala delete mode 100644 test/pgo/parser/TLAParserSmokeTest.scala delete mode 100644 test/pgo/parser/TLAUnitParseTest.scala delete mode 100644 test/pgo/trans/intermediate/ModularPlusCalMacroExpansionPassTest.scala delete mode 100644 test/pgo/trans/passes/validation/PostScopingValidationTest.scala delete mode 100644 test/pgo/trans/passes/validation/ValidationPassTest.scala delete mode 100644 test/tla/tokens/AltBitProtocol.tokens delete mode 100644 test/tla/tokens/Euclid.tokens delete mode 100644 test/tla/tokens/TwoPhaseCommit.tokens diff --git a/.gitignore b/.gitignore index 11cbc8512..552395289 100644 --- a/.gitignore +++ b/.gitignore @@ -363,3 +363,4 @@ lib/pgo.jar # ignore copied src in example/output/ /examples/output/*/src/ +target/ diff --git a/dev-lib/hamcrest-all-1.3.jar b/dev-lib/hamcrest-all-1.3.jar deleted file mode 100644 index 6f62ba00c7be664f5b5a23aae888887d176580ce..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 306578 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�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

&R7;REBZd0NaNVcN6Eoy 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

?@Ib4$R$ZbA6MIsF(ZEk4Ii=sfRBa)&Yo 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�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 TY(h;@!?}i$7z!3V8^-w`q)kqw diff --git a/lib/json.jar b/lib/json.jar deleted file mode 100644 index cad06581d98bb13032f36bf4990324f67cc9a31c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 61749 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�O+eKbJwhcOm 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

~| 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%0AI&#^lr`oJwacca-{tJKu-%cyU`JmNz)9 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�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 ywc3<% zVa+<_HWX)}l20p8|VyFLBEoQC@p z9baJMcaE$5&#k^-XAFcwFL%VP2~lT$gkpMpA%r`H^`W6h$kbVUe6g*|LLZ(i{1YY5 z0P)$Md?DHUMrT;~k~4RdT!SW$zhaA1S4H^^IJzc}9-XRl)!bqKM$nvb@TB;T9GoKX zWa}P5J#xtxa=dYRW>U;`c=L3PP|QN`r2m^#J|*Fc=i4iLRLd62aYFMMTR6Mn3GCia zf0WM_{W`XM53wo)Oqm}4wmweeOgyPiwpts0Se>SD^2?rS>->YKJ@VEW2jhW+u&?aS z$Z(veJwvwHE2rCE)R`2!XTp;pf5dESjKOf?sM}}cP8NHl!jmn3!@I$w*z=+?r&A(c z^w9GkyJA<%(*29y4cryR|I`(r{nthCcUR!@U)ORjY8LJQGc;d2^07@BTS6?zp9!;6 zxw5A7g#s90$k0&wtU*7hSc@V#SU4EnSvY{fL+im2RyI}A7={&1I8~~2bU;9D(UO!^ zmFm^LZPnkRr!xLWMFPLlo40EqHw-F%_ghLs=Lzo#_s-GK7rr010LM180SSCaEj-8g z?Hyvfy@Y8_++HHHH+7Kw0Shy3`N4gI;AY{06Vc*<=~^dQ*vv&MThQ9|I}Ee8VhBU{ zbE-)zUD$@pCXx`0?Xp8j%z&Uw=xj(JS2uBwTd+MxH+KJueQZq4#B`V7X34=n#FTw> zJcO`h2(SyJbY9X81c*C0ydBiRmeJd=7`w5(7L&VLfxj`d1j&2mh_PqxJV7vEhhn&i zQxwLd6OLklY}A&WB?s-=?{%#%!ffR55|^ySyQmnmz}N1O^`$WY^G1n*+=v48O2bb2 zrG}kWqAGPqxl>2Txi5u*MH+9CjK)CQm;(*3Wz5DV6vA(Zg>Bp7#QJCUiiVCvEI3&( zX%IP{5}7;7D^3l#=wvz8$tzA-ZJw1uH;SvEkdXc}#&`v7>HD4B5P|;i$fQK+@GWC% zqoM{$il*gepbt7)Cf7JC#E|)D9m*rKr~Wu~-~QEXE8mfEf?+VxO?|yqxX0iQl(X}^ zUD!u=xV`wvnV3*Ia`y!0FablUyxSaqnM4sRI;Qr|Zc@WF^d||n;VddP7WnqRdCHoB3`B=au7|Jm`(Q6+x~tB|6+q|zst%HNjb3U{nxj4Ra^+YqUwN@kiI z>p@<)i=KnYps47_!Sv$K;-&&*0A)HAYWDb@iF3S*woSIJljB)y6A{(ZmIC4>ItMu4 z9|BBwcq4G+T3Bz?70lN>TKPRGkQpQDFbvpF$Q5jNq~;J&QRji*8~6?hWtGXgJ^Z$^ zZDh-A8FHH863gMOPq<7ZRM29JI=i~09UBp(Jc#>#vHk=HWSY;0>mt|*%FS$s#Z-!h zZ7OvbOjnI2?9=x zQ|b;B$zib8*93St8Z~(>J2FMM*`%i%;`s6Fv80u)HpQ}aXiO9mK@oEAB7@Y69`fnk zW?cZ0&P*hJ2JB;C+pn}vW@T{SkQ|6R7?7IXB|=@6Tdu=pwN(~-p!E!O&p@T|nBJfs z{hevN!-T6+2lF^I@XAzS$oVgF5A&}6cyCRSgm2&uI^73Hhl`cP_jvB1wdlOJ_Xbq< z0c*j0_XU&n7NXN&H&zMLF2XvG(N(>fcdwA5N@RT8SSq1)v|y-fy`)Ishn|hTkW3~f zN1WJjuWn)C`#+I(wVE}43-M>oGuWvodfjE8?R_>MB9M>44s_xov@IRfmRs|Zkn&_C zxoZ8IXXDL!JXJgR8e*?M4#`?t+ebAFT5Ppwr4~IO(5Jy{VAAw$A??P)6s>*V`n=++ zmv%1dHs2z<_pLlgljQjuH*%f7DaNLxSA%23kyeb!W5rGmspDKrlA95wY$e5&sQ%8t zGPEAAOiS8qYy2IfAsEFqQ*x3T$+GhG!s*KhIz9vd7CS{aNojWI6v}+{1P-lm4zGb} zePB`4vPp#TdcVvLK}o)ZzY$dy3!%&9gR7AoHHXE5BNdD zAyqcL)GN+RJz5+hzy4Wu&OluL(IqiZg`u7IQ`kmx+BoqgMf!?cqL>DENLpdG6p|n` z%zevjniyG3)#LLzED~07u@-l+Smm0K9+2ue9`ojmFH6pQ{P;cAf*d_l5cPnkuy4!lt|uDE zMM)zeZw_V(<7U;W7!chTJ7ymlZSGI3?~je&MqT+3-0qs96RC!i(ZX6XU6xX^BiZ5u zP>Zp_(O9fm-ytG$W5btq_6M*T#w0w^hl;wITC+NJ1lMS&e#=Qlb`b1M4&xWb9qkYeIkO#^ zDqEH8Tdkj1Y1WmMtsOq4QF*91OiLO4?L@F z|HK43yO8YZ)ntjA3yA|ANslvC)(1@@Aqph30W(LsGe`5i=c;?Rx{dGE>7ZQ~ShPL> z4?k(I#g`t$CR{r+!L7ca9m$DM4XG9*rt5nq*8W>25pP&&Uf2v)2ZRCXq!ebXWEs1A zt0UfW)pmSmn*FZeh~MJW#TOo!=gmvFeHw~}SErH9Gr3OUfNIf3=?N0_f;RQKPX-Z? zk&)5O1LG6SW5QUlG@@pT^jefwNO`6{`G!yVdt@Hrq#5MDPQF53WA8`XV3Q43O8O?We^k>)i-;Zh2#&FU+bn2ct5z3i? z>Y?bm)ad|{64s6x)%KpZZNpvi1vdoC-$dA#h*uAL1Xs*CE1ByYJJNX5$Knq}Jg>6n zxp>4c9|eJZrtg0B>prs^d?hz_3y=B<6a16o`V!RtA|3TZy6=&k_w$y5nxk+mS%I)x zRdjVw6|G`~LhWZG_2}8$eMkK%Q1v+U5XmW2U$Imm#v=7@U1isk^0HVQO)hg^+}`X7 z*a5S|oCg~^uTGY=$zwKZ{lz!&X?dR{-ZjnNqw>DUD|8cVv=?c5+nuP$o;#h-`vhw~ zk!MANxJ*y&&#@EAp|_M$%%iPyCP<0Eqkc@p9{8f>iCG*v^;r9)!_!(Np2$EkGhnlr z_ zG|_~wX!@&OqH}=3qVwMSzQ(qdy&9WEeM|mU{Xj_n;#erY#ImZDUYsd4U-$uMn^WUg zfw3<|^*9`9Hp_tuQ)7^P1Nqq8hF8OjZgX%nd0@B}6TC7$lSjQh&7ol=9f6NQBoXUI zQn(dJe#O^l`BEV4^@BG{FPHaFoFg>a9^m5k{=^t;kN6&?$ zEdez##QXo&ieioiX8%<)CM#*# zEij_~%PN+I!Z8YF9&YN@$I3t_BGQc*_L(oV6^>E~olyPP&RDkz8{VVp)F(#i}VyEnSO+ zI-9U>7h`Q}mD_5eSr9H4X3IM9Sc;lu1_W{q?B7gsJE)R|OF7N$NQsQQG%!4a#KU&D zy0)-ub`dWQk`HVWkjpC5#i#O+>0v~pmp`7rJ581c?x6y`>!Ylnu79qYajDx|)TB>< zWfl8aVhXsfLuU2KNcxIY2wi~Au?#LF;v$_P^j7v+ICF}_V)JGctx}6>8E@6pZnIKD z)b_-d(c>(^43x%~OLI6CM@FVGG+ig6e^e}YkyPPXGHLf8`Kh`yD(;Q@EzV}={`k&f zP%>!q#+mrXI_&KoWD)JC$Dw=ipM!tNWXPAx@4>^_cVOcG|KQ=ju_mHI!XlEw|2;#& zMQQ3k;=%r*Q*gGz#|0IV5d{lD4^v@6mGL&7=h;$g)bIW%JQ;E@pc!e-a@hlOkKN`} zvlKkfLzoRM=VA{!j>C67`T8(5dw$8u>G^SKSQ4ZHM^-r{IK&cN?E;5$YTO+YaYD_G zl@ypg(Tf{Wj~7fbCcJhccuoWAAi5W%$H=-l^9j=;VvJYJEO!(yB-Cx9 z&R$$%{elJU%6f~1u8s5#adx{XAM<7*kX?@B!E^c`V*K3IKsYlLmUkUe=7I%Rwaxv} zW#lIl^oU{z$OkZ+cS+C07UjmMSTmtA)N`WY$PJJ3pn;p$gkKBjxk}yvQ*a8H<$A| zkm1C+clFOK%x(Kms2REkBo%?xopM~vv<0!4DV=P^AU0i>NM@EGiqmZGEoF-{*WEty6<<5O0_142^_Yk?iEmDv_wnlWvFWNl#L(RZ@O#DP$ z!nYuJ*@x^uiIevmRnXPl`KH^s`o5v{>OF#Y*klbZk!yZIaHtP8mHqkCFObdzH159z zH+>0h3zB>6WjcjQfF!(s|1(1j{@*;{==-do{EuhlznQs2txf*p&GLVnxonhl{v)!M zcYz-0szaFs#zw44H%~7G<4Y_N04do-g`k4`ICRCFC%wL9>Lz_#@_HW0z-LZuNE+|v zmvlGX-dr?qYHD_!Ov5DpS-ND(m5qs)B*OT+xD!NBaO%j))?dc({>Z zaD+yTXiNw03nr>KE;wxEWE>=Ra}EttlxmjT-K-57M@BwbmVP>siq{D!9MUTKo~rc- zyeii4Ltt+|J5zN>M*xvd9iHM<<9WZA#d4!A2OAuB21A$S^i9ZQhlepzc43XicIhRUtiZ%H=SvgO-L(q^(o=y0 zo^B4_dW9%Bh(hz)AF_?ow&~cFN7{OwnU+oon0krre8?I_R6rE181sRRznd3Qk+ysb zDGj^E7$K+65vkI$T!$U+rxt5ad2Z_CIhOJDE1@$M%hU_2)A3WT2NAIORc>J^JEODCTMw zJN!!{W5nS69@6l!gnIte)L3$i9sW(({46c^gA|w@#7Ss_8;Ip39)@*CGT0MG6%yH4 zai7jF9>K7Oyv627%1Lho?U+@{fwV+Tbd+i9Et;iz$(@9-J1$OnC$G~TGpUxG-sHkcn^9$%|xFCZ+w@}5NSM!Iv~@! z)1O@H$$DV0cK4rj-AhmKRKWL`RpS2?b^70@_ z&~zvR#h@SlhywYN3TwtFA;!M~4aiN&X(Mp*o35KJVKgsPjp&-y$qW?hEbE$7DpaeM z)-{`|bQae&H(FG-Pkz5l0y7P2yLV3Hzfbq|?-`Hht8Jc#wY-rZGPB)Dp+a{i-P%WJ zY9FUB*aW)BEBD`}!6r@h$poBtTYQdhFoWLFge<;80|MASdh9Fq&IFy_$%L)$_jQ&n zTFc!Phj**o=CpM8SSq*swH*G|5t7>nqx$ARs@>gWm-pFo_{Zf$%iFUrzE5cU`Eew! zPv*(<{Q|`6bBDKAth~4U|q zz#;4g!E1=*vtx$@|0!(5JB_URDT3tlgLCGqmnM5Rlfox$jJp~|-eU-%YoAisJ420U zuz=w1XvEuNn8bGei-%L*Yr1&nE*iso?IPblvYOZ5Gd+_S zl4mr!cjaoI0qJiUYM=8ox-StNo%?FKcg1R->omRxXm%b$c3t~6HSQx6+i3EhLpSa( zH|Z39yAxjCZw2C?V>JIJY5wh_+(aUD?h6x48%6y)MY0kNuX389&G%@FHQz*y^7;f(Qk{w80R9+{Ly!%!__Y2iD#ue zmVRt=FzV4PjPtG&#l3tf65uQvTqlFy%i!dKt2>jl&+B9YO}E%K=5$HGbFw;r)xB?RLI_0Qr!I= zBUQ2qP|K8BF9Gf^6?-(DO?IbtYDTMN?k$;mHfi8jEr((>{>HD8Bdp<_L$mrRHo@aKYnnB*(1|iD&L5l5*%IU z-q>dK@NRyRF#7Hq&aqHSJCAkX#b!~+K73l4|ETe>QIJ`1hl*!BNY-@Vh@1GKPbYPV zAPZt?ZWn7?tHJK4CEZAZCOrsMzP*Hn!l;FO70$V(axdoOqgL6aqQ8g1MLn`NLSpA4 zmZ)<@WoT&fEX+5D(qsqv-bBjP+%d#>{0jGbh$1Yi)7|+3D_#z2R9^rz-7iIi9Wsgs zUjd#cF}!*j-LN6&Wyy||50TSfal~d?G-PKRDAuQl>6M@Us1N?&S#W6UUm*AF?ce3$ zn}GtxK9S|si;AAxng`sM-s&-D6xL!Il-yq$r)tAQ z?gpB9e5*)NEfvfHDvJ6-m%LeCD!8F@1^C{D1oprGu1Q#E{*Ljbp;lgb>7`AA>oh*M zmI*LJD3Mt?O`#9%e{Z6MCbvI74=z(u**KUG5UdbZ<&(rm-BCwW)8Q1*oh;kg?e%h$ z->lr`pa}>IJiJ)DiJIck z&G@k-OiyQd7}n?U&!Se1-OZV?))0?&O(Koy-}EhB0xwCNZgBQfsxBlog~!Mkp{}mj zL)Xq>Y&<)Z>YmSs=8~ewpU?Y7tmIkO5cOmXXvYIEZ`RjP&vJp=?#y)UzA+4{W~r^J z3{j*U>)auTFqd?2HdEmM9WOK1`F5abf)d<<*n-)Lg8_?KIq?-^XnK^hptT(BwdGpr zZmTk;9W5H!G#S?zvi1eeVr2x%2opsn4LiS2;kpxvq}GQIjy6a36RYKJd>;ujCE3;6 z9e`Feruk2aPPd}1LW+5)Yg3#~5O1?^j?CmCqZz#9w6}Ujv~2uyv&hM@ISrlLL$Azt zewigICAaO@W_5EjCChg_0|k?%1ND4*LYctnYtk{Omxd5n^M-?=HPTrC>w$!qW~4V> zOqJtsymff(c{uvJn*3MT-Wzi88#TrqGENfB%UG5Km7alK1L@*JA`Z!=^5q|NPI?S| zG6^#4EUJ{@1o(`@<8U9c`MFj1Wr}^9t2%T~)l1MLaB+X|M@6Vq=r>}zq#Fux`7BN* zGi2%hh32_}&Y_KivgkQLC0TZ<{Y-QH5m`&9z3NA&LE^{h~re5=Aw{sn&#d6t!*}-&&c4 z#fft-)BuaJD~y1$J;2P4&}V@p|A&#PaD?!d0P zjl`Q=UNYnKKaR&72d5(ee#P=~pTQ81+5gGnBOQZV>~YpV|XISJk! zgEuh6S*cqwUJ9`4U)Im`ldGdLzlx=7oF8jQ9x>N-x%BW+6*LS zp&r(`rxaBM^?*emyH!eKF}g4Mq-eW&f!3OXy9l|*Q@Ph*|RSB zz(PAbp&3mCcq3)J6HEP^30XEv`IEva5Do%gK0;%|&b0It&pAPqAT!K9xFC^Gy8t@8 zPg(+v5lMsRQ;Wi0FI<9M*ZwjN(i4_aToHeGefyF< zz!b9pCc?E&lN@m6SvHAn5Fd_zRMI;xE-(e6fQ(ve+nH@Nw!gN51NFF5`^zwgQ*<{u zxQo1JYMQJvshG_jVp9ky%IO{>3Bd@ego9$VvglIwZEiuh36 zRT;~)2pb3c*a_8~D0m&;ITW z@Nw2A*@D>xta9_VTFpbxG0oc%FHv7ZNqf-twO^^XaJ4GfJG&Oy=b1 zkEu8)Q`bzl-i`Bt-rP(#m6S)YbMBFs%f^mcZWwK?(YKXWl5-kzeTs-@UOD0tMIC-1 z)ba|17=>OQ)alc1ZK&Kws!R6q6;FBdmz{9wAlhNiXS(Q5bPI11E#!9c#rc_Sz@;^; zHCs3Rz~7iFaYj<;*C{%6FhM;EP9s#dv_f0-YldSU;VJaoHe;y?=G84Y_@ZlO^Udmx z;g_heQHo4iyVk(mgatVl*QQl;@g)%-!v;9{`dF1|TM5(MF-f5UMym)`$>i+Es1JL% z>t|6xt;()0qHD<2jr~UQ_p0%P=h!=lY6bxrE_QLe^uo7a_Y57>&ne#X*q+`aogA&ThW9nx-N$?nk zp4Y9=B&8kG43ODydO_Ak96aCGgi3}+WY3GKdKlX5D8+C_BDr?QThGU|5 z@ejsF*wV#xz)JOVExkyymWHVC>Mx!rn>Ea{O6j$V3#MPe?ofZgqG8yuEwr1)cGQ*_ zmZI)c$Hi{_0JQTi^q?4A&VS*yru^k-e%LXh&UzW}P`Y)Bs^w(yg9 ziwiyM>u`xnnD;c~h4Ta)=b23eb}XeF>bK3o_;I{1sUNA9Li`=CB0-pEa;l4qqgIf}4*8)o zTQgi%F-jDNTpy%352$KQ4haK)kR^s)Zzpa5-PUjo74~*MftE{-*n!E}1etgfGPF(^B?}lq5GlMzm7xW)$?82>S zR@0Y{MZJ?%LtcyE`;%lJ$K4+HXm`C3|H*(Hrw7wB#_^Ib#jSz$&zwJ; znV=ZdlQ^MGbD)+K<&MW8o!QpELt?D8L&EfMcE02^b=PA=DJb24 z@{eM{$W!RAp@kCl!{Tb%xe|AAE)Q9?#end2`h4;0UU2Qkal}L8GN*5Z7Lqt85pA=A z5oVjEm^Q7=Ui@P|HZrDLm9VUH>{i$cC+|I`|0zW93 zQIk9*qHrRuNa*&R4O~&ExqQbkZBp^0o8xN6I;A#;*G@@Ny=S~ErG($Dd(qoI;#D8n z5#B)Q&r}LyZSoU495Ld!6IJE-Xvig{%@|gfMh$k0J5T!Ggk&_w#>nQSWD2L-kG%&`}WmV8RhbX+4Fgj4uMUxYJ6-H3XC! zcP6SUYFWo)E~@6)Gqi-w$-It0NUjCU(aFTwkgY~_P~gbmD_w9q_Z)VT!fV0b?;zaI z%4CLr*T)wQ2L&E9OQn(?cAO2ZA0)^WxUbT$MfzQwfLb?RH)4}XWMmP)%%kNF=d5l8 z+h{dcQSW1e^sY$8DS#Y5bP^9V7!KqzhjjFUEaXtYZ4oMUJF){$po$@dj|F1{dI*|O zfWT&B=2J?K;D;rpx(AG@RlE74NDMhfsUa7bMsOmUnjj)FDaq;V)Q zw_G?Q{825n`kmox;joXmA>*EKUCgf;JsqLe76_C*V@V{Pe(3aHNX_iCE&hAo8T*Lf za1$fxz{e~}5f?a4mO1JwRqBxQ6RAd=TQwAW+(Q*j0Ls|bbV5cd$5t)as6m|>q61=Ygaf{1DvAXSQpR}qsErly34qyS3Qid= zJ31YIQ6mJa&cpEO@NEIT^{UGa37rQU@rTu~WDRWHlWT||jYXE()4vta6bbQE;gspR zGI8a9!=8>%xk-Np*+TxcYjxXJkc?K4{x&-ve}B!I=_8UDX1{m;jgu5qY>FpFo<8+R z6sA??KNpNsQBMsZmQ~qM|N(Yi72p&7|g>{+9u9{hTuJY%AKzNq~I6g1>}K{i8i(Em|?F&hg-!c+-bJ#QwsVXcjBleAPU9 zSfpQDyWHzTVe|>_lehXLhsTYF$xUSNOc^}$E_zEp6d^M*`;MeA*j>Z>mZ3TCQzP$r z7TS*oTL`1qD6o9Sq}8CD@}bXQSJbCXD$Kg4DkhUk7+_DP);pe#jpoRD_@6-R3`&iCxaOQKcae(w5rVO3WTg0YBINScqsqd>S_%f;)MX&3@nEd zWQI7VbB~@0Z|!`5XPIiImL&Wl+X}+S(OHZ`-Ip?{TT=N*#l?(3S(1vs9BTd#dEFpD z=8vW*L)f@Zgi92L3l%LeB{ndru`nY$mgMV$0ekzY$)eQ^9`@d&hCP7dkvy*D-b!;k zh`d<5+Mu#MvcM{*^7RoWDPDbCagFAp*F{Q0&5SktMY2`K#geadc_G%#8Od8)kndHm z=w^gC7aWo!F3IUj>HK^2JMajjOrE~);Dt1&cAWkanH^i$QHvN|Ksh&Tg3w!^a@?(r zdml$Tf0HaY=`TZ(T#~5WbT2;#Y|E$BQvu#0xciJg5xwB2Aj5KoQ5vm)%uw-RIsAYr z!zsa%b-WIy%vzb^Je#&mA(&H|2Snu4BC=&L-B9jSaGY>+FZANmez}Sm!2)i`@rT(j z^jEL27ZuCAmpmL>WU6qyhmQFJCV^e%!illC`uwR`N`EHJAU1w6dsdq|iYt}##YZJ~ z7I#2?`FfH%ES1D+!ca~CnJN@AmCnhxB~XD^gpr;Emhx%8yk&fuoOAzE2i-r&lK91k zL$o|t-Nb?0b4WW+*?l(dn8~g&g3@i2BxU(wMmiLO0!rOX%YI|FE(NLey*=zxuPtdt z5jp$*MznF5Uk41K1A;Xt4wjYlnyJ}9BO0lieef*)A^Ip%>_wQsnOl`cQmXhj3;Cb2c!LsYcWrWzE7493qvru;DDh)^wJ6!x0E@w|q38-O zRo(UkuGGW5dc#}c6ir7FIIu#F(kA1Euy&S68A0Cl2=vP}XD;##-2KLO!O01CG> z^g?t0(9Jf2nkuyQ7}+MR+F@r117)W8c{q@3uHUtu-rPLXQVV7xRTYu|asPeIU?8a(qCMJDi8PP@B zKQNNTFa@`j;_k`v2rg74nuO+Shq^_R{45pEU11CIfaGdn9p{atK*m7QEJWr2L#_Y{ zOr=F7tC1;t+hGc3xu>JSSJN4bI_Y(hQ(q|2+Jzf~&I98Zhbbqafx3UANt6A|oP#*HeG|rML-l_-!sCxOLf6jm@BO$eHPVWj2r;$EhG^ljQa$YiuAoziR9%EfYyz zG)g+4o#G4iv=&VP-8^)1G?UP{lkSMzveX&>rT%K-On7MaP!P2|J9K_I)j7EO0)w%* zD(FNON#hzxU0ASAKf{_sWdJ6Oj)rfj8J-ZCm1=ZBV5jAWGL%xg)dGozxonVP2UN{u zJ@7cBVi#ct^&7q2E~FOBBg#g%+m1t<{%WXX$g9u5QzQ|~V^DOzUAn^+qK#E*C|G86 z>JlMrG7P35@pwP(^5v?>XwNYX3v%{ERk$D=O~`p>T7_*pN^LaKF0hpFojKbPLnO`s zTj;Do|ASMgY!3NR`O<>F^Ap`2T}Mr?`^Sqpt#v$x*e%~irCuwg`tg0a_Qsqj%Omqu z5OizA#kf+2baO^WA*_-gCXSsUsS_Y}>%Q>XE652FQCIME#j_@UD7SN zH66EuVE_BBvD!s;&?tj%2GjP*%HA^aI@1OfY8Ydv7Gte=W?A2>ntrYR4i~Ur`*sMd z!B2#y68e>|60Rg6_eVLxOEFq=un~^32#F#mauT7%Z>Txdz_x-76)ttZW*R%@-54HhqUOH32$hiNb97lR_MlrR+qV3y zFGP&pL|jZ0;+HBxQ9Vlk;yki&c+uTyRYOVun#4uy{KE(L7X0|ZdYV`H!Q8V2^RZUM z=J_Qqfw89poLfyfU6k_go#;a~P$Ov)ZArc`x4H`d>uYpHA1BzT1vXBTZi?eI*PyvL z-^*XM4mVa8aw+UMkJ5KW0Uov~52fQV&|3i?)zE8{5~sSfSJsfY16)6Tw1krS-7ib5{Q30AQ7igvF1zd)tsIi+@}=KG!Qa$rKmxt;GtP zOrul`n6JKQ5l+dy(JxvAUWVB5=zU}fqapoi#SXg63tz-q`-L;0?Gb-r-ZYLNHF_Be z${Ibgy}ZwP%RZm;^VkJmna=dn=!++(L*plhjfE!cu zV#ko)D1p4xdKFc_?xFJ0p5fQePGSR8ud|5Ov;wSfXk#lyAP#42(zi61KBjASzMz|O zao?q)cFH|#cD1goVnx4|hs|OP2Ew-rx{PP*5hx# zCE$=Lo5PB-W`x<)fCop3c!b-6({-|!*M&F)mDb4T7F zUMft)OsDlaUVf0I)9xYP6ECFFChTYn6}&)Ev26E<->aB1ZwpSmF~3wd&lr86wof$M zb-uv9RJqudynt<3bcMW5^6c^5%ebz*LAg)D-L$;q8U9flm>M)iML2C#-czj27RG_B zc?w0vIFK1Mo~7u-@jy0XB*$J7=xWx`3o=We z=snm^$?(YQYU9`ym`EBt)i!TPVhk7?djFVwBc;06K{x%t5}1&oU*kNQOSY3X#Ug|| zcDFAGWdjJ{Z<^uMzWdfTi)~l1+azB!u$^`t`sumpsd2kjdXjEF&7^NfNZsXficsGZ zg|I%dF3XJ%C#rMzf0VEA(!$E!ELb#l>9Ctd1Yh+I)V%fRdZs?a-mqgI{Q{)h`&`;y z4Cb}VZkj@j19uO6=baDQG(8}?m9vi-e_W&U!Q0j2QpOd9rg&nytcwl` z*!HJ=R}!Qyt2r+Kk9i~W?<0FU)byIKpo?c^f__=DMOH;2YY@iMjS@^_h772hEv=zI zs2ef}M;UOW3`|o-udkw@Y9QH>v_MQ&PpBPA_b+u~SgR@%RV&dAQ3@EZN_&oHhFVr{ zT(O!QvRcCSoGz5uZ2l60cWtPaF`_?WtVnspbXuCu`P?>yU&ME$?bdQVO|g1p-ijWH<80qQzD*Z=?_E>>A)-%a>98z0!78$ zZ*J+$qmMSWjjkM!{6dXy4Om^WJ0fpP`w_JHfxt`l@}Ko`hE;-Pjgb9Si|7_ry};+# zh!^UJXY5QG=VGN*s`^5;Yv%pxl))?(NPA1ICv|ILHFlcD#G<8umN4CmTKSgwGXg(r zd_8MoJ?nl2$Ir+{AX-(lJ*RWTx1}~oNM~k@RZCz&e(xDNRJ&PxzzlHt&UV7A2_B8Y zY>3WX^5}|V^B-m3%Qvf+9{_v93V!lzq~p;Tbh{@!1s)S$J5^{tbezpjF{SWNoM?dZd?+$+md=sR~(3EvX|r7`q#F$%g8F zaz~!=wqEkIkOD~}A#v|B6vvtz%C>`HR}$m0_*V1;B0%JOa)bY#C5p^Azh92%q9|o) zyp1w#{~vZSr=Ma@aG>hVk8aF~N6Kk?%JiR)Nelt+XX90*MiqW@Y^x=tI!c>Nso3K9 za=4_QQan6T-F|GhAzDr2Shua!SIp{`K#vYt?+V3aneTbaHTJ(QhYv!u4K#6GA8(De z8fe#*7DYsx(s_9K|IoZGao-uh>7_o>3CpP=5;&5mg4xA8g#v%Is~*Y9-VidaxuhvR zf#hFEYc|{w&nrvd3pT2<&K>|uF*Wml=&S3qd!v?QL=Sz$y)V=@thhpKG-!2yJrb0? zOR!pYMh;i%u$p%znER98omWaqGT)+qQp4Bs_<|*ULhhc+GqGdzPLBCx1)e8;vV$y> zeKKRUFQlmYe|jsBkMS3gee8T!WC0~thK4liT&~|D)%N_B^Oz?={{}0J^C*_n>jPDu zy95u5Efn#*ucXZNVO)qNywpw;GyPaisnr7YAs_}~Qs$n8CVu=pZEwIeU*|d1Wi$!P zne)yt&7D8tBsg*^s7Xd6FA})e&N?~b{&El%H-kW1?g*=r^lW_w2As7>+6T;3UtrAZcoO;30tn=FU^OZtz9`R*X+30`3vGAqZ54Rpe_zSu%Bfs~0JWb!1xeEL{P zpfjmTdYIK)kCkb4pXl&z3S`DIrZPByn`Ov$<-}JA8V8RV^qN9Cf_QAF7?8JR#h1qt z``U+7S>7=wiaW9rNz9da}d1O9;{z44&C+%e} zeU0;S{o^<<=6@pwM2xJB?9B}RefHZ+X;T471^LsePESBpT(w7;7lcOud`RDdQb&32 zTOK{%4}zI+346aHy`P&g;p_%FfE_yah3c+6)PyJ>d@{eSqDw25MSM-!-goC zD@NOHYT8SfFl>tZwR;OSvs)k{0nWf^gK{E^^Gt}BC~D6!Encmc7VQrLF-c+oLV9}e z7;hU-7{)CwLvvD1)7#7`4Yi&;Bga9JR28(tn`$LtTE#(OwvH-7aCj;qTV#3UD#VX9 zrk0&$f)qURCm^!g-UX$Tm3DXH(>W4rQ)M>D8X}9dIWmK~oHd{xGFg#o-vflF)YTW| zM`ET7wB&TDD|jbCm8}^Ha0~s@eAm(sw zGzZ5p5BPt{H-|gxU(9*+NIqlhCR_> zNhOc{1$GWyf?nREW&t{yfanXw=!7AAQbu`{%;wcio`@DUMU=&4iui=|$(yxiwCBZ= z%LX1ru$u1rDl=x)2>ppX6K!-9x^^0A73B=v_4(IOkpvQJeAu zHsnFf%>;y_Rfp^CpXb~!0>-om9CtnT)5$x5eFx#pAuuu7Gfp{NFQy7XTKK1*odVwZ z=d&Lx8ltm2yBg3>9YLSp7$E!xPq0QB=54H#iHUiiEHn{C|EJ@}kE5)3*&Rxrc__#gUkA$M^n zA~XIH+b}A3iW^%Dm2bU5Ghkx2a(6fQ!X1+7-)|L%zpgup5}Ywb>*rBE4w-*^c!>*o zghf{?zx{^%?$%w=Xd+4XA-5*qHfFlt5b2z4j{!*Yduj(CEATi0+~~k~5bfcAJzA}iVU=1Yxb4)dV1r%;J2WTcc6R`A?vrHiP zwNI|~$7JAB98>$4el`rede@=+88w}J&S@_j@d>00S!<=tNe}GjO;Tw?z^^h9?mZjG zNP*Aqe}$dRZ;=zUU$fWDVE>elu>U*kh$+bM+3V^5XW+@2|CB(|!|u7A-Y;gHe~VAU z_v=9{KNGKJh(OiBLcSVAE_qC1XF4+eL zz_3ft-9iHd95eF^#D;6sdn=t9_5S|!UY#d!^)@arM;5a9;K!#t{HHB+945b z#?RIV$yDxKQxYwsx3}MP{&ET)cAdHLFHi!=KdJ)b{D)HrxY?UoTK=b7bS`+AO8w;) z+xHiBX?j@3X-wDs7gMj}#w%I$)lpU~*BhGvhnDt~b`O)S?QP=&YOy)~Pz1zyA~E%^ z@4r6RtuC)%ugh0m=U>dL9#f~QCMCDalj{WWBw@3N_*sO+`0{OJW?5$Llf23C+~iY5 z)#fRi533UI#yvMCfzwwqjq&Vtjvr)S|jpC*Jv@Q#t4sg^e3j~KGZ z=&spZFeM_pIVC-nKAFI>bTvVXct0jEB6605g6{O+w}fv)e#}EZ@8= z`u7|+J8#Gd9U!m3F)~_#D=SyQF?|XVsvNXUH01xHcNGSbK5u0(zyvZOh(tl$|sOuhnBXd`*ls1nPuyp7Oc zA0JEV$j@z=aT$cJc*pF?3z6hu#)SwPS-7rMj?;P0_Em;>R0mG*b~EsLLMnh>00ypq zO&&N_aLq0_mS0UAI95>2EI3v`4RoLpfhAR69Xt!H-aZ1$cfD0`2Rte;JtTzWh#E2Q zjK~_!Kqa*>K2_qr4)A+?OSV2`yos0^ zia-!}R6$kdK4pSRP`wKHCQLmG_$E}nbND74JuLVp1icLSCJa3d_$Cy+b@(QL9*1M~ z#Q~33N;W~`8hN`@*TU&(oe0_(Hz4-CO&#_GldV)`e0Qdu82_!>)VtXhne?_pEYT7A z9fso_^e^{RN;P~|_$rejK>sOc{TrL+SI!c#H!`yL_gXn=;Z;FV=^NP1^;1o79ErIp z(r;al?whzO-xEj*@NnAXO(;!OXS>xwB?Neczm{Ct$e4K91eJt@2T$b%z0~}} zFq7A{7P|YSqQ`N)$5rcbw!_s^HrKLGyC(`Sto1Z6X5Ab;DZn8t19c67qbs$=psSl^ z2K#1B&c^6D8z`2mbg%4x*R!9JqzTZZqGG9<23560yF-VDV92W+( z&&V(JGBZZSeXr3OiGCSZ%r#*a)J9Ltj&GvwY&ZmOE+z56lpVdk&pX*R$+^D3qm1x#Y zXSWldx2srp2W3#$bQgB2#&n?PsJ~GQjG&=Ty`{GaJv2G_Kh*H&yeTM(Q=T)0|r zI0t5&U3JbedCnmQ&Z$RNe-zjFjM#B%)e&(jeH2v2K;p_Fg~~zsrCqb&T?63pl~B&1 z*lAYCmB>TM{8)}!e`?iH<>%FCr3+pJ4!H@MO5>kPHDDI25s1I@65myazbD$kA7b~p z!x{j|NV!Jj_niiwVbWcJ?7U-ueFPbO`kX%^iF|rtKf<+&5vhwI z+oiy(iZQKtVn2w5b-UL?^p^O5f)Vb=9XV3JVol9aIN&JXFZ*bG@G zj9RRgZL>D+wgV6PJrBF3r^C4zJ@kyB_>6)3#_0V=MAE4UnGDDD`ZPO{?KYEQmjXzy z$>NOk64x476|dPguYkV-!KHZWXU|t4(EP_h@Snx2sFA+Ck;}hFf}lAy86-J$(4D7( zK>~j&f>_%Cdhiz6Czt}^#Ba*H>JbD4TA=7ujI01ugGjlJCoMriWEZ%-V=zS=zl=TF*SZDrXq9A=9d517_*$M=q4k)QrtF{mwOFR+aau8jh!? zkf`gbz`A1*<5-85h`a0r4avHT>ru9Dz$(6jAgD4E-NRF+ z#F!`SREWg{uv}4ItHt$ZGC{-QZ?RR zFN^tO<_l_Iuvq~15Lzh~e9G2Yxcm^jH5Y2-diU#{XYpjNw=?Whm}g~62J8e6kdMPI zK72})Rb20wO*3cICcb=~C{Bt={tQrND zd~NYsiLn_xloe_kCUIgeGmS1kL_iujnfQDw^t<{rj%(oWHhFP{JO*oqlSlVG~(Bs)T~CgYRKT zNrLAGhvx-N&;yK&_4tiwd8l2VSeq>G;XDHg2?`#h_zFhJ89>t+fYS?xethS?`$ZoZ zJLqCF3=}KEX*+Jw`gHM-UElunVsSK;6Yst-TbP<{BU{Hun|fpo-j`c9+d!3saUbn| znwz+#0ZZZS=Jnon5>#;7E6xTkviu93VbDXuZJUV)De!~W$#a0#q%)3y&?-%SiW1iC zFxQ!f1N|4WznB68lJdMl(XHd>&Xi>@l(7okp!i~V+2L)GRFror<)K=`@10M}0Vdjq z_qT(l(afI+QsE`;D$p5JA=(P_x@GE9FJ62N^&-lbWn5Kic9ZmtJZ2ijORKw;JW6FT zWeU;D%CGi2{d=2si_@l79eL+PSL<~dvw@)AEJ8>+hVtT3nodh4rx@M^CueHR_pxh> zoW%L7_lxpAmKQcx7`hcIGJ2+SS-;I&Erk*ngdmSQ^ zq8=+TAR2OEE=BW!plZM)X2Xb8!w*ICpf*o>#Vh;FD|^*z(AIsURwAia!nwcj@P>50 zS}Rdh!8LIGtiA!Pfd~h7=s_zFpPztE^HaF3dyU}`^S?Y-oKp$EiH{q^ep)d4gUvwyOZ4iVQ&ZJLjXnyn@xfQMby#{1!nGr z|H--Go|hu;(8}yZX7M?K5(dT7^VP6N<&WIUKc>%OWR&9R-s1VDC>u%W-=X8ojLdXF zUx=-jq4_)LGBx?Eu^N4aTA|@cqOPzvUw_&%bMrTL_0|n zV=>wyW2`jm0fRtF0u4IDN+FEHh5_C=1&#>+w27IBP};eHwkMQ>1rV&S;kH=DT-H>G z44ML?)twDHm>`j64!tJG3j6a%98WQH5sI8Q-e#>;=d&|k*Ga4gEV+>i1Nt6dygp=a z=wbg*<)G}@1!AD~Dg|0#_wxe!H6rDSe=N>OCb0TMBN-T*K(ZSM4?_^4pn4Xy50h)+ zXI?s9p|nS+d!=HwUnfW=(W0ww_Ut7ai|N>;+KM0~crkUMSpV`ERfGBgMsao0SP5gG zcZAlQ93ebM>U^^P8vjI2QydJzk^gy?&0n>_Ee@Ho;?54_5OzqqvXcL`@b0Y71o9GA2SZYZ|fJ7Ce85p~8L2t#>` zclRaj8x%x^5>sQUG1N_?Lm8bx@>U3rLo2QL zL+&>P5oDhG1-`U~- zl32-%MzqYw?-rT9L{6;u^$Yu7y5jn)ZT=?cE3VS7z;di?yOvOSUTgvnDll@TXka~O zzms-o6Y!snlOx(tyb9sUdy^=Y88PC3#zEX?GMhrM8xSAV!2qsD7|0{E&_;B8pEmRe z>tmISBsNN}xy`x8r}8QCa*JS&yvg|iE-`{Xy}3gjAm>eXyT?8y8uSGHpMum`S_2Ob8Gj03LWcqb@oYL25;!szY zfk7c_M0afc|Ew_^|pMH{Js1kDS;hV9U-6=*{P7MRImBor=MI{WQ zf$9N_UTQgpa6Az={(FKuFCyG$>R@@jxiOBW|1d z9@1Z%ptFI)x#?>YF#Y4r*#F)H(t1|^Q$oW_u3h@a7w1jC#U!LZ9$9XfGh}d8gWrrV z$w@G1A@0&>oiT13+@Zi50%d*>?oQ5%2G%uAAUZy(1Mcyb$CTL7{_7=x7wDA%aRo|1 zjbDgA3I7;kdFM#9C3|<}XD1C%yZ(qH_WFJ6WlRf3=)o7&gaee$GIUw89+r1To@?dS ztw?q1#!`~sHD=QmCk8zc`&5^zA3tW)tJs*oG&Bn0;7Qre&~*E9&~f_x%)!PM zY7?{n(!TJr4vQ!wx$oO%b<>PdRaV3>x9E7|4@O#cgM1_i5Q_rCp+{M^rW*kw zwPm(53;Y;6hi2~UXEL-5&g+qVAATQe829SR+yl4!1M8dTPb8m6e5SvWJIoIeZpOd1 zFicir{)n+6(U6cwCUSzYnQahJKIaLgcHmpOCY;U6U)|?lA(C!4CST>vE^tAs782ct zu)6DMB}PI$(q|4fIHFJ9w)OsZ;*<~yaQjO_%SN2NAs7{??x4#;JfV zWBh{Yq6*ydb{{@z*0&g#zV|Q!3fx!?MH@D;dSe%*L>~BG)m?$Stq|guHxVH0;tRZC zN&IV1881$yOQke5&efCYT9|jT@%`^dMK?eUD@Joy`kq?x-9Anj7Lr?Df}w}9U*XBc zBSsP6y!0t(vUFu%txuu`f-u-BshSr;mFHz^F@t{eUv<;sW#>F`Sw{>~mxs=me1kS3 zip#H*MeBzIpoYmxBF*J<3$rOz$n<6(NCxLq%p$FE4Pq)4ts>Wre6Ld%$z~;}?#rx@ z_%fb&l{b^n#ZR>_ZS#0bAC@LOg(E|`M!)<9)%f*{zuVsztNM2qU$!&+^iN6ue7Z#_x6CQGZZ@wqWRz_f&mr2HJqA!QQd< z)$~pJ_Vl9?R2AyR$oCC>X}AX8)>uentqL+Tv-N{_XCc^(%&#mydcpdafQ(56E$3ZnfqkTW# zT+_-$pG7nX2}QBVd3mmvuiZ8MVI#@y_v*;q4$^~g=Fc#>{mh)w8F`vSCqx(WhI z(`LQ(YSXc8`?{p10a@jwQxie;9-pnQ(4A~Qm0zoV4pvk|S_ozl&!n`t6z$$Xr=103 zSvk3FsiE>>fPBgzt5K`6?+BZaIWoM!BDykOk9CK7)U;7TiBY#7OyGlo4`7y#pbBM#aW`ABIT&XCzj@pKf| zV+*Q8COg{~pL-e!fE?@fWTI*NPkq%U5JefQ@gg+}Ii*XS*cHx>XV(^jG{9(u1+{?i$J2cWzMyIW`Zj#ff zUTs^ai)_)`6+YKQ%J|FXnV$6ue1FNAXcXtE^v{JZg*kPMTM#-azoM+kyCD{hgXM@K z{m0nU4F1}-cC|8Dyo4Qi6F!5L}2JT)A1QPCKu-b$R4IBR>5$|S0d7}wvg4o+BQ zQ-CFP^sJ^F1@ye2*}R_!agmfm>zA-wj#?qMuwo*t6+XFfvt}cTJG+W&x<;w$R-U`y zPiIFk{=(wI>lk)e@R7cWA%z6yJ}6--(B>M%#(?DM73q+UMqU{lj@+ku zcQmAOR$b5GdIgXc%W(IS$CMy(GWL<8-?!t%MU%4HT|8J4WJ%s^)Xp~}o+|nuBYD22 zE;$l(+DiVBCg@DvDFWV>x?$LlsKbS0YYYCy$U5!AmO?*%hxP3LX(69FOs%bwTK_td z8%R~I+Ow=G2=jB*86ugvtKZ5qhU5AB_%njbEt36nT9tP%*IT#}XD?UOVN~K9%|;TB#OK$9 zF7aZY`eKkJkn3#elRZKFFL_P`g&WKQJmL_KZWG0h9E4=eFp;iizAH*Uw-`t%!P^@J zqRappcFvpBsrC@?@d-0ERS!2Nj4dsib=ue4eXNrA9`O{LU+8%01<^W8?iGG?Qu-I@ zzr&^1A_HleW1WqEsH-uv4W=F)b?|Hv_KMeT>BB`fr9GJSli|Og#f+_5MR*L^t2QkI zgziFN+TEe?E$UGUEkUW0-0_yRpq=8*@U7~1-N||CenTIhB4IVhHQfN;{GH(`tuv{N zzOsbme`JY&&@>a*b2YLSu(7uOl18=pm$keU&#keP;6I`}e;5BIp`I#ok`VCY1&~&^ z2J-JSNjcb^EjR(0Ng-8Z9q(8+tX4TMCj|w%e%H?J<~!4&L5wT=>JxN)kMSK~lJ23Perf-)QNZqFAI<#l+kj<@zX@HUm>lPu!<^Z z9BJElM|-D;gkD|eA~+R?PLt=NvSg#kQyh%~d2IG-HGlo7u)PeZxwNSInIWqEU>_Ds z70?oXVoxhhXf+X#1M_R_hN-Yz+KMffwiGJ$;KGfac{Le&Hvdl>l>0a(6<; zP?{YhAe0T}*xo`vC(qJ-LLjUb6I;A%C};rf2rmjQmaDH6kjAs1kZ1WmBT$Zkg6^9s z3r=N5ul2NVX{OGD;v#t(7q$>>dKWZ;=;*99`V5s!p2d(*EfiJH18rTJ&ve9sY4KzSb4&v`s-s@{7x{IB6 zRlkfvb@l+4ybqL&PWHhVrdJp6#P!T-gT!5I1)i}4tTFVNhXIZ>nnf=?w%Vm4FIoev zPuh7+uu+(F@mcPWwQjy6-}6^<^4`N&Wb_V*$MWdTtk7N2`cr!=G@}~#Z!opN_^p1} z&~0ZdFn`eA?`t;QhoU1ms&8B@eBW~^)|dgIXhj7D#xaN(BllCIu6mCiFsLkUJQkf8 zvOiUA2r>kwM!&#c>chi&|DG~WUlo)GZoGf$3RQwKWGh`}0_>#|zB3xpo!#;5{byJj zN`+q34aROlu6^q6Sga2wx!o5VRj!9YXA1>U{@_q`5Xag8_poMBgUTx_(3pPk8M~l_ z+#r(nKL2o)2J0MtH$IdzBc{Jk;~|1>n`P7^1Q|Pyk(a`xv`ios{1hazMAS+cj_wVL zNvI2)GUgs`54;1-+2Qf;Qm|ayf++Lr+~xQmQTcy5Ir)E=f`2=?w4Sq>iQbo!6A74_ zSsIFcbyNQO_kT)6Etz#=WN+!c6<2X*uMuRA4JUKHc%ICYN^#{b@(Hm%^ZcnQF46jG>m*)Cx5pjl_Hy={`0=V zY}(dw+8JDZtqz(rX<2Jo*WsA2O3Z7#rtVL1E6E!TZiN0uRf(TCl;UD_$^XaPdxyi> zzU`uk-g~dnd+!Wlv>-YW1VN(L=$&ZMqxUihqeX;Kq6N{SGitO^M;J!$EP3CxfBXH` z-ru+OZ|!3rYtMZ=Gq>9x#_=4-bw1~LUDtWZ++`P4@4C#)t+{m9U65FRxlu$YIAx;= zW7}FE4zmR5Yj1fu@<~CC1_u1zGZG7Jt4>Tj16g_enB(;Q<+Q#*oaD9Go&7|6LgaWb zeg{WlUTD#3nRGZ$FT95KtPB>ufdMscg>S^ml)bLmkt8%yZjR!_5N#+j>@gPQX)b4q zs?D#-)>9E56T~NA+c>gj(cC-3)nT*T!RwHg+ z!zHxOJ#1x2MQ|PKcr zkY7E6kzIwKUbVF0&|_Cj+%N^UI0SyI(yJ@ct3%Cf4*sw?1m~T-1HEdMKg0n|c$>3y z7R5EW1z;bw7m%ctKTKx9HDoi84`)WGx2_N)+AcZTOv5~rJKq-xK_{JE0FfS|iTpWF z^Y)8#Pah_xq0~fny;7i5RT&SbLM0i$8gf&6b^eGZdk^$wKk{kn%Qt};XMg%9 z`So8`E%N`TVd;-F^ydFAHW`?D=o^yVy-3+&EiZ36K|#kwS4c^n@GT2RSp( zysbH{3A+0$HpO>O3We4QUJ3DMrb?T4b5*qSW*Pw{`8KKZGfNxVE3Hv%#oEexzDv<_ zZua;iN5hXQTJ2mQO3{2>Pp$f>1R19%U3Tp;br9qhd&qM=)-nyOeHl$ z`Gm#P$R0<&L+7THuIwXX!z_S9_v0}vP{?sp2 znZ$*^#cA7vOS?J4$P-)Tr+Y;1u<7R4*NpYp$8Cn>T74#UnWZbBe9-#WiqFk99>4IS zM>bQ^$t!=4i@DgUKt>tU-NbZV>6*TR-sU`xNZd-t=WlphwTNT> zRlz8Y$IsRATEY~!mwfcIHYJbCi#*6%7XPLfV%(_sbU(mhvU85FB{0OE(>BLbqiPSN z-cqq6L+QVN2`ia&r|_Uz78Fccj~J~9w|xEBNVLs4ou5Oq`Ug3Fjm1O65-icVXdbyc zFI4z^Bn4^ktuNp;khOh8UyDJrw{c>&!+z-C2fwyx%fVXnaE8LXy7Ml=(^cMDuD6w( zXAE_LaY?Nyk0d;`Tw?jnJqvAw<((#8=oefCCDx@I(j&EfV-?nQhq1H@+0@#N$85hY zWIk|6T@g9T*A)W%X4)`?gTyX|eer`uIuf7aJ3ly%baj1Kq_R<}Vrq!`A~g_2)Ea#N zHYGT|BI|zCp7f|aS}-V7>xu~Vg!pW-|HA~wv+;6(jl^7%YvoEbi{Rr=YB!~#G0^e` zNyp$%3128y^$Qj-wnFAeUQ5}Iu0#sBc_|ck#5FRyMMW0MuSlPWW{!8nCSMc^va8Na zBuo9w7?+kds*5`}Ys0NHd--BM$QIGL@;pVos@nR->S-Ypu<-aKB&_Fz?fJLC&A>>Z zE1GRP^3)T2;S)aoNuR7w2Zk~1JtEW&@3E1G-x#&4-ksIab&FKawWy$eaFtr-+(Xl_ z-+gVj6rzAz&9vG%{hl;U1!^KT73HuH#Y)Q2RaKuFfq!h&5_F=;R1Jh_DgX){bop zP9BV=gkCXQ@p?6$TI1-#|8C28A7Erb@DOR#{>w=7k6N?;_yF|xBTv2wZlM0G-+iLz zC!Rsd&M!_wZFp47zl61{P*kW$tgWrAsFA3Gnpj_hoZ|*kN-(oLcfZBAe>Ji&-EGj2 znN(=4OR!0x2c~}X3WxB_mn4aqW_sJ_@-1a}BWAoDNw4ll+rRn0OuR&77LG|tZ_C^t zw|5?}U*4FG$!RN@{@@~%eO3!T@k;N2G0C*AG11=EM|1BOGIZ>Kgs&)SJ4VWDD^3I$ zxIrO?JEtTj3M;xhD_LtReiwx4%d5uA8K~YJyC8?F0`>bH(E3RbL+~odR^s+! z^gXOlehn6~bP{r6O&AI10JQCZTH$;QE|u>A4Qg0;ZDu@9Y~B26BrqbaYN`Q#gG{%U zh+J&h;a`qy#Y%R7Y8_>JY)Fi-VcPL47)g2&k(Ob#XB;;S-L#mdI*!H=`YmEiu~mt_ zvtFINN*2mBBe+WF2gx`+F5{l@14pM%v;6jZIR>Tmof}XL=N4DMSjIlo`rsoT04J&s zdA3-F)5%REE6Uqz*~U&tPwrJ|cQ!6W{5qb3p%GkcNZwSnMxc;>3$qVubL1wWKhWHX zapNu^Dn0G9@-OD0(PBR>Eh0zn-&B(&##SZVjd{b$K)a8iU_BEt24p;sw65rZ*_rr6 zv_g`^&GXvX2j+=ml=WKC=Wi3D(YeeH-OY52Em+IW%ga?yf9Uv%#^(R*xS)F7^Qhm| zLtjl(`MaW~1@DqHZK2B&W5KlbElfXI&Bms@C_UBRK_^Meb5te8nBn%WBNe6(o3WD= zpZ9-#QYx3R@GxHUlYX+DV-(3F=J%cEZDgr|H3My;rDJ8@!l+j#@lRYwH%FD21Iq+b zHmtXwOM?3KRv%n+ix%OSREhM-bIo#be#|M)-m8b{38g>SKy$604{`8N9&>}q-XRix zPkmqTDD!!x6F{8&&KpBN=9!Z)%Nw~2o`Mh0RjgokiN5UN>dXw7iksQa$7*?V%`Klj8t+F7VtddME8J2T ze|hpG(TD5y40oz6WOsMjNwXygQ)t%@a)YeS?l+$MK9|oL=V1N<-TEZUVS&p`K;N4p z<@)laWX)i&`2IjMkwI=i$^qmzrznp4mu86!^}Io!Rvq6m1s9Dbk$FftDbm7FLiDj_ z4v|{om$ueDOyb>&%C#|ERJGtowZ!$XD34X~Q+KC3!9N?*_ zlw=)orP)QW%!j3AzHT47e4Tgv=@X9PYhsaC38d-;9GrP5-x~AUXNUbIu){H*5Ba^F%Pz93v$M= z%G3j4nQYCayRq7|o}UiEI~`|60LTup?- zplQRl$^e;yEGOB)-p__93T6yJ6uN~Q#Z|E~==7bR-n;S0Xc(yYq~U(uF{v!VHiS1CWStX*54)BM1 zc%OM6x!45P*(1qLEc+9llPa29_S+2hZ%R$vXAZ^D)E%aKQ$O0X350%(fKDDG#XnW@i0;$G1=#8pskCgxMEOo?P8Jc^X7}sXZ?*n6ue>5lbaxYrPS?xc-6oupva1F07F24N z+1jkdq{)r$Y1`Y)>_=b5iHGC+1#wRmZorsI$JVf4km?H6Fv%+Rx-;1L`o6?_!_-!&etIY4E(!-%;Ulc_LAvCx&3F>_R-o>78~S)vtvTjwZ%^OHr>CRw`{HAF@N|1T>~YUi z)T7jzVGAnUWvc|V=ISq3t-Ptzcg)EHKg4f5Vkt%IJ{v5~34NQo z%WLdH{_b$f?RxBm#ZQ|30lwZx(W+I(w8zu8cwfIQ)drPNPA+ojWFzEym;QT4QuafR zA4-UqsFw5=HuKjBR_E^cC@dL5%jqcU&2&0VTvj2gOwnTsqVn$H~7Y@qV0S%;HehIpoU9|3zosFV1miPf5H#a=+&wbeUa6hU(IgzKMFRdA!yCrUzZf{ZySR1qt?hT}hV$bv z4TgZkhcQ7&8NMJR@S9SyHM%Ly20!vEGU-=i?Z^OGhM~i~09F*9#f! zoESx?abaguW3PkLuHd|<8t99JOe`BEXl#S%rN-*IG_D3=S7iB7B)^NMjHMNEzNqdH zk4quD-TgUUXtjCZWvL+_8)iFfOpi^rmZAqIE<1A@U{($pfP)e%i^j>%h724^stjgA z!d{I4nuhf+*EhNhgj7w23@h=tDF+f(c#L5R(b_F48xNq^Q4I_LqpVwEy^C;Qg3|bh<}hu& zz)>8LPLq0^t_4ij_r$7vXu=>xW>6XU;NVEc9cC6Wy!g$cQ%YHR?FU}a@>w0zS*3c> z`AD5ZOSp>aA?X9hA z8qJY0oh7>WFuf^24bHqzZP@l_In^pu$1Qt&f}rX}$Bh%N%+ZB;Cgm3*j%=<;%-*AV z)Xj%52u2(2_bV;`=jv_b2cqBGlEPHN*k?7OzlI01+|t~Bi~m;hakDzjr7A7vK3#|= zFm-lC%+DD$+R-OW@yoU=O2F>>pZW%4Gv*--;(cwF1>)jk`aQ~nzlYA^(5pKrpB{u` zFKhGcpw8unGp%5X1pct{VoSSYc$i-6Dr~%&mu&fE&#tm-pM8-GH8 zw?0~cHTTS`ygK3MD1v_>7CdfC1nyuE^N}X-ViGkR5{k0rO-46 z^PnA|bSXHO;@592(g2ln`l@|cmd*UfD^+-1E zb^H5Qr_^>ZspiGw@oq!p6|;^UZrn`^bOA4Yb(lqLqp!xrpDq~oW68VuN%Vx8^_B3DEZhM<_{DPqEV;#!x3^S9O z&)9dZq?i0;&05^J!_;ygGhrHRo0Q)-@zJ0fQsTAs%V3cew{R;8rk~>XXgAh%66tj# zGC1u!L#uZ@L;m_dmF`fl6o=#6XrX~C9+BP&2K(kktrlNC=1+QCq=Kh03<-WKQyYau zK;HXN-rdbjjw-TuzNKbt=jf+iY|e9!Qh&wnPhK5F+PV^@W|2B3W?4ur9{(c6Izu=v zQh10r#7Y)m7posWX&|Ng)(Gr@1~A|sFVIK{3(ReMEO5#HZs6SGO?4duSV#=hsF9(W ziJE1>7TO{9sOh}v$?`WM*Y#{>D&e>%aUEYfdr#siT!hm|f01of_Ez!g_+)@azN%gd zQC(q^EayJ+cAfACJJx?;%0NKb$$k?N48q%sCW~6NyX+A~4J>I4>B9&0Su3`}oz&Ee zlFnt*Ul-8El1KQJm(Wj9x>`!*}hz6u7YA z7~VUJkyV`=nTh$GrnIBu+!e{zgR2@uJx zY5bba2e*T{SRDYC;_^=L8|d4O8*?SYW2HR_tH95zF@EjZrGm>T>Ixd;@O`~l?tPS` zImOl7y~8W`7mc5)Zaxk1mpSScA*w}h=^0>pJx}637uy^@V9S`vEaw}r&$BB%2q5OqLcN%$yEgN2b->5lnhr{~Z>$P2PdA{Ih2<`D7$ z0fF2m`M8|^fsi`Uqt{GFJWubg_*g7TcG-{G%LELV@C{1B`b9-mx&3|E%HG5_CMjxCFgJ%FpH5F^*FLv zuqRSb-UMSS3jLUWD&sNBq081HhX^gl)9hJp6yX}!_32@*>zn{Lr3bHWKQ?I+SX_Zz zoOXJCZ=*>HJXmHjQ~R`P%rDjt`(+y%uemul_aq1<`C&X4^R3rJgfKum8kZ!t#wsS_ zNP>NGg+Dzfk&M|;AT{UiGp8Qb3Pa?xs*I=pT}oHXL4!^?-q~hR*EsZ>wU^02@D&|r z6Z)o#-w-0ZgV{8*Q$k^?c__b^yTr@bFEVj(hHZRJu^gGmjEF;sQ!QzWHL~w|V9nNS zzW^=JS`<{ltB!_JjRdUUW>$rKSFg*uRGt6+HtUkc?gF(s9Kzs<6-diDTLImETGmq7 z*=qE9(87%nX{4yNz3cIAm)7%{%Vn?40!BH`xY@hW9WSR}1NOhPTuf!SuL+LkrR_=( zE;w`2_PI523(iY=m5*P3k9j|oUxa#YqT|03m+xKA;rVRH=FPrf0MPvHoBc0u_FuBr z_gzdlT zq5DS*!E;MbdlwbOw##6XqwTaYC%i8qbU>Y06k9&oJ+R6Q_W+ zB3l#F{?jp+e$~L;GKob;eH_opaHX6B?(TAN8fS@Npr*D))f{fLN8a1JaiR3$Zr}Op zTEVrx*x5wKB`F7bLRasgV=?twtOBCZv4PbXO{t3P$`MG~xIOp#PVg$E%7Dzr%B-rS zINWyDPzcnTFtFy6n1!uYS83HD-1u~oL`x9=vhEp|tO-|cbnJj?F!v{6?sDBX`65w$ zlfF66QtgB_K^3A2Wm9-LYV~&FBcK)og=4$Ne5JiVNbAt;sQJp%8)9EfnV6{V#x&(R zvp5%zG(;w=cx1ON{lT6ajRpFfUCF`E=wI;cwHErR%`6b6Q zT0eFfD_jmNP^Yl*py{QucXIL)q;Q{8i& zTlvyy8PanXb&G#ZdnWOJ9HctoJ}YvV85`gHG%Fx`cEHDf|2a4jip=C`X*Xy!JKZ)p zeW}@Lap`ladUxMBbCYv-j&S_eIqow#SyUMmUQj9MZIJ!Syyq=Nrc>p&ciCjDrjdu2 zFJu)iP51-c?OPUFe`73KJE<3Sr_B1-N9#nZFMp^c|Iie*KwH#^4_(HBID^jE!OoZv z2}S1sFyawpM<)OmYV#CPv)I7`UB-aq7m1TP$S68fK)u5jKI{C#cW6~~CIlm}A>LpF zI%Hnw7p=qfQ)de>0uyoz6329Kjb3;Krhf!M1)ULq>CqrQK*VcsJFY|YQ^b;v44DJH zPA(?oQpfZWL<>xh0qFrX5;>UZ$e=hJgqcV{6C+Frq5hyoEQfgd~`r5JFny%?y=8fut6l>4Nj| zAV~@cGH?)`LpcyZsw0E%P#CeWqjOCL9SvP52YItYh$H9>A8dvRaRnm$!9lnV5>FAobXtiWR>BrEb*}lLE>R2TMc%m3 z4nl}2=nNHH6R|)D@}@oLNGkG{fd=D2WQxv6!AsbXLLh=4e2eGcqlnnnX~lHt3|(l~ zxn_gzhcDDVv^7D4@gbN+XS85hEXWEF!34e~a3EAfoa+RjIfR5Rl;~WuKpDap3X9Gp zp?7!?j-oS4uq-yD6Numf-{L!HDKe(^-?v9U3#+gH|P3{SG=lfF0=Vt(3e=pR6=T*3;e-{=t#B>>#X155)m@IR6!n{9|J6 z-#GG57;*kMrtwge-QQV~>$p|sXsH`go~*l zANs+UN=u@J@5BzT+*zkfe=!KZYnKQ;6)c>O(cvYMSOMejWizNnh*c*rjy z7!)fQ*>#`rmlky0&Nq~d{QUBz`^({&PK536r@U(hilkCkBJJ-QDkx6e$;?tJy#ieC zSIPH!ABpF)p)!y_6_Sf>VlC5MUKfj{4JxS;%;1|Th}FxMyy6*6jH^|hn<1^fIi75L zjgyq%&VruVNAL;?FJQ2}82PJ$&R<0At%p+% zU^YlDfx6K$0`QxQ$=M|3rAE|v%1ahCmtU~C{W+K6`#-Nt*87x(hzM3SpvHq;#oura zz24uNXP%x)l|A^iJr& zuC=~Nqz{o`pSg3^B20_nS}r4NX1#DFyj1WR-;v#v1$$XEQ|v9t5`$6IUObtRO^OIx zK1*`UvVpDtSCJ`1rxh9Ur)yLKDzV$&f5f+yNGh{w~ zdhParvism#e}EHuaO@ zuruSQps~iJUZ+yFwxiQ5QWK3Vo50Ia_ORn0DYaX`{G9$nfcbR#jEQ}D(gwb7RMUIRO%R3sz^+X800(X@KtI~ z7(`pe+;>7tuArf7oCP$x)(*fCuoR?J$w9fM0-sG+7*bB~7p$v;ME@YW%%{|7e?9g~ zu*9a0Jk8U+a6FKu==(W*ONodjB5%ciYm?O}7-D(XeG_?!drY|{Fl_Pv>Y(cW78Wul z81nY+=S})0&#}=~?XX35r||#ez?yCLev`8qFId1|>GRb-XESe`*-0~53rBz9=(`)j zPK%4FA&U^7YPkF5m__7RG4eXS|L%5v*1upj__J~dOX!xF4J;PlbU=fyq%|CQ+Fgz@X(2$%SAY^)_T zP%g9QL$BN;P%eunZiGwBIN{Mn4Aw0Xun7o{CjKS{lz%_&O!SQp$iZ|{f|VaXjv)Fb z3zUx)@)O3}iN6s7x1V@gMC?b8-xB*j0un006|iKfK+#W5 zbRrm{#(RkU(SS)xa9u1}8c_d}la~<;(c|mH{wP3gCAb=vEH$Y7$%#QkLDcvZu|EcI zObKp`B})t1esZFZB})k^RDt_p-QoeqRN=P7{*QqIN^oVYb}CTjlM@fDb}~?*D*P?h zEecRT6;4SkO$o99!pX62g@Lt7a6_zi8jytoTny`$8(6Ch_rhvt09h!)@v&~Dfv#_I zm!HBlv2NLct}5^*B7a<9XTrEC@fCfhV!V*$#4_Rz1(fvUBoix$ z4AcpPTVvgd0U1@{u0&U8z>v6c4&p1B2)W4d6_%5SUY^IGu_q@sAE# z@Q+y#U7-N)W5+3puOuQmBE~x%t2aqwAtqxKQ&%$}{A#;A!-OWLZ^IO`n~f1$3p!?& z8o$+P%c`8Y%&awbO-xm0f4MEaX7MaZfNC~YyEJZk#_`pfI;XkRlY2(jfc?(=m+X0V z_)U$EoynJ+UB_h`EB7H17;@Xn=<-cwcX|B~EYiVpX*oxX<>Sq}2i(EL(p5UURd{$L zh{FAMa7g4o;!uczz878e;lbNNS0WG!m$5-~4;PSGP)vkLSQlvW259$YEA%nToE;vs zh=>@A$e&jaWA?)+xQgWL?Cd{R&R_2j8{M&`zQNFv`;Af5UrTR)QM;Od22}(n=y5A} z5xk(7=F(9{tHj0g()!x7gDj=`ee}{Xrsih`+>MRETL$3mlXBo)F=CvSwdpRCr>ti7 z4v($kGfFE+`X#+qfX!Ruf~9=tA)d`=&C}_wJR@~2^jpsN3WsDe+<4Q2zpI~Dd#AIR zI5R}ox87spy>&PA$0J`j%El*ur^If$)vTB+3PB=6LA4Hs($tda01j^o>yOQ}chopn7SiQ$>wp*Q#)@;dL z>1Hw9pa2FcpSL&aZ+TA(hz4d~AH)ddc}C)_nWPr>0p~>c@PMG9jFG*D*#=N+JoE5vqh8;$PrM~|q6r{((E~DLqI*y?~ywV=kxfEkTDc2s?`IB=) zzW4awq*CmvFn|$pZXy2^bBBn&jKwo8al&0%fn$eEEW49*O_uaC)&U6l8TSAZp%Z}f z$?f+uVrVvhaomnxY_Z*13tN;GSK=C1*f%|i-wLu7l&58H)IoC4%qv}*Px=_fT&Wn7 zPkxrs(EwXS)1oHaewLtcms)Xy^xo-7wG1j68fdb7;KO=wBYNVbF!%lodc|RTk~5o= z(%gqH#Fi}GDiH}-w8Y}f|HHu<)1Km7^cO-)#%{TYAgpVmfAhc@>lcwX(;jdx@(Zpd zWjB9>8CL7R4xI0nvO+ZWfc3Z|{GzSn|JlZ~0h&!2cVBgIy`vhank&F}0J#|ZNU?nz zplzzUDQ}yHu>CZRXymu;cyKAMv50B7x(hKIJzE&P3EXN=j=Okkv8E^;N?(C{*^zpX z+)?N}Gp`38E-?bRqu8)p*%%GC(TKEK+V~9bg=Npaw$UDLqYw$O-15qrrxi&R6rmQW z?H?v+pY;!kwzXjkOdY;^WNx#%IpS;IJ7kI!CKYh)9SZaH zqctb!9^!2q?i>1bD2yq9xxPu%)`lwJad@QFMi-mzW4S4q*G9_`yY7WZP4IarBA`VK}8+xsd*wi@pBQe0M_t6@MZqy7N ziP1xcNPNJnuxOq`H*$uKnCMgA3krtMeLYQwZukrx;n9x9v#q|(1cWO+JrBQ;ZjqiIw%;3`9lXU1N!VvsE+7yY@2Q0=$7s6oTfEzl(rga#lZ!;>P&l-#$ za6>}qvko)zZN?<*?CWXwy})M>UxPLIHWLzd_VnEPUdS>qeD7gIBA+naeTa@mA~^tn z_-Ofc7%|`moiJ$)R_p7FM;Ox6v+jE#!%*&#aAa?3%e}(YhXszprZUeD>el7|z(LIH)#AW|eL~j1 z#SlgR2?zNz0fB!BjR&)GjP-xf5@^ZLKu;-KT?QVAtxhE+&$*wj(PM5j>-skM!8dP^ zPfg>Q-GiB)MhYv_!_Nprc{`Ss-oJQ>1GRSSR9qsvlt+7*by)#dzvI@meqwViEOPxtK;l&*rbKfI z%-`DRS{rN21APDEmlW56!Rm|l@Am8w2UPbpvF!127cPdv>9@8f-)Q&_GWG@$P%zgS5&Mh>MwCImd)JJ zUS;F~4Jz0m#WT>11zk+_(nM&Cv_1)&zQk`WSun?GF`0VFGBo;152K|*{%vw52F6|I zkor4&EPR&6ClAhi2`v9ifV>i>@peqYZcZ`;1$zNP%hpJv9{s^bmX1I|Z&{huE6 zsTUlufZ-mi2Ry2ugUzm7xxAOBld8^n{P?)swRSx2?{7cNwX4h3ul3jZw4Oj}ee%C{ z>L0y4bW96UneSJ>-@V@r4l4;3Psk=1`UQW~q(7*(vr!zJrp7??bUsb-k1G2KCYqu$ z^^!)L)LvMVZ?~>Ch(GM}P4Lq(k-L>%CUy)6ZOK_acnJ-107SfmcF;m{i_c`iOL&k2 zWyBVE2?esQb1er=R7G6twz4_Mhc49U$UKIamUz=bUE&r9iyve%m!t)H-^FMh8Da>d z3L+7Fi{RsfG z<4|7gP2(V=+bZEueyli;2{8jNQ9`ak-WU$H#f`L(hp)u=ps;yUIM|jnQbIg*0-iV! z0uisE4Dkz!Isu%2)HWDc76qbOe8vf7NLaAe3E*`|QbZhrWgkO0iqBY~1@Q~|Isx2& z#I_x1(E$n(i;OJY;^;~9ps}IJan%8papRY0)ND}U}DI2$(aVY{Sm}M1rZ5u z$AVCnoRN5%$Bxz(9SeH~ljmoa96Q3>Q1UHQw*j8PsQE_4$GPw}oP48_V;aw3-2B<% z<6rPLg8bQ%V+_w=%>3htOEb^q52FWlWt#9CIcZmwZNhOsTa;PbxY-hX<17hdkZ3hTpJAGpcSEj$fil-^Y(~Ok7fW%0-TL z79ZPt%7u^GPFzZO%0-WMmK^(e-l66T6df1B1BvtRf!iAJ8wqI(mFPaOI*jq61EM;==_U6GEEoDfDDW*Xom(Yo7aW=mi6L6ReBP~)jN3hjrN?oUv(%pY6f2?4Q~ z`lx_-Oh2fs;~#cwO|!{FNOGo8r`qE9-I9Oy`=f3b-F2d1li-Z+{)Lc95sXrxu~ ztpe^1BBN3L!N8`Gi}la>=H-1(+JSn$(*W>+m(k-BEXBXWlnJ&MG+$0c*|ozW*U+BvlHFDrf7 z)KW3;*EQ?f99>(8y-2QEO#y*6hw_AnCa`eps)+W(+rjW?JXz+2$36(ERwsJ@q@;EZd8n4mk92+XkuvohMGt#9L*0)QI{4FiA0#u%3!L78lZ&BBad0scpoTrQm_F`9k_)O{ zW&f8<79&3OVnIvBjuP@m9lK#EphA=r{0&E+w4_x6jb#4S24k57I34hgy8br6UjhE_&q90E zQL;m2)seMB1?DK)QSf7yDo{4Ew(jC*kC9wQL7&m%jy{+pprfE`7A=r`&5^ky7HJq? zt9FqSUrQ3G*)?krczGy>Z}I8EpTc75@RY8@X0-~>V)G&=rWPk~qY3Z^uxESj*mMk4-LZwNG%{2{@4~wfzz;|ZX+s-(+huU z3-JybH`l>$_fod|k7&7bdZ_5{D2x3s+bbwT0_? z6}rX2s-slLi&aOqju)^ha*KmCN3o8XRY$JMGN$8ygsMxgVLS@yv8q}q{-h4-~J z7Yk9fh>NR77BWZ(sYNStI;z$?5Yacw5E%5Kw*BG?%iD(lBcIDwSGtQhVAoy zQwaW?dM4iI+Z*PVmDb_TzdEDIZTy&69(o3<|I40%|1l>b{vRUEzf$Y{L7gKua}+~r z<@HlL{R4HMAU{kTbH%=?4gbllFMQrIUs|$POZoUmejiC<(bGeeiMfSr4h5uT8Cwxq5OwEO+RIbjS>m1`nn#Hdzt|Vj#zcOD?dm^}isrj|#MhO? zyT_Mfizc&AyvYIT+tX;4Q;VkBOgM3uw}=)}j04va>B$?iGRB2Xw0P{u4JRGeT>I-X zW+wa>p3+vtickEl$vc7$`xGX3J*fS!^Q9VBrOjt?-Rd=Z9%Sk;`v?g{|ceUF1 zyU}4@B<9Aj)3j#}TDoM4d|VkOQ_7w~WS)xFTFP&fimsgouZ;OCx{?ImKMG#`I&cniX%stQNmBTAEOFHj-S1=o9%YkfT0LX;fQX-!}9;5v(LJn|68xuvgVFRYR zL{I@DUG+S^HeuT%tJ(MkOW*5de3wxQw2*D&fPm0#=hb;qfGg&h`RY6^z~g&8q3_mv zTMOhKW`R$rZ3wcB6o47JZMG^!1USGLQ&`= zq1!{NEkpo|$79N?m)yQDLbn}PTc`jQm}6|KEo6Yqux;Aa7COKR+8Ft23kkp|Y}<6z z7`wnVeA@vT7~NSWwtC6$`x$-g{JRIeZwFz)Zr3p?a`90C}>ie-ZauKbd zFm&4nc|!(h3f;C{Z6OE9V~#nmUZVTDV2%lNd0_emqZi0@9Xlcy(F;~Ww_T7o6oB*4 zZJ*T^NA2dk56`_J<-f^m66N!e1A8W zG4F`5tvyI1z5kXpBJoe4$e+Rgy9R4z>^ArTC~O$i%hx^C3l>hvzCtqUUN*7K*s1L| zI{t+dHJ=`^;SV%utC;|S|L25(ha>+LnXipf`KkHmqapXV2jSQALHVtRCqJkAve2d^ ze@Z?N$C?uC7X4aglQO%F&u;2r>@iE^Q}=7m3bjYiJe^{$H$#fuGQyxLxsEi1Me`~K!sy@X{)bYL1Or?I+$%^Lcmj- z1pYz!qkvE`f)L&DoUEToPMUm40<(qv)=~RSKaanZC628R^6Z&s?J`hwJj*F>9BAy@ z(yJ8H4Z2Ydd!?NtaYARsBWDMMj}|99ByEGmv}1?H@qVg8ntGs))3C04QpO)=3&fq=ZBVbXdJ zbyjL=&$)hJOeRc%F+Zio34=>sO#?M|MJRVew&EQyg9zz%l@6neSfz%+fv9=AbbAnXH!KW z;=Z-rpn1BpP}i&9u+VGzVLX<_tylU%`_=4vV3J42_NB#G`S0~eY_T#~DvPH#vajof z_`u|53R(`Phxd&BwrO#RxtQHX$~kCxUTaRYdCqb52)9PrQSa~bJnoGwquy&*qmlvS zquyQfN_m>y^HuKR)V8%<^JIDL6t=BvPTZs3J@fmLxl#4AFek!1L`?mTWPt4GH@7p4 zypiwowC;_RqstNX?e2|)qc&@MBa*q1^+E29jHAo%>*pl{ct+3q=YP3*KN?+5tVea9 zNvM~S%#Ew}licl^S7>WLa`zS-^>_Ei8eI;nN0*c#vkj8m?Vq=l4B!~WaBC#84VN^H zsPB~wpd8Iu-CL5Bp|d^cn%B!~r?gdF-3yYGA+bH^pVyVVel(icH;?J=jW;S6QE%;j zW|>DHU7xhN=bINqX3Md$AGIE!j$H+xdOoO!As-biZ%D*3Fx6G&rF?!2OIiZz;NdWo<7w@0P%paCPro zGJwc7fV850EzAW_j!HE zYmU)^zWL6E{9a>6NJ$MSzech3pbb?k{_hJg#Xotf+Rf6c@Y&~VyB zdr&v9{w;Mw@}E#rGlQF@xk>Z=@O;U!ld+F#oj;SQ$!0vhwTtQLBYm0z%c-5Vm>~@M5nzg@BBKZ`U=Bros zF^!LP)8Li5Ala~nVFh)exMYy8zn&mRg^`P(z{g+3s{!8rcCYo$+ZJEjy^f10;J#~= zGJc%CX5Xb#q;dB#{;5mSNxaim+Vi2o=VSZX1+;h}@)A>p5}cCHKRq|$l($zJ{aD&? z()OD3a*@EGE$;@9K8Jf=ttUzJb9m6I5QexzNE*aOqJ&jjBBI}x5hmar^*3q4ONz7Y zsz|0~Ipifo#+j((qDVrP?5%vQC)OzSxxA9Ytu9(xWKmd-aJJM858X$*?*m_(!F~u$ z$F#sMBOPWdTJ=tP2SR~239)$bwmR?0Y$_eP1i89NVxE(y+liADaI*^~PxP`izOL8p zzZ|8L=&-`h7SSFy)pI9CZA0>J$G|uDq7WCw#NjW~l@bC_J^xeQy3XIo87%a3*c*^`o zf^;l`Bqf40)`Ar4f()dB#HoVR`hw(Bg7hMSr1gTd9)gs|b&qhnuuu8A^mutBn>sdM zh8caqsj92`ni|~?{V3=xS+WtRLKvDlJP8(vDT7_q>?fE zk_jS`Jjp}->p94qWs;DM^?ZH7px~ePnV%?w+wPAJEsmNrjPJYILgWkL=+8UvBl=Zb zP?LFDFq>bb?J8B4uz!Av^83cI7B;~!v?l55e(uh|Q-afdPPlvda?4tlarg3fDB>zb zhY^2*N^=5_Z=9sYjeMb4_OlAdt8hnm`p>F9i=pPt#1b%@#rK|Xm_x&`)?VN#5V-UR zZmfGRhRL{7?)S+yQ^M}2ZhapSt}y}PRgs(w4{0tG?KLhyg6(&YALqOUJ;yKODUpOo zy5shU%sP_VHLc7fixCUKJ}f1&B;;=f2#5LRCE-#B~A*vPhJN!ZNH%*=L~nHk&6%*<@JnVGrG z%*@Qp%*@&VQp$;ad1UIY%QmhDZ?0`)Z zxVwA!^78AW`vOzXJI#y!lX3Oxk1;MLu6Oz4=OX(b&osK&EoD`h1B_9CB&WJ#wtu-! z-SngCV=0ZfdSaOdpO$jo3hNIxcuP4_t;O^e)_gWOOF5QmOL6PW#Y~JQijbA2BDV6T z67*_IIqRANHd_lhZLP)Fm8McQe2eMjrV`TXb5U#V#Y}4pIh^YD)D@R}w$=H}nx+#k zt;LuXmr^!9i)r|#63XgxF>9~IOk7JjLM><1>T?-uyArk!i)s3%5`k)|Qa0=+ilh~j z`Anc{Y(Z;?g-oF)3Q22-#Y}BWIreI7VQb+gim(;9Vz$=#OdTyi^vcnErjHgNdu2=B zT6`{($6{Ji%bBtoTg>{VfUVGSdfUYeE~hCCI$er0zFsGQyfIOQL z<$ff}$q+RsC;%j#PYt@5!Q^-b&&U=7;ubP2T~3&}0bj^b-rQ_1gYs-jmiv(`Cqv9U zw*b(1KDFp#hLGd=b;z_B@OU=m!~IB?quFQsjF+Q%_Im7@*)~Q?7u8Lrc_20ks~1i8 zY-F0TDyjFBIp)NusrQgM3BxF+_w$=+@pFpmih^GAXTt`|5!+-U8@r%ht5CxV#3XJi z{Usfl{f45ZefvY|@i+u7gZ(Ddx&`SmJ}!BdO;eY(u}Nc0%8O05P5u2tk6e5;yApq$ zRKqmIWEi_x%cjcfSjjj-76aiX+`1*;7&VK$)27A8%GsoKI%U?T=c*q3p`AXtyG636 zj=W(ubt0`r_UES4>x9}Eu(w!Gi>lL{+9XGdIKsNt>&nWwq4pODhu|{8J@(!tldx@k zH_$#xw@o3m&BANFen`5GM{QB|YteODaGPXok&s{4dtLrHZn??WyAI4{40-I%LuP(m z_iiYma#dD=ubhXkJ}Y0gD_^lr?dqllyN*q7W8NH&8so%IfANlUosHof!Zspi>4;ff z&mb<-ra^x$ZAGoFCDYlUHIlO0P!pKyoYK@4wK%DxTD@0cDW)z$+peXxK5U&`S*@z0 zTYZ7@?4+(x*$$z#&9;D36S3klt~JTFN~;q&(y1cnP~F^OUFfRAQ+>&OmQqtl(J_;G zw9u4$S@5i@ZoAiEDY7bp+n&3z_Pjz-6UXlA%eMZ!Xjaq9?vA}NU}`DDA+EfwVS7Ac znKhQ>upY><`Di~Nn-ZVc_42?@;5n20`M19GNd$rV(^u&%gZuw7uf+B5rL%k4Qzcmy z3*zpy`?fBe2o5AMJ)s;J#~3eeG+6{sNjYmOe$EEpV1PNj-jHc(Np^b5cNcXSebiUT zad-Ns@9vB5?xL3&ghKAzr%lhJ@s0awj(2bS><7PmUbO%a5$d>-BAGZ5H3&V}{yIbJ zWE!bOni=5<)_z?(Z;Oy#+U)r?0XL&_n~W`}uU=YblebrXU*ajXBaG2CLu;eIsb|8X z_8t|Du|n6j@)Z^B7YQBk7%CrSUsfp`Z{e=KQNer6-Z^;cq`$}%Ajp@(FSONbjv>mu zJ)Da&gN@ZX?+RtKC2uYzRvT$FdS{S8PS5BYE*MFzfW$VZd`|E7(+#|)-|Mp|BcQ*) zP$>P!D>y^sF?=`p42^ynVmXseW8WlFFDwI|w(mObS=`v!Ts=Yqn+8&UuTuX&rDk%7 zWXm@ZQ;PuwBpWs{R!Hb3qd7Va{HV6MIzzwQMhVDL4JG9ursq-(<&Wilar)A_dM~yQ z@G(govA?D!3-4L~)u3CnfS4}eVvWO?BheE6qNJ;T;2ivFNL^Wk*pSRZevfI$ar=gU zo!|YnwOTOb{>w^+PhMe8`3a6sf^kmf38q`zeop%dp<9A*PT~pLS6qKi{R!SzLSRne z3HC$We-8V=3#+DlUn`5r2&Dv?tr#nkoR+Or)JiB#5k^-!ZT{E=yt$B;I){5s^`iBc z2!o3TPPaCL)^C4;fDe-Q?nDLSHuH4E|NpNU)+_ZB(kY4bI3_|v{sAAdl6~&k(XOGl zSu1w_&&$TBWyl`K8-BLy{@I}$r)$ljq}k&7Q#LMJL6#xJob><CXRjEjzv6=6#T?f-Xjwpcy7`Jn5Ab9 zfcbUAaf6sg0_!R85HlsC0ZJZYqQ+g8q0kfvsB*jn?9k~ZiFe^rBPNR|ahYoAMq0)d zQp2o^5Q}o!Q+qfwtd{AfEKHj&LwHFM?Ioxu8FW(|IrV)m{lbgrQL-F#?CTmvPIXI1 zMj7V;$5ukkp~fNNM#bX!;)V6nS%%FchA|_?)f5If6o%atg=*SHK`nv$+Qx+?MoBIG zX0}oE8wA>H@SCilo6V$d78Gt)lvfLMOP1zWD-3Iex=OX%b?S}v3eI)<&W?iKdp~{- z5nsm)Za_*j5yn>Fk2VR!UIJy$`D8DFWG@Ks5C)igd^^kVxxt=EP4N!>V?W2+mWT5B zH>BUUhhtUxq7jV#kwzf-FOf4jLmM-Dr!QqQ)o)V&mx4N{*vpQ`11Pv6X8dw z6AH7y%&Vbl(j20{x_mj$H=~2QPAO_iI@XKkX`9gz@&$ zHid|vLeFVjmz{%hrMs>+NApO}0Ft$)NPiv8Wl7u92&m!9uRbC&T5X!Y^wasljBg~} zv06+QD;267KLT;xQ~59kKUGg%3L+uXbl9+p>K*WEz*+rGu)hvSzYBViZhAd{gN8Y# zcq1?$W7;v1b*7qE9>~7HV_nw)(KMLfM z{agH8ZCorJY)rr8j7{zSZw>q}?-4;XzD0F1wd$1>%7VRu7Nfc9Z`7*!C}N78gq!*J z8S>IB^9=9Q>fo4u-+##+$Z19X(mLXopW!5V{K zFym*zCY_C}1o>>;{T~jds#s|FV$rZltxi7A2zs*fR-hqa9PA4WTWHz&K@!voP2q|r z$};nb6yi1Ksf>K9(KG&S0)y0&gYXcpqwgM>qac=|TCeqLLA*&z)n6uX;Y05AH2CjAqEk3gVv8g&jzdO1-A~Ye4Gc6)pVQlY#n0v+<&ZPHQw zqe#Cwjhi8RL>A4ffVu;11f$B;V6p}rI5~I;(-Zh$-fR#S9$GQ>FdO~4FnTA0Dlk}wLfIrKD=RaHrDvxzaKl;GP@@2h% z&=4^S{a|g!Ct&%=?fzb$j~<#Es7+C13rHP24fKlONQ+6F4xw9Ry+SXvjCdJaKU}3# zxDu0e7SHj9A3PF%NExeE~I#RV{pyPEwP3b z9d;KHgS$w?WtHPMjd*Bnxx`1_SR6CT22O5MYsF`Trj6Nb8?0k2$ZE0GW3x$MZ#R1o zr}FSJ11oZa^SYxweP@<910Hfj%j1}pkZqGMY32HI2VQI z;ve7kr&)RDbVeBP3hG2G(Ht^~eG6llDoUA&eXb}5Q)4a3TkJ$L_5C=QY&s%3xfwrw z&e=K6we)WvBwA%;y#`L?mrMJ1F_fzAN>uAP+03If4^ML11LKG4)O+NTc~=p9Jdk_^MIu)aMR7hE=-oWaB@iX&e0PPO!f{t=Xpn&usVrswa9&4oPk4&5n8wIF`g zQ5IhPo;s0muXt51W-9}Ge%iG70yMr~x|W%Q)fmT=zW7ZkaB53(jRFNK|Cab|unT{o zSNAQ?NW$$Gbd${uw3}I6^W2}tCEw^3v8TljL9Z{@%ufwBV{Ayrl#2GyB&q`tyL}e8 z4f=fu+2r%nxiIoRd>?3B{Y6%Pk;f-|A0LGs$To>T_CI{qfsgJ9h^h-4j0d>o)nv6O z!%5|LlsWN##vWuuUrc|3Tsvx;33K-*&Yd$6eF?AnFCOJ=kMG)L`aqZ$9z_+2mVL`J zR9C{aFnoDr2qq*O5X4%pksaoWmOfz4j;nJ@h}U=@Wr)t>RvFr$VLR$}X8 z$V&I#AW zr%e{+|09`xDaM<9`D*`XJq%Hj`pe44H?JJNY!4__DFRmv6j#@9?K=g|0mP8&I)-9N zIXfSf#63=pq>cv=>Y-Ry;NWd2Rv{MVbE(&#ZuRogmoNz+u__AWK_jG8I67PnViTQn zD#PZYLmKTo{8cCy;q;1)jpyK>S_2QJ@8qs8Ki{eZpdvtvQ`Ct~S})WO#FOdrd5S|% zskW)@TcPSJe5s+&I~E?6ZgnL~sTt^Ur&er}Lck^+1#m{XYMh|6T(8sK+-hBDycW7K zN=!alie+!>>?f?_s#BmLcH0Y3ojw*Q&_+1l*e%`gf3qvX+m6WXcTOeaM-h?Xw%n#a zNP;u0{%KK#TcJ!4rGat|e(z-@u8LtgU1->7SxidH)c*-CNTBpd`n@ii6D1q|h9rGY zBmiSnDp#c~&Osi{4dTadB)~8;w)~5SJK>_vaVS+$0`PzpMB@~)!*onrtR`S$o$Bfe z0qIpr?YLM=vV}R=H{nZ3^GBuxds8}WD<=QnxF#tpYtrqjE_(iBUBvu+EQ4tB8uo$uE$HN>+plZ=Kg1~|AdBV`-vieCaaKEzNe*nHTbw~EI z0H0K&-5kW#wsp34KX11APOt11cK!X{!I(nfv4v!1(i8Rv8rgr{>j(>nj&4n{yuh~P z7*EO&o@AH@(AScYk$0t1+hktv)mO)4%75p&NfWlFp-sCU~U4+pD zwVFWunr)b+BGp;=cUwXMmdGS#Tm;t{(4kH(QrDVhx%htv!wG@>&XrK&E?DjaNECG(u;)&5b9*g!uxs57e! z79L6JGcm&HexdfjthQnUtXs6;x+HG03U?WSsM&}N#p3SOOv^GY&z7C z0-u z)%XsJ+`>}GE+mmW1|oYvZ8AkyfM{| z36}iZSd`(=@=PXyYhXcbagZ42A`LnwA(F{b9h252IL5tu@J*#$?(ot%9T|=&C?#dt zmKU>d=2vXUHY0vn%(5X_yi!r4_Q+dpqL3dw8+&@W@m4@jo8SF#nIhA{u}XO!J<{jQ z(w{@sylv8zcpDNC>DcmNf4R@hXT&mVvbpFEh%K7%l!x|_^Rmur;BQ~`Vep~zkU6D^ z`dT63HKh9-;gZViv5eBsjHVjoLGOGNOEqr%SU0!M-SedL-&v@tdk?_z!rO44`ypP> zjKvxwtr48o9dsr{P&h zg4~zu-Ip7R@`nLj@$%c}hEfc}nrh}8iirl5sW*?^MuJ=DYoEeBhYb=6EvOFU0s7clPW|tv#2zowAr89D2btihL`UKpv3&9?@%)R<)NLw;RjBy}X9j4g!G>eQ zxf+=ljV0}>BDm2bp}RNeqaU_WN{~ddU%=dvpB_aFS@c}hq_-qI z;!f2FgkB~9LzN{Y(Lbn+e{SUyCKCO#LxZ+F92ss^ zOzvqc>8gd=?(Y8;)otWPCFPJ{?9C|JR=-N8Gj-!qOSTm6dgsfr%5b@AR2X{f(1Ltw z{}Pl5YCS*d(doWksT0c}E{P%Hq{wo7u)>Sc08)3=1ACU~IccZ)-~c_;#dKoXkHcK1 z1uj0GI{$LMaULyO+DX`RJ7v|W$3Ld80?_0~@uwPlG(mQH$!!PQCZmJRS5`};ocpbnVG73eu5`YVQaOsE$J5bPquP7 z)-V3b(+F(i;z~<;qpXJSuz#)8@k)bVe}(kNKZX?b-$QC*O2+)J63Fvxzse5*0l^1B z;0EF52EiZ>QM32HP;jKuI+d*=4k6$Bo~+VcHPj$V#M8!7OGesE2FS<>$Vv#{s8#7D z5l|;A5+06E2na|B7zHpgHji;p*0*ssrzZ#j6)6Z%GBfJ#3Q*IswFf5z;7XwefhfYF zf`T!D5`)H%4)npCID;@_D&{5xz>gjLm1ZEJv}fK5qrd)Y>DT+ePdon(&+NZ0M$Fd1 z#q)pfdcT00i>Zgpzb-IDNml{&%W2X5cfAWW2su?AjI`u_z%VAN@}W#ngp{&WWS7Ef zy=-HSty!tbtNNYE0jNNq{(h3cphxL8P%&B0)CccruJ`HcZeA-;>>alta29an+Ee}Y zVR4*#@B?IV%7-M?65u-Stg3Wm1yW;z2B zO%AOsW05K{@fjH@>bSy$ZvKH*>{c|*#GUUIirb$~8pCtFl{7nj@$3yrS;ng<*$amj ze?w_x!%v}T{Ld{CdzFJ;hCXLu&dft9lgY^fmtUYe@H_-G@2R?pexwGy+?IX3x&1k& z$TD2N@U>?R&)$$9X0cv5v)^JJo!>pA$+Q|c1- z;%XRZ8`plP$G|rTp=WyeTfF5FqH!tz>k&Ts$4B_zjQ-@mqW(Xd8|t1eD$DqvHzsB~ zbaCVXND#_c$>if?MRVX-NbyiO@CkB6YuBa^lA-b^@b)_f7M8l&8&=lV*65YRBy3jA z@IO$As|_lpbjxg&tSXx?^|xaQ-V|o<4SIi{Oq)<(b8&HbzU=Jw?D8<`a=y}i7yG3R zq=a{8jL?I!cUt-I$Oi8ItB&P6&%LYXXJ}w2nhyX-pocubT_)FFX38CH>u}H=G(FJ! z_>~_V5;Q#&^uf6|@D`j2^hNp{acnyX*oQFe=mt`VH+WEpH=6X}Q3O0r^3%`LL*;ltD?M)2>I$Vz={rVb^xd;4 zcO|UK3QmA(`V7k(fL9jB#&@?u8GRw@4ij3%)fQ|s_eZ;G1qJrF6fvvY2@e*#YLv3F z%3X>*yL_YoYTNswo!s;5rRi!d^T7BDcG42^7E3doT>KxK7ZHndQl30`us+)z&2lm( zlFZ#TJ+`ea>eliW<2NVtsn`l`NhFeyv@seb9H)>Gc+j3imS_t$>~IIA(FgeOzy~W< zmLG4^)gXQZ?A*lV1myJ4kpg_ufWjKM2$!ABVr{Leu!`s4T!5`ru8S_hfye3ss)7r$ z_A2*EgOsODR6+s>mRjanEOxms2*Ko9eSS>j6CXA`v9gXjTFxc6`z5or*oQo@;aGT_ zh>~Yq>dpA^SR-X&7FtJ>olo$i`1M+uCf}<`T6$&)Q$mri_Y;4Bj5Joujm-Jwn~~Q< zB(Bs#JK6XZ3B6lHi-l!n`UD|BqlbBt3Eb-8p(ep~HBn;hqN#ePsuTcCOMhrBGp%ti z>a5Lc+lkfcqTDzv%Q(=&J%=u~U~3&^TXrVH%(5(2f?>?(OTCaL-lCWoVA8{7qBj8% z@401awGEPAf83F4P|CYiqT863IzG_`_UrK6^;Oz9pXq+b!>e+;MYI{Kn@dHGw|kz| zLL>8=R+8o9)KHPkRiVclOw<4m0OJE;Xt7Z4xD}Bl#l-_Hp*7i24_k(_n{ds@WGcOf zpCN05v09rfMtwezR<&vb2ffvxH&SkG$`0?aGw@W!W~iCQZp1HOycm8Ejput{K8;_j zewhaWW7*jdJdIt7&$6lW#OrbaIi}XWtQO*CSzQ90wc#k6<$hhHo6abeub{k2^j=!w zgADDrVRVhk1F^26JyZ1Bz352&eO2&YwS*yiw0E^(&GR>FkDPsmiM+^7viI!hx!WR8 znU+k)Zdw~`!`SZ*X~trlQX6&kv|H#3Jn+H=E+vaBt`MC+jpT-ffA_T;;=Z|DK z(Uqkfjd4&bDSyH7elCdBP{eu$-?PAs4NPChs|2iCUrLv}tzqly*0g&1gEgy2E4ZOE zgnc6>OCOPp>zzGa(!Gjod7Y3Y{lapS>dpu(S*^Qb_P-4>Ikcw`FiW?(oLXmp1@N|` zkuc7^Jp{E|@g}EH*H*c0^13hRN$-M%R8D8f0Aq8an>r#T!pq%v2-_ zXSAjZzUc5H7y4j!{u+Iq)D@JcsUiM!rh9B}i|tGqf{n1n3bsH}7<64a(VD$AQMvO* z-_jU{d{li0UBY9l5vSe5XoFaN(1~ETaUi=nx;Wsj%%^9Gu8_n)e<2+k-d_3h$&;{n z2ZzS0qQw5=eknrg>fY+CB^8?snu~sGwg|C0nMYOLN4R*OWG5Zdm$6wl7QM+<@+i`F0Ii|&MD=3aBch(RW~E4Z6sZ0(yuxUyR!tD}3?ciV)}MJN;GtsO+wfpE3fxQcA} zkX`@2F#m_v@m{QUf70kbdn{c+;@OPpN`r0ogKnF}CBh$9f??e^L-0S}pik6m@?0)1 zlz%lDpID7f8HgMqQ{DKr(dJUcWNIiMIoItuBjp)JI37%n4z%qd8ZBrrXH9_he%le` zGFvqiR$ZVsCZix6Dk7FWFU#Z(pHMEy`B72EbJSAV;{>(H4Z+;qEd^2$##Bhk5}sLB z>Ijx3l53ovAr`I#?}^ixKI}Ut@+niW6aNBc1zsR6$rXSIjVCI7V}^PJ`zmiNzeM<8 zj?5pvj>4aY$;ZWz63k`IkhJn-Y`G*5{E9E4Aqc=wTQ*gi-6^XrNPVLtA+{feX6;}K zFR>s(BeGJWa;W(8!4o#Oh5UeUFsSrJ=fBILYtroyJiv?c5hIqT2J@B{5R_9fz80ck zJ(%1xOVpVo5vJL#4ecn;8ziLfQFp>3?lYY*Bm0kbR^hhyj1so#i18hM)P%2DGcdX* zp&S5H9SEsJilkEz2utFX93mF#;R!W*piK@Nx9RZ4Rt_hvkwN?#Cb~hQbd19qAZCspJYbCtKXnl2jcYsr&qgKnIqj0f-T48|c-Z9u{s-0kF4qGc zb4U{zqc#Hkz*R}1t198Q#jBrM#|+N>A>1GL{46;SFqyd^&ROi#Tsi^5)I;p65%Y6z z$XApz(`MHLh8`4nw>i&+pG4qsP|mGkJd6xP!s${7D_T9-?J~}>(B5hLWX{YukB+3L zn&8GPVb@y|+k*Su-9 zWu`jd*!t-}rCO&-Lw3GJ=}qUc;G;GcLiqDzL!nk(*&$f7c&5j#tl!0%sddZHm660sH(LoH<4g zit2rJOM||)5dS?S$NE3_7vhG0d24$93!_!1Y^vd^VvYXE!lQr#PDIk`S33uW4n{%L zpbw*QinoxaRn)3br5pzW9fzBd{h{*;v~w2X8|x*a(~yd|7ZbOaboQ|6O_4+la9yUs z1Z3HN{(ixKnX&i(c%c1GjW>xkQW8zPl~zYi8VHF(FcEI3Jx~b7udoMe=SwFtkcQHe zm@u@8f`;u&B~vygnNK5>k|31f>_&Dqfi(o$V;d*H3jG@e0qejyvu3>&o231oKJ=_W zNfrA|CbOo7?ZR|w~~j^60CKTr&#$~s3(g| ze23GI8r;xs9p%dkJHXad%Fh(iVnyYr?SW8RtG64QIhLJ)_TNzG%PAdDBt&LsC%aW5 z#RK4})#*R+kH7PK>Os0uiCNbUawlH80B#fpNg9e;hRO{jLHX5X#EbXeCOnf<6Ph&r z!E7DbG3Oo#$SQJ4@Ifw*O?B(2Kb!{D$d}4^vna!oeH+RyE7~=b>12vqc>VIN!ZdX9 za^o)X2CWOH?CenwsS4w5y}Y-FwUV_nnEHG_=-q))Z-5%+BCMwp?aeX(~(; zvI^|h%?3Z%KW)YB1hz3V0*+CQ^N-q{o#T(`(^~Ew33qk}D zVQ?)99+{0gg=ZCizST+O$@aOI0B3g?vx{?lzWdK>1M!i;8oJO=ZN{vqK{!5^bDh(v zLzoW-grGmq0r%s@r>1YUg7)IKYoe%Elv*zPY+fTF_r_iFvqhwRP(p&2m2D?>dL_F% zP~F85??==fxvn;hQP-rgL)$aztIRY#G9E!{x=jR+@s;5)-9DjXZhj3B7L?E0gsMNw z8YEKqtPlyHMX`1sOR>5I16=kHi8f90$dwzmflneZnrfmL*xt zk$Q(~kI0ojy6rhA?mm!u2W*cg}AC~y`B z|GPob^YhzMq*B7LtodInqg&fjp;GTtS%;_cAI*DX;oWxr%4PaV3-saEy$mk ztm)RLG4E%*C3jijP4;vrxQ5s~kCLu1;i>tPk@uQOjqxt&h~J&kM*#QWta{#_vJm}# ztjsnMn|)AnUYAd#I(NMQ$xQBB$FaaCeN`~qM3+p}%|5_UbQRoO1P>uY<#rA@b7XG! zuinIKv~ld<*Bp%eKhEc&{GW;Ne^L!0iP!R9ZHUlaO=;~G8R}yZ`fzk~8Cn&zULY}k z<7N`*@Bsf!w;-7bx^+8fFJQeOaeKj_2#QPysU?33z2y5TmqvQq82_1>sa($;z%5tr zAD`a{26&S+9n1uRS|Ne=2%-*b-y?`>$}L7+9XYWF;J48BQ=wWx+emwqNo1p#Q2Vxl zZkU^#D-DvdNY?Rv^%c_a8`Ebp$;~tS1&o~*^Rruq&LD#916Z&-8Yno_COWwW^;Vt5 zxFgJ}yY#l^Y?ZIJMe-iE$ZR+#C(l8xIl4(qpm3y?@?>S0()MOh1+ctOV#p(ozS|~G zh=tAdB)%@h51Ufi;l_S97ssW#reMT^go{pmZ>hJwUc~PmmkE`_>`+ikLWc44wV&Ms z4>j01h?Os&R<&m?vsPQ5!JRDesHVx|V7OSGi{h{7QTv^3d&xKi$|^cP$VBFk?%I>1 zM~xX(nL3U?sK-5q>m6(9C>`I_7SGX!x=Wvy?J*PX92Mu-L4;-|)<)Qu9qLJE5q{Ve zYDmWtd;zn}6eyNZUql=M4pH5M`&6YxuHeKYo{M+xteX~Q9c%k=ZIy(wkbO6v8h`JV zKj%;xnMm;*5z6{uc&1>YrL)!tHtobQ%?Y1!7paEdL?J@`bJ32#wh4q}97f{-Yr+iN zR)7DutT~Ll5}Yyw6F6bXdH$zJ>e9n4R% zqc)IeKS_U220veT?>k zgh}}WUpWS&Cg~@4`(0CPxtA>Z=@@yY9WxMv^S2xDqzeAP35PT0kB2zD)5wcoZHKqiOa_`tk5em2GIj>rK$F+-gpa?SoR0nZ$I&)Uzy&gkGt+IYY~mWIe^IKQMV zOl$s$QSv*ep0bZfRqK#1rR#xeU@7Wj2WnCzOtnNe*Ls0XakJ5)jtcs&^1EPUSkYbm zjp=k`GzIDL#Z-rUh>la*!cx~Ex5ijd2=5wthQLqEzt+@_+~_9S7tKKbk2C|(zpp7f zHB%=`Gfzu9b4f!x6Py3#w_dFd?V+-a{%Owwuzz>}AvXNpFR4@*3>Ho$4kaBEVX^UD z&w>(=F#)zEgqA?#D6zn@wd- z#k`b#5^RPQM`-@iLY%Y-hm1RZ{Yb{WC}CfzQ4}A|A|1U*T8CmdedvSAfgYOhN>jfW zxGa-3I__SIrDpD$!Dpu%h;^?*MUL@0^6=WIku1|TvBByB7md(ORv(c;4zbH?Zj3{O z{2ubb9PXZ&YVMl>wTvD5LB4_uJ$%x!F_$d3&7d`6%3IW*GekG5_xM*RS&WN!->a@t zZ4s@0)qH=;jlDgDEbxj`PCgZT*-GSFsc3aAN^fk7xOJVP z0SIC=$A@9GT1y2Dors%ZLX%jM%9D)L^3WBitEw!u?Ge(SnE^Y>ySdWe)($`q$P)RU zgM90~M)9ibr4!auHz zS$S$94P7R20?Y#X2~8c>LYbISlu1ohi;D(F9N8_Ar!qzd8n-s=yl{aKLf@xp|)59MhxVvDXsbqrU4ft|$w z{$6yEKgFh#%b7?^4aJDZRj^$EHN}M?CM*e(o;L_TOFNC+id5TX;*%QQf|o3et;%+B z4s|xxgu2B|6 zX>_Ufs~m2auLsdU1f4c7|2?=CB)FE9x2Bw^xe`V0Jd~ywGMQK;gJxj~Of$ox%&Cff ziR{>z$ZUpHC8UCN$)szlV3`d)QBE1HYd z8Izu3`sXLS!xC_5UI*RmqkHkShRS|2qL$C$CGXrVw?=-0ZT2YnabY2WTh$VcnQsrc z%E}e3`~#=OsHQ-@D59@hXi>-Nh@@xcT9Pn9gUdwhG6#9miDK3@RO$qX%}-!}bdrd% z9DlQQH+nwz1fwxH$IAlkbcD;+CC-&5YNs6K@IiCp4#{@=>T&ZLJ(pZ2l|8BuYl}>a zr;U)x_i9DyoNK*e<%grp^^ls-2(HNnQ_MgRnZoiY%Oc#T!)9I1H6h;Zodp`UVprJ8>T>l#I{Y4CuA1P zGYbl{9ddNUfm3cDw-sRdWH$QL!u}2qyrDuWFPD9JpU0p@0VI{UH@@Qi#+&R${*3~9 zXq-b2!^oy)Qpv3X=rqv1YyoWWXaZ0^7+Ryolky$>licE^o6O~wj(aBLSb27~7MA9R zHn5y!Xz?0)$;R}KQrdas!J4$!t-GqSYUN8;Bh8NAuG_rtQ#bEdJSL<^rZspz=vUpB zKWl75QbE0u-e)I!1@_l+hosyvfRT>{!KOa_dg9Pd@DzVM5amb%YQM(oXg5jGO zXGr0V6Jh{iSV77Xnms0eU|h#H5Q{;U2}O-qWj@Ve)1y@2i}wv%s!VMTbDl`tkLH(w z(YQZqvWc~I0wTJ@q;pn-pU7b2w8*(V+^zQ*Dlph?3TBF#0YVivkQ7v`5CZ{x=_m;C z0Op{F>AAsA2cjS;!(9XwDpreO_6xNPwTRvna;!D0eZo#5;An|VlR-DL~K!i4^QOo-(>Z}rn5j6scb2~PW|{Ya6Y{xjf!qmCsGoFV%6a~MCL z^l5c%`jUd!2qws|!rUbvyr4oykWq9_1ZziLBU#9>2q%UhA7oG;E)gGCP#;{i1A?jn zhNeUE?10twPxh64-R$9)ALTACT8m9A&% z?CfP^E9F9P6^~3u6syWmN}ozY^@$O!Q3Af|2{gqFF*rQoA5O8Q3F?855e=x7$VDTA zjvd)Qc4(>+P?z+id}v>Rbj4)4muKEDI^JpGrzX51)4U$Y9G%bQtmxHKWPGDl5@d3u zD%Ohm_djPhS?aq&!|t9Lg9o`wcsl z=uP_~6N(KW!s6Oo`<4WZP)nejaT{@b4GkgO3qzj)IQ!UkT>5=uc0)pKND@qT5(h?f z1LSlMlRCEyKTgD+3^}~Q1F;^&x>(K0%d1j~cxj`K%%w0sf^P8QadNuDo~d`Smtud^ zsKpqtm%4g0<>@=K8wXCc7~5?!N%J}BWoamJl;oylo1mtXihPuDNgz{T*}$v+08wA4 zsAZ6w z?>Gd6j6aS+GJ{!%J+(XakTBx9x4w5sgm^I2&Q4DN%J2kB{IFnn_lGM*-f`HdT$m5X;x zmQGW(<5J5;jz*UmZY*wp;0DtRVXytdb$(UY+AZOT%cn-w2&oNCTtfzLssgvwgt3i5 zzb6*%no*aEwcvzYGfNBQCtjf{OkUrQuvG1juXc7wVH2v%%91L67d+ukEUFG|+qnj# z4rC{$#1*vom6Z6E<;gL?rgXL;hJRH2jd$}n$_A=- z?xl7iaaAMTKKg!Sq>F>S;Xdck%b1jZ9FN|K+7fp-*^^>6PsSc?U%BSw@ecAuT6=`~RXdUDa%raaYm(YREL|t2~fzCD$78 z;Vi(5{G@b^CBJjBK^tI(8_VK*C#cnFSR5};2tKZ`$0jvdnsYBQo`=OIAv*H6RRffR zve@0ezM6WH5paD2ePdbNos(a5u4SkcYh&8#_P%L9<(+Mx<(tg={QXJ_B=V~s27R|? z5Lrjb(jx^?{na4`5kg->EkQi=cLq$uR#$-m8=Oo?D4Shx4bkZJrQwn48r5AIu8)HX zYkpZDd|^>RP$yx(9KQ|K8l16=7@oDE4`uYKN6o5gR{#fk*D#WNtyX)q@d-9gYRO~q zzMQwO$I47PDO`m{R+EfpT7Vq0Xmpb{ixaB&ypLz>PT`{Uh@3H}`H_0)sqW}R?Oe?U zKyAlq6f5up6cbxG2`xI`abqH@vH00^QIjdvnPS(bG-gX|u>MykYv`70<=9+9)KQ?& zoK6H~gHcBkzhv@v!6oh2g7aidtjymp@#zOhRtv|?lIXn-{R~<)rl{`M7hjEc&B8PJ zSNepfii{q9OSI^wV>{$IKV*=0`tEy6b+e+%e$x zaI-0f$kjh!J3sok{ZT8JqKmvuzx*kuEUq|V&synvE!8OqMXE`gmNnrWwtO(ml?7NW zuK*EKZcZRU6P?FCP|c_$vWnFl!#>xA;`8o)d2Dv>T!uQGhUZd^D!CN0x!h%>0#1}> z>rwZr{s2`#(N}iNGp{>RY|m^|nX5o=CNZxt=r~HYtbBAEm&#()(20*h2S>Q~!AYEB z!xPI3Rp!h$Oh(+@8?=nJ@PO%t>8afJ{?!xO>KKJEp$-K<>KM2$3I3YQd6MYO&m&YY zgEnhdGA*o`qzmhUiQ>7Ds=@Y)tlnFlE1V1dc8`5~qx-aUA1@pSt*dgMudCLO02asZ zJE4^awlf?v;*1YWy zm|;zAhYer9Yc0??1G`5*l01R3H@GW4!ne|hxZbe6av(t{570=Vbi(6FUd6&7;U^*?qq@Ml2C#%3Yiv_IoFnxH?&0S-E!#<|tiTk}sV||` zNmMKC{Rfph)uAEs!9=vTqYE=Io_?G25#qc~!xh+srKi-cII*JIe=lOYUI~XWGd87J zHjE`Am#s&q$(cM&hTkPTvsYTbi0C8XTfe{L#DP?EA+xl9kpokag&PELCa{$gBptTT z_dfF{j6R|mc#;Y1;5)XZdFSw*rUs7CdsaT|YP_U`(DU(CtHfUMyW|86bI2105 zu^d}JF4`8cjhKF5cpA|GdH5LE-n1aaFY4>#Ph+VWZkI3fB}e|>SUFFM2S!l3hb0~- z!~+Mqc?t|L_7yF;TjILl^S}kbHb~cU+-39=FF5&LIaJ+3zGrfT1I&o~>0u7CBye}~ zJt&%nu@bH-awXQX%-vze+|>HCWYG*onW_K`Z3``vPf^nvcU z%v~}UUU5KO3e*C3d-!6s=f&!1)H@8w<}j)EL{uwSrWYNA?q?s!G! zjGyP|wFKK9dNkFuL35`Gyq5{@0I>qAgNr}JTuB?^hhb$3C4O-wwye%B^|Dlel}G0$ zC`@8G@|D3jEejTr%p;1Mi4*1MrHqOttMESHKP6fpkkdtN^4wGWYEh*b!us7zx#l!x zntTk*@ah^tKa%N0p2Brfny-d9?m?7b;(gOkdVM!Ig(*t>ngK#!0Ia%`$q+P?XQ#>8LSqI? z$1VmqB=#c>wlYz6oe2<1xvBX1;zZ2lGb-W6?3^}A=ZK*iy5~12`0f^nGZKGXl8NYI z;G>$M44udSc^?OF#1?P=sIxggyaHBdEvAA-kdA>z5 z*8dU4Cmi_EPy1#2^@?H&kF@HRfB7R^aRiNsjea3I?YhB3|Bdi31VF3n;Mo0jP;wgK zpAZ24e>Jqe5Ps&6Khew-4|LIHN@dr)C@S3?U0c5x&OCRre z+vPd;-1?llP$Clkd4m0J?4d0rK*3W-i0RQjHdzTnUwdCZR4U`xmD`sb2u5+}K^kBQ zF2!L+5vwWBRQdxp30mjGH#aQ=3w_LJsg|JeupP}H?MjwVPYRmT1J_>FOxE#mYOe#=s?O8I zeBr8HX6!iP8QHU+9C3e)S1^(EXzr8hOQo;gVg-tCYgiuwSlwI|Aln{&&DUK@w6ySN zVwD;@&sy55cbPjhyJX|M8jOYHZuclKw=*`xt3yT@3R4Z3I2sr`E0dJn>%${$*)vr$ zYd(0wv+ebI?KXIO9-m9Pt@NtyT#7bF_pwIH#}1Ms%^ehnsTi^GlpG<sxwUsxo@#z&&>;t#0I$!ES|GUd?#x-OHR5qAl*gf*N)Amo3c~)@;w{9KBy$H zeDXD2CA0z8TEmW0)->Wjpr0Tx%MbA6lWsEiE#7OaXw)1+(pt~hYujsShb5X|?0q}C za6q=Tf#_SAjcuo!YQPaUW{~ev2&Yore5H+UOBr#H27x}{0?~+QgALz`jgB*LNM4le zOU=e|HblHBhfV$mU+3JNN%U{|?j#-CPRBN$*tTukR>!t&+qP}nww=knvu5Tuf6UZ6 zZ=hDysygSp_x@~p;c{u^$gBPaxU*I%aIS_Zcv?NKj;N5VZC=M$4~&d_Cm&s3J3%=g zzx{{D4;-$7y-6o-i)PF zmJbX>!=$@uG1#{B`Qw~dY$kF+(JWyi732GgVdGHqeNmz5&|JOR&==Gyg8ZsH;Bsp8 zu;|d)k)+4Se&ply5;`4aibB=?_L=zx2xLURe<9~)6+x`!Dzi!m9wx>g{wJJ>mqb(|br`pG3ibhI5=L zeht1QU%>p^Z)OH}cP6RAPB}{FB`K z0M^P8>R2+{$E80^HbZntswu7nsU@xXa`67t@gSbq5LpiE3hhi^0Ss!rAm_I#ngef+ zv#|hX>N6w?vsd(*)arC*GbJ9mTcbw%LEoB8Pnh80{bdK?+Xm@C2YyF{A(YAHccS)8aceqr(z#Q7P|Ohm7^ zJ-4o0$`wL}XS)FTVW2F?W0_tuQ9MsK;mih4lX)-3t!HFX%VU-X`+r1~j>BtgN4cNo}_dLSaq50*+G2p@lg@cbSw*7tx!ACj8U`=jab z@#$`&3+s2z?8*JI2W}KTB>S(PkOyxZI?D9O%v#0TFNh-x?lLvaeo3)3^44wb2+(K5 z*J}T)VeE4gPpTlmO}G@fXC68ecBa*}N>tE+{oo@qc)g`ZkP+$o(C}NqdO4LO0! zuZmK+LucXj-lfazux%=#!Uhyj@(-j@F6sywf+(-(ELVtsqUS;@mb;D|fgH_7IBS;1 z_WDt$K@xp5u0nlv$kneLAco_?tQ0MQlX<(6u8$_Gte>gWdCZ5d#;1OCT>st@pp)^! zGP6?}#YNMrP!W1(3#1R(Zyod#tDYd1nUn)QSTpSd>}E4-92}$vSzw~up8rwk3%~Zl z+>88z-@!W$Vvj80f|XK+T%Nu)i@p2%T;+?|;HwDZ>+1;9n?AO4uZaY1_ldX+@g>h1 z*dEi1Mkcm2c_V}kydV}dyC4P%Swc7bNf%A_x2MWI*qzd6&a51SVOJI77i&-|5e`6f!CO5f;zx{7h%ijXq55 z>BFzzMGAt+U9&(ozDd#g9HkOFwInocUU`RRf_4Z-19n4@x?mU?D8>YY0Y=9LB zFEO@VCrBA8uFMIgw8UscpjLt@Ti|G83z9?6Q8JEP&M7}OMxb$ZX*L^NW9I%=I`83o zrg9H^rB2YUkI7+?R$5EzhUg~$XSMQA~>dTVLp-ngio6lZZDNCbpFk+e~_pSc9MGRjh>&Jg`O|Zt|DD~uB%AO%OPwt zmaJHwMa)y-+o}fNz&7n_G2C-J?7^{y@a(~F?N@*CAbi6lJxDP;aAUL$@>llt1Xq+Y zBi|w<-I^p`qcdI*hr`95|EgS)3Hk>)_x2YfQ@LXWM%yww8Rufgd2nM^ed3>$!UV_4 zT74uGWEuP$CM*@nn>nj%`(XceI*q8!uUR(Kt|FfdBa>yXLa)ERJ08^BU$X%OGrYH= zgn^XYVFq;_NY9J5Wa)90qd+<_YPWUOdL|TE6?E|5XPY0^9U8{c=r8V4n-WogC>gxfxBL>*n;1O<2Ljmq@P*H4@>;jVEN>uar ztUA7!wcpqQ&G%C_whmy|tqOzfFCGBEGwV(I3$^uC?S4tvwsVj32kiAH4ej>$B%k$_ z!malgcaH_!UDdnlTX4%WFD5nTK~L~49YCZdlp%=BhP!N!kb-+m6nB3UVCOhU?& z0^F4kmnC~EhLUaH!{?cnPO0P>M0{Tnw!NR;Wix#I;*kN!mc0d&d=Ku}m(Kb^xVOaz zOglKlhVeM}0KXtvdzbA&QG7+T^QhdSQGCUKG1G@K9x7Tms zI9~|iw43%RIbV?Av>W%ua662Lmz6#kJ$iMpUqHJ`_jGV^bQGV`9PM%V0rhn4h zn#Fd$chcSZYiN?g`J)|YTd2lEz$;77243$6YAxSNNvF7axruTG@z%GsBOfran*%t2 zxw>I-=ih3yP=~h#{z=?p+yw=3d2PY>VO09=ERAUi_$T5|SB?F?{u>LW)HLkuC=?V7 z+)FnrUitXywd)@6k+)=(g_9+&lT$~Ch#M8q-p5yMVrq8F4wB9>b6x16;pJ`PVQ5+p zSh-x~6lI)R;>|X(%_Ke9ucasNXh-LbSX2Ke+C90xeQ^!-@cyBZ?(*ms+~4Js{cEKU zxGN@bo`x0y>)|psgThx7T~FTL5WKLsr(zn`{X>J&EQlsSvqXE}eTd5%3}Plg$dy50 zt0s|ze=WvDrF^-YnUnX9B(?bM<5QcbR|1cy*3m7Pi%*7?S6tyk;|;!UXu{d8-}wU! zXN^2jbezOqp>mbp(;`?*!+MUIKWrm9MgciqMj?lmLGW2TX+~uE5$vSx!tQ)PcH76M zW*aAjZY(rz?yYHw#Af@iKLPitEkb;%sk{yD!%!%rjWRG%9C=)UQCB9Ff8$B9Q$R;% zmTa+g#(>E5ug#Ugry-U~1>-5CD*`<@SAL6*EIt4doI6Bvyzv^acNa5vDhSEyC&;L3 zeRub|K$=u?epL-A`qJ%!H1mP|%NiNEcdZ4Tlj_!OM8!FDr&I2z}EeH*r7`^`$mD z@*Ri^VTKyhR%Tp#&Jr2~!*`JDos1YBezR$Z?eJO|2c6+sS*Hx1>I7v|1l>I690oL< zx!?RAT%dm}H%3584~UK@klx!jH?Mb%!13R5(+GdM!UaA;(UrbAQhU!_VMG(2P;qua zQJ0XuTGIHDa7zsw*Z@y;4t3cHfA^2*re55nG4mu z5HG*U^{t-o?glYCK)Un%i{tCa=?00rgZct&Ml94SE^u$!mKs|<@t2Qub=#M9cFiH$ z-+;Gb#__=0N8rGvR`#!5M$;+5Sy5yA2hEy9K*2bG=d`IE=iSy&#$zy(5ZYUQQ8G~- z8`Dh9*WjX=-Eif+-DG3Z6k@nyL|LeYDq+$b6rm=YvSwe8CmmEkY(;&~-E6<$adZ{$ zzQ6nk4SW9#CP0gWx=o0*3e?L*L;Fa|+f2Emt=hQ3!-=&hl(8DxNg+|Q7Rcm!(g z4qLI;jaKBpZ5nN3<;O}0$Y-NdRQpuqp3U7hf6;H^g&qOIO_sNyou4GsA0ttC7B3Lq zWxFOfs6d^Y+-NzyI=j^Eyi(wEzOn&Q{j01Z{qkFkoz55-xfWoj=}f9Btj&34Gm5%e zxg_$c2;#eS?(L$B0XU(_5J@p55Qz`ubE>6yed}qqH&J4t*46%t10ZwFGlFd-4665d zH=&Yq0MCI=s;8*u9WNMdq}4RryQ5Imf>3Pjmz3rMh7)8$_Gw)3;9v_1N|&n*wOR-7 zKOV@5(uoeqRBD=L#$r;Eh;G=fof@36d_bJ3A)%haT!C``_zh==8j8b!AaOO(P4&}K zszNbXr)f0PQbswAh)LMzXhW-nuY&Qy`1vCP+)*Xm(o!lz*+iELXK}eZqqkUn^$?*~ET@tHCs_r5+xpmBdhx(-uGb zlxP)&ig$@nl`jjT04uRr7hGxb#j_P1ib4S-g(lFTm}+HX06%X&=kVsj%%*Kr&>vPQ zq;SJaoU5y?DdV^v#H^}ak2%du3oH$djVgW?C^WSZ`K%#+?X$DXGi&Sp zQT5PKrzny$(ayXqU!#ahC^2m!Cq(rwk|ed|$TXkij5OBpWXLa-qT|TcG}D?nx;P5j z*1au}CB0DPRO{&M{>%w)8o1h3vJL0if>2{&p2XGBTe(_`5iDGA*(mA= zEVuEU9G7yF8vGU|<;NtByGN$ev-#?^3#V5zla*$FOG`GeHX~I&U+azfunTJGE`xg( z8$7gtTDs*qy;g$ty(q5Q;P4F$h<8xR!~JNB_oFA2N@^|2NtZ+;r_+>k$7Et2I54W{ z492h_Jc+bzg-$dNXxB?+W(#B8OED$-~JgVy5cGGGd=dGbm1Rt=^o-Z*p8 z(|pcA2_SF!$8m}!EXqEadRCH~R0vvDoXqvRAO!=1s%7;sq%GaId1LB9JDY81n}6w~ zEnE!P(WRGlX%dftZANP5&w&S&AyJ*#vT^p4;=pJLPqI%wKtyF5iS*^w4 z#skD*!1UFp>k<@)q*940a~@V*XOE*$yvoH^yQsNsc+hB(K_-@g0%LZ2YB+Y5DK8|m zd3;4#GNq}6(6X}#;#M~U^vaYc&q-eR-?-vR8?0hwTVf?}Ix{Yrv^`se2F12L(@@q< z^TqFG9N~%U876UE(5!9(_nI0G8fe6|*P{`N^}<_GfgAGn;?}5G45VYsGO_)eH}CQj zsfj4}nL5dm!49cM34W_gOCJ9i2Zsu4vmw}x#KR)>Y5D-p9)23D{}?^-TZ_jnI{sXK za7aEe&WCC$C31rboy@l^KH+(BrAv0)HD0?u88Wi zh2D?nG1j@wEHBR$M7KEy_if?h9*(%ox1eQ`;K>O45j2eq8g#eGZsT|m9M|@fjyl^X zyQzbw^T~*EvsMx$#($Jc^&y9j$ufo#5fOq<1eolo{gUOiHInA)jYfVg1OxX9|JABm z_~eGECB=dAmXv_~he|HWhl~wW{93LC$2TGFr{zJeCYoP(onG|Zi9M<>pcr;`6gvfS zo{u<H(~0oW82i^`8lmH%h-)*0!X0mG<^f-C^`5#Zc%QiQSNlidg97EVdCsC>)?|iTHr4uSIpvSN! z*5``w$%dsD-VTYs_P4J`cMw|WoK1;MK1SkKmmtu*UZ=!y%4Sp?nc>`a1-p6Od8ysf zN=c?_ro276eO`=4{8(l`UFn*(eA=`hRVr#=N1Pv-B+aN)D8F}=7s#CWot0b)BA5=$ z>B5$T3LeqTGau-N3^eC2g&n?>KfyWBxPGrUbW}n8vS1=TFmk5BB18%nj;16EIG_q< zHQ3%z-T7DyIlsMSxB^XS0(s!`S@JsIzeHK$_#eiJ?n@ss2cy{#4JDzgXHJv#*LuB} zlKCk~B@BKFNYcnWz(YFCn43J)8JQvHMgG2{Pn;w=ADH6>wwrmAOyc=Co}s9_Ow74l z6uz$74>O!i#&!lSa0on!m%0>POcrRzUL49*uN0^em>J{x&uz`+%L*e?nl)``R@ZE) zm2Rifh!}CQf+}?$is)H;h`Fs2(p`fe3@|Ier7m!bW$*~ud!pWr^c%-TE5&7O7`B#+ zfi=ejT#-QF5@Ya)+;tZbs8FJoj8GiVcin5tWNGh@mhP2&F@r+O_Ji7V)`z~$yzz($2g}( z4!qR+A+(4DFKJp);`5Iuo+WG`=Q+rc4+nyB*$e6of@cg9h3vI`C>EI(TQz;P=VY<0 zvD_*%>m*{0MftWrqgNFCT8*=b?pu{p9h9hih~!_FGp(-GN#bAT(drv#&c}8OagNOB zh|qJqshkic-8~Flv>Wvb1tQsDfOkb*sr_A7gFup>PP8J3Xc^?z0))CFt}1BZ)B=fF zgEBS5a?&HM8eOi3R2BHQ%71eO*u#!XGqBSZ$=Zi33pjeu?S?fAZhDWz6&BEc?|5{4 z5{PE^qwe5k3|!uTz7-}t#biwpmA_+k2*{Z;9L9Gmh)U;HFzBc!z*G^Ge}GMv)?odR zKshY^F70(FghnI|x{$}D-gmPPS}!nc(pX+dKA^s&+|dlfzjKxNiggl~N+Lo7u44z! zF&qJrDMOM?;QjwdYTub+v|)L}E^{2SniKsYjM4p&q5XppMvAYYH_Y0CGtt9ahb58L zB!Sf-kuVA6>PSWvBpp$a;b{Ao&Y#VEKigz2t z(=bniO9CQ$LgLfmhyea6Pp9j{Qva}vsP1pH=H7YqV86hAs358#c(S(N@M*W*2UmC+ zf2$ertHtxKWhP?S!&8p=_xRhiB6vAAPpv4Oto4{}xcGc&Ab~FnE=LPgwttTt(K|Jd z23*ChXa#(tTV6ZCvQHOoa0xo0FDrVlVbWpSgK`|uQ4c(wa}=0lNsip;Bd!SH-c*OX z=|duil-9_$DAR*2g&>|F6xwEy0aufOb(i?iMLvg6)Pq_Sir$lZ3P+&Iay_$Q zg!9{3u%WbIt98VPxy7n@jFuWidFPVXK*9Jv_E;(+-v9mXG7F*MKW4?cBo(GLbpRbN zkZg!!zzmM!Pk99>Ebyo11wA68%qq-BA*5VD+ec3s$+GV>W;)6rl^#pL_0v=xNc&vE zhg-Nfg~?~8rKhFaqfLx8AI`OMF+X`?9mhjiD2`FSQs7A!_WuikYRrU0fv5Z{R1p9@ z%g=8`nA_BkJ^TAG4+%A7u|~7PcadqC&|NoQ70xRUttk|SXvJYi-;PETpQW#nX^WI4 z)hs7tAf8`e()SNtWEd2UhKa0NMX_%TYz#;Gkg)V++VvOH#~L+*Hx9wK4b>wPUGZR(JR`}+=+<|PqY)mC zFvy;>5Xq>$$svc=Wt}9fg5W(_3YQT4g!vO7b2s!3RPM zCK`V<4yhj-*@bH322vhuB%9IT6NX$1G`YeSh3p?tkmm4z^Z*sk1;~dYmF7tW#98pN ziRz$Qc-WKagbKV;ghq0!G@Y_o7(#B!I}x9YR%7}I5U+f=-~> z@K?T2GKDthN_7~>*|vvv;E>9FMjDdU+u0-jImWWH2Flz=wxjRmXpc-Q7wJ(r>L3xv z--Xp$p6+o1%L${qq65~>6`bU|ek0qU!eC;o!!|!xWY7hZM{PaOxM4n zkV&Ni@T2;~fs%&-laOP!Bsiwz8}bImK|G4HDBVk|^6j%2Ayz2d?Qj|~SSl3pi<0}) zFaXoYLl&~4!Yc?pEX?jNVw3fe3sbbLAkPl6CPJ!4Nwp7!ir(;YJk?HXt*?y0+b@7~i@vXVfm$N7 zy>3b?(~qcUQ4b#%WaNrA{Ksvz1)_ig*Ff<(Q|OAH_o5qJ7irjzQ>6^LOJW3Wt?*&n zjOgQ$sK;6numeG?f4fF1)yfmfSQ~TD1(sIgDsiL!b!Psa{`+d0)RftGg*TtabkPpXOFIU7!qik zCdL|R`8EjBH&{&MX-2S%hqRlW;dgUj7a$=m_7W!8M~k$pB8_EN`YIvS_#uVHi}NfI zA^mJq5avSF-Bq&h?Zx*MO*&e-NFx89P~!FUElW8JxxdM6L)BR2x*&e&mQMHsKl@(S z&$y25t_41j`o#S9acx+B9g%Z=ATMHJhKwHUWoy;0rv^&5qBmSI*Ndy1A{gUTNN~Fg zR*TYgu+z4W8OD|T<>o9Ob6-2cnq9IwjAUqx^=t7+qDt-coUUKZmLioamaN`Zo)tu{v#+dQz&_&0oI)u%Ku)S#lpw%>JdDmWb!uvF|luRBV+k+(obd`@ivevgKS~I6sBDg$)1c{`y5{%>LtE_}|xm zfUFe%H>fO9*~3TjfsyEw;zfY(qx3a3gn+~+5saC3<nq}r#AT!pg*s~i9&h;h-Ec{ViklK7h$G30ji zC+w4u3B?K@Vv(0 z?{6%R!z_?+{+mRmL?`@GM zThPIjYP4Bj>vW37Xqvu?Dr$-*p5rWVk>QMoPREf`A{-nmH7=YArmUF_wo<+9r_iKH z0Z^7l%xqmnIdOCP$w1M3vX-JyW!>5X3~+E5O{|uh0tuYBIFc8v!qZFJR5`VdOUm-` z4KnYH8-H1Q4h2tB$WQas>%V5`o=&)%Q0Yfqj}^GUG|{)lE?7G7F*23dra`6P>zP;lwH0?TTo zXjIS-&0c~~docUOWSrRI)>7*Z+JSkp1bRcRz$%^rujV)m|!m1QVIPYj$Eh-m6*AKhzm?`Z2V~c#kqtMI`5%)!|cebe}g~bPV z%A?iWhvWUkmgmei-l#DujS?f2dc_G%Q2ZqO6pyO`5G(edz%h`Q59RYD3Bd=_;>T%i`~`6 zRA+mO2M{xBDCkB!hxTN}KJ|EO!-QR_W+UQo;pas8URj#3nGT`DHEkOIs-W!<6r~6; z({XFgU+MdI^syE7sqC%^`m&dD?EJ$P%;f_DHC>f`rU&kSugD+O2TFqjA`6zJRgD{4 zzB&08feM=Hy-;rKU5w>*Od`QGj_uf^I1hbyHFk*i(>;L5KVB6xVGv4YL=>cV6yMB4 zA5LE-pN2_$sr#2>LiR;lq_wsL)8*UKa@Vp}o2brzQbCm~o#6t}{-l%0HQHf@zneR5 z_mV5Rpj6l?wU}ou1*K7F#+RrmsLH)$$md)(*yrm*eZ;-s+=A`F>{0Jo?cwa%4Df{h zL;5D>Hk3s-A}8V;;LJ-PBSnRW3MCdq;`=saoE5vke?k%%m>iJXL%xN#3vvy5p`aJ? zOm>ZYVY|iJlk)Q(d4EVZs+dhumeLe%fR6}WvVP&A4_(8mvuC9&tstsnNJ@;YfHoqI zOO#cHH7w+z>{MG#Pux^nO-$5PX0M-%O?;}bq1klTTMS zJV{EV#&ky5~>p)?!QJznZ_W=3UYflUBl zc}6T?(^Ps4-8op4#q^NK;J`+r zR8+B>>;>66j% zpIMbR@z4}R$7q>XIN(;MBhzLd@gsHefR^gWWiYZk4DCAx@k7F~gY^E^S20X9v86zG z!#>otP+RJZyS>x6_$le}?^b?E zd$@7TPz3^Vl~Dw7oOoq6vC($JdQQ>P;6f?f!|vPtI<2fYSU2UW*yGpjPv%v8S_#=H z@#GGI_5+WFud<7zWwTwAIu&nxz({qWiuZW-GQjkfdX@Hi?ri%or-Ky#mA6klSCA)RV;+;J3L|btSzKO&lH97(u%Xgkb)95?4VEp>X;jXt8hhUT zu*ErkqX=dMM_p0cG~d2BDNbQcuT`TR#m0j4(7Rm5QlD0}=Cj1BMY}jbf@a*5r&t$M{%|bcT z6f*hEO~zd96()Y?vg8r$;xw;bwW^57!bBy?;ILFpIn9BV>zmSw@`CEmlE){=VYzzw zV^6(pdz~$cWy6WQmzjluZ(EZTM*`krtF!7S(-X7y%8!F(P+COOp!4D>tq-!ld+!70 z28(47YsT{y=H+Ib*`#I1Mot4w6O^0a{`5{omTWp#Gi#XN?RWU<&6yF9)W@hAwT?)+ zCotHd5%egL@Bx)|k_`d%JS)ZakR4mF!a;lX)1 z5`>WvUa@kUWZX`Ul(%_#h|NztAEmo(znie@WL{<|9IH5;DK2)hz1+`F1EKSxQj+W< zKs6cZ5;RHNmLPK!xJrf%Q@iq?Wy)W~={Fu0&Qc6=lV{EOJogNO6}Pfd zR2mdle(ab*J!#xRdsAncOtR|sc5CboIL!Uq^82pY`2(e$uw_%=Di)R;ct|hFH(cRktR%Z} z?=UJhU>}K6cvk^~2YRn3{&$bXA1{%-0rz$(UN)Y5ZGtr;K~62&f0~bAp3}&oS00pO?EE=s7~UO)i1Jpl@iB8M zd>qJWf>0z!$~;5o975V@@r^U@$Y=d9{R+~(&;~lK&!Hot*sHL+)>Tf|`&Mx}&-Nl> zPLQjDr;-=_*i`^&ZOoLS^;$JMCFzLb4_Lv5eST4;p5;vLBe;vB z@HC&QTwA4y8NWPRhC&hZq2=gybwQk(QI#P&Du;<1k&kB%LV(58W9c88_!#5X_2czrLnbKM;sj${$p^h#ZW6HM`L-u`~3ITDPqX@>pL1 zJn6UbFyE2gDYq(E-b3mboK^D*yFaDJC=2N zocT~pi+fSaF^`@r;kfrUd8<$-+q&1IE(Ddb#3%~te`aLabXJ9BnCK}yjXRi z+HJ*K9J_CLHm->XhzuTpe63mmL$*(*RCQiZaL)H><8eT_=z3SS_>?$g@7;yv(~wcd zTV!3Co8G*z0X@CzxV5E3n1{ON6QbBD z@|2Dsu~T%(@qhVc?F0|#X+-P>dabpXeV>m^!->$IW;!$X$`ad%*y`rbHbFGWUsl0z zimc7DY2K=4ezW${GFhO<^Ao|t8vk77#Jyb3hpSEjrj4FBj0Lz#*2RuPYVZZZHlnHL zHldM_&lQL!_i3KgTnGg*RmvNR>%|jDgjtf?7u2AkUJAAMd3)@x6kY?O$L$;T?a{9_ zz$xDd!GKjc22TQfPr~kJk^E=S1Y8}-Kn<{i_T?j#QOK0Q=(0Q#TVkBpfVhw1@c6=C zZ_e2}C6`%Fsb`z_lz+hlImWlrPTL!dT-wdp`QXG39ir3F>ieKE_8@|)mf4tw)6uag z?y0~W9d5*5VoQs>Pmb8Lvs?PEE%$f}6aKO*O35N!A$D345)$gym zPQ9daUhWaSV%#$s)sML*sb6i-C?wpB%pLxL1wMEomBUr|$yrJYqzKbT8kHHU_cWxK zVa!WOTBI(~TN$qn4VduB&~ptxK+dO2UNhpDy!o9zOa3#yplTh{)%TarOi=|@nkw>; zMsi2H@-2lpwp*OCvxZ_vnc4s@=kiLjyJMTQtffBDG(`m7A!tuUy$E(FBCJNyf<sdA?J~^-@yK0x!iwigBaD}(LHr9H`zX3G;RN6B4y(Tg3hR%wgkt@Jzpsnz7 zg->ROel3!;1cl?&?4k(RH7;vd+Z}@15&r!IJ}a-eCL4AigWb>M6diVk)HOB;p0!%wJ*D z$IoR7k9vDQC`Zdjd_gSvaUjQ5oAow&DO7E28RLEJg#Gs^C)ok-En+L$FSYXId}mxS zp&9N|eI{GuDV7?2#&1tdANMnVsW;M>9HxLXHvAr%1}RXYn=IM8v~>XIh4|vd=UTV- z`QpvHr`1w&lQpyx{a-K0N8ZtNVO2Hrz=D`l-z zL7IQ$RQIM?q6~|zpy4fqa@m}qN;ADjC}?*~=I)I~QU$AF!8ZRJ`pxH5p{N>B(*{t~ zC7JP9aw@4pKWVH#5%#Pik)lk$Ips(@FI*Iyifdx7=bm&5kgR6x9DhKVH<8?C_>47j zV0a8^dFpB#XX6ReCE~1Jxdo)`gOrq`}Ow=}2g7v5*Fs->r zvhYDE{h2*bN*GgqFmSv8Q_Kqa8R{M*%r(m2`65*fIF#41mq&0a{NiNrfhHs*lN!WQs0Tw9Aw!Vs45&SvZTF6HX>c+z>NnhB4g|OJPc_#s554`0z_<4pqB0 zvuI}j0m?kL)X}GCmhZ?m#CT4lAs}i_o_&f^W(MZrPi0QE8Oo=xvO|+czIc9mLZY=Y zn`5~BjMW)-o0d}%$AVjfvQu%pB3_#Y%3P;8-Da`y{AXFhQt9nN0mbQW=2VuF(gwN7 z9I!={2DQZ*R3#A&B`&TC&xH!02B|=^c6CvXg~o@JwyZ2!O4DL>srJRnhXQp0kHyV} zysLaKb1tqzmRaw{#4I^ayaibHoUEMV1zdOS#yO}n40k!4oa64M$3vm~|S6q7@ZJ<@!$}mfLao_ji~S)Z4H4 zhs0Rs%|YJPjUXXt`G|#tn2M_++s$KMLuQ>I0&o z{5tqOL1P4wkaN~lwNiV#^0N>R*3#92sX^r^%=HAMc10D=!aKVV!V!)#4pLSw*3#3= z8+HdORJG{BkP3uvV}3ULTgZ*8g@~-T zmynm1&9dp{(@QGrVdhyBW9ugY?qZ|Qg4E-^sg-1MNAM0A)!Ce1xVr5vWMrC5wm5eUR!o)hO>Sj?KO=y2d2>OE-H-n$Wf0?( zVk-FXUE&!%>B^m3a%6x_wbEofv?S?+t3+HrU%kKNN>|YWV=*(roI1bl7>~bk@0w33 z4O0mz-`z*9(nJvpebHU`afc`1YzV!q#+QN?C97)G^&wiN48!aUfo0Rmk}aAp3x}TS z2!zUwp2`h0sR3E_Abejc2(4A{oA=LV=Gs!Pd;^>jN4WElb8@tVY`d; zddiqnqkB5em|j%IwO%QEpWJ;3%`JLTcZyNF((=ZSOg23e5PNZM(|`G9R>klj=g&RV zp-Dw2jiie74#^(PO!S78mP7bHME1pw)2-lgs_xf!rYdD67}ip}Pc=t6qCiR~=oM?r zDqs-o0Jc;F&KH#_M*1!l1`o24YG0ew@lu=+e!WMDtcE?g0E%{c+X>Ms6m{#~uWV=t z^j2&xrT+^{d&yfe<+Q|fkQgk^Iw=XJcnS734fu~b4X9ZrqNS&;<$3R$inp%=;3~B9 zRpc(-@iie1^|*Z4wi0UitqP)J&Y)xN@f#kz+QUu<(kdmMCUgl<$Z{pq%F5+-JChK; zoI9$@*&EY$q&XcT5=wPyr}pq(o%mOaQm9Bd>2Eakki@r2+0?f$`Z7x!J?XhI!!^?( zRa>grjXItL3Ju*ry=aV0Z{g@hQD23WM9f?qcHL?fKsSHtpTgJ&Iis4{R)V+(-Q%nY z39x$4-k)iLEtH{I8)-N9CBwhr3P5gT%SgQ#zQcJPS5JkWa!|h{_Ouf9m4(5`>dU4 zU2Uvr|Ic*j|Kg%YCTTb#3H@-<=hvwuDBx*;2>#li662pzOOYe56()9`6-N4s-+GoHq=i~?VtPW|(~ z|L$tNm~i~}dOe)|%X09U;*GB3mmQHJI%}S;U_w5mWE4FLwg?IlN(80o57>4%AWWPu z+D?@M6^dZjl!R`lOkU$K4KPCtW<$;M>I^1avtCrw6BJO6~H-ZCp<`k zpRHi4+OY&?cV0`gHY&lUzrZ#zt%8g`9d^o2eKL}>Xv$hpAnXdUN-d3DI_nEaC>==A zU-6`6PfDARlq{fL7j-P!I|cdUEIk+ru`XFWqLnta0v&$OVIUi!)|{fqw+tSJM1o? zzI`PfWK@42UMP7sK0<;7(Utq>fAICzL2(4#zc=pg?gWR$U6u`Qi%YP@o!|u51;Pdb zAwZC@izE;rkRZWfS=_Q{fFJ>a1PLxdU!Lc8Z@u@Qd#k!mo$l$HoE2- zh0l|7p-OrnM1}bGDJu_8Co6ex&JPC9+$1~)h@&xWeiYR$Po<={7BJ>++b-uqSVW|7 zw<~tVp&}bk5!K1a*#*P_nWug2D)X|D7I3fbR90$xylR-xF8`TB?0Y_NA4n`-3qS z-O2nc4A|$}EXy{wwhtoS|KO8>Zcy(%Po0{6E6oAL6r^{g$aGKC`&$Z&LEcy0Ve(4y zFYg89jl*vxY}vwa)ATAkNL9>CBZ)^yGb7`Dp8XA|&hT6#v7Is#Fd%>JnUzSV*O>JB zCr~fNOX*uZ3>}DH`+5hcF2vfXTRNM>7Kmm_V|&s#2i)VaG1{TT_kF!%tj^5Zs8c$g z)J&0`SeKoE=WvkkRbF+WS^IN?qmJd);^nD)Kn&mK3Gvy{7CZ@Qg-V@Lj0&$%F!+NP z=MNeDCfy&Qfd|jQg~10rKRz=y>dkQ4F(H<}?$Kqon-X;oF7x(3de2@qv4v$yPP~?! z7~JY0%nYag_C@Q0s%uiH;m6B;$9=N)(fhuYh1#IvF8??YFgSU(vS0IhXdz8Ai2`mg z4da_scM$&hdLUFEfr)b}=A^STxx^{f!ka zmk(vB4=tV*H`I!m?5iJ()6MgI*0>3()P?|_c|sP5JD_(0=|T?}_{=dJqXk_?O1-+^ zxgq}e`{FZ@(UTS=7iaS2-7(H9N)y&T&c$7#8)l;{LC$C^Hp;u$|3G(AQ|Gfa9z}h< zAJKdN_XGL=P)Iiinf{;IdROqMVeg}+J&4%+w>2%h&r&`H( zB>D!Pq^o7mWIpTLUSY<>D?U8!l#~*Fp8akqa!bkY@Amf_{J19<4cg9w7+q@LFYA)+ zh$Bhf1#xNwBcEG&tA-oB=f>KWp`j#ymL9V|oHhMQol~neq68V7$m!1Cocy~uT;dnx zJ2Q;%%g^}3S2yL|`oaZuv`qoz8{O{~(cET^@V?!}N%@aPTp8rFkg6_YeCKDzvP+cn6_w zw};1pp96YcalSp)8px014_iJ6{o=jX`OS^zdOe+7<)4$2Qv#=Wo8^{$GCXn0UIYPGxJe%blbGv0(OPQ0!Am*8p)VX6TJ>anPnAU0%Tud3 zJ|xN+5Lor&MjP`r8rjd-PX)TxN|Y3SH7JwlPCDLX!P`OH1=2@b6BAm>wr#r(V$s zvfCMW>zBx0efmnIZ?+|e8;Pu!i~KwqDB7TbFqs@b{_19}P#s~RULUw9GXkpqu)pFi zE;gq1#U{7ob}qqfj$j3rL;tmU+=*~c0_B~>3<#;Vce`l&JDoAB$GhxOIAqr3M|Tc_ zK8LsH_)rGnGS??!;9_gzikJOjEHZv>(I>A|?Wk<>Rk4oa6%FS(;ByP<^xJ}*Cq9=A zx=ZAO;f7C3!gp!;-rE`?Pg^*Ua)~iWg*iiemN7woC&Q%Aj(jJ;oR&p=aoyC_kdUa0 zQv1fkc#9nprnmCZf8^RvT!~OowaM+S^cFq!<|R$G(;51R`X`seV~gSFse{CVTJh7| z@oB$t28l86i6d*j)+;e7>a0wi>e*n%8UybI)t1pc$qn*J%|l+8_2Je>EP|uVLXv-a z?cR0m7p>mi?PPM*d9h0t6i|%sFRmzXVhtC(;Xdu#f*oE_<(R9LOzb{AC6~O>@59ia z1}-IA{22pg3(uq}Jl>nWAN3gjv_iveNvYr9`7sC~QvD%{o{7LtBb-svv)OdIN@%Ae zW9Z#Qt~Xfob~&age$MaVV}|cy0CHfV{15>(3~&A|mq$7JNvDLFU(gt8(fiR(YCv9* z@6ulQhO_tJ7;kZ<*En`XY%pB(k3U?QT^sKz(9#0X9i%w<+l4WjEdPuTJ0tJuDZ_J^ z)$)4LiyM{cJtVjAYVhwL`bUD7q_W|w@K7j?^NpwZv$=3>o$x!;=7Mz{MLx>k?mLX?7vi_k`%9C1SN0q9kS_HO)z8y61uB!zv&<_ zn!dtJ==(k57CnV{J#w;x;}re?&K@F^%&J*^RXP|qK9mA!(5^guWjsdBW>pK#5Qa(W2+L9<9k)>^vOc&K-Aj! zou01r@Va@nS;3Z{cJ?4DBqY67xuYwTb#J0CvW`=J_zd5l12M9wHVBjKFP5Bo%bZHc zLKn`M_(`f8B$dVte){IQ=+VHQpwqg}laA?lXHk}rUr1WHU0ZMXUgxaD0L8ZcO=}YA z*ceBI2LX0p4H(MqMH}fsoq={Ma)M4w%8X5gcBm;rOxW@~=gKb~c{z3}@(+0m;! zKi(gC)I#lzBahGbzS8tI6SVW+m^Jg`t?|?&^$0}p|B6{O|NlqC|2iH2=S+NMMI4^f zKdZ7m7PT<`^>zJgwH8fWl0t)oHMUl5b%LxU4vN>+!oztkkEMd4-N|vZIqCf`Iq1dW zIIyTRu3mXy5hXMdygb)Dud{hp-F$!jW6|QLS8eY5f1#481|@?^-xXIC-6x9P$p^Vz z=ubTCy?cZ4nwZ`ej3G`hob39^Be*y4+z#=w(C&!4rJqp9-1RNCUr0Q$pWc>J6ZIVb znhkzU5b&kMYpie8>w}-H>S&yGkIBq$`*69}49$JOv+ZVIjH_xMfzVa!e&#-*y>xs& zA-yuLzu9=(EWg|oJ@2M&R)nNbhbpXL^6dxq`td34BqH2}u<319rL~=W6AjXiiKHN_G$K~YOOrBN6E^|VnolI@mC`~UvKfRbT;GbEh@EfG-Xu1?n6A<0u!=nBSx|BmrUHjPlu;rpiDpw0 z2!>8Wa7#DnG(qR$>AtPE0ZdlNx0DAAe(seQc+Z8;v8%CpA@$))=~u*CWI{9A2-A)Cr{IOY9JrM2VBPoDt?koq75e*6_{e75304z+MHD}1IIDaY+bs@R% z{NEB(lIneuO>7#`AFOArT3?{is=kFpmZUEh$5%=+zu5Qc-qeE2C)@HP<68VUax58P z1HEhDK8fn|M014KUyCIxS7@yo|IpnVE;lKQ@6#Ig--OlxiWo&+)9WgM^-2>sDFl1T z2etf-Vbb#UjPA1f#Qoum)L4Qs%W1Dh%}oPP9t<0C4*{qR^gfjD7XkUZZ73gNp414K zj%~C2oF;=aj`=;*eLnWV_vUTYhF?B5uTn|JlC5k}oKw=-#qt5veXU&3uysvd?f_b% zp2i&W;UzO9m-z!SShmP`cH2BaMx{N-uQGw&=jO%!REO<_IC(#H4CO?%bVs>cz<5XWfj{B&?OW$#wELVGz-XDd6uTjjdb z8=#_h!{l=r@w;%|6R-Lw^gIP+>#TYQH?1QN_~D=P)FB2)jeTckYRHI3Y{)}Ws@eDSrmt#{l5Xf%7}kEiraaK!+A)iKF^+);!UBED{XDx?VZ3)`~@fI{$hd^#CZKS51WA z*`=4i7f=Yz?{Cx!r%lpoPWZw~5-=oW!}*6nF0}HcQhCZzeEVjA0 zS&Mu=2Jdai(HNh)0QpwZ-Z|X0rmWF~I`JYWvfI6r+DNZ<8Yy(pcPDCXIGg*XX;a5% zvKjWMIr+;UKXdvg(Xe9Anlip-=xM<7aVPo^{!3+CKchj5okrFO_LLlJEzVilLf2Zf zymTF{QZ2dycS%>daF$Ofkfx1psOTfdf$-UAy$*5t0#7IIl<&F<-g3(`>Y6jTARq7H zpPY)IPm@-k&AzL@{5y@a8Tza!(^Q#??9$fnvut($-g4`EPRVk=+X-Ni4=t z(@eUZETm?njQ7Wh6hGVCpbQJ-GmGKR#r>a)NKJc^-hr`+<(RO*_^;|2=G2v!a7pV) z6YBAEdpJ{(;uDh-$iQ%Hi=LYzpL^AsB(Yx>S9o)9%)NaBCaN&i%u*ShFT-P3KcLb= z;XLb$j4ko+99dGTY;`j%@84~p$fE@RXn+x*PwGG{}}v_A*t3GIvi%L@sx-R(`^ooc?qN4{IGrv2>G*0NCD zTReW|CV5be)2XXj7I_dyroVu&T)5X8-dYHK|0lrEE8+8kJ#w-0ZO`b_qa3KK!xoBZ z=vN?LT`Yadyx+kWoQX)JlamUyS8-Fb{oaFBo#!t+Y z)@{PMD7u0*p2p|=ESB=P?$oN=@YbGTRACW&W3n}Niow!ln0IptyH11efQqF6EPB~4 zt`+dTOJM8U0qpeP$^i0oHUnm&a`1xY`fa-SBb8lxE8+!02jx$(rA2mPbM9wxW>hqZyVVK<-!Qs8_Rf1G{%5+)b%om-Ddvw0&&LC$+I1U9#!aLo7a8tM z8@fF%VhiqU8XP<>O5Hw6c~9<(mu!3e#6NqTyS#ns((fAPxxh4@>rFQ`Hsh1wChK8Q zy5KR6=Pd(n=qjl2oC8YwIA2w`#m?-5##iR{&Bx#W*l%$&@|Y`M5FKy!3QcjVmP+?* zp5JElxFNc;k(u5;9&p{XvG{%JGU&?PBy7}hUvNHC)8LjNgSYB+k?dCDaq-^G-|HgV z?W45frv=FPg=e!}gF!*<^uF78u7^eSg3|a0Pm50rR^!lXC6%AduMbXt_bt$>82J^2 zOh>T3V|{$3wHK=YvzHRRdN=%QRM)Oh!|_-6PE!ACC^eiu_ZPR-%gl}QaGcR2PvJpo zt9VtEKsepU^-(!e2bAtD??g}7k!BRT``Y1ivU|+!b$2=T2dM0t<<4Mw%WHya0Y-yB zXOR%3g6^Qk3^Tpy6B+a@1CJQ=50kAr2%!6;RKxkX0PTiELF#A~mL=NkmU6uJnTP1- zQo)Y5UeBeae=!klDA+*1O%vG~eOqH~q&qBE48Zp7dlgLXS9%j5shs-EL(H#C>zGX; z>2mT-xN6fnSp;3!R8UL$#G0Q%X5>ytRO(7k^qJ6-Q8yC%EYhbm^Vs;Bnyvi%F~uD= z`Lyg+3&p%}_EG9is?kd`AIjx=^Rpi3b)qPnGt>qbvr($8k^ppFKpe{`{mYf9ajN@M z0Tr>4qoRDMSSn+<{TM2*4=c)gW?jgM@{y_WYp=K0A+_+B^b6I4Wev*V<@r_fe9~d6 z$kk)%S2rE`uSh5MdkdBx@;=BdSZd?2-}qKrDUm&W`YKH>F_uDX?c+M_t$s&ZES3M7 zLto@o>lMa>pbD}(&FEO~7&nIZKEom1|G0$e=-Hp1SRMNKeSQA+?AOXVBPuyOH*Y|0 z#$U&{^TznTvFNaF^6O@4A539I>oYvxgg>_%eyCR(v@DwHd}dO+Lvq<9X2UKhZ1T=>Cv~XHv!KnLQal0yC6a z&@Lk?Q(SgDtEd`yE49p^{T7<(#+3L+)0tshMsu2FL!rPu2OYH$VdJ=@7UQg7&KOj= zm~Zr0*h0q)B-)Ysm}iV98{j9(Ih#)&W9XNp`^*thyu_gS`iT@x?!J%9JIAJX4-QdL=v9a-o{wF@GU`py6?8yj@G?3pi`*Bw(nza0)w!Q@1J7?pxh!IydhpFm zVLJvybipnbG8j?B48+`52#ely0XId?pBf$fF?I9b0dA0+&g`*O-V4bwR7Tq4KtiQ5 ze!67Hc^x*+x$3ny@}K{Ia-biJAN6`3!G2+nO1%H~9H`*`@jdAW359t2K%9JBK^~C6 zN5Nj#K#g!`*XRE~P4|`QGowe<%6sTa?pHMd+WrV@wdc>ioF@<^#0fL#eG((^ieef; ze->zPY4^USk2-R=+DUw30(+uzwUa6Fe!+sn6*R`w(9{0++%~~Mnxh| z`XXc%>|%o&=V46OS?cvA4U<|jzkbJK(()r6xMcYoh}A$iCSK0e+w>w@uZ8qyR$+xX zUh@RnU;gV_z#re^HZdo5i3$hyRpB~-OVsdcK>NhEz1~j&d6r6RCa``up>;s0kF~3I z-fFhxmkHOVmbKRMLibd$`Kb#!Mos;_M&)n)6ir2}NPtyyMfl%CU*gN;Ph}_av{=K0 zg2Sw?Gt~>E(5kOz=?3m~EsP01wbqn3Y$2NGkwSyv=bw%YdouIoz2KQS-df5oW42cG z!=!^@LhEU@9Iz7W26%7P@?T-0`@f%`huHRkpvLKXf5M@w6i`d*0ZMJqpb{O;i#`g; zv8psTtaOFk`l23ZR-t?zsZ)7WE|7z8pqrE?*ec(Q)*=M?QOVVEwV_018bhZOduRH=r2qQfTff30`>y;Pabs z{hS?PH;?Tgs~)amp>pv>*XM8LaF!U5PM9C#&M8zg(#UGKmPhDDV>KQ=mi<0fYh~k^ z`AJrsbS4U5q*6L+6}ocuI5PVca`#^)9jQ*`)v(9Jao%H!)f%eOF%CETn3fBhWM~LjRL+-f6cG9@ z=EichR)ugG(a^p$(;jJ}{^^O;*+@VE=cj1#%<2($i3`a34cS_pf@ku7nD_RVuVck7Y*;E9ye zmL60NK7Dj!R2pBNbzAS$sgnLF0Of7@;!45D;ny0oiY=-J{{#6!_ynPk-&d)@Heo$^ zHevED+DiEbH^Jw&23fWu9X(zN#qCv(>sN!^ zAeVL_JAP|-%iOJ+5sjeF+CmX+Mbhbc^a1mlGV+D zdle?}(#^5BHlNJC3J#ZA*V>e?)8 zT-?v<0`ALjID)1G&g8ji5_t0n*!ldGC*?iHyGr)vt5aL%v!~bPZLts#neQz!GFe95aZ@a{P-z zKXsT4+k7O_{~F624BEE@v7a!pY1QEqGnMjt5O7pND8(YcGxbT?P>EdHvpcb~g&+0M zJn-ammPlzc9+ta;NV1x%Z;UU)M)6x0;mo+ z?fM%`GAP|5cRmQ(Vt-2>nMKqkWL>~R_oQIN|*ixlD+2hZLRTx zh2Y!3l^W~qG4!jI0YXL6K z=oy~BV3U4Y;G%l&is5JBJx4{GCj8Ck#XDWmj!x5g^sA4dR@r%VDHK<`i{44>n@5R? zA@I6IJ@fU74@7c1DP9J;W^rfdQ~vB13D<-=4n2hA(RI*65TT-KJoi^JcP^Hzu}ea; z?Ig+1OkTg(2DqSYWR^>=E$e=$Cd^B_RC9B2+h!;1_brOI;xq8Ii5dl3lUm<c z@rFfDVLTs`oLb2GVK~G)9_kQsWvZ98romwSorkKDbz+5nY=!<0V>PG?G;EoZTabqp zNgc|v`A^}ue-zQ76mY90Gq+Ka((#z>stgbMB!T&e)s%Y~=dW`$8P=(+3l%4|bQn23 zS98{FWdlfm3Qx*y`{sEa1TZA|4XA%d&^h%8$_m+Ybelcq_!WC3YMYT1e77-_GCp0L zjFCiS(1PY%A|N8aAQr>(V56;Np!dzEX@5-@qo20iA{d;n?g(sjwq|G%PB zn>&I>@bt)-(5sK$xvL~!K^IopH)KDYmni5=#cfhJz_6Z;5^!?M;i1=GlzhU-HV_<* zzh>m?2Irp z6B*OzoB0s>8!l)hYfPfjepfm@Nm%c5gL$RCS?O}@n#m0|)JFIv=f*s0pcBdmS*0`@ zAluFc+yz@HQ#Lp)2OpnxPj#X&hy4E95cs6cW;rE+3U zE&R{`0~m+cx)oJfDYw;Yb{JTz*6R~bn3*QV# z_zM=B-3D~>;qz>DhMPM5b&}f4XAWmJ(iu|>peG#GmR;#h`VELXT>EpathC}It;#{( zAu*7wZ?MJYl!ehmCK|H)#BR+o>C^OIUK}pVCmm~!c1yRLbEHdyV=qaf)>&@Xl{kYi z@%w4;`d!s|6OF~Wjc7iE$GrR=-K!I+RnR0k*MV?8|J(CUMgbX_BX9|&$-|>Qmv?AW z7CzQBdZIL5G+`2Eg#vp1x*U($Qbd&op@%h@Db|3y%xi24J*X-NP+`7C9w0#NHw87_ zlRl+vuFPpC;}0uZgnej@U>w)pDz{z%9pXF6fx}?sHTG;$P~jEL!Sp4>r|C_+rsAaH z3do!1YB?m>-a3(v6Wu;H8Li=TBed@P-C|RD;!Y>$7p?1#)4NZ9dD|Y$SrGs7TUPp- z3uE>b54cH~=b!9WMGzjo35S{lAC>Tqn-zb});#E|G%`4=Y&f@c>+Ya^EJYPTwrS(d zRL+q9PCW76#vkXo1beD4m2$Nh{MaBPOSh~7E)S%J+dT=->D}jAXD09Uphg;7e|VYW zB;mVHHW2ylx&**>zRKmR|)(I4MU|94H)|BBK7 ziP!%Vp<#CT;THWDq@m`AQbY=a1M!ULpLvc%yz;6Cwo$syZ)i)wqRlU6j?UQt#ZmjNM zqV7?mSnaWfU>#)(g7`^5}W-AE|2PM!1=aqltapq;@8}cvaX|;N-s;C#Jfw6HL zrgKm6be30~N1XQy&mW;-gX|??9aSAX?Z83~|FPFDA9yCS$Ff{L^PKWpbLo`w=<(|0 zxwP`&X0uTI9)GTbN9ds9mf$S>^ozNSp(m%*_Joe8+4DnX-qu{MPr5>HmEn!Kzqu$) zDhyJmEL<;N5;|TA9`JaI>F8O{0cV!JyPPWtgy#4LXD{_<2j?OVs7h_QlJ#5@^MHSd zHUs%B)mo`^W%(_Ef5Jr z0=@>d(vD#8e*+RGQjzguji~V_!bzYKI3r+w6r3a_P%(!Rtf|h3>nfEa4*nY#$d~g4 zJOE@Qcg4y{13v+_5|6m>o5Gh!H`(|v)mzC&%=j-sX-N{KBfNwKM4MaoWbU$8&TpX2fibB#mtf8Cq@V-oB(qA!EEtgaYo9(Y>6jwIec&>LS8mq ztemI(I^bM&9cVTdFRd<9PB8x{TsS2g(-k-8Em#6klaP(e%RJ)6?+vd>{z^6y!Osl; zt+qhmN}V$fZdO|$a%Ijr00$!W1uvZ`hdfB8x)@e@cI zUH}%Ul$oIegAmP0i$q@DmGnSg>?V7B`uQfnuFUxolIWjmCA^VghggA_R1e>opie);JTCu>=|anMREl7Od;YTF@kvJ z9_*j2fU)ZfM!}(=S8)myyBw8?2(owunq5F83b8^Kf-{o^)&jDUhLFrC!dD1Ggl7W4 zgP>xJ5Uv>=@L_@i<1S5Q7^o9}w-bDrs6e}W2j)f?CMvM*l2jUl-PMb6Lu6(=D#_KN zDRx;ZgAfC1uaXtWcR}E7kR66J*{*tJI$VV$M0`dIE*gK$KQjndAv-6mG*W++Qh*^% z=|weD0e*w{pk|O-%z(h;Ad#d9 z952e5GH^N~S4||@2Jf63LA4gPJn-x$q2AWfOQ0J_quRyXKv#gU66IQSNrbW3bPkRjvZ>*mlXmu}Rm|GqIpM z#@$%>J=VEpWjFASb(bCdkQ712lsJI+2gg+-PNKsRVXz^PQZt2Dp`|<&q_7JJ#}nK@ z-k2gZHhLbl@Fr*|WupvwQQaHAR=JT3t)RY#bKvArj0lMjC2Z6~*x}U*HI5?eFb{M+ zmf?1|wTg|^i1WBPY8x?+PQ-b9C~2cN!Vdo+!b4WAozlj^Ll)T1Xrt=!O>K|-z`_F? zzKkbAVk6f`;DL=GO^{(&r0@VCNE2mP77x&xYRrVbG>wz!0kwAQ#bWe;Iy1hnQX?Vy ziFzTd5TdCNyufEf zB8)afjb=@x^~hH8;)i^ORAqzkIXH)wlk zDAA%2+CKS$sqqJ*6Z62p!yg#Qyr_s?NxoofyhKD}9DqF7fj10`d}x*A3&zH2v`Wea zZlff6LcKcPg1DBS{32{ffD2wh&zF=)UMBHHM5L(U2jjL8*(H7k$-)cKB0Dl?bZ8Lb zThay=~?|662~x$l<2VDM$w6XCF*p&FXJzPgM4p;h zvOV4%!&%@CEm{a+39N(0uw0v>OQ828XYL49{5zbpZA3T5oyLwBP?hk`b>}0z8|%(| zrw$m)dd-YpO}eK$`-bSozO&mo1je#o^tEz zrky7A9{dN$KklCQtPUPa+DUoc4Uc^kpxRjlKCoSrqhpiqsn23T4~*Bb@CU3r%bjlE z1M4+A`XMQX3@;H0xpKtmAxNUc;bzbzAn5@+Rsy6L6iBe4gs21v$^(;|MpKWW*0B*9 zKnarpEcSZfmnp-@01CZ3I2%q3#gO3m0794^#1^ki2sR3_#oW+kSa!6iKZNkfB_pq zk|547K*0clkR*z;3>*M7dl(3vX<(Cpfu0uZfnvZwF9W`_5{wY=q&FXDLzLkSL_a=2 z78dEaM7*KGU{T+)$~|V+fz*h2$|2800i$;V8vACL~r z4Fd*$WH|GHB48!?m<@IbiNe?bF|Z@A7zX$ND#^!;uxWrw$}uiX5-`zQ8E;HnMy9C@ z!((vhy&@X;0bqjM5)a4%x{{AsVTX`gj14UYRpgZ{tORn4KOhE(Nj_$VtwL@wH;fpz z9VPNvK9IX%jH%@V0f`W34~{0;3y!eqK)p&6X>my|;s9ixyCqv_QIL4roVpFu9TED?=_47MR`G z^MCYo&~1eP>QY`{k1<0ol3!4d6+$i&Ul5Po1N@WaF}8dGC`Tv?7AH@!#gU%~A&Zx% z*#hLFAS+}+IAd7=EhGzR5XqRL;|gJr@K^v~5LJW`#5JY^I82ad+@i@3Lv`S9bpj3( z0NfD6M0wUNl6+%;dv6hLkj$7zK6y_R#TH9`5M-bSmMl-c1p;iNY%wIsw$$^} z9aTtz#K*K8MdSbRj}1Dikew3d8}-6c-eE{mx>1c)0Ny}8^ynwQ!;@s)lE@#0xb@g# z2Jw#R=T|$rA;+MtOj}I(-jL6Ut!!I(`SJkS-X)wM$uSYYx85bZAjL7;d_~7CJ z{n#?#6!JIT8Y4(-EE;f$Qo=ap7y|*wQNl?taNH=z$^hw*+#ca%YrIp2vA}#IbBCzlpW=*dL%J|dHS)!fN`$Ab`5zs-uujeM>yS~bTg-sfq=$SC$Le1K}wKgzL8NDS7gX?_V(iS#rm-=Rkd`&4+0DZdG@=QxM*iTlSp zR_7Q)+CaJ0?HGf7`YeAHdCRs%4v0|UbRroD8vqPPuFVM(GIs-v8Ebw9yd#EA!gMHIgbw^ zt?`D~;qOIQ$@a8SS~ytABHI`(RIR@C?2_+USYbOZ;|Y;i$kh;7VM9n0q#5QYtUwUb zL}`|}gL=&#CPHtTn#uZso;K{c;`)JJCVX$D8p8S~y#+XXqE>Gp2Js=XHIa_X#Cs}M zrjTWFA*wkkt7*u194)T*lN#%KH`Gh$IYtdWWISG)-h!mY%Iefn8OK|t2Dg6QQ6#B} zU=CGJhl;?Nqq55EjUbuZsDB@K&QlX^MOaS-;YHdI2{Bp_)tFg%)=xo15}Q~o@M>u5 zEqX_inusjuYJ9A!A+_;MbaM(;dl28ax7gm?H3s!Es6{Mqp&H-%X4FV>6Sf6gO>uoF za*`aP@`_8g$JgvU>M9|Fz)f@Iiu+0(I+b5k<)x4>sOM`*=jBy(X@LYD|X~H!yI3|O7b~l&2+s=$~kV0Wc@_%r+9PXYBCGu8ayk9 z-fN<{AN5R-JK{On`mW@2)|x}e9mbxPl`8UDwx$Gfhd(D)ACr8}T(b(f!`w5n+IEzj zXK5x6#n@My2i7M-QhM-waGQyqCDx*391H73=4JNj>OqiiNy|i`-t+WGKkRmq{m}ZK zsJ|HP-1~<0V$fyAQ2P12o-UdT*ZTI}E|v@0`nsfL(hKwYc2pNrDEYiH$laltYl1R3nfNLD7l0M&1!>@gI{F4X7K z9aTvp#rL%w#p3Vy_XizS$!-Yeje0XuiZK)^L#g&F>fb;<_82A?<0-OUNX(By+Pe5Vb z!2J=7ft5Um9#sW;C(Gpd*&;@2r_zsu6RAw}vZ@Mhbne$j`T3Rqu(zLzT2VB`H3;ED zGub2~u6mBLOz|@qX~mNb`eitPhm$DDYwf`#Qg3Z(aV+rGx)m`uiNh{4!{e_$RnX(GI<(@ba|(Khwgx{xfa#KhyGT=b`IS zfBx&*J-SQh2{N+A4jYe)NWQxBn^3UxFoMUAU$bjURg>G#4_T|Ei~9WjeU|+IdHSa0 zIfUE&g8CtaGUQuMgWrP>jY>?^RSzT)-{2L4Qs5YmXY5JBEBn3uXNQ4vdk>Qy;Yo5V zA2L`~g6G4n_o64-?t?^59CwG1prH#CF&nSJO3c{8=0o-HhkMn{{qm4wwvz$b4B8M(kdjLc*@-cRK@FD@!qCkPlh%jrd)ZmUUWIu`h_d z;ie__TC`tyU!?8ez<%UOs&T4c%?>WA)P0=o+w=R|dF!lzsjik8e0MSVMn}^~_u6EkSb7`LC7+wTgw$k7_o>DOC$m_clr>AzV8x>C;Gurlqb5vjFGz2O z;l&C@PX7GAAnxs_VwAVE%a4UGt2eac)m=!A>7 zqZ*t`OWlMS4%*aej|C)L%beW$(^_l{TBY^n>Yrx}CE-p#m9~^etD=C*(CJ{P@X?f- z=O-a-r6Yg*sR*~TTigKdGA{R_4vJA;nI|R#V^8iXD;X!9;s;b%con)*%{I2RG{4KQ zHrtVi?21c1v@^ECI={LZ5Qan=-Q{gPg;ZL~@hChA%+RMm_^b&GDoeO$ED0o$5!>2} z-gJ`y3x6)%&;`Uk?&3PM)5>k7#^e{`&G&0Q(d+#G*ag-OV!Qf(3_ZQ7OPKr;0CJ)q z7?blC5c|vhl{4`AjDHeXqB5T3T|oRphW_&#^>jbWJ6EkslF$Br(V(EUfh~0h0r+6eb)<1HoAO*u;FIazORdX|YDy(P0xycnnI{5W0xg`5kKL0dY z!#?i2b=aT}!|xv6v65h-k)9T(@(%3sQ}tCX&t5xFeH1_(uLFDcIjP^{&IO+p)Xyr`Q7D)A#=rncD$RL?isnB#r#i^Vx44&Ghry z2VlEYBJ6uy?_6}cMW>zVC*Do+K9TvHuB6b`Qr-UV&!V?xxi(zp0ZipoGINl3VA{LR z9_l0CYuT4`{a6(7J7K}eFyzMk<{ib2^m5E{45+50TTwgs#-Kb+uVCH&T5n z^eJwfZ>Y2M9}b`ycJsAAOV)Vp_ zM-oTzgDuy-_JR6Q3~@emh{|`DofAJR4r?(wqEI7qrv9*3v#rWiF}sJ#4aW znrg%uLw+2|A3^xr9qTx)kB_QEH%joBu}@DSb%&%hv1*h5e;W&$N#u;)qcIbDxdYyH zrJF>UdH-)i(`o%QC2P|s4DSuUg-)LsZ;ZgPK;K7-?vyL#zR@|qk8R`>tUzBC?O>i) z(PWcZuArZD`23qIrBU2g8nX=c?p?PX|qiPt!6g z=(ea?wJL~HGr0ZfDOj~~|Kp9~J{^4XBx5Ihs*kc*?bup780$sT>m8gEFV0EAoC@MJ zLk@C!s$#W(XWGG3=l6ig;iv2YFWxzu4t?i+`Vm}|M^UV<#26C@IN-K$HtO*@mebZud6=KtD`>i*FTfpBNv$ktBNQFOI%eH-ArK6lCzjmgpS9oPR3{wvmrasRKk`RvJK zJGSm~H*S;^Sp1)f|C$R=d}TN1{YJhlHwsF6n7h3$srvn~VYfJ1%z@0an0k#0e@+3s z|M`vCiGaD`5YXM8%y`(PG*f%`4f1rj<;t*@j_%`Bs_F~Q~Inl{S@?K}Od z-#-*Sos<2Rs~^YYyRD<6=x833)Cn3PAYyg>f?Ywz5+o>m$>aIY=Bw#ii|LmBk@p`m zmq-o+dj~yvj=1t!vx|tA+`hr(q!~KzZ3|7f9{&l=3kZb@(ikVp&dHm!ns&nUSF}rs z{8`>MFkEShBlq@-EOc3{HhUmOxsPz@7xMqK2aH2=25*_6Srn-m~fVP zp?~{l*U5><$ddIqzbv~-C9qB5eLhznrN-wcKWptf7n}o?-M$U(pXQqz(w7V#UMtP9v4`4&W#)+${aq)56rAO%lFEZ|0{t{l|~u4E4paP`wHF}$TXR1`l4@} z(m^{4v1DOdY|2w&m<4oEOx)r4S_}-Pn9YAQ2Q!kXWC|g1;Xv$?(GTOlTW87So-G7b zFW;PFE-sT(#O7b20{2!xkptj$V@XGt~;DLzLC??<;Fz-9JO6HaNIxnkEfqXVzw7uqbR*%Vv7mxK= zzyTSB*dKnc0MSX~->0^vWtFw9Pqp4Wf$n%r^|f59uM?-Ks@-C4ljuL6=)uu?+*X8q z68yjTEaYATpQvZwtpbDJkN$t`y$4uRTh}i7i6Vk1B2AQ{bfgI=5?U-EAP6c_rASw4 z(mN69pmYcwMFr^y(o5*Q2oVBECp2lH2nmGb%&2>R+r969o_o%{=RD`$|M%e;j5*$S zykpF{R#s+$S;+#IK3=zrsZ%G@6=hy+4BxVR*(T9{rY)KmTz)v0!KLP2DtYwLv|**7 zjgUJhtzFM+zj$mJ6z2ZGPNrY-kM4d}s=BxG?p%x73=JKa`r+oT;gn}5x9ED8yi5w| z=tsv7^9&fc(DsLXL2_ioEQWu-)UQmR8Wf_Ip+`fPDsL#K>U4V0BVp0tov!M(aIyYM z-NyYT!t|K=oVP1wKmP+OU@kXu%Uf2Px_Ic{a)v9TA~fixA6$rjjLmkMLC)pzN3$jc^D=9lrb(X8R9+|&Q?bZ8ap^}Rt#l@d~U1=#ic1=k+99FvopdnuW3^=I4AA4qk-*eL`e?OLcp2e-av`z|=L4y&Cw#y=4?z{)=! z70trm5w*#}9}z7P5j`}G49SuTO0l4ke%AhEr|57HOH5Omc{C?C1bhMd+`YXP4XPGW zy|?PTa;aFZ8FL$ZQ-js|vyg#KH(iZKFTyqk&PB7ngmL#rad+l!J*7w)ePWyM#DpBv zTN2K!EJdb{wy3R|lxtsN?zn9`f8sAwqd-B_E*Wqp=cUaeIr zZ0nluXfU?s5x?wKHj!OBkzd=EuQ@ftR<7k6<~cS>uC{6ler#8pZ1Zn0(NvdG8OW>* z2|GPqkSui^8#TAhHx-VrEDf*JnIDpy|01_W`YCW&DCtb?yXY#Hd%6bR^OS!EYB=KVVUH676VtFU(V&Fk_Mv_Cz?dx}v*fPS~QNqOm1T*rKXpyhWeM zwIX3*Mvcj}vf^ut7t?Nq&eV({({5$OWXoY;Hm8k9KTTWW|G>`|L<*9gVv$F~d3aE& zXflTHM2-rJXjgW$f?d0INeZRwgMs?pZ=%A8vlW$&U$P&3tG}+E(KyQ=UNQ89vu8v# zSeclyZehvwJV1NxNPXNllh zEpMBPSJJkk91rM}K#@2KK$515V1!mLS0>EQI52JLkIk99_ggCP_9zZ}06zDn-RW#k{$!tyb?Tc-)nZwKPjd?g zlZw8e^T)9kDhfDv)uKm{U`xvbu;vwQEo5MoSKT;2IDFR?u8Pu`-z(|nZ-oQO*OO4%)R?*gzmEFvMf&N%sl$Ej74^vn=RLScU24VK>a(NJC{e&T8~$lvGg2OFKIx!MZu|` zoUX<2xX<2}S`nT2S4<6t2hvONg{gDp!#J0=rFVc=;TNW;%o{%IvJYM4KPRc;#^1d0 zC_%d_d*94?cV+p$^39!W?iWLI^h$cEf?r3T=?~=3MbCGrS}Vm)##rsP%f8nwaS@{e=O@V@%yDYgd@-d@L$x~wX7}Iu z98f8{cDS0aI=EjcP#-_Pv|}?6eM`IAz4l#8F}!Lnt~m8wTyf!3+)B1Gf1FdLb)`$` z%14*Ur{A=9?w2e31bv85KhOTo+dKTFviH)3kzNbt+`z-l@XmXv)yT=FWtR@gFLBoJ z_{4$SK}iA0)Ls*tF@h*vwDz65#S=UfuKCpl?#$EJ_la zPRMgsy7gMZuuQA`ey`8C9?qe#Lr2|5>n_(^#nYVQAL3J@Mma{bS4YJ*!OeSOy^6n} zJ0(#znQj*SUaN6i_dO#WGWE*zJ^hQVAnq0V^Tw;4t6$cIJ5S-ReBh~kev9kjhw%#! za|JRIZ$sq?mKv=V_gT=3PmB2qT^R0Zt-wo%cr_UBb-Ug_TJV-d;C!8ac)^<+^U6J9 ziN2-D=oJ)OByB-q1}$rhzz2zdV$oL_@YU{MuYy5tmC0|#A@f}$c>?bl;Mdr+I$<}n zjfC0;PKm6Z(^5)K`t<$F+b>_tx(4sTx!&GOS0re+4?PV>e$%;k-9AR>3v1@R&pD8X z7f?5Pc#^849g?JzHsZvzmy1&dtD--hs@9GVzMw3~KLT+R}6{N@r9#BWw| zuh+unzHkp&e(Jkdu@^3L2AQAyQt);#_2R4+JVwd%9q8s$l7lJd_hMggn>^;R8>S;X zmRV&wAPs`63C$>vAMGAjtmJw-eogm5jMsAxb+&n>$)_{#@ATYzV)U>IK2rl1(+Gbr zk*Kxnk~H!P4LfVzf3Y*>M(3v!pNh-!-qnoWOsol$iP~{qeqy7=`j+`kTr^xIG5)&f zyS(<-lCf}&u7`YQKgF0K>ps<`cw{k)aH)6B$=$7v+xc*R$mZ!by(N{=f)ulglc2>AkQ;K=nrT^u6#<7(Qmf_kLeEDHyNo}>CtXMhfUVdZae1*SC zZ9ntbJ?Wx&ja=%ckcx%UL9gazjpDhzgHK^=SpysptM7_W3O{6))`U1%CwI37u6|O1 zcjSFgesd5x^Q&p;)l(`|@8(g&(g&5_JE zqTSz_lgW_u$(KW2)abUSXL0v8y;1k4;!iXSqL*tW1d=V}!wX!*SF2(bN-5B1tOS%a zt}k<>ZQ5AL^#rrr8yAy0RDurCDi73JJ`4F)b%LIF;wzu&($O1N)2oDHYaj9v+?~YM z-d6=Y$W0IwSfbXu?w+i?zrz^1BOHpit)f|R?sd|u+<#nma$v+jnK|v+ReyTsm_Vl_ zI7{c2P4Z(yv;4q=jDxAxG4odeT{0H@qRg+_=IB!(d_m77(&D}Fq8Ig$Zi1-^-(M-@ z29FFW36#INomK+wj&8GS*jug0&El?2=)!uEuX9VDpL{mSq6Fu7<8`5~yi-)~yKUm( zxYNZf?Jkc>4_mS5EZ0j>NJvJ`*59I#fE11R=99L?C|?;07pbDJzFrhNl6R--4GX`T zhFi9!vV}_zk}tmc8X>`0$XnG#cQr-CmeT{{wecA@GriT)xYfd0pyRMo6R*5dQY2UN*C%a?~I>{C2 zDtMkvwYADlb^a8Q|8{67ig%emCwZy)o%YQ;CsW0GN8pMJ{SsAlwwygKQgLPXKbIjt zl*edGr#$1n$_QT4eBg^H*pTj+PQ8pzMNbs47TDw1;MuQLRO(*d>`A*L|0HR1iSq9G z@(uCilc(d7m3w^7iXC{uOl@zQ@`nU1)_Di#uv~NqyT}?M98w5$}0Da}eYg71CldEGf!xm)NXO{gA;y5CPyiPih+6YQ2WCYE%vb2SOvMO!jv z`K46;NB?3zcn%!-4vy51g-14|wLV?Y$#z*KJ#Qh~HKpKv==W9C=I+d*=guyfKbRdG z$lZxL(IYwTX%&vlW6i?Js`091Sg&^XI%FhgM{T!KRbArhIQ&s!1X8wmFGdyqjlN3e z^V#e>QJnejbMM(CZLz$5d(mL+YiZZJrqZtLQij|y*1G7V&JP(Gw=ZTScid)vHQJq8 zFk+vh0)I8CS{0x7ZgKUEzzKtSs}l4D&Ez}Y=KUE0uPJ&*4{UW#A_d%PUtU|~scKqi zzv5;AJ9%$U>r=%1)qoqR94PBm3y*&5cPQHo8C0*uK&?kf%FL+Hr;y?FAP-PUL-eWby*`J=12cy*D6TFm^AgA@;myJ)N~HvQ=Y)4~iP zqv+xf?WW-sFTKVfFR7i!Ef&C6PpR!=bUg;s?&vF8Se>ImeiwnuVY%iiZ@bg+WO}{r zdhj`T(|oa4_TH9I71GVvybvLj9UjqELAacfQon&GF?C+EDi> zeO*gf;)#TkLPYg}&dkJ}P_UHvg2lgYOqs6`q58t}ubGvtn)UdPW!^ z1xl{#RXGmYc}{Fb4iFTpYb@lI!a0Na4=cHH#?=DxD;GA3sxxxS`lF3hy3*6QROZe? zt3!pWRLr}sc!rHv4dU1|R!kDWme=X24UGuyJu4Rs<0~zD$!6ab8l1H{ zKDRVdF_xJ3>Q$WB)o<_3Me7MKU#aYr`iZ2O#rt&z^KlesX-0wq)l*B!s)0`1P zCTL=pUj4`w^x)HP-dDcYwJN{qdDWJkS}JX@f4lN>Z^3(M+^D{`uEFA2X}a2Yy{~?8Y+{ma4t9I{abo+5NJMY3wI%P^s2loq7k!uC{>rVrx^iV6^#jAFMbGm0gC%dIv0P9O zT}-^0ZnGSwV&K<#6WnItQcw0)M}~i9=62D;2l7U)bB8WAkF^e1N4ycS-ac)olwlX4 zQZkltd+%jQY?{K8Z6`gobjA3tRK$f;wmXSpWG8Z2v|TT=W!dpBKOS5+RH>OYGvt(= z=$r3qkg(1OyGtqCEU{3zJ3M0se?vhSA=B$6-@f*BJ}=myx6<8ZomN|hqkJxKmApXb zMytD%_@oG3rg2uvSm3zBt+Sg;T{dzpxJbvb72CX6RC3^r$_tn2`(+WqJMTHDRP5_K zr|sj+3*0V`n0IPbsY1LXMY0sVMcp;8M@6~5dmh+nma$En8GTzI^)laMK{^BRaYDD; z9mJdcb)(Ic-Q*NeBwKJ2TU+9HBk1sqpqa%AzCX(Gt)zyfLd&aAy`u9D@u&2h_xC4h z2;+UTJPsC}lgWE9#V*}yTNrLoA6aOZjJx8qga6RZyqV>Ge4#HQG-M0CRqgtz*mF%^M%$BFsLAinb(EZ_vR}Mb@=j!Tl{EU{`2U~V{!sg-evT;J$wQz{M)D>g=sp$iE zD3UIQiyBg$?S8fQ$k?WKk0wkrBnZC^*%nvBEo=2_JVV#G-xK8!WF@Rwrrv=@DCpbC^cex_Q*w4-d%vHJSZLHL@tx)T4BiNuRr?upgRuh|EpEYM z*-0k)rXU9V$&04uDaZ0*@{6X{|FWVv%rjf$kMeXghgR!BhXssPCXOkz!!O5(Fl?IlpbKu))g*caL>5}}xYBKE_Mq2p z)Kw*p-E5al?x^)2t4Cx=u|(mA+^LvFMmPVVsYm#IjUk#E15+|lGO18P)9DqfCJq;h{C?*1vV?Q+ce zsm;_L^v4@)C{;EQG-VGuY9NUG-uc~$G?Hb7)yT>8Li86QE zk;xt6{w#y4Y5Zv29`wkKa9bYec{D|Ghoiqtc_IrZde~x9<^uGKYMKa|yaz3LLByIz z2at+9nV&@h(|z*@Vn(ROvE;wySw)-81DylnISVcOtp*aKa1-K6Xjz~{i*X_hih{n zZ5}-@iZ#z4WjEFm7AGHe7v#E>PJVR7?x{$EwZ&ztTn4QRVWXY44m{&H8tWooMV&CF z1ctMEt$J$0CPJIKMW17fv^cAveK)G$ABPlmJ|FKEG-Zk_lHg3DzeR2(4f$liZv`8J z#;PzM@eVFE-5TK*RHJ@+VY!9zqt%Fs3!SIGLQz}t*weNu(&nxCp}eM;us8|Co$+T2RX(kBsI=J*qpPqHxJMv-3-3;OmmR$b;*swXcp3l6O6;)|fWEHymnX z;_(2t<$6_nuPVgqlZa`?S#0 z$0@3VTw?vm+23*A9W41Tm4@0U1pwc@MYGn$VlqH80DMYyF0 z3tw$pW#LLc-Vr*&Q`LJUQ)20bR%O-eyi7H}p}jB^t`y?4ddmbFx59(CUNCunvQP+P zwYyike=vHO(0cN;r&e(g{%FvaPEr2tg1Zh$=x`-9xPBCxx`Q6ILpNF=Dn+RB zen)Afej@q?x3+L)d~|N4zCefO?SfKt4wq{bI;ZwLD?CRc+OtzbR!Gx^d-o-JRC!Ie z5Cb9dsbMLIHQM+W3(7@vIWN9m9z13%pdu2lFWuoBukYF695uFT2<}Ncc-?`M8+Fg& zEf-4J;cfC+X5^Q4);q7p_$yVou4*~JZ`;;P9)@Ke-KP`9vLSZl5E4UMmTA^YVjZ=! z*>XF{-rtt$Fw4Ezb27`QA&>a)J_deS`vXRERxohCPl;w1p__V2u2r`S%Co*9A8?}2 z!d@-oN0$#q&mD{=AB_6=~J?@v?^OlAMAA%`77DJ%gT6nkIOYEs|so4XszKH3cVRi)mL1cU8|Ay zjiFF>a9Pvlo91^9&14VF+OjX1We*C4O0$J}tW>O?s%(u8B#jQ#gz9N1jF$`~=WTDK zJ$>=u6?{y-V_XQ*$6DLLI&P(D_jC}WcO^;his9x1UfH-2lxE^pl|jLd?^YMV$ASiK z``mSSpY|=`fl&0=@w9K|*?Jt3xvz4I@s=6RwOQ2-h1LDY@86egH=V9tO-&h+QQtka zbec;#eOSIj7!x|HRQ{ki!mX<9z(w7o$_*jhfaJb17hd`$?0MWu+#U_jvVWFmUB{EJ z=Yq#k$)~@b3mT_amu}L?f1ES2DW{Ecc&b5TqgPcWkzbQzQ?T^_bv1he^T1959F_;^ zm#+-DMC4jM{OlB1y5(i%>WHL8^&%WURlo13-C?SXUp@E=+b_G*!YWfPrN92Fy6Kww zm3GJ6ro(C98ZvK5b#GiPt_P>A;I2oUw8xv(Vfs29MeGRlZJvW|l;3HQg*rZ5aW7CtEnL(_Wl1l| z#jXtANgT*hM9vke_hsrYA(MxZ(c@EtlYChe`(J|$ryt)a+?JwToqt;Jbim2=igq=U zWwc3idz-#iU%}3f>y5X5&y}=}(t;VO?8hQ!T*D}9-(<62b-$6k1HXIq`_1Iu?$162 z^YNK_2L^YLADN}3K3#u;jE^WdHP@SP9@#mq0TiaEPA>lEZr+- zss6EW1i50lL%sXava%s<)@Fp#huJf2*F*%9JQ9|%0LPwjiB>lj*;-nmk1#I81dZg% zMAf!x7ol)RcaHX%+HLx+2>HCM?MXLX$DoF*@i%wa3XRvd>_#Z?S9jisBzU9gZtgli zO2-OYrtf)_^m$z^LDu=MI8O5I1lXOHo((gz^rk63J9$HE*)w_&H=tWob<&FkM4+=s8z@3-!`&~{?KkZ5?u%YChLV3WBc5Dr_BmM* zeZc#gW}o{t`~H!zA-5Vpm4uEueSa)KM< z?4vxTh##oe^UY%@nXBZr&2}d}!gi1E zB}|@v(6vwD-DG!SFM#IQ&c@dl&TNchNkJ5@^Rx})*!n3e-0P`_*r}-oFD1-lxyx8# zIYG&28XBL-Nj8=?#Us!L#iLmp_ZoD)oG?6cJZ`)QPV9Mvctvc)37@2h<8mEs6o?+) zBd|u^qo@t#hRKcU7qGdQn`F4yQ+|`I1A&ut0|Arg22v-P99YxOianoX7mHO4d^v}_ zu{MvqX|c(C;iJq&Gs<-4=w{1+JaoxT2REnolZ0#ShX{|9DAVaSFQ=b#h;H+*X)?Vj zH@9`;EcWIFC>EQj|bECj2*_(kEiTj zP@fTHi!e)ju9_BnLWWWrdw*rNgKwH&vRA`CI%`@eEnFQZb{R8=jk27gsk?E=DEkvS z@wQ^!?aCLH{I%|74&p}n@|Y`~e05rtVTBr*Ti-ib>aOcHJI3-|a zSebqp$5D4Dd;V)2+^t|!V)Bhw>sG7?PHm32PQ~1-JO|@d$}suXWuE-$)jI9k@O6#- zt%GlOeXiB|u|HU!5BkE4FFM z%Dt0?ccF7}PY)N~hoJ|*L45Qza2k46gikJ_uv^Qm>4STig-QKj#nDJln`b2 zZmpJ=xzj6aZx!@e+LC(lac-C$wKeN7KcV&Y(DgT_>j=>b=OUuOeNWtlP-5>39J}f) zte6qcVl`{JV#1!)8wfeUkuGO`+csjV;=|w}^2S5#$YF(Hfr@_(y%-tht++N6m^~~~ zao$Drc>SRU^5Z?%SsYm7(woW1C-fRx@0`47KC4(p!yrOF`)y~0+j{1mm&=pIcROWO zXu`_Fo9ot-98+U-yOuN+Rc{5WtLXYqyP&2suj>n@ZUcOyqJQ;Sc_NM&EAV*+S02Gn(<~}43$KV6*fsKJW=9plgx6eXNu36v0f@8 zfg}5)7T+7C(e4}kkoTPkyG5x>^6i@%rTi?CjXbWA{f{Tuz1w%384sM__y{}XCGYi* z`8+q}b4BcyIUsh`C>JMd{lR~jd~_`W~u*6myR! zg{)r`LaV!6&%Ih@6IISnyv{y!n0%6%A=dq1xaEU<+*G5^L+exe=g)QOz1Dkn-TG7T zf_+|=dVxkWeIfYeI?WGmD1W-Kb(%R8agiwT{@nMc{aTUrQDSlj=1I42nSJA<%{?hS zTzcmtRccz-=&^*TwiUMg!(BQLD3kf`>oB}f)ufuTlI>L)7Vuy1zUoho^M}_N=jGc~ z1h=f_W!d?kAwFglcDm{9I*?Gv0sR3C#&*C3Zv}O2N_PL4&zm#26A32wJVVK{fcA`mevepE< z`>~*Ie`K)k2?u#**s1PEH@(D1_$IAg3PqCc?8?@&ZORT?Gs}iB@zrvdhXxiDDVWU6 zeO_m1$jMya&cQc*R6CXC)uek%1NpW5k^1VR+xshG5)02fA)Z>E5chW>Qe!^sSERpd zwchZd>(+QV?xHn?BwIcr$B9w#?W3}$$EMWVk*A%)`qeWXAv~N4BZJXmqw6Qh)9BsQ zrn*$k%Ih`A%wN=U+$C)FX~d*zkHavPp(v zg((U$5jyOfdVwQ8T$qbI#F#a~yr6pZBRh<4dQ+ujP$oCOdXXa&T$q>j508X?3_Nj4 zhx3yD>oblCH9@H3EEkKePpy(EP&eM9#NVD`B||Vus=W?Y9+vkdo|e>|x=OZAi%qT1 zCPOeu-gzCYsS{hzPTtFijj5*~4;>C@IY$5SxTn%oA=&Ja(8^<;Iv|lI06s3|m`{KwH<^xw5_~!Xmo?laWturk1;89e4JekVlFmvO! zBV~*_{1^`3Hu6viH64V@kVQ}xO>M_}7fr?Fc$UY(&-E0agRd(+pTqMo$VocKUJ*uY zT755B3yY)Zg0YDjj+?9{Wm5%Y(-)p$)DkGly(X%Scknf_b-U_oB3#iPa!Hh;rurJK zqfco)@fbbiG>=KQCly}fkw|N!f?#EP;xk(53B}jJ3<$&5!6%q1>4Z%h?C2jKUlF+b z(x4_yr{avjI`7?=ufkHOm`tY+$f+hPb+o4&wS^r7^|7rKRP=Qn<%SiQ02)TVz4@C* z3_0(j^(z)*Xz2L%rZ~w%%PQMzpY=1c3tdv3I^&xmBZkau zE82T7AIW$r>7{(&*EXQS4p;EDz8Xg+c<*ASqsSE20{c$671ryLDd=JklPL%X^)a|1 z>fOl#Y_Md$9OX?+lqtd(THg#?tSOm7K@gPxF51H_qyDjP2bsdd=_f!SDD2=>A8p0` z*N>(3^(&jZVgd?j&j{SL-qGJ?sJr)C=iKzeBfU&~TMxEb>%ajLm?kGHms;44Oy2X$-xkADTMXHnJDV(ZOvjKVu)gsN*FcPbxq>dz++_cgYR&YM7wGg&2s zjfF?L^Nfa{vWf{i5WJChUD!eP#yo1DtVOO}A)VGlD1=EOEYh8Or~KGQiHhM#j^?vd z>7dE&#A{Kr`gtM8qPq04j2E_)Rvc+LEGu<5X*m>0Rt(lmV7#yc5eA7-p88m}3tP8V z>}WaKNE-6O_8$W|%<6(g6@vArO<-ZCAPp@^p^@$!z0Z${w&|}}(wf*-p0V=prukUL z(X4MTI)6-*7let5gVk-zR}ijy9eXKhvpni8$BN5WXgM$XNQcsL?xplCAm!{#E}gjt z{ylj4;lr7Gq9*bREy1+j89)A+GzW*$GB7Z3UcB}4LoMgL>v%NbBy6lOu5jgm1^gE< z)V`sL5d(brMP3V}EpH-bMn%#=c*a3CvbMtQcwq}%ea{&l=E&-n@>a5L6HBq7$+Drx zLSP$t+0;Bc)-t_5U5c$TDxX%~_zR;V1c0MusUUKyhdmvy0L9>MK0H4ia=dcv~Prf^{)7DFQToAfrLB z7qWrTPjQ@{u9Tb{X|f9GKnNGboc5xKSi6md8JyweHdCoTL8*J*IB7~&hmn`tO(?!y znG#!~q;|VL-Q3|m89^{M<}^MpsQffuoW_oOYF!kdj{!QlFBFc^uHZZbYvGzIe5OQ3 zpkn8qDs0yvBZRVm$fMZjhz!%y7;RWPEg_Ve7ewIC5hi`g^+x@&lvn|=RDk;deAm$* zk)Z;dJXT7>hiNcww-e;mNAQD=EYpSU4}n?@kR9d)1gBeIwq| zNzW0j$-wEoM@Ben$1_#9L2^iQabM?3S3rg+W39ZR{1NlAF7CtZjV_KGRG2<3JGI26%d6u@9mE7HotR&t)F31>yPrVBT20EdPP z7Y+;`c@6sl$NBX(*OTr08wQ6r_b@aA%luf1<1Ewc?{YOTG@I`Cf0+Sa5U*VOE!MI8 zEc`|aoPObaGh5mVSn&A8mdaxt>kUvY1O@Suv^5pM*xd*lH0M3dKJRh60ouK*@`rJb zeL)n(UTATZ3Ph-EjD#D*l^Td=3ij#o5m9|7h^7g^c>~wLK#%V5&z~tEl7>OQh6&L5 zV?@(ONkBpUnLkl{m*Z52UaTIPB0(!O;*9JAia#E*65 zjHX}6JZAyCu7&5Yt8B^*h=+1C_-f zI7ym5x3F6aFEN&VeaB!s_+O3>58!WsL|N!BXR_xf+{Vj1-De0otFgF+osD~m$3J#!Y>AxJyc94_&60^X@&55tf>OBUNdw2`$*ax!5OfCJ1sVo7|bOp12bR()0-3(z>h=}H>Mx({c_gR7zkq}mI2VTZYtQ`c>z3x zS9h9tN)aU8*TOogr!x>za`P|?6LJFh%7_jsSg)=Yc6KBWL(~XwO!qthkiJC#Q3Eu< z)=Ndq0*9>EUJF}-Fb{z4KLpezz!(Giq`{xjCN2Sd`T`%G2#zYu_bnz!Qwxh|zlSA~ zD^3$nD^Alit6F!uj|~jQXh3w|07Q~N#0O4CSP_AMwN9cV z)M%?=OV;Q7q5FnvSVw3A9l|g5aBV6`;sr_G#%kEDL;!nV z;>C|p{Bm%@0FndQD}E%73E;4jBuE^ZUk+{!Kt3c+&@U$?CIw>&?WTn7H2rdVHPx_0 z(yGvb!%+vgDNQW+>|Eu_D+q$NDev6WBzUX%ucoQ8rvVX^*89WQ#KYJdXbG|@TP)q4 zi%TrlBtuOyc^;3V{FG^AQ)kC^KO-T%_9Rz-r=G73viv5?F(sMJL#hq32wX1|+wdG# zO?KNMyl>)g)0i<1buor#4z~g#X??>tMHX;^vPC^xX|mhT(ok!@_GzfaH$hu?TN>Gv z1xt^`X&D&m@V*T4Ce6b1e>_ya|?|6jy@Py4~!?fxgPFFFVY z+W5_+i_#F;JS2Y@5&Y704LF_);2cS2B6tPWV6t4d8q+6wj>9~zir{g!?%-lE9{?US zfI0$DOMs>Uw9eBIi!AwtE^q*J5D2B91E8`=OoZ*nhFHh&&Bk;#lF(&<_P+oR0S14l ztllYrUdJNel27+RgpR>HKAr!8W+@&AmoS5Wqv{ci{!nTvpz#-0(4C*DKR}Y!C4t{1 z*yG8k)$Ks0Dv+BH1Yil!?|FdR@cGf0`%_#`rj)BU7)}klz`R_^hhX3D^!^7bL9iq zoKil3W?-_6!Wz@pwf>E&BN)NjSN;X{5u$>5km!Set_|pp8i4*3h~+AP2Rop91ND>= zfI z1GG8-n>VbH-33TM0eGMTKvMvI0$>{e*+C&6P)LXA-ykvqOqTv{<4Fcm;55iq#v+5b zr`6fx{h{8Zz#|aw0|6QkDAYVnpaZLV0bJ)S!F6tzufd4Gpi4=}!WeR6`(E?j#-v|o zkDY@0$?-M7j-os%3E~wKDwy0$u3Lb1_ZoL5E#RY z4G8TC3PNp-A|;^~TXlqJxE6C8vp!b~OiK(mc6X-jG~N?84$KCqS&PjB6fdn8Fp)xC zUL`&A@2{fAp2w%*@{69myM-9Q+-bth*1tu`=z z_m~OZDScwrdy?tq*xml)<_X*OhFt)qAyG(XwkCdhQjsQhdNPOz06+7@-NmLtbHi#H zk$B@_Ai6c`ozf=uau1`Ch+1q?G55)$VUIIL21RsUT57s!uCqN&>ItI;D!FA*6XkYx z{}^5Zz0vdmWr}K2NP#)fyNDE02cb3}1JGz49~c^u7)Y_g!64qwnp^45d|~V_yJ~K+ zLrC+%$KgigHnr#1_a2dEh6DNQOyT=J2dMIx&P(h;Hq3kjDZ7h;{mCBJ{WGX0#!>pQoX+r*M3*@ zv;y>$7*Z1tf2a3q{vq_21{R7)J(DT|I@tD=a^NB54AXrRdSFkL&oCW90iuqE41_0O zcOs${0QI!i#5QGI#E+Qfg3VspMf`>W2z&s)Z)sw+C8=Qedklo4Tq>B%eFnlxspfQq zdQKyICitzL1N2D=Dj=Z>{8rV(mMj3tx@;;~CK#)M@h%t>z?e_~0(XA}Jnb~GThf}K ztA`8(Y&IzF35ug~z}{#g2V=RO|I=BJ1r^dhfQu*SZ$l5{O#G3P4+0NCAQAM^rwMj} zph1s!7xB0}(AYYuv2wsL1Ps=kMxq3`2+@G4cw_;FEzn@o2XkrA1eYq1J6XwtAMvvS zv#;R6FTGC!JHszvTm0+}wuA!p({T)c`V;<>2XVbZk^%dmhAYz%Ss>d{@8{spXkTRk z*c81;!dQxY0M1krCg}Pd?Cd@W(2x*P;Lcx){HWIb_d>?Hf05n3eFxh_>JpxW$s!d^ z%cg`4gC@N-ezMfpLF>dkz(@yW*g+YO4?K9>2%tv*W$!;`cm)i6awv(28F2Z}22(Bt zVs$y7D>TSc2YC}E!uS#RGI%P_Jr3KMs{&7hU%>v;!2nw#g8J!fF$1_Z5AeFafu}9N zlk@xq%j$p)#UlgkRw_W`^1#cVB0x(A{B=Emm;f3Ss2l)VieDARGNJ$!Sp<%H&T&}p z9RTwVf^+jea1;S=fmGxz$d;}8CC37|z>2S>Zt8)R#PY)@wc zEONnlnkEJmKmgiatuTIRw+d|E0k954d<=jH3NV_gFj>3HjYQ(JvE60j$k02fbQ`iV zXSt>$2Sy9EJc~rBLdbO@3O7!fa21qA7!y^7yV?;TQa_P?2wl0b0U zodYL;E!a&}T);!%C%|^$DmY!o!0y9d1MD}GNhsLwRPf`MW;4Nl^D5X4{X&s#cfc{r z1R8%~84vzUC4oRI080HAkR%agqk;Va_DKXlUji`A20Zf1fc^*oy#ZJPGD)E9S9$`z z1n67-g@psG-vaKh{vKHUd!X-c0i57pDr{S8V7Hk6Qi0URLJ8=cRG)+*ON79l@+o+% zmT`kF<3at0;DIsc2?@+5D}IOLl*o3iNL^`uaZoUbJuh zFFhhlY^M9H%BEq*GHtNzGjcg6h&SCze=|ikTO~mi>ra}9r*>rlsj&o@7w*aF5P!?B zc-*Np8-V;UFxx*oA5sj43M5{@kN#$ANJB4@@hK-&`SgdumH_YHrpDzQAqZpnn{n%t zz|&0k?QAN?xK4fCp$d1)tBvMlvnrfv_bk(PY&KoJ!m^>`DWoVfWY`w9oK>5~iBk7G ztf*6d)d9Wt#BQejJ946%1eixFj;lYln>!Y^BN4vs>?y6dS5@oB={-KtL3?Y}fMscU z$CebQA;saGE2I081E|#lQv48z@1IvpC~Jc_ASUFxqxQcOI#`z0eVS;84t&D5-Czlv zyUPa}k^qIqaiXpfFNbe?5S>Vdnq*YN_0JuYNDeF?lt6%SBzX%C=%l6et|-IxbkKMn zv^C0SUELn7_pQ(V-NL>KOQq3zp*`BC7SR%Al?RLDteu2*k_zKU2qJ|OWeC0upwf1q z=^46e)u=scxeP|DSkOUeAqDN`+MT~5{5erJ#QWj;xd&a64&yr_3#8x+Qt)=Te)&Nz zDOfn)?(-QD$ceHe>V@kg4wfYy4t5F`+P{BA_>zLR!u7Wfk|iBjckM__5qxFZegG8Z zhyd?NEHV-FQ3s9b%T-3$m?)p=zVG7zuOs2E2=K1l8o(z>c(oDM(R=qetYG~YX@uq| zcr&HpIfmEjFn9yx(KT!dJ2iMK%kR*%`caCXkR|lYDZ&Z`z^zaIg!+6god@rffYe0R zQv~$WYuK1vkWc^um1qAJU}pc7{HJ&^^jGrkGSCD!kC=|21DSu0`q)Izad=a@F3Ur>o6spnuIW@^X(Lc-kk;>o2BAtIZAOq~$g0D}jQ=I(i0BJr_R{_v*$zP6V^J`N3^aQ8* zU(O2cA42c{A=LIyA?bezZT>@O@E<}!H2>&G?w644C9nbV1zppC_B|ef2^|LMY@o#z zvcK!}g#+@B3H>>bm6QJ<{W)vT=19_HPlHvxNm?u=u$Q3*JFMUfqyxqUlmbZy?60K# z?*Kd4i^MGWcmsL~ps%5VNGAbM_yG!wbKxtE*iRG23Tb|U(!IaPGX>}qE*q6d| zut;JP*h{lB61Is&m@Hxt*d#;$Z%{aZ3N28H06Q(1JW$~zsn7zIV4$K1-oS$Xr=(m2 z>vE5@E?|!ddjQtuEooiATkFIRq;(;!?te-Oc!fw5C9Ml3SQk~WE~cb)p#$rZ0M@0A zbiVu_NQwIIw0o3v-S~fQz$+UVHFzmQY{9@6cA1)BF9?V;giRKr33y>e{Bx`i#$ApF zVbdag-$eouGAI)1KM2lLMv81Ty^0{3zE(oyeI+YM6N* zqCBOdpx@-zR^{VeId+{nh#%=H5p=r!Au^vs@bD)ii;nY*xn^N0z)X-6C zXs9bkgbPQmbW|HiUXo{9mmhNCPvGTrUGvov0ww-hBZA=|o*do6szAVCl~Bm#%(#&zq@lg&?FViMa*2uql> z$WVP5B2LNE@h;(VjB&AQc!xN7W_xUcn1*qV>Z@$=6PX>K5+sm))R+9a!MAt5y!5vF zjH9R{rFeQ}EUvuUynC*jp&MaZU{+vKU_p>|JW=wzG9Je|FJ*DTQFg1k`$RX#{H^)j zgye*l?w;;-@$yUMV&$T+`mtU?y;UE#B_g?z8ih^XiGbiKX2d-7w=ciy_gz zOT;+$c-=mkHas)ZSmIKjIIOp(-rCI2jPSxeWTd&K8_&H(Rg&l)hZC5;VsU&+Y75nU zu3KyV&b(bhd4f&%*KU~UgmIbpx)?FlJz}JxrVlT)b*Ll;7l~us(Z8}W+X<8!G(^rdG+8qw@#F#MdEU)dKxBh?2SzHKDW0!fo z@x1l$S(?ZHM>%`@Zzm5kJ=TA1@7qd#_NS93=~003ZKXKN{@CmFhHnGKQT8)lk1+p% zlTg4ZNUe5BvSI3oAKm}B(=F9FGDYskL~VGJ%<^B;G~xxmbOCgsty7Y&q0|JOQf zQVv4rY93);G#o!Fa;D}Ho2*nt!_-l~bJVt%emdPTiU@I^OW1}f3O{!0-yHl%|N2XI zYE+FoVX-paibC-Wi}5r62HK;)Ifk+xYJ_i#?hOoqFPZg?p9Q$j9+Te4X<$BTnSg-I zL>m=4jv1G+%G%kn%eqQ7Pn{|`;Ior4!2~yO9*s!YjW9f1(L8n9PlZ}ow4&L|2`zKh z%S2AjLyow%=-w=FwD3%g2__V`0tP||Ly>fLNY;$%7L8)xDwATLP@O2Yb?O{vVdeUw zd;Id+^4o=d_J}mcjR^g6$@Z!9ety&^#eO*8#gr(vZHnFRPsfvbO|+tIip|ecaP4D7 z+YDRSf5&kZocQS0Hp3eBn}aF(XY8L5$+l3(_JkH`#&w+<(-vv7UQ(&NiXgl$-gG0P z1uae8qf{?3fSVPGb;>at%usv@Ndah$lk* z-U@~nOLorih5f@hZlz)?h^lP47jHFW=wQaB&8V%bZ*CvQpgn!2%h_}zj=`wIb4IZ1 z%Hxj07F|Y5-4t{C_!eEQ-mDZT#L`QoYqxllwY@M7)$|9*ZTExKk;R?t($U}WkkM{L zI>ITn#emUOSL|^|`VVK!yv1Ns58E{(5{3{Y6#vDEmJX{HTq~~ViiQAZqS&o#Mo48s zkh!E7*}l+h5brg@8*wtRSe=!%*lYvNF#l&NrnHg4RTp=%qARo!fd396F?4ucY z8;~>HVG)AD#gi->;Vm~AX>?`G=3uiI!h!_Zirw00{&2$CH%eL*7@2hS&FrK88((h$ z6-TtJ3nw9j00ELTY@{m-Q5OvcO3?oVPJ;f4DvYV z-247>|M%YM?$zsCy?d?QUA4QWcFnG@{s9E_x9op+OW~6WE(Rn}A2)T&;WG)QZP~~C z7m$$AN1|f708;6eqrnAm#RdwXST93089o|Bt)T{4zoV>+geeD5D%N2iKWMg}K|$ z33r#*S%OO_%N-ks2EAvzWju!0*_b>D7aiS(LUZf`yH%CWnYedQaoxoD;!W_$PSt;Q zV;|T3{{oFWR3OL3!F5I^WN;#-p`+X2I(={~rIO?Qoouksf4}bke((Q3IJ$`5T6Pc> zc7)r<(nUwz2y$4i+3lA4GVE8t@MKH^C`^Sz0#)f*%Aa==#tTLvUhR8qdFV zvgNt6W)l_NEslRLaI?APxj_@`OS$Uc)_*LR?xo~D&KZ3q z9P!WAl}-ETSl=Mef3~huT|j@g4Xjf$>2!$VUkLo8vHM>D71b?_j}&O#{09(g-TdcC zJsoh*LoIXfdvGs)ZyOD}*}Wg@u)90)wOG5q$V3Wkf63gA=2viB&6YDlUN9=2fKp~Q zp|59GZB=)n)Oc>LU%FS*Cr#Q~vfJ08RHCabOhThA{2tY=fZF~R@udUNm+AYWZ$zP< z@2^u=yC-W}WwM=GWpZ}iqNVQZF5FI^AVc>=kb{;po-8S-jHvuJi)=yUqUEF~hwib^ zWb=hr?RMKsDwJUaz9*+te`{jSNtOD;6%c;Z1FD z=>5uj1idNnZ`7 zFYTI4(gcOEIpT#!d*Vgv*@VUX9^cZ*Q*)KVnO!_aig}EET+G>W$HJ&`u8m*0fNhF} zn85x*oZuKC@wqaNkWm%VJ|#`k-n;m)zA=^K1)KPYvm$3ig9aZsW2k?p*cc(98FgD< z+_zCoEnj5LR-*?K$P)1{LMe>}vcyAT|Cz9{`l7MG;D=mkkPq7J&%Pt9&QuWX#la@yMKZ<|GdWeHGbUB-D$)Ih zTFO0qB}^uIGwM}k@cjk8GXQK9) z2ft9;1Zx&p<#6VKsPv!{(`h5)hnF=1+NcOhTsPEbT8@k0ZI>U9;6R-f)^JICh$~IBtTUT#B4YiR42f3TCvA)2@XK)nGk9__CY4Hz|zDlv@>a71)L$sdD1?Dz3>ezmycrQo5$Tk$w{Tt*f}-W z?PE+`%}Ghw!=XjZDM|SUq5I9rNmo zD;Jj?o1kH|fJevFoc0ecUdL`x-dg?DztwRpzY`Hu_Wd2P&l$^ntI1u^u9R@fKbUgI zw>Sl3z&g7aRK1mSgxqntH{CJ2$7jfLOo%g)!T~YiBe`3~n+$fmLQOpjTWXu~96Wwo zj)Y&!KNt+g?<{Pw5XzPF^)t*TZN>seu?JmtdbT{A932Dpl|Ua0==qaZx6GZa9m56L zn`YB8R?Np_LHrhsu1Pg9!ioULL_y)E<+RuplQH=t-d(1PWZW3^Xy72mPWIMkLdB?5 zx4)Hg`HZQ~LrFG6c7Ka1ne+3L9IcCs^7E5DtedU!&6B{^`DC)A+>%9$=JdS%5qV?0 ziMcx|^6DoeW<^O&?;hxu^Bs5K8iV?=#mPW*b|(Yt3H?lRUjE#jR0{RP)KoR?{0LO+0lyEAhJ4M@sBG7r6k znPn&+@^R*#Cy}aqj>;E#?`+TboP34#v{fZu4-mi3L z676kG&9GjTSLQ)J&;Suk@r(rTC-3B(vYj}1)L+qy_Iss>&3h$e0L7HYc>uX4JMv0v z+WTo&LI&KhT;R^K^RQPU^+#BN%qYSB)lUEE_D;d6rune#99vP8%% z{PZ<&TE2|4ZRFY1uKGO7UgW4&&XW0;FLu+ zkmeICgim4FeiQ|5?sxMgC)-SunbeTAk6LuqCnXyXCl}SHB%2>3@7E_M8!aa%gWvKD z4wHM&qejZk$3|XzYMU3e3D=CQ#_E8OqotJ>W?D;V zo)QE`^6Yu%2sv8ifw4iLW=t$b$Bt&yrZU=$Z>gUr6+xIhdOkQpg4QrE@fNBX6^mU2 zWsV{$$IZY?O6G~)Vl~T!WqR<+mcj z<37J57ddN~(VBb~?PCcD{>7AAzU69|8P?&&qAFSv47ug?~x zujC?(cg^fvgj#wQ5o)``98P`+N7A8kdxORJqXh&D>0mjy-)z2dvjzyoUUWI?L3p@2 zf&&i5K+XlG{7tI}b60C{xG;OmYLO8Ff|VGe`D(JKQnQgH7Ik@lFP%k0WW?Quod(UlkT zW24R(O*)|W{L7JBJB?Kj21RhC+#h@qapn8TwHe&8e1IYq0lC?ql^_tS36K( z3unU=G*fSzdY}wUurt>f>fWaU9z@X@>Na@^enH+Szlb2b4FZ)-j7^BzcsG7s;{%aMguV+dN{b=4a6i@AWpV( zsA}V^tA$Z0vb;+T1`RZWc;XCuUyx{B9e3`+DICa5k@fs%uqYd99 zj@!O19C#L0j$b$$wIk!Z9>Yok10eG_n~-_jU~fAjCiE&BIZRKg9eHTHaG~T7hJ99h>Nqx>FAA38KAg=cpeUew%{w-yLGco_VB+u&3!>YMm zCuQ9((fk_gYt4;h-s0WwDa!kA`}+3`c};in@+UWm@y2(oUzzXY^V06&YJ04Dhf3IehdA~j7 zbI+QGai=Yhbz2eNcUzH&kA}ThK5y6IyK5NoxnJI{yifm2blX1M3yPPt!p z9KJVjpSbsSpShQGhuru7-M-5l(!OFE!o3ksB)#@!=EPB8;ly{_*28FSrT;!Gj{*5x z{pnAu$V--r=g#rk&!X5XaJ~$cVD!h&KaJw7z)MpxBo(M?6|;AAm;BSx%4Pr6UHwl( ztDwELyZl=1-?@(cZCgK{p=At<1lOlyEXWt9@vfL-97y~$^;JTFidKGmA9ui-|KGcg zz-dou>o#%47fef1*D^0L||^P0~v z=C!3U_%(L0K&ATBjYW={Ydb^!9qjRee#$RB=?=S)W{JYCSuuD8&&`(V=pytY$>1nAxta4>fnt#h>}fuu?pU*5rFeU15VGqPj@w zR$a}2(l7(A?GM#=@WdbbS+EK}8P^0q6N)$R+huLR;M6#OYFLWEYt>jJb!(~?M}6J? zv^G1`*#V3{?l_3=_Tw*(#jw*-Tq`RUM}c`M-3o*lP#_oUwKjNd2YPnjkD!?635}M; zGqK_^954NJs>@sQ!t8wvkyyOTk0{|s${nIS&W_0!ml@0Iw zUMoZ$p-q4lTQ~SwYwmmf4#5s^{d*N3!?$upJT2g~|Jl;%_ZmLBh4RrC_%r61!PYea zbajHARZC5s^43lPiE}%coF%>f+B0gMtiYzV**Y~;iY~jGZ5eTEIp3RB2p@TC7N5AA z$>HBM#kvxI{&|w8c17$jR<-nqTHERc+++^t*3#=3I$Nye16=15Fp)*<1gm;_uUaeW zx!rtiHBo*`@U?(C-p*iaU;x4V941Xs8G)GY@=LGMdag@1TXj_E(#~3J9eZbiwO)Yo zd_87nku8Ck-tsH2@_L?yqC*@pz%rFrRz1_Dv8^2{ZwazCTzA{4ZH?t$F^B&QP!fp+ zsG!1sn9@>u)qwo%W^X$i4%XL%&zL)157YyYvjv#23S|NxmCRQ+m0~=Xs@__t&1=LO z)0tqW^1<#i@se>oAHz)2n`~-aA01`P_TpWCz`T5?9lUO>;Y>XB?ft&nPq+Qc7Lw{cm*%6ctNEH zAP$?+4vs3Rz@`EKD1@>g9L~nx-g{fuK`O4^CVO$$`6_naPJ1)g2@_UlWm(e)%Mund z4Z&lj$mi*rFfw=v5+~gNMkQ1LVRAO~w%fb8hD>0d-Dcq)U`de95(H(R9jmnZ2*lYa z;O9{=#@SvaVM_SLGiaf!~@j6AQS;E}|L)XB=~Lrln;C|Q;|fc9eg zRwnWy-Lr5oh(y;)&5n z%q%@}T*(Grl0c9h8$NWhk=NP6L~gIVZ)yS>X_n}4Ecd%G#}qjYM{*v(bWYakL)VJQ&SW9y`sLkiRnn&EDQ2w$#FjL z&kP{qg$sF$#5g}V*w7Mz-L|km;Zan@dFp85yBFW*H&GH9kTp-fnKe%lENSmGDxX2NsSD(fP3T9W3Y#ZNJtu@~MmX~fr!g2JbAPD*>zJ55>R zDNd4^{JVh=%RUJJpL$kBO4G#rsM=ntIs2(?4e@ok;G1iRAo+Ecp!liD$=?a((Gm&5 zQOvB&R9wmSkEDT2yrjWxJ7q>t{nz!Qc}4&y9f1jbYJ6VppDih@-Ti#pfpnv@>zgUS zu73XcAZ5#P+{^`i8nLD(+7;-^8?n45=9T3YO0l{o1}|MF;N|H~J&J7faGfVrxXXgq zH3*&3(q+N#8a!@wgq=CRLLt`P#Od|f$@j8r#}6en8nABZBtmINjnAYP+r3gARKxBo z0K*9mFJoSJ1X?#PrI3_2Okfyq~Uh+Vr%lf%& z)L~igy0C6T5YmPn8#b#;4r!@l^HK)7U#`xDp}foD*U@?iLR6Cd3JNwod*IyhXn0YLN9&lTt3|B0!3~-4(u-@&$m#iwuC+<4{cEVV3?IM zcKdP$xle^C`;CvM$7R5I1SW*6LfiU-ijhU{B}7E zX1UQ6CcSGm!10|f4{Wz>=z`T@b;BBDy2WdEgMDoP)OSVRnr_)`Z*QDDjV=?+;xTist5JiWVg+J2>3d?ntPvE$^WAe6D9P~Iu=0$}O=O1b>?F4$m6yyBqx?%O=^ZBaQZ z+Q~rsBC)xAzrw{}8Ft;y+S2u>II5pBYd6dL}D(fdA=fKT_#o2Z`yv{Xs!Js

vi79rG(cN(gN>kYHc^DN_Q9=9$)m*IPKz;kJI3~D>!`B-Io zr4O&Kt-9 zgg$v7O~{3X1fJ@terYG{jR<*7LaS9RTNNf1u4W#>O+q)M^GV|a3kz8Ydqnu5O<|#N z_ZK`0j`PY_*$E6GLgyic7SUmnHo2Cj(V>jzjh5y)UvMedbr;`E_VtB=`3#*av9n`E zX`8<_@0k_H8oK26u+p>OYy+B%0#u(KG0= z@#?)hSy0pINEno;*XJ;0HGSnNMN*?}hV7|XZd$Ube@TJ_rXRo>O< zhlx~(9|%*LL5{h%EsLMs!>JNn7hWxPM-3T*70#1qy$S_!ap zGNLrhVprpxa7D}lX8Z_8F%eiU(kxMvr6qf6K{LLyyhs6TplHHB;|x|GHO(wy1M8X9 zw6Fwwm(!yqtj_a>OaMhs&g)oAVTFMRJ@S7!FN?H3*Ro(r#($1r3I0+1 zsF>yP49S|c@C!}N4+^s#_H|g&g}SmTE~t>=V3}FkH$~*@T(eK3OU&Qo>3*-Z4&*Av z>nj4ksSx_^5C6%eL7H0vN-6|((z{?WmQW{Udl(hN1DG_$Ma z?-t_oCELnzQ1C4ni?UL9ovsC!903xrg!y-$QwbPfbf~tFMlE{VuN(yvMiD3psiKND zgVmKN)4(ss1Q^p?HrCT(pYNvAH?GllOEF<`2%4-{$Kq(GeQboAcJMM0mJ3g>1@TaU zgm~6@m~cVDi}v$_e&bZw00DA{^WQbrf=3WA&N_t!t=9ojr>hdz>w>3rY4LCNOS>!! zi0}$tn4~$r5FnOK|N7Jd*U>^4-=)|-Nj;!DT~wf}sP}0BK8*wXSatVhlr#A;R{=JS zYl=hMw0};z7UgE`x7~eR?T+d`}=P@0A6RFmv`;K!#~UKmF(UzA2FqW;}Ixl#-Nofl>Kb$F2+G&Vkis zc1G06sX|&sjlJJkU!pTU$JA?5V5Gb=HODMwqXOxMW7|vZy?0(xq?;wpPXW`c4iAj- zKxgLiS+ho^#7&CkC-VniSN=4tNw-n)@3VNx&##%cVKu;YSMm=~R0h$)r?jPWk&Wv7 z>m1OC78hJdg`PtNsN1`l>f!)jF%LhkUCW}|{AlO6K`5Y+yxsW(#oF+w9gKTS;Y#asK(g)%;$i|}N84-v zm31YK2Fo|CCmg?NNW)seQG$NOKOz}}9(on(^#(WbdNsBLN81D4{q_2391gB>j%dZE zY`3DD6mJ|FlA|5Za}h#xIkq4o3ycAOpCu)ootY|NuvOq9hB7PK~gMUz-uo*QY_r7>NR7- z*Ivn-1m!!N6cvOLLBB)RjQ`SY{!}Gx-WC03u0b(#5Y2V>z4m3Ms&oj_g*)Wu^&RPN z1?iFDFJ5*yFXW=1@`&QRp331e*1G9%_#>VDIQe@Wj3+fO&44yU2yQrtF zQ60Cxu?U2I37WpAZH@c#m$zrFo%XSz^p6TU$*TiX0ZyjS8%6FIJNleU#+W|VL3&8? z$eNxUK1|y23OV2f3AhQ<{!QGPQo4hTafGny|2exbgf4v7_%%V?Zbx3w`s6C)vmyW8 zR@U>^Z`-+)JS|^7{tL{RmHchUac`1#tU^SlWXN}i$g+%)O(3@r{g@O%FD0EC{DM2| zW=dd}Ry_H0bws<{`=G5~%zf?zy)pWK0n#nOPfW$+xO|XuM7!8dodRCUNzV_T$I{Vrm!5#fVXpLVrTq`q?RC(2>^2@Tl*lg_lCWE8=9N zD#ax7l~G^N&8v)$v!;f|v!>bnf<}{C++sbKhCV_`D88#u>|ZDjxeq3aZf{=kY<7|L z2XY%yq1rC)YubKb9aaX>yMqhQ9{#_m>Bh>Sf{O@Kq7bMoi(rp&d>T)%0Ag{SFlH$F z*I?`K8-E&x`_X9k1j~0R_kKhuLQ^g~#^Ecu>Y)4IHwl^VcyE+V`R{qIeq=H*T?#s; z+z0A!?G9?LDjogB%?$>;YrCn)&7?WO+tBVJv3{Gz#%A1sBLJs4G4wjuj? zk&+}chF}0uN&6;Q5gw`Bwc+`M!j7UHZ*iRTtnJnd@)&(auux&w;nRk3en3_UJA913 zHR@*(W9FW_*Z!I+rHPZhm)asECctml0DS451GKm%Hdta(7TY95| zf$gQR;X|{;-^!cQ+H_$}Lv_S_?c;mA^msGoc;23qpCfp+=bNNNw2?Ep-6~*xch&9v zyP@R|5p5U}t8{3qBsP1_j+{cb9~)uEos#dLA@3jKTtDiCMWhpCh1_MaQRg;VJ3|X( zpGSK#2!6_zkh{DKTt{C5`3dzLyJ|kBq%wW^^z9ITJyB z{6O-#u};~2B(<{nJV%~(7q8MqycPku&qeUJlK*t&=3e(1y?kkc3jT@56+zIJ2|N$Z zy4SveyrT^#LVLP$Tq%d&T1?F8{OYQeIHBd)hsY2{45z94xWxPBF*jO-s)F#zYe*k z+djVd!#|^|Mico|qHH@b@@E_43WDjG=M&odjc@2@zPX((w1w$x$_u-Ad>(X7g;FZN*Q(}SF|2+^gxdGoc-BP{B^5dXtYCb0E%|yTPx`q31ueIPkFV2it5Rk| z_v>oqLS}u*38tBs{I*en1-z1*ULj-ng z&#r{C{p<^Q@Jd3Q5Bz&q!JDQ79xv?9WC-tim1l$K?q{Ds(_S5Tf0}<&l#!Tq`#u7e zWD7MUj?c!cDr}#mh_Gt-LvsZ*+wjxT)D6T&GU;>SYNx{)6Q6z_g#eX z8w{7>xAFdEB#82lMJ)P-TE^$*mOVC`jO>$2?Ja7F-(W0DCfmd#^l#xG%!G6i31Azbw>ondk(jRPzZchAUB+Jh&8%ZH(M`}1wCxq z=@{5-SpV^Ru~%ct##C-z-u3GS=hJ>Rmn3OrdUP%%>5F2+s3YqFas7~L(|Fe*b>64c zMvEPq{vUCmL{T7$OW<@s#Bau6izAiW-of;Ow~y~&lruo@!*hytiBE}NOxMiGCbQ)m z7$py5So1*$A#EE>sK5s(PUWPa;vh@HZ!2!E=ItNdBgsD(m6=8|X8IBSxr?_tXhTlm zNiOL^egjtR5(m(AAUpl9amºqXjievd^-S5VA|LBo3f(4Uq+8@Kuz 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�F;F4C_V=3MXrr=R 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

3SE$Ht?mHL^lm`z0% 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
c7GDy(7!ECQ%u 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ͤe$8u4+8k2@ifv}G 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�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

gk+W^8r3XK&4fVbf{`i2wS4v*YRazJ zFm+B*mcd7nj1)NEs`5Vw`vxG(wq@HccG<2j+cvsv+umi{)n(hZZQHhuF56vQ_;t>` z@7;IayZ8JZu_IROSg|8ku9-PAN9G)(&WYC)f_1&DH4M@OjEVA+pci2k5+TSRo0LKl z>*3C9dZdX)Qy3QvwUd6(KI1T~Ej;me7{JmnX&s6hRk&li<^$7{Dn}1aOF%Us=1b*Q z2@AMr<%aw{=Bd(yqc(z4KNsG-^iL1FOM1cG}i#D;cc1{&4_AyxVL!a&!A78q)pl7(nia;=aZx?!)t=STeHD~4kJTU=a{s}+yym*qH0o`&Tna^ z?Og)Q=jw>hL!Fo1y)?}?!$ze`htR(zqaQ;lw8*dLoobc+EX1jrcMm$OHy*sex&^BG? zkG~*Z=I;mM+A3fz#J8an=YjtYyhm6i$y=AR9B_akZnuVc(e9qK`yt&nZ1x}tKq50$ z<^jnVpjg8`c5)4@2&fk%b85gd=+_5;`R)oo$MN_Ot<(qX5Iy%t_VZB5;YrqiSzMHZ z^NBGBw~lj6zR!@EOCSwrb!U6*O)%3uQ7U|c(Mf#AagB5bof^Y6RRT~PbttT;&;2?+ zkW4Zn;^`tYefgSueTf=SHrv-msZ{pam2D|6Wm zt}jb?$OaxlJT6=^Lf!+AIQ-}>)7}%+oR>83cI+}+z*zIa4bQJvfvxX)aNpw|WR2dK zc!#TziY0|q(rVcKmnpV0UO8oT;eRfJy$~vmtt`ea3v)p8dP-#3#2AB2|8VUdUnm-p zmBS_lUfn;SJS{HK-ez>J9JRZi*>IRbjaPa~i^C zh`I~&^Yms3)ZYbOioc|XPL5`lbo|za0Ef>Y`v>o=xa0rigN&5dmIUTU;ZbFqbed

;-rz=5OTMm^Ju8t;j%W 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�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
  • 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
  • wid_v# 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 z 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
    156QS9YkW;f-BLlDx-()$tOdrK9{SV%WEw@*w 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

    HJD+aftI_0a62Sszok-jBF#zR=n_ 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

    RGK`ay@v4X;?L&r zi4qK_vUFTEBr@x;kaUR(z$rrL_GTeL$MX~5d`A@EbOGqRzX$=5YX{Jm1p<3=UXgx9 zZoN`~mcoVjWQc+Ned)=-&V8qkeAGVcLr}rW!ue4}cffvb zbSP<O}su9y+a6U7{!Oo>rU()la8h2J1=-k8Q)Zg0 z2$A!}$3TFh0nIG4t6IpZb9N>@ub2^eT(OfENaf+o&Z|Xwp(It)!uv2M-sj<*Xd+ z?gHfuL%pkpknhQD$y9i%^6Tpf5TZp1rI90H08cu1_tV0N#aP=TTC&H(Ko`1t_4Gg| zYBp7A$xG~`%WWk<(k(R#i8XLDk>bJ5yH(|&;?Xxt2j!K9BF_>)U|bK>xlHXw{n*+c zy|<$X>DQuAZ&3p>qfrM7>s$l89)!`K;uCd>1>QMt!!c|2Yiv4$SGL>$ZQJXhCZKnF zHElYhT%o-73xI`%OQ3lQN=tKj=I0mX;Gzd1&;5buRSLk-{<+W|26E)q24&S6R#nn4&**W6;&{#OdT_ zI*AT~M_c8j+L0Rr4bRie%hMECdDU=Jl)ne?e0%x`HQpDaW^UUsP4$B?b;X_}=|zdZ z&W3-_a+n$tPidg3;gPRttRk(b7Iaz#eFi7qS<`Bbp3Vv6vLi?~LoG*tMx&h#tNvY& z3QIlgWwr5&xY=Y=w2G&H7OLBRvHAFOWb*;}oqQexQUscwK?-W{;HEZvA7t|Z%3DVl z4$HlaHCYlWi-L=qBNdSMEj`Y9+LCj*ay%57Jgn#CMKE#Vlt_BGTaR)vfn#O^6P$M8 z!KmTO{pAp08dFnw$wr@oH9MA&KAxvI)@yU+P4RP85Rro!MuHesm5QB)%6Zqj%TR#q zr^ZktcN!^*z{m)R{JDn}|lf0gzmXhU` z8X~x30W$?nxpEL@P%jVMUX4c?IVw`AkDjIL%kKn_s-g2Cm$A^JJE1Heb53Rqgp37q z#kA>M(5~)-+p)-|#i97yCB-K+qW2!A|WaiP~TxHVz z)B+;Qj!bG5M{amy1s(2EA?F+bb85dUN%4N_pk6~{Np)5|r&Q8RMjc@Cx%6n|-PNC} zbq122LqBLW?Rec~WL{cKlPwU>=B7&zrw88P+MIn!*IxTglEv2-y;~YK(<>p9Bwtjm z1_`Ry?Z~XtMnIcpS6qF|glnPX(U0xvxAA6|A=C*hN$zYFC-WfDEXQ01G;I2-~{@_kn_FJ2i5skw7wk&;Z{Fx;fRrYR3#EBFWKV{^~Dn= zDbr6Qr@8p32HIh$>b~&nR?1FRIqVW{PtrWSb6!|k%xjjsK z1e*aYu0Rd08FrmL)MwLa%K1rm)A7uh;>lP3@ywf|$yb5#Owu`QhQ&L z8jaz}FDFS!+9C2@?r${%a%bxsF1+_9>Rt;b>Io)B6=*9PQ6~A_B~1i9SCW*BW>Hs~ zZTB)-o-Ps(2Wjem+7g4wU>l5i9PA(l%EI((|Lh^^r!pB*q0H0JpYzCMHR~~>=tEzq z8i-3YY!{mRtU)jP)L3>TL!L6R0|^;tU|Wu}%97#?k7g7y1uKn?cx@V_a;{W=tuBei zoS#ogI`G3zmQS9`Z=>(9o27a)%Yj#!pwn!o_61aVtGDKqt2IgG-nd5Zz>&EijF!Vc0OKI4X6Bu3vV@9F|Oz9kg!xy0Z4>&UXL#wR}asI8ADf z)Us^$28GcvFDRCs=|~@Qj~JA#b_RVD*TSwh1`^&Jidqe~_AII~uB0xxl)8SRavFfh z1~g?1t18^d3BYGd@#zVlv&XS^0{Eses&5PB=?O+r^Sd~GW!-g{_98azhS;!o9;f(( z7mh_~UO=f(+F)rWJiA#m9B*l1EIzjPR+)x35chg_c?%fiW1aSf@a~sb^Jmed!(n_( zt$U}cI_)v82{?Ug3>eM+2#VbF|I#i9K|`y^ zCH)Qhz@8zCpTodY@E2>$6e?$p*faKQ!d6({Ijn^&Zs>g8cnDlwy4{LTfQ3N&SaKBN zjGTM^=qs?(am>&z$w*UC-6kFa%^uh|#lnQr`xve1QrMHlCaiG)|bNcJz=QhV=&mzEcfxW?6V;Zn7@hV(~q=uCOx(=kyM z>O(~FL+KfXZ^qMd@kIPGC#iOF<95H(T5sTGp_BT&L(*A&VG^ul3be%NTk(VhVm;OI zxs-1=M%LJ439g#!>kIuG2npS;I>rY($mRpo0cz2OxTE(Ft=ANK&k*Kc z7~6-ExA%{tFM1!N3*Xgy#%|NaPa}rNDYeK1C(Mq!efEWg)@7?FX*3 zi&^rS11-=D;|GZWG56ti_M$Q!hX?wsJqGPvdK@SQZTi$F{o;=5+CMvYvGoFNY*0(c z5)A0maN$%}P#S?}NDjsraYkf5$)p6MaSZsJg2PiUKu>_r3gwHM@6~v(b5jYt5bueP4=wD`nXOh96 zYAXRxA5b?6)pus4sUNJL#Ew-l1y;GYN-6!W?abmUK$UNUg*Ny|qe{qW+XJvIZ%U8< zI9I@jAizqJ+#G0Ut&m~!wujKq6-s<~dM56D<*TI)1B>7gcIjVbAq z*DTm3mTF&{=HSF|FgK;NOUDR*6xbTC*17~`AYz;L#SXF@Nco%QPqBYFOUiUhFD85pnN*SyjW!24v(;=bXGENtw=F3^mM zmAbcFQjKl1|1YkOmUu@RhotC2Z&<*o{&8`>I*ARZm&22R{@=dJ!@Yw;VbWK?6&|6Q zxmxdrA18Vf&V3pv{ag2lPQsf$GRWuzi8@y&PvbwXQl3LM*c&?Nr`RhxckUA#lmVRw z8`t<$v{Re;tfJMPXz(mGZM8HKPog)*6A%?}9wCHr?@Kf

    r- zCWs?6-NsZfXs~B zU~mm=5~g4Vnl5xi!+7~!!Vdv)btN{cjZ=Va=#Ep7359)ib^ZcGl&?j5&e$62-Dgj_ z#jrCrD%bnx#t`L~S0Ub9zb8W4#;mH2nsP&Xaiu$-mY0;#(0O?Ma6MONPy{77k%B^m zSUeQQNs>Sq9-!mzoQyygvL2ibpWR8(FL`WJtIPA)ma5``oJQl@R?93DLGk9!mq z*bAv!pE&o!bah7GO51ZbexF?OWvmU1fpDvq0>Mtm$jQi{C}vZtl7xx2p8TF+`}y!1li=$8I#NmF^Lf4%*EeCe3N9(>c( z?U1iwdmlaLZBoQZ-8u`NR!ZU-pTR93(aR1FL5Z@eOs%fH9Ayj75O>)_eaFj@0yh<`XuLI02&$=~_kYJa8yZlW_=}n0&k*|1xG0`}#rAol_I8gZkVpQWu zgl`egUxfUojFGEs;8!>0%UcF;iD(jGsQk=w!nOLdUQM}%mYR-^$}f=H%DF$wiS0Yl z2y?B>Xsklf$?{IeXM8n#MJK-wv|e&G<_6+usL6@cq*%@=3d8J}!puY>5{m0Q-kN=4 zL;}W^`$C$Dmtms@J_bpbWS|*)O13usP~v2ve&@q#Is7IEHHh9qjqc3H$)M%B#)LlU z)qa~DMl5HVTs~&84r8)m%y39AF$}xePboaa4OR+?4pJT(szs}Yxf#pKZkB}-Awh78 z>b7E(n6#rB?uawBF=z};TlyX{4jJ3uT9F`92xS%HoM%);?4fBe1xGdbVA%)FG$f>K0tWf{8RT)mK5T;5~`om^>C zfVk&nHb6R0!G86 z&3MV|+=0GVz>Z*AJJOvnP@j!>jE=5nM+qhTHM(u!E0oX<{J6!}4p*2EZ=KzB?O+8J z{i0J#m~k|**USqgJ|`vTJ_Jvo^D|}&*a2YMbp`VUP|lP$#WOs}7H0+Fe1(p@*{@!A zb^$s5mvPi64>L^~zJLW59^dcynNlz|B~>ytlausVqMXgnazf9NzhhW~Q8@3i{x_OM*z&Wp5m0DK#~ z16Swlno$(V1%KMf_BqRgRzKp1Q>4xcH2a5fC2GrV3ZR2hYv7u38PcqZrBO5|6ok}Y zv+VvwSOFf5zR<6qn>)-k#}H#m6lm&|52+(klpL8YN&U%L=Fgcs8OAM@EaCBUXI9tA zEs9*u;d4u$d;jfGhh9~~>%?yCE#*^ZnjNx6&r^_F8^S6aF>q=%cv%ECU3XkbIt}v< zhGq2WE#WhSrdt-l=R=Hut8x41tfQ6Bx+`%@f}l`ItCy<~m0Og6q2>#8?K(wS4K9j( zQF&EDda`y;huwiDifwUO3Q?Tlb}}_-L&D(0RFkDB#k@LlWVT_3fpHxJ>&#Ja=yg<~ zrqaRaaek0Wad-T*z)PYjs}Wa~YpjTE%d4?R;-Ub!ovdTgx>56aq?Xx&L`r*aTUz0e zdpUR*j-56t8M;~v%#L&U*l~;?HmV7-yrO0Hi^GhZSH|J^N&ZV!g9e$kF6C33oP4Rh z><_&<7Is#2vY4@710g-)?1J;0ABWj66yiNI`)H9>Nm`LJy8W8N=`J?ogz$?%I1ytG zc^)z}UW$R;j^N5dRqROBY_~?id(nSau{o(tKUQ5GDqhAK1(YiXHdI#N?_^~5UmJWO6zh`U=u@$#7XPT zbDSq}aemzF<&0ZN-BIK3rro8@9U;Qu(U0l3rDfv$Y@GS1C*?4A8E7&GXxEwB!fZf2@XL$Lv_C8!12`$EkFCHPYL zBCHFsd*o1c0*0x7iYh}B7kL11zruM~)_{HLf`&suqOS|i)A1v2K!Y~QibKrl%AWbk zI|g`%The_ROkBBHzPN&XxF1o4TRT8DnNqLjHR_yRRDc8KN4DQO0h^K?b{s_mu)} ze5=EE*{o-=3FDK0@3#@}AB6C7dShnoYFbJ8A}pa~wMb{SX z@xyh`URi+l{7GjMcMofsr|@Ly8jo49_@wU|!kypvMAz>+eJktDroe%8ulA+dn7wA) zrJ-%q05mAP;Y&Ao28>t&|5Q@mIhgByy7e~R2|+nzoVy8)x;-h5B3uoaUMuG6{aBBD z)q+_zvMfMs!FNxWnz1sr{fV0os93XvqxGLn|1ul;fH=eLh4l%X@{;_(H%o)rRp8}C z(0nNgZY#{w836NU^!Kt`42*Ci43#0YQ6#)vz-w)Yl-!=$QmkzrjfbYE`o^-l-NK0TN8fE6B*Kv+N{=MwOvGIpY3nz| z$Jkj+bxP;oJI`OHJ^?y^J+QJfNpZL!vo&!n+!~23IiNG5Eh`wgR+`hWZ11SH3ip=B zi_op_91vqUs+&Srg}GJS)oHRoPHv5>ts)K~E|ih*Wy}O1LZ=+e=FDEAxx;aqQ;coP zj03ZcUErDyvctRyWv`)4HWrLcj@NB+JNZ?FsnxrXQm;mxG-X7S*=P4y<%S)wry8!d zI(7h)6XKlkZp0_1B6B5figGzv9yo2(Ual`X%=F8=FoU#w7a_kj)6d2o*I);C@Egka4Xu>*`b!508!_Ddg1 z4CwZP|Ev~j-v<%|&k|VT1f=4~l2PJBsFEc8apZhRroORmqo!W2UQP8rb1zF5+N{As z(esvViAUv9%DvF~{Q`hvR!@++5VU}j_ri2NVpOEz;(LONEPr)4P4MlUgeitTQ2bm> z$6s*ERE|J;dcZBn8+>s;$%(W6k@HfDBL{`d;vPcT(U^ z^alR1IKolz)vEU18Z#-Px=?)QgBYPQ zU*~LbM})i1>NpiT%jVe8u;d{>(uW$r6OH8spC2kZA%540Yp45d$iva&CSxhP`=~DY zDm8$sh76R)Cq_Ph)g}Wh(*-0(>R@~rQ-glT_l}?bf<7YoCGYM3af4BNEIeSycW`7ulpB!RkZChLg!lnt{KS~uUjqjJ7vOx{XlqR1 zhp52rv~PbJ)89?fJ%<8wCKq3IvbX3BeK+Jkqob^`j(ZHHQ!evDqi59DdC)~C-Gj9w z+=d_|aS0py`me0eW$`mJ3BFx}ARc7BUyUKuaoJzG901RTzOY1~8e`Cvqh)xRj zwA+s`*ufh{8>jbGa%89&)tBMc>AG-QZA+|}p|Dy>&ZrnF8OhpvR0+Rz*kun>#OsoY ztfxyqHRDJMUNb0}aO9`xU2wG;f}Xd8SJ-`U*ho%wfasx`r;5&eJB(1P9K;M1XtYeS zg*0gp98sCt8PP-5E%SsnPEn^Zg^f7*S*k@7#$YKddmko(k?S8*gOSmbP3YevonR?0 zsjKp0tjU`+?wq=tWDv6|8=mH;nmh6E^qJ|$|d7^WTrx4h61DTx}Pw!pq71_`V zt^h?q3E(lr0hJU?HbMyw>NOaZTsd;m_>;`!iuhHHlP^LS%vHsr5?nJdo*Hnkhgwg- zM^pgL2)E$5uh?4gJ1X42;3m6o8m$uu(6*pGeOAfiZZ8X@AhWlq>vOG|rh|4FmA3tU zy&Upd+!Eu6$Z88sDw1HJ~>#9tC{3YzAqLYIgv2HkX1soO)U z51*$k%Ybv<#y+b>#|CG;33DvO#4gBsNymQ9hjBzYnk~g?Z=ZG334F#cz~+kT)n&O- zvA`DDMCFS1ZJ<-ipLOeLdZaB#tFj>> zS%F_j?6{GbZnVtvil>)hm}g;8mSpX}etTqe^Mb;&rMIHn<-8gn3bgQ&*aUTSz}h)d zB-yeg-Cd1lT?@l>g?M`Myt!dI-2pq|1aKpvuJk7DK;XFy^lguDl*ZuZlem_Aw(yZ& zoKkp0p>Hlg{OU30;F&OZWy>DyIV$_)+`otjMW+!U&^Z9}&RV(E*qpX` zIQyj5>AksQ`s90TC5S2hliURy;)G+$!LKeWpipD=*yIEfA52M|a}nh>J6Njyy~+M+ z+w1S`8%)A}2qwt#AbU=1N*fOBUR4|8Zc*4TEV>p=^}K{~lZ!3+7qNlk0I@+|rG4l& zMAD|AK~W;ZY9^?`_0f2Jci#SrL4tw6B(r)_+kKUFyU{aq;AmCoqZP~6(bge@40El6 z^KqWw&H_iuYRcebz0Kq0&A$HK_2t?i+(6q0FltztCm8P=Q2QH^_A-Vsf=4L+1$}e& zWO39dU+ELn={^VVn&yoDE8Y5}NB3hVH~Sk)?A@hwttTd%xSBt`Cou(&*%9AJ6V3#W zmd_KqZ1#4~O0#S-6`v!WeB+v?M7p2uoo4+`iXiFPN~5M5xU!zRm$GnQ1dH z8K~I!S=~%F%&Ei!iXwr{0me0x2)X3V=%s|ia$J-^P zXRY@mk^R4x!74>7nFU!SZ)+B1=J5zb*|1I+V(WvVAAvnS1fLiH&!q0BA@zYZQit=I zHQgtL6o^0J7l2RV-Db1eelq~>>imYsG?!Pl!?eRXkB`q^FxrSFB==aEd`wVm1+qbY z1N9L}D9FPl`VB~ht&?`z7!q^0@`JSK6LxJ{!g3N!P5a>OD+2FHDIN9ZwgC$XN5WrK z?#|JA1{+W0#g+DC=hkZJPX;5DZP~O`B2Y7X&2LqP)}iz-R%)9YS`SBgwuMUj^Y&TT z*SF!f5HxC>cBg@G5FTqk&b$6wY8TAiH?H8e|?DL z6AqMjt55rt=MiP+4Ipk-%TMz0CRhvQQj+73>+cDx9d7s)hF9Mt4Hg%%r*sv+s)6e2 z0?@z~+NJb$R_FCiB5ZnS^Ayf8%!Y8l1WdJcJxv(xp{w@d15aSM1`%OTfN2{H^8f@E-YY{J%eCY9(GS{-PlD7e1;#tHN1?o-sHoCD^(eIGh2-(9V2B`W zeRp*ZiVUm}x)mB{&{>eUMIHz1)x+{;*hbEYl!R;-X`4Qhyq#VoDxW9R;GUxvSO5eV z?i6gnt)<^1P4_`5l*~exR+lA;OI zV(@i|2_LcK+nL`=s#~6S$i92GsFKYUT#v}arlRL z`I>lYo@o9zpr1HkRXVO!3$mcOc@QxYl$jmGvmf}##ubs)=5=yM2f`P`HzKZ~u-|j;>xb2dbBYPn15>TnxQp9S*iWMChu~PF;J$aS9B0#jS`)3EsADwhlMg^` zRXtG^f2KZKMF+1sESpLww}cw^#`p?QxEJMC$0bfRNs1FRVe(BiR1UtLM7{+r#CW`p z(+_@SPMl!>#GW(YrMeWfLbNDRI~Ei@#XHUQowDIuk#6S@mbNRq9=#QUv-c=_8fn4Z z3e2YaY&gw$`dA5km@u=SF@nNN>X-2rC=X6vw%6sS6-DoMR{BEyGrCOAAQu>5d0U$R zd7@@JlT$UNEbaL*DYA5H_>geifG!i3;Kk|RJv=n$2xRdhmnd$?_r<4@x=kcCIHy~A zb4AlkO9z{FgT{)e^<;)6W!tC~E=HDBnmSzsnW6FRqT91lwf)U;S&$M)=y2i)@>@0$ z0bx+UXx%px$TuTf8Ow7F*HUF8j05~WykwkDf0CnBZIvw0J%+->kh>^@X)AG-DC=D( z28$?BY}W>pC{gT^^z>zd;)j?P>s9;d2UfmqQuNWTC3yzgQtGrW=^KKSu0+5}wGNex zPj;{(_iP0OS@hL+W&vfJDmBJ~JZIoquzNPvK>WrHpQWZ5QU@!?38rnmTTuC2Dps$u z$zv_rZ*ay@oi93%jWbo#+^8tFgrO){g>ukPw*LNooGAk;xdT|V0SG4dO2;i+!0sZUyRIEIQCQKZET ztYmCT_!xY#X)&dunW9IU{u#pRH5KMs-aEzb6{-=rW=!Q`ch z=^&>lheW%;>NrWwia<)_p&O6$)Px;-*TnETudn-&-VbA?uV{&Kb7gR3k&)hmb9Vtg z06L%0Sl@t8KLWZ&H+Zx<1}=~5u9MGchncO<_m^KhfTzP2Rj0kRgfgYAm>)zbiHE*~ z;6&(ijGBIC9+SdpOF}e} zXnGWVVAsHpThi*9DkyFRyE_FH?byvVxaf+0KC@OmQ*7Y+QtuSAb};bRP;|aInk_wx zr3op|JowC3@7(N4QT*ayjYhAm;!F*5NQEt#z};~fMwa3!5G)sY`OuxpAI z_5>lA#lQuqlNmY6d3Rk~i}hPO2<>PjwMpiMj?us%s!wt+#s%Gjil zZ}yqJP~bL!&6=ajEWp-efZ-FRB4G|JFLnp~<<}wwpFvO-zp8%h1~cfYtTahUV|u0R zk+p&!U)_~h+gNRNnl*h}i7=OKKP_3=SEeWfrA<7zc-^i$yFgd3iQw35?Nh}AU%Fb~ zLvT_9S4qtBduWbgqcXB|v<7_eHq5#8aH=@J7F^zQRHtSQ?b=%&E`dLVNqdor6 z5scocrGAYDf3O`*a!8$IJZrt45fwqcjvh6p^p`K@Y|Bsc*Yk>Mo8M8) zScj3fQ@|XPD1nO1Lenfxg%`!XqtVUljoiFp&aSjtX}bj4@<@90Oglj=e{Nhesq)KE zngnqO)t;+MX$D|AXvVn~zEt&*_ltHk%VK3x)K>hZsgoE~^8i^c+q{FGQJd{)@nv~{ z63gyXi(zB+`96F3AvSC<+&8d*c;zY4mX?RCP@_ROIvUi9E4H2Ao&1=5>PwJNJPT1B> zuyyG6P2up;AV+4sh7-Dvpr7%sN09)YgB(%QB}Vm`elbmcU5s;-AhaDOL3{^7hNxPP z&EHDJrr4dquS%0#gfWNlUuTCH$AU>_lO4Xkn@ZFLR_4J-6(n>%;zYFLn^h0P}l4Eq6yH|`0k|TuH_OXgu0C|s_SKm20SQo z;@p24aOK&!`+qybS*(tn>gDJoe!z&Vx@GF+95_9LPS^cpi+P1fTvB|Fb`RfN;#W7= z+=73g`20TBx%3!Touk^*Yt)DQd+Q3JL3*_^ca0*Qysbk`VW(jh)3(XXNjV|DNuaG3 z=7AJ5R{y&No5N5o?1Cz(=@*AYl&f!c{bBd+khmfh^*QoN!qc`{QJQBp)vq&6ZZFe*7Y!cFa*%Ed+}=Q}#7kaC zHo2JNYz!}~pU*!(IR88t|12Q@06w^XRVvK?J*7fS_9v^_%)#-eMf+D3qeyl_dVm)O zD0QxViJticT-*>1Y>T4^Ma;_>^8pK#!_ zcuZyF40)qIGlj2NwrR+}6DRyQ8^}5OEc=to)v**>ka~`I(A5>UQeWw?Df`1!hT&ZO zo>3fD{;UH@?&OO!`UPW>nJe6bW8`|rmIWvK5a2$$FvP>595t&RcY%8=Yb`DkWI%hi zQER7{514@s-#Ll!5ZH};TK!<{2sXlt$Ar@JsxGxbe3M>{mpIJ{+y4w!5xI}_0{odD zL;mRo{@-lff9(X!{yi_|fA(Iw)F53omz=(4l7wxJrxuviFHO)jnvElG5>%n4-gI|RE>6!Xw2@TEKXXjH3rTFJDS}1|~MTgD!HSpEbgTW*< zM(4X=r5oY`1Bv~zKei(a=dJ^3zPPtserkKR$MW|!hxgu z@@GhR)T<2WHxbi^4el5C&i%gAT3g}%#;Xo)cfd{gD^7RKE;xDfUS{JfY}>}KB4(a= zjZam18}U4zv6cCWA52RZ-#nIxgW!R%3O_ znH4&;1N3a&wG4tfQF{tKpW7|??5g*3X?|;i&J9AOW@6GsC&^|A{^%Y ztYGB0zmK}rj7hR<#_G<4()VC%AB}2vexfaA2#v?8lZ_Y!!B!ca{hp|eHR%>AXC2pf zyh^IaSAUDMEF*=BDe*knPT2{}2cwsq2&+UdSBujU4Wpi0S}fZuK{==>tgq;-GL&-S zW^{|ri&s0!ES`+0cSj$GuL>jAk+31n`@=~jDbVBMNFCYU6XHy_a0vPq-kPzUycS0# z1M4fjF-2~pTbHK7aB(mb&j^l&s|qt1LClE{2i;v=*Fdm0*R<>+q}JT%wO{1=#+*e_IDTXvYM zlnY{l+z<`GPKYB7YZwzmes?A7O+dvmH#A9BXHvZ*T0V)sG?ZZ;mu>kCQw})9i0D^J zO7|cWQDzYcxv@+<#TrYC^7cpG(y=MI8THeHMmbomF#B;$K!#hrw9{9oO9+dIEG)W5vq|5M{yLF93oN%fwxnCFi=VJ{Cbcyu zD1d6HFnAmJ`P;1O%r0rs+epmu_`der0BjZ$cg^FGSy*G3g4$dErtEo@cuh6Y_)t`% zcnU2i3ENzxa|bHJnp|A3M#Tbg@_AEqCEIgNZhiRNIeYa!qtQz|a9GO`(x7ribuo!~v=qb3 zMN?!Y3Zz9-rYbqpD&dP#;R5w?34?q|o~ZL8ewFbgwh<|AwF#0B3lATe7&9|Rd^(B8N=I2S~|<#V+OvV`vd| z>r}ge&2f`ji=Swl-m26Qy}UUOLvqcMIp+20WhRU|RZcbZ<3Gex<8>8MMov#zPbK9Q zOy-GV-2w$!jS_hmOy>Enf=1P;u8P_QYwuv(^ z&BBDQ=nFB+1PZ(wbqb`}?0hL=;pXvz+8Nu!td&n|g0ti?wjl z4fF&{=qfXH)DEBqtl_V48r9gTZQb|}PdQX{TH z4@}Q499yJd)*q*4G3x6n`@9^nnpdaDQ`ekWDzs14GNtbBk2Cy+RN$6fo}vKU$^e2^ z?`1a@?=C2_>X(R@@UKZg?mJdf_DHys#PVO@IxL}?-M`y2ZeHLc?}k=u9@|3S94oiX zv)?YU>wLM{ zWaTr#?YztAPf}--{!+BDMCh>FH2vYn^$Xi@(E)86az)a?aq5AVB77A)Av>t(fN6zw z?*$PO^?>Jr)R=H41$gixx5*65_!VRBnXL*|B% z#RKbV0las4;-kv;_p3{L3iS$&ck;G1#@3x`qRe-1A*R5}Ikn3w#CKjt`Te-%&{!S(h?DR7Y|I?Lmx7B!QuXx*t{^e zIF-++{lc_G4E5ZB#e`fX`W~%VudU-O`1^oRPM{B~rTQGet}f(9p~)<`!Sg5xWcjtX zFmJO%WOmg`@o-;04Y-tEqVjKn8U@;I(B4eqB=EjLk+A0fwyP(zME2vcjrH3v!xfMg zo{B>a{puGGU?PAB?3|VtdKnkXxkeAtc`20LhtU6_m9z6+K@;mfdEaPJ0zcb-vXk+o zR)E~0BKY4V6$@)!K~w^v9{uGGFF*-Y_bu_tit_lme2~(!bq0>x2Gn!uyYfY8FofiC zHEG24(hRyYRn~~Lk_-%>lS@#ME`r?cpnm8%Af>ZDfCY*LM@WW5(cs@Wnn^g6OAWrWVFldpNX0kRP)=a9xg1fTfnlp9;kJac z6Ao5xTS*G%;7Jw)9HVjilw8qhAb(X4O}K8oY2)X7#*0T}+JJgZzGde{Our!8zn;eb z3E7dFuhHcqIdf6FevuX38Nq)C^nV1yI1O2q;_2smhjc$J37yjrot>fO(N@PvoUtnXe+q)J5$7 zh+P-Fjbsr7@6=CV9*AF^C?wpZ+JCedN&4REi=s!NA36~6=R9tg4i}>qtA(LRpCzSi zDCnfbK{K5>p0r>jwE!2Gv_$VYnjv_k4A^Bi@H2;dJ&I2|Bj&`ELYiL5cZD>R;|{a) zBBO8*DF#`NsXMqMmHekp4tbU}~=GboLB16}uZQNHQ1`|k{X?4}Uq z_(2qJ&v+in;`VxBv50xaj@V>MF$ zM{j-Hd2k*dK)~&KkAMg6jNsO424`YXTQ|czM!_&vCM@MtoY*(CYvs zBCS$#Xb9Ib9nNvd>~j&cQp-+5YVISIl9!#teGGzH9=xwprvbT7xiKE^0wg5aZ(p@3 zH5A~*@QbT$qbo-1mJG5$BEs<3Uvl|DZC%)dn=i8o)z9l`ef&5SRuEOG@5qC+$TV;6 zvxdNdpQtakCY!hqlb}%|8-+(H{JqcF1rkw{!tL?ije}+Cq zHP6H?(Nj(#6@Nx|WPBGl84INYrIlVz$pcKFJf>?q4BI}Acq^{iV!8q!ObJANxneLO zP2dxebeM@|Eh0lOYF6lHdHkc1p0m78@)K)$OhB?OLp~#Uzfp61b3wB57hu3&<{}>D znXy7E5clCR$;wj$7kItK^Ab&@~tW$5#4!-L-@vx*YJ(NS&=*4i>qA%>V$ zwFc?!L0rLuH9;n@3;hZbq9GczaumlZ=@876j^J)rAw1>Qn=1*Nx{WQQ2?KPO%PdS8 z#D;MpIaQ())j@S(H@Oy~-g(M=|7Dx!+8T($E_5-ZKstoGZ*V)WUg-#>I8>o|Xma~! zrh5q0e?jw|yPZWV*E@L2-ZS%!(H+3)733>)gqpsFfg*xfp;7WL9V!7^BBjorto0nq zY=pGhF@0-y%u7UrG6`9v47-p=xV2NRV4n2y5}A57#~BKh*lRp|-oC;a^jOp9iy3EP zcjDzijYxj*NnD+WXf`m;jgx0xUlw+U4+OaUXdd^$`It|Rk?pu$DUVT>{hP<~8CRsi zbdhMSP4Mi%4mC_%`pL&X#WHC6-{r%g>bcl)t0YnZ^PJ&Mv5P67$-|~O4c22>W0Bzcy*tTukp4hgnH+o~+ znAo;$+s4G!#F?1??7w^bRc+Ot^>J5qRo{I-eO=(gYRvogT49a9uM^i9((;VDDSNFB zf{`fS_JYY#W086@Uy5QZOH0J52dw0lcq}buUuWHWGjfQ8`uxED35b+`F5roPYhag^ z2#|#f@;peg1T>Lk!x=M&z>(-J*E4l-(sZx1=;jhxl@sZjO-)ZSbJ>@G?zf*8sEij= z1ufc5o{EaioDlx~#88~JF7G^QS8x;`x_VKl@6$ccTs4CCcFFz|%fpyAZf@DpK4!tD zr}AW%nqe{c>+fJ83O%>rRY~@xN*G<(;k3E6^txOpBi0a($u!N$S31?AMuIuWbI)u4 zeVYE%6L=dw*WRExj_pV*;NCNJ3cTVx@}k2iuq*H%uKI2Z)arDWw>YaIpPeH$86cqm zgZXa)*}T-VUi>}GLzCw*TG{iJ?m%A}ciZz%qpz%wL6Wkf5*b+)r(xm)b&ngHe(oCh z)IEc2iI}a)6WE&W#BB$#H`+M9)3C%#;4WhuoRmW%xve+Rg-bB4&ETu|)!lD&ufGZi~?Ti8~Ob=s&ZF@e~3>!*ZOx(PyApRm-koq*i4 z*EmPt5k71IJZ97~PNfVhPEMtkT47u(I}+rxc%!p;l!d%}Y5ypVPaNKdQ*PmRFi$D= zLL4OnxRljo_XvJ{&zd83>KkTH$Sb0O1yF|Q>XEiLEpFHsDZzaXKcxEu2Z zQoXVosS(PJcMt_grmiP@P#A=w>3*K|Hro3Bk@a6uogOv9c-Bm!t-)FoFIp(QP4sP( zS6e&D$8Ozr&MQwxZRSaeduAlBw4Ws=8*i<{&$JB;ecH)6f(}3$W&{|ZYFHd$iYF}8 z#3UZtfG2yw@&DHzl6sd#qWvqEYX4(JE%kqLHvh-sqw|kUvGV!-N!i7hG$TAH8gQI| zCz?p12MYO<89ahA5EmL!O)HT?d;PMu3y(PJv3z6I>rn~O+e&w&RqKuzq{2OPRcCXf zYh`07w^hSi+xzVM-J6ZCYn_~&_H!tl%VDScxofVC|L^KhJn90yeM%bO)CNbx>pZD@ za&P6;qvF>-K2zRQ3-8*5Y|o`O*^o}ouH}4{0qZNjr^D?%uYrT3DTu?~Usu5WqT>$r z5M?ma?R}`vuYoLt9n#%kNC%Gg^*zjBF# zz%2zRqp_pPX>!`6XNu7c^&UaDYM4GN@Xv#7Fw@E_E7Q#Bw&=z&WZ$kV)-49)+^=W4 z(2%N-oGSB|0Qj|WM|%()pPT`r=~JY;@E#ul|KUA6V6U>m_ECvV@A{su*=Lc#7q-7% zs?h$i?ki``GrAJN&5CDU+Ul)eumjgi60iTHEW(F1jvyKI_3h%TPuXl9$BPT=XLs7o zL6@r_@zFLJU$4Z- zkmaR(0BI`26w-fWPx9w&yw@v>pWZ1I&~H(ePrOGF=R-X>kMpH{fC~OAbHI@61t+-A z__hhse`)U&_?4Pgd+acEOJKa`X?)qm>pv&E_V*d#E0Fl30A2`{*H5osXg?407Ve`E zUI>lS;QoH@70U#>kNrgxvd`|e?yuEAmF5Y`r*ZUb-@N|kSr!P!J*rr z10riv^wXE1sj$e`)}JW6*?pB9Po*J*cXk*r19pRN2~YSCC(Fh(ay3fLn;Ao9w6%mb zk*^SAhFb|`I5H|TZ1k-+kjVmfbw?W`8UWW;3r!_D)4w>u-u!g17iT2Sttf1 zoewvzR5a3xS*4*#yI*Z&7*qbscYE$I}2x%1#p%Q<=^y6%o?PVSnQk#NET& z(w;d(Mz)J`19b!9bESWLQKfC1h=KMR#@w8K0pG@$w$W&LG>D-9bLt1b?BIf<4b4(e zVs6xiRgXl_!fI5Q8Y#ZL{+7471zA!R?J8(%l%|< zRjJaFUDt)ROvm5g>L3HmWC{`*|FuAWrl9@!!@v^p9otsAi3}s|_o5!wCSg<$)6?ygIhsXS$g#bDex~d@!x~RQL*X?dA`k# zssO1q@jgeKdf0KjP(lcH#j4dQWfmRyI@{ zYlP$LjzTlXJIe%`YXavIQK@=uIgP|HoIk&`!XaHE2vSC*6svNToLQ?d*uA{HZrYRZ zUdCIE8of06Q2~f$m8b=nB*fT(PUz3(dek;@By4C(TzNr0Y%Sk|u;_@Pz23m4IzNVRhHm^vCtraTJXKC-}6Rv2!6Oa-V!j2qv;{rLl@@A&YC3 z0zt&kxzOlj5A;;0^v*R%Omc&YT+T^6fE!;yqt;i3P>hFCJ*fRn0{6m93MYafC|y9V zR)x-JF43O1YNl3a!~Hp;-l$v{WtsKKxX90hZl?_eF~+-xcKkV3ou2;TNrIujKuC`% zIUNl^TU0$i+zI)cQ}NxN3^z&Jq}p(zHB9S`tW#8;iQm|rD4H};@z-L`!iGRikDz=X zM~-k?`n)LHL z7SM0xNa#Lqo}-tqjQJeEYjp1+ICB)q4oUd%w4i5hkSuc7x&CrR zuBr12eVMh#p-MP26>2GRbZ?Y;0JKsJx>+j#bVfwgWkEMzx));U>SsTIE6h^MAXf^U z&vs}cSr~YcIkpV+8(M}Z1lYW0Vr8Xx23%_ga7@`Sr>Az4wc_I1G}-%c$<=7#(Qsgt&r+W~fGl2ly+an3p~`U@|H$`1XVsWfL_;f(%V6Y%Xje!CLQIiY zcn>ot`^vCXRD%nwhJG)>?krQ<2ZLcXzXTiPr&pUXAvTCXsG>&gd|yLZ-#xKp4~ z&v~rX1pLUfUK9fo(QkI%u%07t&ov*QOPR$5FmbGt#i^Dv&Sgs_vA3}1M#Zet5Y|es z?29V>Nb;PIs7Q&{gd*qdTF4M@%i5raLDnH=9MVZD8$TzVZxP5wrI^hz58W_ErMDZ= zu|-WO`=b+DF|(S`NeQn+#ikBF+=bzbccBTDWIrAwih}BDK-{ZZY8>gL4K(NPY=^SX zcpSXE+C1j0D<4y6VQ+-0(@yg(@^a38H2-;xLN|)_%xhG03Mbw~pZL}^>u2k`@TiA# zGQn&Zw)Ah$191?rg#&CrrY#SU9eOJmlI7~9_=c8gTShuthnHuUQ~zvem$t$?DeKne z*e@D)%C1$)*@tS_+t7`S>m|Y)+ujEVWYTi+ns2S&robbx*Zr7SA6ugB`Ji-aKJs{p9u^%uaDDIfO&b==x(64aSkmdL$$hgV`zE&K9 z-&;A)n+dy}_695X8kI)TtFJUmhyYSx&3$)9j4vX3Yf}pXjiQ^~rI$w*<44rC$JJCC zE07Q#8b*Qgwf1=*UR}cTw**hMWsjR8+~@Faq7l zolgItWizGevJ{M@!C#*}qKO?&_#0o=Obv{NV%!kazilt~3S=;}QB9~ic{?{=ybH4Z z%nacX9ZV-oD-gJ6`m?^(CCbcf>sU(rUh^O*;wL=bS$~tW4douW{8ux;-A^>a&{d|k zN-cAIa`x%U5+pNSjTv9Qa(5U`r9tPn^`H#Nju~yb6a`nv2wIqVvIS_V%!zh=>vyK$fQdtF*}64ysO;9+NGn`gY^ZaKk)mRF|a`LRrie;sff8B$nd zg8w=ZS0hdFqah@-muYGtnL~Y&^{T1Oa@+LXtF90z;z`x_ zFxk@X^+5lN4dRfvF1036hCb!vcU9b9A%aU%Eq%!)^3EJVX}P>Y(8Z(0ROq>` z^8l|MF+-&}rp2`7zr@>BxrU|h%YTu#>vECiga5oH^!WV_TPm5&fqdBpf*&e(+f(Fh zd1RKDAAjkaBpVvo~Z4K+f2<}-O@j@PY~C%#=z+ER`@Nd_3sI65jj)99H9f$;m4{g?6;I{Uhr;y-NG73=sC_CWG@J=Kf!#@%ae&V z7RE|Ssyo^ml+RFHq9U025S_l?niK8){(?AJXSoMa>{BeiXc4VG$gWi$QBx5+WjyD@ z#>t5o$gUPt+$LA;;-Pz9enIb@^VSug{7(GRr73%Xbn>D+8l7w3j(F13f|jQOWVy_c zLo!hT4eU-}n?FP`qLjd1)}L-{kX`muif?RrhoDN=zWuqIQk-yn6#EdR2u|U4d8IQ6 zT=}g0UN|d6eQ4Qj_(%J|A8jUfrI;TGsu2gxu_{V7R6BseXlo|>GCms6xu_vcMvzf( z-=svDqqIT5Gw6MjQkKZt!cQMhg^YpdI9!8bhlRERaIVjY-e6zcC!zSh-B1%rvHe|D zi~3N;vK!MANQ|5ZFmp(xpj9H1Qm|8xY)t&!V$wGji`NIVeoX&Yny;Q8^r=C7^?XEz zolWSMbTBU#r6nukCGXPVL>>2-!WHH?DFj9Lr2tqhugcbkBfPYlvUM57!s0`Am<=xa ztD7IMm8Y$#H%e7x1YqnQf;|PsdJ~L+qKc2G%}< z%b>KpT;*+0+#n|^@I{zFeVL^*R*!9f4!j6M(esj5Cumf6Vj&PiUw%y#VU6U$SE+&` z4h^ec)4%kmhGf~2Y^zQuK?{)2#CE)O#iJSyyRO8Lx`iI{`ky!@KedNF z(4f>1YzKt;kn2{TOcp2eqtN30+TH`LFE=*7slTm08gr#$9Vb17pkVT?--$LgQim?K++jJr^nD_Rpnri{Y|(UJ*Cm+iyakEPck+EtjrSs1Drj zcR(HPY<#Jv+Jo^M+2;gjI>w%u<0ZrKQ1j0)Hrc<3ODY*T5NLr0$R32B^!ACC4Yt=X z_xSlMPqNzi+1dve$~vX0CAxB_%_eE@h#^LOc*x7`#m&DV68xSEOwvvfX>S?)17-z9 z)z{iz`ZwL*G?FWjSue5Gxn9YI>n=;x!+okyU~IU_q9tfYJ?OZ55%jJKM6FD~uQVg; z;VT?5eQ|%iu>ldcMQryQV;^|522S^P+y`oq`eSbbH?PA5w&9{X;sGMC-3S|4JdC06 zl_2}-#R6P~pBis$TZ-hJYroD6yyT_TEb8c@e`RPX8z5PJM3ZeEC)8+d6G~ZC*hZg1 z=a7Nw?=iY@hzPb?X zBop$`q_n$`yBNhXJ7KL)hPd6?5~ph-LeACNCos#P6r4j*%i0GCC9}QpovxjRJH{}} zV3NM8RD@fNz9szIz-7OOGqLS`F8#O@b}1xmaWb{8K1p+Zfnh}2eQrcE%IkjDXliZo zrN(}%PHM~^FWc_>^>0tyE3ezffkkRJq!6N@rycJTWipUH28ZrLl4}-;H+u6@`701y ze@X4o2S%b$rX)$-=0vIu;;6R++I<8`|6+#ZVGl}e%##b3lpvS+_w#Gd7&Mh2Yu=Bm zHgOqMGjhC_vCi0ec1wRZg3X*qF>2|B3CDxJIcu2rBdYx4CipYk+>;d{9H{eYTs`&F z$&EaiOffwto%78(&(~B|1`*>uDHn10XXE}clD+uDQe6iu(f2eHPJse(-I3vhDly}p zp~WFLeP|%N$rt+srVRVZnxe>B5_iss9O(p@^pS3M?;=`9w%hir9m42PzMezdb4#3Z@tng}I9YMoSIaXI z7RaBs@Tw(Zv8N0fGx1l0FQw!4?}i9{M2Cr9suI71BEQ3W>7odsM3l{w&zdg$5yc$@ zO#js9;GAH5U8zM9W%?67KjVws+3|0Qip>+^On5FVl)TLzD$tzZsx$B!OrET5IYbGh z=^f{aUp~`yw$UIAyszb+VikyU!<|*dfL!9efL=Nx;oO2%$3v5*ce9jJI5>jsu=8uqoDitJ~2jJiwR+h37td}70CVpquQH;F+^SYLXioa3sB?Q z=|}m)t#!VL2zq0oZhkW!m){-H?F0GRkvMvf%Irm%a;E}&%c>Lm&=EOTIzz3j)1KMt z6nl8RIUHdmdaz;7>2A;&AxR2b1W|U(FEg^Z!j5u6JkUSlM`(Ii8yos_9^6UXzZ(m` zDChP{zeRw2?*d(L$~WyG&}7CvgMa(@c+6U@R_lN?HQnc#85av>2C#dqUHEIYeEivO z7vr2mO`$v&sNJ*Zu5O_&d3Tk#QsqlDUR?zcp`M1{|(nsZVt&PZiO(wfWp4PeMotdP0;Y zY3y^}i^aGq84IYjLoV#|m)8cK{N>ddyg=c@E$Bp8o|FgDI27x8pl#1!&1=4hdgXF0 zA$h>{^y{8e07}z%e%9S`dc_VsP#VI2@6HbK41&bbwm1Y&8Z@osGEK@><&>@4Ak|w` z`3i#C^Fn>B%!1JU@U7l9@)g4g4cAfbJ zB{d~_oH!Nfm{*sSt_6#yp;~I8-{z?}XCqpzF0af&akHZ$f+`=}5$x~Jv98limO1a3 zRrVBTE?;geOUcw=Zvv>i;iMdBJ8?_l_Fn0ziTESY-zgZj-H0m&D+~D!3EykRLw`W& z3z~Z$xX)3KUJ{zaOM3C<30708b{q{lRtDG7Ak<)#tQhbbeW;a6@rRO6WA%Y(UhkGo zlZq) z-AZX@cAea$l555$Mp{s#6E3Ko>)8WK*2}OL6xtI>Yfz!EgePtfk06b^r23|^GateI z15DoS#tzz^bVz!6Wq$7|EV^?my3Q^uNL zZqgcZxc4c?iRU<0N2K?q@tcRj!D<{S4F8tmfuR0M!!(>n0m22vCCaZgk&C>uLfs3W zwv9+9+1p+dr&0|)LPuw%hx%r_RNzFgsX=|2qOIJ45&h)NuB>z-VJQ62* zXngj;t;|4^mr$t%Rl8_aAIccOUqY&rsYeR2<()I*jdr~}hWKSXzC004%YSXS5WnjZ zzi+Y|c<<0O{}>hF8xY}}l(4;35uCaXp=ArjBu_s)U=F3%Cn+m+ZPAN?>`?!*(kmIo zu*#vJ^WKYVD@q|0TRZfGnqA%ZEThU>-FwyU=GuGZQ6f@1J^%hUn+yg0!vCU_gY)A@ zj?jOqYsLPzm5`)@`cG>M3rTZ;xwA3Q!TG=2pc1WrZO}2sxBrBNr5l^Do)i#*B5IH_ zs~%MusEq6^yqI8ws#K4ec1a#1@3yp#fP7`FUa6t$?Xh2@-e7wk8?+7BenDse8S0r@g-C!b`Yz7m}bjc|oIn=ULE8 zT*qYdqJrE~*n#>EX@|aES$7Gg63Cg&$aON|P1z}ocrCT! zG^uDWoiwJW#66muFl;ya-GSh0P&HK)Gz_Vfx_HN00ncSt`vP zH%ncJvDj4DteTdiTyR(f7x$-idDG#`YJ18Q)27SOq4$e}chYG|#CJAg^I8%kV{r4D z7jH1J`)v+rWko+Y;0&_O!g;G!Qva-)so6pCX zqY1IqCVJNH2j_D%btnw{v3_y_aa|^&GK0(R9kCO{pZQVIb8dX1U%9JZ;W99Jb4~{{6yME96VwfHk!k2amxTF=P_9_M|_EB?wwk+WYa}1jSQfa>oc+ z8A^4-HSvO~Rd%xyELZwqF7`QCrUu|_RVtyY@v0rqrlP@uJh{tArf(BPZf-ia4WL#~ zYWv$Dw(~tt?}O6QdAZ2E&5KrnK}S43N6H+vXWfaRw^xp6NMEx#DiuJ}O2Q}bv!Nqg zDt<-JWJ7yunwy}SBPF>K2>(Puv*$Jc3!7YBMh=_AxQm-6B%G~u=`V%R_KDKq`ATdS zYO9Mzy>QU>xpCJT5RBLR{!7p>$Y{^rifcZ^qIEPq%n0U+P@hIH`p9dvME!6N+^rcwx%WP%MR}Z*Y)H6)kM>wz3o`2BD^8 zypTl?E0%%=ZC*|jLs@c=n39=kQ*K>3s1#m-+$14Sr4Un6=OvFMAkf`;OEgq#QBR{G znf_-5kz~EU^fMJe4+}^6OGwx*Xxc1ah4L4Evr5BikgmEMJ)(8VdPvSpwz>3XHNB%` z!aclM7?%Zq;G~r8fWes}JVM4I_8(Xpo`~aAisJ`6ujy2rUqP9c5*vslH#b~OGdWkz zQft{w*)p&>`F1YOZcQD@;K^k7Xy%Nh{v_1x@U($CW@x zb-)44R7F!kg!8y|qSOL1r9}pfSm;in!@8&6vt8qo?vdv30V#a)Zz7%vjw*S|DV)BQ z^OzLZ+8zGf4Lt*w$~4R1;)>aYdz9;erBbC@Sxk*;JA>8bt(Jl=&&S4EbAd!*ia{nV zfTtHW~MjloY znrElsFUKex=P%MW?%H(MkNy5D{S{j@upyOVaaYEUI&J52wl*76ek+D83`+@I zsw;hNNLeSyxij;R5kt~6lmNpW+ia#elhdxn!#1x&PD?!n9)sW)gArwT=T$KC7VmsF z-YMRfC%);!g^9L(#(taZi8@iN&W@--3Xm6M;wsM*-vkfclle%i2{S=AtA@`5{}>9w7OqpDqsGfIB&cMdV-5 zZn{unRizx)JDJo|6E5|OQNL;U!{=;M>SZIk^ip}?BYwuL@;C^4ToE7g*;14)7=^>f zOjj!qR9Vj%HAFOm;v`TVJ^?KhMdmJAu})i9SpE<+ABv+85;p|;b0L6&8^zKTg>w)6 zH#dgnKF}w7%loJ=6??NR17waB%0MDIbB0bGJZE{e_D_S%$U;G8dBf5|l?(n)q}7DV zv3;#6C2LeErg71nSXWdJm5Yk5;euHb^*>4uV;!g#DmVE8e%YrXIr@P}4oQHZavC|L zV796!latPR!rx-wU@Z%sZ}m)im`~v?%-WKnk;@B#wg3txFG3{|5ZW^kbwWlYD3^a^ z69r;yQ{kBu`eHQ5ZSJVBxuOZG`Fb?#TWNMzo>=>`$b%1vgw3uCA0A8n(_oXM^uNW! z=Eq7sQc-`47-E#k}MFLdm(X2-iPj`}1(GM}aFq5erD z_-J8sFEZ2mz&lhYTFES<9f}4BmdSaBw{mQax!GUq{~+ViW3bqcy=#BIoA%eq}=!oHbw%p zxHAK$NywE4=Y@&?vC+JE7vf2JcSGq}+Y@eNnJ?RW6BKI3er3A`?xunn<7qlLiniF( zD@v~~Yh?y^CEmcd@F25zl*GkVT3O8w#KjB=t-w4%mol5vTF3rYzK}U_tDC$sI3^d4 z6w_8nIl2+#Z|%yQz>$voWp&nmx2?Wac3|ETGkoWBay`)9t|);b$iZsDFY5GdpjHd_ z{*TZR+(`vHN`hNCXBsvI%QK!unI!|3Gl4YgeSY??6d29z&4QFJ+kOJ3=SnlMI||<$ zW6NY&qc;%qK@8?Z(b@dqaIixrF%8o|JK4uj9o&?k{XS6KocjWD%;Z zXeacAZMaIu@I`I#5PsW(iJlzPQD3LV9DXE#b}1al;byru?J~1wOco;pE>bI$iq`lM zr7mke#F#8hbZXWkY)!rOfG{7%g^o{UpR5`}T z7LZpc7d`{_n$2x_J~{5Y${zioPXcqa(?=Y5q=z=*ljK5;%=(SwU?JHJL9#W;y&I<8 zPB3mm>~+Yoao@sH&9<=Os+6 z4dk+}{9_NiY1u99AVe-+A09%_cf`G;vgN!tGU|zIKepeOce>xzq^|{CYuGxkUH>Z> zlv|2smc#w{F@*b{f&tI}HWDl$R>Gke?%)arld{4dWxFPbz|3PUbh}0b?bk~pP;Y2DXw?jTcA1r^e z*XOO5UOb@$&#%?kK9~J)){0%(dnoCzv%pu61~?(-Lq;U};cdo`Bq*C(Q=0Fly_cW$ z{>m$V)7z#oU78{Ep~~{7+2NatWg#| zYyLWP3@P6Na&bT=@vaGye6cjB{L?&ow?ux$qHAVWY1g?C5`WNI`#JL0Vgcd(0(>B1 z5@vXpb!oJP^cOTz%KRlc?Fa%Oa|lk-JaIb3LQ;lRu`{*noEmH9x&O2JM|NF;Szs3J zw%T!ND1diEd<9VHq{=`C$6yj!I3kC!BJCWLl?q*30^nVhAL}^xz{=SRq^j7Fr-J3| zi%x}kMQEgsO$0YH&m`BrF2raw5<%iuq?+)m2C6nO*NG=;q$0seFH%m>Vuk9XJ1L`+ zw3N0MyD7{2sy}8o{<)tdLs_I%xUYM{YLg6}8NnEk0zwA0l@zfrZ!F{6MWnuEWu?91 zX^^68h73+c7cqQU5u@5fVM=PWVRD5G1|D!Aj2v@B)0qmKyz1g*ff*BydTP~kVCO_8 zr2Ajmy}ECigoG?AnFgGfL$^ZGZtA8&47Plk&*&Z0Ky$ogVZ9HDOz4KfEMN>k4>k+z zBeqI_?Q8fqA+u1;A2~S0vC_bS?jJ{iN|OIU`dfYedmUPbe16nAzXfFCT1V#$c`OBO!&*exoLg3v%8%V7qOKwuYn4m-%oMvJ6LDr@AB?%RJ#;E z3ee;bu&)BwDrknh2H<&nPd!ho-bx@e6JedUMDWN1PoR_-_is#uFdcDTuNR$`%VObR zcGtE$JK9f%z@10TT@<~Ac@uvZKFyn7L4>Km^3pB31{!>uhPQKD(ft(u^b~o$lX!6Y z-vlvgVS@}`7T|i5>NSBJ9LoO90*zR9Cq6S4Ed=&K4ALh`tCQqSAHo*dtf_25p9@OA zv#s`uJ46;D(3`}W)#yEIWvwjaO_b9Ve;)DSON{SM`AiM&D|v_zquw#4eU0ZdU5ZRq zO|Ei+qc4g3gUV?^4JMN?bWWEJW$Ww}Z=|+{ew{_-X7eC$kTsDONT(=8RLr%)RM^C~ zwn%!?fPGx^;hhoWmwzXUBy5qI+<=h|aP(t~87 z+1VT{e6S!0bH6}UBGxImSn&)NlUyWFc*&^#uICKntK8J4!yg#WCT4Osk+Tdr!JfV% zO%?XK6gOv@pS3N3U%ND_GSqlZ{Mcb_S=%z8(A82mKR918|8P)mkC6 zvWG^Gj>90*H#Hv#RZo+G(%qQe$+aLM-=H%sbfE?Ai$u+D;Vvc3Tt^gSqv-N2=`}v3 zvJs*GxyKDL=3J`M))Zx+KtQNIO)YTD3X$R~n^prcw#8?X?QB+u#w&qpdaM@6{KY-Q zU~db$;43B39ZQtR=g6MXj1C`|>xfI4=X;B z&cUT)5la?HIBrMYLYcgDV2E=j;FfV-Toq1k{W-MkM}c}psXeSExJ9}+ef%V+0dMu8 z_86w5JEj*`G@WW48))@=7Z(N2Y(@-67p&Y^Vzm2kMI znS1`l)Wygs_pHH{z2a^ZF2Y*qN^~C~TC3c%1--OEEn~HynP<>dFZMsnI>tJLQ4Me&FYCetV~Vr$RIO&RCG*dbNd! zm!og2;qMEI)tRszoj<>vWNZG_r?#r)bD3gMeGM%0R+>|<3P=cWANKra23y>ckUC)d zMq<0lkcpK%fhWRhoG+Ik#d7-*_RWf$;g9$sdXKi;=$sUpc-7A9X@8zT0w!@8zT(VJ zetMD@Y-w2P@y^pM_+M?EeG_yT@&ah00YLG~2no$V-=Yac3}6em*)eyn4XZw_WSJkG z5|J6uW^BIO^zsaB*yPF!)w_7E$2%u}dI1E{KP!v|zQO2M zFDag*#zno!^eUt+nlpClmE|p9@G_2J@aj*P8i5z_zBy&Y8B1%JG)31gp4;I3!4C`B51*S&VE}eUIij?77 z1iJ;BuAO2Q-c&WG1k2z&{m#l|3hoQryxU^Woo9kM*JW(nVOOCdWeCj%Wl&Z{3P_8T zSOUdMLl4mL4drft1rlD@1q&?Ki{?bp9N}OTBE3{FS3;(mPgwz>axrkTklEOb+)UBNmvvgmeB9rr@xs zJDA-T`ZwEG(##%`@TAb)^$p<-m>pfh+e0;P7r29E6(>vttwuTT0KrRGcK*N@s9*$r zarZMvuy~hDZo4WnVs~=*szv_+D(6dzsKY8vq3aHa^(kEzedfgmU@o=AyRJsyslY)c+UmPw_s`a?1u48 zrOe+5hD{`~j{H?8(fj9pAIiRhtrgt?2X!MCkoQw{Ql!k`+>qCIY$HOFRkmK@gcVWO%j+Slk;kk^U^qFKq%`woNNCmUeP5&Dvp?xe zQL}CB-&g0$zTpZQ&cA1-P&h`U^fv`V=y3z%|A2mV0W@nEF{Xcy2n%a)nBMl&%^IW1 zG|ZVz=;{z11~xl6CGe_jUrj1UX;e7^$&mH&>M)4WpPgU6`002r2LN%_-o7D0f&yMR zxqdZp@6D-)9X;$s-E}$JC@sEMMJz=VfgZ}qWKQ~Y$?3*h`E&gq=rvMnlzZo$8uSxC zpTalD`O)?hdJs)+INsm2^|R!NCi+!@_Lbo7;qW6FnSmV#GvNAJ|Hua$z$+ttzK|m5 zDwp@B`Aqb(xio4|xTp@=q6%0;saDN@eib`iqK zi8%S|NE^-a3*EmUVw8sjdoaOCt`ob{!IsC*{vafq+XCz3y=55CkFOGQc!o4fQNvq$D8kJq@J7tV1JzBQznN?O7DRTr$ z)KgsOCS`3)a@g>#U}{opJpEn+*w%iJG@cneZ=&W}3(wHmE8Xnt5`22i$5*zW3hWF)vf z9^Z-QNP8+Gr#Ycs?pPZaG)1(+q(aCjp)@pGulnbpbRC*BUpe`t6SG(!7jWqfw_u7^ ztm=0W+vi2hKtCOWm-G5wlY0kVlwM&h;&GGP>jP?qRaD<6sN9pqaX(Dv#^7Z{e{zQO z;fGFWuL=7eIhmaZCpT)U?GyX|omtC@M3^b~y@^lezjrR()gz91|1s?Y{)e%ylBue; zwo-!I$`EO_IQ*DwS!`i%!g)8Ju;HIl=XpbZhm;yeBI5FIXtrp(W?-D>{y<*~-a?cr~M4T98W2P?* zy2!j1BexXJa%gxn6Ja5Xh2m6i6Z;eQZ9UN?U9!A8J3G|Jbk@UoloB`QrfWKgPODdt zk=H1$rv|R87Y@GY)50ZF%((6Aa*} zLHY=z2;39CHG-pgN19`MqBf5ZwN0{7Az=>|MhZ1gk5$EN`XBBG_;2e_&) z8dkDq>dKtHn({!DK3`pRcjxFN1*@`a$ts;oB;{3Euti4Gz??;cwx2UA^%^^J*4BX3 zWlbv~-1Q7ws#tjYRFr>ot*)_qsDH-%>6Li5IyT%)jko1vrDC9`w=WyOA))e}e|^<- zKkM-~Q)7ai7B#+Bt{>C-OE6&uawYO#ET}>Wu7VdQB_8W-Ml9>|#V>Cb@4)KEs5;KIspZjJ z>9N+FcYewk>DEt~@vUWeTj&=0!}5ZgP12ShV6-!PZUQ(0WiA91zpzunkq%-QpMC)H zm0i@d+3PuV?AALw?#YNd*c}=J#GvwDe+RZAfWZ?zM--kOV-8Lek-s}3z24JPvNg~h z?pTjBy_F9L$l&7tb;0H7#zU5ui@i!S2D5lC!uJ8oaER-`=7eZ@Iv;Niyt{FcU_`_O zwXMp0azxby5J0^T1+KO?L0pVk_xxPgh{8e;K{faPWpa_}%KY|*#0f8SDX_oeN7!sh z$JX3yGo{5UIV*RXte(7*xgY*R@2DbEUsbnf9KNoF=XeD={`+iyFaPm!3BE~2HNFODR&j3{qEYasU%5kLsOX@L)cVcJoCb<5CCxdKx;|gM7k) zEGNExLMOx`vJZ{KB&L+4R=6~%CrWMrykX@&vq~57Qkn&My0BNl>mz2yE<9NaUSp}H zMaNp8U@ly2^GrfcN=Mv;+zvR;cEW|MgkkEhUa-+vrty2JlufDY5b&dd7=9 z^RujhTXWYzWr>a4%+hCe0!n$LWDN=DYF0q;r;qmHrn%W2{UbxY(4Z^x0Htj^>C}7+ zgX51tCO$eR0&c#(?;R=D#%qu^{&6&dZ4lESQ>6piun}}fAsrvx81ydWYL$McJGl1HR zvdmQsC9M=V0B+b>UtPY&Ju)2yTD#X6DbcwyW$RIbl{OhA$ND$P(>T4Hrn@miqO_xt zS(Mn;yeZvOdz*QMuLiEvePAHx+iz|BmJn6b#0)r8ki)!?)&XPTfyBnzwRa0hpAcw* zXUtqdkkpb-^yPtNb#5IAiT~v#8Z0ngD^7C7Z?mUj=@wA&4! zj&~K9v@v0XBA@r^Os@scdvj}WGmyqxZj0_bwymU72#0_tg2Qp-KkA3Ev;A;HrVloO zuHWDkfdDT+)EJDMpH_lv7KNS-O>8#QV8N7%@m`70ytPOBl{k52g@?wTIrS zUDi~?8;tQHC-=|KfHFH^!cBBKB;Jnf7u4billvph1WYfC!4aZ1knT>c9d<6j_O^_k zUMTqDPNyB_CM>G~4lqKs$GHX5c4+BH<%g7W6woCV?oCZ_T@t(}mmR6gGG(~W z_9bh2eHk=|BV$SE`@@j=$XuZZ#^01W`1O(XgP=D=?qpHo1gx#7gbQ#@c+qP}n=2y0D zblJ9T+qP}n*7TWwZq7u^iI|9t+_~@a;<ASlVxEF}aeV9lW= z0ptP#=CB;diPKDWl;ogH?(iUhJL)ayaT9Wc^Had2!6+!%JpAO*8<{{Xu2>)ej;1*b zypav@fsgbrE|AR}noT?IUMFzs2y%3M|EopOjXU-vA$Jvy%ruj(D?7wn{%kr*@)!ce zS;!D(u&6cQ4xNGfF)`HflRh zb~W$mm3%nxhmUZmJ8WxGJwpOx8+Jetde45JNj<906+Ot!?G1xVnEx ze*mw)90j7cRAgM1-e05TEIWU5wRbjU@Acdk;r;m)%ttmim zbu@E_{E5{u+E4;i8tiv*omEi-(rAz&tG&`%>y)t(Yf4FjUr9Y==l~)su1|6Wkd!hE zR;CI&BBy$^>;Quu>M@n*l#%G9aTvmyQ!lxCc<6z&?vJ6#6>{cKqy`Yu9VE4a!lOH@ z&`bk{NA}pPu2p7KQ8Km86rdh?p>ov-nC>}!To6U1@@O}2R%=`yLP%sg0fywSzRwJR zNM97O&KwWFIdf<$O2jHHLL->8A2RdTfgL0AUScatj!6Rh6ye+y4fnV&u~7FtOxKFn zbnagsKfuW$P@UM|%jmeRRFtID-Z40J zPksR7rZo^nYr-^_@v($Bug@YS2zPT}L4bueAfP_7?g49gftVUP(r3t>&GPumY}iA6 z%3$m4G!(`TLwhpsj1#sOrxoOS2;ZtdsWwSS#lRX%>kde|-~AFs8yh=j#Nk=p#vo_v zy2Ltc-9kbclY3B#7?%X=TCF~*ckfxI(|BK@*a2U=FE*jel9p~y&+Smg%7_whs2iag z3`4WFI%yOZmkF@7T(aOujo<_5qNKxi1@#dEnkxhSi!<(g9ttr(vohq8&~L$hjn2N1N=;Nz+r5rV~UJS+pDSgM1`~S*&*% zRi>xHTI{2&zU;PvPT-fM*oF#ze@>PZ?>p85jj`&4{c|l^#~7T_I7V+1US87lGlVgd zP|YP$uW434kwC>0!${=6>l&ox>7EXXzd4y#jzB$TW90x4?20~vim|HW@nvg^NB>YP z|H4_epGHTQca9Md)$`>;LsTnJy4l1cb z%$k;TB4y)<(AinDQk*eZV@HD@deCRhp1Hmubn)i%7wtqRbc4DvqXnqBVrY+kv`O7T zZ*S;~f%u|q2CEGOy1{Yxdv;c}MkgI{y5ZKG;EciD@^0k+zB74+whg|yV|CiU>bz(L zb-a_s_P^jD?THAi=-}{Z4aM2&vZ7?$74!m1*%!4Mgs1~!+oSYCmpk$<7(MsKZiz9p zu++fBp^rA#8;n&tq$cfgvys+lODU>EkD{Pz)*NsDJJ8`Sse#2HS5}o^npVBIJmmO9 z-sJoc$x_rDW=HTTl?MJ>8~R88-~o*lTZ@Ce(n$Q|&n+UW@J@ZjTej=4R4a8+iV5|Q z5sip%@|k`KcoBn$D|wO~COiN+DW5BGIwQQ=N!Q7%nG^ov4~aq1iIa^Uz&A0;n~Lhg zsPZzVq2BfY%o_xLgv?zar``xz)SAk(tm?AJicbbWr(#h~uM-_Mr8J~eIi_)L1Lot}FN`GFh9ru%MyO*P(Fo}f_wO409A;;8zZ~{%zB#Ei zZAb(6N+vPjsu_l79pW+|=7k7;<=&`6TP^m3d3Gm-eCs}N`Ue1T;_Uh2E5K65=Y_}YXLCgLe#*rnY*chDK}j)B7@s>P;%<_wBn z`ig*i*?`*NM&shB{J?M->T3f06(rOsryBOzFF zpbf`lC@QE6BE1*1%JmV4+{W*aeg56b{qQza-9!SEj-;2~p;z6ZkJv$of}{^*eh*#J z|4)%X;{2W{<1Q;E_*Nqyx9Gs0Hzrhvd81~Oqm1l&#hv|SW*7kn8X?#ixQ3E^p!@V7 z53dTUHa>@tWBIyhh<3TO?CR#fTOJ|`vE{jfJZ-2$zGX*knEh$jvO7oUKezzi@ghs3 z5!7j}Ue-j)P=FvKyu;&gp30gW577*pSP9rzULiAc$WklTTy4GBOwE8Vd(g=u(wT%+ zYkhdW%8hXWHDm7p=9x}0fGOiyR3*WGV{e` zSYaD|Gy&ZG;+q7s@S}0{8HH9jaw!9y7d3$sg;wyUTaqwJ9?EA*MOKL8o25=QSl1{` zjv4h=*F`RJ>Erq6XUrO9izFOW?l_wUr`sRk1+FEKMGGzcUse=suZpwc3dFgBGuubN zM8OMD-leBOiW-6?v|$vMw0Df-UtmIKg&GNbL$~Lg&oc-@@U<$o}K)4oB)5VIwGV2TwG0b4?AX zLu#XjB2vcTvq*=2g%L=_qSycL(Hcr34yzF`*p!UVU<`%0q8Ts<_|Kz|WbCTEoP2oZ zrc|No8llQ~Rq(V2i6WtR^;I!G4*4v-?&Wvo$e3pw#AN(-5n%`u4TCm>l7=X*)0Kp1 zGW$_uQ%YqgbztHseyIJ5%ypNOb9qh0&YzUgKLM|KdHB^xnZbc5XZD-7d){o+=Z+TQ zQ`CMm^Z|nO{;GZ2;k{nrf;>$FM^22|VkNznPT-v)riO%B5fo0ixYB5QcTR1H^-@zL z4I&lWs8t?Xjpx>L{MYDMOg%)nRri{KerBC= zo4`P579OkfE{k(-ICa;+_s18tILY5UPj%1C`< z6w!Xi4s60&jX-hF({D#rnTUe~v9vBDbGSkvO%+<`kxI+O4_xEyPD-}V*rAOkHAmlv z;DdRWok}6SajC-N<0ctbyr7*s31v}BCrddZWRDzvb8fZwJdb}p9fYj3_e|3>!qzzZ zX4!1%nNp69Zkn)zV{#9PhrwN=o84M_;&4x3b6aMtlC{Lu>gd{C#)5ua%~~aM9H|I^ z5S>PFsAQ{2Cv$mY2pc?WrZW9{KoSiJ=2#eIW~83fg>h^Sh`hAUQXl+FpQEr(K2U}W zLtIKOROZ-THBkKng2F+H!m;sdDXV`^3%uQ6lK*-Ot-%A4VJ)Q%C0je+&NigPOM~*H z-eHaMq}GAszPfLe)j?htiMpJL5d{UwOT!^86`(_E;ut|4F)1A}sSSqFwlSNMebff8 z7||@G8255U>o%OyjgqaCUnx}{r`N6_C{}ZGM!v!aa#%^OPxl|3(tRHZkD&A#*E8#?B^C8+($_ zhT(HGfmlUfKgoq(%=ZmXJ~CQ&?N@&UFAmsP5z1%fDMMP8w0ZIn$J0|b`^Uai%mWlL z>m;-4=AkK~s!wW}tRY}i=5!lxJBi&KqO@V;(#5Sc$;jr5v2>r0#`)W@htrGzBr-Ey zFpBjKHxC#Na+X#Pa7ZZLMY2v|3(85w5*{z~@K+`R9N2KYPf_)I?3n3GY|s@;FW~CG zv08PzYwUbLFO_%Hc3IvGS&t2PUl(0@Paf)&y-yB6p1Ocnh+fq6%zJ=c%WtS&)8Bo> zRIsVv7hP#G+BhwgcAA{(y$ph$^M|h*)f(9jExYL4L(4!t;=YEYI?>$IULta9b_iM*jVPMKE60CWy(RG;1{-G{x;RIkz9!^-dA4QE=D z3x9skLq448v1fM=2%YVyj{_cBt$2N7=9smMN%Rwrds(N#OwDMy#U6H-G!eIRNe(<{ zKyQ{9?E{kou$q)Ni;E6qX+7g6boXvLG+DnDCi;9WzyyRA z%!o=Qv4on|)yo$|=Mk-uSshmOSKy0Wnen~^G6ZtWLg)Az2hOytlTFM>*3qq-RdbX6^}8@$*8Cl+nU^ z?CgvBjYO-g_Kfk0lUY)|&r}EX(o(wxgqOD3Xuj-h741?0c4VQ24<>iqN|Zvh49zXl zRp<^RwqNE(?{;Q@9bK|_CcVUUi<0ecDp+j7&z2p`L?DF)`chu8X=M$sonP(XIGD6? zW7XZbv*v}tMY3BDevvhmLfI@KA3InFzcd~0h5p_j>D8*bkJA!Bye**|`!+4Q(B0dB zA!%sg6LHepf_-#sakJNUe(BD4h2tEM1p;AaTW}Zh+GM?#ljdCi`nD`|FDRtsPP_5t{Pc5<1HG)bZG)fulM& z5eIq}kXZd##)v$J@_>RJ$fT(t9r8mU+85n_QM7TF&Q3d&KtLxJ{}V;~@83HhTL)7* zCu;*IfTOL66P=@r4V{s#1Axxl#tGnHV_-$+YD6atFfnkpa{4FB{0~JdVDw+A%>S^o zS&A~Y3;ch)Gm0h7+utnS#FZ4GvDa}epkzzID2Qdl&Igllz@Ct;Ct0_~n@CKRe9-pg zp@@Be_@EgqsdLx~q;9&>va;MSw)A>>ety{nsDZ;aPOLJ?^LqyFriDa@c*D)GV4Jxq z3`>QqmtN>hdR)8h!g?Zg%-Ed|j`b_LYKH;5sw$7Xjlt{*sWB+xgt;5Lf2rzeKd6*` zp1Bdn2aC7+$J;xN*RFk>ws-S<%syF%h@!eb7hU`&t9BidpK{32zAgYacjQe zRI<)ZLy5Gy*}R?s7YgM}nl>h0@(gJjD4-CkL-R#F+>VPwuem-ZOuKa#Pb)@(;Lf}k zK4+IgU5e6XRGto?zc75gql6mdKRR`ZN}LCe&J)NgIX9&4k-^w4{85r zF$rnUHVo$0RKNaI{RIu-!~wo#0!7o6qAX=A*OqQibKo%?l?d|~r$c`!{}_^rP=m+k z=Pi?hhj5+(>?A+Pi<`jsgSscNo*z)+4w|M4a^sV0_vF`POMYy@qgJGy@FoKVi)He-p+C{a;E|&i~(($l3i@ zJ{#7$)vP0{bM||+h?R?H}P*aYg<$W zJoDN#3zpiS2xz{GGA(x_#y(XMeAoMOqn~=(URe<}u6JZQUPAC&18n0V8QPx|XgimO zTAR$l9hqJg5w?y>48EG_GvbaN5quZLir*{P-`G0@Qzu!UU}rt2g*%+?H5s3qBwWv9 zr&6@tO79)NI=c@hY`QaEU_Lz$7lF}ss337Bk85t#07823J0p4%dmnH9*t~;!DaTm# z&$*HC6UU+2pS2Nq_ICxey!*u&tvh3&Hkt%zJ5ypu&qniJO4Yoy1-4Lrz6o8YKgfA7Y_X1(w0`tYv;Got5aA12Fd zTqfgff!1eih|lif_ZuK?jLP9&%%(limwF+m^-aY`Mzn_O4UWzERt|8FNBf-?;d{N$ zw)F|~T@>L<^4fW{ugCRfP4+V^)8U?y;d1B8`G&)$L-TmGztjHe%J|mB>?;1?ZvMS{ z%y;k0@g_(6-GKjt#^_rnrwlq3I>1?m#sB^NJS2G; z#S(L++T?!G_V*R6il|VQ7F7n~R@`(IOqzqGVb+~+DN`LS@)Z7)pV;&Omwl@nK_bU3atdsp9oG|JQkM`eIl>lZ^jz`mp{Vt@Mikf70Skl&7eP z@(ZmCRc7YuxL^kVkaNJ3ziL~x%1)@G%+%{@`COR>QfX3=ihuG`l%)krCR`L8u%9ID z65F!!icudKof|<3ARV5o*Jr<_c3hVAFWpP=Bzo`CH zJ3kG*wYsjJ+QMdgCp;t=ttC7&^AZc|?z6o!+>}4d63dkHMG$@$%*2}j{=)iZJ?CuU zKfw)aZKsE|_XEDS2F-kVi0E$IXR2^3ejB}b;@q4TnjR8-(+FolmvkpE_W5aWZnJRn zvS|B&b(lKa@`JRysA19s(cG<|_w**QV{!0P-E~z`ShPGLc8s-z^02FmYV%P0KvLYa zaBBw>a@FRND%9T6AZNSboj4)48+z|Omq*~wKj7vXRA)(i<0`Hxj zg}^YIppk|5Ee~Sl#KedRm`7N~XJI~M7pz7G2g3HatVl48b!Tdy>M+%vF5C4FdO2H|8c3KAcRdSRiJ`l3IK@OEP3iE2i7&1%QR@+UHX^i6 zSwF?GH@1^oTgp&l2KNIk1Q(;iishCP4}9gL9n7ffE;j%ox~Gbopd)e{d9dNg`h{|# zRniO?X(!KMZ!kN%@fWvwFYRQh*Lhn7Qe8sklM;*L&|#f58sT6pJ}!cZan26e?+!@%7)^AyHO4Hv=Ub(4}czU4B;IX@47hBtK> zqUU4DJTk4FnFAal!s;}Mac&HBAbhUt-)Msxt>*_O5FvmR)b^1)fLrT>NqoZ%XG+?= z4~S$1ykhWA^JO4mKntm7Z7?7Q4dCY)2S!2T?$fNK*F{;;-9&+Hh`8t9;+!9s=J_*0H(kPwy6 zfR!@lTY!{BoM(-CE;9>#8noUD3!bA1>l)nnB&e5Q=`WkBY^J-hxv+*29q=xT!;!We zGfJV|?jrNmkANUGWJTUVt!c#q3_4etZG-;YW(rKFy4`@mC_A`rsGxK{9W=~Hn_eS! zOQ=Qio)y>duU8)}s|j{YP1$fpzK0aS8}uH}Ya(PrhEzPek>)s^{izgpX-V?DUaY-L zvuxnb?q%A}Q_*v97_NkHsI{Jgasfb7a)v% zqVok)psB2&uWq4U*Mk_^AWCmahvCF4hJ{DV;m`-_wt7c>2QUTiO`aYBf2@xt)5J>! z3xD1351?jVF<$hNyH=R@jwyTHjoMf#kF{cHsJFC%h|ycfoBxS)v*kv(7Vk$l!e}Nh zF&`Pd5pyxasOmN@w3X?~3Y)!l;%Idd$-lCm#i0pcS2U<3F_iHB0#f5t4sFN-PIUx)W%bfJ$QehO3NKj=_r#&({U=%*LD_ywn5W%=z#rK&tV*}Rw z(2iKoS3TOb34d~G36^0%%ZfWugX9kEmMST9-_AX7n$1m^_mWCCJ;h%Lii59iNAH1uW~gX0QqfQ7aZCBaf(M!bek$iR9Cmi#Jd(4S+^B4s zPVGJVbA1a&V09ULXEg*w`xRa{3Vy*Ty1T+*MqK6(a9t&t5QM_I#* zOb~Ih3^sFghpX4s5SC}i-!bnr?nCQ|{3~{@TT^}I)r|b1Dt-&6vdGXZDvyl>$cvSC zbO?2s_*~*JB!FWKt?j~|U|LXjS(VynP6>xlDvQWEN9PS!5DK|3{fcGOMuKHgkO_!n zGMx%ZpIi$`&z}w!qhwWPFnL7tSSg!kT2y9%ODR7KNzV)KeHWOO8gB!zY1ZokE=*G`C5= z$>d7tj-bq1+T>G{Pm{<3$!&V%Piwd{_!u?7fNJxR*LS(Spy;xc0 z)AA{$DzYlSb@Ed3F!9QJSrecQTxZKLVVB5}*X>Fp&+-*Qy!|+c%0@Q~Le7^p(c2&FQ*uHMDM&Q!vU!tmzj;ojJn0q=CE3T8td2G0_&; zFwUWu!vC%%!Ol?RB}sK_M<*CM4_#}^r%*|u>`gbTb3M+L+1dUr0Rce8qTCt38<$RX zYHus~*}4k`Xtt$ApaG(TM~UWnirdInn+TxBkQ3mRXeW=&L!cu9>rK3aRs%Oik=I(~;n+1kyXr3&_}Ke7q9gfefyp&VHk$onA#*7BbLS)p)63h99TRJN<|Gd9>j(Niu{v^Q+a+wYxj`W}aw z|An#K?8NbyWHwT^#gzu&D2p)#1Ip%`gZBk;m#n(-@FBLd%$jjk z`_-O;^6w06QAqKetpC-21jdm6b;)~nu}6nQdykXZjzna@(fQX<;4UozGErMhg5lrK zF0T|y!toeWu8r*#ATc%3i z@Z@fuE1eO?vG$bu<;w+^UF2!Sx z*mRpD>Cw3m%~DNT+A=B;;!JhL2jF>^bG7(knq!wzZB;cn!&DuOmKek#E9G2!DgSWE z^K(W_Jp+kjXIJg>+t>HM^6__7a@*j!%gd;tZ}Y)!Nq5D_X(y4pR7x>Of7UV|FA8(5 z0tkqjgP9fy1s>!{NBf97VX8*{`tIKu-$Nw7Nplo8ol^S#1tFbqaGcn!JfuEORGmH< zT=<=>6mOp5gM?k_GT-R=Pno-DGEXZZ)CR7_wIQ@cI_~`L8enbk1(dUQn$}Xd6B`7G zV}SI4#3<7d6g7|lkG+`Ok<5%EU_ePR_9Cq7zDPKG>!9^ky072X(NX+7{$uHa-WJ?Mn?2JlSePZOZ!u-LJ z{zfW;uJ^OM@y%nhCz-Ve_TgjUc!J&+-&)u2EwAy7c(Ny(m9GC2%lzRkl`oa`w~-IK z^>*}|kog1VB%W-BUd$Vj`Ge*po=k=(17AGrO@Ak!HEypLzI8X!LxK6jSSp@WM$FJ> zhWUeiD&9!utgqCI=g`i%i= zOg%lJ!}}^L|7Yy>>y6pgX&7s4AnQB~I>s@pM_hM|E`Me{zgM^wkRbC48~^wVJphLQ zi}M4);Wav;Vdwxe_mb%FIVr2~vLJCmtht`Z_>~kVZ?o^C7>IR_wAZ2-TT=>GQ|x3O zg})`~cs2<$)bIfp1_Gn&7iul;7m&09`cJHG^KJXDj$rWLx8o0op3v{+(%u@&3isHU zq5!N?%M~`{G_p!8SoxoDRPcqE(-G9oDC3omVv;@CO)1)$Ro;5f;Wyl(P4B}-|KUm> zO6=)r-E>LMdD`@3LICF1uV1;Pai)O?kmQ(gep-I#Ri*^HO$borm^{D`{JmX7e{S1J z{m!BgAlXNlbdmHY`1$$daoAyi`EcSGwh=HKGY{eJ0{6a0AR~dh3rr^|=#PsK&>xs0 z82IoMK(^=f9vNvp06`Jki)eray3>?p5m)^f9PhLnbQyhU6Pml6Tt~7GJT89SpF@~( zD_yNMh5jp-jl7Hc)|i*Kanvxe8_Ia^2Yw(-9B&FX+j} zy>mm42%oB{#>nmB9kaplQ$Ci8Eat53yd4XsFPyJ!!Mjj)GV*54&eXzS_jv5=v8NGp z$qAq=EN#Y}^qj85B07pA+yb4va7v$dW@Y2LvQ7c(|0mF3%T($Ue5+$M5vP zwAY)MN4@mH3QmE7i`gcfwfGj6MI~lBar($^mad7Lm=vn~QjTb6VSll0?VE=sp6YrUat;}fA1yr-bH$FPXrz{H~530B-N z+LR=0AEN^R=CCh)evTx2u&JTWa8spNx?C1+GLci|*H~X5Yc7;|Sea6pSs8@&!ZpA2 zz;kNA%RkJR%}EgQD+f7GZ$MjC^*70)Z{jihY-h-Qy%DqC9B(=)5yADP@l?uR@Ixln0_FdUxnAZ|&qgLEXB&eK3r(J_~@p*rbSv{1XseEa6(TG$`{!7E+ zF6D?mMDV5}6;|tAG%6m1Gp&U}P`5teF-s!_`%JCzMb~$A4e(O55&;@4=p{ZxS%oQYmZm2YGNEb*lhvFT#{4Pg7-#OS# z9xO9Kmep$6NwyQLOc7?#&rQih|A2R}Zy=s~Q9&^?S50uU*!2wzdB~)zMG_{4}TnctsvTQh<6Nk;L)UgZa)3w8R9Z&R}&=JI1urx7L-_)PL_q=_DCY@C(~ zI(#6$mb!4k-G@e$&N1Zqz+F?I&G_e8E3aleiG{C&UW-@H!7rk7y8qHglVwNelvdr1 z?MO?{>gwYxtKVuP>6n)?!MmBNu0em#C;ieHh5EAO{b>c@c-{+~%EV(3Fm~4ty;a|L z!B}9T63tekZ_fvIf)zZRg{bey%@nO5ggOru?&(+$9pz(@7}XXW!Zy<1dz3aO_O_iV zC{(RWlk>o@VZ$h^=KjE)^1P7V#XNw`a#a+z&CTH*%e~E=!C?b&TF%|Wwvu70d*%#) zGMxHqY#v`?`%5!==J})Med9aEXQr7WC{Fkd&Hb%b7W?sM@VbD)i%;eR0zW~hF}_Fk z;uY)f`tNyKUg?#*(T*g%;;&Cg?}V7ygiX1fJ>YjhZt>iJ>i?DPs}4pDGu67ui7x{h?$5T4zKcS)mS#(wxAh1g&H|T0B`u& z_r~V#2e)!CD*ue3Eol+2#s>rI%L{`rqk!5$Zl12mOn5^s0Yb_jjJO{ETgZ_e2G@}j2xMJZyv6=5csI z-hpy}mTG{1i=Gd`KgS>VJAW#Zgro|TN~t2JUQ$sxp>~>}3qj_97k;7?N+-XR6Qi3W z0W2Mi!^^D*r<_6cey}QGD}*BjJswNb_<{|J&vYn7#kMAlmPZVW=buT(*Cst0q4dt8 zzLONPVzIF;MS!QG$0CnbS98fOJwlk3ocmRb(UOTO)KjTr3riyCqCzSh;A{dfhn8006iVbF~Tk^({qK{w~l)hzm8NFHB_V zugAD#$`7daCCe8tPDwPP-rtoIFI%I9_HtYrwbwiS}F9AoAc4u$ldWmit{iLVr1Og+E> zWk+P!^MJ~lN9>ndTj~`RURBU)bWe2=K@>9+BXY%7`~!s)Eb=`8$xscfn$ ztj#;+eT7YW3F55_k8+8NV2sC^ViN?ZGmCSnrCG{5#z&)+w?r7KNsPyAZ=#2?>Tj4>2usf&WZXnFXW z!Ssmh;dEmr+4ihs`>bh$<2>;XBs~ylG=dwAqKGD?(zy$c(ywnV3LT#$tVY_Hf|S-c zwS>>)gAT7Um!e5aQR=p8zJ^0ZS7Yk7bVZVtB2|SwnSSz*T}8pGqB{#c&Bv!=Lcf#@ zmUYQ*mwAvM5(hJ(D$qr_?82hc$O5MU`*s9OPo)THo*c~F42aX@_rraKc9u5ON1T!k z%}@DDIlMeM=tu*OnD&Uw^NGZg>tb^YJ{tKK`Kop{l+uzp_s(oOP)3;8h-Q6a@)Zs8 zjw89VO8rJSJz?k)FID5kCUNiOeF6+U2imGqSil4uafb5yk1U)<%@`p{EXy|e7 zoFs)cV;v%Lbxodt?aPA4n$W<}*EHDxBRc*c>1mn*5IgvLm6tf7t>4!?KzX?N6z3O> zdOYIZ=k!}OxW%E1M34V+9$is#wz2A{$Rk8Yu3q9ndz4Z#+r=3;12PF*^{_93()jN1 zpp(gVCQK2NeM}X*#MHVyu2!rF6zT)xF@4xx>oF(%v87Bu7mR6b=>OoS8-iP{dD##K zM2Zr0o!2h`=6PN8ImS4htzCPPdzo&wBj-MH7LA%?It=9fT{}ZNq<^u686YGno-sp_ z)itXs@BKSUtYuFZQ^_nP4QmS=DcX`Rt6HmU$9aE)Cmp*`+G~x4@>p;EE@RJ z0_-Q9-vnL2L z*>+*ZBHgLU6V-d9M+AI%%Nf==o0EE1f=A@96ZXQl4563@6T6(e2k%YrF!Iwqp3Q1N zL-0CBWE`B2C6a9)q=Cry{u<+g#5&)fwdi@YU=Y~{eBa(_NZS?{(W=EwI>Zb&NW=>D zBa8@}8(zxCOD2er6Dh`3OZT|GRLf+DQYGYbF~QpCmhb=BJEt zNtltk(Vh3RX)*E(@~tH~J)fY<-$nAQzGC&zb&a?-)k3t#(?4MUMIuOd^eBJg00HIk z|4$@>;Q#M8W+f$QWd~;4%=4VZb%oG*IMkOFs*#99FXNU3wC3aO4q*K)p1~%0H}ZNlP{yZpJ_FZj zzDoz|wbZMJ`I?T`^xDqqs}f?nTQhOX_Nrz5J>ARp1-X9%_ZjH#ySUW@*v)DDX$IC( zc{k-tzoYZ{r0PBx>Dk-yevM)LB>SG|^{wFDQOW+9OZ#~`p!v*Ev`yK=0VWfMrMM4U zAtUjz8cCrb50UdyR*)>~c!i^Q2s;x?dG%%#`bgtVD^faoXVA)k#>>8+z+n{Qqf}`g zCv*H_lq+v)TZnxNp{6&^>*Zqa^tJtW+BM~#!;^;7q~OB1kpfF7G3>MBHh}PicS|1`mB%S9Ow? z--8yeQunPTOZq$b&cQRG;;Kb#5UO-HNbl;fMtHXyExzcY!5RON@J#F38cN;F9}Q{p z8~$ZAOvy#CMM?IY`Qp@gEj}tvow!NkR$YI8k=ZA+aW?MfH`y}oAGh^`E@pjIQ(_a> z5{Q_MFz@BN(yHmO(5h2lDulV4$y_p)KY1D%J6qR0JXx}(HsCY0+GsH03t{9fax{s zrDH7~(O2u|{Y1N42{f5xSG)gl1=9p02 zh0S*U$w8uDwmzAB&C=W>k^R7!zKQ;sc)x_OOB3Uwc$@(M>mVL;ftLzVhOF^f zvdaDi=DP5AR_W9Bua?NTfFyrzmt)W+MztN-YY(I}A94h|eV?h|UMOe2Rax&)Wnis_ z+Hno$7)^g}i!ILiJcKlqD6KA}pbWA-hwb?p$MQ#wv;)H>X7#!OfN~mvr(LL0=6ALm zCqna9jEEAUX+pIXVF(`M9lbc5pPMSnT4S@5UXDqiEq)TFWJrL366%Um}$2^3dw(+rK)`&A?+QgdaL16;zM2q-=@LJpmy^zphfNTY~8&Auc ztyzj>*5TGn#$DD7M!SkHm9@AIc}0Jodu_*Q=PXy4XDQXcZ2XrJX*FooIlbF6=4m=) zIz!FLJr8|^p3~=vK48~u$ALLUv5>YF5~W2mHjTDog^ID4xfI_Hm06BT7t`G^bC{2S z-DhKsin)n@XBe7q#$+HS>mud!Hw0Xt@%Kw8wwOI9XlEDLyLw^wIdV6eae_Axp%OI; zR~aiB*i*E?F15NT4aiuWW{kdquz24IPf>1zs4WFmsZ(c{bJ(m9S1GyFjCF|ONqMQr z^z-&LNQk|g(;@knJfyq+_69kP3L9rV z?o+AM)l^8c48910YZ4o_e@{+7IumE%G#o>wb9%PUioHor(o!6d-W71|l5W4{PLFGR zauIue29DTHcEQZ94b4x!Rz)$how>*u_p-Phqz)tAG76_HPylbp8sVJMb+BX}rmAP! z?y+?fr^|!bc#7trA$zfZ2C=X6aBs|UZ|AZr>^Qd3cpHE;S91Z-kT?D(*f zdR%|f2}x;#1Na3|Y24ziNteP>eXsO;vh6A}Rb7=w=a-|nG2CW7L8zxOs9I>8g?|0B~C*cx?=b;gVmmOO`vjR&Uu5Au5{G*YOM##2tf`>6yLmjJg}#cCnx<{wGNS-T8m8s;9%nDD zV0-B3p8p>m`{X`uaTJFTBN8Tyk}%1Yf3g`Kfa@Fp2bQ_5)B|~Q+F}$w@f<{UwoV}% zZ=Ss6N8FMrqT~c-_UsMP_@=-M*1lQjvpw7} zv35s+4Z6&-H7LLRU5dQA17v1T!Hr5%RG&GrcceOhvFMA49LwJwis`((D}}zHdfpML z;T)4L?=zrbhR7<#0WTL9mpK`7nJ;#U5uj^L3EBQK>4#=2%Fw zD_b%|&d4VM^=WrNa442o9rukYnfDaNWa%?^42h9C<~^&jC*apad6$v8 z4?Im?JgiDiQL=Gan}&txs9mYW!8*z!t_`{f&Ix+l`^4@*X2URm8G2ejNl_*sZln%^H*TXQ!Yx{KHf{L2lTL&0j{u`raIQgOnR0CaaVTLc5X5+&tDZ;Uliby9)Xjbp#<3<*lg$b2z2}R3T>$mEVrREHmM|Krqy*iPt(3h>hnpT9qkd}2xWpmNipBrPw?y10h{+?;XTxCPvZhS6#LZ|t> zp|_Uo(orr-B|_|C?--kMUGRG#XA!4+KB0EOk1CfXKB2daXIPhdBM6;g1+Vb9y&G=w zo$RDO+{7yAxy#L)V?G4$00dcarUlx)Q(XZbnNND3pt0h|nEkHC3yJA3bf3(z&q|@L zn8m+BU%$#yu+JG3Z3__j!g2y)I;NadDTdfIFmFcW7Vv&69fMMD8?L_*~anSJB>krky4T#xIVIt{S zegl`(xVLOlo;IymzFE|Y+!)4jlu2P|$lNV(a*Jyi<@q!h8J~)$vrkQk){o*!qp_4x z+(<+7ibO@-QKQu2L5ax3X}n{xI_xq@7dGVo?Y$>s=< z9|A{YqBSyN=<1+2G+)f$@Cp&pD?ut~HSJF&Y9u*4;w+4SG&5RV9~bP1j_F9SuA*km zQnIgCsn1{UGJ8^a?=-E;n`aMHH9Z?1k5{nb3gs_-gl@*e9r=qh2%e>y*}5_mrf}J* zdd3ylhU7$g=;UT+K)Lo|Gp^gZJ9tH%ZFtqj%Ny-(C1-&8ke{yKnoi%E{RiEU*4l{G znE|gO4FV!9!h5nIVX_k0@xuOiNi0>&G>uP=AtT#_bW0z+Ykcz!v*GySwbt!c!Q=>o z%*Q*je?k4&*qTD^6~E$=nCa2}`U%RUGp55gBCV{g9n;os%SZG9KYO5t$+0WZH{hdF ztxrdCxWP}E6h{1OxR9EB{s#lV_~;z%zScs~InOZkWVFf>K27_-SbN9dO51f?I309s z+qP}nR>zsKZQHhOb=qUQ zd9IMK0bbEF>L|^f+ zdZT^ccqDoR>RJSR{(k6T)!{$c^KSg4x;TZGnw7C8Rcfb@_sEI`EN1`Y@alkop+uton(#4Yvr8f;M`D}bG&$(Ph$(Amk{#Ks9= zWbl`m`@h<362|`$b*qfqATy%y=Ex+F!6vbxtlm<@0$BrRqqXmRxvwgeC83E(p(Sf@ zAd@?@-l*V_$N6r5xy1@d&^!b2LD}<0#{n0Wi_k=Sd&hcDbuB%c$jmg4z$#+1QDoGKV7D$L@q_dCH@HM}Tj7Zh2mU-%=ngtX?+8 za3YLJT&MtUV`Z~cUH_OHHUZ@A6t(K zyn}4%*D$tb8VEDUs1_l0WV`4d^XkEmFe^iPAvHZ*^stomt7 zMXvs+`l0X~LiKYp?)ccxz#bG=SP2@h36sn_KiXk({IQzGZw7s!OpmTNQA0I}TCYt+VRRcBql{6~d#_@fBYVHs{|<%$q8a zIBe)_j36)nv6+&gyP?VcwQo=j_Mhl#`u~Qm(kAW>02{M^<+6f{ zhf)804|36598x1}$*b}G623%|O?k@>euqA~WY3Q=Fx81KD*asu{9 zK5Xs(WU)Yg*lU|B_vFhaHmOdXoJeoICWYoC&ZR!)+g?b^Urj*yBLL6j@R>hOO?K>0kf@NLSe}i*-Z#B zyUB{ErFgCg!A3;Y%0(ZegPuYUYC{KmNWj=%T?$&Pg@)Kd=r{THk_pvayuAk1UAWx= zHH7&NKG}MLXGj6N@Wk}2RV_HBuwpReuI}LEx8{ls!l(u5q@hT>Xt`XHW`^c{8Fs>8 z)fO4MV*2IgQ^ei3SA)r_GZ*2yrZ$GN&lZRmKHRo}#f%e*{3Z};0w21e*nbeix*w9Q z!h_Rng~zr>_j6B-#)}WjCUR&ZsNd70!=c#)%ibt$&6zsG%Alni}gzOx;=!YAYY(B@EwlTNv(b%&>*2f zD>0FnI|k-FDDIp4IG(Y>)NQ@ZXxruOr|uMwg(c)&YraP5u{yp-`ImvDt+p z%b~t(v4CaEDDx!pbv&EW)-D$2m|Dm?kd40jtVCLI`T z>q`7AF6tQOUEH_HO3mXFz%;izQY+LwH}8 z!;{E431jrF9kuK#U6_W+?0Q^D6CO1{ylq4$q+OLR!n@BJ_vfx(K&o?RfI4bt$)2;0 z>UBsA`;GUGC{=eX&&&9pgt!l72;f#BP5au2^|&;wF_Pmhf0`m~!5&u~Q(&prVp2$rjnax8 zryUfDYqLKqMt`RwMt{#6_ZQ+kxZyK`GSMym$#eDcGp^5cU1jUJk=ym>Mw0{6WCsxj zT$NKqJdf~QJ4zAe_ecS+BzR0G5L6MIlfxDxE*m{~U4gDHh#cb2w;jdJaL+aS(~OLa z<0_$t&1keEo8>c+*ImwqB+JPq%LN`s8_RV)hQ|%Ye%uBt3rp309S@V0Ls3X_q7Erb ziX{)lCu=?O+d1sPu$ja%uB0uz)AG>j@%X$9QkJB~aeMkD{fbog!!Ye%bV+NUcWtjG zjtto?GeO*B_@O~$P3x5a_ZeDhHbo^~LynEx(fl}RJW;VSYa1N}jQsPs_)_+$3%d+7 zyYK-U>agm%L`2BuZi-r-P3)ANWbCi4k?DI5g4!cnfm@zDDC>up1nDxf6@yeVMgNMUQ?)g9&s`Il*U47M(1ET?!N88={Ia?W9k#df3p3VAcLj?wtSxuT;iQsmo~=R^(l258-; zq-8}jXcU%dA-*`^fl>l(aLqxhD(;O^%(UFp@D%{79AVKdocr!Pu0ZGBTZ>PaMR~b8 z52gOo021v{yWoYm{qL0Nre`47ya(Jz2*=|#abtt0!3EPY-z#_)+q&k;@Iu9Mu_0_n zzcp)lgRM#YNGwHF)yxPot6$lpKnDf~z5Ee!6$i@APp%iRp~DxNp+f>JZH*R5_1nvZ zDUv>V!yPHIUiuGhBJwigbJmf79h|n~GuUv8BwKp)77*Lqa)cC)D8g_Z_Auq~MH5o~ zjT}!H98ZuOPc&U;Ao9J{DH*SRU#=aJZ|}x4wa1O?dZcfDY_&N5TI}1hL6&KMYcAcE=+h~v-hN}SS1uKV;3g_r~!HQy1;^NQWVh}3vQWb68p<1m!k`0(kdoN z$V$=#E>XQysZ+d$gTfEbnbgsT4Hk4h78b9t2L&XzSJJS7Bw;AEOBT0R5$1I}+3$*&Qu7ozrXXqQ-0!NyDKxuY2vzmtAd zYQvPK4}kOHY%R%Y>N3PeUI1v2gCso!OJ|gY)+Wh`=6QDN2?|{F9tLLhbrc)h+n^bK zaxH(f7!r|TFGsQyLmhEh+?=`sB`xJx zN{}ZEy2(guKu2-tLLSX}Pm9|R&r9f&g>zOy%mjH|^%2a_x9)39Ewdv$ew{J;ZY_^= zGxPCZJFGVCL<|7lQH0C}UG6kf3e!H?HD>&^m^2;8R5({@Q$mHH#AqH*%Fw4q(U6g- zpJW)TcP-Rt71)(RbhoOZJh<-DyK?c;+SO-M5(+Jn4_2Frq|D3P{?}a(J@=M10C%Od z7Ho(UhvD_63C{6)>TU`Y^gri=%$K(baVokU2W@9AfW?$PD4w>iEkE8-7+OAS2(X?W zHH=+V{SmP4d@ww!ut)0oWm)+eMhx4*79j%(3bSIGHu*>&X{cG={^|yECkc5tC+@W} zJvpGmIbqUE!gvDVV1-~95W<@(jU!cZbCC}^MAd*&RQBTL|Efyq{UrH>en{r1!3PnCt_B zvUOJB07cPa2$gg1kj+Bvk?Z5<)j#k>d?V3Ty}TiR6)|W|;+T2||@IgvmAK`^=qo zaPq3}j>%|DbbCZ`H$w1q3OwT<{r-lbNk4 z4`f%{#b_p1Pb<|E`nj(G@fG0zJxpXpmzzMn;eGU%wkW-%;mp6FtX z2LpMfm$Z{0KZ-wR|h<$o^73%M(s*gKop7@7Ptb|pq&iwoZGK+ZY+P7&n0_AlY{`(tJxe$Jaq)d` z-D-Qv@w{|@ziK;z<9S;Yjs?=7s1~g1O%&CLE^Ttx$}|hG`okAyb`uTMjoITU2zu>> z5d5r$ur&m|`YsGafBM8Nn6%x|zD-)Jw|MBe`q9nC|ND|3Z7=kh{Gz*H(%#yqXfjr{ zhaddf0-^ER7=gc6o_7fz9-jKsa?lOe_IUZ1`CaYmyG*9<+~HCCJGvlEAARzx>&78} z(~ByC?Jj@w3w`!;v($?$&@b3+S3#OZS+t!e!FTpQc_Dw~5o`@OC=ehe1QCvQNB!Ia z%t?sByT09k*>}&~fRi8$1dl0Vh%}<0N-<`rC= z9<$DbY?>F8<})Wokb9&+Rz1elR4zJKS?O-HTacQxKuKvOggcRCj95iI!Y$(sfdYTF ztDY@YX_fQV5-iWobhlSG7ms67BFLPq4Vq|s?ro$`$*?3NqUdbWlucl_ycL$4lcn#% z5f@e>F+%C%$qz77gNmxAvY+LiMg!YQGnp#eY4aHTgul10SJs`O?P^(#KaY8|i7MG$ zbp`KAx4voG&T28PC?%XjpIkoKUz8Dk%@7fGWinwOK*r=w4tr$NS=*>rG!m0 zmRV^M6EsEPgd&N)#7v6$s(B`!dTAo9Ww?v2auR5?+~ujEc;$d{>#@gQRNd3u`loP>qcb^>@5L|>b zmLr;mEg86ArLuQont95!Co(+Bv4!MKCupyqKFFuPHQ`{G5i zUE$>gZ5zsy(n5zs>y_z==dn15@Az|%fAH?WjZlsLs;q?Bc@}ZeOBd+JC-ozLLgFx2 zZEt)*Amx&iOuc%Rx&+0L>~#7`BzZ=9nHn>teF=Sg zy4?3Othd$LY71V;E&EgU#VIweX{|+l%!R{M6`nmf88|8<9QBPN0?DqYX6zg`jeh zPvRZo=_;+A9ZTN3ZWZ(AKg=8m7OZPy&elv`M=?$F+b8<-%kGsrhf3R{J_E~rkJ9kn$prhpl@ksgghL8Irh5}<21 z}tE-JmkRFm5fSjasE!FuHytqMpn%8xeKP+?8RTP#BJeS zUEvp}lTvRr&p)_W<-LJ=(z~S&>-DxpxR%vuq)l~SgEXurusXzVpSuQmmoy>@I9au= zCXE^4&m_(?O~nirYT;%CEuZtj=DhuSvo`>4v*~-#y-fB05u2@PRywCh>s+d)8vBr` zQg*tpD4X$+xEfWnuV?+Z7}a(O7Fj`7W%JmkF9dnE$Gg@*6tO%lR#IRQ^;7Raa#}p` z;-}~wEePczE2iVOx>jf>v$x1$B2&cqYb<$<5h(&Ac&B#~v&g-@mH(OQn zY057GWtjkS48k(AXGgSEtAB;b;Z|Z4SSfRy;MwRp?Ly`SK=FyIEr>vqKt+^ldm?4+ zPtK&T6hDYjaL>=LS>Gk(yb&}F=$cs4M9NT%0$Va6W)^0d=9^{KIY@G(+B(w{pf*SFc{6Gh`Nc6 zc?D#j_55?+jrSQ7F2${jN(BJlnZtHBk5S9EZ* z^G+Y}HT$dO87`3>5NfpOutF=PjuVEcFa#ggBfgluQM^yp&<~Eh++8Dzl_KI|;j~%v zbiJO7;Eg4Z(0QzN4rP#ni@u1~yJbENV)|ts=p}kuioDKOpA7 z>orW&IFzUz*Eo0ON71jMlW;L?99=aS3-COL!XiMf#}N7g)3|doHYHyCcZkep>L^lI zYTbe=2M#>W7O>#BEJCFFy9p;Cl3@#G(aRNvr&Lm>U{rBn?4QPZAOmxdU!#@9+jq)i zktBlC{8vC-vT>5sA^Zw&TVMF->C>*LZ;3zJe|tijHR=wl;!=gdciS8e2vxi z=@&F1pmdm*tNH<_>6bLWjdjw~+yKU14BoMCp+oNd><6xMD|_V=avT|;&efoojtoD9J=g(wRK2Rli>8S=A;y`DXk)!!r=?i%nV`Z z(4Dra&e5(V-@OxgC)Cdt+~Hftd&FvzpR*M;GHAVKkb4*+nn3iA;EeBqI65KprLcoH zU0e$G61Ug-7Gr4hjc#Kvk=KWl;oV#PcW{n`LD_E!?x?w^{7yZcAt8q@#9Omcwn{9U zqo_$l;oH`yd0*1dndpoW28pvrCZ$}HE4ZwH=^dDEOw00Fr1gH|7k8FDXpyU}S@tK! zc5uuNdgkx?y?A_Nwuet_JR_>19Lyr8X}uEsM(sg*tNqL9OdlTCM^XBIGwI>jlBh}+ zv$%!ij(}$d8^eJ?g@|}y2cOZr9%0<4Jz|}M;u6=rLY=e1Zr5F-qW40>!PFX0MV+yn zKin3rkCZZ%o>0Zjq4uV@fpzfT=o@2?eoW!|G+r2qeavNvayIw128V>@^T}2C`9AMD zv&FMHpgY*`2j^nlR6K{tvqwCiHNi5pY;8FoJ9)9k~(T#nh`-%fQyljiqW*`C`x zcY-_L+9cfyvlzQiw1W}m8ay0ncoWt(ybAq6RBPlZ8-FVFqKV1sqIS#bDcT)Y=5djq z>ze+ZJ$;Me3vzcOTT*tEp3@zS)+xZ=J+gm~8?xWQQ$l~o@ZR$b=rVGhl7DmbS-pCd zEZ4>)fPZRBRL~qJ(0pd$1N5o)#;?gf%NdOP8SBXx@Ex#=!4f=T2GZ0*X0m~ObDJ`a z%Mf>~bUfM$1h6(g5dPw17S{M7H-2{dh$x-SwLL6DS!;;q6JX(kecfKaO*B@!e_R@k zwoYj_u9QeLpx~*aopRf1#lEazft0YM042Xg0dzTNwr;GrYiJ};pHH@)+`pZk8#wJ4 zm;Lh2O<%HDX2QrkA%k>#aM+poWB}+&Alx!FvLKfC(DmU*csxs1ZB|!jw#LEm>EqrF z2(nadPpM>XqD;=E|ULlft@kt66s{BDMV z0R;x#Y~qfh1cfaHM&wBm>SHGK5cXciOTM8l=314I6c3ec4r0au9W1zxO|qOzV|YJ* zaY@UeAPS6u!AL|>@R$(k(+>|>>t%eZ@$4?9u0WVv@fRuBEtF7t2C`iBmk9B!U#sg! zW(6vT256P(U`o+<8Z%B(v>rup>?1bQxMozVrU<_4L0@-@!kYCc z031sxi%0XqSjV9|X_tgP8|RkXnQIPSxMK}Ih$tgjwz7Mis;K;|YiL7RL)(7U;f_y*p#R4(?J$YXk3MZ#wSIC-grrCX8W>dD#rU6E z?sCZv0V9xFoc$i)q|e9mg@@HCwLQW#VmM$m4�b8^o>!LdXNNtKfEz1|njViUt<_ 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%0D?_OtY7nXny$6L(AbS@Bk7I?-@{WFB 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

    3Aq2miQol4bEJc^@-J z8+Yt^TJ@UmCQ;_I#c*ck#aI*|0IB3$DxB0?c`Nw*)JeP;6OaC0jiP22o**X>K-I*_ zMNO8UaKEAAGzmf7^!#u))?VPu41VOQD_cgfLL{Z}L1TGhz=f;CLE_7h4=5^sz}4nv!f|2w?E;;sIz;dW`&@5$9eR}O4TXyGRx2f zUJ@cYefZ7=w#kkih(tZpFz>om%?dBYq~uLSASg0Wj+{@6O)tFG-jFnXPNsqp$crS2 zh504;H?jon5W&5Tww9(A$IpsoPUc0xUq~|&hEU3o5b26?hFlOxc^~1*+Utj+q&Wve zYgg95oHs67RKYG>XbIwagtOJW^Y}9wCdQgO#4peiWE2>mqQzE+4r)n{75taqIM2BCo(KFkkz=G29x^EbMTDNZ6g!I5GPI*OK+Eoh+lOQsl9}PcSTo5QxnD>wH z)Qt3CoBo&Yd~$41%AewULA&*xd_2>FT?ib0M}-+rJ@A~`>QzPE(LN5@EC~o7>NSaD zk2&71W9<36m=Rv-RtaAgC{(`bI|+;s?jKuny>Ixx_SuY6%w6%*=D2}!Xl?lJ+9LN} zK#Y)KlWNbPZ2KU$4v3{w%$e=QQ)lINY#isKQ^8+GxTSnycCuWBRr8>rdLGc{&?5B& z3zdmtz@5Y22geog&9MzFMCJgY$WIvMlj@~7==eLx>L|b~*JO=0vqnf8bFFYv+ zRiy^n1PlG~?Js#ZHaJ{r;~4%41PYf{JVgJQ3|B#;XNFvtH_y~%WtjAoXXk)+=@jme zNE9Y-Q0M{G2SPAv1x_@UNB=FhG0ZRt%xHzR##sbWm5><7BMoBlsogs;1t~|VatK2W zGmZ-}RVPj_EU;7<-G3*cz`G3Bb&El?7V9=nK#5r9v@4YujrtcY>|22{ULy1Jl0o#3 z_0Wb5qGv+iW6I|h{K*@5tR?xT7D|9Yueo}GcdxapbFX^7iZdx@C-~?g0luTB`c^HJ zGctHi;#a9?_obggGAWmjJ)f%2w}Lp>)4qo)Fd5z=e`iy19!&5JUW4`kTL2wS(5>W> z-8VXuOX}4gC1IKSp7V_!v^HNt(`p*#z?IDXSlWC?3rRx|9?nzaWyfW5uGsemYmAF5 z@K_q;FAI2^5JRm#MeW9xwM`H3WSVQNclJ;4EcF-;kK zCsNde60&8^yTafSohO*l7}cGI{^0Tre0Qwn{Xbva?cS(oNyAAlC-A-7mv3|F z7fi()fM;jU^&#K0Nq3aT?PmDQ6N#vU8sw)CEHNpb6Gs?kux&)PA@LjkZ)M)`jg(Pn zptu7X!@xULkYg~f4Pjifw@Br3pqFaF^NWQt)_A+-#pAs-b#jsTtQX49Zt*vKC!|Vo zo^*GX2f;r6tTVsJcK5||$-nvDxh9DRU{Dzu$z()7EV;_cd}io1%`C@Y`T4<*Ii@*- zhzh~&q!@vqyra(9lqcw@bXcuUNP!*bQrjA=^D(uQBN^=ar}zXd!Zw)KlccwfkT6#v zzbtkyHq#H8#nOsmHeEx#8c7^b%iQOq&-x8v+FtRZgv?8VGl2zSwyO!Uc6@miInZjI z)Pp(DN}UXYe2ACxXVdII4#U?jbb`(z>?SRqc3ubr%zTAlyPtxtM|z+9Z$8YJx;vr9 zT1Qk@7d>U|cnLaduS-bo953<_M5HYR3_0EB$-OR$5lbq-8bh%);~7aFXVUOm0v;9J zKcCneR*41>JFU6z=1gC7c6wcU1F@t;`(nSh-(l_;)dI`)cQ;KOydtm#yHx#!+{q zJ)=GU7*xwd0q7MyLiX(GkE!D(52hWQmaQ}g2fW+Bjf`+Y_E`DQUKq5!z^l4a5+dLm zIq@w3+*NT1E?(hYw_0|*70HUzc19njp@lpObBHfWK+4t>&xQ=X>VVL9kwW>;iu{Xz ztN1+#vD^9l{!AekWrE2Z@RFM@PYmO<48l91#N90!CFtm+hwmLLPs5fAam3rg3{Fl| zfMk?Gpd7MKq`MgghCmgz_d7`W_;%lTSY1}YjQA%O>%X{oQ-8Zt7Nm@0XmFPD1ytMe zaSEM((HA^Pw+Z~?=(ZFG#r~zt_Dv%fCHsxP-(-Y@EQ{d4b73|S38z4l?EY92`j3h+ z2|MRutc)yJeykaXoUX+`ui@kHJy#RF`@$RNXk2SIgWqEdPH&jRp7z!3)aPW3R{As7 zTOTyFzkT-oFtJ0kYV*R6<7!T`)_YgJ-Y1*3T*0K}ix&YJS?WO zy>eE$zTU=dL6-KfX>D#GFz}FR$Z5xkOGsl4F^t56(_~8IG5l7hCcg1R6&17FQf%LH zWTW9tdB0-hr=3c9znH#dxLX9@q`p?{jfovW$S1aEPNI8Zl=VX&lWEgL^)M|0JTl=)YUU1rS-^4Vf+dFFvs2g~u+(R@(T2IBk zd)QZqyTbCNyj3#gxo`PKz7zJnX-KkyZSo$^5EX;G$yZdE;f@@CHj}}QQ(Hs!#UoqP zwh9{HiF@X3UOCl1pMs^c$0SZ9m1}9wrX2jBPA?VtLpqJJz61F~JdRQke|?S<=oDJi zX+(!KbH+jvn4ZPF`JlW23Y=uN$8YUgrMO{*O$W%S?jk3&_!HlU|W+F`Zed^opP7`JQ#evM!w6)>H& zVKMwSM8y&FEFO{^qpBLVf>&aVqc#=FEQRv)`I2~-mQs2suOh9h^W9ms(7w zgc(Q0l>kWvlP2qV~C{W}_vLf^h;khQyQ!DzUKBY0qR zSUc_rR8F!3Oe`fkO`%5lY6G=6U1K}&A=}K)48t5{)MJ}RvwUghU5FGJYaOo6%?vOnY>_5^(HbAYw#e^%km~5fQGe6>cYy> zsTJ;0fJmKG$wTCzUA4FX-RU-u0XJ3?uz$h9?r>?;N-g3Ib?Qr(R9hq16ILVeG-c^- z#ILxeuj;oolKEm6e=2``FFY&B?g1n&Tx`r0@T<^n&XY>pSUalr;PULc^6pr9kE4QU z*xD~NF$byyMsCk^*MmQ2F_dVq_^12$h~H? z#ckw*D`%HNw^3Nr+v@{VD{rdj&(!+WjFi_lttY3^(|+jL`F>N`a7tRo*VUGcDA#0FeP2tHA+^wq0D9^;O7?bB3)1F19lOv0EWrf@bOo*D%d4LCwi@{(D} zpP5PIB|6`mGr9XNXT&+{JNu3FMxbOwt63dYh_xZ9{_p@+b=OXAOc`bqDO4_~b7+1+ zptjPgRD!8TH1V?k6tvx=$;z;@g-20BD`U(%3N<)&!UQ|4mAMfYq}!$nI$|%SWZs&Q zgvv2>6AJpe3nb6JMbTJzl>=Shx%HA(=L3;8Mh8)SC=xCv~eQ zV*>vHeA@BOkJRNgNaYjmNIDw;#vrSq ziQNA9T32KjiT+~TezewuX|j{K5G0P#W*q1+-J4V3YUPP!SlwTHocTCepQQ&m`m+Lm zFG>}RFl3TS&3Xvys+y_VQ6jN4G4%tupN*@(rhvn^Z|$747~|MA)x-&BEZmfcw3d+! zWs0T%+{aQCn>6{RA|ImslcQd#8$oqdc_Pt#Pi%^xMB_tbWvFkv=yAK4x7_wvO1)G- z@lsD%k4W$n%)h0hz2yqMcF%viVvRe+24k)&?!c$ut?s(zneuNLHuMg_XGhbi*sEG^YO;V#W}&Q z&qVM~3%ZU)TaJ%wlnBb{0LjYvPHY*6ZykJNn^taK;dPn2lsZd*QB{lYB3p5*;9)(x*EvQt&tWg`0pXif z@Yd-`av!}N-G9yL((R5O4pGgwV9ArB%~m&cOU3U%A24W>!4o|10=dtqJfzlR)>UR9LYffJHxpi&W1PO$5_xvhw0O zkRY`#L#Wm@YR$4{&AzaozADNL*xQ~ltr$Ui-RvnmnJpx|z9zySCUh55njwIlNml$;{Jc447 zYi~i#?G@xg61{3TMEP-8SWJ)*8(zGL?Xx@`#oz zlIz|R_m*|1|09Nr#)tbGX!F(wPRUg)waXSKQ+vfl#$Z6Vm}+7H+}#^xDx_OH@u^@) zb{*X}Kb3Jy*{!@dVa&ylCxqzrwvQpvDS~CjFOyMP@VN?wwqM7~foAD8^;o(Pw()Aq zSl}Sdv-KP*V~q9hA)xAb+$?jT7UlwT9*?cJNbPYI*Fr%R1#gwHfBw^pvX;1eQe*%3 zjGsr*G=(gzD~KcZ={6_`iD&5+WhBaTtak)IcSkL@&@*G7*>L9>J{OO80D&97b|*cE zGOQPV1ZEO@<-m$$!bz5?c8^y4n@ zNprTYN3#P)P)yQ!xRjDaVz)++-1dQP-{R150-7R5RqGgrY=rM{okiWB2iT2D9KTLu zw9bp2i*=dO%EpxlOBRMxY^tNJU%3_MsM11C3CUtlucD|q48_amNo5%@W=~1{0Mg|z zq?vto;!22@Wk?ZG_9UenU9~`%^xLe?jfvUc| zw@L#{w?QO7A3*kX3BL%fNrzWBCqaP|0pNnY{-kK&_@hb*t9`X&CSaJ=R0$>FJ;YP~ zL+G7R){l4=tJm6Q0Xw*FXc&)JHWv<)Nmru2DA@yevl3~c%S#(z7?dbZ$286L;XX-; zN_z}@Nkz@l$5;hzShv2(uEGBDHO7%ABn7o(w@m*LBZk^_pliSB=#B3<@jvM3|NKT0 z{Qrm%{|y|R(uL7iU;YLMu|3%az)_Z+wk0rU+sF}Zf&(LajX{>v(@`X`f8(&Sl@$Rn z3$1NY*B{Oc+?D8xtnCUk7U*LX^yKY2xZJnrI5+2;PE%W~yT96>rkII+?ihspUADbE zc%C*IbKlw?az_NE#P0$3*{)cn9VZ}JjEeiNSaCb>Sg(@f!XlOO71u4SeHBHbMi^`r;vXgZ{>l9;%w^@ghig!*GA5s()rqH^p=up(WxJR9mdAYZ zL$t=eD@jr9gF}^GF|M^7Z3__sOFV6pLx=h#IfhVL<1T;lx(xGZskB^TE;>YBIboY* zTDIt?Fs)lk<~DspklPdt9nfnw$?qx0&)u!(Iq$ zW&WE(mu}S0^wwD*o?#6Fo4Y`Tx#Vn9G0fC=1&8|mOPQAIo}nE7D4bm-MDJI!fatrS z_2XEOZgIOtW~=nQrifoNeL$9Q>saLa;ln@D5xyU)ejc)oMs*t$Q=ry}vfG<;T?UyR z()Wtih%zp5>`##w*GWfp?ANG8*O(30X|qq*??#Y4%R5gv@BWk{XTpU&>}_m=W~q=N zpN=YpOsKa~>2s0bCIJ9;bo=JeEL}M=jeO;%?^=x6UbXzGLiO*ywNT|Y-m|C{vBkTG#b;;DzuM|K^$Cv8??kTSC>b2`A! zO(7`HuDiUfu4Rb`XRksO6n4Nrm(=-usTb(>Sn48=ci#ElL3#r~CkgqS$1 zy!)p)(@$P5Y{Y$rP<1o(-q2XXQUo=D$rn)gM`7KDn|!(3r)0o_5o&a(UdFIR%Jtpl z?IG7|@V}SESw~`RqdZL9@NX1AEaHlBXYb&MviLM?-7%>ye4wuB4G^ zl+mh}tTGOlBGJYvmc*rK>6E`4HN1Mnq|z2yWyTSLH`$3Xz?6DVYeafH(Qn>XY{!xr zH)1GGu%2QVNlt?`ljAi|sC%P%8H+|U(f|tW7x_N8ic#AZ(c-(CcQi^zsY_CW8$_A?iNFh_BP`qod&^+^=rxvbfiscgW_jxg3J-@Sd_hqfWlL zxnGSmn6_tA)X44#?fv7s{VvxQnM+81tl;koalG|`UT-pZ3Em^IaNdS_w7McF)mx>V%X zKF&kr6jodm$cA6L*uEJ|_peNEV*^sIN&NohQl}6>9rKgo!V8@05}49$?fDtEx+GMf z-AfyOh?v37#sOv?iK-!e3HE7#>6zf#qI?i#F#5uV?7BiUh&b#J7#9uY5p(m z+(U!yzD4#&7+KV?7US3%W2wk*4kr#?TpGnH71>T&O$Gd=9(;Pha%P`?DmV1UP)28K|5A?rND0#ttDFi`_JE#{i z%0GyhGb9~h*8j2!L07_r?B-0o)5eH)<1*h_KHK_`(%)e|i~2?s?DyS6h}d7$-jUHV z-mSkYSNAYULIZKkQ~2VsHaCToxd&>L0jY|azL|fqH%#ty1TAm8l8E+46#Rp8*`Hk~ zg(TACyM@!>KfA`1?y=;(Gd?ZuuudsLdd!@uj4pisii4)V!wcEoQSdCMz3?RUh!Ve4 z27lPP#*G;QeP0j8Mp*Y(HbhdQz^ao;@f(BK-k#whu%}0e=ISc_J<; zdj_!-KFNCQ?sCNw1CF%hKcgH^Yv5!Y31Y2X zg0NcDZ~84{lOR7==8ADh6hhg_02w6!bfF(H^)aE5U=1+|=BD2>uWN2wOU>}cl3 ziGT*{EK)ti6pPHsEJVRI3+N}{j#6ez#(TJR7KK9QP8J}`bnR%ZA-x8NQ7WSbcVq4< z>h&iBH~FHAo$fSpq+N;mKsQ04l=w$}AG0J&`B4 zlL@p$A9HY1d^Oof^w!)f5K3m~VWk-{**@G?u?<=GTL^wsx9&?aK-(ERAP1u}%Et^` zFHBPX!s6#{JeKuU3Pcfg=Db7SKEmRQIbll%%ME?<^-!@!U45U4yjqF}w;>&jilLhq zJ8wzEW^Ek4iIDIY;iNX(ioA_*XNFMIHxyM8T7!p(vU%Nnu_fyO6G^i}4-+P~3u_fs zOW4-sGfZ0 z^t83893_=}7E&B^|5cw#kN_N}nC9Z#g8r>7!+S+HUhM-+L>K zd|)e_8nlgz&5=MD4c6`&TI+{3ax~kZc+ljzgtWGqxs_|BC-KFPQ6DD0krp?2OCi*r zaTFjz7zMr3myOMHv!T``R^go1vX`lZ>%cnsmuqbR!3(JkoY z`hxfmVAI;utlK|0s@+gV5O1_+q}z%}?b_RMlB6i#H*`FXQKuA~mTEAb+YrJfn zM$0^Qxb`fu0CGZPv01LWptnLlf~c+wcN4gdbQPyuS^&C@Y#Va`hpl5S6{Pd=*FaF= z7exebo15)6g-o2@bwUCif!NiK%dHol^*3}3H7W^pYTvN$6@Eq1fB%gP3n0yRF5GXr z3IWl=4@>Z`uZPy5MuUV3%2#>Xy-Y7m6E|t>_vu#~8t-|j%R??KX_31M zQ=gzc$grMp8}m6v57)-5F*q-q#_nL}0EEP7R^yWDDY9PZd8XqVsbZEvT}WaIG$M!V zBO_;>aHZx$9%yzHH;zeOo3=($MHFQz_L46Uoey1=D@G7UUDx{(*_9gj+C%1)X2UsU zJ=O(iGH?hBb0j-13E1b7NaN(=`Ut~x6X!$<`D5KP_nkT}kFBCd4&8GK>H*28?(Q>f zh`0ff8vrw*Q+L5b_cnwJ=KQ3{#zv*2q|HY)_FHs?J?mquJDp6@oKowGb$?*V>Is+v zl&U3Fj2qu>jcKKb9@Nx~nx(rc;%K^Cw1v5zz}?Kwg&Mn5d`OVmnsp+OYdF(AK@|cl z_ZaxYL32iz7CenT%p(yG0Ml;8!QF{St1a1Bp6xs)7gd(X?<%0FZaSqIy`T&M5bjKH zpQT(=(4&@KFH5oi_0v9V!y(ky?*V&pHf>C)2kLRT446cdNA3|g7r34mcKV}82&v%% zULg1hx9qOa6_s7x_)G0UXY>LTSE)4rQ8B?lekpL;7=li^$bKL*Kn?0<0l5nySnF^Lju4QTRAGj~#JWGTtZko~~3 zCg%uB5XqDvaa*uk6ymEXYBc=??u{C+Ad)+PlGuUrpf2y!myG_K>>f6_!`*|1-{gW& zrBhMuC=q9ygRR@PWT3WPIGL>_2eE$cSX^*>&`n8v%J+jBkEu9tv0i+HyWv$At>V$^B{TN>pt(F$J1-COslqH4~hl{G@;GS0DOD#^H4LFPVF z$YG8DV>`#5T2`*nE)6~+EQG<;U6EnH{BeX|3TZp5lIa|os-X=R2Ya5{tOh%|vaZO3 ziMc2s<>8TK^UuqL*E(AhaRTk&h=wWfGo)k0B@#AvzPkv6=X)r;D1H9+$So1?)`TZ} z-br?TCX!ROrFL{U9*%%+eQY|lHPg(5UvAmrIH&kLRuxxY!DP!z*SygFB+9O-JO?=0 zE`24`JB1w3iQ|1Us6Y)$c!(h$-O0XvQTMUV+^4&mS3>cywh|6=X9~V zp*YeV?JK(0yjWL+;FO?uy2m_>pmf}g-vc#K;XL%3<+JtKj+|?3Zt49yn7~*-;1lwP zeW-ofEcb;AjJkc8MF5U6>d9F1D`H>DSvOny2R>Lc0@?Zronx)cifyoSw7YVBP&aI= zH8{i20|yRBZIcee21k(b#N3h;@$p46C#P(D_5X%`pQ5l&6c+pEO@^JylFc_D6C(w%9rKHp5yDx>*#Ti}>*7lB{KgY(6SZF1;uFlf0N- z2Br>EHQ@S{qM%$>V|x~*A;cr9?*O_t=-6Epdx$?m)(67Mr=EDz_JHV@aO;d*xD(Sr z&pS-^vkSkB5lEK5=BjIi`7LQCnUg(1gv+~Q`r^3M@ z5(xxD&G`+bYTa$2Q-vD(QV-?mDCYL!_kyJPEDDSEk8HH*l3Re6t&(J4(?VnQjV&~X z1CTag?I?3JC@ig=?zoSuV3@TuC6T?+12!MHH|rp-*U8DZR@@+Snm_Qa_BhhV&eaBVj{T-} zu#b^b3s5chISa2dW+M`f+39_DS>V4B8Vw)J&K} z3KmQQBvu(bb)D*$Q_{WeB!?(4pd08|VY{4+b4~o7&HFb#tL>IFIDR&<&;Soqessv< zSPoa(6-mfB;o9}yY=m(iP^&=)0srNFtwj+9gN^K3+6%8T=f<%q9(IU`DZA-Ho@^zr zu0Ysl+6v(U7XhYxWG00+YpdA%0-Whf|Dh<0A%U!5Lls21ydG`F8k`y_{M4i~jK8YN z?f_MNPVbvz2h0FO;~F?JEOHTy%}F`>cBVOW72c^#ev=q9whhH8ERF@p57%LAa16cO z`bwMbn1;=r`2x-&9O_nsg{*i7(g943c!rW^`@3CE|!m+os z_l3-}c>g|N*ZO<1_hf_aJ2*l8Tfor(f*qJP&u%C(|Drp-cW#BE+Phoemu#cl-|68Vi(P5y9~zs=F~{ih?zLy4-=LRZ>JInqSAZG__~ z2{6oljP!S zIW(+2(8G_lTv;YrU~3>ZPsR|Z-k39;5%2V|M@I2h?r;S63>mou$AXJA!Gh3aI|>rIgAi2NViCa|L{EZsHQZZKa;A4XIXJm+RaZ zY=<;-jUtL!g(!)8qvO)D|4oN>#FCajVxV4a>u^_0Exd0#{Zk%;P^k#8!qOK{~i71 z?D${QMz%t~4Wc|UH{9PmI=*2AY9-AojWm+%;F0K(OcD}A4J3N1HJCxlu8FC%bg*XJ z1KqO$A%lYfxVyrr7jCmiCl!+f&s$E%S?<%G^j%+{Z$P`SK&%G0rV!|7CAX>pB$S+r zx?Fz3KoY_JPA-IRP9Btaa4*o648xgH%&8}uU7>6!{A~nWIZ4|;*}y>dB*;oD*tpqr z2cv{HKHww?_+JvQ0yy+WnAIw^tClY43Zwmgj7b{`>vx6@(zEWcC*ljaymq7yA zXnGPcLPK{2*g=At9={$;JCbX&i%lDN2hG=n&>qGXTCL7S?rw*z_?RpqTJ(pV2Mc#w z_wpRWwQLfyH8&gl3R-wZkNyeuNL1K?Q(8s`BK}Q;-3LN0ds|9xdx8JhM8eu zn)57B=|SuWV-9Z-g~!VkI66zykRat;d~@X}bOjY+?m&HI2F9Y^^Iy<_he$jx0@;G7 zUHTALFK~{+rA~4dw40j%9U}sg<&X9@p`w)POS!~_MIG72Npg>G~I-7$-au=@TP62n#*i}Z>dxHQ^7_qA1_z1;%4DqVL z__^{!quN8wO~nt$f5uJ^(~uJm5CDMeH<081J$7vW>#_U)bMF5&blaNlzd;=Tesa_w zOxzjO@x}xZK>Upo{>t$|fP*3uB>+na#0g)=K^qw{B+f|9wb?dXTrO+~n^|h2Er4hi zlK_{uY+$5TEN=*JYFJxaMoL<`eppW4W_|2PkqjCQe&2t59wmPKCURu`4(3ODxa`kq zz9>MJm80jJG!1LQQA$5ypem>~XfCu*^aHnDx*P}&4y3Wl5tr2$scoW>cSC4|c?9&R zn;8WvSFx@QsjrHhH6ZfM)`9qp@|2-&AtG5O@-#7@vtTLsI8& zogS%Tao1F$^@*pPZ0XpQ5*&42Fay=YZ%SfEDym{Kv?P-T#hocQ?qpEmvA{nm^a^7& ze9T%WMVRG@I*FB;1pVgJi!-a}6}P&ii(r+&R1EX#)RlR51}5{Rt9(?A+kQw3lp0ny zIq_3SMNICdaF)qS)P62mH8$NssH06(^cm-Qu%P=qXie@Vk?RI5M4J|f>gxf)P-uNt zZ81(Ra_DXb&x?aInoY1$3Ik zeFy(8fe=cN6AD^w>D9J#jSd-|RgW`4r|wW5Db}%#XpHTmc~S73nH(6(%FPXdaA19T zZ>pYdhIMqQ5X5@x@rj`sGh8rYFz5r;qYo_bH>&5Dy`fTM&KHzveIRg>-=o? zMb&9_fcgP%+1%6PdJUZQ9Dl82gARfs;_K3CIYzKRXOKU$xtq~4t4J{dw51xp2li(4 zj9nS9%8x)C6B`NYtNX*o385S%K&K|uh!8C#Lk#6Xsn4$B4~YlH)w)W_Q6&*gq8y_B zN&kydN()!QwcL!C3(^Rshey z#nsqpGMDO>785S61|FSI^AuA;iV4B!=Ul2O+HPcT?M`78Y$FoFdSo z%MmPUt+YnFZ)9moBWEAjvX4mH>nNi>HjSx!KvHG0p1*mG>*w5*-dy2Oc-9!>m|1D+ zE=qE~mNlW~l$b%)Z#y_gan&SB0f)E@N=R6c2kvE9Sx1-Aut_sjAjxuZ@-RW1kz+!? z#n0lvhincQT8pX46YIC_kY`hAr@(?3_h=}MBxbSA%0Q|@9nq7Ly&ks4SH#8eP8!aD zA1}_Dh|+!(eL|l^Y2?yX*U@6P_u<;)cShBdX0yS7+ixXYz!8QQCHGF87NhIvZeT}; z6K#zZBfGZ0N@6Em3G3k~pzIJ(X~OEwP`FQC7SjJNN9yH1fX>2JC_+l1$ zf9u2NY#bz}Voc}ez*pQVH)I0kL|-LW6v@uY@8{sLor6~O$ZWpnI93Qwk0J$*0m1LV zK*iXp(aX}cklt->4SlQBbZ=-^#ldWjQ2efg)R9soqD%|N-mgK8sbmf~w7dit-AG@e zNMuD*YzXUElrXB(pQ0oD?NFiH*e)i(+Dy=F`Q7~tr5zo_53Z*5k4-v-P-HKXijfzt z*oP}-B6zHn?K3I+x(%iuL+3_7VaT!-W|7Acnw*FZpo@AcPdrZdlnxl&VI>N z#ga$y-`Wp4=eVATw^$q>!IdHs$ky5|j``Agu8&Rl`QdD7GG8>4$x6qGkc?4k2*Tk; z@tQW;OJbnZ7m4bq^271)y-BOSTZrc%FlA^VL{837%;~zXM~@@9q<$dw3Wt=esbLE3 zxgN}<;U;MIc~>T|RMBkl>XM!h+p^e4t`^U9OeQlXZl`yw6l{bQtaDb!s>RA-Gc`iD zKS!7@?N-cK;9|5dH4xMy%IIb9^m=9*?Krf~SFSio%Ua&ZqUz(Y8Gzz&IUvABD-<0y zZc`d1X3&bEbkYj1WJ`}S{#$aRfvF0HggsRpQ)wR^^KvJPy?Vfb&AKOoU3*|0ZL@L@ z)K#|l>&O;qJ%6HqZxd;~e1do{lF1dQ70F#WhutWix5?%q#PWjCT|IAnV#l6^D#ac6 z$H6mobS~plJj)2~%^yO$pv|$GP_(%1R4MZ^*KI{VWue^hJ!cjx)BQx8-6N$te_q+7 zIvRVAlzmfJYd+MuB@1`fB+K>@A_J$8EAqv0UHT^*c23aBHhlqw2JYfX`sw0{j=SK{ z`BP)G^EEMs^^P;UM|gMTOg{nr6s#*K)wwIUmHE9!CUz08b3e|e*gz?vGdySR zT--yVu+;e-hr4jTk%N1*?8)0BN19}_hRJ~ZlTYT8;7hI)H=N9eYL7SGv8!lt@<}n< zhXjDv6o5;n)()S0-%r?2rZ-R3*&|wK`7D(~r%?C&iQ`M7ba##>+lR7)BgpsC4e8eG zDMY5XaM#jFtd#YfI(w(Y_4V!vY#`|hsp@Q}g&G;n|0n*RYWZU4z*X)Y>}Ks5t(CG2 zQp3QBoI)Y*8| zP)u`{Oq<3{tc>aM%?GOt8^?W&0dk~X&A%nn&6>2(;->VLM?-NpX6uQV(JKo|&Y)GLFs|pcBW=_U;R}d^V>lyx9 zL)mj2Hb`pjww2glhluRd*4Qg+8)jQkThQGyLjA_oSLiw!J%^M;hfh~Wj&=y#7hQ0! zo-##;+ihi3c!Z8Uj7;v5Lcq#Sm5;|YZ!BU&IXxnrL|IJ_Vw37_&kF~P-_69SyHvAp zEKrbo+tzh^mqF`f1yUhWgc>va71~*VM#q!DsXEd^_mq!BFnBxm;ezm>@76ekTyBO2ldz09J74 zCI<4!+%2=K@lNCwG22>|)mmy9>eLi@APZc!S#dI6#JCv7*&mYFEHPXySpQZ4ZmFf( zF^-z}eawzDM>kX1&%kS)$mV$-3(R+2h%uKC7dqn$YG=7A%8RRX(?+^;3UE&sybL5v zx%j1qWTpk!2Ul0}!5RQ|2#C>cXDV*4E$5c-;bcLhXU=B?EdYC`6HZvz@G_^j|_}xvChf+QYZJaJ* zoI{^tt!((UapT9cpOQc}|)Jf(NTmNiBN{g|m) zp}E4UE9Yq=X{~7J%&o8WLZ%|krT~%yVe!oqE=@8n?MBe7!b2m<8mL#Pj?7$dk%<3T z<9t$9z(6c{`o-II{C=x;dgl6e*ey9F1WZ)6~-*5%|-qlr&W zv9Y;q3mS!R6HRn8jjh{{k2*x(=?^z=pk3Tf?9iI_VhIa+d4x@vf9A43rlX)SO328U z#$BUHA1+qRZrdHeLJFzF4WcX(@?u^51%!S-ao7ljuham`-EIRNxM2B*fc&WV9$Yo$KG`y6z_U)$eizc z;K-aGd(eN~y~m*bYT!2Y@wc(ugm%K^@T~)MdCvhQ?q3Ri16f379@CDex$A*osX?$> z?1@s77^0NyQ)T%rrv-9MjjpRjF|#54YYWcLlp?XCv;kVWGJIugBx~GMhh|~^0EQZ< zG08PTU|YIU8wT8G ze60%ZiegQ+egtF;!Cop{voOg*71odNn3cpOfXg)uNBZeR%00D}isV3-O!K0jiw)3j zOMI(;DV*~{{%5Gb9qH^K_{M{L+mEW#l6)UZ9*rWaXX6(lcsoeX<;XGC4_A$==!q^u z_pYzR4rs&%j4!MAI?Dgdv?hLt$IJ+mmZ1 z$k>}rrRuv4zxsW-6xcS^NZYw`T9&SVG2@>Bt*xYm3$ABsH0v8ikIeQtkQaN~q5U^$GGIog%!b5C?ds zq#!7=87fIo7b7Tq+xOAfx$R&7{i$O5{3=@y?%EmTW#9_orJnN2*XacFA?(GiMD7b* zH>FckU4c+A<@Ktpqs8E{1gMmTUHE(r?l~w`Hi^JpA1Cx&!tPsVx#IbZbofVt1v^nQ zd%UI$(7?K*I74R1@Z84UE$Xe@lUAO`TqN_+IQ7U}QA{c=g0a9rMh7YM7%ZY+auOLO zF#lQPXVBz-O}3k+q($^(a^*j%SH`6>6{n0HQ>>kA;=uB!R5;qvuixCBq;$wV3pUm9 zvv%Li4z}~;Een<~3$j)(v^!pL-#QEQ<<5(?^WsbDSl{JtbiF?JgqGHB#Xb6Q2D2^O z`y=sasB|n)cG2jnz_30O@D+M`)YKg1rU=z5hvfjuiKj;lyDgJu5T^r6x5V-eWh1!T ziS?$i+szMWi048O*BkTe3GsQcmY(l+AK(jWx5@pk&Kd)!UV5~!CEaaGCFXWRWlwyQ zgUk4`Z?T1_$Fvh>cFkt=#oBexeN)?Q-UXhwo;xtrigw?46Z5tF8s5j|gH)&f3$u3P z%WYaGN_Rtcp!UkxZF^^ebpKA6RgWgu1~T{M4|1K>L>=7jUYZx|=)UJ2o)=Yi;(VwN ztPgD-)(3mUNh48-p&zkkpHfNPJoixgo?23xt~zSSTQaeNk+=1JE!e&Ehz*OH)yXZ~z$~I#+1|rBJ8Wz00sZUi67y?J)%wioZ^eqv3^cEJlll9XB^_{`U z81l;&=c4_O&*jwkSgZ$5F-qL(#)?F96L~qR{4O(V-j!mKQ|RJS0_7Jh1D+kD>8@c7 zH_}3{bd&5Q{9cUavfKg*_&#Ifu#d)xTvx_BZSzmu1JU!1@P+0?YRtD$bPYNb5 z2OX9NPxkor21h*37Zdy+PSOWiM*_}0 zA|o7&Ob}14ES{?>vW-dPm-9^!S+gxz^hCIF#JQH1uE-e=?xha$HK&Q5-CsX8D*#_i zgjh2_j{}w;s7%aoeZ$e+kAcjzk65zMnW@p#yEJBs>yWiEQSGH|*up6yuwx8dH9(*u zyF1s^p1j#waWP?5@k~%GJLR>mc7g*8Zf)LHVx{EJzMqD$9PfLtu?B>r6x)ase$B(y_nBQM!{%(;3cnGHZjr-Pz!MVp6d+QxhXb4W zRmt7LSel<2T1EhwjozD9zdNb0b3ChiV7szuN@}UZ$k?b`2m{C5}(SHtVI6tUjK|Gi47axTKOfLe8kAw7d5=Y44Z8aVMh zYOnK2xC+K{JWB4)L~aZ(d9M9Aj`$LbE<3Y{5vRmeX-3Iv3UeIDc8Rx<*84mH$)hwD z0s~fWZRkG#{B>65AO;V8I}rZRRfo%2krmR28_$Vve+IyT-t}@viSm*Pb57nT0u> zUfyN(PJY5()9Co~>hkvW0guTsg+AyHxY@6y%Fgbde%sR1fy z=ik|+Er0`pMuy70WkF?oj~% zuG#-5Sp9#`=KL3|u3&6u>)>SU@L#}swc495@+r2DN$ol|C_6GD#!_DR0Zm)Dy);2M zIe!(r8g(A((nSMwT^rcUREAzGlXb=<$@zAP>te}sO}&0{(ee|4^#*UDujuBfw<(rt zjrP|Q*v?C~YtQIox9Qs*@2w6{9n#MNydX^g*@FSOS=z9=J;Sg;c^z{ZEWbR}sl^>r z&OBY{BL+{fZ0J3Dy{`(@Y=mpB;(Zq0rxy&zT`+jgC>k?Qk6fTk7nuw#1PX2FeZ(4V z*s&yq&T<_>t+^YvZpz(%fYl51N+&wqS zuIfDy3a?V$@kvP3dVo1*Nx-vz06R*nBl%_>WTML!M`~;-R0+Z?@`3lDXd)|FCvsVP zJE@`zer;Z(1c|uJ3`~p&r6Jl>yT1U3v1w4+bY*yc7@;7L(b6P3%9Wa6ZRH9+v86Zr zrCh$ABv9FBRB@h-9*Hvz3hhR^l@}ee4Qi^8Yb&h{E}M=Ycv7!dLcO@ zVb1oXA9r?s=<`-eO9K@|#sJsNp-fE>^lJ4*l0MW6<(bYhzs;U%G~+H5f)Y}i^!nle zF#4Dk1uqJ2%e0hF#O8oha%s1n-rCcI@TE72^;E=Dad?IC zS}1W8_VuJaRqr`2(gK0H2Au+%;ZgCCBf2E&uek0!C7a=TXRB)3NOi=GUf&32(=Lgr zI!|a|(&WJuDUqKPU$5E-z+Vtn4*D2KP`JyYntCMzmg)ze^!}@>}d4OmT&2vnVF? zJ}idYO>9`!=@Z$u{53r$^0hre_w1F}XP9lo`4gje{$BG_W|X+AT5oZqe~H~_oXL+L zCDr*8XORQeP-K+eOJJ0Y#JMZb9b`^^00mpsUZ8)4!a;5na7Xz*Cx&+~mZIjoE#}4f z6T(;J9u3=fc-ILFjfcTbV7MR#?#>nEXYL;Vdz{?v7rQb%HIaggp8ab+Z)HY__^j)Npw`Ev-)X{3RtF>yeh<+VdMd98ifhtk8`Sb0zXAW(N;_jvry7s`lq zI^>U4{2w=?U^!LvPwmzp_hF*CiNriwUUj)UJ?Fu(k5^>u?h6&EZ$hqyy1$V*0yL^) zj}@G`EL0F@O2Wsk-{;3gw?NARC@_8f9W&No+bXk8B%Jj`Qk61;C=wXfpZ>^!vAo$F zZ;g|rCSblLZ$nv$oTZst><>phquwV+37lZKt}u|JhlX0Xr;CwygnizgPmoDwqg-C| zYh0i6Y7qYJz=he5;KI9s93CM1?m{~$0nhf^Lg08w0R2MX#@PK#NE6(^jnQ&Bdz)p1 z7`Vc$c(SsH83eN2MUUf)J_8SrEofj`a*$bFK-LJC?ZT*Xg?Fjh7#{%q$B6sq zfd|wtMxv$=&9;1&TCJ>h2+areH9_y)fBIJu)%XJ8ZVT@dLcO5|v|jdTI!c0V)`fsK z&l0kia_}BV!&LWnL*c3K4-MJKsKq@}h~`C49eNfIe0u)H_hQT5ACa17Pv(b>&$teh z{J9y}@z~eZkEiYMgW=hFI^%c<&;eh76A0j&ySj7pxGZOvX%BTnePDgKrQ^A|5Mw04 zziFOV6WugsVg`{k>nZ0;9C&}DzfVH$(d1}fLDHerr+i={ibgEej}p^sW(z1hB2%57 zMOJl=wbX&3*2LB9(>_jNk4W5tOIBAtB(JeYNsYuAPNVGTGYi+MEL6^({-dv27Sx#< zfm;9++FcjFg`|553T30`_50dDVwr&fKQ0I;!PdS#(F7pDb7#uq00#Kt_-{T4>c_dE z`g=m+Ek-;U;wGJ;nf@3=7U}{WD`KmjD9>Giy2B1pxlE_n>{Y|aw%H#y%d3q{v*_j< zL|THW-If^;tNX*XN1o#Y-=FEpI5C&|hM?+!VW>9Q{7@iZSJp@O!YxlD8(xYRoE7ER z(*mLuNA8hQ`401_rqX(Jas}K`m5f(9nS@&=?G%DlbCYYfMhfW*h#va5ZoIJuLK9#1@F?a^HR>>Bm46cC>wY$w{%33l%ch@eJvI;VNfwgt4>|@6mE8x z^sc2!&ZL?nO-GZ3WY*cNa68!{GCDVu&F2u!fh&}Q@J(eaT_K_kL{w@SqAIbf6uHC> zzh}Gj3lnvG)AA`HN~(@ZvBp{Pzk&_nL|s&pZt5v_4OIKa>I0Jvz$Is6aa`eEium7? zDfqT-;_9<)BU!}JWPYGv7MhZEVS_T7jw?FgoU}ZpGVp_#nsT z?hsk=8Vx@{|JiqB3%@MG{~Bab|3@SJ|CP>Hb~3jjqW^CViHf8n(r;yuNJ8^M1E?Wh zI35IBi=n%<-2DU;;46M$G!>?#OCJforMne%mCN+a#)!Ls%-bKWGKpgm`Q!-@3I_%D zqd38`iP|yp&^ug(^PT2kq2xZHitF>6^KX+5&l1<4&zIF*0IYsiiswTsMDi>{hCZXX zari`i5_J+nshP?)KY0>EaV;U4VYUY;5+$hvL|LhOA^&y)$3-sA#39kPsSZjC6Z+AP zN=P1+yYK)@!0O77Wn~8nl*O0h0KYU8G1L|7UMlZKqPz#M;il4~3O*wnD@nsGNG48o zy6%CD^VEqe-1N+9^U-V&$9bdc9qC5n!GA|`>M1r-Rj-+Hmc`T{6-6K=m5-~mNmEr2Nzn@nlNekhlwOcCC-b9dTrG4;+t&E z$`8$Mr2nylYNhK~_5LsNa?;D(v&CG3v{Md?Oa`q61{%&Z6hy})zK|9hvpEm1X_`lL zb>OK5QL5DtOqyrenb(z6_WC(}CrUq^xv5T5PF5`Tp8}fFI6lr7 zsDoYLpN)3=C2?#R#O4H!@=E>-o4B&cCGjO23xyyYY;UG#q!+?yag5k=Ucoc4im9;vcr{fPe}^G0OQOS)~^jtnx_->f8lu zthZ|+_V~xP-?~kc01pSEVfEroRu5*RRBH?O)G25q8yGBr+LYZLTUX1U`wFDZL{vD6 za|keb^f>{l(;d3PC(Tofl0)JPZ!I({4+u*3FHkOiSSL#EVCE3o8_$?tM7UkdHUolc zk#)JXEeKbx?>22jH?5zy4GUSObm)1HX=m7z-#lkY;uZMz5JU)H|A#5obKL9Q; zJF8zFLwTVXFn7rJKWioLqwC@=$JK>jj$IngPPhM*_a*-?66U~=;M(1 z&tB0_5nS=xm^kjDF18;J0^pBvsVw#r`q#AhPS%wXXDQoyzf9e1dB9?kI7$vI2Yd8l@wnaGXcoDg3Zy9~d#Gb@ zktChFfI~!F7DY78G?RJBJ z%+5v{?FvqHEJy%lS_2DuJ%*tr9tL=5)t{2d2TInDmiGw2{elR-IW_%%0X=gi1siHa z@Ec79=1tXgfnb_Rw#)+cj9&RCc?jzDb^%^6ra)cAPOq1i6!pbp-r#U@8MH^X5Qa{} zLN0gAt)K!8vf%*42!p2(*3eMsPW7yb)?XIqZ!PKErg$2g2w`uUQ6}gX4D`zTCw(J+ zdJObiCy_$Y3#fy=#U0!uNk$KoPD}6eul+Y^_?{Tk{%LhS14U6PHZ=+Vu)mvo)SwjK z?G*XV>%(Z_ncnPP2dk_7)uh&p?`qKnrv{qL7(|$=8N=be*U00Pd5o5iV3$cQfDLQ zJE#K_l%vufqr!yJ^85Ntwv~I&m(52Y;jaG8{W4}^Asa@x`$VDX2c`|!&fqI^7gkhE zB$nq4P?S%uwXRZji2Jtn7BY_oPB)45OjBeL_;B9bgpY{L+_SFfk_}45^1FjCIkB-O!MqvLv3?TJLVn8w%*@FJ<2e)A_6xCu!q=Jad z2LI0rQlACf7@UV<-hxwMC8dn0ala(GHhLv!Fpi{n7)=`!qE+9(15X1C0!+|aqz?mQ zs0g?~K$$OeXrGNyjXZ*S*W?`IR8%P$oNk5%UfgLR^f5G#JLKrs&u>v5rk@ldh#C0D z*D8w43_Z_g?1+KzA{Kb6kJJH-I9zkHCYdIPn3Od zmeva(Avd_I05^+ym{VV7QgR-yibfcV(LcD23XEHn1{llgm^QJm(U6O)4WY?6qmZr` z!DLpakkPWIj7;EupPY_TB67!4Jh~h1(Id%P%;UoYCtZi>;2keP0wP6BWC(1KHS3hp z%_Ej?mKdvc)!CO!HK(A_tM}<+7orOH;Nv3EnPgS>9z2sXrj}l?xt6DoOwaeA(O+9u zrhZF5JuKkLjc5u#rn3o&>}eD2wB z=UyRv6b?&)Jv2^u38xzy>~s0P81Arsv<^?-KsbBL?j;$X8|?apF@8&J=3kY4V9ZS# ze4;#@>-=hV>ek}`STg<*o048Mg}*)Ev!kj&p=0O#Dxk+=2Y0i6l6U{YYU+k;M#+hP zs>m@Ha9KP^#oUZ}4qVMID}x&63rOC(QF7_XY7;JI(F2ySV*;z5uvY6v%O-k-JaX*7 z2+)MzMwc#HR4(ugP@GGiRhTb*?E5_(*4en<`0+B08I$~t!9bi#e|Q|75G_8bCbemb zQfr&KD|9fIIV#bj;+ZmLa3q3FR-Xg6M(jLLh&jqI2+AnD1Prh{#+5L@w^1X1t5huv zL-9$J^6?jth*5nuCd77d_)cr1!Qwp^7Sr1+FuK#RUpRxrdYLGMN%kj)Nm|WlMXtEHf9yFdgu(wPs>vauYofOHJ}Gp{VRRtcQ=Tpx%xm0Rzzu5As>Z{0#5a$SOdn$@E9EqLAqDm}y z?W4Mk=<#ZOeIf1lJ^w7me`QrBi)5F2MRuZ0I(yLS3chN?QX#pZgao6wEEsrD+&K@# z;(1RPM^2uBv}>@_H5t&22cUwflbs`wvc~PjCH<}rKo%36RwzK8#zZn|&grECgfy8b zr`03yg&M^M?<9|FFg`Ez&8gzf$!SCx2K8;h4u;qW(4 zfn%U93nh_L)>5&uF96EJVf8e_Fh=p0aPKT!R5UY;QY;ehEeE&$#g{ZMrk1NgfEGG5 zHZqWK78TohFCOi5IHzZy635%S9SA!z5^4;`QLyY7{4|~nkmV%s#g(uf-izfNOgKvI zi=tu${Rr2yYG2!$FI?OEGU6y1?XG0nYT5Rv#^BXgS>{w5%CAYnh4?Dao}(Sp<(AoI zQ=5>lIiJ4IJpvUsffXM8N4whmoc4x6NDL36dSYpN>E$;l*0$W`e+11BjVSdXEDtNj zq3$-u`I26Q0`EI@0>L-H;eZw8>kL$tTw3*b_FB9eD~T z-VBlcM-F*9AFny#lNez#(y+<;3}t^jfO<{Tix&VhJCbf8i^201Wr-JIdR7r2CgPTdWgFER&hVm-ki5q5GX2I#)*hxNu-ICXsz?H*KJ`KKBNHYG%znzP3O2T2M_1RfC-{hj#gNU;swv4LDwAhu6HsRXkVHy(&(ML80s z(i}IeM;Dd{F2xUwQz3Ehmr6!BT)8U6aJfW%334g<@VSJ2h(cC5vZ-_8&CE@S`3;uK z=>@sB(u56~QyfsY)GeVjj?F4gM*Uw3b*qDhqd&&eej+9v+8vc}GnoaQPNKBafCyRP z&@`un>F6 zu1m|^lKv^8;v9dS;8&a#g4h#qJ9V&sK)XHzj3AAUy)VlZj=7A`Ok9;P+y86|k{VPw ztf?*ctwBe*bB?3nN?w*+y#57UaanLeFAGUOZZ}CaJF_$>by$??q~;n)4KMcBjS7Uu zPD7FooUt<|IQjjTlT9bDhl9o$Z?!?Sfo2gbJB4H%IH@|IDMRj?=MlJ}HEz|j{4ksGsjxNjzqjsl#qKeE zRv^4BBw0jQfD*pvZrX{`QbbH^05-7zRE+OCgOD-@WQ6%ksxYm7wjNPB*^Wd?1y6s^ z-I+Smf2eh7kK-~rSZbPiu)mue^9_ndG-sdWq@5emgS%@|HRtFYKMYTEsCt2rY^&G_~RpDX~bj*(q4dwBgqn9RcEj!9gyEB%CjwK8u$ zQ!f-MZosBQ6QDbI$dQsM6U@3Je|Hmta}na?Ov$V?&IP~!`2J51Xa^WkIhb)k`U1cg zw2L89gF*(MiUiUbteQA;erMcCqSToU-#CdA99}2Hw&Y8G61*Aht7BRmkt8Yk1#AcI zqXL2eZN3d32H>Oc6F?r*!V=UuKi_#$zK);4A;qgk%LYH(p9!K=j6xhfbtY+;MV_$~ z>Bi;hB`C7clZwnUeUBiAbCzT5jaY}V;wz!>e}C=VCo+Hgsl?cY*}=210hpBEu)aTl z@wBIf27D3cn4D3q^GnanGhlPDN=QthCAVhh8t)-rLCi!U0pS+xZTAf zTtr9u__5$`VR5mL>{Lf#aJYko0z5QEN@HoUNQVMANDfM4hXOqKjlTF>x{$2+M-ceA zPX~(bY$t;PQXcn4e|Vy2U+u7D$HySfd9H^s)?cIG6xq^a71^!_(YZ2XPwiGhdk5I# zAJy?^q299MelG!Nx=#m^kToGECLo71(~u^HnvR_UJI^CAo0~3H#GIS@FHKBa^`-6g z|ETvhQIrw|_EU@qvcriOItlLc%OYR374Bf7n2KG6zzFM+Rj*w@G2mcD5Vt!Txj7iJ zq?}7pA~IftVTCM080y`mC5`O513dMDMk$ZrqL@S%(5KNHd)1JnpMIGE~KGayBuN7xxU+1F9RZzGBf7FR5O3jUcBnYazY*iZD6u4M zGzi>j=CS`sHatAoQe>PFt}Mr#oJ$#@14aV1=li9i<`0M6fA91R44N#T97AKFDAs|i zsOBEBVaWP2F;l0qDJxYh@Pw3JNfm{Hf+dzqHFeU@CtsChZQ)-Edt%^cfLn~`NC)(^&!Rtn2AOwv5tEOv287Iw7P@_@~dcP__qvnQrQx7j38;rbwiYTVR7UZh=no+eGNdu)jx~ul8dEOJ$YY47`ox)U~ z?=7jASoYB{uy833NZX^oe|rz7^H~^dd!X6yvRSa;N(H^|hgPfhO7lG)>DzKg(Q`Wd zLj4KA`*a|R>Jzov^%@?Wd!S48DfRTuuG4x~`x+dqd!Q=tExljz<7nSG(A3iXQK0>_ zldy|mscv}Ijc(w#TtGWeX^JOM3nlTyF)6mA$AI1FYVU`Be35*`TA7hzyCPV0<7S0N zl8+=_OhCv`ZYkw|)58AGz-AexJ~g`2PiB>M1vb2GfU*V_@=Ah)L5X(S$TYdiqG#j# zU%~w`EUvg|0nij>wYaK7+-3lym1Ty$m}-WC1#6>CGGq4lNPZQ^Mi}V4z%JKED1kl0 z4uy89%a2X3cyt}@6uY#wXNE>=Q*#Szb10_fpr;dx+VclwlvN2y@~UcRnJ$`T-BNtZ zu4ZS`+3~9GzKz?V1PqKS3#sQIVIbFXXY+kZNcOaT0Yl*b$Jsjt_Y!~Yo;$Yf9ox2T z+qP}n*|GCWvSZt}ZF|S|Ya>pp)Mct8~p8N<3rxiON(8L3JM?*-TUh z%v%#ls;X|s;sH3HoAv8DO+PT@*de-v>hh&lsW0=gU_owY;NwS~pS54|LVf*3vtSK7 zAn3v^dcn?hU99vdCto|&ZHw(}d4##yklT{kn?EeeUx38}n#v;g(X~~_R+%BFfU-4c zNtq$o&l&p4;1!jpZ`Ko4El>Ol%7a`1cV1^3l!rWlA54GNm(3m;%*_}~+CehCKi?X< zAq17Tc*%mWN|^A>D*eNUl8C_>N-DsLet%L4xIVPpju^ECDPoJoA3^Yx>{r#MYeN;o z`i*$NvE6}OaT}hFwMBJ~K^qIkar)S6&gu{+_T?Mv-EJ|JalyUVY7?ak@=$oJwy=$~ zoRM1&mJfJ?m}A8b%~NbqN>`8pM7Ud4PGd;LafrIZENPE33A%rn-jL{rr<}1}bhDSx zn8q9hesN{-fk%3mP@*cp6wOjo5DV2%v~;(|9b%K-pjpq@Z36k8~TBw+`pd|L7O+`P&%i1*{tr(0$he} zb=o_pS$^GbnHYJbpM*}{Djh!ynY}RO>})uYtGmtp`;>`sXJ*AW(!wVz*k&T}_8yz#(c20`z_J~Pfb+a(c;M?X_(H*FbqLa+&KDmHqfeMBhOhAKlNDbNew=2C6Hl$oOZjTth>1 zs~;@7@?k>w`p4`wA5lf#K!2P<+Zb#{*C{IcN*0R4iZ}4Fr%KddfG0RRHf->#ANrA3 zJPn+OPLjMdaPGl5#~(_gv90NMOWFeot&Kr#1tBiMqg(+#KCozfivDB|6u#Ks8>$>~ zJv>9Y^3FSwS3Y6ya!7j%ELX7nsJTZtpOs;UbW-V48kfsoC}&-##4Ey)j8eCdzc|yw z&R9FL5sdRd_8H!q+-aK~-zE;H`9_|@eBwDAf_wv=!$C?JDSv^<0GV5MWgRbi$4JJ; zyu+qqdEozf%(dAOi{dr9Pz+KN?S*Af-C?nmQS#u!BN!!Y%v=uu?tH;D?;dQUcYfm0 z{RR%+6IHpFw&3mVul%HHcm%F`_kxf0Y&1=9Yi(P1m`#Y7F{&jF?~B6)=f;H%iFRH- zq_oDRT&e_qXHDXJ6>;A8s(=@*eF4?voMG6wy zIns5O#A z|7NgwW#X~kPA~bGv**OI5;~o3+M8?5yfT@1A!8}1LtU?%yJJ;epS})(UJn_4_#d4f zHeKH271b2BW4tlw^}}b9?fWWyHNu7B_@QBu1reHq)J@j8^H!cf;8a8$oo%ac_S6`i zc(@#XhPd^p?IE=^{cb{q(u|UztkL*?|3fk zh2p!8O2pj}Z~SXqg6@IvZEB7FInzVo%AKYc{DVhvj?uK!4G(g>e)*f<{HqA}-k*$q z)&Af;2CT27d^6tXz+WIc$GVRoADIn3d;k2YVZMu`ZnRaSqOFkV%1onXG>R9oP5;J@ zt8AobU#j3Qm35ZuA5}Eol?9h8Y*m?+6_rcK{xy08P$?=~#d*n1sp>2EJr-t`(*0F> zlx5ZLDo6jjqMGqWuWFZG-cO+v9i!B=N}(h ziWBneJ#457p|MvH_uB(_LY`P74`Y-&aMrRiU4RnfmDhHuI$%Q;r`l|f*?OQap(6V_ z?hIli)&)}qQm+XZW=Tq=9D5U>W?WT1MCQtjt*Tp{uIhBTaSOlJ*X5mkH<#r7r)5{K zG^A-ar`hrFD?}bc+4*`NqtoGe4KXp+gpeja+dK99&poyII_vv=;<@@VI~=YN!ttmMrV+i<^rU1R;H5|a17UqX7?8Cy8n z+gW;<{?~52|B7oAtG&D9h@*X}Axxx>#2u(-A&(YW5>MDID*dK}FNh_G#2bQg+aIJ< zSf1Bd7g<+Tr{+EfSr>xw1)@c@@LagN;nLmJ4!enPEKx9L(zTFa>1(`XL!UP#T6<`msZG_{_R{IfEpGF)#u zUaRCRJppsoEeZEIbgtt$SDy_-YB^pBewnGoQ?}46(CMO0M2>X(vXdh1r7Vtynt6kqWymMsB?PZrnl)o5!M z!r-p|OjY?ejapf+l6$GB%ucW#;_1!nj?qap>j0R_&?=ja?2bLoc8c8Mz`Yz5LDLoA zb}6}IaxT)Lv^t#{4{`yNj-A3YP?5J^dfkj+l+<@-nbY-TI(-*apLleYxaH?H(y7oR zT{hBiw5#j8qP^v;mzMbqbr$TM(~=;n$}ekZ8>`DMcnmQ#EDs;1!w3-2t7Iz;5h9jh zv~kpbk-?4F!7bkB%)1N&@OQ+`*q-iQl2q%M^+cX77hU7(w15%z4Fe%=JOdd?z=jzK z6Z$`a#S;-*5k^2u7-(-)c`AVzKa_UWUz&Ph&A^T|CJ(ZEfv1OVZ~}Ms-GMP26nBy7 zU}%`V&`Uw9cgw>DI>^;wdoW%=w$VKx{83*}z9zZ8NW*%dKj8c^UbwmmZ!o(_YsZNO zgqQ}f{YM87DGbyGZa4l7FPfes_0)Rlno%Uixy&=LZf>pf_0TH^x_H>nfgOrB4d0kd z?3Z(h5xVNp%j#_ucj(vs!#PUIO*}DOo^6|R_aSJE)bAR)WF3!YQl~tH^Ys{+IMA~0 zVRNORlD-=V+Wfo1sO$FNcUEvDP9>L%$DED1aRweWmueYQ>ZY@ik2_@j@G4`Jb$`6k zuAZ~rmPX3$Z=Aq;^_ly$aW$73pE2Cc-5ewQpwb2LpeBqVq*L@T3g>uMo>;CPtI})* z5K<#vVvj9yxf1jV{OPmmgBglgZl--;YB~9!6qtCR>>U=!iX@?AMfl~%`9&V;ihvhJ zAu1v$KBCMaDsD-NjGRd)bt59m?Gg%1b<2cgX38c(6S8tklJ_^hp=IBxXcT-KVv8rO zleKFM>fpgAz`MRF7N2~Q5C~)kJSU(Hn2b0+#`cN(oFj<}&uH6eJj7bc{rwimrn%e} ziVx#*)5+nNGs{u%=-)cq;}z<50nOXe{!7H?IaPC}r7A3rSmH;kbCK+U!)kH22Vf!TTo<_DIAu~rk zV?m;IHq1dj!2!sJ@{>QrrT8_(ZXQ0?KPZrW?)uKo(7rWr8Sae;%oi%Swel}Q`-smu zq0dwieqoNZOMPNOwR}8-v~}gfO$gEE0rGZBXrDyDEfr%m;&u_-F#LPWKzH3h6gR+Z za?9qQQ^h;mRmzXPVE)G!jpM9%Y{ zh4lX}P$z;2kf$Hebd-m6o>JoHe?~m_Sj{=Rcs}5Fj|2XK`TKM1rX#D4AHW4-_+f?+ zfD2x6chKHEG~Q}%_IA)fwA`#o1Pl?Tj#txg9XT^kSXrmefN9zxOFyz{FjZ;7gKFjy zrIy+Uhi<3gORq;y{A$2;P^J>X7=L2&48zPT_C9P2gJ<7ufTM^zUX{)>9zQsJh7kkaX1^8(6rZS z9l_5N)-2uIx1UM?@O?fkB|YINHjK`SM;tg`igO?EY^hjLC-DmlV?nJ%HSh{LxLiLCm@nR38v8g77`)~ zlnjD`f@_5vBZ-kQ>z@o6(!E%3H>gmp)w&RSZ$niOMqDY+UoNgt)qZSPu8OYuT)(zn zvid&hem0XN!_j}4@_pVq+HClmX^Y3`@p*tE${eugKC^lo6!dpg0{1PP)6Z#4;B%eb zIeg`pYmfT60@OVqSbni*eZ_y3&GlqIVEN|C>d*G%JdpZ^a+ctlO^@!$G)pEQ8E~^T z3`l}i9yzdaAF+xX>#D^km;r{14l}5kiyGF3i~(2`w;Whw$v@vB3Si9rMg&6MX`UvR zMkGGDj}luRtmvQH9ZT-jA(l^PusK&*3QWiyO{`wBc>zlUYrFE32d)l@cT_Ru*xUF= za?#0XyV9PU9eiFdmeVxPnsecUT#{LLGRBRNW{X7T5R=;RAt{quuXK)2{hT)0h8&Vz znsukpfsP zN7ZoYm_XMs9Cl5zT~Vd|IC$^{>sKaE7VGx!nON*Rx*28`KIL3f{9!JM-7&GolLpd7Asswhs8cdviErb z3PkPU6itqf$T2k}yGQ2OJ8+?|_39tM=_uDu$!{^8ZHH+3)x&7e!!6v#AvTCYndr_v z32)2F0gQX`0o%Iy(`E%rX^wq*xDcZ+iBSxit!<_CS(OgD{b%(MVcR|d=}Ja)NIFAo zyxVuJut!#)<}J+{jmLYGK+vwSP66bNkmZVEu$PE{)(s*1mO9GQ`UArt{h| zxoTAF)!jY}oCl5h({v@4T^>6c+i5E_{v^n83}{cKY=6s@QWsx}6!pEKso}Ig1WP!B zsdVrlxa#rWS*`gOg1(-fn&zbZ8%dFCS&G2~HZV}8N65xhY~zeX-K6^?irz9Q$~|UK zqS*z!Zwdho=|-RD#9b<7QMtaAMzNb=1p?x2^ydh#T!UpTph8tLBM1gLTA*XtmB<+b zIYj&xa0Uv&;at|F&1=52!?{U;&l)^67IkbwzH^2)mFg3s(-wfC3;Sr+S7JriyM98k zD$%h`NTniya=zJaPC@G!%%&Bgk|#s0MtvOk@wteI9_CGrYu0^aMcZy>S-jpDjesuB zoUbRZ@8*C$=9(}F7b*b?j6Yu1Mn7vmgHoz3TB+yv<(rNyj2VX1orHAz z3_fhZ0{?pZ$ed?yuZi?Z*+NaZgdeYrOr5mqOIW_wgcpq>% zSI72TFW5OXNB6GXaW&>t_;M_#55jNsIqtV`@L#FZJI6S#UYWT@nd*4!WUG0*oJYp0tnuAPBrrYU~1U#MzN=Rc89;S&O;N>2ixz}!-dbSH0! z=*ljAY>Q_>#oKs~yy^GXfMA08S3^IM9{?IVm%H?}FyHAeehxw(!v_Vy@++gC&I$R8 zBm_U$=iLJQ7o*JZ%;`^HUhc%)lYK#F;6W+6l|5tWEMVL~OXnz9PkXDbwgU`{>Dc}G zt_!e4MK`|LV3x!F9HiMm!j-%58Uea?@en0vKTAzP?iH=Oy|jD`;jJUDNf4r%i^SkCA=A%#qRAf)-xAa*yr*i_d>O?5lcSv4es4bh@jZ=>Pep=`{ zHCK-mf?-n+E8@ay>HG|oebg|KE^Sz!Kbi288ma|MeFopWKi+^bNXi3Xjdwy)(A3w$R=sA^Tq#5Zz!b@4hgKg-!{207 zMS7ZDs|r(egsa}cSH$62>H5X6=Nor%uu6(Ogs%_P1ZcKS6R_{9L+tkSj|{(Ash+(V zW}$?8$}{ol#mM}-4LdSQse;7$Y!v;nDme}`(ms9KYW9*?sUkbLBL~_<O} z8qz>44)!mTZdh6@jSd|R+|Ky*2p1_u|MYJ80j$M(aaGdK36DrUMhLP5=)N-s56L~? z59;y{T9Kij%Ceu}M4b6*zTlDg)<=nSns9CCjxM2-O4C;tDfG&%n5B;)59(m|(PCXa z%(!sBm9Hxi!j12CNP>m4BIe>%T~4Nt?c;xL_S^5mTpwf6 z&WGyi=e5hcG^y39Rft)a;NX^;N`c$4t+S{uaLO;NOnFf5N7IGC24igRWaSwOt7Y?P zrp}zI`SF%Dqjn4k8woQSXpyfNn&(;CqpHbXainSV)n@gATauy(PtkUVPtDrqY(3=YxuiJ5DT`izn_f{nt+i8Dn9-ZApt}kK z49qMIoaqh4#3r8nJWvzzgY)EnCQa`mP|sOtC5HF8D&Ku(IV6&osK+>eU>y zfl~k*3+zIF2}W)#@C>nwkA^)X;VYr?Ub7@k~6uU8d3RE;M_1tI|Ap*VSg@=w)qZ1-lhX5) zrJ5<=p)F`}A(iV&U09&8DxrMk$X-}7+vd})OQg-8-MlgH>YEGInNtgA!z>&HC1DbQ zpjK|LIUWeOO7#J}j39@h(iVL4lLMXI=06{PE$)EH;R6T^M~WFf_||KTZ1C~&!wsf+ zS)%bv#03c2i|ig6QG@XS_{`A!BiKi44Cx~*(3@T%Efh->dLhQQ_)a%^P6pj1V-n8e zw8RnIBWVQ)#Dla<#gl&NQd!aW4JAKsYko5%h}R(EFPhCuK{gwO2Xot=qw^VVL^l{X zq)-#yq7Y&6psI!?W#XSSY-s0!281$)+-OXX6vT>E{yhAmk%C$(szP#xEHEzOKggGq zRG!GU7JmWg@&(*$3$o-E?h4i9C_=5rt_zW?xt{!C^6mW7pAuk{NZ8_v4%>e~y^>|S zljJ?Q{Ki2%#;3tKN!cAIeJ(IJ<|W&nxGjUsk;AN`0vW7cn2x*jeNA2)%-Lh>aIt;E zZRyvTP$p%=x1jivA!f1!PJ~4<6o7OkNL`R-?|djul!j_?Dp7ws_``-VTM+%)$MRBx znwu4mugm;Iz*z*83*vtO9c+3ld0eOB7LeLc-NozT6nlb5Yuq|dDbqv>ZqZONIQTD!31_)? z0SR*gtRC))wC5^)_S2Kz`8QEcl~|Cfj7&A%8E}#X#%&t z+DhNW&-kk4Prn*@SJk`cgV^jGh0upkRuyXtd|)+D%d@vCl0ldfRuNn{J4i+=G{9D1 z)GmbIR%jiH_|^u3PZtVh8?d*p)-Hyks=|Lx|!{RYlS#e9T zz(z!ssUTkI?pu|W8CW@04QCNm+<*jE9(HWUrCYBfG~yYx++dLx3_?JN0nmjVX$A&8 z5wLeJv$7`qQ~@eL!P+yY!qf>^%PUHYM2;pfz zlj()>j*e3x+@9eQT9D~Rn=mg*Gz`|f*2|0zMM+kF*;hV@`Q*Iot=MWBvo6aY`n>=> z^M}_@n%H*O!<*d}JT?R$S|#unSt>D2@uRa4pa<`{B0SGbXp94Zp0$>u_Y9Nq@CKb> z94+c$d%W}7lzKLdtt{^~L`!-Ceh%t!eky1Y^%6XDm7pi-s(s)pZc+6@Iuk9%*cgE# zn@GTj*bbre18Mo7jV)~Ho!k&;cK_A<4VU7D0se{?@WP9E{miiX-WbCtu>D36c^lO# zm{vAO7t@1e-Z^37Lx#z(ig_K?&`e9$?-qPZvJ5->i4yUJRp|@7{1tTY1-;A%X6+AR z?JsX+XqFAuQqB|-%1)S~cqO@AYwU*6%Ysu2>3&;@1W8NBL}O(Dtv4-X(e5U38{lW_ z7|BRDvF>eQ?z4t<%w(Rp=Wp7)?~~QG%sTV$uaqdzVjH?Z!79TAT8xUP7tVfO!h=2q zHec|F54_47F!VS3_z}Hgg|8^Bgo~hoa0>G&^6unPw&+TouB9Q?VaK2dVq~2zLy2O} zWsoEonA4dN3YgSbsRJ>J3dUch!PKOWov_>3&bBp{oQ)=sVQz#-oHOzHlUJjW;%6Z! zjEC7!Q7BHbsN6Luo{0jaUO|j_fDgW?vID!MhO~|~LM~my;9ko8PUrwubwfXmqnPKS zrQ1rJ@9sh2pksOYo+HKK-6#~Ij0$TJsv&UO^KMHRhczSd$ca!;beE{nfV9$@yJSXh za-w5=Fr=~ti4J+6TlJV5`duq(Q<+UqeCw(Abn!5!zP$VNEr&VTG-WSm=x4Suhw~jL z0nt;8vr&m>32|e`8Pk9WHb^T=wojYm9oiYJ3h=>XpyTnpN3MACi-;4kq$cSy#YYTB zDg%oL7J^<(orxY_3IAY)B1pRK{um3<<34|VUpRwb1YUDt3cOm5vas~ghJ(@SH{}>b z9w3%C_u?V<|X3 z7X(Gj?OSfi+$I%aa#}bnQF%)rot8=2u)6Kj^7;Z$6=Fn1R{ZkekR&Z-SHsa|BxIyz zXF=o#=z*I^ml$Xv$fP``o!`9dHs3Pf-;PldenRQ=2V|CFt2x|qBDL4S0-e>BMy8l@ zytq8USr`UwDj@K%Q&^D2^B9Cs3%am--|7ZYnr zxA8!@>XOs5-iJFXd94tSrMB!ko@O2Fsc3z@PJ z;@8oImjc}-;tCk8u_t`Ov`eJK6ZgDCt8ypv?uxcjj@3L(nO?l&m)u&Tyvq*&==Juc zvraSo+Ytt^yzSix53JMSX+{f?#iuSFPCow_KTBjf@Vtx&Jf?D5Z{0jWLW-A^k5oLzHlQTt_ya? zFLhd4C>j?!M!&uKPJ}sy9=wjwG2%zGj|rCxHMGW?NfeJU=OeRFt;j3z-_)O65SdQ zaTV~=6p{7UMvPs>@)%HxGSeS;645SdkI|*=s~`0G=Dv6H>c01&yBd0dU&TENy&L#a z{)S^7`Godz%QL<9rWL&oM(X3Rno@f$f-pz7o_xv~za1po49|XUVLtH;hU@L{e6k1C z-du<3;@*1yccRD-VtWRO_UdE~@d4E`HN2Dl*yV5z(*>;*4}X1K%vym;|1{yseqdp* zn;xB8=ktq4Zf>D5{5Wx%wsE0;;Y@0F{%mHqIAh{WX0t)iN`#q{F9y=gk}cZvUH2DB z&;sfxyM;+leui%}`qMAnf7~x?&zNTXzx(|LVc($|9@N%mW>;%kC;SG)|GE22e)W?7 zllK|_st3{yOtayfGZ)4YR8G7jj_||g9jxow5XwWxIQ2$s%X-6EmVnhCdLx;Jt!uCuSRKksYw{Xk|T?M+yAbFlui1uy^7dn;qrcb^AkND5gajG(&M(DHj-2 zV^D>b_pCHbk5W<|Ji* z^oAX@+d;EwL_rz#XG$VWI7~g72VURdCT^yoJrJqId&S5n9tvHB1UzQt7=b!a!iJLC z+ANP_tQW{~L{OTmGf*;(Z$94))4geb0jDTV7)|Gwwb2zNE1Po6&C7C(4m`W2KEiG| zktT$l$Cwq%u-SM{2L%+Yemg9t?Qv@so5M1rg>(jiIg{et@QfT)zf(Eo8kVOu*<>f{ zJSt26_LfU2sNW4eSd9x{CiUtAbBLRmbZugR*+(&P1%na!G_JQfCN&xPmtDkMtthZX z_K&+w5c-E$C&;XY+8H4Xoq3ZK(ij8_3)KL9)tkal+8abmSg}io3r2?vl^cY6OuDJ; zKmY^19agoA$D?qQV81iu4ZRJ4Rr!VC!*^w}6>)3^=?By#vM|Dt;M<^D1hcI*$O#J2?&V#L!c-sVU7{|(v^^2!KlpqR-&ToDE? zt1+LFZHO4v5wmaT7^)vz$xqe!R16$TD{G{4)~F)VL}sQ|B@X2urGejevuufCb@)h) zE&+Nid)*OUOMkMG^Kt$XM1#MOB>9_W?YrH$$EAUlNtJQ@~xPSb-NAKx3V&K zFth$$Rx{I)w06H-JiQ4NmZMWb)BxK)yW+5P_p#vA3Juk(%TzLHOE|KPMUDWm?<}iA zgFg`A8&MIu;Dy)?`M9^}T%6ZvgKorExFaZ0-26HElwsz@dai&4cQbTdl`mRBbDV03 zKfoD@5t}*^#|T2patnQSVRLVyLOX3*eG`06-|>_14H8UIIjg`QBMyQq6i8(jLBsML zs=(O#ug0)@BWhlu6V&IWbwcW_FvK3Kh=qC+xF;4ZkSOaMweQ~B&2_{wir^H};hTd6 zTn8Du6Ahu(?rP3Qw}WWu%+;}e<$QH z3fV$%w9iFamEz$ZzkK%vbx?503#y|5%o|1NE_WvctRcims^pey{Yw*bcl~vgy zsYv7lNfjq(4YD+rQL6EQ^|X_u)n1yhZ*2)!F2y07zvRa;pUYgFcG$a>0OF=!BACAv z<4){SSroWHxRdsNxISGc?tUkmKO;x}U!Mo`ze*ijfG%4x#UPZ7SkOw2lR_p80gj|G zEeTKuR3!s{2R4K{(TBOykt!OD4CPqvjqC(1=%8+w=d#k`ufT?Dhn0`8*E_PR&&Is`>vtKR zB!`UPLipQO%c-d`_ru3K6g7`6xX|KM9EjTQ<7MVg_bedUAgN3=&5Y$e>x$4GVlqbf|aHX0ZqWHqV z763Act7);Ob{C5Kp<9j@(Q?d)u$U{(Vaki4*0Nxs+%dI6S2BkhLOL?o)MUX)Z80~c z&dY6`*AwshYR&1XUJ0nmi9Qlb$CAf*+{uQJ)l%i#%-5U4 zw=5k8q4jzh!FWA11u^uLYJuAgq%O~-M=5tT{v@c^h6zGt2L1dk8(qM_Fp*`zL^qWT z`qXyw0S0(D(00*n9N=g%``JMU98`wNeRwg{5(e3Xul%5YezN3J;|}F%ZY}8?4zmk@ z^vc5x)1}d~O`}skx6n#GU@7JHUn`s3TVm`6dD^@_9yM0=sq?9OsWoq>4PG9hR+BAE zXr79rG5<1e4lC)irF6_?lDDgub6WW*jkmfw%%A+Bv7w9@InTtB_BIJ&7URe=aBhpl zho<&L!fFPn2a?@hX3{q=DX`G+jt?^-(_oiSP}t}C3LUr697t#_GSBo zu>|!FNFi0#&e?_6S?~-z@m^Nkjw#&$;6f?I84)PQcMQk=OZj=f-$Ygzl3R%W$gzL( z72lyHnST(N3WarFBakA-+K_xMjQYjRnw4W0f77HbQrKsuolB|SfB5?t^0%`?76IMo zz$_(&VqLxT#3K9#gi=M5d4IK|_=IlU7t;v;5RTv%?OC~!ZR(31xQMD;6?q%rkVA}H zcm+%c8emODcepjnAbhBqdIfz1`9Qed>Eb5yi>Z8pqTH2Aj6E}u`yVsKtEGEPUYrgn z-k73xfQB*1NGNJ?1|!|w&|E^!ty@3HFRk61C8~v#>WYMX#!gdsE@=%rYa7fJi${c1 z+Y=Hk=ORW!7TujB9MU5u_6$0{Qm4fz0o{!*X5tLAnqNiX$mGik*cFMonBqn<)jvDL zht`bsvs77F%lK9<;CzxvB7egZ{(7{l2t@YSB&wnK2s z`v$x{t+LG(_kIXLk! z%Z}gm4?V5%KdP+g|FO!7+PVCH6jt?rDJ)`rTB`u0!h4wp$RUWvIuSG~mFz+$G^!+! zHh`}Fq5 z>q_(vkc7Vcdq(nA2t?QFw<^Tj^dA1q+Q>;)t*3N8Kjv*jBxc8sHIVr2OGa zgw7fp-%7*$R6}3eD1x4s@mZ$GW}REC&z;uWJWg=JJGwZDg0Xf4RyQ^6efiF(>>{awwhxiorgF1RNAUr#CAXyo?{0dd*`dL7;XY&}LEC8)Z=fc<`zG6V=jO?# z=(M%J)<(azS(7an9ZpEICUully&jTsE{>}dn##vmwW2=AqqzG#ig%*S)0%{5qOR=x zT?HFU#y_o~M``A2{!zqo$+f)ykydkJlz&O+HSU9A?N!ZV`f2OUF{Ur|XNKy7Xa8DD z&nU_892O(>nR?OIU;RZbvDQwj`G}t3Fxec4duUs3h} zp*z4%k9%XcVXC!|VlVHGDz>U&78-JnHyo?06>gZbisvpQNpfj`CG2V_aSX~2!q9}< z50{pMwT0qJtDYCcmPB5{$OTYWW{fI{r_LxrnBuP{@u3NqckU4~!WEWiAdy`n2bXvD zf~(BcoiOp^WJgx=S+pt6DGW2)DVTX^r_V73g+@9gEb{N{K1Ub}!jJwgAT;OBO7|vw z65u0y0VO*j8(jvIjNQquJhRbqCIR=M+0 z*0UIo_K+TH$$CTFCd5iw_)9Vso-`oKS!kjYN8?%g+aD>!GL9J#pV%y?hezVQFw-}m z0TMEA3~~CR85+N^PCWI2-2P(va6|pD10_`K6x~4t|BevsFFS5#0PMA4JJKYbQaMA;rTPAzu*+9~w`EY|N8r^?KCc)27i=aE zhk(gH(&<>dLTl3x()JMqBweg;GuYC`)H} zv9f-L@($1&KtWF2WeVAF7pl-2Q~i}f%mW!KH>htReIIM`28zZR1jh#%z9;PZ1pLrF^|tffZ2(N zxw(ShiHV5YPut`dL2bn$+!_K*mmHIvEplrAKh;P>_W|cejY^>YljjrpKUO0#OB>Vw zZTFf|^_4foP>14SSHVSqK_THJv-nd2B#FWk5T&Gmhb=8Ai&+Cxn=L~dcWrIPh-n8s zue|vs34UO((+>smp5x)?57jgq^@&^t%4Vw_9a^7PYZb&b+n@J8*xM_E8XT(bBw0DO zta?wnEZQ}jiQ^0WhdrFNjl`)I-qy%#WRJvN1ZXbWu2EFj>Q4Z{xt3tdQ&YA>Yg12t z{zz@KC>>jyP9n?Qq{kUPDw>YL5i&CgB z<-_!wE_ClEosP|#EHdVnwo(3r>e`$Y=oCCK5O`)xev@M|>S#1I#P*;9uM)TsI!1Aa zW2$tGh8$m6RM$QoZ+VNWf?}-ZfyT{cFJC;;ZjCno4L7}cvET@2*ZN8EGn`bl<1n4~ zUPh}dfD>a*b35vvTEn|Sin>AaFeQn#HZ^GTIsWtoFl(_PIXxlne97f3Cw8ZrUpYx2_S9Dg*?eV5i7 z(Ee7W4rR*-y6bBG(I?X$TkYpPm{LOjQFp6onXEe5`pH*TySm5VeL82h$E_f9AA)x3Wxp~M|XI$BlrL*%sM707?{Zs5Df)2VQ3$eYcZpl+6xIN;7(x89a_b7Iu-O$Fe}Q#CG?+12D3vNIGO8*WL> z`V|X*=s$*H{#=8zi*zAo*rPnjop)y0#>DT@J;P5%kGOU^*n6!Nn zZ|1T)=jZKbBYhSf-`PmCM0gLta7>rckQ#=3qj}G6+4t~$ z<7>Q&gKfllby3!ss*YI3RCHs#X0!yO*LylZv)7erABaALqu0A%(SP30XMs}W z3;DPx-3C=!lv@}Tg5aWz1C-c*N19l@L2i|4i=Rrm;uc)E$2&>uiDR4wquv7IwgG`( zfXF?P0o(S}a>UbMu1izQ+xxL?-AP2jr>i-9Zi`eKDQ2c;*x18zlXHZJPQh#YCL2f2 zyh(4DruyMh{`_yb%#5Op@bqWNO!;#nr9!M^ID__^#PG5dqDU~FJ0utqIcQlxiF+I( zLU@cy>I>r9dpcG1qC>O?ZXpFQdi5z(Y8)jtv8ZlOuEv~&z#J1(0Zz|{EJliB(BA*0Rn_!)u#EFkeMhwdqiEj7u}PNtsHJp^Zaez>CvDl;CRTW(5qY|N#FO?blHnz>0+uBvxRM~e^*gR^nX z?$o$BOE{QgxM*rAic(!jH?6(NQ!4|9ZVviv$Y=bI@)4MdDdAC^YeSFKNL$lElc>ro zsMLp@hpzU&ehjpf3V=?)&uWC0#R6LA0S((uWtjFRl%^y6Dya%LE7phl<+7!=#^lBX zoMeXB*6lJ@#96dOQ{q@FQr_x9_lmNeWZiYj^)eMVY|_$&ztj2K(||)7D>pV$YYNWr zBxl`q&-K@oN>^(P3yk)r=*DQuwvb(2DTU>^#^tugiN*=tb+q+Ai~p#s9Gh_1ELK_@ zt((Zo>vNMXHrF55;THdKmAeynb&VBoRc`Gs+PPY{ShjRD!mW$7ELU#r&0e_(Ba+X= z7w&XquWv2B;d`~Nlx>|XU#+kyre)=fE|~`JP^X%ChHt616^d6JR_~nlPj23BLHixRrncRsE%u$v zC0^+hLikfPj@{CBQNKS|qkmiDa}xr^YXZYN5-CAPlYFB;cawb1x;gx%Gy7(RuVC~C zsq8;$qW&7nXE@Rwr8_(z81AO)oOJ}bOY!pu^3o?}q&IrGOMdvv9yqrQG#-e ztCV4_Lkf&B1_-4lpsopWolZ5%CbOtLC3B`kTTwJY%t^=0fOA7GzkPe1GrF9 zP^ry4M7q<@5F1VldTF6Wk&euinMNq%3f7&=+!+5P$RHJ`Ocr67$}#5ED#pS7Mpvj$ zXy;88lSdZCl^50wNfOT%XuVk=j{3tc0(L}23DvqfVMIbIz4_1dl4G3KHQJO&q78*o zQ_fcvsl5U!lvPeqdWfP`58X9|8;VjY!~&?FPUal1u#Zw;9jtP~}k`R`DMoFKAzw(O9#4kRXNoOHJIn5Ud0-)D94A#iDHf**Y$rM^s2 zM~IkvnQ~=O_{64!Uz+k2v{W^~U7d4ii9%wKb+NCBrJSr(Lmt%w?=jxRy-RsBKr^Lq zUySNpoYlT?b1J1HG=EcSwJla_M^3~AH*iOQVqJnh(^AfzV=%`~jr7VXx?_kpg*(|` zQ~LU<=+Ljc=Ld{fVgmDrcNbNg*C@-P;Lo<)P*uvm-!BMUL&6~@DT>TP#3|k>Njalo zMrq1C$B6MASYs5;VmyMJNgw-?Qn`gD?4;fimM~>o`jE#9puAb5hgk6*YCI>XGbo>3 zKb_q~hIiztC(}}oQ1Evuq-*_15v{Tp*3uW8&+aQ!fA=VM$VJru3qnA>ze;i`QH1^` zC2tX}zU>t6IK@Al;$5eB&nf=t6#t@H?^E&t!TykvkDUBmr}&tt_!H{=-_-t7s`Hss zeC`xq&^modZ@zMiuf;b`@vT#Q=M>-5oPThN9|_1$)aYlY_{AyyL)rg2#jj5Bn^XMm z6njZSJnfX=l*}o)Q)*5ru#%M6iPRm^LBCE)Tn_0*j+Gut44kKobIN#!Oh6)#iP(`$ za>!(dOkt2%Jg;bKFche$uMMrruUS&dz{szu350U1{NZpQ%)o;+rUk14^wJ@_;d?B| ztEsoEd#YCzHwNn~mX*#eV31sJqJM>dRF%JG>8RrRP_Sm{LHO3B;t5@YVghGLu`pDcE=4A@M>boHwIFd=AmU4V)fFi4^zv+mSDRiHjl$zULr zmDa2Xgs5qta`xhIeW;5DE)tOb(UA?L-H>aW^5XOh>Ls}}kojGd+TkoF}s-=?J z5Q8!Mg;hJMGPq<3L1^2?gflmAQbQn&15`6)FkpXhRC}y~%~GmY<*lp_)DY6<`0Ht` zIGdD(9Z@i@IW5<;0MdB?$2qn$bI!LG*=l8uG(TKWTd{n0&D21(zXsPuKQdSote?c- z-QjW1|qk%68R;eAXpP9YN%cu2$lF369*+DO8iyx z{GlK{TZN*2Suos5Ot<4M#Iy)1G2#kGMN=O?@xp%i1edsykdhy^*+W*Eq?A$@3WNip z6@khKwP0;meN>7$LJ=9ZB$h~wsx~W~fc4ulT+iVn_Q!GwQ3kgv$NMWQW16EV7;ZL3 z)*w_*R4A_V)0pGizA+oefWz4aYYq%-fvVG{O>(UhyocPoyFkrLxP|b z9kzC(fCvQ_H`LQoB*d&*p}&sgLuIXrsywrkO~bp!Hyw=pPtjTjkOfG%igaXP1!9Q7 z;QiG#`^lqP3Z0=4N$mYfEvidZ3QpmVp*`N(p-FZ zouAaM`JkH*NGbKp0>O~tzy1fACstn4P*pWYF^Q=0SCgDs9whGE@3gUL5z4JuSc@ch z9Z_;^LpX+B8$wk$oE1Uj-D-TSs$I(9utQqyf?85CMm@4wZf(tyDg<=^y=pE*NlfLb zfpA4AXrpZC0j7d_vn~*-4+cm9r~0c9m6b>$C2e}{*IpR37bnhOxGdLXP8P&}`B>zy zL4{mTB;m5N$SR33tWppR6XocB%Wz0SFXJ8$~L(02E)Y-i;4SYFHxpQ)vAbbts`xO524e!sycS+C3rLZVFj>I z;km+Zsl6k+XzNW}sC2HORM`wfN)_1|hd{ddHkVk9ah$y@U>y$hw5|@cb6nhp`u9Fk7TeJcF1I?LoCm%??C(mS5YSc9Q^2L^+(oCYjYD@B~Q?*ipnI{1J}IHF7m zTwHA^xHO1Uw3_N<7zRxkov{7YkUZv;tdYkB%viu2OC7TS5hz&+5dzIT0PE!2Hbs;o zQ2^Afnii_9Hj$QSKSotmk= zsHzPI)Uu)vL}MTel{8{)Rpk_aI55W?l4CLE(eJ>8#TVq2(m3#`CeRptO0adiiKH+^ z#jFxV2v%X7U1&YK)F8-QAenHWCCNp-9IUq@SZ;F?CcQaOsF*qB#hKY;lXU1Ix@dDc zC3Oyon%os?T$a(|udAzCRf3vAMU5B?>r{sXM<*=j7bA;BM1OuwT|+%q3HYl?Oi_hg zGGW6F)uyRb<*y)F6xR?Aps>Pm(W=qHMrwJeQE{lkVoZ7}sjf4h;_K~k<}PcfS4iSOjj_9u;N)*pjGXiJId*f6iDsr-%P|(Al}fQhekg zm<(GMtY0=G7&d48=ASg3KRD3;naR6tmYj_oKIM>PyiLXJILd)ejY%Ek-jK*qB3qHK z#1axEWZ9sor5Dt1_x*8avOPMgNua2i}ASpN2hL$7J zV$0&I&~~avXVEmP7_9Bc`253uc&AorpFo>l88$5&CuXc!8JL}mj%e5t>QVd9G&v1B z;9$N-S9V39DqK2;M3Bj-Wm8EPShehpi%2tb+2ZU+t5=WxtU^l(i1?5nbzU8+ccsn~ zBCzdoxQL^y)(*<6mZ$v@`{<8Sx(dE7v7Q(-bulh^Z~^)!Y=WVsOXMA6>8}6th8vY9 zf0n**l7(pba%f;jxji1AP^m`?+&C+1hY1M-yGHg76RFpt`Gk6{CpO4clA+Ax))KP; zHchSQxZI)meRQ#X=fc<`6M9nhzGW^7 z5Eb|r2hg^3hbVeuJ-CpA16H2gb8Fy{IoZ9N<;fKt6vhWu)**HSmA0c57gVHRE`a*Zn7+FH_J_1F7`uGwSQ@_LfN&s%J!u2PsDSKh7R1p@Z6~FR#m$+ zCnnZUjug2&res+hSyNAa>+O^$M zJz&k;L2h+T1G<*JuDa7^^g*fE!J|iyW>D1?(l|uxA?8#8Ux|IXidWUtFALNME24ur zj0Ur%ON06UIS9&E9!AL+N)D%FY;;y*XjVsb4aKy5Ya>Tt=cNCIrD}gx$8EZemOg3+ zdnDn*V4tvm8=SLm41OYCZm^%(F9z56O%9oA$nLU-!M?+HvZwSK>_hf}!QQ9jOZJt) zer3NI?0fbNgVBe2vczEjVgEJQ?`*HZfir`BL{L9wA2?($L-v+^9I~$=`^o+cz>sNj zfWdxXKjIu>cf4wr2P$db%V0mT9}V7(r#j?7L;C@1^X?pnKS&OC$RUOtDu)?zI2Owh zm}6h#gtXpTAA^0$J~L!G)ygnrrpz+rNSvn}B}W_bFgeDMhvO9GSUJv+*@T57_)tTR zXJ0WGb+BboW5jvS@Q0VFcv3Rf@u_&O&)%?i$O(q@$%zhmq#=)zlTbrOD>a0w40$yB z04E(S4A$80vqMfcWR9Fd0C32;aw<7TFv44LMuRG1#{>%VXqRLl(;tgZJTm4c?FUH~0*mZ}1+xr$d$+avoo6 z$TGgxA?F*iTrP0Pg@!zq4>aU)@_0iok|!9_FBdyxg&`~X2@V-BFph| z#3AoANG#?$90dsBF}yadiGgLvh0%Hj^CniGUQ{DoW?e9l{w#)IgFt>JWe8Kw85Vs zQS*d+(%>WcC__FacN=n#ME3iOd>Yr9ruhsd&r=^P5TFlbY z()_7u)xofGf_)}vV)T6mn%3wKr>QU)4zjkPK8+S0@kP2iK;f1&r9OgYtg;aO!bnS; zNXKvwqqmi{fiPmdK1~fFEh4Zj2xF9lNsQWIv(=Ii%HL!#uM;cUCEUJ6V&rZ1jYGa; z$bS&34!)B6rCL%wUs_vAkrD|%Nhzc%<~{PH$Pul9$QN7mWw%9j?b4^;1qgkU&=WLw}=Dm8*L4VpUa z8-ArBzm?xPCkmUcj(SG^kv%lhVGJ&I&?SEneHJ) zf2E-ta-3~#S-W~+LyseX@u=1H1WFS1BtuWuQw+VEp30zCZf!$VWzDd9B=fX7E0UO| zf)l8N_3nn=L+@$mUcHy0_eQ+yeGt`pUoxSd#(C)d^!|pPrlWCsH-Fw>pR+Fveh zxtD)s=mTk`jzR-iA7to*^&y5nlp~;FlnmEL7cUg-?vIozLdW zOyp;jA(d7Uv7w=7>RE<963uRX6t0dwT0hLt$M6Rj9Nm?Gea!Y9s-D8B<51}9ha37> z9bsqdM;LsQKAw^Z27gfZ8T?V2&O}6xek6b0;M-{+M-gup>^r;0Wn`u_kWwMJbD)Wu zyJgX7@?HEpL!U&;akM_!&~x-DhMp_0Mo(|#NJF2h=NbAmeL90-6tjqsf6!#bV2vVt zE8?UW*3f6@`G!7|7a0019g{+3ofg$%+mYB(aVoAyLro<$w=Ffj2_Lk8WfUOH?@YN<$CmOALJ}l04s~FQX)gHl2Q=p)aS-tB5nJ z^$84yBUvq>_|u{#4K)=?D^vx|MN-@lSY!s5MmqEwL$B5A4E-dMhanwjQ%^|)v6K%j zSVWUL*VI;Vl9}2VtY4P3%-oqI!p9X06HfhvFhgHKsAxoa$ThUx^p)sA>#GQA?^vi< z6?H-=khVBfyPPi6bZ;+(r!>%tqEoN0HuRH8zMewKsS>5)X~>3%oYM{c4D_(|Gxf6^ z`q_rQhJ8NS3)D^7hz)G>0JJy;A;hIvU z#L&-2t6E=6nzEU|t)ZJ*AvMJ%$RG_kLxkBrk`mdBA3nmDX731%q=2>>%~5GMn#|~n znn2@}n0JT8zH1x8r`KanHS`N;EIEfR_uGj>bcWkWxCS~BU?YNj>iSS^m7!lq`t>5h z!dP-JOz(GPprWDPyg;G~Y65}Ea2D+fpzB8k%LA)WR91#<&01TP6|P@p*Iyp2_f;(O zhr;Tv8dV76c!PfI?qdBCL%)=gZu&Yyzf8ZJ?x=(sa6PWzCmZ^ev?y26n6B2ZAtwtd zj}EWZW%+B!&+^xVtB4}x5;WWOYxO3FzTV(JQ%uA$()L~0ND}&r0NS|;?*nE$rSrJ#tVy{NpaN&t8uXY z>N-M7pgt?+IVIYF_F2>`9I&Nr+IVMHSyni>8pm@pVd56T#H2sA^*~H_tD)aUS|#^S z*a{$cw;TEfeWRf(_Q|ry&25oeL}NsyI$G3ji(VOwIrKr0ToQ(U2SsTP?_^xR?UuyE zLptJ{Yew-S2QWKhE_Hynm|LC`x*Xy~K3W>6k6srXzyCvJ2Mg`TMQ#h3+pgX0`%`T% z>m4)zV8=c4YAR|gu}vvHBO5e?f~o`|5AEn!Wk-GOH>%veFEZWCesq6bU4XWI$9L{5 zT1VaLfs;^XhTEP0G+k8{*N+K8NAH#49O(#CO~o=IsR@U;5V4o3IuqL3w;>7+y6L43 zcO?$r_f`psc7IS^#>0B%sS4}(7>zp$rZXX)eFzAJRVc6&Z3w#D+?GEYyL@)^53r@$ zDT^nPM#Bb0lu6T0EU>mIXLLXxo!jBt=TwbTT_;rc83!HkP^W!4HokgQPW9p-9WyqY z8NqOVB(SdzsM6_tw2Wg*J#8-XC0DPSv(Ig*_~?`hYDt4Q>ub%q5i!r~klN$gT(`r{ z(OhlEJ{IYBzzq8qApmuZASwE0N^LEz4XW*uxutoi_6qiSH&GoF$cfx?>f}jM+G8{0 z>(;7vc&M}OeZmD@TxC~8KAN0n^3K5h%d#l%31qw~^FC(e46`-hsry{}?9$-+AB5;| z$a(W~3reTvk>%xIp$<~1^J-$ax;{)ZGVkyVJs=6k+}0z6m{&3w3^-sT^LF6y&K~c_ zK^4!+pM#`XI%jH5N#3HVc?EeTd7U;66sT!_>ujlY5X3HLEUuHc;10ZXJhSt+75;e5 z;&#_P4^U4XIGRfbat?N<&Ax0p@Zhz`R7IV!ue^yVRdg`$K$m6g%R3(P){O;u*nXSD z4pSW(M}jM$`=5s&qH;BFfMy)Ry*BL3Cc6EhCx$$bV2frKVcocrxp{eua%UG!E6C3+ zF*&~N-8BZI_CNUjTz2c+z-{YN)|XxD(sf?eIodicwr3 z2ooPu54?p*L~4GBAf>dZxOC2(*>kbYqG@?KC8cxo4stQsZcMjqJI4q(Ta&vP_z!wl zT7m9JT6g-6^?-eA+7>9H$~^7O%W@G#9l&f?b7JSknHq$@2FHM!v8dB`!aFer^Egpu zWv+b-^vEt9r=^QHN{dK!ap-_N6TP026h=$A-hMU>G;M1BT=V-3ZI?OyfcmA~GC7oe zt8Sq;hRCETIUXa&Q?_MY3c+K{@WsZ^G??F;MJZMD*}TFz7y-6_Oa)^=C)@Ug^qB-r&} z*feUzwETiR)8QzN94GK7Kgzzb6Q`D7ZiIT;4Jyal21I5oEt*v{yQ~PkX63)wQJ=`C zsrnw!U@)CH8fQ*8mp)d(p!{Gq#vvGM#qF+O(nZ&Bpmc7&8LOxyTjS7FhH2~WPk)(9 zjFcPlTV_UaS$;|Gj01e?qg@kBol<(HJxEhB%`ax08sv)>7a z5L4Obvjhh}F>QNF*cC@(b*R0x~xmICCQ(lfeq|i}BCK$F=V;acA4sOy|#&A+u?xKRcX(fvaX6NP< zEGnEm)r>ji`Wr|&^=K2QjanHv>ioh&)EOu%ic!kv70w}Ya$8QdQV1hEhgAC(zeyEl zZgN+wlj1gC1n7nnn?0qtWNv9Lc?p(SgK$?(`9EaSxzO~?%PpBb7jYzNm2HuT<13n7 zvMA<_D;QQEzED?NtZ1Tn7qHFe#>@{_4ecm?+>y~hSf$N!2K8N?`@%moc{C7ntz9xB z7)I?KndBi*h$%Bu?PzjDT$xg2$N|+uG^UUm4A1jd1uN|m^J8}A$IcdX&Vg0dV#H%g z4b+4iLV*ZF=UK-Sg6*|ump<5cAk)GUrVA{Orp;$NMjkK>(7}g062k34j5;)H8^xH5 zB+2aDS!C_m!L_{k`NbtDAM~*O-B2{;%&*s>kUHR^ML(>8%wR`7Vqx2c%K85rA-9;% zeEe@${J$vLmtY@Ui`?3C1Z)}B1D(Q-KckVnZz(oJ#a*N>+ldKm-AN6bh-_Qqz+d-hGiYxVM&#Qe zHkfYFcWo}7WAT)Bm(is^toCmlbQY_aT-3HI35(k9_NY3}U}QPF58uz?8}`lus^o6jVF}+r(Q{yL5m2 zQPE}W9m)i{M@P_>%O`fdd-AaI$6zioDbXiO%$iSw4gfH^*XvOd+dln89!~D;xpPbBlq@RAn_seM zN=|WJ^nU5#bT4#HS8sPmzeCY}5GnRaz~WFvbTGPoFgMx$aFmJ?`YRQswGSpmfwuiJ zlXGfmVPW~A{2~UK!#k|AzgV$7>#?K9FnID0&$>(Bm5Ckap;;UqL5Q6buH@N&!b<+} zAq_jwszlEj;DV%e=mE8nq69A9wV3r=a0yx z@0mByN6W3#GWi|Lin)O$xwQ@I)5zh-v7f;Q^4epxe_m0^+;SCCm^Qn#XsUT4H1>>- zi?V22melU&^jW?_Qsl#o=(p#ni#n#L$uF9hQ;kW*05Wr4REsrshq{DJ>|8 zlIl2Ozo~ziR8^?YQCwbFkY6+ltz`8Di#Ff5>ZOF=obqXNXBRG-lT$LI&CJb>+sOCX zrg!<12?MVYE6GS+~k0z|QQ(xBDareUyrF zCV;sI{LojYFx1XQoM~^GEp4dshhoXep2QI}qf7qBRB0zo=Jp<~J-YEUx}<%!{Y-8^ zxm8=$P;YTV;tGoS`Ar337R6RFF`Q6eJ2jy8xp~F2OXue1 znHw^(-wMMuq@W>cmz+6s3i5MvrqJ$iQtphr+*!q?g^LRFiwkqqCZ?;jD0fCq(R7Ld z#;Z0l1yPzs##{D3XDaQV8b>qM5yAYa?)Lv%u6u7Jg-D!C?cAs@jgl)IKDhn3!2IG@ zNn^mj+&b^-4%hob^pbwb$`;IdFfEXM@KhC9Y*T%E_Hjrp6Hjg5b~Y>d*6%g z+{zx{plwo&Ct@FOG0ZPtn>!6KfV}~40cUTscc2^ozRx}Yz~2w8-;b={kFDQN*uT~9 zr|dKJ`#JkU{eH>5QomobZ`AL%*6(-L@Aua459~+v`;+ziGy6sT{)hcn{r<{+Q@_8n zz4S|8q*A|JwI7Q)jSFC00j5H z4;I59sDN~+gwYUyY*+$0uoR}lGAM)~6vK&74$HAcHNL5Vl~4z3;3QZJVeUYPb>@t@ zle+*^&W$U=RL+BI#8u8fY-uVNhdH5g@rYTeatVlAUF8z7g+t|%Fy~acWW=~jKuj5!=0~WK(4N@v8e32)q%JVU-%XVK%jf&gr{g z9f0lE25dhnX%F^P1bZ5SJ)=XgJ$O$G>{P@C;ln`s=%29z(m0ewSIDj2twDUAqu_Km z>qanZa4+wLusMCSqXUQo_5<;Jgt+z~5c}}H7Q~PRab(7B$jHFivKAQF0)tv$@OtQF z4SWcPCXnJDB%VYW<8R>syr2l@rzt#W6 zSch*@WGbK9f&Hk|nFG1Jr|P<1{Cg%RU}F^{4GDUk6Ye5f_y zQPd0mN}OWcy%C_gDr}CSC}{y?e3(5X_9AwQwb_7l6d=RW(^;}t+YZCG!3cyV@ZX3Q zNH>27g|0pDgjHCSmDK{7S_@?Pgjejw##rtZEiiH$jI#5ix4~g{e#|yF{2>^NY%tCz zy)rqQ#@h-k%Ea^;K&v@%6!I`-FL%4`myS@!lWih!g@zjp;=1} z$}0tqYce%)??$m`jhJnRoMxC{mX0wAVv0o<8%=3wmAF*R1iOS9MptVw^u+XTMBF_n z1n))RcOMGB`(X@hf}>zFOo1&>1P{Oh*op$L1!`eCoB^$H8SH>t;6Y3uf<5pE{1tYh zqS^(Y!sGA_Ji$0T$-2RAmIhC&MH`DfjDc-@I3Iyja}?ag(|HE2e=V%!nLLZwgblE1 z1as|agwt2B%w?9hA_XS{Xz|u`k=%2AGNToy`gB@o#8?aD`5aycuHP1zwh{Vgdi55V zo{8l%GGdehl1ct%sy5T-q@OWIxaen=&x4w1I}|jbutR9up>REj&8n=(XLya>;8PE? zy;8MiwEA0M&K5X^u~wMti}S{H$4-j9ab8agl&Dd~wLt0StUch)Y=L>r;K0Q#^O4H) zIx@Z3dj1wD_hMfQeDU7+-EetFJuHm$kl;;FBc@JNZkF9o0`}vLZ-HaCz;PQPBWpLr zV^_!HzeUYRVR5^`ps}2Q!|xc7m)BKttj^^f6b8CkFH1ZZ$nY;>Lu5N*oeM#OVYc8iC zaNYzXt>ZZ{-TP9@7QMWx!%X7VGn>KV zOG@`9ZHKe0@geRVgz=b>ot>!!c$<-Vc{GUTV{AP$~~6nFvp!%N8PFQcLJ3hIDYVKQ=Y z9{dfa!5e7oya^@9(F@@nG;{ueeEJ^3`6rwL|AMpNebgKuz^(8h+zB6{g!mXG#Ha8i ze1g+0K!v4>eIdyRER1GoqKk@ZBS z;pLL`8d;%N6XRvf$#xi&%%jC=1Xug^q#@Dhj z{1P^nuV+W_8`wC06U*is*hGFOJCbi=llWGa%eS-1dwIJ zo1qDouf?%hBAR9ON_F*hHJWl5;yd+~8R8xnaL zbmK>$WK85Yp?;*YB)%5RUsBT=(UNa6pbFKMCD?9aba64?QT{4qX>AC2Z_34f4JMmg+)h5P}YgKa%X zQ`hh**w%n2`AnY6ry@1Ifn&Co6LY+H0smvFrlmai6YoUVSHW&(Ok1^UU2a z&IUnE_mCJHge5I-VYZ&CH_>y74NbLe-urw6s>6ip*qOBhE~4+IWXn`}9SqJ&l{?^K zj+*U~LIvzn9Du$XWag$da&PnAci1MJQwr)fAI{4MN2=esXlAa%-*s@g`Zaa!X~=QF ziqL184Q@6EQrKMR!-`=DD?xo;3S-!OID(af4}Yh!1(44c!d!M7%tOvSfh~dnI{}ul z#Zbp8paI>hm23%|!Ir}L>_oVjEr)gZyPj3Sova$Ru^M=U)xzVf4mEKVJi|-}WeM76 zLm*DAwM3_9h|WrVh8mP(F(nC=>R%i2e4QZKlFAybyC7AwJHF z_-v%H6xhM%pvx%Qtp725uDSl&(@0C`c(EU}Y-f4~+Gd5>F6MK4m#bjM}B9p7KM2X5E`SJA7h=+*p>w#<{m7*(j{J<03|#G8_F|iEU0AMCR7~Y#%9pBK(jaAo3I`3@Fm(tuF_F0aHluX zvS^c9;VxgYZ3LuvQ<9gHxk?H;CHZb|GG#>aJ>C>$4Qog#cpH6 z+3jp1+sLM{W;UJO!OBs+EM|AJlh}Q14Z9zowxF_kfIZH(vZvWL_6loZ@38HtbXwWh zYzO;}J*1fGTQs7#qfjp9B`6Lz!T`lo26~TGycC(rgG`&iJt#mEm~z%mttF zGAuJtIljT?qZp236QPxt^96{JHBieJVlIK*1^J306WIeWnIDVBauRzQ()n@NBALB{ zy&aDtH-*?LVnF|3yKa~xR_7`=UK!t%Bf%|HZV^908Q(u}KaNUQIZ_i2T%B+EVjR5_ z$NDL+z?=)m^)avH0aQq_?%NW+)N%^fAuRe$M|LUKw2~s^S4XBMN*;oH%hR(mx5Irt zk>M5E7P!9!Hf3ptM_trjs`s7XWV;Y2kKufuK=JrK3}qigTnL055k%<<%S`1KBj!1d zbRaLqoCbX$o-gCUc7o_czT8qoCt@9fvW}cRm&lgQaE_L(XQ6D^2=T-fn~`j{*d>Xo zqy-+xb~MAR%nZ}2;WLJv!I!#bpvmL2AI`yfJ zCUA&m5E^NmC^jZR0*>?FAlavg|IZQgUqCAR637uB#=eEI>^nG`eUCiyBPxiWkVk%o zlh}XY6!se`gS`r4Ymge9XciI;N;nL2RhV;7K*!3}L~`>`*jFPyoe&SF^BScJPC=8y ze2bWh;C)>L@9Pwmag`&JK~uR}q)P!8+x@m#fjWMYwE}PBh}`(*cT&YZ!rNw_w1o|- z*yIT)O}1IGMo(@@-X6)fBGPw6o*u-fF|F`Wq~PIpjy78Q!!wji1ZPl9v&=)aRk`%)LXb;tzL@k7JW`&X>2+*}N6C%!IxXr}rnv&* z^5XyG8??aAGR#LHL>=*YkcwFi%|8JKVki|$2jMD?;!ZdUF<->pa6I>*L@{6mkAt&$ zJjDg!W}XZW@f1|S-QYzu2;W3Q@k2fqzTxBGH#8vasN@PXF+;d+4tNnpD&BCS`QB5> z1X|bMBkTLSk{C?o?DhR!$pjo7{LI5xhGT?pc|EQ)juif_TzDOB#t{;2INC^u2EM|Q z4)d#-pw3P%K0>CqyPT!M2VuNAU%YXc?*OUjaQ(bdZHBVE`h9Cabq0+(y3A zn#AQ+NNzkU%qT?hmWc$lvIU;l0#7Q}xeq=+^%yiZ0cq{0c0nUDH$!9dZ&+Du&e$25 z!$7iyQ4n*Uhkn8|T=MDIcRn1(XTdnMyRy-$ipJ%}N9Hk}uR_fJ~Gd_ZOgmJM$R`<6N&K@8M;i(F{3ch}rA<$_CKAaXYaC2L*(1&|(|BiYrYZ|7s#|H35$I z##?}m-E5av8Fyw-G0xHg>LH%8uX*(y@HcWSUPogMjlLWT`W#8U{(U!$rDzQPW~yiP zfXH8OcKJq3myz%cftXKL+#Wc_;;G#*-O3S^9SXoW0`R8(2)tFUsnX(dD=@mcxLjJ* zi(BFC7|02G%zoe5U%x{M()H^R*Kx}D?oPk|SRcXFyUnmZhR+iz=0zC6MK43M9+%Ub zNO7+uMF!1~=1V5~ab@x@y;@reUqN zVQ15bN9?QUv)ik;LeIz>#pM(=OrW50oT-19FTo5&_i7)Cc2NP=w`szgpzv%yjcSFD zux(;=AHpluPQ)_8a0`6wOQH4QX@~^)SYBAA*bwsPZF0VlSoQcVZTT@pQCuS$d24LnFVF-^VvYBU_;*YeUhu9;yweUr{gCimRYe{XUM*SBVz& z`?z?Ler3GuE&JIqLHu_nrgI^V7efk~&V6_(4B_)2gO{O}oDaF^f)w$EXm%V67xLrb zT67m~-NJb|Y5Uw9R~z^l>xsDUrh(EEXhnB-xW$XBqQd=*RM ztJxra3LDMWvcvhQY#cw0RbxA|4*3S7etel5@D*P+RI13EG{@)CXvx<$96R@}hX@MgY_-+|b<8}V~L-^}mf z5Ab{Wllb%kKE2Af@HepJYrd8Lz_;@UO&L z{*$x(l&8uRU z=ff~G30*3#=wXRylTg&rU_mPv&&I)#D*hOU=DS&zh);H|B$9j5idd%b2cWlVk<7nF znj*-_d>v8}Sy+kuP6#R2Hi@0hu2p7d99zdO(Ak`$AF140#k4jr= z=Y$8HYkHd?u7UpiH0n*%!?FByeg-7TG^-5fjiaX#B#}*ITT_^`tU}D4X>QSD?kuzq zHHeds*pX7X-HMdAZbFC4uIjM|qMFRcR8!?EsTzvpIZ7li^m(l3Z%ELh z0(aQ*n|TdJ*5S7#w7(<$9TnOUL7i-u(xgyK6Hc)vVQyCJreCUiJ*3dI66|ShK+D#) z4bVVszkBRyzkBTI`ASZJ*Abi7qkWJU2P%z8bvT@$Mc@rB0f~}^K5Oga*S?;MA!nF z5+P1_43!s&6*rp+0e(JTi$ZKZl<^Drg($>A=tZkd8Db!t`7viPKjuuAFqseG7a=PP z7{TMM;CL?kUNNu^=d#U8AUNP1w!rH5E_ShEc^7lBk*K!5!4bRwLB;5vHmrOJztnOf zb5OXDU+qfIK$6=I-?uwIp#{LHEr~fl;fi>FE_29j0I%y9@HHI(Mq#d<*h#>g{_>3# zuNh|f?&p#JSY%5W;T2iR)K!}`{fOYMw@l_Alu?X=#x#m!Lp$xrT~DqE1Q;7s|KmnK)hB9J+wL)tepg-w0bx~YlO+#N;pPa1&g%RaH4iH ztkzCJLOxZYU@k7-C`*qJtn(tsI4=?_I8TMPI8Og8r2#aQ!K)NuP}HE#+DVxV)6F1A zn{~N@Uumt&0_(I)HDt>hv z@1N6OFtiqIjtbWR+@7(A!VZYGpNq0~z%LA%;Bw6ThbiBaHqOS76u!D?@B5jQ`JCLI zy{~6j`Twf(Ex)4N|BZnB-n{o=Ree1qQ}8p=0{ZQ@1@t!+hi=zU`|J{ZICY9;@A4=H zrl=jwb3th5;fk(>ZrTOVU%LzmU&Y*bEs=bb1ukd_(1kble!koAB8^|tb zv$8kxn@l{54XBkpIQ-Wv4VKQ5oR7YHxjyhB90mI&k5vXODV+V6GAO&nK`7p}S znlqQr?G;{k3q!ROPdV1gJT1&<-uoK*wMG_dQ?J;~2AEx!(bnj0_!U=<#jS_$y&{Fh zW7{UUBQlT#Rg_5MP`MM_`IT6w|`S|5xFjqumaC!3*`~icgpXhXGU!ccGu(_!c?)D{x1!B(8#3ocI9h9l>DnDIN4pD3wY%YX?Os@>-H%MV z2~O5F!x`EZSgUP?o3w3kH%f+WXq7#oJq#~tkH8z+qwtZo6TZ=QF-?1n#c7YT?%ES9 zO?#4MX-~1q+HSNR_OLSTFYH9^X|_sxhMlWD%dXa5V7F>7v4^zR*rVDjY?t;bdtUo1 zdtG~-y|4Y9eW|_0e$d`#ziRJrp}os9wD7AxY_fTL*!<=poemZT2+AKr2;xi!8t6CCa>X(SY-jzqv9xyfmyqb_=?Z?jI{BR#Q81kL)IpZE<<*W~zDYXAIShRBvU&ki53B;jyK{E*;TK#A8On8Zq{{VhG@4QqX=5=vllBTxHDzsKnJFyG47ZyAh8LHM%;IwC zb*L!2lTH+peavVFhANC)kL+SrCBL~lsQgp)`@T1WCsM+q*NH)Jw-^kMiy`oV7!IF{4ERc9!Y?9=Nim8gh|#R47|RBV zacqbf&qfL#J6ud;M~WlaJTZx_6qDI?B9}FbJVk%2(H{H2vgw^{9!%j|_ye@n%2GHWGU*-3$!h!4s*GC3nkUTVWs%)@DyK~J#&28x9+Q5*~T;y9=kC%_6(5t(u= z>QEv94JN`wzS9ysjgiSWnv-uceb)i z?{y|;ct-cxd$0Z67k_gM#$D@`r~pJ9>1Tw$nk)X`eJVGi6#@L<*^G!*yI1$o?N&?B z5nG=QRtL~<7@dt3xoWplh!1+qdOgYxoXE!mHsd!RbO&FHEr7)687+yHhTnd1s1J2;Z+255{Wujou!|r4&}oDO*tar_aBzt zv3)po;^{!=eXCa0Owg9_hh1I!y#6&fqj?KyBnfqlF+6zkQo|^ast&TR!u-f2j1oQEUO?*CZq*orty|~kl$@lXh!$WhWWjW^ z%x#aSdRKm5%1vcsk1jf@#$s$h=672E>ET+TaO|noOyo8X!FNX>IbbAVX-%#hI1qS zuof{M-dTaH&I4H(w#*^l&v(x$PgbFUND5~gKN*smi&^C^{P{t627yhmg2AcM0b4)H zeN_t7mOlG^7o!3AT9mCh$Jt{G6xV**eY#bO>j0BFtn0p{Z94ovAw#Ne=zTp@F1XB8A+$Lyu#CnGJ-AR zi`PL4Hs&v;)_%Ro0cu0nnO4|dlQ~67w^l5mXn=g)`Admbj*UY;iQR!$$8)nq-b)bJ z`{&TD+h5$nxPmxzT^angqLCJH;t5FWoanYjC>UpFx?4PP2~ChZTR~hp3=EbnNqUG| zEw%Bes#2~Fqh>}AvE+#remqm-vmS*2#nD5_MpA3HEHhffdoFhOtg>iTww_3lUb=mD zXUwUvWSVCwNaM}rg8D*Um~iJ2^JHidw5ei_Yu3M+?O_idr=>ydM=WFxJ7rVXkWqbI z;JWz*95&9VBgzOzX@lGLP7h-|5e<;hxiB;7Xlwpa=jho5W9gIqCKY>iS2)+f%#{z$ z%NjT_T-?mspXHz|HNnBRu2>OJg=A z;p0v*+0T8*o9i~GDN4l7B*O)r@ivct5j}x&X2A(ei=4xB z@*P0v?Z7RDDb1gbl7`E_JPt|cI^q9)JiVFf)CVMZukRl89rcIk2SiQi&YpGQCn9NpeBqy*A|s*m$yhoz zf%Y}KGhoOVhfAW2zB>vn0Q&eeue8bii6hKy3d9rBF?%U>FMpFe zu#Mk;$n`^=&BfJIT-gD^<5v}J_zOC)T=F0aPGTY&t>i^B~h3jaXm&@urEZ5M(wN_VNOlzVGvv4u~d8x zvC`pA`S}sLBQC0WAHS&;q(+R@NwXpyuO>yZ4g6G_3nSkay%8RHd&qYj%VvZ(%H@VY zsIJ?s*x`y#X2t*`YWPpH{r;#UVxvxBL<`k+1~TC0sL;|no>R*jQiZ;-P)G8bJkjYHtl!?IxX3|R@ohqQ@QzZ~>S7@%C*UN;T7+xRN zPs*0Qc@*$7qNI3Ye2m9#rbf6g+Ol>;ZAJCCHh7+`7<~BlBLA3&RK$nIcSn6pOvr7? zgu`M&6dT9Iq%G+sNrUBd;F^qoQy?+zXLLZHOaQmbqzMEVAuo=t+0|!)VvHK@GHJlA zOrW%CCHDt7@bM5$08_M~X2uNnSlw~G2r=@IIDU2~_`Is9GLTWH(Sc3|y@^b|Buf7# zq%kx!ij_@KsgzJ{aL}0eU>cN51gg^FtirVUXA!H_H#wkb(W^CV98z8)xKnlD__mBK ztRc9gdkSSwWv5u8Hrxn(yR(p_<*B{?@VHNTqaKYP$s6`X(-;LM?}hxR8TEnS0Xex_ zc?CrZsan46xm$@_o1p!@3p^3v|8ljmthJ!nwcXVUSLwnGqwO?fW;+g*Z5!8!jN(kF zd6VQ9UGMQ7ch|X5jW>!Kl@c)5 zd9yjiBO1RYiiMaaPeSQ)pR~5iJuduuUY$poQI@yCd~E*6c%)QCJN0*Sx=v z-J~R=VKgT)7Wc6ccEd(ze7tDV^I&JgFn!hCLW74Hw+~G>qcFT4Ug4JM>%XNein0Ch z!UW^^uGIt6)i@3zoorX<{cx&U#-9QLU@e&0VAJYQcIYM>J}5Ya%Cb;?=Z~T>Q3eTJ z5b;szJOSO{`F|kC1hxLZOGN$m*on9+d5f+1)k*BVQTJkI$?Sb5?#w)dw!&lf+&q-* zy%i3`onbvUW8AZmtpL7c*MXFK{MX;x5yyjMuR1njlJ`H-Q4#CG+LB1etSkBBZ}i); z;FGvlq23rKl4EM!9musPTkZ7O=Bs@x}NT+?dcX z>I0ByXit+NyZ5bn@+@a`_o3vxcBTEA>>GTGat4C`jhjbOC%=dC1->jjtlIFFqE25F zW!3R-Hr5;V5Ir#!)pc@A(d8me11pX8QgMEl)@lpEC2f6K4wzy};Wy6?yQ5ndr4!av zQ)r7nYYW=}BfYMJ(-$dhid5o=S#HUoh`}J2!l2^C!~7mBUU<9rvC$pAM`LT}g(t{@#^S=)f^ zxE4Qc9tlotWWkJV2iQR}D%yL_IWQ&9>$F3?R_OG5dY&^4ia^pf%8Svi z+gQ&%#T3C!<<0);spnESt0^|Kfo}FS_v2rkBIjemcwV&ic)Gy$#6{V9F8`GCybLQb zK&BL$&T(w%`{g6e!=X+Q7j!6H#QJFVLBvG;7G}G!C4S#R3xl9QzPy$?;7xd$k_Ywd zypf2L^KO}v+i`^}I};b#*_aNpkYejc*@$2~K4RA+n8X6$m$ZB^qX!Ibfoq7v7OYPf z#^PyLp6(53lm|bD>0YS$DLLOzY-{-N4-`18BGL>8iIbo1gIuzKD zRUy!6^~p-|nt747Yw0JNpm|XE0Jf)BC6B|pNK|LJ`f=L~!7(U$M6^00I%6F>A=-2Z z00P}`s5j2_4lL|TtyaY7m~056f7s|h|4IEBMKg8alG3rBIMyFnZvxAi>HHO!i4@B< z$DYrnHf{b=8Rb#@`RBK2F>Ec#62;?Jk!D~te_EW3T;P``#PxPAor+&$say|CLS`KK zva01~kPiG`b*h3e^8pF$VLD`hdn|in>lc^sa&M)RY}cKp%OPD4JlCDGM(oteksv}0 z2mh!nC5`*k`HsI^gC;WOcV}Oj=GqT{QSKd2ntEvlI5ht+7!3@5a$+RPk(+n~k@1&@ z1wVPDF8&b_Jop#K{qi{$I4~2Q0300+6?iL$1j-0A*!Yon=oRSaJ@g}`X&{c9T z?nRfFLxLVMatUe{T16fF6Yugw`4iWL`rI+9iGf+dfn=|9%+7E1+H3Xdrjm_>O;UX9 z9Yubk?EKX}1Zo#Yn>-U5Rd({(I|kFqZks|NQC!WXCXCyvwNN<@mtZ<73KX8jc<<72 zZ>6L3_Z`ipd9>wx6pyf?e7>rgeL>A-zXg9wG|ks>H5k_EWnPa46mp}dMT-id4$ZMc zY&q$K=`B{PG>&e-rrL3jn zp1-LHLmK9wdm_?iHYI!&CXKbFo4<)JudHyK(lp?z&P~a@@ra_MmUlq~NHQrrA|s*A zF1;jhdg=IUTy_4|9xf6jNxA=77{8S835~80OP+f%-d3ScR0@ZjA%RNckK0kL&60Zq zo>VEkgzf9o%v)TYU#)H9FV({Y_<5g<3R3=2&H_>n2U4y)OMF-^Sm-gdL^jv;3V>N) zrB6*)z)7$|@hMDwGV_;Sh|*0I>;I*>D2=iDnc4kIMOS|%`wTsU-mQ5_$kc~aFM`N2 zLhtJ3*7KcHb8OgKBQy!R{cwo)I+Wkyq^MoV2EO4><^WsK|cQyI#Pur}^*u>EMiB7#APHqE| zol7{mx5cYc#ClyIXI4(O*fz^filET}J+yD~B;r)RHG>+0)iVs1$r9(qZ8@$5vy$6Y zrfuv4ZfEu{(6Cg2@|g>suvQP^r}-Lh#qy<$Z?y`$3!MZC4Wro|a=_=L*ZirePpp`4 z8s73K?D%wm5Ah2WTK5u^h8O(4!2pd3rRwz_b6bqMHBlV>m_eW-sYYb248P52OU2Gm zqPzbAT9g=@N5@aqrCJ7Sl2cNY?=dB~@qTg*hd)J)&=5h?IIwN9VQ??YQeR0?4;gAg zlK+%&PgX(g+xZ`O=|FLH(&<$NsFwpDj2>oRUkwV2l)pzh^&-=B7=~lcK5ZXhO~NDV z3K^r3n6&ICD8yr0?EU04?s~&8%SW?6Lu%t$QN!<~B=%J*_2C1;I6$uZEB16dgNv@> z7!bt;iFGFwpPg?(qJvxRAUHzV`;l>B$?Y>iIyKBYMUVEY%Bi=DE$scV{aPyKI3%}1 z6PDaMrDX>x&*eV4+X+g_)7)CpBVNk&4n8ed`Eu89LoArTB&>%Zmn>gn*TWW;e*UYX z3uIn`d@X$k@ij2dG#xN`F!*=Iy*hTnYwVY?IR(}Ip&SLC3_=0OL z0I$J(0k-RZY}XLFtw(P0xDj19-dablgFUbCU#qteU)FZ|KcCUuW~)bppVdDScz^CR zlQ{xdby*2M&>c`jUKsD zdQJ0&h~dJP=b-bsHrk^s0c5*4+)0xY%y6K+x|YE7IJ~29fJ$-(j5-9z9z+s34Ffn6 zMxC#VX-@dgcX=f6vYryJaEo{@CG9)IP&fi$Ztd^yB&quK6d2hQ*tG>oThpcN@sjpD z&ZDc8gSbl}uk*6qLd)-nrS|R1hZYtiSe{CR$_rqyC7PTVg?9=kD01_hpmk(-@)=n| z$>#Oj1G;5jZWAES9MVOF&DeA#9nYvVB?inmKLJ%m9u~!WjbUO6+}Xmu&Mo*VyUjHiaEqS57e<8Q0E;^WN7$k6vD}g-xYL&==}|)R=kuil2#F z*4cZ^*RcP_6S|5t;(4; zow)6>*&R%(<`{wMCvf4dt4{?(8ttTK-Pd5}_#IUseF%5u_g=fh=13Vew8>W^TrAn{Dm7Pvm2Ofk4%dCxrMf{6L0?-e7mF}sy zpXZ86`S@y|6=|wV+vy@5-&yA^?SJ8}b@Ab+V+%hAT(zylemk5l0`&o;s zuCdUlGpaRhpt8Ac(d%c=3-QTZYIt^@=`4!w=doIO-0Jc|+TOb^3wT)PR#C-G?SL6l zpmmWTSz~8}b85H~+sYAhjHmDkgK}@CO~mxkZ?9w91}FTO&7`)?g7gu8p<~MdC)0pW zz^WvV!VuH0Ntz)>NdIvO z5uv(pX8=kQ(eO;8H7h&dta5`_uYxrO@b7CT8ttNJp7#>=h%*X?R*&QrzS00}yEr;ao1mYDYEQFHAyRAq=mFVg zxSDA-jQY$kd#B8(*%W~a$f1+HVuUyu#49Gw6OKgp+}?z9o-mcF6 zhVtn0i8K0hDz0p~ADlsP1YAOY`wz&dQTusO&-g z%$yM?(nKf|su)t6f=!-mw69>V4kYWMCYTNB9`X$}6WGc=C(**g(@Jr%M%+#}L=2Z>C?xO-Nr|nCRcI|Iu%#F!Vgyfj@r4Z~QkOLi&HC z-!QV0{J+dYt^Xi6U&|QKlMZ2q6sYk6c~x;gg+aiC(iceuByiL1Xdlsm6U``E4y0+l z^5z8Zkni)8U?mIFk8#tFJC9XYG7H&BQH&{*e~R5!m)5o(vTn4WC31m*#`Cb>N^JZ zQ{lYk7+5UXYSx>@$kBQ1aXG@I8KF>BkZ*6z-;G!*IHBVj1B=Sw7Uue3i`t5*CXJl- z^reR)ZH7-I(J#tjy%(76%xu_2!SgbLX%8&NiS6aW<2&sIo0sw@52anE!EePyL5wSm zVkH<;l-y|iAiL{PJoo8Z+h7&U~;&hk|T4s(u8J(c8 z!(`wLe+?e+pW4eEtRr3yX6$G5lZ?i98guKbi=d1)mtmazr1vwHa2rZv&RoCZrJK&= zevByO(4y@4TOK!Ui7x!Tp=EeQr_eOd>vpMo1*H?nO!v}?(GxxHYLIBr_q2x{ENtAhCA(xW(1P8Q%%g6h#A{QT z(5iH*9$;Jo!GIOq*dAvW#h`FEv*gIa2EFq!~L}iHk^2Oxm zW-JJ?jd1**KdJ|Vbq7iYpZ9#v47%hEBUWL*z$stJ)BSx9Ks7I_GDkubw0U$zG2|KH z;>Z9xQ6_$RVt;&k+lA!E^pG}{b^E>ng-nM`*akIoucgf>*i;4PWkmP3bNpU^EC-BP zd_$&zzF4$4BXZ4j@Zai&9!VcUw*+7Tw*N-dF~Y$%lS)IR_$sA-rnD&n6^-!+0V(ta zsZ)f}zl9Vf@CTglZy~avX16&$l{~9G8U(rf7x;+!eS}Mdbeodw%?V`Iyn^g@&-nTc zZbH@7F_W+frK6yve?3ZUk`7P{s4zVp+ZdEvT>Ih35E2n0&QcXK(NRZUcJTo7qG+^* zB2b5oDHTnBIRpotr3ZDWz)pqhF}QYxWsdfUu#!3ZOY1n-PMP*@=X0p)ub4g0ZQ^qi zwxg!rl=TJ%tunsCJm9lPs?Cz=h>Dy$%Q`71T9PhblLakdS@v3cDYLQ(lMK0Qgjrv$ zgy^Ek1o$orj<+fWC5}B^uV>xv8M?~o&lVjKC%}fzZwfx7+x^o^eImYeT|IY61?$@Hf4^!3cK^>w_T$U(#h z;fQ)-fM8e%z|=((F2+gePaQI@OI5nl#H2FmAKedM?WQt$FlZ(W7Pa@N!jbO(>&!?~ z(OPW~lxJz|p8bo>cVd<0u^yQ8n0b<_Y91~))y_ObM9);40moa+{nziz!=Nf{zpx9A z77L+;2dx5bZu5MfbYTyC#^qeYa*OPy(%7C{iA_7D1J3cGS!up2e9wMG_r=L|VIH=5 zzCrZOh01T?N<}?~*JAUPO=G5Nb1mf; zG^%I>INJbVuHuZ)B;KbzQaJ;cpC}8+ zRkw4K^H)=kb)1z>^3;V_{9kYSL}~1Awv35GKYPsJQU|?XBq)%7%*QWR>4y2T@YZ-Y zI`F2~SW9~8Gx7z6|IymCrE{_U>A^}8W*lLHF!?ZKZKDij`|$AWc1i;b`*3#w%H{jA z@U}qhfeiyU$Quhc#6+?f|6n4r(iozFtNy}ZI4`7Z@IiRvu#Ku3flM>uJar zy%Q#tV+F~0;e-)olGa2=m2yB>Y0LC7y;^3!jlKVO9`u_BBT%<;eQQ=ZKx z@GaL4+%(rsH7@{e$yNepikgaHjRUmYMAkA;DV+&OJxKnA$1GLi=1oGnI!450fA!0p zK>ZfYKy_Y>{x$G<@2j^(;2+_?C(57opeCvY3yf$$W0{j8HJp?s{wQ+$c~FJQrD0!O z$S1tA#bzgAMFkIC%8IA?2kwMn4$fqRQYH4edA@F!Eir~Mg(!74=JXTgJnHXhH>ipg z3ljEL-|Q)y2l|N1EO&F%?f&YCo0VYZxV|+`m(#W@WSbKWQ6CBj%{nx?H6fKu`x!4y z<~w)RJI*PF7}wQ2t7M?yoByfDpM-HW%-`K&n(k0KZx9FLEgUsoA>c=zl~nw_sxG&A z_W(XcpJDRxn)oo(EjC$9dXy;t!z#8hEw`}e)Xc0Bo}cORd;W-Hb8_*%52SDTwsxh= zudX}0<~zIpN^<$V{6XC`qHA_3DW`vA3n0kHN5%05^y>X5oQRNjd@25gQ}cf%4#oaI z!s-7+4y#l@<#5E2zN_vaIn+Q%f*y%KVPxwhIS2`?rP9G76J`~{K}Z$9&K+9%GFDxe zw}eKuMBL*=sHztE-+y=qb_--kcn6g;pF}Y3CY&xwOkPHt`aEQ0tu^_6pZs$UWq{5< z{tZU#qer--!-}H*-diGyus|l*bNT5CtBx{SJsOOHso_K8TBwtR#5Y^)q82iYm<=5o z0y5y|khuN(x_zBBqTHsi*L=j*;>h9BVwYV-zYzv}n*MKJvNiU6>8!8OrQJva9>2o# z`tW!+0V%%a5dUoe`CvD|z>Xm8;rBaeHLce6q7w%ntsN_6-g6`jk48%lSLR1Zu{52E znvw>yT4-9yH~G!6?U+D;Kdw)S$i=9-OFxxS9ga>4IAJdK@LzhiH!$@{zCFVLCXJ5-Lp zSo>Nqohsjo;S$C1+7}8O!mO0iv7Ld^Y3?m~U2g(&KXfxF@W=xWp{5rQjxrRtoRt^M zc3@%Ei@Tg~(dKz%7euz?SGGY<6u7)*m^v1+%uT?3E(OyAG}=kB*5tVcBwyI^oJ`&l zPP%d(D?4&ln+N0vwR}>z(q@<*MtIHVe2e=`n~!ZFqvynbM7qFukH+KE$?JZAx7{D&-ygwxQgnv@m=@hTjQtDywwc2b z=NXl^i4&R7wFxtL@=64PAH8sE0YVyntdb^mN=!XPpuurObG2I0^8tY2FZed*R?5C= z>mhckI06*t6@Jrb6ptDha*5R&7UKRgMjZH<`3oeM&u{Y9tzhTb_n18CwJ_sK(EX7mQe#jB8Oau`3bA>z;YASn|NokU{@2=F@OYIi-tLqS*-V@mT8bPVMccRv{ z&wAG`-uY|$F}!7PgD1t+Ey?$2zQfBshG6Gp9+Ia5v28;f|E}(JkeUz8_aS^{@Wktl zyXCL{-sb>uH|qBxu=_srp9kjkmQ25McjQ^~D)@1lHzDu!hQa=|hWdS+{k-mO-%IX;*(afb`BJLqIG2d?4*xgG&fGUw=rb**1CH=kU+nVBklP zj2Av)h{2^3zcnV&6SHrb^BN=V9OV&en{=H3q1P5QoFBl<5686}x7W>=!vX%j9;qEB zANxE4>&D$p4&sRbZS%;dM7)>k$s9z4bi5ezO6yN4GBg5l<7x zyy-y3KY2f{$eAG>a$hu==-BGa*^)iM`heLF^h%qdM^CNyHzTADYd93@rr9?qn3mR? zywL0~BE~EczmF(*bzm`crA$e_^9R+|oKB%a#HV(ARlFK99D>(|xj$FEH7-)Cj%U?& zh0{}gcy0Q~k2e23qin@sT%d(N!3>keG&zM1Ai?^@nJnw2F_6-Pe_k8CQ+)!AIT$(M z6Z0@_2t#B?VQbox`I!+=M|#hsgpYPT|Q-AD~Khkuhc_o=S8CL^{7EnCxz zo**DR;a7AfBD$jq*dI17-W&obZ4b{g;t!`BU{jizrZiu-XuaB!N}eIRH%-Pj(qe81 zy?@;t&g*!!W$bJXcx{f;U$Y*07jF)WF7r5W>#e^z@V9&sFFgIcz9)2b52Xu)^VmCR z4{;y-Y#k$(y#M`{N=aaP{SKhNg%&$W=b4s1Nxet2xuw$6HMFaFID!Z8GaO~GS_ zpj+ZaoQlj?jBEElMys@Kj>IIiYHPhbWGU3q%%Q62tMumn=qD|&Knf2v`Pp$`ib>?7 zGh0{$e9TwLc*vuXKE;_m6t+LXE-#CetEx=X3y)H8lhu+jG_xu6I9&QmlotCOk$^SW zc#9G?GGWeDUFF+cm1*(!r+eU>7uE;Qj@QMt3y@&is3T+H=qm9ym;XY= z)lwpW4n7BMGF(xOg17ry$AY(2M}Z1wXNt{GVB>ACM1fivGq@bg&_GTIt!`|{%1T*Q zooDkGkD-#PT!MASzA;mWWlQ z0-Bssq;rWiDyr|?-EWjC-^Dh=M>Z~fy>1A;sYwvtzxbp|tEaTJw44gFST)E~G|PcADY0%+wt6^;g%=SYAv{jpmo+s8nwOAiISz1}_jS`2JAUaq3o zz<~aDNMzQ>qoyf)jJ(B2i=0-*Oe|4}SLiNxI+iYtm(JC7nU)+pfnBaTQ|{Up-M!a2=`qu>l>g+kV4(zQ@I(DU4U#TSI1UX3d5r^$+#E?rZ6Emg0^`5@QHdzwCB!-BD_>488^q6lDb;b8DiDMa4s6&8{~3b;!y0%Ty9ucZkv8}k&0+kS?IAKJ zImN3|VPR2WEmJo9BSCcu@*K*)g|QcA(}&a&N0sQZMJ<%VQlFO501@yjXbBTe)WW~= zZSfrYI0WcvrYBeLK+$ASH8=V(H;WqW=vP99yYO63sT>j81*txmmOf}{7UhY#gkFeZ zBRU0HLzG3Is3PvQm$2&WRKWlRg6(L@e zX3ZS&md%mdnpa&-w$IV0i(|^>*&!*vN^1T0(ja)M>;vf}&Yf40#B-=~n~IlSYpW0p z8^>}*4QxfUkvyECUL4e7NVHO2tCLE-iEC3?oQvqrUQi#rib7{&Z`v8XL8ueM9X6`T zk4p7(Om>fuk~f{k5rGl1MH{KyfdzzLWs!AVo-*zvM`# zr~Mo;wiRfIvGV!?F>&C|r)ShAGxfVCSQ*{MXgnrYeOoD6y@jgms%{Q9Zh1XkxiVE< ztJziY-OW;_q>3ZPVE&{|+vosadH{ZcKF3hvQFL;n3O&%(S~wK9JSohX^3Z)@G6HYr z$6n@j=k#=RFJEgnZ~p<^b$tbw6^=^+%yc;o)ifd-TOb}Oz}4OgSIf@>#tpjZ*|Q;e zu$xVrGv;W(q)>E0gPpS~zt6ogLpJ>Iw1C+{@lgYkzDy)e;g6FYu?D;Kl%ip6!NaZH zpMysiM~xSrBVT*OFIU|~!9|!8=)Lu>IV(@fm7b8@QZ&u9x`x_Au~r@0^pJI|9#HjkbE{0{dgSp|ss-E|BNx zDoftp4mz>8Akh-IIRez7&Vxy5E`eh;$96b>z3Dra@r~0997@y0vJ;@jg0pp7EVD|I z2XcDv3EwnzVf0l+33y261xqfY7g@OgF;$dY={h;Tmt>1H&>9TKSksZMK#*+W^O1AV z=|=vRmI5m~-ULknomQ{~*QqJY@N*%L?Y-maR98)CmXKkZB`bl>m}(t9(FaSvOR!-m z4ZFdDxF5uE1>x2orfaV?*HV8HsT9THb|X`J zbzgj^UuoZTNR|moo*d=Qg;ok7Pf|qWZqQupT!GJ6VT@;4#?X3c2mP8qs$}R{te1z=OZisO{#f zr@|~N3!f>AJ#m`to;HX6sX04~TJDf&eWSA;3Dned1JyOyTXTyJV&CuC95KyN%IL)e8t`9QZg@BbmnFw-=3sO5^Mc0i^A&lJE_{Uaf*e3+7>^q~|3}4XlB;;iW z;cQY3DV9-9Rn5~TECUY%U^MwJa)hLIE#r_vBAN%+eb`_Efm?XL8wm@J``4tNaAb4U7J5xOO6k>E9_O9i{YFR!3l?aG zs2H7`UM+1S7ND>^QBpF|ANu;8P&@GGxXCgrD7j-c^E(`#7Vn_P;ZZ31&`UqVjiQp7t_ z71y$$+%_#UrqVAvDj!!|3WsXySEOE|l3pq`+_Y#avPerhe^s1Gf#@8r!lreugwddi zym16=7eO^Y6=eotc{yM?1df?c z>}e~>>1OGd0o=>U>yYTauKF$<)AwWSt#k27DGyn&hYdRv7~)^ekPD8rz~Er^5daQ$Bi7)>3svWUf@MKNieu}iNci{?eL<@21~lH_(xjpEtXVz7ilD03q9V;jS{vtzqOV>V*Nk>NU{4pq0j)FSOSjTi(5|6H zWz~HMh;#+0-e(bRTd3f?)T^rr@| zb(!g61Jq|YPP#?Kg}9hQIgSH%mOhVo$9*MaPQ&8EIkYW)GQ}b`Om-*(0E%OY&H)YiQIXgY}9#`Mttp zMe%0OGub1Do}d(w_6eDJbL1Q#?LA(vgerS~w73-Le4AR@NFJxa9?t+?@%gXrTIJ{j ztei;JPg936n~Do)Ta9iuyuRau!xm;PTrVF^u3Yy`+woE1rUivFGVnIR@(Y-PdZKS4^?s4OUFzzr~ImrtU&i|Ec#L^r{)cgNIrHrOnvvI+`boOGqk zWHzw|#;DAp?q~8M_AgK4mx>1?0N1m3pJp|&$^M1|27e~+{dzESiz11zOSHnGBykX< zs%wrD^8yy)U?sZfYsbWv`sq0fWBVrGCNuwlIoUIR_a z1muoBm?khM^@C$Q2uCto4NKdHnS#qGllyE68U67Nzrt?I0LToelN$II>QyrYQB9F? zi#wP@DRWc{Ob%f!Q9QwkG2iu(Ai*rdxh@BzdTh_k!yQqdw1yxRmEHC@CgdCvnXs6E zWcwek)FhHj2#50`$ID~PD5FD_+hf_+DTD%HUxJ~iTq6|8_DC0Nn!$~Jhz&uH@v2C| zEOX&d+9|ijGFB_VMKfPHmKKiS2SN{`1V=NXw>yk~E6@d$?W>g6YRBggy%_#ErVpMJ zpiW><*b8m`1Nk1wBg>-ZFiAb?aG#JU@40hdd2y(>oS51oWWdrM2-|)qvMgFfz=for za!5gPUS2aHt_Fd1PdnLujV2mY&=Vz(4HB8NCLlMC3}^6%(pi2sBSKvyks&t05Hu?? zM8qBKM5>$_iX2RaI zWpKY+#BO3ma{#zSX6;i<#}zlUhCe4_$Q6~uVWAdTnezSP`~y!W-PEQV&(s>B#OV{H z(R^ClTKC8stcl#7H^gdZgb&{Ae2^MThs2>r&sUd-u3&23#4lN(zRs zX;uAdSK?>_q5m?$tJ1J*45LJ^Ki>ecOB^9A6k|S_uC=U6tW3@Vs24lT^z2jY@}F|O z<+@^xs^G--Pe{nGeNO(i$VrinAo#D9z5GLVh_mD=zsTb9(?a9lsbH!v)Kur0p#_yn z#a56Gk+<+z&ul8UijCW&hv=etqp4?CF%Ku72D7bGUD+$C-Do%s_UKFvtX||!3TcEC ze}9N<3VMb;4l>*G?!D=hihBG))s|#Sk(YHf8EN|K<#yy73z8MYqn|TO`ZVq(jsSLs zl5r-|ww}+D(|IA7dV>3kVuiMD3%;kQdmp`0lR^ZD}3 z#?h#@lvlGcd}Ys+L;$a~N%7j2gO)={LL^ju9p!wGH{S9^FqUf-(GL${a^5c!O<~Z4 z2srbhk8ubizCOB91-M#cvGO%4@&$(67IB{_1F1xO1#x z7I&^*b5$}s-#S>j?4afzS13qkNJyxV4S-ykP4vps*BMCH|6iP)Q*dU{x9vN&ZKGq` zw%M_bFUA+!wmP=$j_ssl+qO>s@40mzPu;qEKkfChUuKQDYOXbYV^4U)nAcbMWFe=% zZiseKO;MJ-le?mn3R{{{b2>|3O}W9vOIll6TzW=&n8_SG8%%4O!KI0ixgD;W#QRHJtN*6)7vA4i9{{lf=O#;?^ndnP3 z#AWlwOJ23e?y)`AkC)Lj3Nqomu6sq}DXiUVsNn0r73>w8QLxgarcTi_(CF}3Ts>^R z91$CVyV*s8$pg6>6{$-38Q!5+dv|Z+lhsm*ehIiMbA!;)=PCcv|5cw}rF)vqO|c*= zjf|;;tjA(Os2RK3S$NT+P%j&H5!G=5q|=|GrYG~f5Xa8qwF7Bq8^WMiNL!ni@%5(% zc&|ZU2ls5RDkMMaNHQ*#y$Rq6KI6Z&w@UUjVR-8q4yh3K zgVI_Har_5C*IOt>IUPUNpp)0iETz=#A5;AM)os%cS5Ur=gOE>31*oJKt54djAJwU@ ziFI9ti*4E;tg?j0k~LcKoxb6(2x_|;K)bx~VAYHFsD%2<}o>2L)! zpTeOK$4I%CUBPwiVI+ByzNSHd^FE5Oh8_9{tTOaz`-vW=vsYAL)3KK6^M>xw+Cqs* zdmDJ~jlQss7g&Yv=WP9E7}c%p;7!)KV;xbgY1<)Q?K-ww3`ZlS?wNC3a9Sh38S12DQoZuQMrIof<{O3a@wc z^D=u@_?pZ*`lNE6*K`lc9w!HI3&tK`=9^&P&cA$lsZ!QmT?{R>3qC(YZmIhR^R)3{ zi{oeSucoqvWFG)_J!5Wxq1Vthg+`J(Z45zsL+@11-$PMwGUUHjq?``;3_GS$UZqGM zWfjgU(yh!k#$s3e)|_-kw+c$XO9X6f7B^3mYb4K6D6fkfF5X~rvuyqJ$SerCpmN%@ zD1#8{CgOkAV=0KM{N~vOYq9T@yV!kJrSzk-_8tuJPFn(0?TUQ8#0+r(D6X%a1Ixmy zz3MtP^I|sbjBOoy{+u&FwP58o*0vZOUJVvo=he4z!krN030vgnHC+!lKjkOusrwvk z)fXH(PjIV5_*|)=<(gb)-Y>g(6_#;%F?q-$AzbEmzYxB9%65Fqy>Q~_(@s8|1jGhA zV5U?{0dqDzk8S*Uy8rpSPM%fQoX_%~D}D6Vla>Vyg@V?$sn<^XujZF!JEnTF=BC_u zJ2El-oLp)@*<6r*>{3IL4t{_61yLjI1fpq+Q>K!7kdqGVl;-i+&X-;VYw z(VWg`^f=uZhb;j1Q{}Q7b(RW@BNtiv%afLavZQHEzKUj9ta@N#x%XOV;Z+%w3%=vC zcO=XI@^N+C+`#Are8_Su3hzX%Ea9s2bfo)<7Df0`53bVCT;^&YLusOOveoYtr6y}m z8dMdY;5gGxl&(v{q2@p#VM!0Dv0a#xB?)RGjBpHvUPkoprN)TdkRAgqQN0x@lr@u9 zTbh7I%G#$7#m>j{IXXQ}>4KQ>7qshFQyhH{i8$gZW*Aj~CUf}(gL#)Xm8QJZ3ePBu z$vj?*)2@O@?HnbG<7neN=9!J-TILQGcU|Bx8QnX;3d*ZHX}Ii=M&_&t(ZGv@brizRx=SJ&6f}?DcRd9-|4IPQ^3oM+jmXU6=@Ft zSe^STY*;VGVPbdktM|uO%Yr38+xEZQfS5BvP+3vNn5z`|<^UzqoSGRndAWE2F#RdWLJW zqzDT^JOikk=!yWhm&pF1kA?KY{cbU68T`s_ zHMV1_TjT!RMUVu|mr6%qjL?qe?Krr9jFYh>wkujuIvntjvT-g?HObDCxgd&#syFUr4~bKVqLew~e~ z2@5Dlgu)c!Q4?|~3l^?J4(%r$4H+=PrwbL)0u^@zpA055Lc|xRk1JU#eqj7TYsg&{ zWWDl3m$KB1m!CRs%YNnK86b}2rSg%^``kj) zHkDyR0vNC&VJ6;~BY$|gV!wbgtYV`dAiUCa6%OKhI_`xq+knUQ1LZnS;a_rzuoZK9 ziY(h@T2>T}&!O8%F9IYoTPW9W1jw~kVYzC8y3KMrMrz9-+f_(z-$PY`*}QX~3Is@p zAde!dy^ z<(iQ#YmsUvK-a2u9_m^Io}!c<{_)-GsZ%~0U^(jOkO&JfMR=O=h?zftO~ zLfVFc9!)!3>x{W6y=?%wpLGqRYv+*+?w4bY^w?vul6>ltoQF%t8=shp11+5dIgVbx zp_lji4s>AZ2BhSfF!Y7;Gja-1nBYJo6CRbx&(yhY(6~Q^5vd%@{BjKljz5*ZSmt%o zk`%fE*>)uMdT5QXZ398uGTC;TnJ{XCR94{ccf96fIFVboqICc!P?+@{JnR!XCw97u-^apa6z}2fHdu!zL2H%i?Ve> z)!`Ek!g`>``3ug`5e=B#aMk!z0oeIMns3-n|5%LW@`t7M-+Qok{ce9#ZU`gt$08aL z6sC#cK+gL^MG`W68bUC5`V)Mq_*})RNfNDbOKS^;`MLy=Of!%vY-Gp_cfLD1a2N6ws5i&M--MNI4XlKK zoV{-tF?3@kcRp24-vos{Zn^-*;8uFy5k{P*lB_v($=!U36l)U0>4)^(@LWJS^n=`B zD!&lKjNw~!m8qwP*P?~SzhUg*siEe$^ku!I@~fHzRm1%&GSHpC?UYJa)7;4NcaXJF zq$t^Y!N1iy=&@z4!6z*-i`%vqhx^lMnqoP1!eVU-eE5j>2tO zR1L}Tz@ql8Yr6nazeL8LGU1{0J9iZPBBGs{V+Q#+@d8%1yAf66Tz{2G;aBdo5e*%n zlHV+|%go3u37Eo#Lo@R^w+FI}f0H7Xm0Srm58&!!87bEq+8tvYT>rSyZs@!MAX-Ikhv0|DYMEpvgJCxG`T-aUbwb|4uM1H}ZMsZ5syDKp={5sMftr!94~}~L3vV~-+20g-^dT&{ZK_e1w##B`W0Ss z)wUI>cQlhvgu&kPBSdHW6Vjv6m_lr&Xtd*9;EfrpM2Tt&F-!M__>dX_WJgNqOu-+U zy9Wue#0cDpY{%5|fWlk7$sr^rq~1Tk4-~i?3w+v*wmhkkTVv=eMu~lJ025{;DxZ?t zZv(o1X=4mRx-&o|7h-AT0wA-EP&g(68z4X@$c=2$$Zt#$xc?hQKe#|qc}Pm ztwl0A7$@K{?~Rn2??R|K$m}#3l{VT2RU|pchQ%pj-4iy+)0%zZ{FuD;i7aE6EX&>C zGfus%E0?8?vPjU%%|RabGFFHh(buE`ymWd0(R2rU;R6NwB7wktS>aJl5=f8kNqy2i zagUpj9;!mHPznd7=ZMC3_ekiN?&+?RUMHkPjrMhNJfSy_sPPFT6kAnc7Y?VXLyxg_ zM^SV1rY8?l1YgM-Ve3PhM93l*IUXTzfQKcpcB9t@nB4s0LaZgT->6b%%4@TzD*VAs z0?>fRu@G+$lexHn{q<$_D@U62(JL(OO{j1{GVIT!-V5|C(Mz#t8im4MK^lEDmTg0f zH6i^+$ICBU%8rEOJ^A`9~;g z9BEh^NXukw1I21>AU_-0=4$V_fn*eps`t}zckPat@4CDOGtT3j=S>5cxMs9qR#vO8 zzwLWqSnjl3#k~Lg-hA@6<)!#tK<~n5b?^qCqr1}16B}T~bJ7!nAEFac&^m|f5N6vI zWcsX7aHLmca#ccnO_(0H{yS76961E2dvSSu`mC^VgI zo{^sK{4NZ8St$Z0O5?fb%c;8HE_zX&G+r%^wH<}tPD3bi?u=k3w}9&oqALl*iQQQT zt~54~>sxPFU@nK{Cis{dvE0TwUTm=v5%%1)jWO8!XR`cVeks*3Lv=G{@Nz zypHj{!*Qk?ZqD`dySzmzx?-FAAL_hS5K+%N0WWjaN6GiTTfz0608Fh5XLrX5g5Fgp zy4J~NgLe+$X~HZj!_muR99nlwVwy2(@7da4zXkWhlJJn4`v&mAU*&i!cb!ie$gSe& zoW=*+;v_yHcro(nx7RzPt=R12ikT>+-U1N?lx848`xc;AbH*^*Rzd- zzhLPqQ2728SFw-rmQ6($YfsYy1Lkn*gQ1D713yt@<8N0y`9F6WyeY$MMz zL|p`5T?n~Xd*9*0@iYzWAG+O)37D!cR?JCxm@y7zMf+I_CSC>gP~t^015#sCQ;o_m za-3v{`PAl?fj<=^V$xCZn1|eyd1Lk|fUEm-PQ%jUQ;fd>xm$=cZUm;_5RPPMsVV4q zmy+1R>8mC6pNbrSUdzkV@^~dpC{0Q?wuUkk})^PqvgX)Rrs(ZFccrQz?V?D;|I%-)(PWqpJhD} z%$f(6oSc8i-j6bj5XaDTXw8VA9S#6fQ`Fc^a5|`BMEOl37kCfG(2WB#nmjWcRJh6{ zS|cDgJt!<{;0BtRD99Luke24wqaK+ve8?j}D{yKLdJ2G*xcyeWFP?Sa&I1GC0m^_? zUS&T=Zlq}98U?mvm{6n6eyd5Rv5tPIOk-wAco|2J|0l0cApZPF=XBEcBKX z8f~y5UF`{=@~oFQ%lw*64JxLTvea{(022we=T($%Xs2=X_Lh!v9>aHHTA|t zE#Nn>)ym_yE$xF8Q~yC%!jo%mZr{TS{j*ikBkJ|EW*`{)+GrFx0URR@2al4qr9+P8 zSg*^Hnfgpzl&}%xd#LaHQnQ|eBym`e&VOe+(2dT#80}``FKix%DBP+zu!J1!r2; zu(1vPi@0VHI!pY>v6(CaQWu$4KA=!M7JG7?zfKu`uHkRifeZB#^Pzo|@>Pr80?0>U z1!8xs`yISz@X?%S)OAp;+9SscO&shppsn1;GARkbTlOKQJu%I>AGP$(Zj43^U@r={ zA(qvZh1-(bntNmt+mPyab_Sg}8Y)SqlGyRoD`8{dp->jylXk4ng(^B3aWk=GI6$1* zoubG&r!CzXUxqcX0E)6>F-M@kAIXtUn*wckx!)If37U%829kBVIU9j+@COW4i@i3X z%DS@ki#r@IUpyxx9pvo@zB^ZJJNWOn0YK}njEp}p8~QtmXrAYm4%V#rlh4T7fj|Z& zmk$%T4Se}DC2Zu0u$5~c`|{RPogGu(uW}s76MD0!eg=mt@I%Y)!zy=kthxbAAG6Nb zu#>AS!vfZ?Hmw;2J9hX*(Lp!UpDUKD+JB@q@NS6C5<{Q!_Wpl9dkX9YfzB-=nq^r=m|+0AE+~mM|QbysXRpaK=Psx zU(_#zYCT{Z2lD_09*|Lkjcqbr(XM-p^-VimVSN~Ul030!%=TO57=;fEN5waph&P_! zy#nSgXLk01`fXxaxFA7}xg6}MG61e2^6S$dw9_^v*q0}nGj>=oJv&O>t@H0np6Gh( zhw|}Du!0sJodjPdRDXO)uEwV(7*DEO2K=t4r;gEG^#%Ap&fJ;3&&V61x^VhA9daM6IdNNP6!T(#tu)F5OoS30zx% z49y4;w%i@WI@u)^vZ|UJ`38tSP4o*^7wH$+b<}si1uDA{ zrw~geEEVrE{ylBWkj(Xnj96rP=8MRIb-&Xl;>iA|Nauq}+Dfq|6N3Ga&X|p3LQR)6 ztA7^$<;3GtFwBx;syT!r7363Xi~mdLTQMqG6&25&5dula+G9?jj z-t~bd(*C>lh1deEtYDK7>Tx`DlVJIfy%fT1B&R>`1?1ewCXbUM{tr3}c!1}wVN?p>)> zsMPTuC3>H_Ur#|^t3(QkU_1ES$Tf*UhK-W}f}?$oz4)MtW4kw@_|g|VusunIb7c3- z@|cEx+?ZkGx9N<}BlUMb_@prRY`Ia6$AcUNHsg|gbt$R#t+^qVN6Ryp9D>=>;ZN82 z9};(aejT8R{!&sz^ai;OGWuTe-O^f7j3(jSHhzk-YJ5~KDdh<}Ek9u5Pq8g&t(!J_ z>%n$R_vO+E2MnH3M)wa4`c6JLk|Uz;-)d)0s9aDzm8z&v38xE@gyehyRXS0L|Gr0a zT*%_aUkjLnyI2_aro%Qp|4`7EJ3@PJ-S@xbszZQExGg?fwM#d-4mMKYMQl-2$FLN_ zt(dO!WPN)ZLuuSaG-@L^Qf~7a;6)2->9eve_ZY~^Z`x;4sk`LLUbFrp*exZVw#b`e zy0N!so|ly4Z|IoaSM{x>lN*;AzuWl7&5I|A(RN7Q?hGh6&GCEobUzW$|2r$)Q>0P0 z*^dGA@5fXyHhag17#k2eu1fKVHKvX4YTmUxQ?Ruo`Y~HU5`vY!4kB8{y#0P^@%bBU zLW@%ZE$_6S?|m?JSi@HYj5SU2EjxyZwm8}#%feX7Xo%@OPyrqn4S#= zqK#O2zz03?>e!_Voi;8$ONT^7VgTPdN-;|l=l^~%cayFQt2l0U6AAxk-Q`r#YaY9VPPDq`{U{eAXYQ0mb>Co=Z2>u_)TGMmGv-+_g=LP*P^c zgYQ?an9Po;E|p>*+F`jz!-l`b80(FbC#639%rM>|_Y0IK!xqKNfcJs;3MJ$4$U(|W za2Gi5LGepu7yNc|+Wxu|Sr2X2EnGWHZ>r`#(jD%Hv^}QJ0fMoAmoj{!j#$kG4Pr9= zo}p({I;jI1#vNk4*4EG1_~&p)&)V?O_d(otez&&Yev?3!nAN$zfOX=ZnD}bG0+5kuX9 zBS{0(LNy0Ejd6vgM;LcRl;tj2#26+q7RvR^ss6>Jl3Z+V<4JisP5&+vg4%$>Iyh|I z)pCnlcii}FBkFu0V+8vt)yB00P5h&_7=ImQ{@iv1hTDVl7UpkoR zZ3P={*%QtCk?Rk%ySrPH!?1e5n5fNxxo(7gv0Jd{l8@(L47sV7prI}5IIyo!8wjfC}5XY@jDoHAh^U%r)=5N3Ox?QU~kgP`v{=qz%hs-}mYfmu? zI`yM@bCC-l8FZq2fm?(%#zN>Ll6vlbj0TKP%Zh z5%2Lcvyu*IrH(&a6hA8HE)Hcc{b2>-TkX)2UsYJ^wKyM~0UZpnhsF^Mi2Hl+dJh1A zIl3j~^gP};qLCLf=+CV|mA9-**(LAhD-OQol3bDT1l84xAwH2WA(pWG4>|j}!iGA| zN2&84aWog3pzkQT2b80;5ApcXj&^>Oo(>hx^{npLjo{rhv=>t+GOh*W7L+~(T4%Dq z#aP>^eOLhsl&Sa9uRSd#d?uGKeep?(W84P zdd{xTukV}tj_qy~{R9mJ-NbI|%#HnhWi<19d#9Q=?w1C0!GK`K{4g?I7Ji$Jf{jBz zEKPbc~KQut&yC(4w!T4FI7f;am|3J2S$9d4TB?f3(-98`s$b z)`j7w-GY7+ZP7vV(P>-}>KWYrKLVOdSrK>Uf02i9l)eqO4HNa9Mxks1a>(Jr#`}%5 z2iS`6TxDpM>#_oz()6!Y_+q$9|!-xIK=L#th+G z&0f5ZSf`%g@;>b_vcK^djfP{U?j5&rHDNn+R?S3=7=sIrhWBv&o0&ICUa)jCvgTiOSCyO?N+YdJk@`n< z+}Bm91KwX<$+c<++sWvRo}P^$@h_QmbSqCmbExb~vPsMp87Hw)@!F?i?)@dV%o{|f zO=!=51B;r%Io5gso?mGZk~-`cH7WGQVP*(xgKDAAsO54ploDpBU0f;7$$CR%2QH#! zm&;78?Diq#9dE2$`Rx8(V!olWub%$ZnvD%!oX%Orx)#=tClj-_nWq!;&*YScP4te4 zL?dG@w};K@5`Ok;Z4eEoh-qiKr>kEVm{MkPocG!}&Xy=OAJbozj00)n3AQcH`e7R8 zeuc@R2|w{qCyZ3*LB@dRP8w8_L_Y374Npp-(6ZuB;uk!vJJvg$-rtswL`(|4Fc^1u zTq?d$6Nk@AjDG$L2XS@EU*MV(etnmB7A&dX0mp}oH?bcn1#>w!If*xgDrLz5W8)#K z<1wl!SQa#J7L{t*rSp#YG9zT_kTpsf*ecyOYD;)C%09Q&hXd=2Ke{9l1~09V1&SJO z6|I>BDns{Vt+9JbBzBIi(Z7C6>@(76{vJouS0{E_#7?Lkjuc^6kkbq?F5yv9D~s6s zY<(z$+>8Io6DmHEEpdYT*SX6QdbcEtD8}dIhs(R5~~V# z7+{@{U4oc)cn0m6%p=25R%j+gpK`v$;#mVb8e`qwC9FQCvn1o$`HSLOo&65RH5#Z~ zo$65e>ovhTIj`L0kdubISJUXVF>=&k3D>NmnMSr+HE7X`U523aNpqx9`iz`iKBo#% zwX}@lOijI7K^5W5#kxIUD_eM(bxHfdp^!(%PUE5B?xvDn zqI}I-tpd{|qhm;`*q&9Ray=%#W1vla(+pVfOON|ZUo&Lw=vU#I9##3fUTGzio<(Jt zZdzHG-g23wE@zpfp3ag6 zWpDe8MqWFka$aYxhM&8GxOcJ{?Qsz-_&W6!@j3izd|Ug>eB1i0dF%V+d@Ov& zdu+5S^UFFt6EqimjN+F2T*j~TWv9ZnRA3I~UWhj@&Yvs}HPXN<(YElI+()SO3{5c2 zwJA!+i&1MFl48APpPvegfo~i*G3zlj&2Yf!o_db*#F2wEG4ty*RGOY|NQNCt11k>kfuyDu4dRBX?1h6Agl9 zt#HkB8@#Gt0N9`|u3gz0Ji9UB5(0o95^cz6(Z1=Ndlc)wJh_r1oU-1(U>@H!6*>a8 z0?(FwS5Tbdk-)fU2g{g5lv(E1zCL^lk(K7w9KaQ4UNsCiWK0v|c=#vF7$!xcgT^q5 zD^R9TDzWu^L$<~H$0V|(ieAgA2rHLN+Ep=?Rjv${tA)+940Tx13ZF^)uX zCT@3@jtt*T#JZ;But0z~bX_BI^I^A%fKIEE0gsPTzE?=Nq$)SGD38 zOU3)LSBzrKO7Q`;?SdG>G-i<*SCsXENAt3_?s#u6`l%iRkM&y8uHA=H%NWKOdAw=+ zy2nwtf%BRiZAalI&<%>Ax{X8DG>=KGo%3SVB@Y(Ev<0!h;p4ZlXTrS-{tCTz-zHlU zQwQ-3eZ=f(Q8lwpa{Kxnfq7i)ZFGHHV(*;*cQ`zjM|506)_27764#Z^DtBo4j#Z@s zntOUOvEH4yGohSrK?Lp~xz@L4O7C6@S$t1Fx_(UC1(@a)a6$V#7&_cBu0tBUs`2f! zgt+%bj~U{q5)Y)qe#VG~??)OIF(bf68?S7qBSPV@8dfl)jYq3+ZKNY0NZ?d)j_U6?25U5bT*vVLWY zvdc5Y$M~PNS3kbqW*3aN*8pwyOv3`_v+Dw{@fBHK4_W%1@cXJV3-K@epoG^Eh*HbX z;BWJt5kv52Z>#_%kIfh)R=@-_yZ;gP<7krfMP`^~i77QHH_w>7%{i z!#I-2aQF~mxUxq1_3*JwsRJ}75LFx%`O{huHZizdOIiq6*v*bX%24jukB+?nIzH3j z9eOg*JRJF(?s`mweGfSng+DI)Vh=b}yHfk;bW93EpD_!w4%x8_(X4E=)x;vpDCOJ~ zQ>CEO=<-$nwtrlDRV0{zg$>Q9<~JQS3!DD^y;Np z5W;$eDt9sG)K8Efwu@40u%X$B6UXN46I^(I#BR!gfw_8CTNHS;*B{cDo|n~alxWLq z87q7W19!YR1@n1#X9Ntok}86R#Px}Nj)`qCaXI5Fss^72<4z7EkG_fwc}9Kvz}&X7 zqdU5o`#)^cP_+P*h_j)12VGFK7+IqL0K{Ag&NOFDz(n-9aqmO@A7;xBZ+yH*MjwBM z&pv58`^DY|5|>lAV@^SiGlMs!j=|msqZ8EciZI!<7ft?+S)$lw5gX7c34BSH8y6m2 zw=S-}e{2P9zkGSs8JmIq&TMa21h7NgTt}_Za4QtiB!Szy_@4^sRNO)%D)J9hf@1iR zPl~?y=`Tq{d!~@o3Ufm802*$X&cHwG-tZ#f3y-c~xpL3G#LUs>@yD)on~M4Gzj2p1|DU-_nxgVX_C^+FPUOu04P8n})N@#1LJ!?e@+~4V zG6_m?pso_qoGpmJE6NAVAuyLmM-@0-mXu75W{-`*e$bI48;5`X@I~KSIh6@fYZ7+? z0v~cmuIoR~pKoFOUD;@r)~c|`ngn^5T>#+^jBtl(0Jr{i$kC=ZJ@jhCg;I#n?IpKb1lj|CdGlX;2^DoV zHaJ2cGE&&4RfMSt&OFM@`afq|qQY$J@Q6-@dZ6X+WgEYipNF(O%6=d9iH{AyS_j8C z=Ya}Bh~AOqhkl)Z^}w${~`zjF|q~7OIvs*aaS?1i^i9Hvi7k+G$HIuN!4sp*GRqsx}kZl7{m?LAVUE3nThDCh2H*KO76N7y)s zRK1{&bz?9{&3d^ zmj7E;>YL8%V#wcmJqK+vNhJY7Mr9%kYtk}{B?tyT>C3B|3R>{#cz@;zCosnHM52>( zQw+>xAvUgjDw?7MB7ThTfc9{S}9gTwIBa>$?^Kz1Zw zNA=5H1d?gA zO%N%P=$%5%dw)q%Bf;zM#!O$by4OImJI4a{p6s0@s?2<`xV;dQ31U`e@oz0(QFPO$}WA7^rbfBoUcd<9B`Z zmzrqtF2;Pi0WonA^vuCh#QWry{Y>`x4#17!o!i+0%$=Hdczg* zwnhgJxe2bcYP!OZW&^d{HnDa?7$$8mlk67QsADR66P1<4OS~Jg*d=RNLff@}rqXfL z_E{y9J>ujqn}0>gm{r|VORnzdqhA@Ru0|+eE3a;$vyHoy(NL>q)T<%)2(K)Ev?L z%H7rGBfx0=?KVF`Ch@bjS`Fdyselq#wJ{&_fkN)EDX%~-Bh`OHA|t9xGolG05_QaD z!*E8=yHhlT{N*4z>tu_C_4#VmTIl}J)gT9~Wsx~4FtXUKfm{)yeg+XQ+81!9po1!5^2~q z=WM+XFQhiXB!Y_I%Vk5r-z^(OsE&IjSey2mSe zj1Q=3+zslOQ-OaPAhQRyn?E>u?ww|uZR#V&-pk*iq(^j_q2qdgk-;m}+iL9@S>^VF zK?P~<`-iK@yyDGq$ZI70t#s>1$HUmTn)7+vg) zT+Eyu%v~6r-Rv1n9GuJ;t?XUQoa~Kk8Qo17|KZ>Nr&;~CrgQ^gfND#R-`vmBcjk8u z2;kTtIBugNLd4cTn8`svSBYUNDGa_|xyJq{P76#W{ziA%_N>&n~-=E(H_nyw%o$uN`7VVrpANTv-AcoPvbr{Ya0jjGJ ztQ^aswCveHM&4VDkK!Q0TAmxtm(0*!x4rY1P%yusUe~>>7tH1E>fP&?=Vyf%yq^6* z_gjA7j{x59IT(Z&0YQPCkuby$w6Bbjx2RB}+qB-hiEXxzbU(qlo9mDF^3c51TW2Z{ zOL4Xntc^QasxPo!r@iGDMf-b3gzxHIPU#nV-_qS@g%6~!-@9>$A25Dy^ZT?2NS2@{ zdcP@yDT_jJGV8cPQqF?q(cIPwX0!WAvUO#gVD-q?#Us&5Zkp&xmq@BeA5cHr4vzFk0JUF>;_$yQq5^bza*2X0@B0U0pwN5%l+ zZpg1#CcXZA#My-1n*^&yqZi^EH;uYP(j`psJ7ptdnzSWX8nG&}rs75KlPE}`?hk?c z$~8st5$=k80Z|o!4U~5g0>-E)vT{cw=rz0{l9}VRrIZn%%u@`ouf?Mbkp#va>3w<@ zcZI=3jfsP{%HyBoFUr%ZYRF__#gs=kY3*IzG`?!Qr^@^2_k%#=G_60|n0Ka8ZJWk~ zmu&hkj8fKvsDyq%e>~n)L8Y|*| zVDQA_Z8F5*-*IgsrgD64p9!gzi6Q=V^%lwSgEhG{6zHS!pmY|wen z)3@sn!n2ieFQxwCpsZYE+Usp3rSF)UPs-trrmk0v`-_cl*EGV`jzjO3XGXrm z>d-p$FZJEYy@JenV{kfQDF%4ReiR2{mYMa%y`0Zbpi>iECAyJR5RNaDm=Uc*hdlRzE-(J_ukA7$QZXo7>uieXX_Er_XwYQdZOY&_{0{$kawyMoEUH}{v5|`jT0XDeFazd~;TZE+q{eYPa_f6a z)YvrlAp_(tbk2{H1l8Q=wl!+HE;w0McaXSFm82wozl{>LXR^px010mVdrZ!1Drg4O zd(R=Bp(Tc*NRK2EDf7fL);0`?Vj?!k!$j&9OA(z=z{=#w712IJu@pLbdS4ahY;m1m z>Y7TLk}g7{ycN60Sh%0*bQ9s^OE#GibSB?TYSwi7wac zH;!#I>g06v{vOy7Kk;;<;2K-O$t&h~h%S*3xmIu;ed1dK+>XlfN>2$Szfo}~@nBf` zZHnwD*}cWFR89~UUo$h|&v%trlxwui@`t-V;%jRt(4SE7#&Vn4mKU7hvVdDcaNQ1X z4s}$NV^9t!JB*E(Lw4m%D~kt}Q4gacbSlZ(X9(}fu#^cJ63SR4{0BNHx~H`FVFPT^ z32Sv%I(o~CD%U1_16DN1-RXAfafF`vtl#d>p79W)1VNo=5-5zt>Vfn6DIgprJZis0dDCb_GG%%3-z z(p)QI_9=-yhKm|R(*)sp0mV%A=)o6-8A)cWdofMHa9JO)c8!Q}E$V=nRmY{Q1Mcq= z(>B$-Z@jU%JL7~z^(-SpXis#O6mXg;cQ`zC6$_K<4YJ7|O}_Ni7@ov^-$&t~L-v4_ z9^{FD+N}$gd#&g6HZ6S{C!ablF|L8>?GKS)jPGrN#&imedz~_xlBrP65MQr2JMM~E zF=3XusLr>E)Nm(?`JeFV=QfC;pQdbovCHbd{bI}`m;mIk6mKs4wysQV)ReCpY?6P~ zhCimzMIg_VFLel*1x{>fcnnlyysnTrddQuF+T6WOLr$}3{3h9QQE&r#Zf4l5716{y zan8w#>|(v=&IXhj$IHpP{j(ucEpfYeI3Vk1G+X&L8Ui(hbt8!`d%j7+yu`M}B`=j} zzau#9;z#?$F|f#@1@5wK)Ks5zR+HefJ||)t%*qSm2=CaN*gQp3B%%$K=7IIK6|Axl zlK;ioIdy5m1Z%cz+qP|V*|u%lwr$%syKLKd%hhGOPk(FH+@3XSF7hu#Mn=ZoPuqi+ z(zR41jq;@I!+~1O7qUAja`X?b9cQn6yB$XZHhL+}1f~hv_1v2=m?;^KwZ~!y+Ww{a z1BmbQB4Rp^Hly%0^OTsBp;n{Cp@*`oIqAkdB%0>}$QK*f5c5!ec7a-TS=Ho1OKBwM z%0Y~^6b(A;B?x0-kJoKn||TW2JcAw_p^f zCUdvbdD`}`ZU@_4fEvgFTdx|b0#6V%LT9%Zd!v+v6IE6;%`;&6la;_^6Q9$y|k%dCiD9LaFMN7VBr?_V1g9R2Nj?{FW-(2u@<0r2tv zlK3*j6ubmbKAi(B^cO47qrZ$2I-)|${Np0hPhh=dk8Z1AQTjsUy19siGA8mEiWeM? zCnCpV|CZF;A(gUw_m1&|OjnBHX`Py!-#11uO`=*od8Imxf;Lz}OYq6~5yXFgBkvJ0 ztFkj6OqqnnKCgto{CP~=C4o+`(}K~L4(duZlf`Hu3@ZSmJr0h=!+xQ{eyAmRfA*>z zAr%egQ$PEa44G|>fTmG`L%>!^iPMK`8)*+o{3_{P6wHuZn6>9f3O?H1Dp|u|w`85+ zu4n!AXQ51m;zC(NrkX+L*K@jCd)Nfy)HPTls$XA|$ zf%Gp+#1Kx8?3!7$>~%lzV2ED%eee?U5(>_n-?RJ0k{RPB?jX7b`Xht4n}6x*X=QE> z18b+>en^e8I@q6KXi~Rwab+IC=9z7?g3$0hC+zrDGlR`}hTU#H`Iq$*AnpZ*g!L1m z3n8pE)B@3rkP{?5gi)z(JcusuG~t#aSJ^z&p$v?eyorf-7_WSnqjLvb3>c% zUd0Rw$&}k>{S1_olkVJN85I*%-F#{o=g!%5D`rV_=AMO871NVE=~LM5+$tI5rH9Vx zxp7Q4mHbfn6-LBH;dHBJS#JzRb-7tnR>qNLSybz0VYMqKczf@T@ln{&| zkFI1W1`Xu3sa3vdC#Unt#GC6-=pNmY>6YWoZa#_pn(4OCu?M~zR_<)k2Sp79zXeS7 zP7&2Ao2NG}>LD!jXm%Wr`fk5ny^7k% z@`iBSJEqkFMg)5LpzC}Y64qUR?3L<(%)3onS=mY_9A^C;VH7D#m_2R~F zZM84!%;+Sh3Yuha^DEX&o02?&47;EM98;P~4Ku3k9WUgz1iH9=7!D_7ir=d|1s%(op1h6bgAg%_kyLTpIy+!Ai zPf8w`_1dSeZN1$unnPrIPL8^FNC`WpDP7;mO0M+leWV5IrY(+JMwUGbv@_xtQu#Q}HOk=veC;Mt;G&Ew%B>fh3q(s0B6Gg|JWzQ(Ko&i5jIc5pw0F%3o%@r20 zn;0d@iah$lQebb|zr%vAA3`p+IQyCT>LDgzCR;nHF=aYw*Z{L2F!yetv>iL1>R3Cm znaML~LHE?_FFIO&i;efWgU0u0RCbl) z4Fo%MN00}kk}IlI>(t*M|6`G4x}0Ho9Ok%GDPk@a@2bdkdX4}o1#M|w;(95h^sGe4 zraeVF6@%yy#wE#G&s{ptSX)O|nXjdzucXJ@S6tqE4%PKzsgZ3dIv=0+-YaiJFZ>oM zv1)xjOrVGL^0^So{kGt9H%MOsrGsP3bk4vP!q=L^+|ycmD1VME5i2HI*4#TD@x-qg zGNrzfI?vFMX&_%#9cETWesVlWk%EN{?L&GekIUX|v*b0@6xo_2p?g_#3MVXu39YB< z?COmYuqpCKmdS1QjGm`ksiXr)Gor-GJJgF`x@V+j{&0lmhNwS5P!}EEvI0^>tjRGw z(G=MzMo<@xAMTJJ1KUF`oB&4|V4nlWBa900ybm5)$|g~E?(6LJz8TsAfRn4OszJnK z@e(?1Q~}(VVt@*Jiz_?b-KD&g><(vwAF$c%tC{WbsGiE*7pK+R!q88aWn^G#;;`es zoNtwO&4HGygwF26lVI>XH+mRz#}IM8k;h(EGytI*@M)__)SzS6YV)>|O}To?g&DZWPK?)OG4M;0UluB9 zOPM^Utar0)@^*KZyj^YA@s+ef;d}9xW;-E?&y}z|R0w$IWurp$u6YZD7C@xm*H+$2 zT)AU?RMIcVeg7u0J}s8ehRE(t`oEH$7p2dzu4Gv-KfYS$=QpzY&-zMK^!GD)ds#g! zIo%Q=un9`Zv{gTYX?-_a7Dh0pCDpr{VVe7nwPK`qE5zuAJ>p>=(?LCRT8Vqq zE(w0>`yIXNFxE6ezxxr|UJO_QScA0omlPYWKI`ZGIcO*~i`#ST>IOH2t}GCZATtlN zAV{+(T#I+R2Z6o(^BsO}5qn8sK`$;Gk~@OZJnLp!Dw3;63>2eh+7ipc5LYz}{Mby? zlhl6F&#vZslPy4#PxEA@9Gp?SW%+}p^%2VhhFr!oiob|&(?hBw?!kHRw(z^Nw%Oar zj+(m=&2dCd?GmwOTkfaP=sg*2;$60EbwWx9M;&Cdrzh$CL5vCM{=*BwTGv|t(`Bsw zdyy!`+qAvAXMTJsr+!DDHCFki0eCe$!CLJT@P~g8-IqxfpD&ak^@*r5nx|?ssGEpz z96LU!g#1{;z*p}r@!Xp%I&rq~Umv+3vVCNJ+cd`~?JQ@89H)w_rURL^4;Z?P?t|HG0`aBY8FEl$wYkd-B^B4p=gmrLc1D3v^1 zkp1+OOq0U@dVU<_T^eo`0nMp^k7kFNlA@_wdSizLDG259{B>!&y7(nDPx5gK6~mE^ zr04d^S;XzP71L#w-*JZnukqn&EM_Fs1qc_8)JD*-j=@yLoTq1`VqYkwarc)~G_cga z@xa}*eRS|y@rQ}iLBGOv^`JEXr#c)nyfRMmY7^LvB{&L6SAEp6=qy#BrBaTeWu#&~ zsuEp`H z*WVJ#P-cD0$23udGlWNZal9NkAmzT2=>)LE9&|4DO(YjtE>&gj+4~x4(!v(?? zwAp1I&yculfFEUQ8JcVjzU10BRZW>1u6DV(I#4~{asqOLN40DwEQI2*F#H6O-<@OR{LZGZ_9)$7}X7pU~Y2US8IL3 z5gqIjhkJ_mor*Q$9+(q0#i?q2;iyOg43eUifc;-mp;ZJAQMDpBy@#>N7|Yu6=7`^lZ3j@) z;M2Xg&mc6OZtuS28E(Vf3ESJ+yI56yE9y821m?U4!P?Y!UPC6F=tK`#^R+r0m4|IcmT7pP#t5 ziZsNr@qEA7hoSwd%#QAZh_{9^%y$(v&6BG35IdBCF&sVLJqGwxbwpO2|UE@ zdW2e^u)WE>lxH88bB_Z+^cb~J8bd>l^Vw0=O5aJF+VY5nmn6$40USq z_Z2Lh`1RTd*YYVLx8Oe%m)M2si!Q5H^DMe0-!o6=0p!j7bNLFa1X3>{yU^2in?WC} zcC&fg@F`9zx|Vqio3)p$d<b4@{XJ+rB;(u* zv!@0jpN*nL$s20E)RT@Wd#ZW4S@Wezx~wZbVj)ZMu9*^`Y>hxvZhiBqyHi$VJLKqv zq~shj8I#N@rRiO5ER(F-5j0225Hw|NNhmr~64yL%NZbb)(Vppd0;J#=90^twy>N`A ziG{?GpTdo?z?O+o%?F^FP|JTo`%#Cne4K^AXo9;O&}G7&38B}P^lJ?9X(B!znri}G zHzMT+iQUO)!Z{3D-4W9TDIB=ILDGd079k*CDn*!uTE>C#`Qt%PGh?bBNFfcV5JfH* zVq*?vX(Afg24nESssng5!#W0VdhzFmJ`ZiT#<|}}YDf2nyxugp2!Dsd-a&RsZXBQ_ z!DK`OJ7!@a{1L^_B_10}1DJM7%ZAmA(shc{1>1~bJLW|WcsmK~5HSSdj-E6M=^}E* z*{(lM&(g(OJtG3@chac6omriP=?w&p^M2og_?O-~OVIRqQRQJQ`$N3EMdQJSD4 zNA)W%^KMC%{*)O-R!x!aX+5L@d1l)(A&(!E{op`1H^MMq?&v8(a&d(7+lKJUlzEab z@jC%%(v&UVh#zv{jEa3utL`gXQD#-^(SZ7{=qgUKVXCssf~P?Mplul{M^1-eIJzLm zkHC^i^aR3DnGvrVrRP{YywY=nD3`SH9Lr{gQ|?SzNdK5IoF0)$1{03La%EY&@k!~% zt4N|G-=jGp%a=WuA@S#V(qJsqAIUAT(Xq**Oh$(M0AG>q7Dzns*Wp|13^tR(bhXPK z9hLg}q=V!svw&sQLcX|j<;5wz48X}iSlt%G)tJ%a!sXcbwnGQ1)A|vEo=g#Jz;p+- z*8YgM;cVHl4kY4MB9_L-=hGU#a2&s~N`^(x9W3h0(}S?n$a;3z5gr%#ulrN!x5il8@lx)?M+C zM5oM$k+f@c_0RGuWF=XLL=qr!+4#IOl3piVkX01r7MIf7Fy3UdwZbX|-4Qb~b z%j%0JtdyQXERtrGox4)|YFvP+SNv*R;+Y$ECSVLAL|5{kP|sGWn0<;v?o#1IilO|vkiHY~-hlHIc77JfrK$x}Pwr@5nokO!^>d$Q5 zogf$6W=fhrb-xOaEbK`4J!3|ibb^9`pEOl>C09r$Q9wzOpkKLWQ*%(-4l2tF?#}?A z1O}vZ`icZT(Zhw^o=?A`$$UY=Oax{ODUe+WE-(DT6^$$;3$YE7S%lC?QM51SI!AUL zIzs!)Ct-fYAMGPRf&4{TUIMO{DLN=i7)=4OS*qlrmbNRJqnrM@lXu zSVpJ-b&s`ZUh30QL%L#-K^xsyX$GQ!`ne?q)TmWvh}H;SJ^6#XF%1ua9j1L?mn&k+ zs#a8qy)3z^T$N=tRk}P|c~Vg&LXvrPg}jza1NdCfDxtP93P?L_l_Kzl0}VrelBF20 zV!Nw=E_=H^cQ)c|6#1(sTi5nSPXrn4@5`R#(sAqkM>rmj&l;r%d>)oreu}JOWoo zoJnR|{i7;S>c|cEI8&Z5M+ToPQBT96Y4f8B5x7EFkmyI&@wZx%TEm#JX7KVPYc8;y zCde6p4y94KGaSniHGP<06ZjQ?w-KgxN0)SEmfL_8z)Y6X!L8dw32h%NWPYKw>>_O( zJQn;<#ncg8t!kqETSKx|oF>)}{46QJM5*k3L@|eko@jriUi#|Mvbr_W8ei349y)_H zzDWM3g({>7V2ASS1+qaMdFq{6e}XRpB&GIhQ1*!r(gzmP79u*~49n>`?Amb=Uvtb^ zao*X`5L*5;Icix7CO#R(iDz=eDmrzyJDZUa`%$I&MaVn7`YJGn_aONT&7YW>CqE$V zi7aa=1uZTAh&7pWCHto+#rE-320t^ zL4FZ)WI63*Yuopijt9>_GTJ*9;hvhiODg}xs}S^uQq&v$;NL_> zGGeqv$gmDLbtEd#Iw*C-S!0(HnobNbwd6{&6diX!hg95iOz5!a-P~Gt#g$@ZIG}Bn zY->oqG_$NbUjG7mbkw3ocgv;eZrs(3oz^1-EJ`xK1%ZF3qolz(2`&yW%HGT%>UB*z zhS||fJE#4*3}F>&pG_RYt`orE3~O4~Y)46GIHAZ&4mo?bA8r3L;f@2HkMYyjn{YCw z&SgcZd#ml>gJQ2q^*Rs-`>E+ZD5nNXud80SQp4U-4a(7o;a2W$&#@D{$TvVg2Bfv3 zq~^99lAEx`F~Pd#Xv4eHj%t7ANMgU~CBI5D+_ie`Nwa?rkoT6hCl^K^Y?w^gnfM(! zRq-YM{S&MFjRU|6{1NT_Gf~h(@NwXc5{_%gwg-0P2r4_4bBM+wC+10;dT7U#005AC zLXIwZ3_dn#2Wi;$qkk zIZnpNy`>A9GDsET$}FV&UhuPXnz#FkT?37eXuuH5k4*~ z9z%Y)a7BM#1}GjJI8At4>CaUk1*99dCoiu^$o~-4Ji^J2>{otU;QSkHiV)-nO{e)y z3{xmO2|Z!U!Qhro@cXCDmcCf0r5}nWpk-Ujo41QOHZMh^4Qaj#Nt?GzOKolqWM%O; zg5K;OwqGaEb_|1lYSOlM5~xNAmN7~1R9e&aEhXfj1^E+99mQI3P$H*jdQ5!x2dAh^ z75=ejnZ|JUN!gvu4VR{%I$Kf6PeJwSs)xRUZ^687H@6E`b!O;jvgY4`7_~QBT<>xl zK2=bqcV?xlTS&vZX9>*or3~o)I{f=USqg%Wsc(UI3S=sWb0C|1i@_eoG zWl>Y*`D0@+&SY8-Z=HVMa((Z+Faf{1-Gv+4tvjn)HN2z7qTa&!J9&e}RfKMfh?;l0 zPRU8bqIynTpX)$}%-ta*9xV}YYXsB}D{{w=6@8o1_W?9^5Rn)Y5QKV9ni)vdHdNa(geo4o8qlqIwbxnkKAlWD>f#pdZ%DH1|&AsHGWXp!z zcw>|X0qvp+bj_6y_i{{h5}T_*PbtllT-=iKwo^qW>0x6#%fJe*AjF>tL{Rago?H81 zlBlRfzb8VFO}i+gQVhE%BAl7APot?DHL)rr@j9M3FYJOYno#PvrIl!y@s-lFRYi}9 zGV+B4klE&kTI3Xr*!)cXiqa?u)#bR$2}L7IS=5jQtHKQaO`ep1w!71B7tZ2j-k-8l z6*aaaZ8aPJkU~$~$ln6>fws#xe!EWI&%`g-XG%fuIkXzYE~?***VtX_bd4DHbZHT9 z$KMc|_M+Hlcx3DFBb=EiEa-b3SV8byvzuR#C-UWxAg*l_6U?#~^pjQb^8A_U_HPQe zgCy7&8o@?XIZ!1@8Z3t$6d}uo;8231E{0Mbbv-9FANa+L3K4^XMQ=W=sRVN*#x0Ay z>R4SFXjP0NJ%X1>UR@|V6XInoz!nXTgbaHK(ganH8FMIp58Ek27jzA9wZzolpiCdy zE=Jfx7I>4T3t8du8@pM#n}!L~V%pGev; zCaex?iz-f(NG%v`dMjeSA=~XLOoDlnRPjReqM#sqjA%N%f`7J_H=UrKR>VprwKVqz zl$rAaOBKGpWmrn~Sa>Kn9S2!#U< z(Q@05Uj!2f@^1GPXzNtoCci_b$sTw=Hh76-;ws}a^mFIuCEjKy*`$<#wQ(({F6<*R zSXy>4Vsvf;GpbC}%%fC4(FKa8ts)HULyvR)4knx`+y`oomv={iozwqlwDzq(EH}SH z-K%w&5mHx_eYgfmlwBui`hy{_W7|Z*ukAp$G5MYFDghAA-Cazmm39wnH;* zy!A4t?m!{`h@tXeS2B5PY*sAWT&&{C3=N9E6%bYP;n!P8wdFRz`))Ooq z5i-Hmv+R-yk){flNDdRM!-i^_D+NVJ;%ON~ZcM%sqt+-~OA)9o!sLWei)u0K?S!yH zu{K2EL|}`0CKAyJl#hlvC<8F|6ww8_jh2~Y?SvD+%t-NY1m_u5+mO+X107*M#@CI} z0zl*v*^j7<%4yPZ7^Zb%+llfub*Ax!Zaal^qTZr-9AY>j-k`k#Q~(0LLbhWW zqPSj=uSY%r;4f9%L5I;0&tJCa*`AV}BOHqwe6s#S?hlaei5_>6R7eTYDEFC_DA&eK z8}v9MMn2eDKfZ4sq zz07@@r`i{pKe-)%J&Q~~!wLYuse@%SG`@g2WddF1U<4v|M>>hx6&PGEqqfo)&sR15 z=83Q-LR(*=jI#r=4meSjrreJ^@{0#RHy1N=r`59wQ_|>}d6KAhXG<%m)eE8LD_&^- zTWYEjd~U2lAspQ#mf~3@&JKC|Bt2EGOX2E)ZBWSy_HG)!3yYk7#qCFuA3(hKrYTc| z(v0|H)vkJv4mXVJIScLRLkeCXZvH^2jch^jn@sM6=~(ZmbanvMrqwV8<7(x&uioqK z;f>FegLIS-sth0hZd~2bNk6x2YZKwNrUo1TPKY*)#+_wgj580eNlTzHjxU5vz~wWM zDI(x+YQx<8-!N`CCgQzD1sH50(43zvVv;oq@&gOsI~h$o;`VT+}Kdedjy(IDKKkCw!KYqf#0yV9AN-2_mryBd;YtQuuxt? zj{(Y_gWK!73)?yN46|Fv8r98Q=b4Vgv-FfY7M`oyE_$UFyIG~Kw8gP51G&EMg z9B07I$r`P@W4wj^m!WJIZ5ZTP2ln}L{ot=MQGwVOt}X!goVK65QAc4i; zAFKobiX~mjC%I;lvsR=-HkSluR~`cSP^YbHO!d!@p$s)esZHn6rAjdhkqzT5g>9eE zmxjoWDq$`Bec@skX=WZd)r2>CbP8>65S*JB97pU3yC*W&8G7i5x+lXj@TuJpI0!?W z8TEPygyX;-7M@dS8bM!rnNyWIvCYxD&&OL!G1nZ@AEq16J;k~Y?YDJUtV5jjyHc6a zy|n)-Fd)?|M_+~4S4}*jVKOzNr(NlyfMz;<3?zBDq36KhWRshQ-q`3*{)lspLg zMCXs3$bD7QB!|qC`YO~qC-=;vCVGPzD@BrI=?!PMf6hXh!+6s6b6!^TCSuAe6gXH>WB9C&w}-rz>0OWdVca; z6ZVU`VxjQ#SCY$zFP6RhA!j&A^Ura+@;*_6#J~5OM-ZKO^w^~28nB>Bt44I6kv|>0 zeeiiQ{wDYF6Tya%b0gwjAg2*2_|Vy5Sd%9}3rhy?8rFRik zQa(LIN430oHDDXn^(2IzCO0FY$KPOI^FR0%w?7 zBT!76g&M&##rW5lnp`PcF&2*^pq~;#mY`!uO@MVoAJSP9@}eti4N7(!4)qfbO2~aW z(fb`OcSWcbuM{{;n!`KSP)*^`3YOQ$R{HSSrckR+C3It#QXY@jFo~5UM#zdFb3;^V z9jn<~@t_hnQ_(O@x5N_D^YxbBpep)0Ae^`tMi&*6^6tvxXdNZxolfvor$}77!c3__ zZHY>^fp|{?d784uCR+??Vw04?q!33A*lvQLJCoC;*GM(Z1vTha=|gQFk46tzBo(-^WVybqvOx`#`NlSc3~n;%dnF=t2F-x3^JKYh*yDUfq)ADr zRkI;-5RU0h9oQ_CZ2E=#s*}NgDXR@!9HwRPVpo}`qGKI4$uy|j+3`#l&3AZ9n`i+gO!fm z^SX-P-ChO3#!76p9fZwmWXFi+OU-fEC~bC(DzuSUN^S?~%?t!-2%jtR#2U1bn)1vP zdwk5&IO&$iz!(wq0E0!-K&I7|eSC}qvTsu)s}Gsx%+C$OnV7o+1>6+`)QLWq#5t_( z1*7}pD`eUj(c&>Iu@W)A}Rgo@-uhU!3uav(Rs$5M3eRJF!RA!2jm7TNii$Y2&{sm<$VeIu?jiix0z!LK+CYo zw7dwpr(fU|@61%S0&87cdO>isCyNM|RTz=(CsW(;-eIt}UrqSZl$VKY_$4QVB>G6I z6a>P(lRc#D9oSV$O(k%vl2onfMlzHBv96vl%GAgdXp?yPl>RjYQ z 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%0Dg)*jw9FyQ3zv1$xsAAA&V4+x!$_| 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ⅈ`Vt=k`Z@48Z%=Z@Jjr;kxn)6{+~S{elY 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 R$o^^`CVWW&o-XZ2N?gU<5H3vY$BH- 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 jRx0wr$(C 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
    >$hvbbr&Y; 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 z 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%0A}MrDyZPV7%^jNd^Wqzh7S5B+ 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⪼HlaJEhm+wYyD1w}a?QF-9}lF-=mRDx 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 z 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 SRbF2?$g6CrfsQ`-um1xe8`sYO diff --git a/pgo-code-style.epf b/pgo-code-style.epf deleted file mode 100644 index 35f7a5e0e..000000000 --- a/pgo-code-style.epf +++ /dev/null @@ -1,336 +0,0 @@ -#Tue May 30 17:43:32 PDT 2017 -\!/= -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.codeComplete.argumentPrefixes= -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.codeComplete.argumentSuffixes= -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.codeComplete.fieldPrefixes= -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.codeComplete.fieldSuffixes= -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.codeComplete.localPrefixes= -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.codeComplete.localSuffixes= -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.codeComplete.staticFieldPrefixes= -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.codeComplete.staticFieldSuffixes= -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.codeComplete.staticFinalFieldPrefixes= -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.codeComplete.staticFinalFieldSuffixes= -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.compliance=1.8 -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.source=1.8 -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647 -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.align_type_members_on_columns=false -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_assignment=0 -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header=0 -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0 -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0 -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80 -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_type_arguments=0 -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_type_parameters=0 -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16 -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.blank_lines_after_package=1 -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.blank_lines_before_field=0 -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.blank_lines_before_method=1 -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.blank_lines_before_package=0 -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.comment.format_block_comments=true -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.comment.format_header=false -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.comment.format_html=true -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.comment.format_line_comments=true -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.comment.format_source_code=true -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.comment.indent_root_tags=true -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.comment.line_length=80 -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.compact_else_if=true -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.continuation_indentation=2 -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.indent_empty_lines=false -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.indentation.size=4 -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.join_lines_in_comments=false -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.join_wrapped_lines=false -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.lineSplit=120 -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation=common_lines -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause=common_lines -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration=common_lines -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment=common_lines -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement=common_lines -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration=common_lines -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration=common_lines -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation=common_lines -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement=common_lines -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause=common_lines -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.tabulation.char=tab -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.tabulation.size=4 -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.use_on_off_tags=false -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.wrap_before_assignment_operator=false -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.wrap_before_conditional_operator=true -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true -/instance/org.eclipse.jdt.ui/formatter_profile=_pgo -/instance/org.eclipse.jdt.ui/formatter_settings_version=12 -/instance/org.eclipse.jdt.ui/org.eclipse.jdt.ui.cleanupprofiles=\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n -/instance/org.eclipse.jdt.ui/org.eclipse.jdt.ui.exception.name=e -/instance/org.eclipse.jdt.ui/org.eclipse.jdt.ui.formatterprofiles=\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n -/instance/org.eclipse.jdt.ui/org.eclipse.jdt.ui.formatterprofiles.version=12 -/instance/org.eclipse.jdt.ui/org.eclipse.jdt.ui.gettersetter.use.is=true -/instance/org.eclipse.jdt.ui/org.eclipse.jdt.ui.ignorelowercasenames=true -/instance/org.eclipse.jdt.ui/org.eclipse.jdt.ui.importorder=java;javax;org;com; -/instance/org.eclipse.jdt.ui/org.eclipse.jdt.ui.ondemandthreshold=10 -/instance/org.eclipse.jdt.ui/org.eclipse.jdt.ui.overrideannotation=true -/instance/org.eclipse.jdt.ui/org.eclipse.jdt.ui.staticondemandthreshold=10 -/instance/org.eclipse.jdt.ui/org.eclipse.jdt.ui.text.custom_code_templates= -@org.eclipse.jdt.core=3.12.3.v20170228-1205 -@org.eclipse.jdt.ui=3.12.2.v20160929-0804 -file_export_version=3.0 diff --git a/pgo.sh b/pgo.sh deleted file mode 100755 index 27505c25f..000000000 --- a/pgo.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh - -# Runs PGo from the compiled class files, passing all command -# line argument directly to main(). - -java -cp ./lib/plume.jar:./lib/json.jar:./bin/ pgo.PGoMain $* diff --git a/src/pgo/InternalCompilerError.java b/src/pgo/InternalCompilerError.java deleted file mode 100644 index ce2850581..000000000 --- a/src/pgo/InternalCompilerError.java +++ /dev/null @@ -1,11 +0,0 @@ -package pgo; - -public class InternalCompilerError extends RuntimeException { - public InternalCompilerError() { - super("internal compiler error"); - } - - public InternalCompilerError(Exception e) { - super("internal compiler error", e); - } -} diff --git a/src/pgo/PGo.scala b/src/pgo/PGo.scala new file mode 100644 index 000000000..201b9b376 --- /dev/null +++ b/src/pgo/PGo.scala @@ -0,0 +1,145 @@ +package pgo + +import geny.Generator +import org.rogach.scallop +import org.rogach.scallop.{ScallopConf, Subcommand} +import pgo.model.{PGoError, SourceLocation} +import pgo.model.mpcal.MPCalBlock +import pgo.model.tla.TLAModule +import pgo.parser.{MPCalParser, TLAParser} +import pgo.trans.{MPCalGoCodegenPass, MPCalNormalizePass, MPCalPCalCodegenPass, MPCalSemanticCheckPass, PCalRenderPass} + +import pgo.util.Description._ + +import java.io.RandomAccessFile +import java.nio.channels.FileChannel +import java.nio.charset.StandardCharsets +import scala.util.Using + +object PGo { + implicit val pathConverter = scallop.singleArgConverter(os.Path(_, os.pwd)) + + class Config(arguments: Seq[String]) extends ScallopConf(arguments) { + banner("PGo compiler") + trait Cmd { self: ScallopConf => + val specFile = opt[os.Path](required = true) + addValidation { + if(os.exists(specFile())) { + Right(()) + } else { + Left(s"spec file ${specFile()} does not exist") + } + } + } + object GoGenCmd extends Subcommand("gogen") with Cmd { + val outFile = opt[os.Path](required = true) + val packageName = opt[String](required = false) + } + addSubcommand(GoGenCmd) + object PCalGenCmd extends Subcommand("pcalgen") with Cmd { + // pass + } + addSubcommand(PCalGenCmd) + + // one of the subcommands must be passed + addValidation { + subcommand match { + case Some(_) => Right(()) + case None => Left(s"a subcommand must be given") + } + } + + errorMessageHandler = { errMsg => + errMsg.linesIterator.foreach { line => + println(s"$printedName: $line") + } + printHelp() + sys.exit(1) + } + + verify() + } + + private def parseMPCal(specFile: os.Path): (TLAModule, MPCalBlock) = { + val underlyingFile = new SourceLocation.UnderlyingFile(specFile) + Using.Manager { use => + val fileChannel = use(new RandomAccessFile(specFile.toIO, "r").getChannel) + val buffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, fileChannel.size) + val charBuffer = StandardCharsets.UTF_8.decode(buffer) + + val tlaModule = TLAParser.readModuleBeforeTranslation(underlyingFile, charBuffer) + val mpcalBlock = MPCalParser.readBlock(underlyingFile, charBuffer, tlaModule) + (tlaModule, mpcalBlock) + }.get + } + + def run(args: Seq[String]): List[PGoError.Error] = { + val config = new Config(args) + try { + config.subcommand.get match { + case config.GoGenCmd => + var (tlaModule, mpcalBlock) = parseMPCal(config.GoGenCmd.specFile()) + MPCalSemanticCheckPass(tlaModule, mpcalBlock) + mpcalBlock = MPCalNormalizePass(tlaModule, mpcalBlock) + + val goCode = MPCalGoCodegenPass(mpcalBlock, packageName = config.GoGenCmd.packageName.toOption) + os.write(config.GoGenCmd.outFile(), goCode.linesIterator) + case config.PCalGenCmd => + var (tlaModule, mpcalBlock) = parseMPCal(config.PCalGenCmd.specFile()) + MPCalSemanticCheckPass(tlaModule, mpcalBlock) + mpcalBlock = MPCalNormalizePass(tlaModule, mpcalBlock) + + val pcalAlgorithm = MPCalPCalCodegenPass(mpcalBlock) + val renderedPCal = PCalRenderPass(pcalAlgorithm) + + val tempOutput = os.temp.apply(dir = os.pwd) + locally { + val PCalBeginTranslation = raw"""\\*\s+BEGIN\s+PLUSCAL\s+TRANSLATION""".r + val PCalEndTranslation = raw"""\\*\s+END\s+PLUSCAL\s+TRANSLATION""".r + + val renderedPCalIterator = Iterator("", "", "\\* BEGIN PLUSCAL TRANSLATION") ++ + renderedPCal.linesIterator ++ + Iterator("", "\\* END PLUSCAL TRANSLATION", "") + + var pcalBeginFound = false + var pcalEndFound = false + + os.write(tempOutput, os.read.lines.stream(config.PCalGenCmd.specFile()).zipWithIndex.flatMap { + case (PCalBeginTranslation(), lineIdx) if !pcalBeginFound => + assert(!pcalEndFound, s"at line ${lineIdx+1}, found PLUSCAL END TRANSLATION comment before PLUSCAL BEGIN TRANSLATION") + pcalBeginFound = true + Generator.from(renderedPCalIterator) + case (PCalEndTranslation(), lineIdx) => + assert(!pcalEndFound, s"at line ${lineIdx+1}, found PLUSCAL END TRANSLATION without corresponding previous PLUSCAL BEGIN TRANSLATION") + pcalEndFound = true + Generator() + case _ if pcalBeginFound && !pcalEndFound => + // skip all lines between begin and end of translation + Generator() + case (line, _) => Iterator(line) + } ++ Generator.selfClosing { + (if(!pcalBeginFound) renderedPCalIterator else Iterator.empty, () => ()) + }) + } + // move the rendered output over the spec file, replacing it + os.move(from = tempOutput, to = config.PCalGenCmd.specFile(), replaceExisting = true, atomicMove = true) + } + Nil + } catch { + case err: PGoError => err.errors + } + } + + def main(args: Array[String]): Unit = { + val errors = run(args) + if(errors.nonEmpty) { + d"failed:${ + errors.view.map(err => d"\n${err.description} at ${err.sourceLocation.longDescription.indented}") + .flattenDescriptions + }" + .linesIterator + .foreach(System.err.println) + sys.exit(1) + } + } +} diff --git a/src/pgo/PGoConstantDef.scala b/src/pgo/PGoConstantDef.scala deleted file mode 100644 index dfbf98f00..000000000 --- a/src/pgo/PGoConstantDef.scala +++ /dev/null @@ -1,5 +0,0 @@ -package pgo - -import pgo.util.SourceLocation - -case class PGoConstantDef(location: SourceLocation, contents: String) diff --git a/src/pgo/PGoConstantDefs.java b/src/pgo/PGoConstantDefs.java deleted file mode 100644 index 66d918edc..000000000 --- a/src/pgo/PGoConstantDefs.java +++ /dev/null @@ -1,31 +0,0 @@ -package pgo; - -import org.json.JSONObject; -import pgo.util.SourceLocation; - -import java.nio.file.Paths; -import java.util.HashMap; -import java.util.Map; - -public class PGoConstantDefs { - - private final Map defs; - - public PGoConstantDefs(JSONObject config, String configFilePath) { - defs = new HashMap<>(); - if (config.has("constants")) { - JSONObject constants = config.getJSONObject("constants"); - for (String name : constants.keySet()) { - String val = constants.getString(name); - defs.put(name, new PGoConstantDef( - new SourceLocation(Paths.get(configFilePath), 0, 0, 1, 1, 1, val.length()+1), - val)); - } - } - } - - public Map getConstants(){ - return defs; - } - -} diff --git a/src/pgo/PGoException.java b/src/pgo/PGoException.java deleted file mode 100644 index e703bfe8e..000000000 --- a/src/pgo/PGoException.java +++ /dev/null @@ -1,38 +0,0 @@ -package pgo; - -/** - * A PGo Exception consisting of a prefix (type of error) and a line number in - * the pluscal file - * - */ -public abstract class PGoException extends RuntimeException { - private final int line; - private final String msg; - private final String prefix; - - public PGoException(String prefix, String msg) { - super(prefix + ": " + msg); - this.prefix = prefix; - this.msg = msg; - this.line = -1; - } - - public PGoException(String prefix, String msg, int lineN) { - super(prefix + ": " + msg + " at Line: " + lineN); - this.prefix = prefix; - this.line = lineN; - this.msg = msg; - } - - public String getMsg() { - return msg; - } - - public String getPrefix() { - return prefix; - } - - public int getLine() { - return line; - } -} diff --git a/src/pgo/PGoMain.java b/src/pgo/PGoMain.java deleted file mode 100644 index 356c880bf..000000000 --- a/src/pgo/PGoMain.java +++ /dev/null @@ -1,375 +0,0 @@ -package pgo; - -import org.apache.commons.io.FileUtils; -import pgo.errors.TopLevelIssueContext; -import pgo.formatters.GoNodeFormattingVisitor; -import pgo.formatters.IndentingWriter; -import pgo.formatters.PlusCalNodeFormattingVisitor; -import pgo.model.golang.GoModule; -import pgo.model.mpcal.ModularPlusCalBlock; -import pgo.model.mpcal.ModularPlusCalUtils; -import pgo.model.pcal.PlusCalAlgorithm; -import pgo.model.tla.PlusCalDefaultInitValue; -import pgo.model.tla.TLAExpression; -import pgo.model.tla.TLAModule; -import pgo.model.tla.TLAUtils; -import pgo.model.type.Type; -import pgo.parser.PlusCalParser; -import pgo.scope.UID; -import pgo.trans.PGoTransException; -import pgo.trans.intermediate.CheckOptionsPass; -import pgo.trans.intermediate.DefinitionRegistry; -import pgo.trans.intermediate.TLABuiltins; -import pgo.trans.passes.atomicity.AtomicityInferencePass; -import pgo.trans.passes.atomicity.ModularPlusCalAtomicityInferencePass; -import pgo.trans.passes.codegen.go.ModularPlusCalGoCodeGenPass; -import pgo.trans.passes.codegen.go.PlusCalGoCodeGenPass; -import pgo.trans.passes.codegen.pluscal.PlusCalCodeGenPass; -import pgo.trans.passes.constdef.ConstantDefinitionParsingPass; -import pgo.trans.passes.desugar.mpcal.ModularPlusCalDesugarPass; -import pgo.trans.passes.expansion.ModularPlusCalMacroExpansionPass; -import pgo.trans.passes.normalising.CodeNormalisingPass; -import pgo.trans.passes.parse.mpcal.ModularPlusCalParsingPass; -import pgo.trans.passes.parse.option.OptionParserIssue; -import pgo.trans.passes.parse.option.OptionParsingPass; -import pgo.trans.passes.parse.pcal.PlusCalParsingPass; -import pgo.trans.passes.parse.tla.TLAParsingPass; -import pgo.trans.passes.type.TypeInferencePass; -import pgo.trans.passes.validation.ValidationPass; -import pgo.util.SourceLocation; - -import java.io.*; -import java.nio.CharBuffer; -import java.nio.MappedByteBuffer; -import java.nio.channels.FileChannel; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.StandardCopyOption; -import java.util.HashMap; -import java.util.Map; -import java.util.logging.Logger; -import java.util.regex.MatchResult; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class PGoMain { - private final String[] cmdArgs; - private static Logger logger; - - public PGoMain(String[] args) { - cmdArgs = args; - // Get the top Logger instance - logger = Logger.getLogger("PGoMain"); - } - - // Creates a PGoMain instance, and initiates run() below. - public static void main(String[] args) { - if (new PGoMain(args).run()) { - logger.info("Finished"); - } else { - logger.info("Terminated with errors"); - } - } - - private void validateSemantics(TopLevelIssueContext ctx, ModularPlusCalBlock modularPlusCalBlock) throws PGoTransException { - logger.info("Validating Modular PlusCal semantics"); - ValidationPass.perform(ctx, modularPlusCalBlock); - checkErrors(ctx); - } - - private ModularPlusCalBlock expandPlusCalMacros(TopLevelIssueContext ctx, ModularPlusCalBlock modularPlusCalBlock) throws PGoTransException { - logger.info("Expanding PlusCal macros"); - ModularPlusCalBlock macroExpandedModularPlusCalBlock = ModularPlusCalMacroExpansionPass.perform( - ctx, modularPlusCalBlock); - checkErrors(ctx); - - return macroExpandedModularPlusCalBlock; - } - - private void validateSemanticsPostScoping(TopLevelIssueContext ctx, DefinitionRegistry registry, - ModularPlusCalBlock modularPlusCalBlock) - throws PGoTransException { - logger.info("Validating Modular PlusCal semantics post scoping"); - ValidationPass.performPostScoping(ctx, registry, modularPlusCalBlock); - checkErrors(ctx); - } - - PlusCalAlgorithm mpcalToPcal( - Path inputFilePath, - TopLevelIssueContext ctx, - ModularPlusCalBlock modularPlusCalBlock, - TLAModule tlaModule) - throws PGoTransException { - validateSemantics(ctx, modularPlusCalBlock); - ModularPlusCalBlock macroExpandedModularPlusCalBlock = expandPlusCalMacros(ctx, modularPlusCalBlock); - - ModularPlusCalBlock desugaredModularPlusCalBlock = ModularPlusCalDesugarPass.perform( - macroExpandedModularPlusCalBlock); - - validateSemantics(ctx, desugaredModularPlusCalBlock); - DefinitionRegistry registry = new DefinitionRegistry(); - TLABuiltins.fillDefinitionRegistry(registry); - TLAUtils.fillDefinitionRegistryFromModule(registry, tlaModule); - ModularPlusCalUtils.fillDefinitionRegistryFromModularPlusCalBlock(registry, desugaredModularPlusCalBlock); - checkErrors(ctx); - validateSemanticsPostScoping(ctx, registry, desugaredModularPlusCalBlock); - - PlusCalAlgorithm algorithm = PlusCalCodeGenPass.perform(ctx, registry, desugaredModularPlusCalBlock); - checkErrors(ctx); - - return algorithm; - } - - void mpcalCompilePipeline( - Path inputFilePath, - TopLevelIssueContext ctx, - ModularPlusCalBlock modularPlusCalBlock, - TLAModule tlaModule) - throws PGoTransException, IOException { - - PlusCalAlgorithm algorithm = mpcalToPcal(inputFilePath, ctx, modularPlusCalBlock, tlaModule); - - logger.info("Generating PlusCal code"); - String serializedAlgorithm; - try ( - StringWriter writer = new StringWriter(); - IndentingWriter out = new IndentingWriter(writer) - ) { - algorithm.accept(new PlusCalNodeFormattingVisitor(out)); - serializedAlgorithm = writer.toString(); - } - // TODO deal with non-ASCII - final int startOffset; - final int endOffset; - // parse the algorithm block to know where it is - try (FileChannel fileChannel = new RandomAccessFile(inputFilePath.toFile(), "r").getChannel()) { - MappedByteBuffer buffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, fileChannel.size()); - // assume UTF-8, though technically TLA+ is ASCII only according to the book - CharBuffer inputFileContents = StandardCharsets.UTF_8.decode(buffer); - Pattern beginPattern = Pattern.compile(".*?\\\\\\*\\s+BEGIN\\s+PLUSCAL\\s+TRANSLATION", Pattern.DOTALL); - Pattern endPattern = Pattern.compile(".*?\\\\(\\*\\s+END\\s+PLUSCAL\\s+TRANSLATION)", Pattern.DOTALL); - Matcher beginMatcher = beginPattern.matcher(inputFileContents); - if(beginMatcher.lookingAt()) { - startOffset = beginMatcher.end() + 1; - Matcher endMatcher = endPattern.matcher(inputFileContents); - endMatcher.region(beginMatcher.end() + 1, beginMatcher.regionEnd()); - if(endMatcher.lookingAt()) { - endOffset = endMatcher.start(1); - } else { - endOffset = -1; - } - } else { - startOffset = -1; - endOffset = -1; - } - } - File tempFile = File.createTempFile("pluscal-", ".tla"); - tempFile.deleteOnExit(); - try ( - FileChannel source = new RandomAccessFile(inputFilePath.toFile(), "r").getChannel(); - FileChannel destination = new RandomAccessFile(tempFile, "rw").getChannel() - ) { - if (startOffset != -1) { - long pos = destination.transferFrom(source, 0, startOffset); - pos += destination.write(StandardCharsets.UTF_8.encode("\n"), pos); - pos += destination.write(StandardCharsets.UTF_8.encode(serializedAlgorithm), pos); - pos += destination.write(StandardCharsets.UTF_8.encode("\n\\* END PLUSCAL TRANSLATION"), pos); - pos += destination.transferFrom(source.position(endOffset), pos, source.size() - endOffset); - destination.truncate(pos); - } else { - final int blockEndOffset = modularPlusCalBlock.getLocation().getEndOffset(); - long pos = destination.transferFrom(source, 0, blockEndOffset); - pos += destination.write( - StandardCharsets.UTF_8.encode("\n\n\\* BEGIN PLUSCAL TRANSLATION\n"), - pos); - pos += destination.write(StandardCharsets.UTF_8.encode(serializedAlgorithm), pos); - pos += destination.write( - StandardCharsets.UTF_8.encode("\n\\* END PLUSCAL TRANSLATION\n\n"), - pos); - pos += destination.transferFrom(source.position(blockEndOffset), pos, source.size() - blockEndOffset); - destination.truncate(pos); - } - } - Files.move(tempFile.toPath(), inputFilePath, StandardCopyOption.REPLACE_EXISTING); - } - - void specToGoPipeline( - boolean isMPCal, - PGoOptions opts, - Path inputFilePath, - String destFile, - TopLevelIssueContext ctx, - ModularPlusCalBlock modularPlusCalBlock, - TLAModule tlaModule) - throws PGoTransException, IOException { - - logger.info("Parsing constant definitions from configuration"); - Map constantDefinitions = ConstantDefinitionParsingPass.perform( - opts.constants.getConstants()); - checkErrors(ctx); - - logger.info("Checking compile options for sanity"); - CheckOptionsPass.perform(ctx, modularPlusCalBlock, opts); - checkErrors(ctx); - - logger.info("Expanding macros"); - validateSemantics(ctx, modularPlusCalBlock); - ModularPlusCalBlock macroExpandedModularPlusCalBlock = expandPlusCalMacros(ctx, modularPlusCalBlock); - DefinitionRegistry registry = new DefinitionRegistry(); - TLABuiltins.fillDefinitionRegistry(registry); - TLAUtils.fillDefinitionRegistryFromModule(registry, tlaModule); - ModularPlusCalUtils.fillDefinitionRegistryFromModularPlusCalBlock(registry, macroExpandedModularPlusCalBlock); - for(UID constant: registry.getConstants()) { - String name = registry.getConstantName(constant); - TLAExpression value = constantDefinitions.get(name); - if(value == null) { - //throw new PGoTransException("Constant "+name+" has no specified value"); - registry.setConstantValue(constant, new PlusCalDefaultInitValue(SourceLocation.unknown())); - } else { - registry.setConstantValue(constant, value); - TLAUtils.fillDefinitionRegistryFromExpression(registry, value); - } - } - validateSemanticsPostScoping(ctx, registry, macroExpandedModularPlusCalBlock); - - logger.info("Inferring types"); - Map typeMap = TypeInferencePass.perform(ctx, registry, macroExpandedModularPlusCalBlock); - checkErrors(ctx); - - logger.info("Inferring atomicity requirements"); - if (isMPCal) { - ModularPlusCalAtomicityInferencePass.perform(registry, macroExpandedModularPlusCalBlock); - } else { - AtomicityInferencePass.perform(registry, macroExpandedModularPlusCalBlock); - } - - // compilation of (M)PCal -> Go - logger.info("Initial code generation"); - GoModule goModule; - if (isMPCal) { - goModule = ModularPlusCalGoCodeGenPass.perform(registry, typeMap, opts, macroExpandedModularPlusCalBlock); - } else { - goModule = PlusCalGoCodeGenPass.perform(registry, typeMap, opts, macroExpandedModularPlusCalBlock); - } - - logger.info("Normalising generated code"); - GoModule normalisedGoModule = CodeNormalisingPass.perform(goModule); - - logger.info("Writing Go module to \"" + destFile + "\""); - try( - BufferedWriter writer = Files.newBufferedWriter(Paths.get(destFile)); - IndentingWriter out = new IndentingWriter(writer) - ) { - normalisedGoModule.accept(new GoNodeFormattingVisitor(out)); - } - - logger.info("Copying necessary Go packages to folder \"" + opts.buildDir + "\""); - copyPackages(opts.buildDir); - - logger.info("Formatting generated Go code"); - try { - goFmt(destFile); - } catch (Exception e) { - logger.warning(String.format("Failed to format Go code. Error: %s", e.getMessage())); - } - } - - // Top-level workhorse method. - public boolean run() { - try { - TopLevelIssueContext ctx = new TopLevelIssueContext(); - - // Check options, set up logging. - PGoOptions opts = OptionParsingPass.perform(ctx, logger, cmdArgs); - if (ctx.hasErrors()) { - System.err.println(ctx.format()); - opts.printHelp(); - return false; - } - - logger.info("Opening source file"); - Path inputFilePath = Paths.get(opts.inputFilePath); - final boolean isMPCal; - final ModularPlusCalBlock modularPlusCalBlock; - final TLAModule tlaModule; - - try (FileChannel fileChannel = new RandomAccessFile(inputFilePath.toFile(), "r").getChannel()) { - MappedByteBuffer buffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, fileChannel.size()); - // assume UTF-8, though technically TLA+ is ASCII only according to the book - CharBuffer inputFileContents = StandardCharsets.UTF_8.decode(buffer); - - isMPCal = ModularPlusCalParsingPass.hasModularPlusCalBlock(inputFilePath, inputFileContents); - if (opts.mpcalCompile && !isMPCal) { - ctx.error(new OptionParserIssue("Specification does not contain a Modular PlusCal block.")); - checkErrors(ctx); - } - logger.info("Parsing TLA+ module"); - tlaModule = TLAParsingPass.perform(inputFilePath, inputFileContents); - checkErrors(ctx); - - if (isMPCal) { - logger.info("Parsing modular PlusCal code"); - modularPlusCalBlock = ModularPlusCalParsingPass.perform(inputFilePath, inputFileContents, tlaModule); - checkErrors(ctx); - } else { - logger.info("Parsing PlusCal code"); - final PlusCalAlgorithm plusCalAlgorithm = PlusCalParsingPass.perform(inputFilePath, inputFileContents, tlaModule); - checkErrors(ctx); - modularPlusCalBlock = ModularPlusCalBlock.from(plusCalAlgorithm); - } - } - - if (opts.mpcalCompile) { - mpcalCompilePipeline(inputFilePath, ctx, modularPlusCalBlock, tlaModule); - } else { - String destFile; - - if (isMPCal) { - if (opts.buildPackage == null) { - ctx.error(new OptionParserIssue("Modular PlusCal compilation requires a dest_package configuration field")); - checkErrors(ctx); - } - - String packageDir = opts.buildDir + "/src/" + opts.buildPackage; - File packageDirFile = new File(packageDir); - packageDirFile.mkdirs(); - destFile = packageDir + "/" + opts.buildPackage + ".go"; - } else { - if (opts.buildFile == null) { - ctx.error(new OptionParserIssue("PlusCal compilation requires a dest_file configuration field")); - checkErrors(ctx); - } - - destFile = opts.buildDir + "/" + opts.buildFile; - } - - - specToGoPipeline(isMPCal, opts, inputFilePath, destFile, ctx, modularPlusCalBlock, tlaModule); - } - } catch (PGoTransException | IOException e) { - logger.severe("found issues"); - e.printStackTrace(); - return false; - } - - return true; - } - - private static void checkErrors(TopLevelIssueContext ctx) throws PGoTransException { - if (ctx.hasErrors()) { - throw new PGoTransException(ctx.format()); - } - } - - private static void copyPackages(String buildDir) throws IOException { - FileUtils.copyDirectory(new File("src/runtime/pgo"), new File(buildDir + "/src/pgo")); - } - - private void goFmt(String... files) throws IOException, InterruptedException { - String command = "gofmt -w " + String.join(" ", files); - Process p = Runtime.getRuntime().exec(command); - p.waitFor(); - } -} diff --git a/src/pgo/PGoNetOptions.java b/src/pgo/PGoNetOptions.java deleted file mode 100644 index 400508573..000000000 --- a/src/pgo/PGoNetOptions.java +++ /dev/null @@ -1,133 +0,0 @@ -package pgo; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.Vector; - -// Wraps options related to networking in the generated GoRoutineStatement code. -// Networking related options are defined in the JSON configuration -// file and specify details about endpoints (e.g. IP addresses -// and ports). See the +config-sample.json+ file included in this -// repository for an example of how to define these properties. - -// Networking options involve a number of concepts: shared state -// management, the separation of different processes in the network, and -// how they are connected together. Each of these components are handled -// by separate classes (see documentation for the inner classes below). -// -// PlusCalIf there are semantic errors in the configuration of any of these -// aspects, the associated class throws an exception. That is caught -// by the +PGoOptions+ class (when processing user input) which is then able -// to display an appropriate error message to the user. -public class PGoNetOptions { - - // This class encapsulates state management options. Since processes now run in - // separate hosts, shared state needs to be mapped either to a centralized source - // or distributed among a number of nodes in the network. - // - // This class ensures that the options provided in the configuration file make - // sense, i.e., whether they use a known/supported state management strategy. - public static class StateOptions { - public static final String STATE_ETCD = "etcd"; - public static final String STATE_SERVER = "state-server"; - - private static final String DEFAULT_STATE_STRATEGY = STATE_SERVER; - private static final int DEFAULT_TIMEOUT = 3; - - public String strategy; - public Vector endpoints; - public Vector peers; - public int timeout; - - public StateOptions(JSONObject config) { - int i; - this.endpoints = new Vector<>(); - this.peers = new Vector<>(); - - if (config.has("strategy")) { - this.strategy = config.getString("strategy"); - } else { - this.strategy = DEFAULT_STATE_STRATEGY; - } - - if (config.has("endpoints")) { - JSONArray endpoints = config.getJSONArray("endpoints"); - for (i = 0; i < endpoints.length(); i++) { - this.endpoints.add(endpoints.getString(i)); - } - } - - JSONArray peers = config.getJSONArray("peers"); - for (i = 0; i < peers.length(); i++) { - this.peers.add(peers.getString(i)); - } - - if (config.has("timeout")) { - this.timeout = config.getInt("timeout"); - } else { - this.timeout = DEFAULT_TIMEOUT; - } - } - } - - // fields to be extracted from the JSON configuration file - public static final String NETWORKING_FIELD = "networking"; - public static final String STATE_FIELD = "state"; - - // allows the developer to easily turn off networking by setting this parameter to +false+ - private final boolean enabled; - - private StateOptions stateOptions; - - // This constructor expects a +JSONObject+ as parameter - this should be the data structure - // representing the entire configuration file. Separate parts of the configuration file - // are then passed to specific components (see inner classes above), each of which has - // the responsibility to verify whether the configuration is valid. - public PGoNetOptions(JSONObject config) throws PGoOptionException { - if (!config.has(NETWORKING_FIELD)) { - enabled = false; - return; - } - - try { - JSONObject netConfig = config.getJSONObject(NETWORKING_FIELD); - if (!netConfig.getBoolean("enabled")) { - enabled = false; - return; - } - - JSONObject stateConfig = netConfig.getJSONObject(STATE_FIELD); - enabled = true; - stateOptions = new StateOptions(stateConfig); - } catch (JSONException e) { - throw new PGoOptionException("Configuration is invalid: " + e.getMessage()); - } - - validate(); - } - - private void validate() throws PGoOptionException { - if (stateOptions.peers.size() <= 0) { - throw new PGoOptionException("No peer specified"); - } - switch (stateOptions.strategy) { - case StateOptions.STATE_ETCD: - if (stateOptions.endpoints.size() <= 0) { - throw new PGoOptionException("No endpoint specified"); - } - break; - case StateOptions.STATE_SERVER: - // nothing, for now - break; - default: - throw new PGoOptionException("Invalid state strategy: " + stateOptions.strategy); - } - } - - public boolean isEnabled() { - return this.enabled; - } - public StateOptions getStateOptions() { return this.stateOptions; } -} diff --git a/src/pgo/PGoOptionException.java b/src/pgo/PGoOptionException.java deleted file mode 100644 index e14d75454..000000000 --- a/src/pgo/PGoOptionException.java +++ /dev/null @@ -1,9 +0,0 @@ -package pgo; - -public class PGoOptionException extends Exception { - - public PGoOptionException(String string) { - super(string); - } - -} diff --git a/src/pgo/PGoOptions.java b/src/pgo/PGoOptions.java deleted file mode 100644 index af033352a..000000000 --- a/src/pgo/PGoOptions.java +++ /dev/null @@ -1,107 +0,0 @@ -package pgo; - -import org.json.JSONException; -import org.json.JSONObject; -import plume.Option; -import plume.Options; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; - -public class PGoOptions { - public static final String VERSION = "0.1.4"; - - @Option(value = "Version", aliases = {"-version"}) - public boolean version = false; - - @Option(value = "-h Print usage information", aliases = { "-help" }) - public boolean help = false; - - @Option(value = "-q Reduce printing during execution", aliases = { "-quiet" }) - public boolean logLvlQuiet = false; - - /** - * Be verbose, print extra detailed information. Sets the log level to FINE. - */ - @Option(value = "-v Print detailed information during execution ", aliases = { "-verbose" }) - public boolean logLvlVerbose = false; - - @Option(value = "-m Compile a Modular PlusCal spec to vanilla PlusCal", aliases = { "-mpcal" }) - public boolean mpcalCompile = false; - - @Option(value = "-c path to the configuration file, if any") - public String configFilePath; - - public String inputFilePath; - - // fields extracted from the JSON configuration file - public String buildDir; - public String buildFile; - public String buildPackage; - public PGoNetOptions net; - public PGoConstantDefs constants; - - private final Options plumeOptions; - private final String[] remainingArgs; - - public void printHelp() { - plumeOptions.print_usage(); - } - - public PGoOptions(String[] args) { - plumeOptions = new Options("pgo [options] spec", this); - remainingArgs = plumeOptions.parse_or_usage(args); - } - - public void parse() throws PGoOptionException { - if (version) { - System.out.println("PGo version " + VERSION); - System.exit(0); - } - - if (help || remainingArgs.length != 1) { - printHelp(); - System.exit(0); - } - - inputFilePath = remainingArgs[0]; - - if (!mpcalCompile) { - // a configuration file is always required unless we are compiling from - // Modular PlusCal to vanilla PlusCal. - if (configFilePath == null || configFilePath.isEmpty()) { - throw new PGoOptionException("Configuration file is required"); - } - - String s; - - try { - byte[] jsonBytes = Files.readAllBytes(Paths.get(configFilePath)); - s = new String(jsonBytes); - } catch (IOException ex) { - throw new PGoOptionException("Error reading configuration file: " + ex.getMessage()); - } - - JSONObject config; - - try { - config = new JSONObject(s); - } catch (JSONException e) { - throw new PGoOptionException(configFilePath + ": parsing error: " + e.getMessage()); - } - - JSONObject build = config.getJSONObject("build"); - buildDir = build.getString("output_dir"); - if (build.has("dest_file")) { - buildFile = config.getJSONObject("build").getString("dest_file"); - } - if (build.has("dest_package")) { - buildPackage = config.getJSONObject("build").getString("dest_package"); - } - - net = new PGoNetOptions(config); - constants = new PGoConstantDefs(config, configFilePath); - } - } -} diff --git a/src/pgo/TODO.java b/src/pgo/TODO.java deleted file mode 100644 index 117a50482..000000000 --- a/src/pgo/TODO.java +++ /dev/null @@ -1,7 +0,0 @@ -package pgo; - -public class TODO extends RuntimeException { - public TODO() { - super("TODO"); - } -} diff --git a/src/pgo/Unreachable.java b/src/pgo/Unreachable.java deleted file mode 100644 index 075d67f2f..000000000 --- a/src/pgo/Unreachable.java +++ /dev/null @@ -1,11 +0,0 @@ -package pgo; - -public class Unreachable extends RuntimeException { - public Unreachable() { - super("unreachable"); - } - - public Unreachable(Exception e) { - super("unreachable", e); - } -} diff --git a/src/pgo/errors/Context.java b/src/pgo/errors/Context.java deleted file mode 100644 index 7cbe927e3..000000000 --- a/src/pgo/errors/Context.java +++ /dev/null @@ -1,7 +0,0 @@ -package pgo.errors; - -public abstract class Context { - - public abstract T accept(ContextVisitor ctx) throws E; - -} diff --git a/src/pgo/errors/ContextVisitor.java b/src/pgo/errors/ContextVisitor.java deleted file mode 100644 index dac34bb49..000000000 --- a/src/pgo/errors/ContextVisitor.java +++ /dev/null @@ -1,11 +0,0 @@ -package pgo.errors; - -import pgo.trans.passes.expansion.ExpandingMacroCall; -import pgo.trans.intermediate.WhileLoadingUnit; - -public abstract class ContextVisitor { - - public abstract T visit(WhileLoadingUnit whileLoadingUnit) throws E; - public abstract T visit(ExpandingMacroCall expandingMacroCall) throws E; - -} diff --git a/src/pgo/errors/Issue.java b/src/pgo/errors/Issue.java deleted file mode 100644 index 45e773c73..000000000 --- a/src/pgo/errors/Issue.java +++ /dev/null @@ -1,37 +0,0 @@ -package pgo.errors; - -import pgo.Unreachable; -import pgo.formatters.IndentingWriter; -import pgo.formatters.IssueFormattingVisitor; -import pgo.trans.PGoTransException; - -import java.io.IOException; -import java.io.StringWriter; - -public abstract class Issue extends PGoTransException { - public Issue() { - super(""); - } - public Issue(String msg) { - super(msg); - } - - @Override - public String getMessage() { - StringWriter sw = new StringWriter(); - IndentingWriter out = new IndentingWriter(sw); - try { - accept(new IssueFormattingVisitor(out)); - } catch (IOException e) { - throw new Unreachable(); // string ops don't throw IO exceptions - } - return sw.getBuffer().toString(); - } - - public Issue withContext(Context ctx) { - return new IssueWithContext(this, ctx); - } - - public abstract T accept(IssueVisitor v) throws E; - -} diff --git a/src/pgo/errors/IssueContext.java b/src/pgo/errors/IssueContext.java deleted file mode 100644 index de63c8f05..000000000 --- a/src/pgo/errors/IssueContext.java +++ /dev/null @@ -1,12 +0,0 @@ -package pgo.errors; - -public abstract class IssueContext { - - public abstract void error(Issue err); - - public abstract boolean hasErrors(); - - public IssueContext withContext(Context context) { - return new NestedIssueContext(this, context); - } -} diff --git a/src/pgo/errors/IssueVisitor.java b/src/pgo/errors/IssueVisitor.java deleted file mode 100644 index 2e10e197d..000000000 --- a/src/pgo/errors/IssueVisitor.java +++ /dev/null @@ -1,45 +0,0 @@ -package pgo.errors; - -import pgo.model.type.BacktrackingFailureIssue; -import pgo.model.type.NoMatchingFieldIssue; -import pgo.model.type.InfiniteTypeIssue; -import pgo.model.type.UnsatisfiableConstraintIssue; -import pgo.trans.intermediate.IOErrorIssue; -import pgo.trans.intermediate.UnsupportedFeatureIssue; -import pgo.trans.passes.codegen.pluscal.RefMismatchIssue; -import pgo.trans.passes.expansion.*; -import pgo.trans.passes.parse.option.OptionParserIssue; -import pgo.trans.passes.parse.pcal.PlusCalParserIssue; -import pgo.trans.passes.parse.ParsingIssue; -import pgo.trans.passes.type.TypeInferenceFailureIssue; -import pgo.trans.passes.validation.*; - -public abstract class IssueVisitor { - public abstract T visit(IssueWithContext issueWithContext) throws E; - public abstract T visit(OptionParserIssue optionParserIssue) throws E; - public abstract T visit(PlusCalParserIssue plusCalParserIssue) throws E; - public abstract T visit(IOErrorIssue ioErrorIssue) throws E; - public abstract T visit(ParsingIssue parsingIssue) throws E; - public abstract T visit(NoMatchingFieldIssue noMatchingFieldIssue) throws E; - public abstract T visit(NonRefParamModification nonRefParamModification) throws E; - public abstract T visit(CircularModuleReferenceIssue circularModuleReferenceIssue) throws E; - public abstract T visit(UnsupportedFeatureIssue unsupportedFeatureIssue) throws E; - public abstract T visit(UnresolvableMacroCallIssue unresolvableMacroCallIssue) throws E; - public abstract T visit(MacroArgumentCountMismatchIssue macroArgumentCountMismatchIssue) throws E; - public abstract T visit(RecursiveMacroCallIssue recursiveMacroCallIssue) throws E; - public abstract T visit(InfiniteTypeIssue infiniteTypeIssue) throws E; - public abstract T visit(MacroArgumentInnerScopeConflictIssue macroArgumentInnerScopeConflictIssue) throws E; - public abstract T visit(MacroNameConflictIssue macroNameConflictIssue) throws E; - public abstract T visit(BacktrackingFailureIssue backtrackingFailureIssue) throws E; - public abstract T visit(UnsatisfiableConstraintIssue unsatisfiableConstraintIssue) throws E; - public abstract T visit(TypeInferenceFailureIssue typeInferenceFailureIssue) throws E; - public abstract T visit(MissingLabelIssue missingLabelIssue) throws E; - public abstract T visit(LabelNotAllowedIssue labelNotAllowedIssue) throws E; - public abstract T visit(ReservedLabelNameIssue reservedLabelNameIssue) throws E; - public abstract T visit(StatementNotAllowedIssue statementNotAllowedIssue) throws E; - public abstract T visit(InstanceArgumentCountMismatchIssue instanceArgumentCountMismatchIssue) throws E; - public abstract T visit(InconsistentInstantiationIssue inconsistentInstantiationIssue) throws E; - public abstract T visit(RefMismatchIssue refMismatchIssue) throws E; - public abstract T visit(InvalidArchetypeResourceUsageIssue invalidArchetypeResourceUsageIssue) throws E; - public abstract T visit(VariableMappedMultipleTimesIssue variableMappedMultipleTimesIssue) throws E; -} diff --git a/src/pgo/errors/IssueWithContext.java b/src/pgo/errors/IssueWithContext.java deleted file mode 100644 index d0a3251af..000000000 --- a/src/pgo/errors/IssueWithContext.java +++ /dev/null @@ -1,24 +0,0 @@ -package pgo.errors; - -public class IssueWithContext extends Issue { - Context context; - Issue issue; - - public IssueWithContext(Issue issue, Context context) { - this.issue = issue; - this.context = context; - } - - public Issue getIssue() { - return issue; - } - - public Context getContext() { - return context; - } - - @Override - public T accept(IssueVisitor v) throws E { - return v.visit(this); - } -} diff --git a/src/pgo/errors/NestedIssueContext.java b/src/pgo/errors/NestedIssueContext.java deleted file mode 100644 index 99ce20089..000000000 --- a/src/pgo/errors/NestedIssueContext.java +++ /dev/null @@ -1,23 +0,0 @@ -package pgo.errors; - -public class NestedIssueContext extends IssueContext { - - IssueContext parent; - Context context; - - public NestedIssueContext(IssueContext parent, Context context) { - this.parent = parent; - this.context = context; - } - - @Override - public void error(Issue err) { - parent.error(err.withContext(context)); - } - - @Override - public boolean hasErrors() { - return parent.hasErrors(); - } - -} diff --git a/src/pgo/errors/TopLevelIssueContext.java b/src/pgo/errors/TopLevelIssueContext.java deleted file mode 100644 index 2ccf76305..000000000 --- a/src/pgo/errors/TopLevelIssueContext.java +++ /dev/null @@ -1,57 +0,0 @@ -package pgo.errors; - -import pgo.formatters.IndentingWriter; -import pgo.formatters.IssueFormattingVisitor; - -import java.io.IOException; -import java.io.StringWriter; -import java.util.ArrayList; -import java.util.List; - -public class TopLevelIssueContext extends IssueContext { - - List errors; - - public TopLevelIssueContext() { - this.errors = new ArrayList<>(); - } - - @Override - public void error(Issue err) { - errors.add(err); - } - - @Override - public boolean hasErrors() { - return !errors.isEmpty(); - } - - public List getIssues(){ - return errors; - } - - public void format(IndentingWriter out) throws IOException { - out.write("Detected "); - out.write(Integer.toString(errors.size())); - if(errors.size() == 1) { - out.write(" issue:"); - }else { - out.write(" issues:"); - } - for(Issue e : errors) { - out.newLine(); - e.accept(new IssueFormattingVisitor(out)); - } - } - - public String format() { - StringWriter w = new StringWriter(); - IndentingWriter out = new IndentingWriter(w); - try { - format(out); - } catch (IOException e) { - throw new RuntimeException("StringWriter should not throw IOException", e); - } - return w.toString(); - } -} diff --git a/src/pgo/formatters/ContextFormattingVisitor.java b/src/pgo/formatters/ContextFormattingVisitor.java deleted file mode 100644 index c69816d2a..000000000 --- a/src/pgo/formatters/ContextFormattingVisitor.java +++ /dev/null @@ -1,35 +0,0 @@ -package pgo.formatters; - -import pgo.errors.ContextVisitor; -import pgo.trans.passes.expansion.ExpandingMacroCall; -import pgo.trans.intermediate.WhileLoadingUnit; - -import java.io.IOException; - -public class ContextFormattingVisitor extends ContextVisitor { - - private final IndentingWriter out; - - public ContextFormattingVisitor(IndentingWriter out) { - this.out = out; - } - - @Override - public Void visit(WhileLoadingUnit whileLoadingUnit) throws IOException { - out.write("while loading unit required from line "); - out.write(Integer.toString(whileLoadingUnit.getUnit().getLocation().getStartLine())); - out.write(" column "); - out.write(Integer.toString(whileLoadingUnit.getUnit().getLocation().getStartColumn())); - return null; - } - - @Override - public Void visit(ExpandingMacroCall expandingMacroCall) throws IOException { - out.write("while expanding macro call at line "); - out.write(Integer.toString(expandingMacroCall.getMacroCall().getLocation().getStartLine())); - out.write(" column "); - out.write(Integer.toString(expandingMacroCall.getMacroCall().getLocation().getStartColumn())); - return null; - } - -} diff --git a/src/pgo/formatters/DerivedFormattingVisitor.java b/src/pgo/formatters/DerivedFormattingVisitor.java deleted file mode 100644 index a4344c5a0..000000000 --- a/src/pgo/formatters/DerivedFormattingVisitor.java +++ /dev/null @@ -1,81 +0,0 @@ -package pgo.formatters; - -import pgo.model.type.constraint.MonomorphicConstraint; -import pgo.model.type.constraint.PolymorphicConstraint; -import pgo.model.type.Type; -import pgo.scope.UID; -import pgo.trans.intermediate.OperatorAccessor; -import pgo.util.Derived; -import pgo.util.DerivedVisitor; -import pgo.util.Origin; - -import java.io.IOException; -import java.util.List; - -public class DerivedFormattingVisitor extends DerivedVisitor { - private final IndentingWriter out; - - public DerivedFormattingVisitor(IndentingWriter out) { - this.out = out; - } - - public void writeOrigins(List origins) throws IOException { - if (origins.isEmpty()) { - out.write(" derived from ???"); - } else { - out.write(" derived from "); - boolean first = true; - try (IndentingWriter.Indent ignored = out.indent()){ - for (Origin o : origins) { - if (first) { - first = false; - } else { - out.write(", "); - } - o.accept(new OriginFormattingVisitor(out)); - } - } - } - } - - private void writeOrigins(Derived d) throws IOException { - writeOrigins(d.getOrigins()); - } - - @Override - public Void visit(UID uid) throws IOException { - out.write("symbol"); - writeOrigins(uid); - return null; - } - - @Override - public Void visit(Type type) throws IOException { - out.write("type ["); - type.accept(new TypeFormattingVisitor(out)); - out.write("]"); - writeOrigins(type); - return null; - } - - @Override - public Void visit(OperatorAccessor operatorAccessor) throws IOException { - out.write("TLA operator"); - writeOrigins(operatorAccessor); - return null; - } - - @Override - public Void visit(MonomorphicConstraint pGoTypeMonomorphicConstraint) throws IOException { - out.write("type constraint"); - writeOrigins(pGoTypeMonomorphicConstraint); - return null; - } - - @Override - public Void visit(PolymorphicConstraint pGoTypePolymorphicConstraint) throws IOException { - out.write("polymorphic type constraint"); - writeOrigins(pGoTypePolymorphicConstraint); - return null; - } -} diff --git a/src/pgo/formatters/FormattingTools.java b/src/pgo/formatters/FormattingTools.java deleted file mode 100644 index 9c37607bf..000000000 --- a/src/pgo/formatters/FormattingTools.java +++ /dev/null @@ -1,25 +0,0 @@ -package pgo.formatters; - -import java.io.IOException; -import java.io.Writer; -import java.util.List; - -public class FormattingTools { - private FormattingTools() {} - - public interface Formatter{ - void format(T param) throws IOException; - } - - public static void writeCommaSeparated(Writer out, List items, Formatter writer) throws IOException { - boolean isFirst = true; - for (T item : items) { - if (!isFirst) { - out.write(", "); - } - isFirst = false; - writer.format(item); - } - } - -} diff --git a/src/pgo/formatters/GoBinopFormattingVisitor.java b/src/pgo/formatters/GoBinopFormattingVisitor.java deleted file mode 100644 index 5e1191501..000000000 --- a/src/pgo/formatters/GoBinopFormattingVisitor.java +++ /dev/null @@ -1,248 +0,0 @@ -package pgo.formatters; - -import pgo.Unreachable; -import pgo.model.golang.*; - -import java.io.IOException; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; - -public class GoBinopFormattingVisitor extends GoExpressionVisitor { - - private final IndentingWriter out; - private final int precedence; - - private static final Map operatorPrecedence = new HashMap<>(); - static{ - // * / % << >> & &^ - for(GoBinop.Operation op : Arrays.asList( - GoBinop.Operation.TIMES, GoBinop.Operation.DIVIDE, - GoBinop.Operation.MOD, GoBinop.Operation.LSHIFT, - GoBinop.Operation.RSHIFT, GoBinop.Operation.BAND, - GoBinop.Operation.BCLEAR)){ - operatorPrecedence.put(op, 6); - } - // - - operatorPrecedence.put(GoBinop.Operation.MINUS, 5); - // + | ^ - for(GoBinop.Operation op : Arrays.asList(GoBinop.Operation.PLUS, GoBinop.Operation.BOR, GoBinop.Operation.BXOR)){ - operatorPrecedence.put(op, 4); - } - // == != < <= > >= - for(GoBinop.Operation op : Arrays.asList(GoBinop.Operation.EQ, GoBinop.Operation.NEQ, - GoBinop.Operation.LT, GoBinop.Operation.LEQ, - GoBinop.Operation.GT, GoBinop.Operation.GEQ)){ - operatorPrecedence.put(op, 3); - } - // && - operatorPrecedence.put(GoBinop.Operation.AND, 2); - // || - operatorPrecedence.put(GoBinop.Operation.OR, 1); - } - - public GoBinopFormattingVisitor(IndentingWriter out, int precedence){ - this.out = out; - this.precedence = precedence; - } - - @Override - public Void visit(GoVariableName v) throws IOException { - v.accept(new GoExpressionFormattingVisitor(out)); - return null; - } - - @Override - public Void visit(GoBuiltins.BuiltinConstant v) throws IOException { - v.accept(new GoExpressionFormattingVisitor(out)); - return null; - } - - @Override - public Void visit(GoIntLiteral intLiteral) throws IOException { - intLiteral.accept(new GoExpressionFormattingVisitor(out)); - return null; - } - - @Override - public Void visit(GoMapLiteral mapConstructor) throws IOException { - mapConstructor.accept(new GoExpressionFormattingVisitor(out)); - return null; - } - - @Override - public Void visit(GoStringLiteral stringLiteral) throws IOException { - stringLiteral.accept(new GoExpressionFormattingVisitor(out)); - return null; - } - - @Override - public Void visit(GoIndexExpression index) throws IOException { - index.accept(new GoExpressionFormattingVisitor(out)); - return null; - } - - @Override - public Void visit(GoSliceOperator slice) throws IOException { - slice.accept(new GoExpressionFormattingVisitor(out)); - return null; - } - - @Override - public Void visit(GoSliceLiteral sliceConstructor) throws IOException { - sliceConstructor.accept(new GoExpressionFormattingVisitor(out)); - return null; - } - - @Override - public Void visit(GoTypeAssertion typeAssertion) throws IOException { - typeAssertion.accept(new GoExpressionFormattingVisitor(out)); - return null; - } - - @Override - public Void visit(GoAnonymousFunction anonymousFunction) throws IOException { - anonymousFunction.accept(new GoExpressionFormattingVisitor(out)); - return null; - } - - @Override - public Void visit(GoCall call) throws IOException { - call.accept(new GoExpressionFormattingVisitor(out)); - return null; - } - - @Override - public Void visit(GoTypeCast typeCast) throws IOException { - typeCast.accept(new GoExpressionFormattingVisitor(out)); - return null; - } - - @Override - public Void visit(GoStructLiteral structLiteral) throws IOException { - structLiteral.accept(new GoExpressionFormattingVisitor(out)); - return null; - } - - @Override - public Void visit(GoBinop binop) throws IOException { - int newPrecedence = operatorPrecedence.get(binop.getOperation()); - int nextPrecedence = newPrecedence; - if(newPrecedence < precedence){ - nextPrecedence = 0; - out.write("("); - } - binop.getLHS().accept(new GoBinopFormattingVisitor(out, nextPrecedence)); - out.write(" "); - switch(binop.getOperation()) { - case AND: - out.write("&&"); - break; - case BAND: - out.write("&"); - break; - case BCLEAR: - out.write("&^"); - break; - case BOR: - out.write("|"); - break; - case BXOR: - out.write("^"); - break; - case DIVIDE: - out.write("/"); - break; - case EQ: - out.write("=="); - break; - case GEQ: - out.write(">="); - break; - case GT: - out.write(">"); - break; - case LEQ: - out.write("<="); - break; - case LSHIFT: - out.write("<<"); - break; - case LT: - out.write("<"); - break; - case MINUS: - out.write("-"); - break; - case MOD: - out.write("%"); - break; - case NEQ: - out.write("!="); - break; - case OR: - out.write("||"); - break; - case PLUS: - out.write("+"); - break; - case RSHIFT: - out.write(">>"); - break; - case TIMES: - out.write("*"); - break; - default: - throw new Unreachable(); - } - out.write(" "); - binop.getRHS().accept(new GoBinopFormattingVisitor(out, nextPrecedence)); - if(newPrecedence < precedence){ - out.write(")"); - } - return null; - } - - @Override - public Void visit(GoUnary unary) throws IOException { - switch (unary.getOperation()) { - case POS: - out.write("+"); - break; - case NEG: - out.write("-"); - break; - case NOT: - out.write("!"); - break; - case COMPLEMENT: - out.write("^"); - break; - case DEREF: - out.write("*"); - break; - case ADDR: - out.write("&"); - break; - case RECV: - out.write("<-"); - break; - default: - throw new Unreachable(); - } - unary.getTarget().accept(new GoBinopFormattingVisitor(out, 6)); // max precedence + 1 - return null; - } - - @Override - public Void visit(GoSelectorExpression dot) throws IOException { - dot.accept(new GoExpressionFormattingVisitor(out)); - return null; - } - - @Override - public Void visit(GoMakeExpression make) throws IOException { - make.accept(new GoExpressionFormattingVisitor(out)); - return null; - } -} diff --git a/src/pgo/formatters/GoDeclarationFormattingVisitor.java b/src/pgo/formatters/GoDeclarationFormattingVisitor.java deleted file mode 100644 index 56c4b16f5..000000000 --- a/src/pgo/formatters/GoDeclarationFormattingVisitor.java +++ /dev/null @@ -1,64 +0,0 @@ -package pgo.formatters; - -import pgo.TODO; -import pgo.model.golang.GoDeclarationVisitor; -import pgo.model.golang.GoFunctionDeclaration; -import pgo.model.golang.GoTypeDeclaration; -import pgo.model.golang.GoVariableDeclaration; - -import java.io.IOException; - -public class GoDeclarationFormattingVisitor extends GoDeclarationVisitor { - - private final IndentingWriter out; - - public GoDeclarationFormattingVisitor(IndentingWriter out) { - this.out = out; - } - - @Override - public Void visit(GoFunctionDeclaration functionDeclaration) throws IOException { - out.write("func "); - if(functionDeclaration.getReceiver() != null) { - out.write("("); - functionDeclaration.getReceiver().accept(new GoNodeFormattingVisitor(out)); - out.write(") "); - } - out.write(functionDeclaration.getName()); - out.write("("); - FormattingTools.writeCommaSeparated(out, functionDeclaration.getArguments(), arg -> { - arg.accept(new GoNodeFormattingVisitor(out)); - }); - out.write(") "); - if(!functionDeclaration.getReturnTypes().isEmpty()) { - out.write("("); - FormattingTools.writeCommaSeparated(out, functionDeclaration.getReturnTypes(), ret -> { - ret.accept(new GoNodeFormattingVisitor(out)); - }); - out.write(") "); - } - functionDeclaration.getBody().accept(new GoStatementFormattingVisitor(out)); - return null; - } - - @Override - public Void visit(GoTypeDeclaration typeDeclaration) throws IOException { - throw new TODO(); - } - - @Override - public Void visit(GoVariableDeclaration variableDeclaration) throws IOException { - out.write("var "); - out.write(variableDeclaration.getName()); - if(variableDeclaration.getType() != null) { - out.write(" "); - variableDeclaration.getType().accept(new GoTypeFormattingVisitor(out)); - } - if(variableDeclaration.getValue() != null) { - out.write(" = "); - variableDeclaration.getValue().accept(new GoExpressionFormattingVisitor(out)); - } - return null; - } - -} diff --git a/src/pgo/formatters/GoExpressionFormattingVisitor.java b/src/pgo/formatters/GoExpressionFormattingVisitor.java deleted file mode 100644 index 4a1db8042..000000000 --- a/src/pgo/formatters/GoExpressionFormattingVisitor.java +++ /dev/null @@ -1,206 +0,0 @@ -package pgo.formatters; - -import pgo.model.golang.*; -import pgo.model.golang.GoBuiltins.BuiltinConstant; -import pgo.model.golang.type.GoMapType; - -import java.io.IOException; -import java.util.Map; - -public class GoExpressionFormattingVisitor extends GoExpressionVisitor { - - private final IndentingWriter out; - - public GoExpressionFormattingVisitor(IndentingWriter out) { - this.out = out; - } - - @Override - public Void visit(GoVariableName v) throws IOException { - out.write(v.getName()); - return null; - } - - @Override - public Void visit(BuiltinConstant v) throws IOException { - out.write(v.getValue()); - return null; - } - - @Override - public Void visit(GoIntLiteral intLiteral) throws IOException { - out.write(Integer.toString(intLiteral.getValue())); - return null; - } - - @Override - public Void visit(GoMapLiteral mapConstructor) throws IOException { - (new GoMapType(mapConstructor.getKeyType(), mapConstructor.getValueType())) - .accept(new GoTypeFormattingVisitor(out)); - out.write("{"); - out.newLine(); - for (Map.Entry entry : mapConstructor.getPairs().entrySet()) { - entry.getKey().accept(this); - out.write(": "); - entry.getValue().accept(this); - out.write(","); - out.newLine(); - } - out.write("}"); - return null; - } - - @Override - public Void visit(GoStringLiteral stringLiteral) throws IOException { - out.write("\""); - out.write(stringLiteral.getValue().replace("\"", "\\\"")); // TODO escaping - out.write("\""); - return null; - } - - @Override - public Void visit(GoIndexExpression index) throws IOException { - index.getTarget().accept(new GoBinopFormattingVisitor(out, 6)); - out.write("["); - index.getIndex().accept(this); - out.write("]"); - return null; - } - - @Override - public Void visit(GoSliceOperator slice) throws IOException { - slice.getTarget().accept(new GoBinopFormattingVisitor(out, 6)); - out.write("["); - if (slice.getLow() != null) { - slice.getLow().accept(this); - } - out.write(":"); - if (slice.getHigh() != null) { - slice.getHigh().accept(this); - } - if (slice.getMax() != null) { - out.write(":"); - slice.getMax().accept(this); - } - out.write("]"); - return null; - } - - @Override - public Void visit(GoSliceLiteral sliceConstructor) throws IOException { - out.write("[]"); - sliceConstructor.getElementType().accept(new GoTypeFormattingVisitor(out)); - out.write("{"); - FormattingTools.writeCommaSeparated(out, sliceConstructor.getInitializers(), expr -> { - expr.accept(this); - }); - out.write("}"); - return null; - } - - @Override - public Void visit(GoTypeAssertion typeAssertion) throws IOException { - typeAssertion.getTarget().accept(this); - out.write(".("); - typeAssertion.getType().accept(new GoTypeFormattingVisitor(out)); - out.write(")"); - return null; - } - - @Override - public Void visit(GoAnonymousFunction anonymousFunction) throws IOException { - out.write("func ("); - FormattingTools.writeCommaSeparated(out, anonymousFunction.getParams(), arg -> { - arg.accept(new GoNodeFormattingVisitor(out)); - }); - out.write(") "); - if(!anonymousFunction.getReturnTypes().isEmpty()) { - out.write("("); - FormattingTools.writeCommaSeparated(out, anonymousFunction.getReturnTypes(), ret -> { - if(ret.getName() != null) { - out.write(ret.getName()); - out.write(" "); - } - ret.getType().accept(new GoTypeFormattingVisitor(out)); - }); - out.write(") "); - } - - anonymousFunction.getBody().accept(new GoStatementFormattingVisitor(out)); - return null; - } - - @Override - public Void visit(GoCall call) throws IOException { - call.getTarget().accept(new GoBinopFormattingVisitor(out, 6)); - out.write("("); - FormattingTools.writeCommaSeparated(out, call.getArguments(), arg -> arg.accept(this)); - if (call.hasEllipsis()) { - out.write("..."); - } - out.write(")"); - return null; - } - - @Override - public Void visit(GoTypeCast typeCast) throws IOException { - typeCast.getTarget().accept(this); - out.write(".("); - out.write(typeCast.getTypeName().getName()); - out.write(")"); - - return null; - } - - @Override - public Void visit(GoStructLiteral structLiteral) throws IOException { - structLiteral.getType().accept(new GoTypeFormattingVisitor(out)); - out.write("{"); - FormattingTools.writeCommaSeparated(out, structLiteral.getFields(), field -> { - if(field.getName() != null){ - out.write(field.getName()); - out.write(": "); - } - field.getValue().accept(this); - }); - out.write("}"); - return null; - } - - @Override - public Void visit(GoBinop binop) throws IOException { - binop.accept(new GoBinopFormattingVisitor(out, 0)); - return null; - } - - @Override - public Void visit(GoUnary unary) throws IOException { - unary.accept(new GoBinopFormattingVisitor(out, 0)); - return null; - } - - @Override - public Void visit(GoSelectorExpression dot) throws IOException { - dot.getLHS().accept(new GoBinopFormattingVisitor(out, 6)); - out.write("."); - out.write(dot.getName()); - return null; - } - - @Override - public Void visit(GoMakeExpression make) throws IOException { - out.write("make("); - make.getType().accept(new GoTypeFormattingVisitor(out)); - if(make.getSize() != null) { - out.write(", "); - make.getSize().accept(this); - } - if(make.getCapacity() != null) { - out.write(", "); - make.getCapacity().accept(this); - } - out.write(")"); - return null; - } - -} diff --git a/src/pgo/formatters/GoNodeFormattingVisitor.java b/src/pgo/formatters/GoNodeFormattingVisitor.java deleted file mode 100644 index a0270af0f..000000000 --- a/src/pgo/formatters/GoNodeFormattingVisitor.java +++ /dev/null @@ -1,117 +0,0 @@ -package pgo.formatters; - -import pgo.TODO; -import pgo.model.golang.*; -import pgo.model.golang.type.GoInterfaceTypeField; -import pgo.model.golang.type.GoStructTypeField; -import pgo.model.golang.type.GoType; - -import java.io.IOException; - -public class GoNodeFormattingVisitor extends GoNodeVisitor { - - private final IndentingWriter out; - - public GoNodeFormattingVisitor(IndentingWriter out) { - this.out = out; - } - - @Override - public Void visit(GoModule module) throws IOException { - out.write("package "); - module.getPackage().accept(new GoExpressionFormattingVisitor(out)); - out.newLine(); - out.newLine(); - if(!module.getImports().isEmpty()) { - out.write("import ("); - out.newLine(); - try(IndentingWriter.Indent i_ = out.indent()){ - for(String imp : module.getImports()) { - out.write("\""); - out.write(imp); // TODO: escaping - out.write("\""); - out.newLine(); - } - } - out.write(")"); - out.newLine(); - } - out.newLine(); - for(GoDeclaration decl : module.getDeclarations()) { - decl.accept(this); - out.newLine(); - out.newLine(); - } - return null; - } - - @Override - public Void visit(GoStatement statement) throws IOException { - statement.accept(new GoStatementFormattingVisitor(out)); - return null; - } - - @Override - public Void visit(GoDeclaration declaration) throws IOException { - declaration.accept(new GoDeclarationFormattingVisitor(out)); - return null; - } - - @Override - public Void visit(GoType type) throws IOException { - type.accept(new GoTypeFormattingVisitor(out)); - return null; - } - - @Override - public Void visit(GoStructTypeField structTypeField) throws IOException { - throw new TODO(); - } - - @Override - public Void visit(GoSwitchCase switchCase) throws IOException { - throw new TODO(); - } - - @Override - public Void visit(GoLabelName labelName) throws IOException { - throw new TODO(); - } - - @Override - public Void visit(GoFunctionParameter functionArgument) throws IOException { - if (functionArgument.getName() != null) { - out.write(functionArgument.getName()); - out.write(" "); - } - functionArgument.getType().accept(this); - return null; - } - - @Override - public Void visit(GoExpression expression) throws IOException { - expression.accept(new GoExpressionFormattingVisitor(out)); - return null; - } - - @Override - public Void visit(GoInterfaceTypeField interfaceTypeField) throws IOException { - throw new TODO(); - } - - @Override - public Void visit(GoSelectCase selectCase) throws IOException { - throw new TODO(); - } - - @Override - public Void visit(GoStructLiteralField structLiteralField) throws IOException { - if(structLiteralField.getName() != null){ - out.write(structLiteralField.getName()); - out.write(": "); - } - structLiteralField.getValue().accept(new GoExpressionFormattingVisitor(out)); - return null; - } - -} diff --git a/src/pgo/formatters/GoStatementFormattingVisitor.java b/src/pgo/formatters/GoStatementFormattingVisitor.java deleted file mode 100644 index 497c8db1c..000000000 --- a/src/pgo/formatters/GoStatementFormattingVisitor.java +++ /dev/null @@ -1,238 +0,0 @@ -package pgo.formatters; - -import pgo.TODO; -import pgo.model.golang.*; - -import java.io.IOException; -import java.util.List; - -public class GoStatementFormattingVisitor extends GoStatementVisitor { - - private final IndentingWriter out; - - public GoStatementFormattingVisitor(IndentingWriter out) { - this.out = out; - } - - @Override - public Void visit(GoComment comment) throws IOException { - out.newLine(); - out.write("// "); - out.write(comment.getComment()); - - return null; - } - - @Override - public Void visit(GoAssignmentStatement assignment) throws IOException { - FormattingTools.writeCommaSeparated(out, assignment.getNames(), name -> { - name.accept(new GoExpressionFormattingVisitor(out)); - }); - if (assignment.isDefinition()) { - out.write(" := "); - } else { - out.write(" = "); - } - FormattingTools.writeCommaSeparated(out, assignment.getValues(), val -> { - val.accept(new GoExpressionFormattingVisitor(out)); - }); - return null; - } - - @Override - public Void visit(GoReturn goReturn) throws IOException { - out.write("return"); - List expressions = goReturn.getValues(); - if (expressions.size() == 0) { - return null; - } - out.write(" "); - FormattingTools.writeCommaSeparated(out, expressions, e -> e.accept(new GoExpressionFormattingVisitor(out))); - return null; - } - - @Override - public Void visit(GoBlock block) throws IOException { - out.write("{"); - out.newLine(); - try (IndentingWriter.Indent ignored = out.indent()) { - for (GoStatement stmt : block.getStatements()) { - stmt.accept(this); - out.newLine(); - } - } - out.write("}"); - return null; - } - - @Override - public Void visit(GoFor goFor) throws IOException { - out.write("for "); - if (goFor.getInit() != null) { - goFor.getInit().accept(this); - out.write("; "); - } - if (goFor.getCondition() != null) { - goFor.getCondition().accept(new GoExpressionFormattingVisitor(out)); - } - if (goFor.getIncrement() != null) { - out.write("; "); - goFor.getIncrement().accept(this); - } - if (goFor.getCondition() != null) { - out.write(" "); - } - goFor.getBody().accept(this); - return null; - } - - @Override - public Void visit(GoForRange forRange) throws IOException { - out.write("for "); - FormattingTools.writeCommaSeparated( - out, - forRange.getLhs(), - e -> e.accept(new GoExpressionFormattingVisitor(out))); - if (forRange.isDefinition()) { - out.write(" := range "); - } else { - out.write(" = range "); - } - forRange.getRangeExpr().accept(new GoExpressionFormattingVisitor(out)); - forRange.getBody().accept(this); - return null; - } - - @Override - public Void visit(GoIf goIf) throws IOException { - out.write("if "); - if (goIf.getInitialExpression() != null) { - FormattingTools.writeCommaSeparated( - out, - goIf.getInitialVariables(), - e -> e.accept(new GoExpressionFormattingVisitor(out)) - ); - out.write(" := "); - goIf.getInitialExpression().accept(new GoExpressionFormattingVisitor(out)); - out.write("; "); - } - - goIf.getCond().accept(new GoExpressionFormattingVisitor(out)); - out.write(" "); - goIf.getThen().accept(this); - if (goIf.getElse() != null && !goIf.getElse().getStatements().isEmpty()) { - out.write(" else "); - goIf.getElse().accept(this); - } - return null; - } - - @Override - public Void visit(GoSwitch goSwitch) throws IOException { - out.write("switch "); - if (goSwitch.getCondition() != null) { - goSwitch.getCondition().accept(new GoExpressionFormattingVisitor(out)); - } - out.write(" {"); - out.newLine(); - for (GoSwitchCase switchCase : goSwitch.getCases()) { - out.write("case "); - if (switchCase.isTypeCase()) { - switchCase.getType().accept(new GoTypeFormattingVisitor(out)); - } else { - switchCase.getCondition().accept(new GoExpressionFormattingVisitor(out)); - } - out.write(":"); - out.newLine(); - for (GoStatement statement : switchCase.getBlock()) { - statement.accept(this); - out.newLine(); - } - } - if (goSwitch.getDefaultBlock() != null) { - out.write("default:"); - for (GoStatement statement : goSwitch.getDefaultBlock()) { - statement.accept(this); - out.newLine(); - } - } - out.write("}"); - return null; - } - - @Override - public Void visit(GoLabel label) throws IOException { - out.write(label.getName()); - out.write(":"); - return null; - } - - @Override - public Void visit(GoSelect select) throws IOException { - throw new TODO(); - } - - @Override - public Void visit(GoTo goTo) throws IOException { - out.write("goto "); - out.write(goTo.getTo().getName()); - return null; - } - - @Override - public Void visit(GoIncDec incDec) throws IOException { - incDec.getExpression().accept(new GoExpressionFormattingVisitor(out)); - if (incDec.isInc()) { - out.write("++"); - } else { - out.write("--"); - } - return null; - } - - @Override - public Void visit(GoExpressionStatement expressionStatement) throws IOException { - expressionStatement.getExpression().accept(new GoExpressionFormattingVisitor(out)); - return null; - } - - @Override - public Void visit(GoBreak break1) throws IOException { - out.write("break"); - return null; - } - - @Override - public Void visit(GoContinue continue1) throws IOException { - out.write("continue"); - return null; - } - - @Override - public Void visit(GoDefer defer) throws IOException { - out.write("defer "); - defer.getExpression().accept(new GoExpressionFormattingVisitor(out)); - return null; - } - - @Override - public Void visit(GoRoutineStatement go) throws IOException { - out.write("go "); - go.getExpression().accept(new GoExpressionFormattingVisitor(out)); - return null; - } - - @Override - public Void visit(GoVariableDeclarationStatement variableDeclarationStatement) throws IOException { - GoVariableDeclaration variableDeclaration = variableDeclarationStatement.getVariableDeclaration(); - out.write("var "); - out.write(variableDeclaration.getName()); - out.write(" "); - variableDeclaration.getType().accept(new GoTypeFormattingVisitor(out)); - if (variableDeclaration.getValue() != null) { - out.write(" = "); - variableDeclaration.getValue().accept(new GoExpressionFormattingVisitor(out)); - } - return null; - } -} diff --git a/src/pgo/formatters/GoTypeFormattingVisitor.java b/src/pgo/formatters/GoTypeFormattingVisitor.java deleted file mode 100644 index 6def540ea..000000000 --- a/src/pgo/formatters/GoTypeFormattingVisitor.java +++ /dev/null @@ -1,99 +0,0 @@ -package pgo.formatters; - -import pgo.TODO; -import pgo.model.golang.GoPtrType; -import pgo.model.golang.type.*; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Map; - -public class GoTypeFormattingVisitor extends GoTypeVisitor { - - private final IndentingWriter out; - - public GoTypeFormattingVisitor(IndentingWriter out) { - this.out = out; - } - - @Override - public Void visit(GoTypeName typeName) throws IOException { - out.write(typeName.getName()); - return null; - } - - @Override - public Void visit(GoArchetypeResourceType archetypeResourceType) throws IOException { - out.write("ArchetypeResource[read: "); - archetypeResourceType.getReadType().accept(this); - out.write(", write: "); - archetypeResourceType.getWriteType().accept(this); - out.write("]"); - - return null; - } - - @Override - public Void visit(GoArchetypeResourceCollectionType archetypeResourceCollectionType) throws IOException { - out.write("ArchetypeResourceCollection[key: "); - archetypeResourceCollectionType.getKeyType().accept(this); - out.write(", read: "); - archetypeResourceCollectionType.getReadType().accept(this); - out.write(", write: "); - archetypeResourceCollectionType.getWriteType().accept(this); - out.write("]"); - - return null; - } - - @Override - public Void visit(GoStructType structType) throws IOException { - out.write("struct{"); - for(GoStructTypeField field : structType.getFields()){ - out.write(field.getName()); - out.write(" "); - field.getType().accept(this); - out.write("; "); - } - out.write("}"); - return null; - } - - @Override - public Void visit(GoPtrType ptrType) throws IOException { - out.write("*"); - ptrType.getPointee().accept(this); - return null; - } - - @Override - public Void visit(GoSliceType sliceType) throws IOException { - out.write("[]"); - sliceType.getElementType().accept(this); - return null; - } - - @Override - public Void visit(GoChanType chanType) throws IOException { - out.write("chan "); - chanType.getElementType().accept(this); - return null; - } - - @Override - public Void visit(GoMapType mapType) throws IOException { - out.write("map["); - mapType.getKeyType().accept(this); - out.write("]"); - mapType.getValueType().accept(this); - return null; - } - - @Override - public Void visit(GoInterfaceType interfaceType) throws IOException { - // TODO: complete this - out.write("interface{}"); - return null; - } - -} diff --git a/src/pgo/formatters/IndentingWriter.java b/src/pgo/formatters/IndentingWriter.java deleted file mode 100644 index ae85e5c7a..000000000 --- a/src/pgo/formatters/IndentingWriter.java +++ /dev/null @@ -1,122 +0,0 @@ -package pgo.formatters; - -import java.io.IOException; -import java.io.Writer; - -public class IndentingWriter extends Writer { - - Writer out; - int indent = 0; - boolean shouldIndent = false; - int defaultIndent = 4; - int horizontalPosition = 0; - - public static class Indent implements AutoCloseable { - - IndentingWriter writer; - int spaces; - - public Indent(IndentingWriter writer, int spaces) { - this.writer = writer; - this.spaces = spaces; - } - - @Override - public void close() { - writer.unindent(spaces); - } - - } - - public Indent indent(int spaces) { - indent += spaces; - return new Indent(this, spaces); - } - - public Indent indent() { - return indent(defaultIndent); - } - - public Indent indentToPosition() { - return indentToPosition(horizontalPosition); - } - - /** - * @return the 0-based position along the current line of text being written - */ - public int getHorizontalPosition() { - return horizontalPosition; - } - - /** - * - * Indents any following lines such that they start at position - * - * @param position - * @return an AutoCloseable the will reverse the indent when closed - */ - public Indent indentToPosition(int position) { - return indent(position - indent); - } - - public void unindent(int spaces) { - if(spaces > indent) { - throw new RuntimeException("can't unindent below 0"); - } - indent -= spaces; - } - - public IndentingWriter(Writer out) { - this.out = out; - } - - public IndentingWriter(Writer out, int defaultIndent) { - this.out = out; - this.defaultIndent = defaultIndent; - } - - @Override - public void close() throws IOException { - out.close(); - } - - @Override - public void flush() throws IOException { - out.flush(); - } - - public void newLine() throws IOException { - write(System.lineSeparator()); - } - - @Override - public void write(char[] chars, int offset, int len) throws IOException { - String lf = System.lineSeparator(); - String data = String.valueOf(chars, offset, len); - int start = 0; - while(true) { - if(shouldIndent) { - for(int i = 0; i < indent; ++i) { - out.write(" "); - } - shouldIndent = false; - horizontalPosition = 0; - } - int next = data.indexOf(lf, start); - if(next != -1) { - horizontalPosition += next + lf.length() - start; - out.write(data.substring(start, next+lf.length())); - start = next + lf.length(); - shouldIndent = true; - if(start == data.length()) { - break; - } - }else { - horizontalPosition += data.length() - start; - out.write(data.substring(start)); - break; - } - } - } - -} diff --git a/src/pgo/formatters/IssueFormattingVisitor.java b/src/pgo/formatters/IssueFormattingVisitor.java deleted file mode 100644 index 40b022cf0..000000000 --- a/src/pgo/formatters/IssueFormattingVisitor.java +++ /dev/null @@ -1,303 +0,0 @@ -package pgo.formatters; - -import pgo.errors.IssueVisitor; -import pgo.errors.IssueWithContext; -import pgo.model.mpcal.ModularPlusCalArchetype; -import pgo.model.mpcal.ModularPlusCalInstance; -import pgo.model.mpcal.ModularPlusCalNodeFormattingVisitor; -import pgo.model.pcal.PlusCalMacro; -import pgo.model.type.*; -import pgo.model.type.constraint.PolymorphicConstraint; -import pgo.trans.intermediate.*; -import pgo.trans.passes.codegen.pluscal.RefMismatchIssue; -import pgo.trans.passes.expansion.*; -import pgo.trans.passes.parse.option.OptionParserIssue; -import pgo.trans.passes.parse.pcal.PlusCalParserIssue; -import pgo.trans.passes.parse.ParsingIssue; -import pgo.trans.passes.type.TypeInferenceFailureIssue; -import pgo.trans.passes.validation.*; -import pgo.util.Origin; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -public class IssueFormattingVisitor extends IssueVisitor { - private final IndentingWriter out; - - public IssueFormattingVisitor(IndentingWriter out) { - this.out = out; - } - - @Override - public Void visit(IssueWithContext issueWithContext) throws IOException { - issueWithContext.getContext().accept(new ContextFormattingVisitor(out)); - try (IndentingWriter.Indent ignored = out.indent()) { - out.newLine(); - issueWithContext.getIssue().accept(this); - } - return null; - } - - @Override - public Void visit(OptionParserIssue optionParserIssue) throws IOException { - out.write("unable to parse options: "); - out.write(optionParserIssue.getMessage()); - return null; - } - - @Override - public Void visit(PlusCalParserIssue plusCalParserIssue) throws IOException { - out.write("unable to parse PlusCal code: "); - out.write(plusCalParserIssue.getMessage()); - return null; - } - - @Override - public Void visit(IOErrorIssue ioErrorIssue) throws IOException { - out.write("IO Error: "); - out.write(ioErrorIssue.getError().toString()); - return null; - } - - @Override - public Void visit(ParsingIssue parsingIssue) throws IOException { - out.write("error parsing "+parsingIssue.getLanguage()+": "); - out.write(parsingIssue.getError().getMessage()); - return null; - } - - @Override - public Void visit(NonRefParamModification nonRefParamModification) throws IOException { - out.write("non-ref "); - nonRefParamModification.getDeclarationUID().accept(new DerivedFormattingVisitor(out)); - out.write(" is modified in archetype body"); - return null; - } - - @Override - public Void visit(NoMatchingFieldIssue noMatchingFieldIssue) throws IOException { - out.write("record "); - noMatchingFieldIssue.getRecord().accept(new TypeFormattingVisitor(out)); - out.write(" has no field with name "); - out.write(noMatchingFieldIssue.getFieldName()); - return null; - } - - @Override - public Void visit(CircularModuleReferenceIssue circularModuleReferenceIssue) throws IOException { - out.write("encountered circular reference to module "); - out.write(circularModuleReferenceIssue.getModuleName()); - return null; - } - - @Override - public Void visit(UnsupportedFeatureIssue unsupportedFeatureIssue) throws IOException { - out.write("feature not supported by PGo: "); - out.write(unsupportedFeatureIssue.getMessage()); - return null; - } - - @Override - public Void visit(UnresolvableMacroCallIssue unresolvableMacroCallIssue) throws IOException { - out.write("could not find macro [" + unresolvableMacroCallIssue.getMacroCall().getTarget() + - "] referenced by macro call at line "); - out.write(unresolvableMacroCallIssue.getMacroCall().getLocation().getStartLine()); - out.write(" column "); - out.write(unresolvableMacroCallIssue.getMacroCall().getLocation().getStartColumn()); - return null; - } - - @Override - public Void visit(MacroArgumentCountMismatchIssue macroArgumentCountMismatchIssue) throws IOException { - out.write("macro argument mismatch while calling macro "); - PlusCalMacro macro = macroArgumentCountMismatchIssue.getMacro(); - out.write(macro.getName()); - out.write(" defined at line "); - out.write(macro.getLocation().getStartLine()); - out.write(" column "); - out.write(macro.getLocation().getStartColumn()); - out.write("from line "); - out.write(macroArgumentCountMismatchIssue.getMacroCall().getLocation().getStartLine()); - out.write(" column "); - out.write(macroArgumentCountMismatchIssue.getMacroCall().getLocation().getStartColumn()); - return null; - } - - @Override - public Void visit(RecursiveMacroCallIssue recursiveMacroCallIssue) throws IOException { - out.write("encountered recursive macro call at line "); - out.write(recursiveMacroCallIssue.getMacroCall().getLocation().getStartLine()); - out.write(" column "); - out.write(recursiveMacroCallIssue.getMacroCall().getLocation().getStartColumn()); - return null; - } - - @Override - public Void visit(InfiniteTypeIssue infiniteTypeIssue) throws IOException { - out.write("unifying "); - infiniteTypeIssue.getLhs().accept(new TypeFormattingVisitor(out)); - out.write(" and "); - infiniteTypeIssue.getRhs().accept(new TypeFormattingVisitor(out)); - out.write(" leads to infinite types"); - return null; - } - - @Override - public Void visit(MacroArgumentInnerScopeConflictIssue macroArgumentInnerScopeConflictIssue) throws IOException { - out.write("locally bound identifier at line "); - out.write(Integer.toString(macroArgumentInnerScopeConflictIssue.getIdentifier().getLocation().getStartLine())); - out.write(" column "); - out.write(Integer.toString(macroArgumentInnerScopeConflictIssue.getIdentifier().getLocation().getStartColumn())); - out.write(" conflicts with PlusCal macro parameter; this will likely not work with the TLC"); - return null; - } - - @Override - public Void visit(MacroNameConflictIssue macroNameConflictIssue) throws IOException { - out.write("the two macro definitions at line "); - out.write(macroNameConflictIssue.getFirst().getLocation().getStartLine()); - out.write(" column "); - out.write(macroNameConflictIssue.getFirst().getLocation().getStartColumn()); - out.write(" and line "); - out.write(macroNameConflictIssue.getSecond().getLocation().getStartLine()); - out.write(" column "); - out.write(macroNameConflictIssue.getSecond().getLocation().getStartColumn()); - out.write(" share the same name"); - return null; - } - - @Override - public Void visit(BacktrackingFailureIssue backtrackingFailureIssue) throws IOException { - PolymorphicConstraint polymorphicConstraint = backtrackingFailureIssue.getPolymorphicConstraint(); - out.write("could not satisfy "); - polymorphicConstraint.accept(new DerivedFormattingVisitor(out)); - out.write("; constraint is "); - out.write(polymorphicConstraint.toString()); - return null; - } - - @Override - public Void visit(UnsatisfiableConstraintIssue unsatisfiableConstraintIssue) throws IOException { - out.write("could not unify "); - unsatisfiableConstraintIssue.getLhs().accept(new DerivedFormattingVisitor(out)); - out.write(" and "); - unsatisfiableConstraintIssue.getRhs().accept(new DerivedFormattingVisitor(out)); - out.write("; "); - List origins = new ArrayList<>(unsatisfiableConstraintIssue.getLhs().getOrigins()); - origins.addAll(unsatisfiableConstraintIssue.getRhs().getOrigins()); - (new DerivedFormattingVisitor(out)).writeOrigins(origins); - return null; - } - - @Override - public Void visit(TypeInferenceFailureIssue typeInferenceFailureIssue) throws IOException { - out.write("could not infer type for "); - typeInferenceFailureIssue.getUID().accept(new DerivedFormattingVisitor(out)); - out.write("; got "); - typeInferenceFailureIssue.getType().accept(new DerivedFormattingVisitor(out)); - return null; - } - - @Override - public Void visit(MissingLabelIssue missingLabelIssue) throws IOException { - out.write("Label required in statement: "); - missingLabelIssue.getStatement().accept(new OriginFormattingVisitor(out)); - - return null; - } - - @Override - public Void visit(LabelNotAllowedIssue labelNotAllowedIssue) throws IOException { - out.write("Label not allowed in statement: "); - labelNotAllowedIssue.getStatement().accept(new OriginFormattingVisitor(out)); - - return null; - } - - @Override - public Void visit(ReservedLabelNameIssue reservedLabelNameIssue) throws IOException { - out.write("Label not allowed in statement: "); - reservedLabelNameIssue.getStatement().accept(new OriginFormattingVisitor(out)); - - return null; - } - - @Override - public Void visit(StatementNotAllowedIssue statementNotAllowedIssue) throws IOException { - out.write("Statement not allowed in this context: "); - statementNotAllowedIssue.getStatement().accept(new OriginFormattingVisitor(out)); - - return null; - } - - @Override - public Void visit(InstanceArgumentCountMismatchIssue instanceArgumentCountMismatchIssue) throws IOException { - out.write("archetype "); - ModularPlusCalArchetype archetype = instanceArgumentCountMismatchIssue.getModularPlusCalArchetype(); - out.write(archetype.getName()); - out.write(" defined at line "); - out.write(Integer.toString(archetype.getLocation().getStartLine())); - out.write(" column "); - out.write(Integer.toString(archetype.getLocation().getStartColumn())); - out.write(" requires "); - out.write(Integer.toString(archetype.getParams().size())); - out.write(" parameters while instance statement at line "); - ModularPlusCalInstance instance = instanceArgumentCountMismatchIssue.getModularPlusCalInstance(); - out.write(Integer.toString(instance.getLocation().getStartLine())); - out.write(" column "); - out.write(Integer.toString(instance.getLocation().getStartColumn())); - out.write(" referencing it provides "); - out.write(Integer.toString(instance.getArguments().size())); - out.write(" arguments"); - return null; - } - - @Override - public Void visit(InconsistentInstantiationIssue inconsistentInstantiationIssue) throws IOException { - out.write("instantiation "); - inconsistentInstantiationIssue.getInstance().accept(new ModularPlusCalNodeFormattingVisitor(out)); - out.write(" is inconsistent with "); - inconsistentInstantiationIssue.getConflict().accept(new ModularPlusCalNodeFormattingVisitor(out)); - out.write(" (one maps function calls, the other does not)"); - - return null; - } - - @Override - public Void visit(RefMismatchIssue refMismatchIssue) throws IOException { - out.write("mismatch in call between "); - refMismatchIssue.getParam().accept(new PlusCalNodeFormattingVisitor(out)); - out.write(" and "); - refMismatchIssue.getValue().accept(new TLANodeFormattingVisitor(out)); - return null; - } - - @Override - public Void visit(InvalidArchetypeResourceUsageIssue invalidArchetypeResourceUsageIssue) throws IOException { - String usedAs, mappedAs; - - if (invalidArchetypeResourceUsageIssue.isFunction()) { - usedAs = "variable"; - mappedAs = "function"; - } else { - usedAs = "function"; - mappedAs = "variable"; - } - - out.write("invalid use of archetype resource: used as a " + usedAs + " but mapped as a " + mappedAs + ". In statement: "); - invalidArchetypeResourceUsageIssue.getStatement().accept(new PlusCalStatementFormattingVisitor(out)); - - return null; - } - - @Override - public Void visit(VariableMappedMultipleTimesIssue variableMappedMultipleTimesIssue) throws IOException { - out.write("global "); - variableMappedMultipleTimesIssue.getVarUID().accept(new DerivedFormattingVisitor(out)); - out.write(" is used multiple time in "); - variableMappedMultipleTimesIssue.getInstance().accept(new OriginFormattingVisitor(out)); - return null; - } -} - diff --git a/src/pgo/formatters/OriginFormattingVisitor.java b/src/pgo/formatters/OriginFormattingVisitor.java deleted file mode 100644 index a1dc39658..000000000 --- a/src/pgo/formatters/OriginFormattingVisitor.java +++ /dev/null @@ -1,34 +0,0 @@ -package pgo.formatters; - -import pgo.util.Derived; -import pgo.util.OriginVisitor; -import pgo.util.SourceLocatable; - -import java.io.IOException; - -public class OriginFormattingVisitor extends OriginVisitor { - - private final IndentingWriter out; - - public OriginFormattingVisitor(IndentingWriter out) { - this.out = out; - } - - @Override - public Void visit(SourceLocatable sourceLocatable) throws IOException { - out.write("source ["); - out.write(sourceLocatable.toString()); - out.write("] at line "); - out.write(Integer.toString(sourceLocatable.getLocation().getStartLine())); - out.write(" column "); - out.write(Integer.toString(sourceLocatable.getLocation().getStartColumn())); - return null; - } - - @Override - public Void visit(Derived derived) throws IOException { - derived.accept(new DerivedFormattingVisitor(out)); - return null; - } - -} diff --git a/src/pgo/formatters/PlusCalNodeFormattingVisitor.java b/src/pgo/formatters/PlusCalNodeFormattingVisitor.java deleted file mode 100644 index 7f2fc0e05..000000000 --- a/src/pgo/formatters/PlusCalNodeFormattingVisitor.java +++ /dev/null @@ -1,226 +0,0 @@ -package pgo.formatters; - -import pgo.Unreachable; -import pgo.model.pcal.*; -import pgo.model.tla.PlusCalDefaultInitValue; -import pgo.model.tla.TLAIdentifier; -import pgo.model.tla.TLAUnit; - -import java.io.IOException; -import java.util.List; - -public class PlusCalNodeFormattingVisitor extends PlusCalNodeVisitor { - - private final IndentingWriter out; - - public PlusCalNodeFormattingVisitor(IndentingWriter out) { - this.out = out; - } - - public boolean writeVariableDeclarations(String prefix, List declarations, String postfix) - throws IOException { - if (declarations.size() > 0) { - out.write(prefix); - for (int i = 0; i < declarations.size(); i++) { - PlusCalVariableDeclaration declaration = declarations.get(i); - if (i != 0) { - out.write(", "); - } - declaration.accept(this); - } - out.write(postfix); - return true; - } - return false; - } - - @Override - public Void visit(PlusCalAlgorithm plusCalAlgorithm) throws IOException { - out.write("--algorithm "); - out.write(plusCalAlgorithm.getName().getId()); - out.write(" {"); - out.newLine(); - try (IndentingWriter.Indent ignored = out.indent()) { - if (writeVariableDeclarations("variables ", plusCalAlgorithm.getVariables(), ";")) { - out.newLine(); - } - - List units = plusCalAlgorithm.getUnits(); - if (units.size() > 0) { - out.write("define {"); - out.newLine(); - try (IndentingWriter.Indent ignored1 = out.indent()) { - for (TLAUnit unit : plusCalAlgorithm.getUnits()) { - unit.accept(new TLAUnitFormattingVisitor(out)); - out.newLine(); - } - } - out.write("}"); - out.newLine(); - } - - for (PlusCalProcedure procedure : plusCalAlgorithm.getProcedures()) { - procedure.accept(this); - } - - plusCalAlgorithm.getProcesses().accept(this); - - } - out.write("}"); - // there should not be a newline after this to match the PlusCal parser - return null; - } - - @Override - public Void visit(PlusCalProcesses processes) throws IOException { - if (processes instanceof PlusCalSingleProcess) { - PlusCalSingleProcess singleProcess = (PlusCalSingleProcess) processes; - out.write("{"); - out.newLine(); - try (IndentingWriter.Indent ignored = out.indent()) { - for (PlusCalStatement statement : singleProcess.getBody()) { - statement.accept(this); - } - } - out.newLine(); - out.write("}"); - out.newLine(); - } else { - PlusCalMultiProcess multiProcess = (PlusCalMultiProcess) processes; - for (PlusCalProcess process : multiProcess.getProcesses()) { - process.accept(this); - } - } - return null; - } - - @Override - public Void visit(PlusCalStatement statement) throws IOException { - statement.accept(new PlusCalStatementFormattingVisitor(out)); - return null; - } - - @Override - public Void visit(PlusCalLabel label) throws IOException { - switch(label.getModifier()) { - case MINUS: - out.write("-"); - break; - case NONE: - // pass - break; - case PLUS: - out.write("+"); - break; - default: - throw new Unreachable(); - } - out.write(label.getName()); - out.write(":"); - return null; - } - - @Override - public Void visit(PlusCalMacro macro) throws IOException { - out.write("macro "); - out.write(macro.getName()); - out.write("("); - boolean first = true; - for(TLAIdentifier id: macro.getParams()) { - if(!first) { - out.write(", "); - }{ - first = false; - } - out.write(id.getId()); - } - out.write(")"); - out.write(" {"); - try(IndentingWriter.Indent i_ = out.indent()) { - for (PlusCalStatement stmt : macro.getBody()) { - out.newLine(); - stmt.accept(new PlusCalStatementFormattingVisitor(out)); - } - } - out.newLine(); - out.write("};"); - return null; - } - - @Override - public Void visit(PlusCalProcess plusCalProcess) throws IOException { - if (plusCalProcess.getFairness() == PlusCalFairness.WEAK_FAIR) { - out.write("fair "); - } else if (plusCalProcess.getFairness() == PlusCalFairness.STRONG_FAIR) { - out.write("fair+ "); - } - - out.write("process ("); - plusCalProcess.getName().accept(this); - out.write(")"); - out.newLine(); - - if (writeVariableDeclarations("variables ", plusCalProcess.getVariables(), ";")) { - out.newLine(); - } - - out.write("{"); - out.newLine(); - try (IndentingWriter.Indent ignored = out.indent()) { - for (PlusCalStatement statement : plusCalProcess.getBody()) { - statement.accept(this); - } - } - out.newLine(); - out.write("}"); - out.newLine(); - return null; - } - - @Override - public Void visit(PlusCalProcedure procedure) throws IOException { - out.write("procedure "); - out.write(procedure.getName()); - out.write(" ("); - writeVariableDeclarations("", procedure.getParams(), ""); - out.write(")"); - out.newLine(); - if (writeVariableDeclarations("variables ", procedure.getVariables(), ";")) { - out.newLine(); - } - out.write("{"); - out.newLine(); - try (IndentingWriter.Indent ignored = out.indent()) { - for (PlusCalStatement statement : procedure.getBody()) { - statement.accept(this); - } - } - out.newLine(); - out.write("}"); - out.newLine(); - return null; - } - - @Override - public Void visit(PlusCalVariableDeclaration variableDeclaration) throws IOException { - out.write(variableDeclaration.getName().getId()); - if (!(variableDeclaration.getValue() instanceof PlusCalDefaultInitValue)) { - if (variableDeclaration.isSet()) { - out.write(" \\in "); - } else { - out.write(" = "); - } - variableDeclaration.getValue().accept(new TLAExpressionFormattingVisitor(out)); - } - return null; - } - - @Override - public Void visit(PlusCalAssignmentPair plusCalAssignmentPair) throws IOException { - plusCalAssignmentPair.getLhs().accept(new TLAExpressionFormattingVisitor(out, true)); - out.write(" := "); - plusCalAssignmentPair.getRhs().accept(new TLAExpressionFormattingVisitor(out)); - return null; - } - -} diff --git a/src/pgo/formatters/PlusCalStatementFormattingVisitor.java b/src/pgo/formatters/PlusCalStatementFormattingVisitor.java deleted file mode 100644 index bdfa891ff..000000000 --- a/src/pgo/formatters/PlusCalStatementFormattingVisitor.java +++ /dev/null @@ -1,208 +0,0 @@ -package pgo.formatters; - -import pgo.TODO; -import pgo.model.mpcal.ModularPlusCalYield; -import pgo.model.pcal.*; -import pgo.model.tla.TLAExpression; - -import java.io.IOException; -import java.util.List; - -public class PlusCalStatementFormattingVisitor extends PlusCalStatementVisitor { - private final IndentingWriter out; - - public PlusCalStatementFormattingVisitor(IndentingWriter out) { - this.out = out; - } - - @Override - public Void visit(PlusCalLabeledStatements plusCalLabeledStatements) throws IOException { - plusCalLabeledStatements.getLabel().accept(new PlusCalNodeFormattingVisitor(out)); - try (IndentingWriter.Indent ignored = out.indent()) { - for(PlusCalStatement stmt : plusCalLabeledStatements.getStatements()) { - out.newLine(); - stmt.accept(this); - } - } - out.newLine(); - return null; - } - - @Override - public Void visit(PlusCalWhile plusCalWhile) throws IOException { - out.write("while ("); - plusCalWhile.getCondition().accept(new TLAExpressionFormattingVisitor(out)); - out.write(") {"); - try (IndentingWriter.Indent ignored = out.indent()) { - for(PlusCalStatement stmt : plusCalWhile.getBody()) { - out.newLine(); - stmt.accept(this); - } - } - out.newLine(); - out.write("};"); - return null; - } - - @Override - public Void visit(PlusCalIf plusCalIf) throws IOException { - out.write("if ("); - plusCalIf.getCondition().accept(new TLAExpressionFormattingVisitor(out)); - out.write(") {"); - try (IndentingWriter.Indent ignored = out.indent()) { - for(PlusCalStatement stmt : plusCalIf.getYes()){ - out.newLine(); - stmt.accept(new PlusCalStatementFormattingVisitor(out)); - } - } - out.newLine(); - out.write("}"); - if (plusCalIf.getNo().isEmpty()) { - out.write(";"); - } else { - out.write(" else {"); - try (IndentingWriter.Indent ignored = out.indent()) { - for(PlusCalStatement stmt : plusCalIf.getNo()){ - out.newLine(); - stmt.accept(new PlusCalStatementFormattingVisitor(out)); - } - } - out.newLine(); - out.write("};"); - } - return null; - } - - @Override - public Void visit(PlusCalEither plusCalEither) throws IOException { - List> cases = plusCalEither.getCases(); - for (int i = 0; i < cases.size(); i++) { - List case_ = cases.get(i); - if (i == 0) { - out.write("either {"); - } else { - out.write(" or {"); - } - try (IndentingWriter.Indent ignored = out.indent()) { - for (PlusCalStatement statement : case_) { - out.newLine(); - statement.accept(this); - } - } - out.newLine(); - out.write("}"); - } - out.write(";"); - return null; - } - - @Override - public Void visit(PlusCalAssignment plusCalAssignment) throws IOException { - List pairs = plusCalAssignment.getPairs(); - - pairs.get(0).accept(new PlusCalNodeFormattingVisitor(out)); - - for(PlusCalAssignmentPair pair : pairs.subList(1, pairs.size())) { - out.write(" || "); - pair.accept(new PlusCalNodeFormattingVisitor(out)); - } - out.write(";"); - return null; - } - - @Override - public Void visit(PlusCalReturn plusCalReturn) throws IOException { - out.write("return;"); - return null; - } - - @Override - public Void visit(PlusCalSkip plusCalSkip) throws IOException { - out.write("skip;"); - return null; - } - - @Override - public Void visit(PlusCalCall plusCalCall) throws IOException { - out.write("call "); - out.write(plusCalCall.getTarget()); - out.write("("); - - TLANodeFormattingVisitor v = new TLANodeFormattingVisitor(out); - FormattingTools.writeCommaSeparated(out, plusCalCall.getArguments(), a -> a.accept(v)); - - out.write(");"); - return null; - } - - @Override - public Void visit(PlusCalMacroCall macroCall) throws IOException { - out.write(macroCall.getTarget()); - out.write("("); - - for (int i = 0; i < macroCall.getArguments().size(); i++) { - if (i > 0) { - out.write(", "); - } - - macroCall.getArguments().get(i).accept(new TLAExpressionFormattingVisitor(out)); - } - - out.write(");"); - return null; - } - - @Override - public Void visit(PlusCalWith plusCalWith) throws IOException { - out.write("with ("); - (new PlusCalNodeFormattingVisitor(out)).writeVariableDeclarations("", plusCalWith.getVariables(), ""); - out.write(") {"); - out.newLine(); - try (IndentingWriter.Indent ignored = out.indent()) { - for (PlusCalStatement statement : plusCalWith.getBody()) { - statement.accept(this); - out.newLine(); - } - } - out.write("};"); - return null; - } - - @Override - public Void visit(PlusCalPrint plusCalPrint) throws IOException { - out.write("print "); - plusCalPrint.getValue().accept(new TLAExpressionFormattingVisitor(out)); - out.write(";"); - return null; - } - - @Override - public Void visit(PlusCalAssert plusCalAssert) throws IOException { - out.write("assert "); - plusCalAssert.getCondition().accept(new TLAExpressionFormattingVisitor(out)); - out.write(";"); - return null; - } - - @Override - public Void visit(PlusCalAwait plusCalAwait) throws IOException { - out.write("await "); - plusCalAwait.getCondition().accept(new TLAExpressionFormattingVisitor(out)); - out.write(";"); - return null; - } - - @Override - public Void visit(PlusCalGoto plusCalGoto) throws IOException { - out.write("goto " + plusCalGoto.getTarget() + ";"); - return null; - } - - @Override - public Void visit(ModularPlusCalYield modularPlusCalYield) throws IOException { - out.write("yield "); - modularPlusCalYield.getExpression().accept(new TLAExpressionFormattingVisitor(out)); - out.write(";"); - return null; - } -} diff --git a/src/pgo/formatters/TLAExpressionFormattingVisitor.java b/src/pgo/formatters/TLAExpressionFormattingVisitor.java deleted file mode 100644 index f102acbe8..000000000 --- a/src/pgo/formatters/TLAExpressionFormattingVisitor.java +++ /dev/null @@ -1,383 +0,0 @@ -package pgo.formatters; - -import pgo.model.tla.*; -import pgo.parser.TLAMeta; - -import java.io.IOException; -import java.util.List; - -public class TLAExpressionFormattingVisitor extends TLAExpressionVisitor { - IndentingWriter out; - private final boolean lhs; - - public TLAExpressionFormattingVisitor(IndentingWriter out, boolean lhs) { - this.out = out; - this.lhs = lhs; - } - - public TLAExpressionFormattingVisitor(IndentingWriter out) { - this(out, false); - } - - private void formatPrefix(List prefix) throws IOException { - for (TLAGeneralIdentifierPart part : prefix) { - part.accept(new TLANodeFormattingVisitor(out)); - } - } - - @Override - public Void visit(TLAFunctionCall tlaFunctionCall) throws IOException { - tlaFunctionCall.getFunction().accept(this); - out.write("["); - FormattingTools.writeCommaSeparated(out, tlaFunctionCall.getParams(), param -> param.accept(this)); - out.write("]"); - return null; - } - - @Override - public Void visit(TLABinOp tlaBinOp) throws IOException { - out.write("("); - tlaBinOp.getLHS().accept(this); - out.write(")"); - out.write(" "); - formatPrefix(tlaBinOp.getPrefix()); - tlaBinOp.getOperation().accept(new TLANodeFormattingVisitor(out)); - out.write(" "); - out.write("("); - tlaBinOp.getRHS().accept(this); - out.write(")"); - return null; - } - - @Override - public Void visit(TLABool tlaBool) throws IOException { - if (tlaBool.getValue()) { - out.write("TRUE"); - } else { - out.write("FALSE"); - } - return null; - } - - @Override - public Void visit(TLACase tlaCase) throws IOException { - out.write("CASE "); - int indentFrom = out.getHorizontalPosition(); - List arms = tlaCase.getArms(); - TLACaseArm firstArm = arms.get(0); - firstArm.getCondition().accept(this); - out.write(" -> "); - firstArm.getResult().accept(this); - try (IndentingWriter.Indent ignored = out.indentToPosition(indentFrom)){ - for (int i = 1; i < arms.size(); ++i) { - out.newLine(); - TLACaseArm arm = arms.get(i); - arm.accept(new TLANodeFormattingVisitor(out)); - } - - if (tlaCase.getOther() != null) { - out.newLine(); - out.write("[] OTHER -> "); - tlaCase.getOther().accept(this); - } - } - - return null; - } - - @Override - public Void visit(TLADot tlaDot) throws IOException { - // (expr).field := expr - // is not valid PlusCal syntax - if (lhs) { - tlaDot.getExpression().accept(this); - } else { - out.write("("); - tlaDot.getExpression().accept(this); - out.write(")"); - } - out.write("."); - out.write(tlaDot.getField()); - return null; - } - - @Override - public Void visit(TLAExistential tlaExistential) throws IOException { - out.write("\\E "); - FormattingTools.writeCommaSeparated( - out, tlaExistential.getIds(), id -> id.accept(new TLANodeFormattingVisitor(out))); - out.write(" : "); - tlaExistential.getBody().accept(this); - return null; - } - - @Override - public Void visit(TLAFunction tlaFunction) throws IOException { - out.write("["); - FormattingTools.writeCommaSeparated( - out, tlaFunction.getArguments(), arg -> arg.accept(new TLANodeFormattingVisitor(out))); - out.write(" |-> "); - tlaFunction.getBody().accept(this); - out.write("]"); - return null; - } - - @Override - public Void visit(TLAFunctionSet tlaFunctionSet) throws IOException { - out.write("["); - tlaFunctionSet.getFrom().accept(this); - out.write(" -> "); - tlaFunctionSet.getTo().accept(this); - out.write("]"); - return null; - } - - @Override - public Void visit(TLAFunctionSubstitution tlaFunctionSubstitution) throws IOException { - out.write("["); - tlaFunctionSubstitution.getSource().accept(this); - out.write(" EXCEPT"); - for (TLAFunctionSubstitutionPair p : tlaFunctionSubstitution.getSubstitutions()) { - out.write(" "); - p.accept(new TLANodeFormattingVisitor(out)); - } - out.write("]"); - return null; - } - - @Override - public Void visit(TLAIf tlaIf) throws IOException { - out.write("IF "); - tlaIf.getCond().accept(this); - out.write(" THEN "); - tlaIf.getTval().accept(this); - out.write(" ELSE "); - tlaIf.getFval().accept(this); - return null; - } - - @Override - public Void visit(TLALet tlaLet) throws IOException { - int indentFrom = out.getHorizontalPosition(); - out.write("LET"); - try (IndentingWriter.Indent ignored = out.indent()){ - for (TLAUnit unit : tlaLet.getDefinitions()) { - out.newLine(); - unit.accept(new TLAUnitFormattingVisitor(out)); - } - } - out.newLine(); - try (IndentingWriter.Indent ignored = out.indentToPosition(indentFrom)){ - out.write("IN "); - try (IndentingWriter.Indent ignored1 = out.indent()){ - tlaLet.getBody().accept(this); - } - } - return null; - } - - @Override - public Void visit(TLAGeneralIdentifier tlaGeneralIdentifier) throws IOException { - formatPrefix(tlaGeneralIdentifier.getGeneralIdentifierPrefix()); - tlaGeneralIdentifier.getName().accept(new TLANodeFormattingVisitor(out)); - return null; - } - - @Override - public Void visit(TLATuple tlaTuple) throws IOException { - out.write("<<"); - FormattingTools.writeCommaSeparated(out, tlaTuple.getElements(), elem -> elem.accept(this)); - out.write(">>"); - return null; - } - - @Override - public Void visit(TLAMaybeAction tlaMaybeAction) throws IOException { - out.write("["); - tlaMaybeAction.getBody().accept(this); - out.write("]_"); - tlaMaybeAction.getVars().accept(this); - return null; - } - - @Override - public Void visit(TLANumber tlaNumber) throws IOException { - out.write(tlaNumber.getVal()); - return null; - } - - @Override - public Void visit(TLAOperatorCall tlaOperatorCall) throws IOException { - formatPrefix(tlaOperatorCall.getPrefix()); - tlaOperatorCall.getName().accept(new TLANodeFormattingVisitor(out)); - out.write("("); - FormattingTools.writeCommaSeparated(out, tlaOperatorCall.getArgs(), arg -> arg.accept(this)); - out.write(")"); - return null; - } - - @Override - public Void visit(TLAQuantifiedExistential tlaQuantifiedExistential) throws IOException { - out.write("\\E "); - FormattingTools.writeCommaSeparated( - out, tlaQuantifiedExistential.getIds(), id -> id.accept(new TLANodeFormattingVisitor(out))); - out.write(" : "); - tlaQuantifiedExistential.getBody().accept(this); - return null; - } - - @Override - public Void visit(TLAQuantifiedUniversal tlaQuantifiedUniversal) throws IOException { - out.write("\\A "); - FormattingTools.writeCommaSeparated( - out, tlaQuantifiedUniversal.getIds(), id -> id.accept(new TLANodeFormattingVisitor(out))); - out.write(" : "); - tlaQuantifiedUniversal.getBody().accept(this); - return null; - } - - @Override - public Void visit(TLARecordConstructor tlaRecordConstructor) throws IOException { - out.write("["); - FormattingTools.writeCommaSeparated( - out, tlaRecordConstructor.getFields(), field -> field.accept(new TLANodeFormattingVisitor(out))); - out.write("]"); - return null; - } - - @Override - public Void visit(TLARecordSet tlaRecordSet) throws IOException { - out.write("["); - FormattingTools.writeCommaSeparated( - out, tlaRecordSet.getFields(), field -> field.accept(new TLANodeFormattingVisitor(out))); - out.write("]"); - return null; - } - - @Override - public Void visit(TLARequiredAction tlaRequiredAction) throws IOException { - out.write("<<"); - tlaRequiredAction.getBody().accept(this); - out.write(">>_"); - tlaRequiredAction.getVars().accept(this); - return null; - } - - @Override - public Void visit(TLASetConstructor tlaSetConstructor) throws IOException { - out.write("{"); - FormattingTools.writeCommaSeparated(out, tlaSetConstructor.getContents(), member -> member.accept(this)); - out.write("}"); - return null; - } - - @Override - public Void visit(TLASetComprehension tlaSetComprehension) throws IOException { - out.write("{"); - tlaSetComprehension.getBody().accept(this); - out.write(" : "); - FormattingTools.writeCommaSeparated( - out, tlaSetComprehension.getBounds(), bound -> bound.accept(new TLANodeFormattingVisitor(out))); - out.write("}"); - return null; - } - - @Override - public Void visit(TLASetRefinement tlaSetRefinement) throws IOException { - out.write("{"); - tlaSetRefinement.getIdent().accept(new TLANodeFormattingVisitor(out)); - out.write(" \\in "); - tlaSetRefinement.getFrom().accept(this); - out.write(" : "); - tlaSetRefinement.getWhen().accept(this); - out.write("}"); - return null; - } - - @Override - public Void visit(TLAString tlaString) throws IOException { - out.write("\""); - out.write(tlaString.getValue()); - out.write("\""); - return null; - } - - @Override - public Void visit(TLAUnary tlaUnary) throws IOException { - if (tlaUnary.getOperation().getValue().equals("-_")) { - formatPrefix(tlaUnary.getPrefix()); - out.write("-"); - out.write("("); - tlaUnary.getOperand().accept(this); - out.write(")"); - } else if (TLAMeta.prefixOperators().contains(tlaUnary.getOperation().getValue())) { - formatPrefix(tlaUnary.getPrefix()); - out.write(tlaUnary.getOperation().getValue()); - out.write("("); - tlaUnary.getOperand().accept(this); - out.write(")"); - } else if (TLAMeta.postfixOperators().contains(tlaUnary.getOperation().getValue())) { - out.write("("); - tlaUnary.getOperand().accept(this); - out.write(")"); - formatPrefix(tlaUnary.getPrefix()); - out.write(tlaUnary.getOperation().getValue()); - } else { - throw new RuntimeException(tlaUnary.getOperation()+" is not a valid prefix or postfix operator"); - } - return null; - } - - @Override - public Void visit(TLAUniversal tlaUniversal) throws IOException { - out.write("\\A "); - FormattingTools.writeCommaSeparated( - out, tlaUniversal.getIds(), id -> id.accept(new TLANodeFormattingVisitor(out))); - out.write(" : "); - tlaUniversal.getBody().accept(this); - return null; - } - - @Override - public Void visit(PlusCalDefaultInitValue plusCalDefaultInitValue) throws IOException { - out.write("defaultInitValue"); - return null; - } - - @Override - public Void visit(TLAFairness fairness) throws IOException { - switch(fairness.getType()){ - case WEAK: - out.write("WF_"); - break; - case STRONG: - out.write("SF_"); - break; - } - fairness.getVars().accept(this); - out.write("("); - fairness.getExpression().accept(this); - out.write(")"); - return null; - } - - @Override - public Void visit(TLASpecialVariableVariable tlaSpecialVariableVariable) throws IOException { - out.write("$variable"); - return null; - } - - @Override - public Void visit(TLASpecialVariableValue tlaSpecialVariableValue) throws IOException { - out.write("$value"); - return null; - } - - @Override - public Void visit(TLARef tlaRef) throws IOException { - out.write("ref "); - out.write(tlaRef.getTarget()); - return null; - } - -} diff --git a/src/pgo/formatters/TLANodeFormattingVisitor.java b/src/pgo/formatters/TLANodeFormattingVisitor.java deleted file mode 100644 index 6ef2e585a..000000000 --- a/src/pgo/formatters/TLANodeFormattingVisitor.java +++ /dev/null @@ -1,170 +0,0 @@ -package pgo.formatters; - -import pgo.Unreachable; -import pgo.model.tla.*; - -import java.io.IOException; -import java.util.List; - -public class TLANodeFormattingVisitor extends TLANodeVisitor { - IndentingWriter out; - - public TLANodeFormattingVisitor(IndentingWriter out) { - this.out = out; - } - - @Override - public Void visit(TLAExpression TLAExpression) throws IOException { - TLAExpression.accept(new TLAExpressionFormattingVisitor(out)); - return null; - } - - @Override - public Void visit(TLAUnit pGoTLAUnit) throws IOException { - pGoTLAUnit.accept(new TLAUnitFormattingVisitor(out)); - return null; - } - - @Override - public Void visit(TLACaseArm TLACaseArm) throws IOException { - out.write("[] "); - TLACaseArm.getCondition().accept(new TLAExpressionFormattingVisitor(out)); - out.write(" -> "); - TLACaseArm.getResult().accept(new TLAExpressionFormattingVisitor(out)); - return null; - } - - @Override - public Void visit(TLAOpDecl pGoTLAOpDecl) throws IOException { - switch(pGoTLAOpDecl.getType()) { - case ID: - pGoTLAOpDecl.getName().accept(this); - break; - case INFIX: - out.write("_"); - pGoTLAOpDecl.getName().accept(this); - out.write("_"); - break; - case NAMED: - pGoTLAOpDecl.getName().accept(this); - out.write("(_"); - for(int i = 1; i key.accept(new TLAExpressionFormattingVisitor(out))); - out.write("]"); - return null; - } - - @Override - public Void visit(TLARecordSet.Field field) throws IOException { - field.getName().accept(this); - out.write(":"); - field.getSet().accept(new TLAExpressionFormattingVisitor(out)); - return null; - } - - @Override - public Void visit(TLARecordConstructor.Field field) throws IOException { - field.getName().accept(this); - out.write(" |-> "); - field.getValue().accept(new TLAExpressionFormattingVisitor(out)); - return null; - } - - @Override - public Void visit(TLAQuantifierBound pGoTLAQuantifierBound) throws IOException { - TLAQuantifierBound.Type type = pGoTLAQuantifierBound.getType(); - if (TLAQuantifierBound.Type$.MODULE$.ids().equals(type)) { - FormattingTools.writeCommaSeparated(out, pGoTLAQuantifierBound.getIds(), id -> id.accept(this)); - } else if (TLAQuantifierBound.Type$.MODULE$.tuple().equals(type)) { - out.write("<<"); - FormattingTools.writeCommaSeparated(out, pGoTLAQuantifierBound.getIds(), id -> id.accept(this)); - out.write(">>"); - } else { - throw new Unreachable(); - } - out.write(" \\in "); - pGoTLAQuantifierBound.getSet().accept(new TLAExpressionFormattingVisitor(out)); - return null; - } - - @Override - public Void visit(TLAInstance.Remapping remapping) throws IOException { - remapping.getFrom().accept(this); - out.write(" <- "); - remapping.getTo().accept(new TLAExpressionFormattingVisitor(out)); - return null; - } - - @Override - public Void visit(TLAIdentifierOrTuple pGoTLAIdentifierOrTuple) throws IOException { - if(pGoTLAIdentifierOrTuple.isTuple()) { - out.write("<<"); - FormattingTools.writeCommaSeparated(out, pGoTLAIdentifierOrTuple.getTuple(), elem -> elem.accept(this)); - out.write(">>"); - - }else { - pGoTLAIdentifierOrTuple.getId().accept(this); - } - return null; - } - - @Override - public Void visit(TLAIdentifier pGoTLAIdentifier) throws IOException { - out.write(pGoTLAIdentifier.getId()); - return null; - } - - @Override - public Void visit(TLAGeneralIdentifierPart pGoTLAGeneralIdentifierPart) throws IOException { - pGoTLAGeneralIdentifierPart.getIdentifier().accept(this); - List params = pGoTLAGeneralIdentifierPart.getParameters(); - if(!params.isEmpty()) { - out.write("("); - FormattingTools.writeCommaSeparated( - out, params, param -> param.accept(new TLAExpressionFormattingVisitor(out))); - out.write(")"); - } - out.write("!"); - return null; - } - - @Override - public Void visit(TLAFunctionSubstitutionPair pGoTLAFunctionSubstitutionPair) throws IOException { - out.write("!"); - for(TLASubstitutionKey key : pGoTLAFunctionSubstitutionPair.getKeys()) { - key.accept(this); - } - out.write(" = "); - pGoTLAFunctionSubstitutionPair.getValue().accept(new TLAExpressionFormattingVisitor(out)); - return null; - } - - @Override - public Void visit(TLASymbol pGoTLASymbol) throws IOException { - out.write(pGoTLASymbol.getValue()); - return null; - } - -} diff --git a/src/pgo/formatters/TLAUnitFormattingVisitor.java b/src/pgo/formatters/TLAUnitFormattingVisitor.java deleted file mode 100644 index 493dbeae2..000000000 --- a/src/pgo/formatters/TLAUnitFormattingVisitor.java +++ /dev/null @@ -1,144 +0,0 @@ -package pgo.formatters; - -import pgo.model.tla.*; - -import java.io.IOException; -import java.util.List; - -public class TLAUnitFormattingVisitor extends TLAUnitVisitor { - - IndentingWriter out; - - public TLAUnitFormattingVisitor(IndentingWriter out) { - this.out = out; - } - - @Override - public Void visit(TLAInstance pGoTLAInstance) throws IOException { - if(pGoTLAInstance.isLocal()) { - out.write("LOCAL "); - } - out.write("INSTANCE "); - pGoTLAInstance.getModuleName().accept(new TLANodeFormattingVisitor(out)); - List remappings = pGoTLAInstance.getRemappings(); - if(!remappings.isEmpty()) { - out.write(" WITH "); - FormattingTools.writeCommaSeparated(out, remappings, map -> { - map.accept(new TLANodeFormattingVisitor(out)); - }); - } - return null; - } - - @Override - public Void visit(TLAFunctionDefinition pGoTLAFunctionDefinition) throws IOException { - if(pGoTLAFunctionDefinition.isLocal()) { - out.write("LOCAL "); - } - pGoTLAFunctionDefinition.getName().accept(new TLANodeFormattingVisitor(out)); - out.write("["); - List args = pGoTLAFunctionDefinition.getFunction().getArguments(); - FormattingTools.writeCommaSeparated(out, args, arg -> { - arg.accept(new TLANodeFormattingVisitor(out)); - }); - out.write("]"); - out.write(" == "); - pGoTLAFunctionDefinition.getFunction().getBody().accept(new TLAExpressionFormattingVisitor(out)); - return null; - } - - @Override - public Void visit(TLAOperatorDefinition pGoTLAOperator) throws IOException { - if(pGoTLAOperator.isLocal()) { - out.write("LOCAL "); - } - // TODO: handle infix, etc - pGoTLAOperator.getName().accept(new TLANodeFormattingVisitor(out)); - List args = pGoTLAOperator.getArgs(); - if(!args.isEmpty()) { - out.write("("); - FormattingTools.writeCommaSeparated(out, args, arg -> { - arg.accept(new TLANodeFormattingVisitor(out)); - }); - out.write(")"); - } - out.write(" == "); - pGoTLAOperator.getBody().accept(new TLAExpressionFormattingVisitor(out)); - return null; - } - - @Override - public Void visit(TLATheorem pGoTLATheorem) throws IOException { - out.write("THEOREM "); - pGoTLATheorem.getTheorem().accept(new TLAExpressionFormattingVisitor(out)); - return null; - } - - @Override - public Void visit(TLAModule pGoTLAModule) throws IOException { - out.write("----"); - out.write(" MODULE "); - pGoTLAModule.getName().accept(new TLANodeFormattingVisitor(out)); - out.write("----"); - out.newLine(); - List exts = pGoTLAModule.getExtends(); - if(!exts.isEmpty()) { - out.write("EXTENDS "); - FormattingTools.writeCommaSeparated(out, exts, ext -> { - ext.identifier().accept(new TLANodeFormattingVisitor(out)); - }); - out.newLine(); - } - for(TLAUnit unit : pGoTLAModule.getUnits()) { - unit.accept(this); - out.newLine(); - } - out.write("===="); - return null; - } - - @Override - public Void visit(TLAVariableDeclaration pGoTLAVariableDeclaration) throws IOException { - out.write("VARIABLES "); - FormattingTools.writeCommaSeparated(out, pGoTLAVariableDeclaration.getVariables(), var -> { - var.accept(new TLANodeFormattingVisitor(out)); - }); - return null; - } - - @Override - public Void visit(TLAConstantDeclaration TLAConstantDeclaration) throws IOException { - out.write("CONSTANT "); - FormattingTools.writeCommaSeparated(out, TLAConstantDeclaration.getConstants(), var -> { - var.accept(new TLANodeFormattingVisitor(out)); - }); - return null; - } - - @Override - public Void visit(TLAModuleDefinition pGoTLAModuleDefinition) throws IOException { - if(pGoTLAModuleDefinition.isLocal()) { - out.write("LOCAL "); - } - pGoTLAModuleDefinition.getName().accept(new TLANodeFormattingVisitor(out)); - List args = pGoTLAModuleDefinition.getArgs(); - if(!args.isEmpty()) { - out.write("("); - FormattingTools.writeCommaSeparated(out, args, arg -> { - arg.accept(new TLANodeFormattingVisitor(out)); - }); - out.write(")"); - } - out.write(" == "); - pGoTLAModuleDefinition.getInstance().accept(this); - return null; - } - - @Override - public Void visit(TLAAssumption TLAAssumption) throws IOException { - out.write("ASSUME "); - TLAAssumption.getAssumption().accept(new TLAExpressionFormattingVisitor(out)); - return null; - } - -} diff --git a/src/pgo/formatters/TypeFormattingVisitor.java b/src/pgo/formatters/TypeFormattingVisitor.java deleted file mode 100644 index bbd01cc2d..000000000 --- a/src/pgo/formatters/TypeFormattingVisitor.java +++ /dev/null @@ -1,155 +0,0 @@ -package pgo.formatters; - -import pgo.model.type.*; - -import java.io.IOException; - -public class TypeFormattingVisitor extends TypeVisitor { - private final IndentingWriter out; - - public TypeFormattingVisitor(IndentingWriter out) { - this.out = out; - } - - @Override - public Void visit(AbstractRecordType abstractRecordType) throws IOException { - out.write("AbstractRecord"); - return null; - } - - @Override - public Void visit(ArchetypeResourceType archetypeResourceType) throws IOException { - out.write("ArchetypeResource read ("); - archetypeResourceType.getReadType().accept(this); - out.write(") write ("); - archetypeResourceType.getWriteType().accept(this); - out.write(")"); - return null; - } - - @Override - public Void visit(ArchetypeResourceCollectionType archetypeResourceCollectionType) throws IOException { - out.write("ArchetypeResourceCollection["); - archetypeResourceCollectionType.getKeyType().accept(this); - out.write("]read ("); - archetypeResourceCollectionType.getReadType().accept(this); - out.write(") write ("); - archetypeResourceCollectionType.getWriteType().accept(this); - out.write(")"); - return null; - } - - @Override - public Void visit(TypeVariable typeVariable) throws IOException { - out.write(typeVariable.getName()); - return null; - } - - @Override - public Void visit(TupleType tupleType) throws IOException { - out.write("Tuple["); - FormattingTools.writeCommaSeparated(out, tupleType.getElementTypes(), t -> t.accept(this)); - out.write("]"); - return null; - } - - @Override - public Void visit(StringType stringType) throws IOException { - out.write("String"); - return null; - } - - @Override - public Void visit(SetType setType) throws IOException { - out.write("Set["); - setType.getElementType().accept(this); - out.write("]"); - return null; - } - - @Override - public Void visit(NonEnumerableSetType nonEnumerableSetType) throws IOException { - out.write("NonEnumerableSet["); - nonEnumerableSetType.getElementType().accept(this); - out.write("]"); - return null; - } - - @Override - public Void visit(BoolType boolType) throws IOException { - out.write("Bool"); - return null; - } - - @Override - public Void visit(RealType realType) throws IOException { - out.write("Real"); - return null; - } - - @Override - public Void visit(FunctionType functionType) throws IOException { - out.write("Func("); - FormattingTools.writeCommaSeparated(out, functionType.getParamTypes(), p -> p.accept(this)); - out.write(") "); - functionType.getReturnType().accept(this); - return null; - } - - @Override - public Void visit(ChanType chanType) throws IOException { - out.write("Chan["); - chanType.getElementType().accept(this); - out.write("]"); - return null; - } - - @Override - public Void visit(IntType intType) throws IOException { - out.write("Int"); - return null; - } - - @Override - public Void visit(InterfaceType interfaceType) throws IOException { - out.write("Interface{}"); - return null; - } - - @Override - public Void visit(MapType mapType) throws IOException { - out.write("Map["); - mapType.getKeyType().accept(this); - out.write("]"); - mapType.getValueType().accept(this); - return null; - } - - @Override - public Void visit(SliceType sliceType) throws IOException { - out.write("Slice["); - sliceType.getElementType().accept(this); - out.write("]"); - return null; - } - - @Override - public Void visit(ProcedureType procedureType) throws IOException { - out.write("PlusCalProcedure("); - FormattingTools.writeCommaSeparated(out, procedureType.getParamTypes(), p -> p.accept(this)); - out.write(")"); - return null; - } - - @Override - public Void visit(RecordType recordType) throws IOException { - out.write("Record["); - FormattingTools.writeCommaSeparated(out, recordType.getFields(), f -> { - out.write(f.getName()); - out.write(" : "); - f.getType().accept(this); - }); - out.write("]"); - return null; - } -} diff --git a/src/pgo/model/Definitions.scala b/src/pgo/model/Definitions.scala new file mode 100644 index 000000000..3ef5cf4c5 --- /dev/null +++ b/src/pgo/model/Definitions.scala @@ -0,0 +1,42 @@ +package pgo.model + +import scala.collection.View + +sealed trait Definition { + def singleDefinitions: View[DefinitionOne] +} + +object Definition { + sealed abstract class ScopeIdentifier { + def sourceLocation: SourceLocation + } + object ScopeIdentifier { + implicit val scopeIdentifierOrdered: Ordering[ScopeIdentifier] = Ordering.by[ScopeIdentifier,(Boolean,String)] { + case ScopeIdentifierName(name) => (false, name.id) + case ScopeIdentifierSymbol(symbol) => (true, symbol.symbol.representations.head) + } + } + final case class ScopeIdentifierName(name: tla.TLAIdentifier) extends ScopeIdentifier { + override def sourceLocation: SourceLocation = name.sourceLocation + } + final case class ScopeIdentifierSymbol(symbol: tla.TLASymbol) extends ScopeIdentifier { + override def sourceLocation: SourceLocation = symbol.sourceLocation + } +} + +trait DefinitionOne extends Definition { + override def singleDefinitions: View[DefinitionOne] = View(this) + + def arity: Int + def identifier: Definition.ScopeIdentifier + + def isModuleInstance: Boolean = false + def isLocal: Boolean = false + def scope: Map[Definition.ScopeIdentifier, DefinitionOne] = Map.empty +} + +trait DefinitionComposite extends Definition { + def definitions: View[Definition] + override def singleDefinitions: View[DefinitionOne] = + definitions.flatMap(_.singleDefinitions) +} diff --git a/src/pgo/model/PGoError.scala b/src/pgo/model/PGoError.scala new file mode 100644 index 000000000..a53080724 --- /dev/null +++ b/src/pgo/model/PGoError.scala @@ -0,0 +1,21 @@ +package pgo.model + +import pgo.util.Description + +abstract class PGoError extends RuntimeException { + override def getMessage: String = + errors.view.map(err => err.description.ensureLineBreakBefore) + .flattenDescriptions + .linesIterator + .mkString("\n") + + def errors: List[PGoError.Error] +} + +object PGoError { + trait Error { + def sourceLocation: SourceLocation + def description: Description + def productPrefix: String + } +} diff --git a/src/pgo/model/RefersTo.scala b/src/pgo/model/RefersTo.scala new file mode 100644 index 000000000..04b1fc8dd --- /dev/null +++ b/src/pgo/model/RefersTo.scala @@ -0,0 +1,100 @@ +package pgo.model + +import pgo.model.Rewritable.BottomUpOnceStrategy +import pgo.util.IdMap + +import scala.reflect.ClassTag + +trait RefersTo[T] extends Rewritable { _: Rewritable => + private var refersTo_ : Option[T] = None + def refersTo: T = refersTo_.get + def setRefersTo(refersTo: T): this.type = { + refersTo_ = Some(refersTo) + this + } + + override def decorateLike(succ: this.type): this.type = + super.decorateLike(succ.setRefersTo(refersTo)) +} + +object RefersTo { + def unapply[T](candidate: Any)(implicit tag: ClassTag[T]): Option[T] = + candidate match { + case refersTo: RefersTo[_] => + refersTo.refersTo match { + case tag(refersTo) => + Some(refersTo) + case _ => None + } + case _ => None + } + + def eqFixpoint[T](init: T)(fn: T => T): T = { + import Rewritable._ + var tmp = init + var nextTmp = fn(tmp) + while(!(tmp forceEq nextTmp)) { + tmp = nextTmp + nextTmp = fn(tmp) + } + tmp + } + + final class Renamer[RefType <: AnyRef](implicit tag: ClassTag[RefType]) { + private var renamings = IdMap.empty[RefType,RefType] + + def addRenaming(from: RefType, to: RefType): this.type = { + renamings = renamings.updated(from, to) + this + } + + def addRenamings(renamings: IterableOnce[(RefType,RefType)]): this.type = { + renamings.iterator.foreach { + case (from, to) => addRenaming(from, to) + } + this + } + + private object RenamedTo { + def unapply(node: Rewritable): Option[(Rewritable with RefersTo[RefType], RefType)] = { + node match { + case node: Rewritable with RefersTo[RefType] if tag.runtimeClass.isInstance(node.refersTo) => + // catch transitive renamings + def rec(ref: RefType): Option[RefType] = + renamings.get(ref) + .filter(_ ne ref) // avoid renaming loops + .flatMap(rec) + .orElse(Some(ref)) + + rec(node.refersTo).map((node, _)) + case _ => None + } + } + } + + def apply[N <: Rewritable](node: N): N = { + if(renamings.nonEmpty) { + node.rewrite(strategy = BottomUpOnceStrategy) { + case RenamedTo(ref, to) => ref.shallowCopy().setRefersTo(to) + } + } else node + } + + def captureRenaming[T <: RefType with Rewritable](ref: T, fn: T=>T): T = { + val mappedRef = fn(apply(ref)) + if(mappedRef ne ref) { + addRenaming(ref, mappedRef) + } + mappedRef + } + + def captureRenamingAny[T <: RefType with Rewritable](ref: T, fn: Any=>Any): T = + captureRenaming(ref, (t: T) => fn(t).asInstanceOf[T]) + + def mapConserveRenaming[T <: RefType with Rewritable](refs: List[T], fn: T=>T): List[T] = + refs.mapConserve(captureRenaming(_, fn)) + + def mapConserveRenamingAny[T <: RefType with Rewritable](refs: List[T], fn: Any=>Any): List[T] = + mapConserveRenaming(refs, (t: T) => fn(t).asInstanceOf[T]) + } +} diff --git a/src/pgo/model/Rewritable.scala b/src/pgo/model/Rewritable.scala new file mode 100644 index 000000000..2140636f7 --- /dev/null +++ b/src/pgo/model/Rewritable.scala @@ -0,0 +1,111 @@ +package pgo.model + +import java.lang.reflect.Constructor + +trait Rewritable { + import Rewritable._ + + def productIterator: Iterator[Any] + + //def namedParts: Iterator[Any] = Iterator.empty + + def decorateLike(succ: this.type): this.type = succ + + def mapChildren(fn: Any => Any): this.type = + withChildren(productIterator.map(fn)) + + final def withChildren(children: Iterator[Any]): this.type = { + val childrenSeq = children.toSeq + if(childrenSeq.corresponds(productIterator)(_ forceEq _)) { + this + } else { + decorateLike(constructLikeFromSeq(this, childrenSeq)) + } + } + + final def shallowCopy(): this.type = + decorateLike(constructLikeFromSeq(this, productIterator.toSeq)) + + final def rewrite(strategy: Strategy = TopDownFirstStrategy)(fn: PartialFunction[Rewritable,Rewritable]): this.type = + strategy.execute(this, fn).asInstanceOf[this.type] +} + +object Rewritable { + implicit class AnyOps(val lhs: Any) extends AnyVal { + def forceEq(rhs: Any): Boolean = + lhs.asInstanceOf[AnyRef] eq rhs.asInstanceOf[AnyRef] + } + + trait Strategy { + def execute(rewritable: Any, fn: PartialFunction[Rewritable,Rewritable]): Any + } + + private val primitiveMap: Map[Class[_],Class[_]] = Map( + Integer.TYPE -> classOf[Integer], + java.lang.Byte.TYPE -> classOf[java.lang.Byte], + Character.TYPE -> classOf[Character], + java.lang.Boolean.TYPE -> classOf[java.lang.Boolean], + java.lang.Double.TYPE -> classOf[java.lang.Double], + java.lang.Float.TYPE -> classOf[java.lang.Float], + java.lang.Long.TYPE -> classOf[java.lang.Float], + java.lang.Short.TYPE -> classOf[java.lang.Short], + ) + + def constructLikeFromSeq[T](template: T, args: Seq[Any]): T = { + val klass = template.getClass + val constructor = klass.getConstructors()(0).asInstanceOf[Constructor[T]] + val paramTypes = constructor.getParameterTypes + require(paramTypes.length == args.size) + (paramTypes.view zip args.view).zipWithIndex.foreach { + case ((paramType, arg), idx) => + val effectiveParamType = + if(paramType.isPrimitive) { + primitiveMap(paramType) + } else paramType + require(effectiveParamType.isAssignableFrom(arg.getClass), s"type mismatch for argument $idx when constructing $klass") + } + constructor.newInstance(args:_*) + } + + def transformSubNodes(rewritable: Any, fn: Any => Any): Any = + rewritable match { + case map: Map[_,_] => + val result = map.view.mapValues(fn).to(map.mapFactory) + if(map.keysIterator.forall(k => map(k) forceEq result(k))) map + else result + case iterable: Iterable[_] => + val result = iterable.map(fn) + if(result.corresponds(iterable)(_ forceEq _)) iterable + else result + case product: Product => + val resultArgs = product.productIterator.map(fn).toSeq + if(product.productIterator.corresponds(resultArgs)(_ forceEq _)) product + else constructLikeFromSeq(product, resultArgs) + case any => any + } + + object TopDownFirstStrategy extends Strategy { + override def execute(rewritable: Any, fn: PartialFunction[Rewritable,Rewritable]): Any = + rewritable match { + case rewritable: Rewritable => + val result = fn.applyOrElse[Rewritable,Rewritable](rewritable, identity) + if(result eq rewritable) { + rewritable.mapChildren(this.execute(_, fn)) + } else { + result + } + case otherwise => + transformSubNodes(otherwise, this.execute(_, fn)) + } + } + + object BottomUpOnceStrategy extends Strategy { + override def execute(rewritable: Any, fn: PartialFunction[Rewritable,Rewritable]): Any = + rewritable match { + case rewritable: Rewritable => + fn.applyOrElse(rewritable.mapChildren(this.execute(_, fn)), identity[Rewritable]) + case otherwise => + transformSubNodes(otherwise, this.execute(_, fn)) + } + } +} diff --git a/src/pgo/model/SourceLocatable.scala b/src/pgo/model/SourceLocatable.scala new file mode 100644 index 000000000..50b56f586 --- /dev/null +++ b/src/pgo/model/SourceLocatable.scala @@ -0,0 +1,12 @@ +package pgo.model + +trait SourceLocatable { + private var _sourceLocation: SourceLocation = SourceLocation.unknown + + def sourceLocation: SourceLocation = _sourceLocation + + def setSourceLocation(sourceLocation: SourceLocation): this.type = { + _sourceLocation = sourceLocation + this + } +} diff --git a/src/pgo/model/SourceLocation.scala b/src/pgo/model/SourceLocation.scala new file mode 100644 index 000000000..e568f3487 --- /dev/null +++ b/src/pgo/model/SourceLocation.scala @@ -0,0 +1,152 @@ +package pgo.model + +import pgo.util.Description +import Description._ + +import scala.annotation.tailrec +import scala.collection.View + +sealed abstract class SourceLocation { + override def toString: String = shortDescription.linesIterator.mkString("\n") + def shortDescription: Description + def longDescription: Description + + def maybeOffset: Int = -1 + + def ++(other: SourceLocation): SourceLocation = { + (this, other) match { + case (SourceLocationUnknown, SourceLocationUnknown) => SourceLocationUnknown + case (SourceLocationInternal, SourceLocationInternal) => SourceLocationInternal + case (SourceLocationWithUnderlying(underlying1, startOffset1, endOffset1, startLine1, endLine1, startColumn1, endColumn1), SourceLocationWithUnderlying(underlying2, startOffset2, endOffset2, startLine2, endLine2, startColumn2, endColumn2)) => + require(underlying1 eq underlying2, s"SourceLocation combination needs two source locations that share the same underlying text") + SourceLocationWithUnderlying( + underlying = underlying1, + startOffset = startOffset1 min startOffset2, + endOffset = endOffset1 max endOffset2, + startLine = startLine1 min startLine2, + endLine = endLine1 max endLine2, + startColumn = + if(startLine1 == startLine2) startColumn1 min startColumn2 + else if(startLine1 < startLine2) startColumn1 + else startColumn2, + endColumn = + if(endLine1 == endLine2) endColumn1 max endColumn2 + else if(endLine1 > endLine2) endColumn1 + else endColumn2) + case (l, r) => + throw new IllegalArgumentException(s"requirement failed: SourceLocation combination must involve two locations of the same type: $l ++ $r") + } + } +} + +object SourceLocation { + def unknown: SourceLocation = SourceLocationUnknown + def internal: SourceLocation = SourceLocationInternal + + def apply(underlyingText: UnderlyingText, startOffset: Int, endOffset: Int, startLine: Int, endLine: Int, startColumn: Int, endColumn: Int): SourceLocation = + SourceLocationWithUnderlying(underlyingText, startOffset = startOffset, endOffset = endOffset, + startLine = startLine, endLine = endLine, startColumn = startColumn, endColumn = endColumn) + + trait UnderlyingText { + def name: String + def getLines(startLine: Int, length: Int): List[String] + } + + class UnderlyingFile(path: os.Path) extends UnderlyingText { + override def name: String = path.toString + override def getLines(startLine: Int, length: Int): List[String] = { + val span = os.read.lines.stream(path) + .slice(startLine, startLine + length) + if(length > 3) { + var first: String = null + var last: String = null + span.foreach { + case line if first eq null => first = line + case line => last = line + } + List(first, last) + } else { + span.toList + } + } + } + class UnderlyingString(str: String, override val name: String = "") extends UnderlyingText { + override def getLines(startLine: Int, length: Int): List[String] = { + val span = str.linesIterator.slice(startLine, startLine + length) + if(length > 3) { + var first: String = null + var last: String = null + span.foreach { + case line if first eq null => first = line + case line => last = line + } + List(first, last) + } else { + span.toList + } + } + } +} + +case object SourceLocationUnknown extends SourceLocation { + override val shortDescription: Description = d"" + override def longDescription: Description = shortDescription +} + +case object SourceLocationInternal extends SourceLocation { + override val shortDescription: Description = d"" + override def longDescription: Description = shortDescription +} + +final case class SourceLocationWithUnderlying(underlying: SourceLocation.UnderlyingText, + startOffset: Int, endOffset: Int, + startLine: Int, endLine: Int, + startColumn: Int, endColumn: Int) extends SourceLocation +{ + require(startLine <= endLine && startOffset <= endOffset) + + override def maybeOffset: Int = startOffset + + override val shortDescription: Description = + d"${underlying.name}:${startLine+1}.${startColumn+1}${ + if(startLine != endLine) d"--${endLine+1}.${endColumn+1}" else if(startColumn != endColumn) d"-${endColumn+1}" else d"" + }" + + override lazy val longDescription: Description = { + d"$shortDescription\n${ + val length = endLine - (startLine - 1) + val (lines, atEOF) = locally { + val lines = underlying.getLines(startLine-1, length+1) + assert(lines.nonEmpty) + if(lines.size == length) { + (if(lines.size == 1) List("") else lines.tail, true) + } else { + (lines.tail, false) + } + } + val firstLine = lines.head + if (length > 1) { + val header = (View.fill(startColumn)(d" ") ++ View.fill(firstLine.length - startColumn)(d"v")).flattenDescriptions + val footer = (View.fill(endColumn-1)(d"^") ++ (if(atEOF) View(d" EOF") else View.empty)).flattenDescriptions + if (length > 3) { + d"$header\n$firstLine\n...\n${lines.last}\n$footer" + } else { + d"$header\n${lines.view.map(_.toDescription.ensureLineBreakBefore).flattenDescriptions}\n$footer" + } + } else { + val footer = (View.fill(startColumn)(d" ") ++ View.fill(endColumn - startColumn)(d"^") ++ (if(atEOF) View(d" EOF") else View.empty)).flattenDescriptions + d"$firstLine\n$footer" + } + }" + } +} + +final case class DerivedSourceLocation(underlying: SourceLocation, via: SourceLocation, method: Description) extends SourceLocation { + override def maybeOffset: Int = underlying.maybeOffset + + override def shortDescription: Description = underlying.shortDescription + + override def longDescription: Description = d"${underlying.longDescription}\n${ + d"derived via $method at ${via.longDescription}".indented + }" +} diff --git a/src/pgo/model/Visitable.scala b/src/pgo/model/Visitable.scala new file mode 100644 index 000000000..2dc015128 --- /dev/null +++ b/src/pgo/model/Visitable.scala @@ -0,0 +1,63 @@ +package pgo.model + +trait Visitable { + import Visitable._ + + def productIterator: Iterator[Any] + + def visit(strategy: Strategy = TopDownFirstStrategy)(fn: PartialFunction[Visitable,Unit]): Unit = + strategy.execute(this, fn) + + def reduce[C](empty: =>C, reducer: (C,C) => C)(fn: PartialFunction[(Visitable,Seq[C]),C]): Unit = { + def reduceSubNode(node: Any): C = + node match { + case visitable: Visitable => + val subNodeResults = visitable.productIterator.map(reduceSubNode).toSeq + fn.applyOrElse((visitable,subNodeResults), { (_: (Visitable,Seq[C])) => + subNodeResults.foldLeft(empty)(reducer) + }) + case map: Map[_,_] => map.valuesIterator.map(reduceSubNode).foldLeft(empty)(reducer) + case iterable: Iterable[_] => iterable.iterator.map(reduceSubNode).foldLeft(empty)(reducer) + case product: Product => product.productIterator.map(reduceSubNode).foldLeft(empty)(reducer) + case _ => empty + } + reduceSubNode(this) + } +} + +object Visitable { + trait Strategy { + def execute(visitable: Any, fn: PartialFunction[Visitable,Unit]): Unit + } + + def visitSubNodes(visitable: Any, fn: Any => Unit): Unit = + visitable match { + case map: Map[_,_] => map.valuesIterator.foreach(fn) + case iterable: Iterable[_] => iterable.foreach(fn) + case product: Product => product.productIterator.foreach(fn) + case _ => + } + + object TopDownFirstStrategy extends Strategy { + override def execute(visitable: Any, fn: PartialFunction[Visitable,Unit]): Unit = + visitable match { + case visitable: Visitable => + fn.applyOrElse(visitable, { (visitable: Visitable) => + visitable.productIterator.foreach(this.execute(_, fn)) + }) + case otherwise => + visitSubNodes(otherwise, this.execute(_, fn)) + } + } + + object BottomUpFirstStrategy extends Strategy { + override def execute(visitable: Any, fn: PartialFunction[Visitable,Unit]): Unit = + visitable match { + case visitable: Visitable => + visitable.productIterator.foreach(this.execute(_, fn)) + fn.applyOrElse(visitable, (_: Visitable) => ()) + case otherwise => + visitSubNodes(otherwise, this.execute(_, fn)) + } + } +} diff --git a/src/pgo/model/golang/GoAnonymousFunction.java b/src/pgo/model/golang/GoAnonymousFunction.java deleted file mode 100644 index 4b2e1678d..000000000 --- a/src/pgo/model/golang/GoAnonymousFunction.java +++ /dev/null @@ -1,53 +0,0 @@ -package pgo.model.golang; - -import java.util.List; -import java.util.Objects; - -/** - * Represents an anonymous function in go - * - */ -public class GoAnonymousFunction extends GoExpression { - private final List params; - private final List returnTypes; - private final GoBlock body; - - public GoAnonymousFunction(List params, List returnTypes, GoBlock body) { - this.params = params; - this.returnTypes = returnTypes; - this.body = body; - } - - public List getReturnTypes(){ - return returnTypes; - } - - public List getParams(){ - return params; - } - - public GoBlock getBody() { - return body; - } - - @Override - public T accept(GoExpressionVisitor visitor) throws E { - return visitor.visit(this); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - GoAnonymousFunction that = (GoAnonymousFunction) o; - return Objects.equals(params, that.params) && - Objects.equals(returnTypes, that.returnTypes) && - Objects.equals(body, that.body); - } - - @Override - public int hashCode() { - - return Objects.hash(params, returnTypes, body); - } -} \ No newline at end of file diff --git a/src/pgo/model/golang/GoAssignmentStatement.java b/src/pgo/model/golang/GoAssignmentStatement.java deleted file mode 100644 index 6ac7f95a8..000000000 --- a/src/pgo/model/golang/GoAssignmentStatement.java +++ /dev/null @@ -1,57 +0,0 @@ -package pgo.model.golang; - -import java.util.List; -import java.util.Objects; - -/** - * Assigns a value to a variable : - * - * - * goVar = {expr} - * - */ -public class GoAssignmentStatement extends GoStatement { - - private final List names; - private final boolean defines; - private final List values; - - public GoAssignmentStatement(List names, boolean defines, List values) { - this.names = names; - this.defines = defines; - this.values = values; - } - - public List getNames() { - return names; - } - - public boolean isDefinition() { - return defines; - } - - public List getValues() { - return values; - } - - @Override - public T accept(GoStatementVisitor v) throws E { - return v.visit(this); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - GoAssignmentStatement that = (GoAssignmentStatement) o; - return defines == that.defines && - Objects.equals(names, that.names) && - Objects.equals(values, that.values); - } - - @Override - public int hashCode() { - - return Objects.hash(names, defines, values); - } -} diff --git a/src/pgo/model/golang/GoBinop.java b/src/pgo/model/golang/GoBinop.java deleted file mode 100644 index 746cc9c08..000000000 --- a/src/pgo/model/golang/GoBinop.java +++ /dev/null @@ -1,75 +0,0 @@ -package pgo.model.golang; - -import java.util.Objects; - -public class GoBinop extends GoExpression { - - private final GoExpression lhs; - private final GoExpression rhs; - private final Operation op; - - public enum Operation{ - // grouped by precedence - OR, - AND, - - EQ, - NEQ, - LT, - LEQ, - GT, - GEQ, - - PLUS, - MINUS, - BOR, - BXOR, - - TIMES, - DIVIDE, - MOD, - LSHIFT, - RSHIFT, - BAND, - BCLEAR, - } - - public GoBinop(Operation op, GoExpression lhs, GoExpression rhs) { - this.op = op; - this.lhs = lhs; - this.rhs = rhs; - } - - public Operation getOperation() { - return op; - } - - public GoExpression getLHS() { - return lhs; - } - - public GoExpression getRHS() { - return rhs; - } - - @Override - public T accept(GoExpressionVisitor visitor) throws E { - return visitor.visit(this); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - GoBinop binop = (GoBinop) o; - return Objects.equals(lhs, binop.lhs) && - Objects.equals(rhs, binop.rhs) && - op == binop.op; - } - - @Override - public int hashCode() { - - return Objects.hash(lhs, rhs, op); - } -} diff --git a/src/pgo/model/golang/GoBlock.java b/src/pgo/model/golang/GoBlock.java deleted file mode 100644 index b6fb2775e..000000000 --- a/src/pgo/model/golang/GoBlock.java +++ /dev/null @@ -1,36 +0,0 @@ -package pgo.model.golang; - -import java.util.List; -import java.util.Objects; - -public class GoBlock extends GoStatement { - - private final List statements; - - public GoBlock(List statements) { - this.statements = statements; - } - - public List getStatements(){ - return statements; - } - - @Override - public T accept(GoStatementVisitor v) throws E { - return v.visit(this); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - GoBlock block = (GoBlock) o; - return Objects.equals(statements, block.statements); - } - - @Override - public int hashCode() { - - return Objects.hash(statements); - } -} diff --git a/src/pgo/model/golang/GoBreak.java b/src/pgo/model/golang/GoBreak.java deleted file mode 100644 index 6632122ca..000000000 --- a/src/pgo/model/golang/GoBreak.java +++ /dev/null @@ -1,20 +0,0 @@ -package pgo.model.golang; - -public class GoBreak extends GoStatement { - - @Override - public T accept(GoStatementVisitor v) throws E { - return v.visit(this); - } - - @Override - public boolean equals(Object other){ - return other instanceof GoBreak; - } - - @Override - public int hashCode(){ - return 0; - } - -} diff --git a/src/pgo/model/golang/GoBuiltins.java b/src/pgo/model/golang/GoBuiltins.java deleted file mode 100644 index 2403e59c8..000000000 --- a/src/pgo/model/golang/GoBuiltins.java +++ /dev/null @@ -1,82 +0,0 @@ -package pgo.model.golang; - -import pgo.model.golang.type.GoInterfaceType; -import pgo.model.golang.type.GoType; -import pgo.model.golang.type.GoTypeName; - -import java.util.Collections; -import java.util.HashSet; -import java.util.Objects; -import java.util.Set; - -public final class GoBuiltins { - - private GoBuiltins() {} - - public static class BuiltinConstant extends GoExpression { - private final String value; - - public BuiltinConstant(String value) { - this.value = value; - } - - public String getValue() { - return value; - } - - @Override - public T accept(GoExpressionVisitor visitor) throws E { - return visitor.visit(this); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - BuiltinConstant that = (BuiltinConstant) o; - return Objects.equals(value, that.value); - } - - @Override - public int hashCode() { - - return Objects.hash(value); - } - } - - public static GoType Interface = new GoInterfaceType(Collections.emptyList()); - public static GoTypeName Error = new GoTypeName("error", true); - public static GoTypeName Bool = new GoTypeName("bool", true); - public static GoTypeName String = new GoTypeName("string", true); - public static GoTypeName UInt8 = new GoTypeName("uint8", true); - public static GoTypeName UInt16 = new GoTypeName("uint16", true); - public static GoTypeName UInt32 = new GoTypeName("uint32", true); - public static GoTypeName UInt64 = new GoTypeName("uint64", true); - public static GoTypeName Float32 = new GoTypeName("float32", true); - public static GoTypeName Float64 = new GoTypeName("float64", true); - public static GoTypeName Int8 = new GoTypeName("int8", true); - public static GoTypeName Int16 = new GoTypeName("int16", true); - public static GoTypeName Int32 = new GoTypeName("int32", true); - public static GoTypeName Int64 = new GoTypeName("int64", true); - public static GoTypeName Complex32 = new GoTypeName("complex32", true); - public static GoTypeName Complex64 = new GoTypeName("complex64", true); - - // types that aren't real, but may be useful to mark that an algorithm doesn't care - // about 32 vs. 64 bit floats for example - public static GoType Float = Float32; - - // machine-specific aliases, defined by GoRoutineStatement - public static GoType UInt = new GoTypeName("uint", true); - public static GoType Int = new GoTypeName("int", true); - public static GoType UIntPtr = new GoTypeName("uintptr", true); - - // language aliases, here for convenience - public static GoType Byte = new GoTypeName("byte", true); // uint8 - public static GoType Rune = new GoTypeName("rune", true); // int32 - - // built-in constants - public static GoExpression True = new BuiltinConstant("true"); - public static GoExpression False = new BuiltinConstant("false"); - - public static GoExpression Nil = new BuiltinConstant("nil"); -} diff --git a/src/pgo/model/golang/GoCall.java b/src/pgo/model/golang/GoCall.java deleted file mode 100644 index a8835b8df..000000000 --- a/src/pgo/model/golang/GoCall.java +++ /dev/null @@ -1,53 +0,0 @@ -package pgo.model.golang; - -import java.util.List; -import java.util.Objects; - -public class GoCall extends GoExpression { - private final GoExpression target; - private final List arguments; - private final boolean ellipsis; - - public GoCall(GoExpression target, List arguments) { - this(target, arguments, false); - } - - public GoCall(GoExpression target, List arguments, boolean ellipsis) { - this.target = target; - this.arguments = arguments; - this.ellipsis = ellipsis; - } - - public GoExpression getTarget() { - return target; - } - - public List getArguments(){ - return arguments; - } - - public boolean hasEllipsis() { - return ellipsis; - } - - @Override - public T accept(GoExpressionVisitor visitor) throws E { - return visitor.visit(this); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - GoCall call = (GoCall) o; - return ellipsis == call.ellipsis && - Objects.equals(target, call.target) && - Objects.equals(arguments, call.arguments); - } - - @Override - public int hashCode() { - - return Objects.hash(target, arguments, ellipsis); - } -} diff --git a/src/pgo/model/golang/GoComment.java b/src/pgo/model/golang/GoComment.java deleted file mode 100644 index 201d6de02..000000000 --- a/src/pgo/model/golang/GoComment.java +++ /dev/null @@ -1,38 +0,0 @@ -package pgo.model.golang; - -import java.util.Objects; - -/** - * A Golang comment - * - */ -public class GoComment extends GoStatement { - private final String comment; - - public GoComment(String comment) { - this.comment = comment; - } - - public String getComment() { - return comment; - } - - @Override - public T accept(GoStatementVisitor v) throws E { - return v.visit(this); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - GoComment comment1 = (GoComment) o; - return Objects.equals(comment, comment1.comment); - } - - @Override - public int hashCode() { - - return Objects.hash(comment); - } -} diff --git a/src/pgo/model/golang/GoContinue.java b/src/pgo/model/golang/GoContinue.java deleted file mode 100644 index a29773acb..000000000 --- a/src/pgo/model/golang/GoContinue.java +++ /dev/null @@ -1,19 +0,0 @@ -package pgo.model.golang; - -public class GoContinue extends GoStatement { - - @Override - public T accept(GoStatementVisitor v) throws E { - return v.visit(this); - } - - @Override - public boolean equals(Object other){ - return other instanceof GoContinue; - } - - @Override - public int hashCode(){ - return 0; - } -} diff --git a/src/pgo/model/golang/GoDeclaration.java b/src/pgo/model/golang/GoDeclaration.java deleted file mode 100644 index d7011260a..000000000 --- a/src/pgo/model/golang/GoDeclaration.java +++ /dev/null @@ -1,12 +0,0 @@ -package pgo.model.golang; - -public abstract class GoDeclaration extends GoNode { - - @Override - public T accept(GoNodeVisitor v) throws E { - return v.visit(this); - } - - public abstract T accept(GoDeclarationVisitor v) throws E; - -} diff --git a/src/pgo/model/golang/GoDeclarationVisitor.java b/src/pgo/model/golang/GoDeclarationVisitor.java deleted file mode 100644 index c480f5791..000000000 --- a/src/pgo/model/golang/GoDeclarationVisitor.java +++ /dev/null @@ -1,9 +0,0 @@ -package pgo.model.golang; - -public abstract class GoDeclarationVisitor { - - public abstract T visit(GoFunctionDeclaration functionDeclaration) throws E; - public abstract T visit(GoTypeDeclaration typeDeclaration) throws E; - public abstract T visit(GoVariableDeclaration variableDeclaration) throws E; - -} diff --git a/src/pgo/model/golang/GoDefer.java b/src/pgo/model/golang/GoDefer.java deleted file mode 100644 index 1b9f6a608..000000000 --- a/src/pgo/model/golang/GoDefer.java +++ /dev/null @@ -1,34 +0,0 @@ -package pgo.model.golang; - -import java.util.Objects; - -public class GoDefer extends GoStatement { - private final GoExpression expression; - - public GoDefer(GoExpression expression) { - this.expression = expression; - } - - public GoExpression getExpression() { - return expression; - } - - @Override - public T accept(GoStatementVisitor v) throws E { - return v.visit(this); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - GoDefer defer = (GoDefer) o; - return Objects.equals(expression, defer.expression); - } - - @Override - public int hashCode() { - - return Objects.hash(expression); - } -} diff --git a/src/pgo/model/golang/GoExpression.java b/src/pgo/model/golang/GoExpression.java deleted file mode 100644 index 9445ce1c8..000000000 --- a/src/pgo/model/golang/GoExpression.java +++ /dev/null @@ -1,16 +0,0 @@ -package pgo.model.golang; - -/** - * A GoRoutineStatement code expression base class - * - */ -public abstract class GoExpression extends GoNode { - - public abstract T accept(GoExpressionVisitor visitor) throws E; - - @Override - public T accept(GoNodeVisitor v) throws E { - return v.visit(this); - } - -} \ No newline at end of file diff --git a/src/pgo/model/golang/GoExpressionStatement.java b/src/pgo/model/golang/GoExpressionStatement.java deleted file mode 100644 index 0831c9d0b..000000000 --- a/src/pgo/model/golang/GoExpressionStatement.java +++ /dev/null @@ -1,35 +0,0 @@ -package pgo.model.golang; - -import java.util.Objects; - -public class GoExpressionStatement extends GoStatement { - - private final GoExpression expression; - - public GoExpressionStatement(GoExpression expression) { - this.expression = expression; - } - - public GoExpression getExpression() { - return expression; - } - - @Override - public T accept(GoStatementVisitor v) throws E { - return v.visit(this); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - GoExpressionStatement that = (GoExpressionStatement) o; - return Objects.equals(expression, that.expression); - } - - @Override - public int hashCode() { - - return Objects.hash(expression); - } -} diff --git a/src/pgo/model/golang/GoExpressionVisitor.java b/src/pgo/model/golang/GoExpressionVisitor.java deleted file mode 100644 index 72ec1e4c9..000000000 --- a/src/pgo/model/golang/GoExpressionVisitor.java +++ /dev/null @@ -1,21 +0,0 @@ -package pgo.model.golang; - -public abstract class GoExpressionVisitor { - public abstract T visit(GoVariableName v) throws E; - public abstract T visit(GoBuiltins.BuiltinConstant v) throws E; - public abstract T visit(GoIntLiteral intLiteral) throws E; - public abstract T visit(GoMapLiteral mapConstructor) throws E; - public abstract T visit(GoStringLiteral stringLiteral) throws E; - public abstract T visit(GoIndexExpression index) throws E; - public abstract T visit(GoSliceOperator slice) throws E; - public abstract T visit(GoSliceLiteral sliceConstructor) throws E; - public abstract T visit(GoTypeAssertion typeAssertion) throws E; - public abstract T visit(GoAnonymousFunction anonymousFunction) throws E; - public abstract T visit(GoCall call) throws E; - public abstract T visit(GoTypeCast typeCast) throws E; - public abstract T visit(GoStructLiteral structLiteral) throws E; - public abstract T visit(GoBinop binop) throws E; - public abstract T visit(GoUnary unary) throws E; - public abstract T visit(GoSelectorExpression dot) throws E; - public abstract T visit(GoMakeExpression make) throws E; -} diff --git a/src/pgo/model/golang/GoFor.java b/src/pgo/model/golang/GoFor.java deleted file mode 100644 index 594b1c757..000000000 --- a/src/pgo/model/golang/GoFor.java +++ /dev/null @@ -1,61 +0,0 @@ -package pgo.model.golang; - -import java.util.Objects; - -/** - * The for loop. Equivalent to PlusCal while - * - */ -public class GoFor extends GoStatement { - // boolean condition - private final GoStatement init; - private final GoExpression cond; - private final GoStatement inc; - - private final GoBlock body; - - public GoFor(GoStatement init, GoExpression cond, GoStatement inc, GoBlock body) { - this.init = init; - this.cond = cond; - this.inc = inc; - this.body = body; - } - - public GoStatement getInit() { - return init; - } - - public GoExpression getCondition() { - return cond; - } - - public GoStatement getIncrement() { - return inc; - } - - public GoBlock getBody() { - return body; - } - - @Override - public T accept(GoStatementVisitor v) throws E { - return v.visit(this); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - GoFor aFor = (GoFor) o; - return Objects.equals(init, aFor.init) && - Objects.equals(cond, aFor.cond) && - Objects.equals(inc, aFor.inc) && - Objects.equals(body, aFor.body); - } - - @Override - public int hashCode() { - - return Objects.hash(init, cond, inc, body); - } -} diff --git a/src/pgo/model/golang/GoForRange.java b/src/pgo/model/golang/GoForRange.java deleted file mode 100644 index 866358ad3..000000000 --- a/src/pgo/model/golang/GoForRange.java +++ /dev/null @@ -1,60 +0,0 @@ -package pgo.model.golang; - -import java.util.List; -import java.util.Objects; - -/** - * Represents a for _ := range _ loop in GoRoutineStatement - */ -public class GoForRange extends GoStatement { - private final List lhs; - private final boolean defines; - private final GoExpression rangeExpr; - - private final GoBlock body; - - public GoForRange(List lhs, boolean defines, GoExpression rangeExpr, GoBlock body) { - this.lhs = lhs; - this.defines = defines; - this.rangeExpr = rangeExpr; - this.body = body; - } - - public List getLhs() { - return lhs; - } - - public boolean isDefinition() { - return defines; - } - - public GoExpression getRangeExpr() { - return rangeExpr; - } - - public GoBlock getBody() { - return body; - } - - @Override - public T accept(GoStatementVisitor v) throws E { - return v.visit(this); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - GoForRange forRange = (GoForRange) o; - return defines == forRange.defines && - Objects.equals(lhs, forRange.lhs) && - Objects.equals(rangeExpr, forRange.rangeExpr) && - Objects.equals(body, forRange.body); - } - - @Override - public int hashCode() { - - return Objects.hash(lhs, defines, rangeExpr, body); - } -} diff --git a/src/pgo/model/golang/GoFunctionDeclaration.java b/src/pgo/model/golang/GoFunctionDeclaration.java deleted file mode 100644 index 7b2b2738e..000000000 --- a/src/pgo/model/golang/GoFunctionDeclaration.java +++ /dev/null @@ -1,67 +0,0 @@ -package pgo.model.golang; - -import java.util.List; -import java.util.Objects; - -/** - * Represents a function in go - * - */ -public class GoFunctionDeclaration extends GoDeclaration { - private final String name; - - private GoFunctionParameter receiver; - private final List arguments; - private final List returnTypes; - private final GoBlock body; - - public GoFunctionDeclaration(String name, GoFunctionParameter receiver, List arguments, List returnTypes, GoBlock body) { - this.name = name; - this.arguments = arguments; - this.returnTypes = returnTypes; - this.body = body; - } - - public String getName() { - return name; - } - - public GoFunctionParameter getReceiver() { - return receiver; - } - - public List getReturnTypes(){ - return returnTypes; - } - - public List getArguments(){ - return arguments; - } - - public GoBlock getBody() { - return body; - } - - @Override - public T accept(GoDeclarationVisitor v) throws E { - return v.visit(this); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - GoFunctionDeclaration that = (GoFunctionDeclaration) o; - return Objects.equals(name, that.name) && - Objects.equals(receiver, that.receiver) && - Objects.equals(arguments, that.arguments) && - Objects.equals(returnTypes, that.returnTypes) && - Objects.equals(body, that.body); - } - - @Override - public int hashCode() { - - return Objects.hash(name, receiver, arguments, returnTypes, body); - } -} \ No newline at end of file diff --git a/src/pgo/model/golang/GoFunctionParameter.java b/src/pgo/model/golang/GoFunctionParameter.java deleted file mode 100644 index 5a5fec1ed..000000000 --- a/src/pgo/model/golang/GoFunctionParameter.java +++ /dev/null @@ -1,43 +0,0 @@ -package pgo.model.golang; - -import pgo.model.golang.type.GoType; - -import java.util.Objects; - -public class GoFunctionParameter extends GoNode { - private final String name; - private final GoType type; - - public GoFunctionParameter(String name, GoType type) { - this.name = name; - this.type = type; - } - - public String getName() { - return name; - } - - public GoType getType() { - return type; - } - - @Override - public T accept(GoNodeVisitor v) throws E { - return v.visit(this); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - GoFunctionParameter that = (GoFunctionParameter) o; - return Objects.equals(name, that.name) && - Objects.equals(type, that.type); - } - - @Override - public int hashCode() { - - return Objects.hash(name, type); - } -} diff --git a/src/pgo/model/golang/GoIf.java b/src/pgo/model/golang/GoIf.java deleted file mode 100644 index 12559d8ad..000000000 --- a/src/pgo/model/golang/GoIf.java +++ /dev/null @@ -1,67 +0,0 @@ -package pgo.model.golang; - -import java.util.List; -import java.util.Objects; - -/** - * The if statement - * - */ -public class GoIf extends GoStatement { - // boolean condition - private final GoExpression cond; - private final List initialVariables; - private final GoExpression initialExpression; - private final GoBlock bThen; - private final GoBlock bElse; - - public GoIf(GoExpression cond, List initialVariables, GoExpression initialExpression, GoBlock bThen, GoBlock bElse) { - this.cond = cond; - this.initialVariables = initialVariables; - this.initialExpression = initialExpression; - this.bThen = bThen; - this.bElse = bElse; - } - - public GoExpression getCond() { - return cond; - } - - public List getInitialVariables() { - return this.initialVariables; - } - - public GoExpression getInitialExpression() { - return this.initialExpression; - } - - public GoBlock getThen() { - return bThen; - } - - public GoBlock getElse() { - return bElse; - } - - @Override - public T accept(GoStatementVisitor v) throws E { - return v.visit(this); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - GoIf anIf = (GoIf) o; - return Objects.equals(cond, anIf.cond) && - Objects.equals(initialVariables, anIf.getInitialVariables()) && - Objects.equals(initialExpression, anIf.getInitialExpression()) && - Objects.equals(bThen, anIf.bThen) && - Objects.equals(bElse, anIf.bElse); - } - - @Override - public int hashCode() { - return Objects.hash(cond, initialVariables, initialExpression, bThen, bElse); - } -} diff --git a/src/pgo/model/golang/GoIfBuilder.java b/src/pgo/model/golang/GoIfBuilder.java deleted file mode 100644 index 5f3a8b6ff..000000000 --- a/src/pgo/model/golang/GoIfBuilder.java +++ /dev/null @@ -1,74 +0,0 @@ -package pgo.model.golang; - -import pgo.model.golang.builder.GoASTBuilder; -import pgo.model.golang.builder.GoBlockBuilder; -import pgo.scope.UID; -import pgo.trans.passes.codegen.NameCleaner; - -import java.io.Closeable; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -public class GoIfBuilder implements Closeable { - - private final GoASTBuilder builder; - private final NameCleaner nameCleaner; - private final NameCleaner labelScope; - private GoExpression condition; - private GoBlock trueBranch; - private GoBlock falseBranch; - private final List initialVariables; - private GoExpression initialExpression; - private final Map nameMap; - - public GoIfBuilder(GoASTBuilder builder, NameCleaner nameCleaner, Map nameMap, - NameCleaner labelScope, GoExpression condition) { - this.builder = builder; - this.nameCleaner = nameCleaner; - this.nameMap = nameMap; - this.labelScope = labelScope; - this.condition = condition; - this.trueBranch = null; - this.falseBranch = null; - this.initialVariables = new ArrayList<>(); - this.initialExpression = null; - } - - public List initialAssignment(List nameHints, GoExpression initialExpression) { - nameHints.forEach(hint -> { - String actualName = nameCleaner.cleanName(hint); - initialVariables.add(new GoVariableName(actualName)); - }); - - this.initialExpression = initialExpression; - return Collections.unmodifiableList(initialVariables); - } - - public void setCondition(GoExpression condition) { - this.condition = condition; - } - - private void addTrue(GoBlock block) { - trueBranch = block; - } - - private void addFalse(GoBlock block) { - falseBranch = block; - } - - public GoBlockBuilder whenTrue() { - return new GoBlockBuilder(builder, nameCleaner.child(), nameMap, labelScope, this::addTrue); - } - - public GoBlockBuilder whenFalse() { - return new GoBlockBuilder(builder, nameCleaner.child(), nameMap, labelScope, this::addFalse); - } - - @Override - public void close() { - builder.addStatement(new GoIf(condition, initialVariables, initialExpression, trueBranch, falseBranch)); - } - -} diff --git a/src/pgo/model/golang/GoIncDec.java b/src/pgo/model/golang/GoIncDec.java deleted file mode 100644 index 06d8852bf..000000000 --- a/src/pgo/model/golang/GoIncDec.java +++ /dev/null @@ -1,42 +0,0 @@ -package pgo.model.golang; - -import java.util.Objects; - -public class GoIncDec extends GoStatement { - - private final boolean inc; - private final GoExpression expression; - - public GoIncDec(boolean inc, GoExpression expression) { - this.inc = inc; - this.expression = expression; - } - - public boolean isInc() { - return inc; - } - - public GoExpression getExpression() { - return expression; - } - - @Override - public T accept(GoStatementVisitor v) throws E { - return v.visit(this); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - GoIncDec incDec = (GoIncDec) o; - return inc == incDec.inc && - Objects.equals(expression, incDec.expression); - } - - @Override - public int hashCode() { - - return Objects.hash(inc, expression); - } -} diff --git a/src/pgo/model/golang/GoIndexExpression.java b/src/pgo/model/golang/GoIndexExpression.java deleted file mode 100644 index f0d97d66a..000000000 --- a/src/pgo/model/golang/GoIndexExpression.java +++ /dev/null @@ -1,42 +0,0 @@ -package pgo.model.golang; - -import java.util.Objects; - -public class GoIndexExpression extends GoExpression { - - GoExpression target; - GoExpression index; - - public GoIndexExpression(GoExpression target, GoExpression index) { - this.target = target; - this.index = index; - } - - public GoExpression getTarget() { - return target; - } - - public GoExpression getIndex() { - return index; - } - - @Override - public T accept(GoExpressionVisitor visitor) throws E { - return visitor.visit(this); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - GoIndexExpression index1 = (GoIndexExpression) o; - return Objects.equals(target, index1.target) && - Objects.equals(index, index1.index); - } - - @Override - public int hashCode() { - - return Objects.hash(target, index); - } -} diff --git a/src/pgo/model/golang/GoIntLiteral.java b/src/pgo/model/golang/GoIntLiteral.java deleted file mode 100644 index de76ba103..000000000 --- a/src/pgo/model/golang/GoIntLiteral.java +++ /dev/null @@ -1,35 +0,0 @@ -package pgo.model.golang; - -import java.util.Objects; - -public class GoIntLiteral extends GoExpression { - - private final int value; - - public GoIntLiteral(int value) { - this.value = value; - } - - public int getValue() { - return value; - } - - @Override - public T accept(GoExpressionVisitor visitor) throws E { - return visitor.visit(this); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - GoIntLiteral that = (GoIntLiteral) o; - return value == that.value; - } - - @Override - public int hashCode() { - - return Objects.hash(value); - } -} diff --git a/src/pgo/model/golang/GoLabel.java b/src/pgo/model/golang/GoLabel.java deleted file mode 100644 index 1b2702659..000000000 --- a/src/pgo/model/golang/GoLabel.java +++ /dev/null @@ -1,39 +0,0 @@ -package pgo.model.golang; - -import java.util.Objects; - -/** - * A label in GoRoutineStatement. This will be on it's own line - * - */ -public class GoLabel extends GoStatement { - - private final String name; - - public GoLabel(String name) { - this.name = name; - } - - public String getName() { - return name; - } - - @Override - public T accept(GoStatementVisitor v) throws E { - return v.visit(this); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - GoLabel label = (GoLabel) o; - return Objects.equals(name, label.name); - } - - @Override - public int hashCode() { - - return Objects.hash(name); - } -} diff --git a/src/pgo/model/golang/GoLabelName.java b/src/pgo/model/golang/GoLabelName.java deleted file mode 100644 index db408ff74..000000000 --- a/src/pgo/model/golang/GoLabelName.java +++ /dev/null @@ -1,35 +0,0 @@ -package pgo.model.golang; - -import java.util.Objects; - -public class GoLabelName extends GoNode { - - private final String name; - - public GoLabelName(String name) { - this.name = name; - } - - public String getName() { - return name; - } - - @Override - public T accept(GoNodeVisitor v) throws E { - return v.visit(this); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - GoLabelName labelName = (GoLabelName) o; - return Objects.equals(name, labelName.name); - } - - @Override - public int hashCode() { - - return Objects.hash(name); - } -} diff --git a/src/pgo/model/golang/GoMakeExpression.java b/src/pgo/model/golang/GoMakeExpression.java deleted file mode 100644 index 9b11edadd..000000000 --- a/src/pgo/model/golang/GoMakeExpression.java +++ /dev/null @@ -1,55 +0,0 @@ -package pgo.model.golang; - -import pgo.model.golang.type.GoType; - -import java.util.Objects; - -public class GoMakeExpression extends GoExpression { - - private final GoType type; - private final GoExpression size; - private final GoExpression capacity; - - public GoMakeExpression(GoType type, GoExpression size, GoExpression capacity) { - this.type = type; - this.size = size; - this.capacity = capacity; - } - - public GoMakeExpression(GoType type, GoExpression size) { - this(type, size, null); - } - - public GoType getType() { - return type; - } - - public GoExpression getSize() { - return size; - } - - public GoExpression getCapacity() { - return capacity; - } - - @Override - public T accept(GoExpressionVisitor visitor) throws E { - return visitor.visit(this); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - GoMakeExpression make = (GoMakeExpression) o; - return Objects.equals(type, make.type) && - Objects.equals(size, make.size) && - Objects.equals(capacity, make.capacity); - } - - @Override - public int hashCode() { - - return Objects.hash(type, size, capacity); - } -} diff --git a/src/pgo/model/golang/GoMapLiteral.java b/src/pgo/model/golang/GoMapLiteral.java deleted file mode 100644 index 24e1c773f..000000000 --- a/src/pgo/model/golang/GoMapLiteral.java +++ /dev/null @@ -1,52 +0,0 @@ -package pgo.model.golang; - -import pgo.model.golang.type.GoType; - -import java.util.Map; -import java.util.Objects; - -public class GoMapLiteral extends GoExpression { - - private final Map pairs; - private final GoType keyType; - private final GoType valueType; - - public GoMapLiteral(GoType keyType, GoType valueType, Map pairs) { - this.keyType = keyType; - this.valueType = valueType; - this.pairs = pairs; - } - - public Map getPairs(){ - return pairs; - } - - public GoType getKeyType() { - return keyType; - } - - public GoType getValueType() { - return valueType; - } - - @Override - public T accept(GoExpressionVisitor visitor) throws E { - return visitor.visit(this); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - GoMapLiteral that = (GoMapLiteral) o; - return Objects.equals(pairs, that.pairs) && - Objects.equals(keyType, that.keyType) && - Objects.equals(valueType, that.valueType); - } - - @Override - public int hashCode() { - - return Objects.hash(pairs, keyType, valueType); - } -} diff --git a/src/pgo/model/golang/GoModule.java b/src/pgo/model/golang/GoModule.java deleted file mode 100644 index ce30941ff..000000000 --- a/src/pgo/model/golang/GoModule.java +++ /dev/null @@ -1,56 +0,0 @@ -package pgo.model.golang; - -import java.util.List; -import java.util.Objects; - -public class GoModule extends GoNode { - private final String name; - private final List declarations; - private final List imports; - private final GoExpression pack; - - public GoModule(String name, GoExpression pack, List imports, List declarations) { - this.name = name; - this.pack = pack; - this.imports = imports; - this.declarations = declarations; - } - - public String getName() { - return name; - } - - public GoExpression getPackage() { - return pack; - } - - public List getDeclarations() { - return declarations; - } - - public List getImports() { - return imports; - } - - @Override - public T accept(GoNodeVisitor v) throws E { - return v.visit(this); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - GoModule module = (GoModule) o; - return Objects.equals(name, module.name) && - Objects.equals(declarations, module.declarations) && - Objects.equals(imports, module.imports) && - Objects.equals(pack, module.pack); - } - - @Override - public int hashCode() { - - return Objects.hash(name, declarations, imports, pack); - } -} diff --git a/src/pgo/model/golang/GoNode.java b/src/pgo/model/golang/GoNode.java deleted file mode 100644 index 3996f59ee..000000000 --- a/src/pgo/model/golang/GoNode.java +++ /dev/null @@ -1,31 +0,0 @@ -package pgo.model.golang; - -import pgo.formatters.GoNodeFormattingVisitor; -import pgo.formatters.IndentingWriter; - -import java.io.IOException; -import java.io.StringWriter; - -public abstract class GoNode { - - public abstract T accept(GoNodeVisitor v) throws E; - - @Override - public abstract boolean equals(Object other); - - @Override - public abstract int hashCode(); - - @Override - public String toString() { - StringWriter w = new StringWriter(); - IndentingWriter out = new IndentingWriter(w); - try { - accept(new GoNodeFormattingVisitor(out)); - } catch (IOException e) { - throw new RuntimeException("StringWriter should not throw IOException", e); - } - return w.toString(); - } - -} diff --git a/src/pgo/model/golang/GoNodeVisitor.java b/src/pgo/model/golang/GoNodeVisitor.java deleted file mode 100644 index cb9a08327..000000000 --- a/src/pgo/model/golang/GoNodeVisitor.java +++ /dev/null @@ -1,21 +0,0 @@ -package pgo.model.golang; - -import pgo.model.golang.type.GoInterfaceTypeField; -import pgo.model.golang.type.GoStructTypeField; -import pgo.model.golang.type.GoType; - -public abstract class GoNodeVisitor { - - public abstract T visit(GoModule module) throws E; - public abstract T visit(GoStatement statement) throws E; - public abstract T visit(GoDeclaration declaration) throws E; - public abstract T visit(GoType type) throws E; - public abstract T visit(GoStructTypeField structTypeField) throws E; - public abstract T visit(GoSwitchCase switchCase) throws E; - public abstract T visit(GoLabelName labelName) throws E; - public abstract T visit(GoFunctionParameter functionArgument) throws E; - public abstract T visit(GoExpression expression) throws E; - public abstract T visit(GoInterfaceTypeField interfaceTypeField) throws E; - public abstract T visit(GoSelectCase selectCase) throws E; - public abstract T visit(GoStructLiteralField structLiteralField) throws E; -} diff --git a/src/pgo/model/golang/GoPtrType.java b/src/pgo/model/golang/GoPtrType.java deleted file mode 100644 index b64b67482..000000000 --- a/src/pgo/model/golang/GoPtrType.java +++ /dev/null @@ -1,44 +0,0 @@ -package pgo.model.golang; - -import pgo.model.golang.type.GoType; -import pgo.model.golang.type.GoTypeVisitor; - -public class GoPtrType extends GoType { - private final GoType pointee; - - public GoPtrType(GoType pointee) { - this.pointee = pointee; - } - - @Override - public T accept(GoTypeVisitor v) throws E { - return v.visit(this); - } - - public GoType getPointee() { - return pointee; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((pointee == null) ? 0 : pointee.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; - GoPtrType other = (GoPtrType) obj; - if (pointee == null) { - return other.pointee == null; - } else return pointee.equals(other.pointee); - } - -} diff --git a/src/pgo/model/golang/GoReturn.java b/src/pgo/model/golang/GoReturn.java deleted file mode 100644 index 2c02da246..000000000 --- a/src/pgo/model/golang/GoReturn.java +++ /dev/null @@ -1,41 +0,0 @@ -package pgo.model.golang; - -import java.util.List; -import java.util.Objects; - -/** - * A return keyword in go - * - */ -public class GoReturn extends GoStatement { - - // the return value if any - private final List values; - - public GoReturn(List values) { - this.values = values; - } - - public List getValues() { - return values; - } - - @Override - public T accept(GoStatementVisitor v) throws E { - return v.visit(this); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - GoReturn aReturn = (GoReturn) o; - return Objects.equals(values, aReturn.values); - } - - @Override - public int hashCode() { - - return Objects.hash(values); - } -} diff --git a/src/pgo/model/golang/GoRoutineStatement.java b/src/pgo/model/golang/GoRoutineStatement.java deleted file mode 100644 index 190f0ac90..000000000 --- a/src/pgo/model/golang/GoRoutineStatement.java +++ /dev/null @@ -1,34 +0,0 @@ -package pgo.model.golang; - -import java.util.Objects; - -public class GoRoutineStatement extends GoStatement { - private final GoExpression expression; - - public GoRoutineStatement(GoExpression expression) { - this.expression = expression; - } - - public GoExpression getExpression() { - return expression; - } - - @Override - public T accept(GoStatementVisitor v) throws E { - return v.visit(this); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - GoRoutineStatement go = (GoRoutineStatement) o; - return Objects.equals(expression, go.expression); - } - - @Override - public int hashCode() { - - return Objects.hash(expression); - } -} diff --git a/src/pgo/model/golang/GoSelect.java b/src/pgo/model/golang/GoSelect.java deleted file mode 100644 index 5494e5203..000000000 --- a/src/pgo/model/golang/GoSelect.java +++ /dev/null @@ -1,39 +0,0 @@ -package pgo.model.golang; - -import java.util.List; -import java.util.Objects; - -/** - * A select statement in go - */ -public class GoSelect extends GoStatement { - - List cases; - - public GoSelect(List cases) { - this.cases = cases; - } - - public List getCases() { - return cases; - } - - @Override - public T accept(GoStatementVisitor v) throws E { - return v.visit(this); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - GoSelect select = (GoSelect) o; - return Objects.equals(cases, select.cases); - } - - @Override - public int hashCode() { - - return Objects.hash(cases); - } -} diff --git a/src/pgo/model/golang/GoSelectCase.java b/src/pgo/model/golang/GoSelectCase.java deleted file mode 100644 index 85c048510..000000000 --- a/src/pgo/model/golang/GoSelectCase.java +++ /dev/null @@ -1,44 +0,0 @@ -package pgo.model.golang; - -import java.util.List; -import java.util.Objects; - -public class GoSelectCase extends GoNode { - - private final GoStatement condition; - private final List block; - - public GoSelectCase(GoStatement condition, List block) { - super(); - this.condition = condition; - this.block = block; - } - - public GoStatement getCondition() { - return condition; - } - - public List getBlock() { - return block; - } - - @Override - public T accept(GoNodeVisitor v) throws E { - return v.visit(this); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - GoSelectCase that = (GoSelectCase) o; - return Objects.equals(condition, that.condition) && - Objects.equals(block, that.block); - } - - @Override - public int hashCode() { - - return Objects.hash(condition, block); - } -} diff --git a/src/pgo/model/golang/GoSelectorExpression.java b/src/pgo/model/golang/GoSelectorExpression.java deleted file mode 100644 index 30254718d..000000000 --- a/src/pgo/model/golang/GoSelectorExpression.java +++ /dev/null @@ -1,42 +0,0 @@ -package pgo.model.golang; - -import java.util.Objects; - -public class GoSelectorExpression extends GoExpression { - - GoExpression lhs; - String name; - - public GoSelectorExpression(GoExpression lhs, String name) { - this.lhs = lhs; - this.name = name; - } - - public GoExpression getLHS() { - return lhs; - } - - public String getName() { - return name; - } - - @Override - public T accept(GoExpressionVisitor visitor) throws E { - return visitor.visit(this); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - GoSelectorExpression selector = (GoSelectorExpression) o; - return Objects.equals(lhs, selector.lhs) && - Objects.equals(name, selector.name); - } - - @Override - public int hashCode() { - - return Objects.hash(lhs, name); - } -} diff --git a/src/pgo/model/golang/GoSliceLiteral.java b/src/pgo/model/golang/GoSliceLiteral.java deleted file mode 100644 index 0d4f1245e..000000000 --- a/src/pgo/model/golang/GoSliceLiteral.java +++ /dev/null @@ -1,44 +0,0 @@ -package pgo.model.golang; - -import pgo.model.golang.type.GoType; - -import java.util.List; -import java.util.Objects; - -public class GoSliceLiteral extends GoExpression { - private final List initializers; - private final GoType elementType; - - public GoSliceLiteral(GoType elementType, List initializers) { - this.elementType = elementType; - this.initializers = initializers; - } - - public GoType getElementType() { - return elementType; - } - - public List getInitializers(){ - return initializers; - } - - @Override - public T accept(GoExpressionVisitor visitor) throws E { - return visitor.visit(this); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - GoSliceLiteral that = (GoSliceLiteral) o; - return Objects.equals(initializers, that.initializers) && - Objects.equals(elementType, that.elementType); - } - - @Override - public int hashCode() { - - return Objects.hash(initializers, elementType); - } -} diff --git a/src/pgo/model/golang/GoSliceOperator.java b/src/pgo/model/golang/GoSliceOperator.java deleted file mode 100644 index 7a9c6b972..000000000 --- a/src/pgo/model/golang/GoSliceOperator.java +++ /dev/null @@ -1,56 +0,0 @@ -package pgo.model.golang; - -import java.util.Objects; - -public class GoSliceOperator extends GoExpression { - - GoExpression target; - GoExpression low; - GoExpression high; - GoExpression max; - - public GoSliceOperator(GoExpression target, GoExpression low, GoExpression high, GoExpression max) { - this.target = target; - this.low = low; - this.high = high; - this.max = max; - } - - public GoExpression getTarget() { - return target; - } - - public GoExpression getLow() { - return low; - } - - public GoExpression getHigh() { - return high; - } - - public GoExpression getMax() { - return max; - } - - @Override - public T accept(GoExpressionVisitor visitor) throws E { - return visitor.visit(this); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - GoSliceOperator that = (GoSliceOperator) o; - return Objects.equals(target, that.target) && - Objects.equals(low, that.low) && - Objects.equals(high, that.high) && - Objects.equals(max, that.max); - } - - @Override - public int hashCode() { - - return Objects.hash(target, low, high, max); - } -} diff --git a/src/pgo/model/golang/GoStatement.java b/src/pgo/model/golang/GoStatement.java deleted file mode 100644 index 3536a36a3..000000000 --- a/src/pgo/model/golang/GoStatement.java +++ /dev/null @@ -1,16 +0,0 @@ -package pgo.model.golang; - -/** - * A go code statement - * - */ -public abstract class GoStatement extends GoNode { - - public abstract T accept(GoStatementVisitor v) throws E; - - @Override - public T accept(GoNodeVisitor v) throws E { - return v.visit(this); - } - -} diff --git a/src/pgo/model/golang/GoStatementVisitor.java b/src/pgo/model/golang/GoStatementVisitor.java deleted file mode 100644 index d870e9698..000000000 --- a/src/pgo/model/golang/GoStatementVisitor.java +++ /dev/null @@ -1,24 +0,0 @@ -package pgo.model.golang; - -public abstract class GoStatementVisitor{ - - public abstract T visit(GoComment comment) throws E; - public abstract T visit(GoAssignmentStatement assignment) throws E; - public abstract T visit(GoReturn goReturn) throws E; - public abstract T visit(GoBlock block) throws E; - public abstract T visit(GoFor goFor) throws E; - public abstract T visit(GoForRange forRange) throws E; - public abstract T visit(GoIf goIf) throws E; - public abstract T visit(GoSwitch goSwitch) throws E; - public abstract T visit(GoLabel label) throws E; - public abstract T visit(GoSelect select) throws E; - public abstract T visit(GoTo goTo) throws E; - public abstract T visit(GoIncDec incDec) throws E; - public abstract T visit(GoExpressionStatement expressionStatement) throws E; - public abstract T visit(GoBreak break1) throws E; - public abstract T visit(GoContinue continue1) throws E; - public abstract T visit(GoDefer defer) throws E; - public abstract T visit(GoRoutineStatement go) throws E; - public abstract T visit(GoVariableDeclarationStatement variableDeclarationStatement) throws E; - -} diff --git a/src/pgo/model/golang/GoStringLiteral.java b/src/pgo/model/golang/GoStringLiteral.java deleted file mode 100644 index 09251fdd7..000000000 --- a/src/pgo/model/golang/GoStringLiteral.java +++ /dev/null @@ -1,35 +0,0 @@ -package pgo.model.golang; - -import java.util.Objects; - -public class GoStringLiteral extends GoExpression { - - private final String value; - - public GoStringLiteral(String value) { - this.value = value; - } - - public String getValue() { - return value; - } - - @Override - public T accept(GoExpressionVisitor visitor) throws E { - return visitor.visit(this); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - GoStringLiteral that = (GoStringLiteral) o; - return Objects.equals(value, that.value); - } - - @Override - public int hashCode() { - - return Objects.hash(value); - } -} diff --git a/src/pgo/model/golang/GoStructLiteral.java b/src/pgo/model/golang/GoStructLiteral.java deleted file mode 100644 index def929c71..000000000 --- a/src/pgo/model/golang/GoStructLiteral.java +++ /dev/null @@ -1,50 +0,0 @@ -package pgo.model.golang; - -import pgo.model.golang.type.GoType; - -import java.util.List; -import java.util.Objects; - -/** - * Wraps the definition of a Golang struct - * - */ -public class GoStructLiteral extends GoExpression { - - GoType type; - - List fields; - - public GoStructLiteral(GoType type, List fields) { - this.type = type; - this.fields = fields; - } - - public GoType getType() { - return type; - } - - public List getFields(){ - return fields; - } - - @Override - public T accept(GoExpressionVisitor visitor) throws E { - return visitor.visit(this); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - GoStructLiteral that = (GoStructLiteral) o; - return Objects.equals(type, that.type) && - Objects.equals(fields, that.fields); - } - - @Override - public int hashCode() { - - return Objects.hash(type, fields); - } -} diff --git a/src/pgo/model/golang/GoStructLiteralField.java b/src/pgo/model/golang/GoStructLiteralField.java deleted file mode 100644 index 91a207e2d..000000000 --- a/src/pgo/model/golang/GoStructLiteralField.java +++ /dev/null @@ -1,42 +0,0 @@ -package pgo.model.golang; - -import java.util.Objects; - -public class GoStructLiteralField extends GoNode { - - private final String name; - private final GoExpression value; - - public GoStructLiteralField(String name, GoExpression value){ - this.name = name; - this.value = value; - } - - public String getName() { - return name; - } - - public GoExpression getValue() { - return value; - } - - @Override - public T accept(GoNodeVisitor v) throws E { - return v.visit(this); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - GoStructLiteralField that = (GoStructLiteralField) o; - return Objects.equals(name, that.name) && - Objects.equals(value, that.value); - } - - @Override - public int hashCode() { - - return Objects.hash(name, value); - } -} diff --git a/src/pgo/model/golang/GoSwitch.java b/src/pgo/model/golang/GoSwitch.java deleted file mode 100644 index 9cb13fc17..000000000 --- a/src/pgo/model/golang/GoSwitch.java +++ /dev/null @@ -1,64 +0,0 @@ -package pgo.model.golang; - -import pgo.InternalCompilerError; -import pgo.model.golang.type.GoTypeName; - -import java.util.List; -import java.util.Objects; - -public class GoSwitch extends GoStatement { - private final GoExpression switchExp; - private final List cases; - private final List defaultBlock; - - public static GoSwitch typeSwitch(GoExpression exp, List cases, List defaultBlock) { - // sanity check: in a type switch, all cases should be types. - cases.forEach(c -> { - if (!c.isTypeCase()) { - throw new InternalCompilerError(); - } - }); - - GoExpression switchExp = new GoTypeCast(new GoTypeName("type"), exp); - return new GoSwitch(switchExp, cases, defaultBlock); - } - - public GoSwitch(GoExpression exp, List cases, List defaultBlock) { - this.switchExp = exp; - this.cases = cases; - this.defaultBlock = defaultBlock; - } - - public GoExpression getCondition() { - return switchExp; - } - - public List getCases(){ - return cases; - } - - public List getDefaultBlock() { - return defaultBlock; - } - - @Override - public T accept(GoStatementVisitor v) throws E { - return v.visit(this); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - GoSwitch aSwitch = (GoSwitch) o; - return Objects.equals(switchExp, aSwitch.switchExp) && - Objects.equals(cases, aSwitch.cases) && - Objects.equals(defaultBlock, aSwitch.defaultBlock); - } - - @Override - public int hashCode() { - - return Objects.hash(switchExp, cases, defaultBlock); - } -} diff --git a/src/pgo/model/golang/GoSwitchCase.java b/src/pgo/model/golang/GoSwitchCase.java deleted file mode 100644 index 2532bb3a8..000000000 --- a/src/pgo/model/golang/GoSwitchCase.java +++ /dev/null @@ -1,62 +0,0 @@ -package pgo.model.golang; - -import pgo.model.golang.type.GoType; - -import java.util.List; -import java.util.Objects; - -public class GoSwitchCase extends GoNode { - private final GoExpression condition; - private final GoType type; - private final List block; - - public GoSwitchCase(GoExpression condition, List block) { - super(); - this.condition = condition; - this.block = block; - this.type = null; - } - - public GoSwitchCase(GoType type, List block) { - super(); - this.type = type; - this.block = block; - this.condition = null; - } - - public GoExpression getCondition() { - return condition; - } - - public GoType getType() { - return type; - } - - public List getBlock() { - return block; - } - - public boolean isTypeCase() { - return type != null; - } - - @Override - public T accept(GoNodeVisitor v) throws E { - return v.visit(this); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - GoSwitchCase that = (GoSwitchCase) o; - return Objects.equals(condition, that.condition) && - Objects.equals(block, that.block); - } - - @Override - public int hashCode() { - - return Objects.hash(condition, block); - } -} diff --git a/src/pgo/model/golang/GoTo.java b/src/pgo/model/golang/GoTo.java deleted file mode 100644 index dff3527cd..000000000 --- a/src/pgo/model/golang/GoTo.java +++ /dev/null @@ -1,39 +0,0 @@ -package pgo.model.golang; - -import java.util.Objects; - -/** - * A PlusCalGoto in pluscal and go - * - */ -public class GoTo extends GoStatement { - // the to label location - private final GoLabelName to; - - public GoTo(GoLabelName to) { - this.to = to; - } - - public GoLabelName getTo() { - return to; - } - - @Override - public T accept(GoStatementVisitor v) throws E { - return v.visit(this); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - GoTo goTo = (GoTo) o; - return Objects.equals(to, goTo.to); - } - - @Override - public int hashCode() { - - return Objects.hash(to); - } -} diff --git a/src/pgo/model/golang/GoTypeAssertion.java b/src/pgo/model/golang/GoTypeAssertion.java deleted file mode 100644 index 3221a75d1..000000000 --- a/src/pgo/model/golang/GoTypeAssertion.java +++ /dev/null @@ -1,50 +0,0 @@ -package pgo.model.golang; - -import pgo.model.golang.type.GoType; - -import java.util.Objects; - -/** - * Represents a type assertion e.g. x.(int), which casts an interface to the - * specified type. - * - */ -public class GoTypeAssertion extends GoExpression { - // the expr we are casting - private final GoExpression target; - - private final GoType type; - - public GoTypeAssertion(GoExpression target, GoType type) { - this.target = target; - this.type = type; - } - - public GoExpression getTarget() { - return target; - } - - public GoType getType() { - return type; - } - - @Override - public T accept(GoExpressionVisitor visitor) throws E { - return visitor.visit(this); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - GoTypeAssertion that = (GoTypeAssertion) o; - return Objects.equals(target, that.target) && - Objects.equals(type, that.type); - } - - @Override - public int hashCode() { - - return Objects.hash(target, type); - } -} diff --git a/src/pgo/model/golang/GoTypeCast.java b/src/pgo/model/golang/GoTypeCast.java deleted file mode 100644 index 276ddfd08..000000000 --- a/src/pgo/model/golang/GoTypeCast.java +++ /dev/null @@ -1,46 +0,0 @@ -package pgo.model.golang; - -import pgo.model.golang.type.GoTypeName; - -import java.util.Objects; - -/** - * Represents a type conversion e.g. float64(x). - */ -public class GoTypeCast extends GoExpression { - GoTypeName typeName; - GoExpression target; - - public GoTypeCast(GoTypeName typeName, GoExpression target) { - this.typeName = typeName; - this.target = target; - } - - public GoTypeName getTypeName() { - return typeName; - } - - public GoExpression getTarget() { - return target; - } - - @Override - public T accept(GoExpressionVisitor visitor) throws E { - return visitor.visit(this); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - GoTypeCast typeCast = (GoTypeCast) o; - return Objects.equals(typeName, typeCast.typeName) && - Objects.equals(target, typeCast.target); - } - - @Override - public int hashCode() { - - return Objects.hash(typeName, target); - } -} \ No newline at end of file diff --git a/src/pgo/model/golang/GoTypeDeclaration.java b/src/pgo/model/golang/GoTypeDeclaration.java deleted file mode 100644 index ceb3fdf6e..000000000 --- a/src/pgo/model/golang/GoTypeDeclaration.java +++ /dev/null @@ -1,45 +0,0 @@ -package pgo.model.golang; - -import pgo.model.golang.type.GoType; - -import java.util.Objects; - -public class GoTypeDeclaration extends GoDeclaration { - - private final String name; - private final GoType type; - - public GoTypeDeclaration(String name, GoType type) { - super(); - this.name = name; - this.type = type; - } - - public String getName() { - return name; - } - - public GoType getType() { - return type; - } - - @Override - public T accept(GoDeclarationVisitor v) throws E { - return v.visit(this); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - GoTypeDeclaration that = (GoTypeDeclaration) o; - return Objects.equals(name, that.name) && - Objects.equals(type, that.type); - } - - @Override - public int hashCode() { - - return Objects.hash(name, type); - } -} diff --git a/src/pgo/model/golang/GoUnary.java b/src/pgo/model/golang/GoUnary.java deleted file mode 100644 index efe8b543e..000000000 --- a/src/pgo/model/golang/GoUnary.java +++ /dev/null @@ -1,52 +0,0 @@ -package pgo.model.golang; - -import java.util.Objects; - -public class GoUnary extends GoExpression { - - GoExpression target; - private final Operation op; - - public enum Operation { - POS, - NEG, - NOT, - COMPLEMENT, - DEREF, - ADDR, - RECV, - } - - public GoUnary(Operation op, GoExpression target) { - this.op = op; - this.target = target; - } - - public Operation getOperation() { - return op; - } - - public GoExpression getTarget() { - return target; - } - - @Override - public T accept(GoExpressionVisitor visitor) throws E { - return visitor.visit(this); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - GoUnary unary = (GoUnary) o; - return Objects.equals(target, unary.target) && - op == unary.op; - } - - @Override - public int hashCode() { - - return Objects.hash(target, op); - } -} diff --git a/src/pgo/model/golang/GoVariableDeclaration.java b/src/pgo/model/golang/GoVariableDeclaration.java deleted file mode 100644 index 1f7ec9098..000000000 --- a/src/pgo/model/golang/GoVariableDeclaration.java +++ /dev/null @@ -1,51 +0,0 @@ -package pgo.model.golang; - -import pgo.model.golang.type.GoType; - -import java.util.Objects; - -public class GoVariableDeclaration extends GoDeclaration { - - private final String name; - private final GoType type; - private final GoExpression value; - - public GoVariableDeclaration(String name, GoType type, GoExpression value) { - this.name = name; - this.type = type; - this.value = value; - } - - public String getName() { - return name; - } - - public GoType getType() { - return type; - } - - public GoExpression getValue() { - return value; - } - - @Override - public T accept(GoDeclarationVisitor v) throws E { - return v.visit(this); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - GoVariableDeclaration that = (GoVariableDeclaration) o; - return Objects.equals(name, that.name) && - Objects.equals(type, that.type) && - Objects.equals(value, that.value); - } - - @Override - public int hashCode() { - - return Objects.hash(name, type, value); - } -} diff --git a/src/pgo/model/golang/GoVariableDeclarationStatement.java b/src/pgo/model/golang/GoVariableDeclarationStatement.java deleted file mode 100644 index a35c22256..000000000 --- a/src/pgo/model/golang/GoVariableDeclarationStatement.java +++ /dev/null @@ -1,37 +0,0 @@ -package pgo.model.golang; - -import java.util.Objects; - -public class GoVariableDeclarationStatement extends GoStatement { - private final GoVariableDeclaration variableDeclaration; - - public GoVariableDeclarationStatement(GoVariableDeclaration variableDeclaration) { - this.variableDeclaration = variableDeclaration; - } - - public GoVariableDeclaration getVariableDeclaration() { - return variableDeclaration; - } - - @Override - public T accept(GoStatementVisitor v) throws E { - return v.visit(this); - } - - @Override - public boolean equals(Object other) { - if (this == other) { - return true; - } - if (other == null || getClass() != other.getClass()) { - return false; - } - GoVariableDeclarationStatement that = (GoVariableDeclarationStatement) other; - return Objects.equals(variableDeclaration, that.variableDeclaration); - } - - @Override - public int hashCode() { - return Objects.hashCode(variableDeclaration); - } -} diff --git a/src/pgo/model/golang/GoVariableName.java b/src/pgo/model/golang/GoVariableName.java deleted file mode 100644 index 2949091f5..000000000 --- a/src/pgo/model/golang/GoVariableName.java +++ /dev/null @@ -1,35 +0,0 @@ -package pgo.model.golang; - -import java.util.Objects; - -public class GoVariableName extends GoExpression { - - private final String name; - - public GoVariableName(String name) { - this.name = name; - } - - public String getName() { - return name; - } - - @Override - public T accept(GoExpressionVisitor visitor) throws E { - return visitor.visit(this); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - GoVariableName that = (GoVariableName) o; - return Objects.equals(name, that.name); - } - - @Override - public int hashCode() { - - return Objects.hash(name); - } -} diff --git a/src/pgo/model/golang/builder/GoASTBuilder.java b/src/pgo/model/golang/builder/GoASTBuilder.java deleted file mode 100644 index a85b17b0f..000000000 --- a/src/pgo/model/golang/builder/GoASTBuilder.java +++ /dev/null @@ -1,28 +0,0 @@ -package pgo.model.golang.builder; - -import pgo.model.golang.GoBlock; -import pgo.model.golang.GoFunctionDeclaration; -import pgo.model.golang.GoStatement; -import pgo.model.golang.type.GoType; -import pgo.model.golang.type.GoTypeName; -import pgo.scope.UID; - -public abstract class GoASTBuilder { - - public abstract GoTypeName defineType(String nameHint, GoType type); - - public abstract void addImport(String name); - - public abstract GoFunctionDeclarationBuilder defineFunction(UID uid, String nameHint); - - public GoFunctionDeclarationBuilder defineFunction(String nameHint) { - return defineFunction(new UID(), nameHint); - } - - protected abstract void addBlock(GoBlock block); - - protected abstract void addFunction(GoFunctionDeclaration fn); - - public abstract void addStatement(GoStatement s); - -} diff --git a/src/pgo/model/golang/builder/GoAnonymousFunctionBuilder.java b/src/pgo/model/golang/builder/GoAnonymousFunctionBuilder.java deleted file mode 100644 index 8c18e2907..000000000 --- a/src/pgo/model/golang/builder/GoAnonymousFunctionBuilder.java +++ /dev/null @@ -1,50 +0,0 @@ -package pgo.model.golang.builder; - -import pgo.model.golang.*; -import pgo.model.golang.type.GoType; -import pgo.scope.UID; -import pgo.trans.passes.codegen.NameCleaner; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -public class GoAnonymousFunctionBuilder { - - private final GoASTBuilder parent; - private final NameCleaner nameCleaner; - private final Map nameMap; - - private final List arguments; - private final List returnValues; - private GoBlock block; - - public GoAnonymousFunctionBuilder(GoASTBuilder parent, NameCleaner nameCleaner, Map nameMap) { - this.parent = parent; - this.nameCleaner = nameCleaner; - this.nameMap = nameMap; - - this.arguments = new ArrayList<>(); - this.returnValues = new ArrayList<>(); - this.block = null; - } - - public GoVariableName addArgument(String nameHint, GoType type) { - String actualName = nameCleaner.cleanName(nameHint); - arguments.add(new GoFunctionParameter(actualName, type)); - return new GoVariableName(actualName); - } - - public void addReturn(GoType type) { - returnValues.add(new GoFunctionParameter(null, type)); - } - - public GoAnonymousFunction getFunction() { - return new GoAnonymousFunction(arguments, returnValues, block); - } - - public GoBlockBuilder getBlockBuilder() { - return new GoBlockBuilder(parent, nameCleaner, nameMap, new NameCleaner(), block -> this.block = block); - } - -} diff --git a/src/pgo/model/golang/builder/GoBlockBuilder.java b/src/pgo/model/golang/builder/GoBlockBuilder.java deleted file mode 100644 index fefb754e4..000000000 --- a/src/pgo/model/golang/builder/GoBlockBuilder.java +++ /dev/null @@ -1,223 +0,0 @@ -package pgo.model.golang.builder; - -import pgo.InternalCompilerError; -import pgo.model.golang.*; -import pgo.model.golang.type.GoType; -import pgo.model.golang.type.GoTypeName; -import pgo.scope.UID; -import pgo.trans.passes.codegen.NameCleaner; - -import java.io.Closeable; -import java.util.*; - -public class GoBlockBuilder extends GoASTBuilder implements Closeable { - private final GoASTBuilder builder; - private final NameCleaner nameCleaner; - private final Map nameMap; - private final List statements; - - public interface OnSuccess { - void action(GoBlock block); - } - - private final OnSuccess onSuccess; - private final NameCleaner labelScope; - - public GoBlockBuilder(GoASTBuilder builder, NameCleaner nameCleaner, Map nameMap, NameCleaner labelScope) { - this.builder = builder; - this.nameCleaner = nameCleaner; - this.nameMap = nameMap; - this.labelScope = labelScope; - this.statements = new ArrayList<>(); - this.onSuccess = builder::addBlock; - } - - public GoBlockBuilder(GoASTBuilder builder, NameCleaner nameCleaner, Map nameMap, NameCleaner labelScope, OnSuccess onSuccess) { - this.builder = builder; - this.nameCleaner = nameCleaner; - this.nameMap = nameMap; - this.labelScope = labelScope; - this.statements = new ArrayList<>(); - this.onSuccess = onSuccess; - } - - public GoBlock getBlock() { - return new GoBlock(statements); - } - - public GoLabelName newLabel(String nameHint) { - String name = labelScope.cleanName(nameHint); - return new GoLabelName(name); - } - - public void label(GoLabelName label) { - addStatement(new GoLabel(label.getName())); - } - - public void labelIsUnique(String name) { - labelScope.requireCleanName(name); - statements.add(new GoLabel(name)); - } - - public void assign(GoExpression name, GoExpression value) { - assign(Collections.singletonList(name), Collections.singletonList(value)); - } - - public void assign(List names, GoExpression value) { - assign(names, Collections.singletonList(value)); - } - - public void assign(List names, List values) { - addStatement(new GoAssignmentStatement(names, false, values)); - } - - public GoASTBuilder getParent() { - return builder; - } - - public GoIfBuilder ifStmt(GoExpression condition) { - return new GoIfBuilder(this, nameCleaner.child(), nameMap, labelScope, condition); - } - - public void print(GoExpression value) { - addImport("fmt"); - addStatement( - new GoExpressionStatement( - new GoCall( - new GoSelectorExpression( - new GoVariableName("fmt"), "Printf"), - Arrays.asList(new GoStringLiteral("%v\\n"), value)))); - } - - public GoBlockBuilder forLoop(GoExpression condition) { - return new GoBlockBuilder( - this, nameCleaner.child(), nameMap, labelScope, - block -> addStatement(new GoFor(null, condition, null, block))); - } - - public GoForStatementClauseBuilder forLoopWithClauses() { - return new GoForStatementClauseBuilder(this, nameCleaner.child(), nameMap, labelScope); - } - - public GoForRangeBuilder forRange(GoExpression rangeExp) { - return new GoForRangeBuilder(this, nameCleaner.child(), nameMap, labelScope, rangeExp); - } - - public GoSwitchBuilder switchStmt(GoExpression switchExp) { - return new GoSwitchBuilder(this, nameCleaner.child(), nameMap, labelScope, switchExp); - } - - private List getFreshNames(List nameHints) { - List ret = new ArrayList<>(); - for (String hint : nameHints) { - GoVariableName variableName = getFreshName(hint); - ret.add(variableName); - } - return ret; - } - - public List varDecl(List nameHints, GoExpression value) { - List ret = getFreshNames(nameHints); - List names = new ArrayList<>(ret); - addStatement(new GoAssignmentStatement(names, true, Collections.singletonList(value))); - return ret; - } - - public GoVariableName varDecl(String nameHint, GoExpression value) { - return varDecl(Collections.singletonList(nameHint), value).get(0); - } - - public GoVariableName varDecl(String nameHint, GoType type) { - GoVariableName ret = getFreshNames(Collections.singletonList(nameHint)).get(0); - String name = ret.getName(); - addStatement(new GoVariableDeclarationStatement(new GoVariableDeclaration(name, type, null))); - return ret; - } - - public GoVariableName getFreshName(String nameHint) { - String actualName = nameCleaner.cleanName(nameHint); - return new GoVariableName(actualName); - } - - public void goTo(GoLabelName name) { - addStatement(new GoTo(name)); - } - - public void addPanic(GoExpression e) { - addStatement(new GoExpressionStatement(new GoCall(new GoVariableName("panic"), Collections.singletonList(e)))); - } - - public void addStatement(GoExpression expression) { - addStatement(new GoExpressionStatement(expression)); - } - - public void addComment(String comment) { - statements.add(new GoComment(comment)); - } - - @Override - public void addStatement(GoStatement s) { - statements.add(s); - } - - @Override - protected void addBlock(GoBlock block) { - statements.add(block); - } - - @Override - protected void addFunction(GoFunctionDeclaration fn) { - builder.addFunction(fn); - } - - @Override - public void close() { - onSuccess.action(getBlock()); - } - - @Override - public GoTypeName defineType(String nameHint, GoType type) { - return builder.defineType(nameHint, type); - } - - @Override - public GoFunctionDeclarationBuilder defineFunction(UID uid, String nameHint) { - return builder.defineFunction(uid, nameHint); - } - - public GoAnonymousFunctionBuilder anonymousFunction() { - return new GoAnonymousFunctionBuilder(this, nameCleaner, nameMap); - } - - public void goStmt(GoExpression expression) { - addStatement(new GoRoutineStatement(expression)); - } - - public void deferStmt(GoExpression expression) { - addStatement(new GoDefer(expression)); - } - - public void returnStmt(GoExpression... values) { - addStatement(new GoReturn(Arrays.asList(values))); - } - - public void linkUID(UID uid, GoVariableName name) { - nameMap.put(uid, name); - } - - public boolean isInScope(UID uid) { - return nameMap.containsKey(uid); - } - - public GoVariableName findUID(UID uid) { - if (!nameMap.containsKey(uid)) { - throw new InternalCompilerError(); - } - return nameMap.get(uid); - } - - @Override - public void addImport(String name) { - builder.addImport(name); - } -} diff --git a/src/pgo/model/golang/builder/GoBuilder.java b/src/pgo/model/golang/builder/GoBuilder.java deleted file mode 100644 index 3bfdadf31..000000000 --- a/src/pgo/model/golang/builder/GoBuilder.java +++ /dev/null @@ -1,51 +0,0 @@ -package pgo.model.golang.builder; - -import pgo.model.golang.*; -import pgo.model.golang.type.GoType; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Vector; - -public final class GoBuilder { - - private GoBuilder() {} - - public static GoSliceLiteral sliceLiteral(GoType elementType, GoExpression... values) { - return sliceLiteral(elementType, Arrays.asList(values)); - } - - public static GoSliceLiteral sliceLiteral(GoType elementType, List values) { - return new GoSliceLiteral(elementType, values); - } - - public static GoStringLiteral stringLiteral(String value) { - return new GoStringLiteral(value); - } - - public static GoMapLiteral mapLiteral(GoType keyType, GoType valueType, Object[]... pairs) { - return mapLiteral(keyType, valueType, Arrays.asList(pairs)); - } - - public static GoMapLiteral mapLiteral(GoType keyType, GoType valueType, List pairs) { - HashMap map = new HashMap<>(); - for(Object[] pair : pairs) { - map.put((GoExpression)pair[0], (GoExpression)pair[1]); - } - return new GoMapLiteral(keyType, valueType, map); - } - - public static GoIntLiteral intLiteral(int value) { - return new GoIntLiteral(value); - } - - public static Vector stmts(GoStatement... statements) { - return new Vector<>(Arrays.asList(statements)); - } - - public static GoPtrType ptr(GoType type) { - return new GoPtrType(type); - } - -} diff --git a/src/pgo/model/golang/builder/GoForRangeBuilder.java b/src/pgo/model/golang/builder/GoForRangeBuilder.java deleted file mode 100644 index f3d8e5fff..000000000 --- a/src/pgo/model/golang/builder/GoForRangeBuilder.java +++ /dev/null @@ -1,46 +0,0 @@ -package pgo.model.golang.builder; - -import pgo.model.golang.GoExpression; -import pgo.model.golang.GoForRange; -import pgo.model.golang.GoVariableName; -import pgo.trans.passes.codegen.NameCleaner; -import pgo.scope.UID; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -public class GoForRangeBuilder { - private final GoASTBuilder parent; - private final NameCleaner nameCleaner; - private final Map nameMap; - private final NameCleaner labelScope; - - private final List lhs; - private final GoExpression rangeExpr; - - public GoForRangeBuilder(GoASTBuilder parent, NameCleaner nameCleaner, Map nameMap, NameCleaner labelScope, GoExpression rangeExpr) { - this.parent = parent; - this.nameCleaner = nameCleaner; - this.nameMap = nameMap; - this.labelScope = labelScope; - this.rangeExpr = rangeExpr; - this.lhs = new ArrayList<>(); - } - - public List initVariables(List nameHints) { - List names = new ArrayList<>(); - for (String nameHint : nameHints) { - String actualName = nameCleaner.cleanName(nameHint); - GoVariableName name = new GoVariableName(actualName); - names.add(name); - lhs.add(name); - } - return names; - } - - public GoBlockBuilder getBlockBuilder() { - return new GoBlockBuilder(parent, nameCleaner, nameMap, labelScope, block -> - parent.addStatement(new GoForRange(lhs, true, rangeExpr, block))); - } -} diff --git a/src/pgo/model/golang/builder/GoForStatementClauseBuilder.java b/src/pgo/model/golang/builder/GoForStatementClauseBuilder.java deleted file mode 100644 index b140f0258..000000000 --- a/src/pgo/model/golang/builder/GoForStatementClauseBuilder.java +++ /dev/null @@ -1,54 +0,0 @@ -package pgo.model.golang.builder; - -import pgo.model.golang.*; -import pgo.scope.UID; -import pgo.trans.passes.codegen.NameCleaner; - -import java.util.Collections; -import java.util.Map; - -public class GoForStatementClauseBuilder { - - private final GoASTBuilder parent; - private final NameCleaner nameCleaner; - private final Map nameMap; - private final NameCleaner labelScope; - - private GoStatement init; - private GoExpression condition; - private GoStatement inc; - - public GoForStatementClauseBuilder(GoASTBuilder parent, NameCleaner nameCleaner, Map nameMap, - NameCleaner labelScope) { - this.parent = parent; - this.nameCleaner = nameCleaner; - this.nameMap = nameMap; - this.labelScope = labelScope; - - this.init = null; - this.condition = null; - this.inc = null; - } - - public GoVariableName initVariable(String nameHint, GoExpression value) { - String actualName = nameCleaner.cleanName(nameHint); - GoVariableName name = new GoVariableName(actualName); - init = new GoAssignmentStatement(Collections.singletonList(name), true, Collections.singletonList(value)); - return name; - } - - public void setCondition(GoExpression condition) { - this.condition = condition; - } - - public void setInc(GoStatement inc) { - this.inc = inc; - } - - public GoBlockBuilder getBlockBuilder() { - return new GoBlockBuilder(parent, nameCleaner, nameMap, labelScope, block -> { - parent.addStatement(new GoFor(init, condition, inc, block)); - }); - } - -} diff --git a/src/pgo/model/golang/builder/GoFunctionDeclarationBuilder.java b/src/pgo/model/golang/builder/GoFunctionDeclarationBuilder.java deleted file mode 100644 index f36a428f2..000000000 --- a/src/pgo/model/golang/builder/GoFunctionDeclarationBuilder.java +++ /dev/null @@ -1,64 +0,0 @@ -package pgo.model.golang.builder; - -import pgo.model.golang.GoFunctionParameter; -import pgo.model.golang.GoFunctionDeclaration; -import pgo.model.golang.GoVariableName; -import pgo.trans.passes.codegen.NameCleaner; -import pgo.model.golang.type.GoType; -import pgo.scope.UID; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -public class GoFunctionDeclarationBuilder { - private final GoASTBuilder parent; - private final String name; - - private final List params; - private final List returnValues; - private GoFunctionParameter receiver; - private final NameCleaner nameCleaner; - private final Map nameMap; - - public GoFunctionDeclarationBuilder(GoASTBuilder parent, String name, NameCleaner nameCleaner, - Map nameMap) { - this.parent = parent; - this.name = name; - this.nameCleaner = nameCleaner; - this.nameMap = nameMap; - - this.receiver = null; - this.params = new ArrayList<>(); - this.returnValues = new ArrayList<>(); - } - - public GoVariableName addParameter(String nameHint, GoType type) { - String actualName = nameCleaner.cleanName(nameHint); - params.add(new GoFunctionParameter(actualName, type)); - return new GoVariableName(actualName); - } - - public void addReturn(GoType type) { - returnValues.add(new GoFunctionParameter(null, type)); - } - - public GoVariableName addReturn(String nameHint, GoType type) { - String actualName = nameCleaner.cleanName(nameHint); - returnValues.add(new GoFunctionParameter(actualName, type)); - return new GoVariableName(actualName); - } - - public GoVariableName setReceiver(String nameHint, GoType type) { - String actualName = nameCleaner.cleanName(nameHint); - receiver = new GoFunctionParameter(actualName, type); - return new GoVariableName(actualName); - } - - public GoBlockBuilder getBlockBuilder() { - return new GoBlockBuilder(parent, nameCleaner, nameMap, new NameCleaner(), block -> { - parent.addFunction(new GoFunctionDeclaration(name, receiver, params, returnValues, block)); - }); - } - -} diff --git a/src/pgo/model/golang/builder/GoModuleBuilder.java b/src/pgo/model/golang/builder/GoModuleBuilder.java deleted file mode 100644 index fc2fb8419..000000000 --- a/src/pgo/model/golang/builder/GoModuleBuilder.java +++ /dev/null @@ -1,108 +0,0 @@ -package pgo.model.golang.builder; - -import pgo.InternalCompilerError; -import pgo.model.golang.*; -import pgo.model.golang.type.GoType; -import pgo.model.golang.type.GoTypeName; -import pgo.scope.UID; -import pgo.trans.passes.codegen.NameCleaner; - -import java.util.*; - -public class GoModuleBuilder extends GoASTBuilder { - - private final String name; - private final String pack; - private final Set imports; - private final Map nameMap; - private final List declarations; - private final NameCleaner nameCleaner; - - public GoModuleBuilder(String name, String pack) { - this.name = name; - this.pack = pack; - this.nameCleaner = new NameCleaner(new HashSet<>(Arrays.asList( - "break", - "default", - "func", - "interface", - "select", - "case", - "defer", - "go", - "map", - "struct", - "chan", - "else", - "goto", - "package", - "switch", - "const", - "fallthrough", - "if", - "range", - "type", - "continue", - "for", - "import", - "return", - "var"))); - this.imports = new TreeSet<>(); - this.nameMap = new HashMap<>(); - this.declarations = new ArrayList<>(); - } - - @Override - public GoTypeName defineType(String nameHint, GoType type) { - String actualName = nameCleaner.cleanName(nameHint); - declarations.add(new GoTypeDeclaration(actualName, type)); - return new GoTypeName(actualName); - } - - @Override - public GoFunctionDeclarationBuilder defineFunction(UID uid, String nameHint) { - String actualName = nameCleaner.cleanName(nameHint); - nameMap.put(uid, new GoVariableName(actualName)); - return new GoFunctionDeclarationBuilder(this, actualName, nameCleaner.child(), nameMap); - } - - public GoVariableName defineGlobal(UID uid, String nameHint, GoType type, GoExpression value) { - String actualName = nameCleaner.cleanName(nameHint); - GoVariableName vName = new GoVariableName(actualName); - nameMap.put(uid, vName); - declarations.add(new GoVariableDeclaration(actualName, type, value)); - return vName; - } - - public GoVariableName defineGlobal(UID uid, String nameHint, GoExpression value) { - return defineGlobal(uid, nameHint, null, value); - } - - public GoVariableName defineGlobal(UID uid, String nameHint, GoType type) { - return defineGlobal(uid, nameHint, type, null); - } - - public GoModule getModule() { - return new GoModule(name, new GoVariableName(this.pack), new ArrayList<>(imports), declarations); - } - - @Override - protected void addBlock(GoBlock block) { - throw new InternalCompilerError(); - } - - @Override - protected void addFunction(GoFunctionDeclaration fn) { - declarations.add(fn); - } - - @Override - public void addStatement(GoStatement s) { - throw new InternalCompilerError(); - } - - @Override - public void addImport(String name) { - imports.add(name); - } -} diff --git a/src/pgo/model/golang/builder/GoSwitchBuilder.java b/src/pgo/model/golang/builder/GoSwitchBuilder.java deleted file mode 100644 index bcb9706f3..000000000 --- a/src/pgo/model/golang/builder/GoSwitchBuilder.java +++ /dev/null @@ -1,51 +0,0 @@ -package pgo.model.golang.builder; - -import pgo.model.golang.*; -import pgo.scope.UID; -import pgo.trans.passes.codegen.NameCleaner; - -import java.io.Closeable; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -public class GoSwitchBuilder implements Closeable { - private final GoASTBuilder builder; - private final NameCleaner nameCleaner; - private final Map nameMap; - private final NameCleaner labelScope; - private final GoExpression switchExp; - private final List cases; - private List defaultBlock; - - public GoSwitchBuilder(GoASTBuilder builder, NameCleaner nameCleaner, Map nameMap, - NameCleaner labelScope, GoExpression switchExp) { - this.builder = builder; - this.nameCleaner = nameCleaner; - this.nameMap = nameMap; - this.labelScope = labelScope; - this.switchExp = switchExp; - this.cases = new ArrayList<>(); - } - - private void addCase(GoExpression expression, GoBlock block) { - cases.add(new GoSwitchCase(expression, block.getStatements())); - } - - private void defaultCase(GoBlock block) { - defaultBlock = block.getStatements(); - } - - public GoBlockBuilder addCase(GoExpression expression) { - return new GoBlockBuilder(builder, nameCleaner.child(), nameMap, labelScope, block -> addCase(expression, block)); - } - - public GoBlockBuilder defaultCase() { - return new GoBlockBuilder(builder, nameCleaner.child(), nameMap, labelScope, this::defaultCase); - } - - @Override - public void close() { - builder.addStatement(new GoSwitch(switchExp, cases, defaultBlock)); - } -} diff --git a/src/pgo/model/golang/type/GoArchetypeResourceCollectionType.java b/src/pgo/model/golang/type/GoArchetypeResourceCollectionType.java deleted file mode 100644 index 1a5a74067..000000000 --- a/src/pgo/model/golang/type/GoArchetypeResourceCollectionType.java +++ /dev/null @@ -1,49 +0,0 @@ -package pgo.model.golang.type; - -import java.util.Objects; - -public class GoArchetypeResourceCollectionType extends GoType { - private final GoType keyType; - private final GoType readType; - private final GoType writeType; - - public GoArchetypeResourceCollectionType(GoType keyType, GoType readType, GoType writeType) { - this.keyType = keyType; - this.readType = readType; - this.writeType = writeType; - } - - @Override - public int hashCode() { - return Objects.hash(keyType, readType, writeType); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!(obj instanceof GoArchetypeResourceCollectionType)) { - return false; - } - GoArchetypeResourceCollectionType other = (GoArchetypeResourceCollectionType) obj; - return keyType.equals(other.keyType) && readType.equals(other.readType) && writeType.equals(other.writeType); - } - - @Override - public T accept(GoTypeVisitor v) throws E { - return v.visit(this); - } - - public GoType getKeyType() { - return keyType; - } - - public GoType getReadType() { - return readType; - } - - public GoType getWriteType() { - return writeType; - } -} diff --git a/src/pgo/model/golang/type/GoArchetypeResourceType.java b/src/pgo/model/golang/type/GoArchetypeResourceType.java deleted file mode 100644 index e79297915..000000000 --- a/src/pgo/model/golang/type/GoArchetypeResourceType.java +++ /dev/null @@ -1,43 +0,0 @@ -package pgo.model.golang.type; - -import java.util.Objects; - -public class GoArchetypeResourceType extends GoType { - private final GoType readType; - private final GoType writeType; - - public GoArchetypeResourceType(GoType readType, GoType writeType) { - this.readType = readType; - this.writeType = writeType; - } - - @Override - public int hashCode() { - return Objects.hash(readType, writeType); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!(obj instanceof GoArchetypeResourceType)) { - return false; - } - GoArchetypeResourceType other = (GoArchetypeResourceType) obj; - return readType.equals(other.readType) && writeType.equals(other.writeType); - } - - @Override - public T accept(GoTypeVisitor v) throws E { - return v.visit(this); - } - - public GoType getReadType() { - return readType; - } - - public GoType getWriteType() { - return writeType; - } -} diff --git a/src/pgo/model/golang/type/GoChanType.java b/src/pgo/model/golang/type/GoChanType.java deleted file mode 100644 index ce84af54e..000000000 --- a/src/pgo/model/golang/type/GoChanType.java +++ /dev/null @@ -1,41 +0,0 @@ -package pgo.model.golang.type; - -public class GoChanType extends GoType { - private final GoType elementType; - - public GoChanType(GoType elementType) { - this.elementType = elementType; - } - - public GoType getElementType() { - return elementType; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((elementType == null) ? 0 : elementType.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; - GoChanType other = (GoChanType) obj; - if (elementType == null) { - return other.elementType == null; - } - return elementType.equals(other.elementType); - } - - @Override - public T accept(GoTypeVisitor v) throws E { - return v.visit(this); - } -} diff --git a/src/pgo/model/golang/type/GoInterfaceType.java b/src/pgo/model/golang/type/GoInterfaceType.java deleted file mode 100644 index 595735645..000000000 --- a/src/pgo/model/golang/type/GoInterfaceType.java +++ /dev/null @@ -1,44 +0,0 @@ -package pgo.model.golang.type; - -import java.util.List; - -public class GoInterfaceType extends GoType { - - private final List fields; - - public GoInterfaceType(List fields) { - this.fields = fields; - } - - public List getFields() { - return fields; - } - - @Override - public T accept(GoTypeVisitor v) throws E { - return v.visit(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((fields == null) ? 0 : fields.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; - GoInterfaceType other = (GoInterfaceType) obj; - if (fields == null) { - return other.fields == null; - } else return fields.equals(other.fields); - } - -} diff --git a/src/pgo/model/golang/type/GoInterfaceTypeField.java b/src/pgo/model/golang/type/GoInterfaceTypeField.java deleted file mode 100644 index ee4e4dc20..000000000 --- a/src/pgo/model/golang/type/GoInterfaceTypeField.java +++ /dev/null @@ -1,54 +0,0 @@ -package pgo.model.golang.type; - -import pgo.model.golang.GoFunctionParameter; -import pgo.model.golang.GoNode; -import pgo.model.golang.GoNodeVisitor; - -import java.util.List; -import java.util.Objects; - -public class GoInterfaceTypeField extends GoNode { - - private final String name; - private final List arguments; - private final List returnTypes; - - public GoInterfaceTypeField(String name, List arguments, List returnTypes) { - this.name = name; - this.arguments = arguments; - this.returnTypes = returnTypes; - } - - public String getName() { - return name; - } - - public List getArguments() { - return arguments; - } - - public List getReturnTypes() { - return returnTypes; - } - - @Override - public T accept(GoNodeVisitor v) throws E { - return v.visit(this); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - GoInterfaceTypeField that = (GoInterfaceTypeField) o; - return Objects.equals(name, that.name) && - Objects.equals(arguments, that.arguments) && - Objects.equals(returnTypes, that.returnTypes); - } - - @Override - public int hashCode() { - - return Objects.hash(name, arguments, returnTypes); - } -} diff --git a/src/pgo/model/golang/type/GoMapType.java b/src/pgo/model/golang/type/GoMapType.java deleted file mode 100644 index 101169633..000000000 --- a/src/pgo/model/golang/type/GoMapType.java +++ /dev/null @@ -1,61 +0,0 @@ -package pgo.model.golang.type; - -import java.util.Collections; -import java.util.Map; -import java.util.Objects; - -public class GoMapType extends GoType { - private final GoType keyType; - private final GoType valueType; - private final Map inferredTypes; - - public GoMapType(GoType keyType, GoType valueType, Map inferredTypes) { - this.keyType = keyType; - this.valueType = valueType; - this.inferredTypes = inferredTypes; - } - - public GoMapType(GoType keyType, GoType valueType) { - this(keyType, valueType, Collections.emptyMap()); - } - - public GoType getKeyType() { - return keyType; - } - - public GoType getValueType() { - return valueType; - } - - public Map getInferredTypes() { - return inferredTypes; - } - - public boolean isRecord() { - return !inferredTypes.isEmpty(); - } - - @Override - public int hashCode() { - return Objects.hash(keyType, valueType, inferredTypes); - } - - @Override - public boolean equals(Object other) { - if (this == other) { - return true; - } - if (other == null || getClass() != other.getClass()) { - return false; - } - GoMapType that = (GoMapType) other; - return Objects.equals(keyType, that.keyType) && - Objects.equals(valueType, that.valueType) && - Objects.equals(inferredTypes, that.getInferredTypes()); - } - - @Override - public T accept(GoTypeVisitor v) throws E { - return v.visit(this); - } -} diff --git a/src/pgo/model/golang/type/GoSliceType.java b/src/pgo/model/golang/type/GoSliceType.java deleted file mode 100644 index e3c9375a9..000000000 --- a/src/pgo/model/golang/type/GoSliceType.java +++ /dev/null @@ -1,42 +0,0 @@ -package pgo.model.golang.type; - -public class GoSliceType extends GoType { - - private final GoType elementType; - - public GoSliceType(GoType elementType) { - this.elementType = elementType; - } - - public GoType getElementType() { - return elementType; - } - - @Override - public T accept(GoTypeVisitor v) throws E { - return v.visit(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((elementType == null) ? 0 : elementType.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; - GoSliceType other = (GoSliceType) obj; - if (elementType == null) { - return other.elementType == null; - } else return elementType.equals(other.elementType); - } - -} diff --git a/src/pgo/model/golang/type/GoStructType.java b/src/pgo/model/golang/type/GoStructType.java deleted file mode 100644 index 6f9f5f98e..000000000 --- a/src/pgo/model/golang/type/GoStructType.java +++ /dev/null @@ -1,44 +0,0 @@ -package pgo.model.golang.type; - -import java.util.List; - -public class GoStructType extends GoType { - - private final List fields; - - public GoStructType(List fields) { - this.fields = fields; - } - - public List getFields(){ - return fields; - } - - @Override - public T accept(GoTypeVisitor v) throws E { - return v.visit(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((fields == null) ? 0 : fields.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; - GoStructType other = (GoStructType) obj; - if (fields == null) { - return other.fields == null; - } else return fields.equals(other.fields); - } - -} diff --git a/src/pgo/model/golang/type/GoStructTypeField.java b/src/pgo/model/golang/type/GoStructTypeField.java deleted file mode 100644 index 13313f5dc..000000000 --- a/src/pgo/model/golang/type/GoStructTypeField.java +++ /dev/null @@ -1,44 +0,0 @@ -package pgo.model.golang.type; - -import pgo.model.golang.GoNode; -import pgo.model.golang.GoNodeVisitor; - -import java.util.Objects; - -public class GoStructTypeField extends GoNode { - private final String name; - private final GoType type; - - public GoStructTypeField(String name, GoType type) { - this.name = name; - this.type = type; - } - - public String getName() { - return name; - } - - public GoType getType() { - return type; - } - - @Override - public T accept(GoNodeVisitor v) throws E { - return v.visit(this); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - GoStructTypeField that = (GoStructTypeField) o; - return Objects.equals(name, that.name) && - Objects.equals(type, that.type); - } - - @Override - public int hashCode() { - - return Objects.hash(name, type); - } -} diff --git a/src/pgo/model/golang/type/GoType.java b/src/pgo/model/golang/type/GoType.java deleted file mode 100644 index 2a748c65c..000000000 --- a/src/pgo/model/golang/type/GoType.java +++ /dev/null @@ -1,21 +0,0 @@ -package pgo.model.golang.type; - -import pgo.model.golang.GoNode; -import pgo.model.golang.GoNodeVisitor; - -public abstract class GoType extends GoNode { - - @Override - public abstract int hashCode(); - - @Override - public abstract boolean equals(Object other); - - public abstract T accept(GoTypeVisitor v) throws E; - - @Override - public T accept(GoNodeVisitor v) throws E { - return v.visit(this); - } - -} diff --git a/src/pgo/model/golang/type/GoTypeName.java b/src/pgo/model/golang/type/GoTypeName.java deleted file mode 100644 index 2254b25c1..000000000 --- a/src/pgo/model/golang/type/GoTypeName.java +++ /dev/null @@ -1,54 +0,0 @@ -package pgo.model.golang.type; - -public class GoTypeName extends GoType { - - private final String name; - private final boolean builtin; - - public GoTypeName(String name) { - this.name = name; - this.builtin = false; - } - - public GoTypeName(String name, boolean builtin) { - this.name = name; - this.builtin = builtin; - } - - public String getName() { - return name; - } - - public boolean isBuiltin() { - return builtin; - } - - @Override - public T accept(GoTypeVisitor v) throws E { - return v.visit(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((name == null) ? 0 : name.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; - GoTypeName other = (GoTypeName) obj; - if (name == null) { - return other.name == null; - } - return name.equals(other.name); - } - -} diff --git a/src/pgo/model/golang/type/GoTypeVisitor.java b/src/pgo/model/golang/type/GoTypeVisitor.java deleted file mode 100644 index 93f56b5f5..000000000 --- a/src/pgo/model/golang/type/GoTypeVisitor.java +++ /dev/null @@ -1,15 +0,0 @@ -package pgo.model.golang.type; - -import pgo.model.golang.GoPtrType; - -public abstract class GoTypeVisitor { - public abstract T visit(GoChanType chanType) throws E; - public abstract T visit(GoInterfaceType interfaceType) throws E; - public abstract T visit(GoMapType mapType) throws E; - public abstract T visit(GoPtrType ptrType) throws E; - public abstract T visit(GoSliceType sliceType) throws E; - public abstract T visit(GoStructType structType) throws E; - public abstract T visit(GoTypeName typeName) throws E; - public abstract T visit(GoArchetypeResourceType archetypeResourceType) throws E; - public abstract T visit(GoArchetypeResourceCollectionType archetypeResourceCollectionType) throws E; -} diff --git a/src/pgo/model/mpcal/AST.scala b/src/pgo/model/mpcal/AST.scala new file mode 100644 index 000000000..ad167aca1 --- /dev/null +++ b/src/pgo/model/mpcal/AST.scala @@ -0,0 +1,133 @@ +package pgo.model.mpcal + +import pgo.model.RefersTo.Renamer +import pgo.model.{Definition, DefinitionOne, RefersTo, Rewritable, SourceLocatable, Visitable} +import pgo.model.tla._ +import pgo.model.pcal._ +import pgo.util.IdMap + +sealed abstract class MPCalNode extends Rewritable with Visitable with SourceLocatable { + override def decorateLike(succ: this.type): this.type = + super.decorateLike(succ.setSourceLocation(sourceLocation)) +} + +final case class MPCalRefExpr(name: TLAIdentifier, mappingCount: Int) extends MPCalNode with RefersTo[MPCalParam] +final case class MPCalValExpr(name: TLAIdentifier, mappingCount: Int) extends MPCalNode with RefersTo[MPCalParam] + +final case class MPCalDollarValue() extends MPCalNode + +final case class MPCalDollarVariable() extends MPCalNode + +final case class MPCalYield(expr: TLAExpression) extends MPCalNode + +final case class MPCalCall(target: TLAIdentifier, arguments: List[TLAExpression]) extends MPCalNode with RefersTo[MPCalProcedure] + +sealed abstract class MPCalParam extends MPCalNode with DefinitionOne { + def name: TLAIdentifier + override def arity: Int = 0 + override def identifier: Definition.ScopeIdentifier = Definition.ScopeIdentifierName(name) +} +final case class MPCalRefParam(override val name: TLAIdentifier, mappingCount: Int) extends MPCalParam +final case class MPCalValParam(override val name: TLAIdentifier, mappingCount: Int) extends MPCalParam + +final case class MPCalBlock(name: TLAIdentifier, units: List[TLAUnit], macros: List[PCalMacro], mpcalProcedures: List[MPCalProcedure], + mappingMacros: List[MPCalMappingMacro], archetypes: List[MPCalArchetype], + variables: List[PCalVariableDeclaration], instances: List[MPCalInstance], + pcalProcedures: List[PCalProcedure], + processes: Either[List[PCalStatement],List[PCalProcess]]) extends MPCalNode { + override def mapChildren(fn: Any => Any): this.type = { + val renamer = new Renamer[Rewritable]() + val mappedName = fn(name) + val mappedUnits = renamer.mapConserveRenamingAny(units, fn) + // like in PCal AST, macros and procedures are mutually referential, so if one changes, we need to recompute references + var mappedMacros = macros.mapConserve(renamer.captureRenamingAny(_, fn)) + var mappedPCalProcedures = pcalProcedures.mapConserve(renamer.captureRenamingAny(_, fn)) + var mappedMPCalProcedures = mpcalProcedures.mapConserve(renamer.captureRenamingAny(_, fn)) + if((mappedMacros ne macros) || (mappedPCalProcedures ne pcalProcedures) || (mappedMPCalProcedures ne mpcalProcedures)) { + def duplicator[N <: Rewritable](n: N): N = + n.rewrite() { + case call @PCalCall(_, _) => call.shallowCopy() + case macroCall @PCalMacroCall(_, _) => macroCall.shallowCopy() + case mpcalCall @MPCalCall(_, _) => mpcalCall.shallowCopy() + } + mappedMacros = mappedMacros.mapConserve(renamer.captureRenaming(_, duplicator[PCalMacro])) + mappedPCalProcedures = mappedPCalProcedures.mapConserve(renamer.captureRenaming(_, duplicator[PCalProcedure])) + mappedMPCalProcedures = mappedMPCalProcedures.mapConserve(renamer.captureRenaming(_, duplicator[MPCalProcedure])) + val macroMap = (macros.view zip mappedMacros).to(IdMap) + val pcalProcMap = (pcalProcedures.view zip mappedPCalProcedures).to(IdMap) + val mpcalProcMap = (mpcalProcedures.view zip mappedMPCalProcedures).to(IdMap) + def referenceFixer[N <: Visitable](n: N): Unit = + n.visit() { + case call @PCalCall(_, _) => call.setRefersTo(pcalProcMap(call.refersTo)) + case macroCall @PCalMacroCall(_, _) => macroCall.setRefersTo(macroMap(macroCall.refersTo)) + case mpcalCall @MPCalCall(_, _) => mpcalCall.setRefersTo(mpcalProcMap(mpcalCall.refersTo)) + } + mappedMacros.foreach(referenceFixer(_)) + mappedPCalProcedures.foreach(referenceFixer(_)) + mappedMPCalProcedures.foreach(referenceFixer(_)) + } + val mappedMappingMacros = mappingMacros.mapConserve(renamer.captureRenamingAny(_, fn)) + val mappedArchetypes = archetypes.mapConserve(archetype => fn(renamer(archetype)).asInstanceOf[MPCalArchetype]) + val mappedVariables = renamer.mapConserveRenamingAny(variables, fn) + val mappedInstances = instances.mapConserve(instance => fn(renamer(instance)).asInstanceOf[MPCalInstance]) + val mappedProcesses: Either[List[PCalStatement],List[PCalProcess]] = processes match { + case Left(body) => + val mappedBody = body.mapConserve(stmt => fn(renamer(stmt)).asInstanceOf[PCalStatement]) + if(mappedBody ne body) { + Left(mappedBody) + } else processes + case Right(processes) => + val mappedProcesses = processes.mapConserve(process => fn(renamer(process)).asInstanceOf[PCalProcess]) + if(mappedProcesses ne processes) { + Right(mappedProcesses) + } else this.processes + } + withChildren(Iterator(mappedName, mappedUnits, mappedMacros, mappedMPCalProcedures, mappedMappingMacros, mappedArchetypes, + mappedVariables, mappedInstances, mappedPCalProcedures, mappedProcesses)) + } +} + +final case class MPCalProcedure(name: TLAIdentifier, params: List[MPCalParam], variables: List[PCalPVariableDeclaration], + body: List[PCalStatement]) extends MPCalNode { + override def mapChildren(fn: Any => Any): this.type = { + val renamer = new Renamer[DefinitionOne with Rewritable]() + val mappedName = fn(name) + val mappedParams = renamer.mapConserveRenamingAny(params, fn) + val mappedVariables = renamer.mapConserveRenamingAny(variables, fn) + val mappedBody = body.mapConserve(stmt => fn(renamer(stmt)).asInstanceOf[PCalStatement]) + withChildren(Iterator(mappedName, mappedParams, mappedVariables, mappedBody)) + } +} + +final case class MPCalMappingMacro(name: TLAIdentifier, readBody: List[PCalStatement], writeBody: List[PCalStatement], + freeVars: List[TLADefiningIdentifier]) extends MPCalNode { + override def mapChildren(fn: Any => Any): this.type = { + val renamer = new Renamer[TLADefiningIdentifier]() + val mappedName = fn(name) + val mappedFreeVars = renamer.mapConserveRenamingAny(freeVars, fn) + val mappedReadBody = readBody.mapConserve(stmt => fn(renamer(stmt)).asInstanceOf[PCalStatement]) + val mappedWriteBody = writeBody.mapConserve(stmt => fn(renamer(stmt)).asInstanceOf[PCalStatement]) + withChildren(Iterator(mappedName, mappedReadBody, mappedWriteBody, mappedFreeVars)) + } +} + +final case class MPCalArchetype(name: TLAIdentifier, selfDecl: TLADefiningIdentifier, params: List[MPCalParam], + variables: List[PCalVariableDeclaration], body: List[PCalStatement]) extends MPCalNode { + override def mapChildren(fn: Any => Any): this.type = { + val renamer = new Renamer[DefinitionOne with Rewritable]() + val mappedName = fn(name) + val mappedSelf = renamer.captureRenamingAny(selfDecl, fn) + val mappedParams = renamer.mapConserveRenamingAny(params, fn) + val mappedVariables = renamer.mapConserveRenamingAny(variables, fn) + val mappedBody = body.mapConserve(stmt => fn(renamer(stmt)).asInstanceOf[PCalStatement]) + withChildren(Iterator(mappedName, mappedSelf, mappedParams, mappedVariables, mappedBody)) + } +} + +final case class MPCalInstance(selfDecl: PCalVariableDeclarationBound, fairness: PCalFairness, + archetypeName: TLAIdentifier, arguments: List[Either[MPCalParam,TLAExpression]], + mappings: List[MPCalMapping]) extends MPCalNode with RefersTo[MPCalArchetype] + +final case class MPCalMapping(target: MPCalMappingTarget, mappingMacroIdentifier: TLAIdentifier) extends MPCalNode with RefersTo[MPCalMappingMacro] + +final case class MPCalMappingTarget(position: Int, mappingCount: Int) extends MPCalNode diff --git a/src/pgo/model/mpcal/ModularPlusCalArchetype.java b/src/pgo/model/mpcal/ModularPlusCalArchetype.java deleted file mode 100644 index 88d4835ab..000000000 --- a/src/pgo/model/mpcal/ModularPlusCalArchetype.java +++ /dev/null @@ -1,99 +0,0 @@ -package pgo.model.mpcal; - -import pgo.model.pcal.PlusCalStatement; -import pgo.model.pcal.PlusCalVariableDeclaration; -import pgo.model.tla.TLAIdentifier; -import pgo.scope.UID; -import pgo.util.SourceLocation; - -import java.util.Collections; -import java.util.List; -import java.util.Objects; -import java.util.stream.Collectors; - -/** - * Modular PlusCal archetype node - * - * archetype A(arg1, ref arg2) - * variables local = exp; - * { - * body; - * } - */ -public class ModularPlusCalArchetype extends ModularPlusCalUnit { - private final TLAIdentifier name; - private final List params; - private final List variables; - private final List body; - - public ModularPlusCalArchetype(SourceLocation location, TLAIdentifier name, List params, - List variables, List body) { - super(location); - this.name = name; - this.params = params; - this.variables = variables; - this.body = body; - } - - @Override - public ModularPlusCalArchetype copy() { - return new ModularPlusCalArchetype( - getLocation(), - name.copy(), - params.stream().map(PlusCalVariableDeclaration::copy).collect(Collectors.toList()), - variables.stream().map(PlusCalVariableDeclaration::copy).collect(Collectors.toList()), - body.stream().map(PlusCalStatement::copy).collect(Collectors.toList())); - } - - @Override - public int hashCode() { - return Objects.hash(name, params, variables, body); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null || obj.getClass() != getClass()) { - return false; - } - ModularPlusCalArchetype that = (ModularPlusCalArchetype) obj; - return name.equals(that.name) && - Objects.equals(params, that.params) && - Objects.equals(variables, that.variables) && - Objects.equals(body, that.body); - } - - @Override - public T accept(ModularPlusCalNodeVisitor v) throws E { - return v.visit(this); - } - - public T accept(ModularPlusCalBlockVisitor v) throws E { - return v.visit(this); - } - - public String getName() { - return name.getId(); - } - public TLAIdentifier getId() { - return name; - } - - public UID getSelfVariableUID() { - return name.getUID(); - } - - public List getParams() { - return Collections.unmodifiableList(params); - } - - public List getVariables() { - return Collections.unmodifiableList(variables); - } - - public List getBody() { - return Collections.unmodifiableList(body); - } -} diff --git a/src/pgo/model/mpcal/ModularPlusCalBlock.scala b/src/pgo/model/mpcal/ModularPlusCalBlock.scala deleted file mode 100644 index 80fcbacd5..000000000 --- a/src/pgo/model/mpcal/ModularPlusCalBlock.scala +++ /dev/null @@ -1,81 +0,0 @@ -package pgo.model.mpcal - -import pgo.model.pcal._ -import pgo.model.tla.{TLAFunctionDefinition, TLAIdentifier, TLAOperatorDefinition, TLAUnit, TLAUtils} -import pgo.trans.intermediate.DefinitionRegistry -import pgo.util.SourceLocation - -import scala.jdk.CollectionConverters._ - -object ModularPlusCalBlock { - def from(plusCalAlgorithm: PlusCalAlgorithm) = - new ModularPlusCalBlock( - plusCalAlgorithm.getLocation, plusCalAlgorithm.getName, plusCalAlgorithm.getUnits.asScala.toList, - plusCalAlgorithm.getMacros.asScala.toList, plusCalAlgorithm.getProcedures.asScala.toList, - Nil, Nil, plusCalAlgorithm.getVariables.asScala.toList, Nil, plusCalAlgorithm.getProcesses) -} - -final class ModularPlusCalBlock(loc: SourceLocation, val name: TLAIdentifier, val units: List[TLAUnit], - val macros: List[PlusCalMacro], val procedures: List[PlusCalProcedure], - val mappingMacros: List[ModularPlusCalMappingMacro], val archetypes: List[ModularPlusCalArchetype], - val variables: List[PlusCalVariableDeclaration], val instances: List[ModularPlusCalInstance], - val processes: PlusCalProcesses) extends ModularPlusCalNode(loc) { - def this(loc: SourceLocation, name: TLAIdentifier, units: java.util.List[TLAUnit], macros: java.util.List[PlusCalMacro], - procedures: java.util.List[PlusCalProcedure], mappingMacros: java.util.List[ModularPlusCalMappingMacro], - archetypes: java.util.List[ModularPlusCalArchetype], variables: java.util.List[PlusCalVariableDeclaration], - instances: java.util.List[ModularPlusCalInstance], processes: PlusCalProcesses) = - this(loc, name, units.asScala.toList, macros.asScala.toList, procedures.asScala.toList, - mappingMacros.asScala.toList, archetypes.asScala.toList, variables.asScala.toList, - instances.asScala.toList, processes) - - override def copy: ModularPlusCalBlock = - new ModularPlusCalBlock( - getLocation, name.copy, units.map(_.copy()), macros.map(_.copy()), procedures.map(_.copy()), - mappingMacros.map(_.copy()), archetypes.map(_.copy()), variables.map(_.copy()), - instances.map(_.copy()), processes.copy) - - override def accept[T, E <: Throwable](v: ModularPlusCalNodeVisitor[T, E]): T = v.visit(this) - - def accept[T, E <: Throwable](v: ModularPlusCalBlockVisitor[T, E]): T = v.visit(this) - - def getName: TLAIdentifier = name - - def getVariables: java.util.List[PlusCalVariableDeclaration] = variables.asJava - - def getUnits: java.util.List[TLAUnit] = units.asJava - - def getMappingMacros: java.util.List[ModularPlusCalMappingMacro] = mappingMacros.asJava - - def getArchetypes: java.util.List[ModularPlusCalArchetype] = archetypes.asJava - - lazy val instantiatedArchetypes: List[ModularPlusCalArchetype] = - archetypes.filter(arch => instances.exists(inst => inst.getTarget == arch.getName)) - def getInstantiatedArchetypes: java.util.List[ModularPlusCalArchetype] = instantiatedArchetypes.asJava - - def getMacros: java.util.List[PlusCalMacro] = macros.asJava - - def getProcedures: java.util.List[PlusCalProcedure] = procedures.asJava - - def getInstances: java.util.List[ModularPlusCalInstance] = instances.asJava - - def getProcesses: PlusCalProcesses = processes - - override def equals(other: Any): Boolean = other match { - case that: ModularPlusCalBlock => - name == that.name && - units == that.units && - macros == that.macros && - procedures == that.procedures && - mappingMacros == that.mappingMacros && - archetypes == that.archetypes && - variables == that.variables && - instances == that.instances && - processes == that.processes - case _ => false - } - - override def hashCode(): Int = { - val state = Seq(name, units, macros, procedures, mappingMacros, archetypes, variables, instances, processes) - state.map(_.hashCode()).foldLeft(0)((a, b) => 31 * a + b) - } -} \ No newline at end of file diff --git a/src/pgo/model/mpcal/ModularPlusCalBlockVisitor.java b/src/pgo/model/mpcal/ModularPlusCalBlockVisitor.java deleted file mode 100644 index e3e374fd9..000000000 --- a/src/pgo/model/mpcal/ModularPlusCalBlockVisitor.java +++ /dev/null @@ -1,16 +0,0 @@ -package pgo.model.mpcal; - -import pgo.model.pcal.*; -import pgo.model.tla.TLAUnit; - -public abstract class ModularPlusCalBlockVisitor { - public abstract T visit(ModularPlusCalBlock modularPlusCalBlock) throws E; - public abstract T visit(TLAUnit tlaUnit) throws E; - public abstract T visit(ModularPlusCalMappingMacro modularPlusCalMappingMacro) throws E; - public abstract T visit(ModularPlusCalArchetype modularPlusCalArchetype) throws E; - public abstract T visit(PlusCalMacro plusCalMacro) throws E; - public abstract T visit(PlusCalProcedure plusCalProcedure) throws E; - public abstract T visit(ModularPlusCalInstance modularPlusCalInstance) throws E; - public abstract T visit(PlusCalSingleProcess plusCalSingleProcess) throws E; - public abstract T visit(PlusCalMultiProcess plusCalMultiProcess) throws E; -} diff --git a/src/pgo/model/mpcal/ModularPlusCalBuilder.java b/src/pgo/model/mpcal/ModularPlusCalBuilder.java deleted file mode 100644 index 6873cc55b..000000000 --- a/src/pgo/model/mpcal/ModularPlusCalBuilder.java +++ /dev/null @@ -1,74 +0,0 @@ -package pgo.model.mpcal; - -import pgo.model.pcal.*; -import pgo.model.tla.TLABuilder; -import pgo.model.tla.TLAExpression; -import pgo.model.tla.TLAIdentifier; -import pgo.model.tla.TLAUnit; -import pgo.util.SourceLocation; - -import java.util.Arrays; -import java.util.List; - -public class ModularPlusCalBuilder { - private ModularPlusCalBuilder() {} - - public static ModularPlusCalArchetype archetype(String name, List arguments, - List variables, - List body) { - return new ModularPlusCalArchetype(SourceLocation.unknown(), TLABuilder.id(name), arguments, variables, body); - } - - public static ModularPlusCalMapping mapping(int position, boolean functionCalls, String target) { - return new ModularPlusCalMapping( - SourceLocation.unknown(), - new ModularPlusCalMappingVariablePosition(SourceLocation.unknown(), position, functionCalls), - new ModularPlusCalMappingTarget(SourceLocation.unknown(), target)); - } - - public static ModularPlusCalMapping mapping(String variable, boolean functionCalls, String target) { - return new ModularPlusCalMapping( - SourceLocation.unknown(), - new ModularPlusCalMappingVariableName(SourceLocation.unknown(), TLABuilder.id(variable), functionCalls), - new ModularPlusCalMappingTarget(SourceLocation.unknown(), target)); - } - - public static ModularPlusCalInstance instance(PlusCalVariableDeclaration name, PlusCalFairness fairness, - String target, List params, - List mappings) { - return new ModularPlusCalInstance(SourceLocation.unknown(), name, fairness, TLABuilder.id(target), params, mappings); - } - - public static ModularPlusCalMappingMacro mappingMacro(String name, List readBody, - List writeBody) { - return new ModularPlusCalMappingMacro(SourceLocation.unknown(), TLABuilder.id(name), readBody, writeBody); - } - - public static ModularPlusCalBlock mpcal(String name, List units, List macros, - List procedures, - List mappingMacros, - List archetypes, - List variables, - List instances, PlusCalProcess... processes) { - return new ModularPlusCalBlock( - SourceLocation.unknown(), - new TLAIdentifier(SourceLocation.unknown(), name), - units, macros, procedures, mappingMacros, archetypes, variables, - instances, new PlusCalMultiProcess(SourceLocation.unknown(), Arrays.asList(processes)) - ); - } - - public static ModularPlusCalBlock mpcal(String name, List units, List macros, - List procedures, - List mappingMacros, - List archetypes, - List variables, - List instances, List statements) { - return new ModularPlusCalBlock( - SourceLocation.unknown(), - new TLAIdentifier(SourceLocation.unknown(), name), - units, macros, procedures, mappingMacros, archetypes, variables, - instances, new PlusCalSingleProcess(SourceLocation.unknown(), statements) - ); - } -} diff --git a/src/pgo/model/mpcal/ModularPlusCalInstance.java b/src/pgo/model/mpcal/ModularPlusCalInstance.java deleted file mode 100644 index ccc4f4d5d..000000000 --- a/src/pgo/model/mpcal/ModularPlusCalInstance.java +++ /dev/null @@ -1,96 +0,0 @@ -package pgo.model.mpcal; - -import pgo.model.pcal.PlusCalFairness; -import pgo.model.pcal.PlusCalVariableDeclaration; -import pgo.model.tla.TLAExpression; -import pgo.model.tla.TLAIdentifier; -import pgo.util.SourceLocation; - -import java.util.Collections; -import java.util.List; -import java.util.Objects; -import java.util.stream.Collectors; - -/** - * Modular PlusCal instance node - * - * process (P \in 1..3) = instance A(exp, ref global, readOnlyGlobal) - * mapping global via MappingMacro; - * interleaving goto label; // TODO - */ -public class ModularPlusCalInstance extends ModularPlusCalUnit { - private final PlusCalVariableDeclaration name; - private final PlusCalFairness fairness; - private final TLAIdentifier target; - private final List arguments; - private final List mappings; - // TODO - // private final Located interleavingTarget; - - public ModularPlusCalInstance(SourceLocation location, PlusCalVariableDeclaration name, PlusCalFairness fairness, - TLAIdentifier target, List arguments, List mappings) { - super(location); - this.name = name; - this.fairness = fairness; - this.target = target; - this.arguments = arguments; - this.mappings = mappings; - } - - @Override - public ModularPlusCalInstance copy() { - return new ModularPlusCalInstance( - getLocation(), - name.copy(), - fairness, - target, - arguments.stream().map(TLAExpression::copy).collect(Collectors.toList()), - mappings.stream().map(ModularPlusCalMapping::copy).collect(Collectors.toList())); - } - - @Override - public int hashCode() { - return Objects.hash(name, target, arguments, mappings); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null || obj.getClass() != this.getClass()) { - return false; - } - ModularPlusCalInstance that = (ModularPlusCalInstance) obj; - return target.equals(that.target) && - name.equals(that.name) && - fairness.equals(that.fairness) && - Objects.equals(arguments, that.arguments) && - Objects.equals(mappings, that.mappings); - } - - @Override - public T accept(ModularPlusCalNodeVisitor v) throws E { - return v.visit(this); - } - - public PlusCalVariableDeclaration getName() { - return name; - } - - public PlusCalFairness getFairness() { - return this.fairness; - } - - public String getTarget() { - return target.getId(); - } - - public List getMappings() { - return Collections.unmodifiableList(mappings); - } - - public List getArguments() { - return Collections.unmodifiableList(arguments); - } -} diff --git a/src/pgo/model/mpcal/ModularPlusCalMapping.java b/src/pgo/model/mpcal/ModularPlusCalMapping.java deleted file mode 100644 index 09ec6d076..000000000 --- a/src/pgo/model/mpcal/ModularPlusCalMapping.java +++ /dev/null @@ -1,57 +0,0 @@ -package pgo.model.mpcal; - -import pgo.util.SourceLocatable; -import pgo.util.SourceLocation; - -import java.util.Objects; - -public class ModularPlusCalMapping extends SourceLocatable { - private final SourceLocation location; - private final ModularPlusCalMappingVariable variable; - private final ModularPlusCalMappingTarget target; - - public ModularPlusCalMapping(SourceLocation location, ModularPlusCalMappingVariable variable, - ModularPlusCalMappingTarget target) { - this.location = location; - this.variable = variable; - this.target = target; - } - - public ModularPlusCalMapping copy() { - return new ModularPlusCalMapping( - getLocation(), - variable.copy(), - new ModularPlusCalMappingTarget(target.getLocation(), target.getName())); - } - - @Override - public int hashCode() { - return Objects.hash(variable, target.getName()); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null || obj.getClass() != getClass()) { - return false; - } - ModularPlusCalMapping that = (ModularPlusCalMapping) obj; - return target.getName().equals(that.target.getName()) && - variable.equals(that.variable); - } - - @Override - public SourceLocation getLocation() { - return location; - } - - public ModularPlusCalMappingVariable getVariable() { - return variable; - } - - public ModularPlusCalMappingTarget getTarget() { - return target; - } -} diff --git a/src/pgo/model/mpcal/ModularPlusCalMappingMacro.java b/src/pgo/model/mpcal/ModularPlusCalMappingMacro.java deleted file mode 100644 index 5066dffde..000000000 --- a/src/pgo/model/mpcal/ModularPlusCalMappingMacro.java +++ /dev/null @@ -1,107 +0,0 @@ -package pgo.model.mpcal; - -import pgo.model.pcal.PlusCalStatement; -import pgo.model.tla.TLAIdentifier; -import pgo.scope.UID; -import pgo.util.SourceLocation; - -import java.util.Collections; -import java.util.List; -import java.util.Objects; -import java.util.stream.Collectors; - -/** - * Modular PlusCal mapping macro node - * - * mapping macro MappingMacro { - * read { - * readBody; - * } - * write { - * writeBody; - * } - * } - */ -public class ModularPlusCalMappingMacro extends ModularPlusCalUnit { - private final TLAIdentifier name; - private final List readBody; - private final List writeBody; - private final UID selfVariableUID; - private final UID specialVariableVariableUID; - private final UID specialVariableValueUID; - - public ModularPlusCalMappingMacro(SourceLocation location, TLAIdentifier name, List readBody, - List writeBody) { - super(location); - this.name = name; - this.readBody = readBody; - this.writeBody = writeBody; - this.selfVariableUID = new UID(); - this.selfVariableUID.addOrigin(this); - this.specialVariableVariableUID = new UID(); - this.specialVariableVariableUID.addOrigin(this); - this.specialVariableValueUID = new UID(); - this.specialVariableValueUID.addOrigin(this); - } - - @Override - public ModularPlusCalMappingMacro copy() { - return new ModularPlusCalMappingMacro( - getLocation(), - name, - readBody.stream().map(PlusCalStatement::copy).collect(Collectors.toList()), - writeBody.stream().map(PlusCalStatement::copy).collect(Collectors.toList())); - } - - @Override - public int hashCode() { - return Objects.hash(name, readBody, writeBody); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null || obj.getClass() != getClass()) { - return false; - } - ModularPlusCalMappingMacro that = (ModularPlusCalMappingMacro) obj; - return name.equals(that.name) && - Objects.equals(readBody, that.readBody) && - Objects.equals(writeBody, that.writeBody); - } - - @Override - public T accept(ModularPlusCalNodeVisitor v) throws E { - return v.visit(this); - } - - public T accept(ModularPlusCalBlockVisitor v) throws E { - return v.visit(this); - } - - public String getName() { - return name.getId(); - } - - public List getReadBody() { - return Collections.unmodifiableList(readBody); - } - - public List getWriteBody() { - return Collections.unmodifiableList(writeBody); - } - - public UID getSelfVariableUID() { - return selfVariableUID; - } - - public UID getSpecialVariableVariableUID() { - return specialVariableVariableUID; - } - - public UID getSpecialVariableValueUID() { - return specialVariableValueUID; - } -} diff --git a/src/pgo/model/mpcal/ModularPlusCalMappingTarget.java b/src/pgo/model/mpcal/ModularPlusCalMappingTarget.java deleted file mode 100644 index 4f1d381b8..000000000 --- a/src/pgo/model/mpcal/ModularPlusCalMappingTarget.java +++ /dev/null @@ -1,31 +0,0 @@ -package pgo.model.mpcal; - -import pgo.scope.UID; -import pgo.util.SourceLocatable; -import pgo.util.SourceLocation; - -public class ModularPlusCalMappingTarget extends SourceLocatable { - private final SourceLocation location; - private final UID uid; - private final String name; - - public ModularPlusCalMappingTarget(SourceLocation location, String name) { - this.location = location; - this.uid = new UID(); - this.uid.addOrigin(this); - this.name = name; - } - - @Override - public SourceLocation getLocation() { - return location; - } - - public UID getUID() { - return uid; - } - - public String getName() { - return name; - } -} diff --git a/src/pgo/model/mpcal/ModularPlusCalMappingVariable.java b/src/pgo/model/mpcal/ModularPlusCalMappingVariable.java deleted file mode 100644 index a6847f356..000000000 --- a/src/pgo/model/mpcal/ModularPlusCalMappingVariable.java +++ /dev/null @@ -1,50 +0,0 @@ -package pgo.model.mpcal; - -import pgo.model.tla.TLADefinitionOne; -import pgo.scope.UID; -import pgo.util.SourceLocatable; -import pgo.util.SourceLocation; - -public abstract class ModularPlusCalMappingVariable extends SourceLocatable { - protected final SourceLocation location; - protected final UID uid; - protected final boolean functionCall; - - private TLADefinitionOne refersTo; - - public ModularPlusCalMappingVariable(SourceLocation location, boolean functionCall) { - this.location = location; - this.uid = new UID(); - this.uid.addOrigin(this); - this.functionCall = functionCall; - } - - public void setRefersTo(TLADefinitionOne refersTo) { - this.refersTo = refersTo; - } - - public TLADefinitionOne getRefersTo() { - return refersTo; - } - - @Override - public SourceLocation getLocation() { - return location; - } - - public UID getUID() { - return uid; - } - - public boolean isFunctionCall() { - return functionCall; - } - - public abstract ModularPlusCalMappingVariable copy(); - - @Override - public abstract int hashCode(); - - @Override - public abstract boolean equals(Object obj); -} diff --git a/src/pgo/model/mpcal/ModularPlusCalMappingVariableName.java b/src/pgo/model/mpcal/ModularPlusCalMappingVariableName.java deleted file mode 100644 index cd1f1a654..000000000 --- a/src/pgo/model/mpcal/ModularPlusCalMappingVariableName.java +++ /dev/null @@ -1,46 +0,0 @@ -package pgo.model.mpcal; - -import pgo.model.tla.TLAIdentifier; -import pgo.util.SourceLocation; - -import java.util.Objects; - -public class ModularPlusCalMappingVariableName extends ModularPlusCalMappingVariable { - private final TLAIdentifier name; - - public ModularPlusCalMappingVariableName(SourceLocation location, TLAIdentifier name, boolean functionCall) { - super(location, functionCall); - this.name = name; - } - - public String getName() { - return name.getId(); - } - - @Override - public ModularPlusCalMappingVariableName copy() { - return new ModularPlusCalMappingVariableName(location, name, functionCall); - } - - @Override - public int hashCode() { - return Objects.hash(name, functionCall); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!(obj instanceof ModularPlusCalMappingVariableName)) { - return false; - } - ModularPlusCalMappingVariableName other = (ModularPlusCalMappingVariableName) obj; - return name.equals(other.name) && functionCall == other.functionCall; - } - - @Override - public String toString() { - return name.toString(); - } -} diff --git a/src/pgo/model/mpcal/ModularPlusCalMappingVariablePosition.java b/src/pgo/model/mpcal/ModularPlusCalMappingVariablePosition.java deleted file mode 100644 index d3678b675..000000000 --- a/src/pgo/model/mpcal/ModularPlusCalMappingVariablePosition.java +++ /dev/null @@ -1,45 +0,0 @@ -package pgo.model.mpcal; - -import pgo.util.SourceLocation; - -import java.util.Objects; - -public class ModularPlusCalMappingVariablePosition extends ModularPlusCalMappingVariable { - private final int position; - - public ModularPlusCalMappingVariablePosition(SourceLocation location, int position, boolean functionCall) { - super(location, functionCall); - this.position = position; - } - - public int getPosition() { - return position; - } - - @Override - public ModularPlusCalMappingVariablePosition copy() { - return new ModularPlusCalMappingVariablePosition(location, position, functionCall); - } - - @Override - public int hashCode() { - return Objects.hash(position, functionCall); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!(obj instanceof ModularPlusCalMappingVariablePosition)) { - return false; - } - ModularPlusCalMappingVariablePosition other = (ModularPlusCalMappingVariablePosition) obj; - return position == other.position && functionCall == other.functionCall; - } - - @Override - public String toString() { - return "@" + position + (functionCall ? "[_]" : ""); - } -} diff --git a/src/pgo/model/mpcal/ModularPlusCalNode.java b/src/pgo/model/mpcal/ModularPlusCalNode.java deleted file mode 100644 index 3513c0fec..000000000 --- a/src/pgo/model/mpcal/ModularPlusCalNode.java +++ /dev/null @@ -1,52 +0,0 @@ -package pgo.model.mpcal; - -import pgo.Unreachable; -import pgo.formatters.IndentingWriter; -import pgo.scope.UID; -import pgo.util.SourceLocatable; -import pgo.util.SourceLocation; - -import java.io.IOException; -import java.io.StringWriter; - -public abstract class ModularPlusCalNode extends SourceLocatable { - private final SourceLocation location; - private final UID uid; - - public ModularPlusCalNode(SourceLocation location) { - this.location = location; - this.uid = new UID(); - this.uid.addOrigin(this); - } - - public abstract ModularPlusCalNode copy(); - - @Override - public SourceLocation getLocation() { - return location; - } - - public UID getUID() { - return uid; - } - - @Override - public abstract int hashCode(); - - @Override - public abstract boolean equals(Object obj); - - public abstract T accept(ModularPlusCalNodeVisitor v) throws E; - - @Override - public String toString() { - StringWriter w = new StringWriter(); - IndentingWriter out = new IndentingWriter(w); - try { - accept(new ModularPlusCalNodeFormattingVisitor(out)); - } catch (IOException e) { - throw new Unreachable(e); - } - return w.toString(); - } -} diff --git a/src/pgo/model/mpcal/ModularPlusCalNodeFormattingVisitor.java b/src/pgo/model/mpcal/ModularPlusCalNodeFormattingVisitor.java deleted file mode 100644 index 8e0d9b63b..000000000 --- a/src/pgo/model/mpcal/ModularPlusCalNodeFormattingVisitor.java +++ /dev/null @@ -1,188 +0,0 @@ -package pgo.model.mpcal; - -import pgo.Unreachable; -import pgo.formatters.IndentingWriter; -import pgo.formatters.PlusCalNodeFormattingVisitor; -import pgo.formatters.TLAExpressionFormattingVisitor; -import pgo.formatters.TLAUnitFormattingVisitor; -import pgo.model.pcal.*; -import pgo.model.tla.TLAUnit; - -import java.io.IOException; -import java.util.stream.Collectors; - -public class ModularPlusCalNodeFormattingVisitor extends ModularPlusCalNodeVisitor { - private final IndentingWriter out; - - public ModularPlusCalNodeFormattingVisitor(IndentingWriter out) { - this.out = out; - } - - @Override - public Void visit(ModularPlusCalBlock modularPlusCalBlock) throws IOException { - out.write("--mpcal "); - out.write(modularPlusCalBlock.name().getId()); - out.write(" {"); - - try(IndentingWriter.Indent i_ = out.indent()) { - - if(!modularPlusCalBlock.getUnits().isEmpty()) { - out.newLine(); - out.write("define {"); - try(IndentingWriter.Indent ii_ = out.indent()) { - for(TLAUnit unit: modularPlusCalBlock.getUnits()) { - out.newLine(); - unit.accept(new TLAUnitFormattingVisitor(out)); - } - } - out.newLine(); - out.write("}"); - } - - for(PlusCalMacro macro: modularPlusCalBlock.getMacros()) { - out.newLine(); - macro.accept(new PlusCalNodeFormattingVisitor(out)); - } - for(PlusCalProcedure proc: modularPlusCalBlock.getProcedures()) { - out.newLine(); - proc.accept(new PlusCalNodeFormattingVisitor(out)); - } - for(ModularPlusCalMappingMacro mm: modularPlusCalBlock.getMappingMacros()) { - out.newLine(); - mm.accept(this); - } - for(ModularPlusCalArchetype arch: modularPlusCalBlock.getArchetypes()) { - out.newLine(); - arch.accept(this); - } - if(!modularPlusCalBlock.getVariables().isEmpty()) { - out.newLine(); - } - new PlusCalNodeFormattingVisitor(out).writeVariableDeclarations("variables ", modularPlusCalBlock.getVariables(), ";"); - for(ModularPlusCalInstance inst: modularPlusCalBlock.getInstances()) { - out.newLine(); - inst.accept(this); - } - out.newLine(); - modularPlusCalBlock.getProcesses().accept(new PlusCalNodeFormattingVisitor(out)); - } - out.newLine(); - out.write("}"); - - return null; - } - - @Override - public Void visit(ModularPlusCalArchetype modularPlusCalArchetype) throws IOException { - out.write("archetype "); - out.write(modularPlusCalArchetype.getName()); - out.write("("); - out.write(modularPlusCalArchetype - .getParams() - .stream() - .map(arg -> (arg.isRef() ? "ref " : "") + arg.getName().getId()) - .collect(Collectors.joining(", "))); - out.write(")"); - if (modularPlusCalArchetype.getVariables().isEmpty()) { - out.write(" "); - } else { - out.write("variables "); - out.write(modularPlusCalArchetype - .getVariables() - .stream() - .map(v -> v.getName() + (v.isSet() ? " \\in " : " = ") + v.getValue().toString()) - .collect(Collectors.joining(", "))); - out.write(";"); - out.newLine(); - } - out.write("{"); - // TODO write body - out.write("}"); - return null; - } - - @Override - public Void visit(ModularPlusCalInstance modularPlusCalInstance) throws IOException { - if (modularPlusCalInstance.getFairness() == PlusCalFairness.WEAK_FAIR) { - out.write("fair "); - } else if (modularPlusCalInstance.getFairness() == PlusCalFairness.STRONG_FAIR) { - out.write("fair+ "); - } - - out.write("process ("); - modularPlusCalInstance.getName().accept(new PlusCalNodeFormattingVisitor(out)); - out.write(")"); - - out.write(" == instance "); - out.write(modularPlusCalInstance.getTarget()); - - out.write("("); - TLAExpressionFormattingVisitor formatter = new TLAExpressionFormattingVisitor(out); - for (int i = 0; i < modularPlusCalInstance.getArguments().size(); i++) { - if (i > 0) { - out.write(", "); - } - - modularPlusCalInstance.getArguments().get(i).accept(formatter); - } - out.write(")"); - - for (ModularPlusCalMapping mapping : modularPlusCalInstance.getMappings()) { - out.newLine(); - out.write("mapping "); - if (mapping.getVariable() instanceof ModularPlusCalMappingVariableName) { - out.write(((ModularPlusCalMappingVariableName) mapping.getVariable()).getName()); - } else if (mapping.getVariable() instanceof ModularPlusCalMappingVariablePosition) { - out.write("@"); - out.write(Integer.toString( - ((ModularPlusCalMappingVariablePosition) mapping.getVariable()).getPosition())); - } else { - throw new Unreachable(); - } - - if (mapping.getVariable().isFunctionCall()) { - out.write("[_]"); - } - - out.write(" via "); - out.write(mapping.getTarget().getName()); - } - - out.write(";"); - - return null; - } - - @Override - public Void visit(ModularPlusCalMappingMacro modularPlusCalMappingMacro) throws IOException { - out.write("mapping macro "); - out.write(modularPlusCalMappingMacro.getName()); - out.write("{"); - - out.newLine(); - out.write("read {"); - try(IndentingWriter.Indent i_ = out.indent()) { - for (PlusCalStatement s : modularPlusCalMappingMacro.getReadBody()) { - out.newLine(); - s.accept(new PlusCalNodeFormattingVisitor(out)); - } - } - out.newLine(); - out.write("}"); - - out.newLine(); - out.write("write {"); - try(IndentingWriter.Indent i_ = out.indent()) { - for (PlusCalStatement s : modularPlusCalMappingMacro.getWriteBody()) { - out.newLine(); - s.accept(new PlusCalNodeFormattingVisitor(out)); - } - } - out.newLine(); - out.write("}"); - - out.newLine(); - out.write("}"); - return null; - } -} diff --git a/src/pgo/model/mpcal/ModularPlusCalNodeVisitor.java b/src/pgo/model/mpcal/ModularPlusCalNodeVisitor.java deleted file mode 100644 index c46b0aefa..000000000 --- a/src/pgo/model/mpcal/ModularPlusCalNodeVisitor.java +++ /dev/null @@ -1,8 +0,0 @@ -package pgo.model.mpcal; - -public abstract class ModularPlusCalNodeVisitor { - public abstract T visit(ModularPlusCalBlock modularPlusCalBlock) throws E; - public abstract T visit(ModularPlusCalArchetype modularPlusCalArchetype) throws E; - public abstract T visit(ModularPlusCalInstance modularPlusCalInstance) throws E; - public abstract T visit(ModularPlusCalMappingMacro modularPlusCalMappingMacro) throws E; -} diff --git a/src/pgo/model/mpcal/ModularPlusCalParam.scala b/src/pgo/model/mpcal/ModularPlusCalParam.scala deleted file mode 100644 index 75675b64a..000000000 --- a/src/pgo/model/mpcal/ModularPlusCalParam.scala +++ /dev/null @@ -1,61 +0,0 @@ -package pgo.model.mpcal - -import pgo.model.tla.{TLADefinitionOne, TLAExpression, TLAIdentifier} -import pgo.scope.UID -import pgo.util.{SourceLocatable, SourceLocation} - -sealed abstract class ModularPlusCalParam(override val getLocation: SourceLocation) extends SourceLocatable { - def getRefersTo: TLADefinitionOne -} - -final class ModularPlusCalParamRef(loc: SourceLocation, val id: TLAIdentifier) extends ModularPlusCalParam(loc) { - private var refersTo: Option[TLADefinitionOne] = None - def setRefersTo(defn: TLADefinitionOne): Unit = { - refersTo match { - case None => refersTo = Some(defn) - case Some(d) => assert(d eq defn) - } - } - def getRefersTo: TLADefinitionOne = refersTo.get - - override def equals(other: Any): Boolean = other match { - case that: ModularPlusCalParamRef => - id == that.id - case _ => false - } - - override def hashCode(): Int = { - val state = Seq(id) - state.map(_.hashCode()).foldLeft(0)((a, b) => 31 * a + b) - } -} - -final class ModularPlusCalParamAnon(loc: SourceLocation, val idx: Int, val expr: TLAExpression) extends ModularPlusCalParam(loc) with TLADefinitionOne { - override val getUID: UID = { - val result = new UID() - result.addOrigin(this) - result - } - - override def getRefersTo: TLADefinitionOne = this - - override def arity: Int = 0 - - override def isModuleInstance: Boolean = false - - override val identifier: TLAIdentifier = new TLAIdentifier(loc, s"@$idx") - - override def scope: Map[TLAIdentifier, TLADefinitionOne] = Map.empty - - override def equals(other: Any): Boolean = other match { - case that: ModularPlusCalParamAnon => - idx == that.idx && - expr == that.expr - case _ => false - } - - override def hashCode(): Int = { - val state = Seq(idx, expr) - state.map(_.hashCode()).foldLeft(0)((a, b) => 31 * a + b) - } -} diff --git a/src/pgo/model/mpcal/ModularPlusCalUnit.java b/src/pgo/model/mpcal/ModularPlusCalUnit.java deleted file mode 100644 index fe7e4e9f8..000000000 --- a/src/pgo/model/mpcal/ModularPlusCalUnit.java +++ /dev/null @@ -1,9 +0,0 @@ -package pgo.model.mpcal; - -import pgo.util.SourceLocation; - -public abstract class ModularPlusCalUnit extends ModularPlusCalNode { - public ModularPlusCalUnit(SourceLocation location) { - super(location); - } -} diff --git a/src/pgo/model/mpcal/ModularPlusCalUtils.scala b/src/pgo/model/mpcal/ModularPlusCalUtils.scala deleted file mode 100644 index 0a671799d..000000000 --- a/src/pgo/model/mpcal/ModularPlusCalUtils.scala +++ /dev/null @@ -1,67 +0,0 @@ -package pgo.model.mpcal - -import pgo.model.pcal.{PlusCalMultiProcess, PlusCalProcessesVisitor, PlusCalSingleProcess, PlusCalUtils, PlusCalVariableDeclaration} -import pgo.model.tla.{TLAIdentifier, TLAUtils} -import pgo.parser.DefinitionLookupError -import pgo.trans.intermediate.DefinitionRegistry - -import scala.jdk.CollectionConverters._ - -object ModularPlusCalUtils { - def fillDefinitionRegistryFromVariableDeclaration(definitionRegistry: DefinitionRegistry, variableDeclaration: PlusCalVariableDeclaration): Unit = { - definitionRegistry.addLocalVariable(variableDeclaration.getUID) - TLAUtils.fillDefinitionRegistryFromExpression(definitionRegistry, variableDeclaration.getValue) - } - - def fillDefinitionRegistryFromModularPlusCalBlock(definitionRegistry: DefinitionRegistry, block: ModularPlusCalBlock): Unit = { - block.variables.foreach { v => - definitionRegistry.addGlobalVariable(v.getUID) - TLAUtils.fillDefinitionRegistryFromExpression(definitionRegistry, v.getValue) - } - block.units.foreach(TLAUtils.fillDefinitionRegistryFromUnit(definitionRegistry,_)) - block.archetypes.foreach { arch => - definitionRegistry.addArchetype(arch) - definitionRegistry.addLocalVariable(arch.getSelfVariableUID) - arch.getParams.asScala.foreach(fillDefinitionRegistryFromVariableDeclaration(definitionRegistry,_)) - arch.getVariables.asScala.foreach(fillDefinitionRegistryFromVariableDeclaration(definitionRegistry,_)) - arch.getBody.asScala.foreach(PlusCalUtils.fillDefinitionRegistryFromStatement(definitionRegistry,_)) - } - block.procedures.foreach { proc => - definitionRegistry.addProcedure(proc) - proc.getParams.asScala.foreach(fillDefinitionRegistryFromVariableDeclaration(definitionRegistry,_)) - proc.getVariables.asScala.foreach(fillDefinitionRegistryFromVariableDeclaration(definitionRegistry,_)) - proc.getBody.asScala.foreach(PlusCalUtils.fillDefinitionRegistryFromStatement(definitionRegistry,_)) - } - block.macros.foreach { m => - m.getBody.asScala.foreach(PlusCalUtils.fillDefinitionRegistryFromStatement(definitionRegistry,_)) - } - block.instances.foreach { i => - fillDefinitionRegistryFromVariableDeclaration(definitionRegistry, i.getName) - val arguments = i.getArguments.asScala - arguments.foreach(TLAUtils.fillDefinitionRegistryFromExpression(definitionRegistry, _)) - i.getMappings.asScala.foreach { mapping => - val v = mapping.getVariable - definitionRegistry.getReferences.put(v.getUID, v.getRefersTo.getUID) - // TODO: ??? - } - } - block.mappingMacros.foreach { m => - definitionRegistry.addMappingMacro(m) - // TODO: other special names - m.getReadBody.asScala.foreach(PlusCalUtils.fillDefinitionRegistryFromStatement(definitionRegistry,_)) - m.getWriteBody.asScala.foreach(PlusCalUtils.fillDefinitionRegistryFromStatement(definitionRegistry,_)) - } - block.processes.accept(new PlusCalProcessesVisitor[Unit,RuntimeException] { - override def visit(singleProcess: PlusCalSingleProcess): Unit = - singleProcess.getBody.asScala.foreach(PlusCalUtils.fillDefinitionRegistryFromStatement(definitionRegistry, _)) - - override def visit(multiProcess: PlusCalMultiProcess): Unit = { - multiProcess.getProcesses.asScala.foreach { proc => - fillDefinitionRegistryFromVariableDeclaration(definitionRegistry, proc.getName) - proc.getVariables.asScala.foreach(fillDefinitionRegistryFromVariableDeclaration(definitionRegistry,_)) - proc.getBody.asScala.foreach(PlusCalUtils.fillDefinitionRegistryFromStatement(definitionRegistry, _)) - } - } - }) - } -} diff --git a/src/pgo/model/mpcal/ModularPlusCalYield.java b/src/pgo/model/mpcal/ModularPlusCalYield.java deleted file mode 100644 index a30ca51be..000000000 --- a/src/pgo/model/mpcal/ModularPlusCalYield.java +++ /dev/null @@ -1,55 +0,0 @@ -package pgo.model.mpcal; - -import pgo.model.pcal.PlusCalStatement; -import pgo.model.pcal.PlusCalStatementVisitor; -import pgo.model.tla.TLAExpression; -import pgo.util.SourceLocation; - -import java.util.Objects; - -/** - * Read statement - * - * yield exp; - * - * where exp may contain $value and $variable - */ -public class ModularPlusCalYield extends PlusCalStatement { - private final TLAExpression expression; - - public ModularPlusCalYield(SourceLocation location, TLAExpression expression) { - super(location); - this.expression = expression; - } - - @Override - public ModularPlusCalYield copy() { - return new ModularPlusCalYield(getLocation(), expression.copy()); - } - - @Override - public int hashCode() { - return Objects.hash(expression); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null || obj.getClass() != getClass()) { - return false; - } - ModularPlusCalYield that = (ModularPlusCalYield) obj; - return expression.equals(that.expression); - } - - @Override - public T accept(PlusCalStatementVisitor v) throws E { - return v.visit(this); - } - - public TLAExpression getExpression() { - return expression; - } -} diff --git a/src/pgo/model/pcal/AST.scala b/src/pgo/model/pcal/AST.scala new file mode 100644 index 000000000..ba5436816 --- /dev/null +++ b/src/pgo/model/pcal/AST.scala @@ -0,0 +1,175 @@ +package pgo.model.pcal + +import pgo.model.RefersTo.Renamer +import pgo.model.{Definition, DefinitionOne, RefersTo, Rewritable, SourceLocatable, Visitable} +import pgo.model.tla._ +import pgo.util.IdMap + + +sealed abstract class PCalNode extends Rewritable with Visitable with SourceLocatable { + override def decorateLike(succ: this.type): this.type = + super.decorateLike(succ.setSourceLocation(sourceLocation)) +} + +sealed abstract class PCalFairness +object PCalFairness { + case object Unfair extends PCalFairness + case object WeakFair extends PCalFairness + case object StrongFair extends PCalFairness +} + +final case class PCalDefaultInitValue() extends PCalNode + +final case class PCalAlgorithm(fairness: PCalFairness, name: TLAIdentifier, variables: List[PCalVariableDeclaration], + units: List[TLAUnit], macros: List[PCalMacro], procedures: List[PCalProcedure], + processes: Either[List[PCalStatement],List[PCalProcess]]) extends PCalNode { + override def mapChildren(fn: Any => Any): this.type = { + val renamer = new Renamer[Rewritable]() + val mappedName = fn(name) + val mappedVariables = renamer.mapConserveRenamingAny(variables, fn) + val mappedUnits = renamer.mapConserveRenamingAny(units, fn) + var mappedMacros = macros.mapConserve(renamer.captureRenamingAny(_, fn)) + var mappedProcedures = procedures.mapConserve(renamer.captureRenamingAny(_, fn)) + // macros and procedures are mutually referential, so we have to apply any renamings using a special strategy + if((mappedMacros ne macros) || (mappedProcedures ne procedures)) { + def duplicator[N <: Rewritable](n: N): N = + n.rewrite() { + case call @PCalCall(_, _) => call.shallowCopy() + case macroCall @PCalMacroCall(_, _) => macroCall.shallowCopy() + } + mappedMacros = mappedMacros.mapConserve(renamer.captureRenaming(_, duplicator[PCalMacro])) + mappedProcedures = mappedProcedures.mapConserve(renamer.captureRenaming(_, duplicator[PCalProcedure])) + val macroMap = (macros.view zip mappedMacros).to(IdMap) + val procMap = (procedures.view zip mappedProcedures).to(IdMap) + def referenceFixer[N <: Visitable](n: N): Unit = + n.visit() { + case call @PCalCall(_, _) => call.setRefersTo(procMap(call.refersTo)) + case macroCall @PCalMacroCall(_, _) => macroCall.setRefersTo(macroMap(macroCall.refersTo)) + } + mappedMacros.foreach(referenceFixer(_)) + mappedProcedures.foreach(referenceFixer(_)) + } + val mappedProcesses = processes match { + case Left(body) => + val mappedBody = body.mapConserve(stmt => fn(renamer(stmt)).asInstanceOf[PCalStatement]) + if(mappedBody ne body) { + Left(mappedBody) + } else processes + case Right(processes) => + val mappedProcesses = processes.mapConserve(process => fn(renamer(process)).asInstanceOf[PCalProcess]) + if(mappedProcesses ne processes) { + Right(mappedProcesses) + } else processes + } + withChildren(Iterator(fairness, mappedName, mappedVariables, mappedUnits, mappedMacros, mappedProcedures, mappedProcesses)) + } +} + +final case class PCalPVariableDeclaration(name: TLAIdentifier, value: Option[TLAExpression]) extends PCalNode with DefinitionOne { + override def arity: Int = 0 + override def identifier: Definition.ScopeIdentifier = Definition.ScopeIdentifierName(name) +} + +sealed abstract class PCalVariableDeclaration extends PCalNode with DefinitionOne { + def name: TLAIdentifier + override def arity: Int = 0 + override def identifier: Definition.ScopeIdentifier = Definition.ScopeIdentifierName(name) +} + +final case class PCalVariableDeclarationEmpty(name: TLAIdentifier) extends PCalVariableDeclaration + +sealed abstract class PCalVariableDeclarationBound extends PCalVariableDeclaration +final case class PCalVariableDeclarationValue(name: TLAIdentifier, value: TLAExpression) extends PCalVariableDeclarationBound +final case class PCalVariableDeclarationSet(name: TLAIdentifier, set: TLAExpression) extends PCalVariableDeclarationBound + +final case class PCalMacro(name: TLAIdentifier, params: List[TLADefiningIdentifier], body: List[PCalStatement], + freeVars: List[TLADefiningIdentifier]) extends PCalNode { + override def mapChildren(fn: Any => Any): this.type = { + val renamer = new Renamer[TLADefiningIdentifier]() + val mappedName = fn(name) + val mappedFreeVars = renamer.mapConserveRenamingAny(freeVars, fn) + val mappedParams = renamer.mapConserveRenamingAny(params, fn) + val mappedBody = body.mapConserve(stmt => fn(renamer(stmt)).asInstanceOf[PCalStatement]) + withChildren(Iterator(mappedName, mappedParams, mappedBody, mappedFreeVars)) + } +} + +final case class PCalProcedure(name: TLAIdentifier, params: List[PCalPVariableDeclaration], + variables: List[PCalPVariableDeclaration], body: List[PCalStatement]) extends PCalNode { + override def mapChildren(fn: Any => Any): this.type = { + val renamer = new Renamer[DefinitionOne with Rewritable]() + val mappedName = fn(name).asInstanceOf[TLAIdentifier] + val mappedParams = renamer.mapConserveRenamingAny(params, fn) + val mappedVariables = renamer.mapConserveRenamingAny(variables, fn) + val mappedBody = body.mapConserve(stmt => fn(renamer(stmt)).asInstanceOf[PCalStatement]) + withChildren(Iterator(mappedName, mappedParams, mappedVariables, mappedBody)) + } +} + +final case class PCalProcess(selfDecl: PCalVariableDeclarationBound, fairness: PCalFairness, + variables: List[PCalVariableDeclaration], body: List[PCalStatement]) extends PCalNode { + override def mapChildren(fn: Any => Any): this.type = { + val renamer = new Renamer[PCalVariableDeclaration]() + val mappedSelfDecl = renamer.captureRenamingAny(selfDecl, fn) + val mappedVariables = renamer.mapConserveRenamingAny(variables, fn) + val mappedBody = body.mapConserve(stmt => fn(renamer(stmt)).asInstanceOf[PCalStatement]) + withChildren(Iterator(mappedSelfDecl, fairness, mappedVariables, mappedBody)) + } +} + +sealed abstract class PCalStatement extends PCalNode + +final case class PCalExtensionStatement(contents: Any) extends PCalStatement + +final case class PCalAssert(condition: TLAExpression) extends PCalStatement + +final case class PCalAssignment(pairs: List[PCalAssignmentPair]) extends PCalStatement + +final case class PCalAssignmentPair(lhs: PCalAssignmentLhs, rhs: TLAExpression) extends PCalNode + +sealed abstract class PCalAssignmentLhs extends PCalNode +final case class PCalAssignmentLhsIdentifier(identifier: TLAIdentifier) extends PCalAssignmentLhs with RefersTo[DefinitionOne] +final case class PCalAssignmentLhsProjection(lhs: PCalAssignmentLhs, projections: List[TLAExpression]) extends PCalAssignmentLhs +final case class PCalAssignmentLhsExtension(contents: Any) extends PCalAssignmentLhs + +final case class PCalAwait(condition: TLAExpression) extends PCalStatement + +final case class PCalCall(target: TLAIdentifier, arguments: List[TLAExpression]) extends PCalStatement with RefersTo[PCalProcedure] + +final case class PCalEither(cases: List[List[PCalStatement]]) extends PCalStatement { + require(cases.nonEmpty, s"either must have at least one case") +} + +// target is a string, because it would be much to hard to integrate gotos (which can reference any local label) into RefersTo +final case class PCalGoto(target: String) extends PCalStatement + +final case class PCalIf(condition: TLAExpression, yes: List[PCalStatement], no: List[PCalStatement]) extends PCalStatement + +final case class PCalLabel(name: String, modifier: PCalLabel.Modifier) extends PCalNode +object PCalLabel { + sealed abstract class Modifier + case object PlusModifier extends Modifier + case object MinusModifier extends Modifier + case object NoModifier extends Modifier +} + +final case class PCalLabeledStatements(label: PCalLabel, statements: List[PCalStatement]) extends PCalStatement + +final case class PCalMacroCall(target: TLAIdentifier, arguments: List[TLAExpression]) extends PCalStatement with RefersTo[PCalMacro] + +final case class PCalPrint(value: TLAExpression) extends PCalStatement + +final case class PCalReturn() extends PCalStatement + +final case class PCalSkip() extends PCalStatement + +final case class PCalWhile(condition: TLAExpression, body: List[PCalStatement]) extends PCalStatement + +final case class PCalWith(variables: List[PCalVariableDeclarationBound], body: List[PCalStatement]) extends PCalStatement { + override def mapChildren(fn: Any => Any): this.type = { + val renamer = new Renamer[PCalVariableDeclarationBound]() + val mappedVariables = renamer.mapConserveRenamingAny(variables, fn) + val mappedBody = body.mapConserve(bodyStmt => fn(renamer(bodyStmt)).asInstanceOf[PCalStatement]) + withChildren(Iterator(mappedVariables, mappedBody)) + } +} diff --git a/src/pgo/model/pcal/PlusCalAlgorithm.java b/src/pgo/model/pcal/PlusCalAlgorithm.java deleted file mode 100644 index 292e00ace..000000000 --- a/src/pgo/model/pcal/PlusCalAlgorithm.java +++ /dev/null @@ -1,98 +0,0 @@ -package pgo.model.pcal; - -import pgo.model.tla.TLAIdentifier; -import pgo.model.tla.TLAUnit; -import pgo.util.SourceLocation; - -import java.util.List; -import java.util.Objects; -import java.util.stream.Collectors; - -public class PlusCalAlgorithm extends PlusCalNode { - - private final TLAIdentifier name; - - private final PlusCalFairness fairness; - private final List variables; - private final List macros; - private final List procedures; - private final List units; - - private final PlusCalProcesses processes; - - public PlusCalAlgorithm(SourceLocation location, PlusCalFairness fairness, TLAIdentifier name, - List variables, List macros, - List procedures, List units, PlusCalProcesses processes) { - super(location); - this.fairness = fairness; - this.name = name; - this.variables = variables; - this.macros = macros; - this.procedures = procedures; - this.units = units; - this.processes = processes; - } - - @Override - public PlusCalAlgorithm copy() { - return new PlusCalAlgorithm( - getLocation(), - fairness, - name, - variables.stream().map(PlusCalVariableDeclaration::copy).collect(Collectors.toList()), - macros.stream().map(PlusCalMacro::copy).collect(Collectors.toList()), - procedures.stream().map(PlusCalProcedure::copy).collect(Collectors.toList()), - units.stream().map(TLAUnit::copy).collect(Collectors.toList()), - processes.copy()); - } - - public PlusCalFairness getFairness() { return fairness; } - - public TLAIdentifier getName() { - return name; - } - - public List getVariables() { - return variables; - } - - public List getMacros() { - return macros; - } - - public List getProcedures() { - return procedures; - } - - public List getUnits(){ - return units; - } - - public PlusCalProcesses getProcesses() { - return processes; - } - - @Override - public T accept(PlusCalNodeVisitor v) throws E{ - return v.visit(this); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - PlusCalAlgorithm that = (PlusCalAlgorithm) o; - return Objects.equals(name, that.name) && - fairness == that.fairness && - Objects.equals(variables, that.variables) && - Objects.equals(macros, that.macros) && - Objects.equals(procedures, that.procedures) && - Objects.equals(units, that.units) && - Objects.equals(processes, that.processes); - } - - @Override - public int hashCode() { - return Objects.hash(name, fairness, variables, macros, procedures, units, processes); - } -} diff --git a/src/pgo/model/pcal/PlusCalAssert.java b/src/pgo/model/pcal/PlusCalAssert.java deleted file mode 100644 index bbbfc8628..000000000 --- a/src/pgo/model/pcal/PlusCalAssert.java +++ /dev/null @@ -1,51 +0,0 @@ -package pgo.model.pcal; - -import pgo.model.tla.TLAExpression; -import pgo.util.SourceLocation; - -public class PlusCalAssert extends PlusCalStatement { - - private final TLAExpression condition; - - public PlusCalAssert(SourceLocation location, TLAExpression condition) { - super(location); - this.condition = condition; - } - - public TLAExpression getCondition() { - return condition; - } - - @Override - public PlusCalAssert copy() { - return new PlusCalAssert(getLocation(), condition.copy()); - } - - @Override - public T accept(PlusCalStatementVisitor v) throws E { - return v.visit(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((condition == null) ? 0 : condition.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; - PlusCalAssert other = (PlusCalAssert) obj; - if (condition == null) { - return other.condition == null; - } else return condition.equals(other.condition); - } - -} diff --git a/src/pgo/model/pcal/PlusCalAssignment.java b/src/pgo/model/pcal/PlusCalAssignment.java deleted file mode 100644 index ac2042faa..000000000 --- a/src/pgo/model/pcal/PlusCalAssignment.java +++ /dev/null @@ -1,53 +0,0 @@ -package pgo.model.pcal; - -import pgo.util.SourceLocation; - -import java.util.List; -import java.util.stream.Collectors; - -public class PlusCalAssignment extends PlusCalStatement { - - private final List pairs; - - public PlusCalAssignment(SourceLocation location, List pairs) { - super(location); - this.pairs = pairs; - } - - @Override - public PlusCalAssignment copy() { - return new PlusCalAssignment(getLocation(), pairs.stream().map(PlusCalAssignmentPair::copy).collect(Collectors.toList())); - } - - public List getPairs() { - return pairs; - } - - @Override - public T accept(PlusCalStatementVisitor v) throws E { - return v.visit(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((pairs == null) ? 0 : pairs.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; - PlusCalAssignment other = (PlusCalAssignment) obj; - if (pairs == null) { - return other.pairs == null; - } else return pairs.equals(other.pairs); - } - -} diff --git a/src/pgo/model/pcal/PlusCalAssignmentPair.java b/src/pgo/model/pcal/PlusCalAssignmentPair.java deleted file mode 100644 index 2d322f59a..000000000 --- a/src/pgo/model/pcal/PlusCalAssignmentPair.java +++ /dev/null @@ -1,63 +0,0 @@ -package pgo.model.pcal; - -import pgo.model.tla.TLAExpression; -import pgo.util.SourceLocation; - -public class PlusCalAssignmentPair extends PlusCalNode { - - private final TLAExpression lhs; - private final TLAExpression rhs; - - public PlusCalAssignmentPair(SourceLocation location, TLAExpression lhs, TLAExpression rhs) { - super(location); - this.lhs = lhs; - this.rhs = rhs; - } - - public TLAExpression getLhs() { - return lhs; - } - - public TLAExpression getRhs() { - return rhs; - } - - @Override - public PlusCalAssignmentPair copy() { - return new PlusCalAssignmentPair(getLocation(), lhs.copy(), rhs.copy()); - } - - @Override - public T accept(PlusCalNodeVisitor v) throws E { - return v.visit(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((lhs == null) ? 0 : lhs.hashCode()); - result = prime * result + ((rhs == null) ? 0 : rhs.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; - PlusCalAssignmentPair other = (PlusCalAssignmentPair) obj; - if (lhs == null) { - if (other.lhs != null) - return false; - } else if (!lhs.equals(other.lhs)) - return false; - if (rhs == null) { - return other.rhs == null; - } else return rhs.equals(other.rhs); - } - -} diff --git a/src/pgo/model/pcal/PlusCalAwait.java b/src/pgo/model/pcal/PlusCalAwait.java deleted file mode 100644 index b7c17324e..000000000 --- a/src/pgo/model/pcal/PlusCalAwait.java +++ /dev/null @@ -1,51 +0,0 @@ -package pgo.model.pcal; - -import pgo.model.tla.TLAExpression; -import pgo.util.SourceLocation; - -public class PlusCalAwait extends PlusCalStatement { - - private final TLAExpression condition; - - public PlusCalAwait(SourceLocation location, TLAExpression condition) { - super(location); - this.condition = condition; - } - - @Override - public PlusCalAwait copy() { - return new PlusCalAwait(getLocation(), condition.copy()); - } - - public TLAExpression getCondition() { - return condition; - } - - @Override - public T accept(PlusCalStatementVisitor v) throws E { - return v.visit(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((condition == null) ? 0 : condition.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; - PlusCalAwait other = (PlusCalAwait) obj; - if (condition == null) { - return other.condition == null; - } else return condition.equals(other.condition); - } - -} diff --git a/src/pgo/model/pcal/PlusCalBuilder.java b/src/pgo/model/pcal/PlusCalBuilder.java deleted file mode 100644 index bbc8ec8b5..000000000 --- a/src/pgo/model/pcal/PlusCalBuilder.java +++ /dev/null @@ -1,133 +0,0 @@ -package pgo.model.pcal; - -import pgo.model.mpcal.*; -import pgo.model.tla.*; -import pgo.util.SourceLocation; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.stream.Collectors; - -import static pgo.model.tla.TLABuilder.id; - -public class PlusCalBuilder { - private PlusCalBuilder() {} - - public static PlusCalDefaultInitValue PLUSCAL_DEFAULT_INIT_VALUE = new PlusCalDefaultInitValue(SourceLocation.unknown()); - - public static PlusCalAlgorithm algorithm(String name, List vars, List macros, List procedures, List units, PlusCalLabeledStatements... statements) { - return new PlusCalAlgorithm(SourceLocation.unknown(), PlusCalFairness.UNFAIR, - new TLAIdentifier(SourceLocation.unknown(), name), vars, macros, procedures, units, - new PlusCalSingleProcess(SourceLocation.unknown(), Arrays.asList(statements))); - } - - public static PlusCalAlgorithm algorithm(String name, List vars, List macros, List procedures, List units, PlusCalProcess... processes) { - return new PlusCalAlgorithm(SourceLocation.unknown(), PlusCalFairness.UNFAIR, - new TLAIdentifier(SourceLocation.unknown(), name), vars, macros, procedures, units, - new PlusCalMultiProcess(SourceLocation.unknown(), Arrays.asList(processes))); - } - - public static PlusCalVariableDeclaration pcalVarDecl(String name, boolean isRef, boolean isSet, - TLAExpression value) { - return new PlusCalVariableDeclaration( - SourceLocation.unknown(), new TLAIdentifier(SourceLocation.unknown(), name), isRef, isSet, value); - } - - public static PlusCalMacro macro(String name, List params, PlusCalStatement... statements) { - return new PlusCalMacro( - SourceLocation.unknown(), name, - params.stream() - .map(TLABuilder::id) - .collect(Collectors.toList()), - Arrays.asList(statements)); - } - - public static PlusCalProcedure procedure(String name, List params, - List vars, PlusCalStatement... statements) { - return new PlusCalProcedure(SourceLocation.unknown(), name, params, vars, Arrays.asList(statements)); - } - - public static PlusCalProcess process(PlusCalVariableDeclaration name, PlusCalFairness fairness, - List vars, PlusCalStatement... statements) { - return new PlusCalProcess(SourceLocation.unknown(), name, fairness, vars, Arrays.asList(statements)); - } - - public static PlusCalLabel label(String name) { - return new PlusCalLabel(SourceLocation.unknown(), name, PlusCalLabel.Modifier.NONE); - } - - public static PlusCalLabeledStatements labeled(PlusCalLabel label, PlusCalStatement... statements) { - return new PlusCalLabeledStatements(SourceLocation.unknown(), label, Arrays.asList(statements)); - } - - public static PlusCalMacroCall macroCall(String name, TLAExpression... args) { - return new PlusCalMacroCall(SourceLocation.unknown(), name, Arrays.asList(args)); - } - - public static PlusCalCall call(String target, TLAExpression... args) { - return new PlusCalCall(SourceLocation.unknown(), target, Arrays.asList(args)); - } - - public static PlusCalReturn returnS() { - return new PlusCalReturn(SourceLocation.unknown()); - } - - public static PlusCalGoto gotoS(String target) { - return new PlusCalGoto(SourceLocation.unknown(), target); - } - - public static PlusCalAssignment assign(TLAExpression... expressions) { - if ((expressions.length % 2) != 0) { - throw new RuntimeException("assign requires an even number of TLA+ expressions"); - } - - List pairs = new ArrayList<>(); - - int i = 0; - TLAExpression lhs = null; - for (TLAExpression e : expressions) { - if (i == 0) { - lhs = e; - i++; - } else { - pairs.add(new PlusCalAssignmentPair(SourceLocation.unknown(), lhs, e)); - i = 0; - } - } - - return new PlusCalAssignment(SourceLocation.unknown(), pairs); - } - - public static PlusCalIf ifS (TLAExpression condition, List yes, List no) { - return new PlusCalIf(SourceLocation.unknown(), condition, yes, no); - } - - public static PlusCalPrint printS(TLAExpression expr) { - return new PlusCalPrint(SourceLocation.unknown(), expr); - } - - public static PlusCalWhile whileS(TLAExpression condition, List body) { - return new PlusCalWhile(SourceLocation.unknown(), condition, body); - } - - public static PlusCalWith with(List variables, PlusCalStatement... statements) { - return new PlusCalWith(SourceLocation.unknown(), variables, Arrays.asList(statements)); - } - - public static PlusCalEither either(List> cases) { - return new PlusCalEither(SourceLocation.unknown(), cases); - } - - public static PlusCalAwait await(TLAExpression cond) { - return new PlusCalAwait(SourceLocation.unknown(), cond); - } - - public static PlusCalSkip skip() { - return new PlusCalSkip(SourceLocation.unknown()); - } - - public static ModularPlusCalYield yield(TLAExpression expr) { - return new ModularPlusCalYield(SourceLocation.unknown(), expr); - } -} diff --git a/src/pgo/model/pcal/PlusCalCall.java b/src/pgo/model/pcal/PlusCalCall.java deleted file mode 100644 index 1d5c59ddb..000000000 --- a/src/pgo/model/pcal/PlusCalCall.java +++ /dev/null @@ -1,65 +0,0 @@ -package pgo.model.pcal; - -import pgo.model.tla.TLAExpression; -import pgo.util.SourceLocation; - -import java.util.List; -import java.util.stream.Collectors; - -public class PlusCalCall extends PlusCalStatement { - private final String target; - private final List arguments; - - public PlusCalCall(SourceLocation location, String target, List arguments) { - super(location); - this.target = target; - this.arguments = arguments; - } - - @Override - public PlusCalCall copy() { - return new PlusCalCall(getLocation(), target, arguments.stream().map(TLAExpression::copy).collect(Collectors.toList())); - } - - public String getTarget() { - return target; - } - - public List getArguments(){ - return arguments; - } - - @Override - public T accept(PlusCalStatementVisitor v) throws E { - return v.visit(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((arguments == null) ? 0 : arguments.hashCode()); - result = prime * result + ((target == null) ? 0 : target.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; - PlusCalCall other = (PlusCalCall) obj; - if (arguments == null) { - if (other.arguments != null) - return false; - } else if (!arguments.equals(other.arguments)) - return false; - if (target == null) { - return other.target == null; - } else return target.equals(other.target); - } - -} diff --git a/src/pgo/model/pcal/PlusCalEither.java b/src/pgo/model/pcal/PlusCalEither.java deleted file mode 100644 index 3e8ded8dc..000000000 --- a/src/pgo/model/pcal/PlusCalEither.java +++ /dev/null @@ -1,60 +0,0 @@ -package pgo.model.pcal; - -import pgo.util.SourceLocation; - -import java.util.List; -import java.util.Objects; -import java.util.stream.Collectors; - -public class PlusCalEither extends PlusCalStatement { - - private final List> cases; - - public PlusCalEither(SourceLocation location, List> cases) { - super(location); - this.cases = cases; - } - - @Override - public PlusCalEither copy() { - return new PlusCalEither( - getLocation(), - cases.stream() - .map(stmts -> stmts.stream().map(PlusCalStatement::copy).collect(Collectors.toList())) - .collect(Collectors.toList())); - } - - public List> getCases(){ - return cases; - } - - @Override - public T accept(PlusCalStatementVisitor v) throws E { - return v.visit(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((cases == null) ? 0 : cases.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - PlusCalEither other = (PlusCalEither) obj; - if (cases == null) { - return other.cases == null; - } else { - return Objects.equals(cases, other.cases); - } - } - -} diff --git a/src/pgo/model/pcal/PlusCalFairness.java b/src/pgo/model/pcal/PlusCalFairness.java deleted file mode 100644 index c0bc0cdee..000000000 --- a/src/pgo/model/pcal/PlusCalFairness.java +++ /dev/null @@ -1,7 +0,0 @@ -package pgo.model.pcal; - -public enum PlusCalFairness { - UNFAIR, - WEAK_FAIR, - STRONG_FAIR, -} diff --git a/src/pgo/model/pcal/PlusCalGoto.java b/src/pgo/model/pcal/PlusCalGoto.java deleted file mode 100644 index 9f2a71432..000000000 --- a/src/pgo/model/pcal/PlusCalGoto.java +++ /dev/null @@ -1,50 +0,0 @@ -package pgo.model.pcal; - -import pgo.util.SourceLocation; - -public class PlusCalGoto extends PlusCalStatement { - - private final String target; - - public PlusCalGoto(SourceLocation location, String target) { - super(location); - this.target = target; - } - - @Override - public PlusCalGoto copy() { - return new PlusCalGoto(getLocation(), target); - } - - public String getTarget() { - return target; - } - - @Override - public T accept(PlusCalStatementVisitor v) throws E { - return v.visit(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((target == null) ? 0 : target.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; - PlusCalGoto other = (PlusCalGoto) obj; - if (target == null) { - return other.target == null; - } else return target.equals(other.target); - } - -} diff --git a/src/pgo/model/pcal/PlusCalIf.java b/src/pgo/model/pcal/PlusCalIf.java deleted file mode 100644 index 5c119be2c..000000000 --- a/src/pgo/model/pcal/PlusCalIf.java +++ /dev/null @@ -1,80 +0,0 @@ -package pgo.model.pcal; - -import pgo.model.tla.TLAExpression; -import pgo.util.SourceLocation; - -import java.util.List; -import java.util.stream.Collectors; - -public class PlusCalIf extends PlusCalStatement { - - private final TLAExpression condition; - private final List yes; - private final List no; - - public PlusCalIf(SourceLocation location, TLAExpression condition, List yes, List no) { - super(location); - this.condition = condition; - this.yes = yes; - this.no = no; - } - - @Override - public PlusCalIf copy() { - return new PlusCalIf(getLocation(), condition.copy(), - yes.stream().map(PlusCalStatement::copy).collect(Collectors.toList()), - no.stream().map(PlusCalStatement::copy).collect(Collectors.toList())); - } - - public TLAExpression getCondition() { - return condition; - } - - public List getYes(){ - return yes; - } - - public List getNo(){ - return no; - } - - @Override - public T accept(PlusCalStatementVisitor v) throws E { - return v.visit(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((condition == null) ? 0 : condition.hashCode()); - result = prime * result + ((no == null) ? 0 : no.hashCode()); - result = prime * result + ((yes == null) ? 0 : yes.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; - PlusCalIf other = (PlusCalIf) obj; - if (condition == null) { - if (other.condition != null) - return false; - } else if (!condition.equals(other.condition)) - return false; - if (no == null) { - if (other.no != null) - return false; - } else if (!no.equals(other.no)) - return false; - if (yes == null) { - return other.yes == null; - } else return yes.equals(other.yes); - } - -} diff --git a/src/pgo/model/pcal/PlusCalLabel.java b/src/pgo/model/pcal/PlusCalLabel.java deleted file mode 100644 index 0c4efae8c..000000000 --- a/src/pgo/model/pcal/PlusCalLabel.java +++ /dev/null @@ -1,63 +0,0 @@ -package pgo.model.pcal; - -import pgo.util.SourceLocation; - -public class PlusCalLabel extends PlusCalNode { - String name; - Modifier modifier; - - public enum Modifier{ - PLUS, - MINUS, - NONE, - } - - public PlusCalLabel(SourceLocation location, String name, Modifier modifier) { - super(location); - this.name = name; - this.modifier = modifier; - } - - @Override - public PlusCalLabel copy() { - return new PlusCalLabel(getLocation(), name, modifier); - } - - public String getName() { - return name; - } - - public Modifier getModifier() { - return modifier; - } - - @Override - public T accept(PlusCalNodeVisitor v) throws E{ - return v.visit(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((modifier == null) ? 0 : modifier.hashCode()); - result = prime * result + ((name == null) ? 0 : name.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; - PlusCalLabel other = (PlusCalLabel) obj; - if (modifier != other.modifier) - return false; - if (name == null) { - return other.name == null; - } else return name.equals(other.name); - } -} diff --git a/src/pgo/model/pcal/PlusCalLabeledStatements.java b/src/pgo/model/pcal/PlusCalLabeledStatements.java deleted file mode 100644 index dbbe9586b..000000000 --- a/src/pgo/model/pcal/PlusCalLabeledStatements.java +++ /dev/null @@ -1,65 +0,0 @@ -package pgo.model.pcal; - -import pgo.util.SourceLocation; - -import java.util.List; -import java.util.stream.Collectors; - -public class PlusCalLabeledStatements extends PlusCalStatement { - - private final PlusCalLabel label; - private final List statements; - - public PlusCalLabeledStatements(SourceLocation location, PlusCalLabel label, List statements) { - super(location); - this.label = label; - this.statements = statements; - } - - @Override - public PlusCalLabeledStatements copy() { - return new PlusCalLabeledStatements(getLocation(), label.copy(), statements.stream().map(PlusCalStatement::copy).collect(Collectors.toList())); - } - - public PlusCalLabel getLabel() { - return label; - } - - public List getStatements(){ - return statements; - } - - @Override - public T accept(PlusCalStatementVisitor v) throws E { - return v.visit(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((label == null) ? 0 : label.hashCode()); - result = prime * result + ((statements == null) ? 0 : statements.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; - PlusCalLabeledStatements other = (PlusCalLabeledStatements) obj; - if (label == null) { - if (other.label != null) - return false; - } else if (!label.equals(other.label)) - return false; - if (statements == null) { - return other.statements == null; - } else return statements.equals(other.statements); - } - -} diff --git a/src/pgo/model/pcal/PlusCalMacro.java b/src/pgo/model/pcal/PlusCalMacro.java deleted file mode 100644 index 285caa699..000000000 --- a/src/pgo/model/pcal/PlusCalMacro.java +++ /dev/null @@ -1,93 +0,0 @@ -package pgo.model.pcal; - -import pgo.model.mpcal.ModularPlusCalBlockVisitor; -import pgo.model.tla.TLAIdentifier; -import pgo.util.SourceLocation; - -import java.util.ArrayList; -import java.util.List; -import java.util.stream.Collectors; - -public class PlusCalMacro extends PlusCalNode { - private final String name; - private final List params; - private final List body; - - public PlusCalMacro(SourceLocation location, String name, List params, List body) { - super(location); - this.name = name; - this.params = params; - this.body = body; - } - - @Override - public PlusCalMacro copy() { - return new PlusCalMacro( - getLocation(), - name, - new ArrayList<>(params), - body.stream().map(PlusCalStatement::copy).collect(Collectors.toList())); - } - - public String getName() { - return name; - } - - public List getParams() { - return params; - } - - public List getParamIds(){ - return params.stream() - .map(TLAIdentifier::getId) - .collect(Collectors.toList()); - } - - public List getBody(){ - return body; - } - - @Override - public T accept(PlusCalNodeVisitor v) throws E{ - return v.visit(this); - } - - public T accept(ModularPlusCalBlockVisitor v) throws E{ - return v.visit(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((body == null) ? 0 : body.hashCode()); - result = prime * result + ((name == null) ? 0 : name.hashCode()); - result = prime * result + ((params == null) ? 0 : params.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; - PlusCalMacro other = (PlusCalMacro) obj; - if (body == null) { - if (other.body != null) - return false; - } else if (!body.equals(other.body)) - return false; - if (name == null) { - if (other.name != null) - return false; - } else if (!name.equals(other.name)) - return false; - if (params == null) { - return other.params == null; - } else return params.equals(other.params); - } - -} diff --git a/src/pgo/model/pcal/PlusCalMacroCall.java b/src/pgo/model/pcal/PlusCalMacroCall.java deleted file mode 100644 index 71ea2e5ed..000000000 --- a/src/pgo/model/pcal/PlusCalMacroCall.java +++ /dev/null @@ -1,65 +0,0 @@ -package pgo.model.pcal; - -import pgo.model.tla.TLAExpression; -import pgo.util.SourceLocation; - -import java.util.List; -import java.util.stream.Collectors; - -public class PlusCalMacroCall extends PlusCalStatement { - private final String target; - private final List arguments; - - public PlusCalMacroCall(SourceLocation location, String target, List arguments) { - super(location); - this.target = target; - this.arguments = arguments; - } - - @Override - public PlusCalMacroCall copy() { - return new PlusCalMacroCall(getLocation(), target, arguments.stream().map(TLAExpression::copy).collect(Collectors.toList())); - } - - public String getTarget() { - return target; - } - - public List getArguments(){ - return arguments; - } - - @Override - public T accept(PlusCalStatementVisitor v) throws E { - return v.visit(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((arguments == null) ? 0 : arguments.hashCode()); - result = prime * result + ((target == null) ? 0 : target.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; - PlusCalMacroCall other = (PlusCalMacroCall) obj; - if (arguments == null) { - if (other.arguments != null) - return false; - } else if (!arguments.equals(other.arguments)) - return false; - if (target == null) { - return other.target == null; - } else return target.equals(other.target); - } - -} diff --git a/src/pgo/model/pcal/PlusCalMultiProcess.java b/src/pgo/model/pcal/PlusCalMultiProcess.java deleted file mode 100644 index 185640aee..000000000 --- a/src/pgo/model/pcal/PlusCalMultiProcess.java +++ /dev/null @@ -1,58 +0,0 @@ -package pgo.model.pcal; - -import pgo.model.mpcal.ModularPlusCalBlockVisitor; -import pgo.util.SourceLocation; - -import java.util.List; -import java.util.stream.Collectors; - -public class PlusCalMultiProcess extends PlusCalProcesses { - - private final List processes; - - public PlusCalMultiProcess(SourceLocation location, List processes) { - super(location); - this.processes = processes; - } - - @Override - public PlusCalMultiProcess copy() { - return new PlusCalMultiProcess(getLocation(), processes.stream().map(PlusCalProcess::copy).collect(Collectors.toList())); - } - - public List getProcesses(){ - return processes; - } - - @Override - public T accept(PlusCalProcessesVisitor v) throws E { - return v.visit(this); - } - - public T accept(ModularPlusCalBlockVisitor v) throws E { - return v.visit(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((processes == null) ? 0 : processes.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; - PlusCalMultiProcess other = (PlusCalMultiProcess) obj; - if (processes == null) { - return other.processes == null; - } else return processes.equals(other.processes); - } - -} diff --git a/src/pgo/model/pcal/PlusCalNode.java b/src/pgo/model/pcal/PlusCalNode.java deleted file mode 100644 index 0bba85728..000000000 --- a/src/pgo/model/pcal/PlusCalNode.java +++ /dev/null @@ -1,55 +0,0 @@ -package pgo.model.pcal; - -import pgo.Unreachable; -import pgo.formatters.IndentingWriter; -import pgo.formatters.PlusCalNodeFormattingVisitor; -import pgo.scope.UID; -import pgo.util.SourceLocatable; -import pgo.util.SourceLocation; - -import java.io.IOException; -import java.io.StringWriter; - -public abstract class PlusCalNode extends SourceLocatable { - - private final SourceLocation location; - private final UID uid; - - public PlusCalNode(SourceLocation location) { - this.location = location; - this.uid = new UID(); - this.uid.addOrigin(this); - } - - public abstract PlusCalNode copy(); - - @Override - public SourceLocation getLocation() { - return location; - } - - public UID getUID() { - return uid; - } - - @Override - public abstract int hashCode(); - - @Override - public abstract boolean equals(Object obj); - - public abstract T accept(PlusCalNodeVisitor v) throws E; - - @Override - public String toString() { - StringWriter w = new StringWriter(); - IndentingWriter out = new IndentingWriter(w); - try { - accept(new PlusCalNodeFormattingVisitor(out)); - } catch (IOException e) { - throw new Unreachable(e); - } - return w.toString(); - } - -} diff --git a/src/pgo/model/pcal/PlusCalNodeVisitor.java b/src/pgo/model/pcal/PlusCalNodeVisitor.java deleted file mode 100644 index d7867caa5..000000000 --- a/src/pgo/model/pcal/PlusCalNodeVisitor.java +++ /dev/null @@ -1,15 +0,0 @@ -package pgo.model.pcal; - -public abstract class PlusCalNodeVisitor { - - public abstract T visit(PlusCalAlgorithm plusCalAlgorithm) throws E; - public abstract T visit(PlusCalProcesses processes) throws E; - public abstract T visit(PlusCalStatement statement) throws E; - public abstract T visit(PlusCalLabel label) throws E; - public abstract T visit(PlusCalMacro macro) throws E; - public abstract T visit(PlusCalProcess plusCalProcess) throws E; - public abstract T visit(PlusCalProcedure procedure) throws E; - public abstract T visit(PlusCalVariableDeclaration variableDeclaration) throws E; - public abstract T visit(PlusCalAssignmentPair plusCalAssignmentPair) throws E; - -} diff --git a/src/pgo/model/pcal/PlusCalPrint.java b/src/pgo/model/pcal/PlusCalPrint.java deleted file mode 100644 index 23ffef811..000000000 --- a/src/pgo/model/pcal/PlusCalPrint.java +++ /dev/null @@ -1,50 +0,0 @@ -package pgo.model.pcal; - -import pgo.model.tla.TLAExpression; -import pgo.util.SourceLocation; - -public class PlusCalPrint extends PlusCalStatement { - - private final TLAExpression value; - - public PlusCalPrint(SourceLocation location, TLAExpression value) { - super(location); - this.value = value; - } - - @Override - public PlusCalPrint copy() { - return new PlusCalPrint(getLocation(), value.copy()); - } - - public TLAExpression getValue() { - return value; - } - - @Override - public T accept(PlusCalStatementVisitor v) throws E { - return v.visit(this); - } - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((value == null) ? 0 : value.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; - PlusCalPrint other = (PlusCalPrint) obj; - if (value == null) { - return other.value == null; - } else return value.equals(other.value); - } - -} diff --git a/src/pgo/model/pcal/PlusCalProcedure.java b/src/pgo/model/pcal/PlusCalProcedure.java deleted file mode 100644 index cce413794..000000000 --- a/src/pgo/model/pcal/PlusCalProcedure.java +++ /dev/null @@ -1,97 +0,0 @@ -package pgo.model.pcal; - -import pgo.model.mpcal.ModularPlusCalBlockVisitor; -import pgo.util.SourceLocation; - -import java.util.List; -import java.util.stream.Collectors; - -public class PlusCalProcedure extends PlusCalNode { - private final String name; - private final List params; - private final List variables; - private final List body; - - public PlusCalProcedure(SourceLocation location, String name, List params, List variables, List body) { - super(location); - this.name = name; - this.params = params; - this.variables = variables; - this.body = body; - } - - @Override - public PlusCalProcedure copy() { - return new PlusCalProcedure( - getLocation(), - name, - params.stream().map(PlusCalVariableDeclaration::copy).collect(Collectors.toList()), - variables.stream().map(PlusCalVariableDeclaration::copy).collect(Collectors.toList()), - body.stream().map(PlusCalStatement::copy).collect(Collectors.toList())); - } - - public String getName() { - return name; - } - - public List getParams(){ - return params; - } - - public List getVariables(){ - return variables; - } - - public List getBody() { - return body; - } - - @Override - public T accept(PlusCalNodeVisitor v) throws E{ - return v.visit(this); - } - - public T accept(ModularPlusCalBlockVisitor v) throws E{ - return v.visit(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((params == null) ? 0 : params.hashCode()); - result = prime * result + ((body == null) ? 0 : body.hashCode()); - result = prime * result + ((name == null) ? 0 : name.hashCode()); - result = prime * result + ((variables == null) ? 0 : variables.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; - PlusCalProcedure other = (PlusCalProcedure) obj; - if (params == null) { - if (other.params != null) - return false; - } else if (!params.equals(other.params)) - return false; - if (body == null) { - if (other.body != null) - return false; - } else if (!body.equals(other.body)) - return false; - if (name == null) { - if (other.name != null) - return false; - } else if (!name.equals(other.name)) - return false; - if (variables == null) { - return other.variables == null; - } else return variables.equals(other.variables); - } -} diff --git a/src/pgo/model/pcal/PlusCalProcess.java b/src/pgo/model/pcal/PlusCalProcess.java deleted file mode 100644 index 6697f7e93..000000000 --- a/src/pgo/model/pcal/PlusCalProcess.java +++ /dev/null @@ -1,67 +0,0 @@ -package pgo.model.pcal; - -import pgo.util.SourceLocation; - -import java.util.List; -import java.util.Objects; -import java.util.stream.Collectors; - -public class PlusCalProcess extends PlusCalNode { - private final PlusCalVariableDeclaration name; - private final PlusCalFairness fairness; - private final List variables; - private final List body; - - public PlusCalProcess(SourceLocation location, PlusCalVariableDeclaration name, PlusCalFairness fairness, - List variables, List body) { - super(location); - this.name = name; - this.fairness = fairness; - this.variables = variables; - this.body = body; - } - - @Override - public PlusCalProcess copy() { - return new PlusCalProcess(getLocation(), name.copy(), fairness, - variables.stream().map(PlusCalVariableDeclaration::copy).collect(Collectors.toList()), - body.stream().map(PlusCalStatement::copy).collect(Collectors.toList())); - } - - public PlusCalVariableDeclaration getName() { - return name; - } - - public PlusCalFairness getFairness() { - return fairness; - } - - public List getVariables() { - return variables; - } - - public List getBody() { - return body; - } - - @Override - public T accept(PlusCalNodeVisitor v) throws E{ - return v.visit(this); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - PlusCalProcess that = (PlusCalProcess) o; - return Objects.equals(name, that.name) && - fairness == that.fairness && - Objects.equals(variables, that.variables) && - Objects.equals(body, that.body); - } - - @Override - public int hashCode() { - return Objects.hash(name, fairness, variables, body); - } -} diff --git a/src/pgo/model/pcal/PlusCalProcesses.java b/src/pgo/model/pcal/PlusCalProcesses.java deleted file mode 100644 index e8ff418fb..000000000 --- a/src/pgo/model/pcal/PlusCalProcesses.java +++ /dev/null @@ -1,21 +0,0 @@ -package pgo.model.pcal; - -import pgo.util.SourceLocation; - -public abstract class PlusCalProcesses extends PlusCalNode { - - public PlusCalProcesses(SourceLocation location) { - super(location); - } - - @Override - public abstract PlusCalProcesses copy(); - - @Override - public T accept(PlusCalNodeVisitor v) throws E{ - return v.visit(this); - } - - public abstract T accept(PlusCalProcessesVisitor v) throws E; - -} diff --git a/src/pgo/model/pcal/PlusCalProcessesVisitor.java b/src/pgo/model/pcal/PlusCalProcessesVisitor.java deleted file mode 100644 index fa493d2b5..000000000 --- a/src/pgo/model/pcal/PlusCalProcessesVisitor.java +++ /dev/null @@ -1,6 +0,0 @@ -package pgo.model.pcal; - -public abstract class PlusCalProcessesVisitor{ - public abstract T visit(PlusCalSingleProcess singleProcess) throws E; - public abstract T visit(PlusCalMultiProcess multiProcess) throws E; -} diff --git a/src/pgo/model/pcal/PlusCalReturn.java b/src/pgo/model/pcal/PlusCalReturn.java deleted file mode 100644 index 1da8aa967..000000000 --- a/src/pgo/model/pcal/PlusCalReturn.java +++ /dev/null @@ -1,29 +0,0 @@ -package pgo.model.pcal; - -import pgo.util.SourceLocation; - -public class PlusCalReturn extends PlusCalStatement { - public PlusCalReturn(SourceLocation location) { - super(location); - } - - @Override - public PlusCalReturn copy() { - return new PlusCalReturn(getLocation()); - } - - @Override - public T accept(PlusCalStatementVisitor v) throws E { - return v.visit(this); - } - - @Override - public int hashCode() { - return 0; - } - - @Override - public boolean equals(Object other) { - return other instanceof PlusCalReturn; - } -} diff --git a/src/pgo/model/pcal/PlusCalSingleProcess.java b/src/pgo/model/pcal/PlusCalSingleProcess.java deleted file mode 100644 index f69391cc7..000000000 --- a/src/pgo/model/pcal/PlusCalSingleProcess.java +++ /dev/null @@ -1,51 +0,0 @@ -package pgo.model.pcal; - -import pgo.model.mpcal.ModularPlusCalBlockVisitor; -import pgo.util.SourceLocation; - -import java.util.List; -import java.util.Objects; -import java.util.stream.Collectors; - -public class PlusCalSingleProcess extends PlusCalProcesses { - - private final List body; - - public PlusCalSingleProcess(SourceLocation location, List body) { - super(location); - this.body = body; - } - - @Override - public PlusCalSingleProcess copy() { - return new PlusCalSingleProcess( - getLocation(), - body.stream().map(PlusCalStatement::copy).collect(Collectors.toList())); - } - - public List getBody() { - return body; - } - - @Override - public T accept(PlusCalProcessesVisitor v) throws E { - return v.visit(this); - } - - public T accept(ModularPlusCalBlockVisitor v) throws E { - return v.visit(this); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - PlusCalSingleProcess that = (PlusCalSingleProcess) o; - return Objects.equals(body, that.body); - } - - @Override - public int hashCode() { - return Objects.hash(body); - } -} diff --git a/src/pgo/model/pcal/PlusCalSkip.java b/src/pgo/model/pcal/PlusCalSkip.java deleted file mode 100644 index 309916582..000000000 --- a/src/pgo/model/pcal/PlusCalSkip.java +++ /dev/null @@ -1,31 +0,0 @@ -package pgo.model.pcal; - -import pgo.util.SourceLocation; - -public class PlusCalSkip extends PlusCalStatement { - - public PlusCalSkip(SourceLocation location) { - super(location); - } - - @Override - public PlusCalSkip copy() { - return new PlusCalSkip(getLocation()); - } - - @Override - public T accept(PlusCalStatementVisitor v) throws E { - return v.visit(this); - } - - @Override - public int hashCode() { - return 0; - } - - @Override - public boolean equals(Object obj) { - return obj != null && obj instanceof PlusCalSkip; - } - -} diff --git a/src/pgo/model/pcal/PlusCalStatement.java b/src/pgo/model/pcal/PlusCalStatement.java deleted file mode 100644 index 9278c8435..000000000 --- a/src/pgo/model/pcal/PlusCalStatement.java +++ /dev/null @@ -1,19 +0,0 @@ -package pgo.model.pcal; - -import pgo.util.SourceLocation; - -public abstract class PlusCalStatement extends PlusCalNode { - public PlusCalStatement(SourceLocation location) { - super(location); - } - - @Override - public abstract PlusCalStatement copy(); - - @Override - public T accept(PlusCalNodeVisitor v) throws E{ - return v.visit(this); - } - - public abstract T accept(PlusCalStatementVisitor v) throws E; -} diff --git a/src/pgo/model/pcal/PlusCalStatementVisitor.java b/src/pgo/model/pcal/PlusCalStatementVisitor.java deleted file mode 100644 index 5c5c3bc32..000000000 --- a/src/pgo/model/pcal/PlusCalStatementVisitor.java +++ /dev/null @@ -1,21 +0,0 @@ -package pgo.model.pcal; - -import pgo.model.mpcal.ModularPlusCalYield; - -public abstract class PlusCalStatementVisitor{ - public abstract T visit(PlusCalLabeledStatements plusCalLabeledStatements) throws E; - public abstract T visit(PlusCalWhile plusCalWhile) throws E; - public abstract T visit(PlusCalIf plusCalIf) throws E; - public abstract T visit(PlusCalEither plusCalEither) throws E; - public abstract T visit(PlusCalAssignment plusCalAssignment) throws E; - public abstract T visit(PlusCalReturn plusCalReturn) throws E; - public abstract T visit(PlusCalSkip plusCalSkip) throws E; - public abstract T visit(PlusCalCall plusCalCall) throws E; - public abstract T visit(PlusCalMacroCall macroCall) throws E; - public abstract T visit(PlusCalWith plusCalWith) throws E; - public abstract T visit(PlusCalPrint plusCalPrint) throws E; - public abstract T visit(PlusCalAssert plusCalAssert) throws E; - public abstract T visit(PlusCalAwait plusCalAwait) throws E; - public abstract T visit(PlusCalGoto plusCalGoto) throws E; - public abstract T visit(ModularPlusCalYield modularPlusCalYield) throws E; -} diff --git a/src/pgo/model/pcal/PlusCalUtils.scala b/src/pgo/model/pcal/PlusCalUtils.scala deleted file mode 100644 index 909e0a749..000000000 --- a/src/pgo/model/pcal/PlusCalUtils.scala +++ /dev/null @@ -1,66 +0,0 @@ -package pgo.model.pcal - -import pgo.model.mpcal.{ModularPlusCalUtils, ModularPlusCalYield} -import pgo.model.tla.TLAUtils -import pgo.trans.intermediate.DefinitionRegistry - -import scala.jdk.CollectionConverters._ - -object PlusCalUtils { - def fillDefinitionRegistryFromStatement(definitionRegistry: DefinitionRegistry, assignment: PlusCalStatement): Unit = { - assignment.accept(new PlusCalStatementVisitor[Unit,RuntimeException] { - override def visit(plusCalLabeledStatements: PlusCalLabeledStatements): Unit = - plusCalLabeledStatements.getStatements.asScala.foreach(_.accept(this)) - - override def visit(plusCalWhile: PlusCalWhile): Unit = { - TLAUtils.fillDefinitionRegistryFromExpression(definitionRegistry, plusCalWhile.getCondition) - plusCalWhile.getBody.asScala.foreach(_.accept(this)) - } - - override def visit(plusCalIf: PlusCalIf): Unit = { - TLAUtils.fillDefinitionRegistryFromExpression(definitionRegistry, plusCalIf.getCondition) - plusCalIf.getYes.asScala.foreach(_.accept(this)) - plusCalIf.getNo.asScala.foreach(_.accept(this)) - } - - override def visit(plusCalEither: PlusCalEither): Unit = - plusCalEither.getCases.asScala.foreach(_.asScala.foreach(_.accept(this))) - - override def visit(plusCalAssignment: PlusCalAssignment): Unit = - plusCalAssignment.getPairs.asScala.foreach { pair => - TLAUtils.fillDefinitionRegistryFromExpression(definitionRegistry, pair.getLhs) - TLAUtils.fillDefinitionRegistryFromExpression(definitionRegistry, pair.getRhs) - } - - override def visit(plusCalReturn: PlusCalReturn): Unit = () - - override def visit(plusCalSkip: PlusCalSkip): Unit = () - - override def visit(plusCalCall: PlusCalCall): Unit = - plusCalCall.getArguments.asScala.foreach(TLAUtils.fillDefinitionRegistryFromExpression(definitionRegistry, _)) - - override def visit(macroCall: PlusCalMacroCall): Unit = - macroCall.getArguments.asScala.foreach(TLAUtils.fillDefinitionRegistryFromExpression(definitionRegistry, _)) - - override def visit(plusCalWith: PlusCalWith): Unit = { - plusCalWith.getVariables.asScala.foreach( - ModularPlusCalUtils.fillDefinitionRegistryFromVariableDeclaration(definitionRegistry,_)) - plusCalWith.getBody.asScala.foreach(_.accept(this)) - } - - override def visit(plusCalPrint: PlusCalPrint): Unit = - TLAUtils.fillDefinitionRegistryFromExpression(definitionRegistry, plusCalPrint.getValue) - - override def visit(plusCalAssert: PlusCalAssert): Unit = - TLAUtils.fillDefinitionRegistryFromExpression(definitionRegistry, plusCalAssert.getCondition) - - override def visit(plusCalAwait: PlusCalAwait): Unit = - TLAUtils.fillDefinitionRegistryFromExpression(definitionRegistry, plusCalAwait.getCondition) - - override def visit(plusCalGoto: PlusCalGoto): Unit = () - - override def visit(modularPlusCalYield: ModularPlusCalYield): Unit = - TLAUtils.fillDefinitionRegistryFromExpression(definitionRegistry, modularPlusCalYield.getExpression) - }) - } -} diff --git a/src/pgo/model/pcal/PlusCalVariableDeclaration.java b/src/pgo/model/pcal/PlusCalVariableDeclaration.java deleted file mode 100644 index 180926ac5..000000000 --- a/src/pgo/model/pcal/PlusCalVariableDeclaration.java +++ /dev/null @@ -1,96 +0,0 @@ -package pgo.model.pcal; - -import pgo.model.tla.TLADefinitionOne; -import pgo.model.tla.TLAExpression; -import pgo.model.tla.TLAIdentifier; -import pgo.util.SourceLocation; -import scala.collection.immutable.Map; -import scala.collection.immutable.Map$; - -public class PlusCalVariableDeclaration extends PlusCalNode implements TLADefinitionOne { - private final TLAIdentifier name; - private final boolean isRef; - private final boolean set; - private final TLAExpression value; - - public PlusCalVariableDeclaration(SourceLocation location, TLAIdentifier name, boolean isRef, boolean isSet, TLAExpression value) { - super(location); - this.name = name; - this.isRef = isRef; - this.set = isSet; - this.value = value; - } - - @Override - public int arity() { - return 0; - } - - @Override - public boolean isModuleInstance() { - return false; - } - - @Override - public TLAIdentifier identifier() { - return name; - } - - @Override - public Map scope() { - return Map$.MODULE$.empty(); - } - - @Override - public PlusCalVariableDeclaration copy() { - throw new RuntimeException("bad"); - //return new PlusCalVariableDeclaration(getLocation(), name, isRef, set, value.copy()); - } - - public TLAIdentifier getName() { - return name; - } - - public boolean isRef() { - return isRef; - } - - public boolean isSet() { - return set; - } - - public TLAExpression getValue(){ - return value; - } - - @Override - public T accept(PlusCalNodeVisitor v) throws E{ - return v.visit(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + (set ? 1231 : 1237); - result = prime * result + ((name == null) ? 0 : name.hashCode()); - result = prime * result + ((value == null) ? 0 : value.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null || obj.getClass() != getClass()) { - return false; - } - PlusCalVariableDeclaration that = (PlusCalVariableDeclaration) obj; - return set == that.set && - ((name == null && that.name == null) || - (name != null && name.equals(that.name))) && - ((value == null && that.value != null) || - (value != null && value.equals(that.value))); - } -} diff --git a/src/pgo/model/pcal/PlusCalWhile.java b/src/pgo/model/pcal/PlusCalWhile.java deleted file mode 100644 index 62625718f..000000000 --- a/src/pgo/model/pcal/PlusCalWhile.java +++ /dev/null @@ -1,65 +0,0 @@ -package pgo.model.pcal; - -import pgo.model.tla.TLAExpression; -import pgo.util.SourceLocation; - -import java.util.List; -import java.util.stream.Collectors; - -public class PlusCalWhile extends PlusCalStatement { - private final TLAExpression condition; - private final List body; - - public PlusCalWhile(SourceLocation location, TLAExpression condition, List body) { - super(location); - this.condition = condition; - this.body = body; - } - - @Override - public PlusCalWhile copy() { - return new PlusCalWhile(getLocation(), condition.copy(), body.stream().map(PlusCalStatement::copy).collect(Collectors.toList())); - } - - public TLAExpression getCondition() { - return condition; - } - - public List getBody(){ - return body; - } - - @Override - public T accept(PlusCalStatementVisitor v) throws E { - return v.visit(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((body == null) ? 0 : body.hashCode()); - result = prime * result + ((condition == null) ? 0 : condition.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; - PlusCalWhile other = (PlusCalWhile) obj; - if (body == null) { - if (other.body != null) - return false; - } else if (!body.equals(other.body)) - return false; - if (condition == null) { - return other.condition == null; - } else return condition.equals(other.condition); - } - -} diff --git a/src/pgo/model/pcal/PlusCalWith.java b/src/pgo/model/pcal/PlusCalWith.java deleted file mode 100644 index 55251cb53..000000000 --- a/src/pgo/model/pcal/PlusCalWith.java +++ /dev/null @@ -1,54 +0,0 @@ -package pgo.model.pcal; - -import pgo.util.SourceLocation; - -import java.util.List; -import java.util.Objects; -import java.util.stream.Collectors; - -public class PlusCalWith extends PlusCalStatement { - - private final List variables; - private final List body; - - public PlusCalWith(SourceLocation location, List variables, List body) { - super(location); - this.variables = variables; - this.body = body; - } - - @Override - public PlusCalWith copy() { - return new PlusCalWith( - getLocation(), - variables.stream().map(PlusCalVariableDeclaration::copy).collect(Collectors.toList()), - body.stream().map(PlusCalStatement::copy).collect(Collectors.toList())); - } - - public List getVariables() { - return variables; - } - - public List getBody(){ - return body; - } - - @Override - public T accept(PlusCalStatementVisitor v) throws E { - return v.visit(this); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - PlusCalWith that = (PlusCalWith) o; - return Objects.equals(variables, that.variables) && - Objects.equals(body, that.body); - } - - @Override - public int hashCode() { - return Objects.hash(variables, body); - } -} diff --git a/src/pgo/model/tla/AST.scala b/src/pgo/model/tla/AST.scala new file mode 100644 index 000000000..b1a503172 --- /dev/null +++ b/src/pgo/model/tla/AST.scala @@ -0,0 +1,465 @@ +package pgo.model.tla + +import pgo.model.RefersTo.Renamer +import pgo.model.{Definition, DefinitionComposite, DefinitionOne, RefersTo, Rewritable, SourceLocatable, Visitable} + +import scala.collection.View + + +sealed abstract class TLANode extends Rewritable with Visitable with SourceLocatable { + override def decorateLike(succ: this.type): this.type = + super.decorateLike(succ.setSourceLocation(sourceLocation)) +} + +final case class TLASymbol(symbol: TLASymbol.Symbol) extends TLANode + +object TLASymbol { + // while very sketchy, this little trick saves retyping, and having to maintain, two separate lists of all symbols + private lazy val symbolMap: Map[String, Symbol] = { + import scala.reflect.runtime.{universe => ru} + val m = ru.runtimeMirror(getClass.getClassLoader) + ru.typeOf[TLASymbol.type] + .decls.view + .filter(decl => decl.isModule && decl.name.decodedName.toString.endsWith("Symbol")) + .map(decl => m.reflectModule(decl.asModule).instance.asInstanceOf[TLASymbol.Symbol]) + .flatMap(sym => sym.representations.view.map(_ -> sym)) + .toMap + } + + def forString(symStr: String): Symbol = { + require(symbolMap.contains(symStr), s"""could not find a Symbol instance for "$symStr"""") + symbolMap(symStr) + } + + sealed abstract class Symbol(val representations: String*) { + override def toString: String = s"Symbol(${representations.mkString(", ")})" + + import pgo.parser.TLAMeta + + assert(representations.forall { rep => + TLAMeta.prefixOperators.contains(rep) || + TLAMeta.infixOperators.contains(rep) || + TLAMeta.postfixOperators.contains(rep) + }, s"this symbol does not have parser metadata: $this; this is almost 100% an implementation typo") + assert(isPrefix ^ isInfix ^ isPostfix, s"$this has more than one fixity; this is almost 100% an implementation typo") + + def isPrefix: Boolean = + TLAMeta.prefixOperators.contains(representations.head) + + def isInfix: Boolean = + TLAMeta.infixOperators.contains(representations.head) + + def isPostfix: Boolean = + TLAMeta.postfixOperators.contains(representations.head) + + def isAssociative: Boolean = + TLAMeta.infixOperators.get(representations.head).exists(_._3) + + def precedence: Int = { + require(precedenceLow == precedenceHigh) + precedenceLow + } + + def precedenceLow: Int = + TLAMeta.prefixOperators.get(representations.head).map(_._1) + .orElse(TLAMeta.infixOperators.get(representations.head).map(_._1)) + .orElse(TLAMeta.postfixOperators.get(representations.head)) + .get + + def precedenceHigh: Int = + TLAMeta.prefixOperators.get(representations.head).map(_._2) + .orElse(TLAMeta.infixOperators.get(representations.head).map(_._2)) + .orElse(TLAMeta.postfixOperators.get(representations.head)) + .get + } + + // prefix + case object UnchangedSymbol extends Symbol("UNCHANGED") + case object EnabledSymbol extends Symbol("ENABLED") + case object DomainSymbol extends Symbol("DOMAIN") + case object PrefixSubsetSymbol extends Symbol("SUBSET") + case object LogicalNotSymbol extends Symbol("~", "\\lnot", "\\neg") + case object PrefixUnionSymbol extends Symbol("UNION") + case object TLEventuallySymbol extends Symbol("<>") + case object TLAlwaysSymbol extends Symbol("[]") + case object NegationSymbol extends Symbol("-_") + + // infix + case object DoubleExclamationSymbol extends Symbol("!!") + case object NotEqualsSymbol extends Symbol("#", "/=") + case object DoublePoundSymbol extends Symbol("##") + case object DollarSymbol extends Symbol("$") + case object DoubleDollarSymbol extends Symbol("$$") + case object PercentSymbol extends Symbol("%") + case object DoublePercentSymbol extends Symbol("%%") + case object AmpersandSymbol extends Symbol("&") + case object DoubleAmpersandSymbol extends Symbol("&&") + case object OPlusSymbol extends Symbol("(+)", "\\oplus") + case object OMinusSymbol extends Symbol("(-)", "\\ominus") + case object ODotSymbol extends Symbol("(.)", "\\odot") + case object OSlashSymbol extends Symbol("(/)", "\\oslash") + case object OTimesSymbol extends Symbol("(\\X)", "\\otimes") + case object AsteriskSymbol extends Symbol("*") + case object DoubleAsteriskSymbol extends Symbol("**") + case object PlusSymbol extends Symbol("+") + case object DoublePlusSymbol extends Symbol("++") + case object MinusSymbol extends Symbol("-") + case object PlusArrowSymbol extends Symbol("-+->") + case object DoubleMinusSymbol extends Symbol("--") + case object LeftTurnstileSymbol extends Symbol("-|") + case object DotSymbol extends Symbol(".") // TODO: this isn't reachable is it? + case object DotDotSymbol extends Symbol("..") + case object DotDotDotSymbol extends Symbol("...") + case object SlashSymbol extends Symbol("/") + case object SlashSlashSymbol extends Symbol("//") + case object LogicalAndSymbol extends Symbol("/\\", "\\land") + case object ColonColonEqualsSymbol extends Symbol("::=") + case object ColonEqualsSymbol extends Symbol(":=") + case object ColonGreaterThanSymbol extends Symbol(":>") + case object LessThanSymbol extends Symbol("<") + case object LessThanColonSymbol extends Symbol("<:") + case object LessThanOrEqualSymbol extends Symbol("<=", "\\leq", "=<") + case object EquivSymbol extends Symbol("<=>", "\\equiv") + case object EqualsSymbol extends Symbol("=") + case object ImpliesSymbol extends Symbol("=>") + case object LeftEntailmentSymbol extends Symbol("=|") + case object GreaterThanSymbol extends Symbol(">") + case object GreaterThanOrEqualSymbol extends Symbol(">=", "\\geq") + case object QuestionMarkSymbol extends Symbol("?") + case object DoubleQuestionMarkSymbol extends Symbol("??") + case object DoubleAtSignSymbol extends Symbol("@@") + case object BackslashSymbol extends Symbol("\\") + case object LogicalOrSymbol extends Symbol("\\/", "\\lor") + case object ApproxSymbol extends Symbol("\\approx") + case object AsympSymbol extends Symbol("\\asymp") + case object BigCircSymbol extends Symbol("\\bigcirc") + case object BulletSymbol extends Symbol("\\bullet") + case object IntersectSymbol extends Symbol("\\intersect", "\\cap") + case object CDotSymbol extends Symbol("\\cdot") + case object OSymbol extends Symbol("\\o", "\\circ") + case object CongruenceSymbol extends Symbol("\\cong") + case object UnionSymbol extends Symbol("\\union", "\\cup") + case object DivSymbol extends Symbol("\\div") + case object DotEqSymbol extends Symbol("\\doteq") + case object GreaterThanGreaterThanSymbol extends Symbol("\\gg") + case object InSymbol extends Symbol("\\in") + case object LessThanLessThanSymbol extends Symbol("\\ll") + case object NotInSymbol extends Symbol("\\notin") + case object PrecSymbol extends Symbol("\\prec") + case object PrecEqSymbol extends Symbol("\\preceq") + case object ProptoSymbol extends Symbol("\\propto") + case object SimSymbol extends Symbol("\\sim") + case object SquareCapSymbol extends Symbol("\\sqcap") + case object SquareCupSymbol extends Symbol("\\sqcup") + case object SquareSubsetSymbol extends Symbol("\\sqsubset") + case object SquareSubsetOrEqualSymbol extends Symbol("\\sqsubseteq") + case object SquareSupersetSymbol extends Symbol("\\sqsupset") + case object SquareSupersetOrEqualSymbol extends Symbol("\\sqsupseteq") + case object StarSymbol extends Symbol("\\star") + case object SubsetSymbol extends Symbol("\\subset") + case object SubsetOrEqualSymbol extends Symbol("\\subseteq") + case object SuccSymbol extends Symbol("\\succ") + case object SuccOrEqualSymbol extends Symbol("\\succeq") + case object SupersetSymbol extends Symbol("\\supset") + case object SupersetOrEqualSymbol extends Symbol("\\supseteq") + case object UPlusSymbol extends Symbol("\\uplus") + case object WRSymbol extends Symbol("\\wr") + case object SuperscriptSymbol extends Symbol("^") + case object CaretCaretSymbol extends Symbol("^^") + case object PipeSymbol extends Symbol("|") + case object TurnstileSymbol extends Symbol("|-") + case object EntailmentSymbol extends Symbol("|=") + case object DoublePipeSymbol extends Symbol("||") + case object SequencingSymbol extends Symbol("~>") + + // postfix + case object SuperscriptPlusSymbol extends Symbol("^+") + case object SuperscriptAsteriskSymbol extends Symbol("^*") + case object SuperscriptPoundSymbol extends Symbol("^#") + case object PrimeSymbol extends Symbol("'") + +} + +final case class TLAIdentifier(id: String) extends TLANode { + def toDefiningIdentifier: TLADefiningIdentifier = + TLADefiningIdentifier(this).setSourceLocation(sourceLocation) +} + +final case class TLADefiningIdentifier(id: TLAIdentifier) extends TLANode with DefinitionOne { + override def arity: Int = 0 + override def identifier: Definition.ScopeIdentifier = Definition.ScopeIdentifierName(id) +} + +final case class TLAGeneralIdentifierPart(id: TLAIdentifier, parameters: List[TLAExpression]) extends TLANode + +final case class TLAQuantifierBound(tpe: TLAQuantifierBound.Type, ids: List[TLADefiningIdentifier], set: TLAExpression) extends TLANode with DefinitionComposite { + require(tpe match { + case TLAQuantifierBound.IdsType => ids.length == 1 + case TLAQuantifierBound.TupleType => true + }, s"a TLA+ QuantifierBound can restrict either a single identifier or a tuple, not multiple identifiers") + + override def definitions: View[Definition] = ids.view +} + +object TLAQuantifierBound { + sealed abstract class Type + case object IdsType extends Type + case object TupleType extends Type +} + +final case class TLAOpDecl(variant: TLAOpDecl.Variant) extends TLANode with DefinitionOne { + override def arity: Int = variant.arity + override def identifier: Definition.ScopeIdentifier = variant.identifier +} + +object TLAOpDecl { + sealed abstract class Variant { + def identifier: Definition.ScopeIdentifier + def arity: Int + } + + final case class NamedVariant(ident: TLAIdentifier, arity: Int) extends Variant { + override def identifier: Definition.ScopeIdentifier = Definition.ScopeIdentifierName(ident) + } + + final case class SymbolVariant(sym: TLASymbol) extends Variant { + override def arity: Int = if (sym.symbol.isPrefix || sym.symbol.isPostfix) 1 else 2 + override def identifier: Definition.ScopeIdentifier = Definition.ScopeIdentifierSymbol(sym) + } +} + +sealed abstract class TLAUnit extends TLANode { + def definitions: View[Definition] +} + +final case class TLAAssumption(assumption: TLAExpression) extends TLAUnit { + override def definitions: View[Definition] = View.empty +} + +final case class TLAConstantDeclaration(constants: List[TLAOpDecl]) extends TLAUnit with DefinitionComposite { + override def definitions: View[Definition] = constants.view +} + +final case class TLAInstance(moduleName: TLAIdentifier, remappings: List[TLAInstanceRemapping], isLocal: Boolean) extends TLAUnit with DefinitionComposite { + override def definitions: View[Definition] = ??? +} + +final case class TLAInstanceRemapping(from: Definition.ScopeIdentifier, to: TLAExpression) extends TLANode with DefinitionOne { + override def arity: Int = 0 + override def identifier: Definition.ScopeIdentifier = from +} + +final case class TLAModule(name: TLAIdentifier, exts: List[TLAModuleRef], units: List[TLAUnit]) extends TLAUnit with DefinitionOne { + override def definitions: View[Definition] = View(this) + override def arity: Int = 0 + override def identifier: Definition.ScopeIdentifierName = Definition.ScopeIdentifierName(name) + + def moduleDefinitions(captureLocal: Boolean = false): View[DefinitionOne] = + exts.view.flatMap(_.singleDefinitions).filter(!_.isLocal) ++ + units.view.flatMap(_.definitions).flatMap(_.singleDefinitions).filter(captureLocal || _.isLocal) + + override def mapChildren(fn: Any => Any): this.type = { + val renamer = new Renamer[TLAUnit]() + val mappedName = fn(name) + val mappedExts = exts.mapConserve(ext => fn(ext).asInstanceOf[TLAModuleRef]) + assert(mappedExts eq exts, s"internal error: can't automatically rewrite module contents after replacing EXTENDS clause(s)") + + val mappedUnits = renamer.mapConserveRenamingAny(units, fn) + withChildren(Iterator(mappedName, mappedExts, mappedUnits)) + } +} + +sealed abstract class TLAModuleRef extends TLANode with DefinitionComposite { + def identifier: Definition.ScopeIdentifierName +} + +final case class TLAModuleRefBuiltin(module: BuiltinModules.TLABuiltinModule) extends TLAModuleRef { + override def identifier: Definition.ScopeIdentifierName = module.identifier + override def definitions: View[Definition] = module.members.view +} + +final case class TLAModuleRefModule(module: TLAModule) extends TLAModuleRef { + override def identifier: Definition.ScopeIdentifierName = module.identifier + override def definitions: View[Definition] = + module.units.view + .flatMap(_.definitions.flatMap(_.singleDefinitions)) + .filter(!_.isLocal) +} + +final case class TLAModuleDefinition(name: TLAIdentifier, args: List[TLAOpDecl], instance: TLAInstance, + override val isLocal: Boolean) extends TLAUnit with DefinitionOne { + override def definitions: View[Definition] = View(this) + override def arity: Int = 0 + override def isModuleInstance: Boolean = true + override def identifier: Definition.ScopeIdentifier = Definition.ScopeIdentifierName(name) + + override lazy val scope: Map[Definition.ScopeIdentifier, DefinitionOne] = + instance.singleDefinitions.map(defn => defn.identifier -> defn).toMap +} + +final case class TLAOperatorDefinition(name: Definition.ScopeIdentifier, args: List[TLAOpDecl], body: TLAExpression, + override val isLocal: Boolean) extends TLAUnit with DefinitionOne { + require(name match { + case Definition.ScopeIdentifierSymbol(TLASymbol(sym)) => + if (sym.isPrefix || sym.isPostfix) args.length == 2 + else args.length == 1 + case Definition.ScopeIdentifierName(_) => true + }, s"symbolic operator definitions must exactly one or two arguments, depending on the symbol's fixity") + + override def definitions: View[Definition] = View(this) + + override def arity: Int = args.length + + override def identifier: Definition.ScopeIdentifier = name +} + +final case class TLATheorem(theorem: TLAExpression) extends TLAUnit { + override def definitions: View[Definition] = View.empty +} + +final case class TLAVariableDeclaration(variables: List[TLADefiningIdentifier]) extends TLAUnit with DefinitionComposite { + override def definitions: View[Definition] = variables.view +} + +sealed abstract class TLAExpression extends TLANode + +final case class TLAExtensionExpression(contents: Any) extends TLAExpression + +//final case class TLABool(value: Boolean) extends TLAExpression + +final case class TLAString(value: String) extends TLAExpression + +final case class TLANumber(value: TLANumber.Value, syntax: TLANumber.Syntax = TLANumber.DecimalSyntax) extends TLAExpression + +object TLANumber { + sealed abstract class Value + final case class IntValue(value: BigInt) extends Value + final case class DecimalValue(value: BigDecimal) extends Value + + sealed abstract class Syntax + case object DecimalSyntax extends Syntax + case object BinarySyntax extends Syntax + case object OctalSyntax extends Syntax + case object HexadecimalSyntax extends Syntax + +} + +final case class TLAGeneralIdentifier(name: TLAIdentifier, prefix: List[TLAGeneralIdentifierPart]) extends TLAExpression with RefersTo[DefinitionOne] + +final case class TLADot(lhs: TLAExpression, identifier: TLAIdentifier) extends TLAExpression + +final case class TLAUnary(operation: TLASymbol, prefix: List[TLAGeneralIdentifierPart], operand: TLAExpression) extends TLAExpression with RefersTo[DefinitionOne] + +final case class TLAOperatorCall(name: Definition.ScopeIdentifier, prefix: List[TLAGeneralIdentifierPart], arguments: List[TLAExpression]) extends TLAExpression with RefersTo[DefinitionOne] + +final case class TLABinOp(operation: TLASymbol, prefix: List[TLAGeneralIdentifierPart], lhs: TLAExpression, rhs: TLAExpression) extends TLAExpression with RefersTo[DefinitionOne] + +final case class TLAIf(cond: TLAExpression, tval: TLAExpression, fval: TLAExpression) extends TLAExpression + +final case class TLALet(defs: List[TLAUnit], body: TLAExpression) extends TLAExpression { + override def mapChildren(fn: Any => Any): this.type = { + val renamer = new RefersTo.Renamer[TLAUnit]() + val mappedDefs = renamer.mapConserveRenamingAny(defs, fn) + val mappedBody = fn(renamer(body)) + withChildren(Iterator(mappedDefs, mappedBody)) + } +} + +final case class TLACase(arms: List[TLACaseArm], other: Option[TLAExpression]) extends TLAExpression + +final case class TLACaseArm(cond: TLAExpression, result: TLAExpression) extends TLANode + +final case class TLAMaybeAction(body: TLAExpression, vars: TLAExpression) extends TLAExpression + +final case class TLARequiredAction(body: TLAExpression, vars: TLAExpression) extends TLAExpression + +final case class TLAFairness(kind: TLAFairness.Kind, vars: TLAExpression, expression: TLAExpression) extends TLAExpression + +object TLAFairness { + sealed abstract class Kind + case object StrongFairness extends Kind + case object WeakFairness extends Kind +} + +final case class TLAFunction(args: List[TLAQuantifierBound], body: TLAExpression) extends TLAExpression { + override def mapChildren(fn: Any => Any): this.type = { + val renamer = new RefersTo.Renamer[TLAQuantifierBound]() + val mappedArgs = renamer.mapConserveRenamingAny(args, fn) + val mappedBody = fn(renamer(body)) + withChildren(Iterator(mappedArgs, mappedBody)) + } +} + +final case class TLAFunctionCall(function: TLAExpression, params: List[TLAExpression]) extends TLAExpression + +final case class TLAFunctionSet(from: TLAExpression, to: TLAExpression) extends TLAExpression + +final case class TLAFunctionSubstitution(source: TLAExpression, substitutions: List[TLAFunctionSubstitutionPair]) extends TLAExpression + +final case class TLAFunctionSubstitutionPair(keys: List[TLAFunctionSubstitutionKey], value: TLAExpression) extends TLANode + +final case class TLAFunctionSubstitutionKey(indices: List[TLAExpression]) extends TLANode + +trait TLAQuantified { + self: Rewritable => + def bounds: List[TLAQuantifierBound] + def body: TLAExpression + + override def mapChildren(fn: Any => Any): this.type = { + val renamer = new RefersTo.Renamer[TLAQuantifierBound]() + val mappedBounds = renamer.mapConserveRenamingAny(bounds, fn) + val mappedBody = fn(renamer(body)) + withChildren(Iterator(mappedBounds, mappedBody)) + } +} + +final case class TLAQuantifiedExistential(bounds: List[TLAQuantifierBound], body: TLAExpression) extends TLAExpression with TLAQuantified + +final case class TLAQuantifiedUniversal(bounds: List[TLAQuantifierBound], body: TLAExpression) extends TLAExpression with TLAQuantified + +trait TLAUnquantified { + self: Rewritable => + def ids: List[TLADefiningIdentifier] + def body: TLAExpression + + override def mapChildren(fn: Any => Any): this.type = { + val renamer = new RefersTo.Renamer[TLADefiningIdentifier]() + val mappedIds = renamer.mapConserveRenamingAny(ids, fn) + val mappedBody = fn(renamer.apply(body)) + withChildren(Iterator(mappedIds, mappedBody)) + } +} + +final case class TLAExistential(ids: List[TLADefiningIdentifier], body: TLAExpression) extends TLAExpression with TLAUnquantified + +final case class TLAUniversal(ids: List[TLADefiningIdentifier], body: TLAExpression) extends TLAExpression with TLAUnquantified + +final case class TLASetConstructor(contents: List[TLAExpression]) extends TLAExpression + +final case class TLASetRefinement(binding: TLAQuantifierBound, when: TLAExpression) extends TLAExpression { + override def mapChildren(fn: Any => Any): this.type = { + val renamer = new RefersTo.Renamer[TLAQuantifierBound]() + val mappedBinding = renamer.captureRenamingAny(binding, fn) + val mappedWhen = fn(renamer(when)) + withChildren(Iterator(mappedBinding, mappedWhen)) + } +} + +final case class TLASetComprehension(body: TLAExpression, bounds: List[TLAQuantifierBound]) extends TLAExpression { + override def mapChildren(fn: Any => Any): this.type = { + val renamer = new RefersTo.Renamer[TLAQuantifierBound]() + val mappedBounds = renamer.mapConserveRenamingAny(bounds, fn) + val mappedBody = fn(renamer(body)) + withChildren(Iterator(mappedBody, mappedBounds)) + } +} + +final case class TLATuple(elements: List[TLAExpression]) extends TLAExpression + +final case class TLARecordConstructor(fields: List[TLARecordConstructorField]) extends TLAExpression + +final case class TLARecordConstructorField(name: TLAIdentifier, value: TLAExpression) extends TLANode + +final case class TLARecordSet(fields: List[TLARecordSetField]) extends TLAExpression + +final case class TLARecordSetField(name: TLAIdentifier, set: TLAExpression) extends TLANode diff --git a/src/pgo/model/tla/BuiltinModules.scala b/src/pgo/model/tla/BuiltinModules.scala new file mode 100644 index 000000000..b4154b1f0 --- /dev/null +++ b/src/pgo/model/tla/BuiltinModules.scala @@ -0,0 +1,190 @@ +package pgo.model.tla + +import pgo.model.{Definition, DefinitionOne, SourceLocation} + +import scala.collection.mutable + +object BuiltinModules { + abstract class TLABuiltinModule(id: String) extends DefinitionOne { + override val identifier: Definition.ScopeIdentifierName = + Definition.ScopeIdentifierName(TLAIdentifier(id).setSourceLocation(SourceLocation.internal)) + override def arity: Int = 0 + + private[this] val membersAcc = mutable.ListBuffer[TLABuiltinOperator]() + def members: List[TLABuiltinOperator] = membersAcc.result() + + protected final def extend(module: TLABuiltinModule): Unit = + membersAcc ++= module.members + + protected final def op(op: TLABuiltinOperator): Unit = + membersAcc += op + + protected final def symOp(sym: TLASymbol.Symbol): Unit = + membersAcc += TLABuiltinOperator( + module = this, + identifier = Definition.ScopeIdentifierSymbol(TLASymbol(sym).setSourceLocation(SourceLocation.internal)), + arity = if(sym.isPrefix || sym.isPostfix) 1 else 2) + + protected final def alphaOp(name: String, arity: Int): Unit = + membersAcc += TLABuiltinOperator( + module = this, + identifier = Definition.ScopeIdentifierName(TLAIdentifier(name).setSourceLocation(SourceLocation.internal)), + arity = arity) + + lazy val membersMap: Map[Definition.ScopeIdentifier,TLABuiltinOperator] = + members.view.map(op => op.identifier -> op).toMap + + final def memberAlpha(name: String): TLABuiltinOperator = + membersMap(Definition.ScopeIdentifierName(TLAIdentifier(name))) + + final def memberSym(sym: TLASymbol.Symbol): TLABuiltinOperator = + membersMap(Definition.ScopeIdentifierSymbol(TLASymbol(sym))) + } + + final case class TLABuiltinOperator(module: TLABuiltinModule, identifier: Definition.ScopeIdentifier, arity: Int) extends DefinitionOne + + // these operators are always available + object Intrinsics extends TLABuiltinModule("") { + // logic + symOp(TLASymbol.LogicalAndSymbol) + symOp(TLASymbol.LogicalOrSymbol) + symOp(TLASymbol.LogicalNotSymbol) + symOp(TLASymbol.ImpliesSymbol) + symOp(TLASymbol.EquivSymbol) + alphaOp("TRUE", 0) + alphaOp("FALSE", 0) + alphaOp("BOOLEAN", 0) + + // sets + symOp(TLASymbol.EqualsSymbol) + symOp(TLASymbol.NotEqualsSymbol) + symOp(TLASymbol.InSymbol) + symOp(TLASymbol.IntersectSymbol) + symOp(TLASymbol.UnionSymbol) + symOp(TLASymbol.SubsetOrEqualSymbol) + symOp(TLASymbol.BackslashSymbol) + symOp(TLASymbol.PrefixSubsetSymbol) + symOp(TLASymbol.PrefixUnionSymbol) + + // functions + symOp(TLASymbol.DomainSymbol) + + // strings + alphaOp("STRING", 0) + + // action + symOp(TLASymbol.PrimeSymbol) + symOp(TLASymbol.EnabledSymbol) + symOp(TLASymbol.UnchangedSymbol) + symOp(TLASymbol.CDotSymbol) + + // temporal + symOp(TLASymbol.TLAlwaysSymbol) + symOp(TLASymbol.TLEventuallySymbol) + symOp(TLASymbol.SequencingSymbol) + symOp(TLASymbol.PlusArrowSymbol) + } + + lazy val builtinModules: Map[Definition.ScopeIdentifier,TLABuiltinModule] = Iterator( + TLC, + Sequences, FiniteSets, Bags, + Peano, ProtoReals, Naturals, Integers, Reals, + ).map(mod => mod.identifier -> mod).toMap + + object TLC extends TLABuiltinModule("TLC") { + alphaOp("Print", 2) + alphaOp("PrintT", 1) + alphaOp("Assert", 2) + alphaOp("JavaTime", 0) + alphaOp(":>", 2) + alphaOp("@@", 2) + alphaOp("Permutations", 1) + alphaOp("SortSeq", 2) + } + + object Sequences extends TLABuiltinModule("Sequences") { + alphaOp("Seq", 1) + alphaOp("Len", 1) + symOp(TLASymbol.OSymbol) + alphaOp("Append", 2) + alphaOp("Head", 1) + alphaOp("Tail", 1) + alphaOp("SubSeq", 3) + alphaOp("SelectSeq", 2) + } + + object FiniteSets extends TLABuiltinModule("FiniteSets") { + alphaOp("IsFiniteSet", 1) + alphaOp("Cardinality", 1) + } + + object Bags extends TLABuiltinModule("Bags") { + alphaOp("IsABag", 1) + alphaOp("BagToSet", 1) + alphaOp("SetToBag", 1) + alphaOp("BagIn", 2) + alphaOp("EmptyBag", 0) + alphaOp("CopiesIn", 2) + symOp(TLASymbol.OPlusSymbol) + symOp(TLASymbol.OMinusSymbol) + alphaOp("BagUnion", 1) + symOp(TLASymbol.SquareSupersetOrEqualSymbol) + alphaOp("SubBag", 1) + alphaOp("BagOfAll", 2) + alphaOp("BagCardinality", 1) + } + + object Peano extends TLABuiltinModule("Peano") { + alphaOp("PeanoAxioms", 3) + alphaOp("Succ", 0) + alphaOp("Nat", 0) + alphaOp("Zero", 0) + } + + object ProtoReals extends TLABuiltinModule("ProtoReals") { + extend(Peano) + + alphaOp("IsModelOfReals", 4) + alphaOp("RM", 0) + alphaOp("Real", 0) + alphaOp("Infinity", 0) + alphaOp("MinusInfinity", 0) + symOp(TLASymbol.PlusSymbol) + symOp(TLASymbol.AsteriskSymbol) + symOp(TLASymbol.LessThanOrEqualSymbol) + symOp(TLASymbol.MinusSymbol) + symOp(TLASymbol.SlashSymbol) + alphaOp("Int", 0) + symOp(TLASymbol.SuperscriptSymbol) + } + + object Naturals extends TLABuiltinModule("Naturals") { + op(ProtoReals.memberAlpha("Nat")) + op(ProtoReals.memberSym(TLASymbol.PlusSymbol)) + op(ProtoReals.memberSym(TLASymbol.MinusSymbol)) + op(ProtoReals.memberSym(TLASymbol.AsteriskSymbol)) + op(ProtoReals.memberSym(TLASymbol.SuperscriptSymbol)) + op(ProtoReals.memberSym(TLASymbol.LessThanOrEqualSymbol)) + symOp(TLASymbol.GreaterThanOrEqualSymbol) + symOp(TLASymbol.LessThanSymbol) + symOp(TLASymbol.GreaterThanSymbol) + symOp(TLASymbol.DotDotSymbol) + symOp(TLASymbol.DivSymbol) + symOp(TLASymbol.PercentSymbol) + } + + object Integers extends TLABuiltinModule("Integers") { + extend(Naturals) + + op(ProtoReals.memberAlpha("Int")) + symOp(TLASymbol.NegationSymbol) + } + + object Reals extends TLABuiltinModule("Reals") { + extend(Integers) + + op(ProtoReals.memberAlpha("Real")) + op(ProtoReals.memberSym(TLASymbol.SlashSymbol)) + op(ProtoReals.memberAlpha("Infinity")) + } +} diff --git a/src/pgo/model/tla/PlusCalDefaultInitValue.java b/src/pgo/model/tla/PlusCalDefaultInitValue.java deleted file mode 100644 index 703808db6..000000000 --- a/src/pgo/model/tla/PlusCalDefaultInitValue.java +++ /dev/null @@ -1,31 +0,0 @@ -package pgo.model.tla; - -import pgo.util.SourceLocation; - -public class PlusCalDefaultInitValue extends TLAExpression { - - public PlusCalDefaultInitValue(SourceLocation location) { - super(location); - } - - @Override - public TLAExpression copy() { - return new PlusCalDefaultInitValue(getLocation()); - } - - @Override - public T accept(TLAExpressionVisitor v) throws E { - return v.visit(this); - } - - @Override - public int hashCode() { - return 0; - } - - @Override - public boolean equals(Object obj) { - return obj instanceof PlusCalDefaultInitValue; - } - -} diff --git a/src/pgo/model/tla/TLAAssumption.java b/src/pgo/model/tla/TLAAssumption.java deleted file mode 100644 index 992be1fda..000000000 --- a/src/pgo/model/tla/TLAAssumption.java +++ /dev/null @@ -1,57 +0,0 @@ -package pgo.model.tla; - -import pgo.util.SourceLocation; -import scala.collection.immutable.List; -import scala.collection.immutable.List$; - -public class TLAAssumption extends TLAUnit { - - private final TLAExpression assumption; - - public TLAAssumption(SourceLocation location, TLAExpression assumption) { - super(location); - this.assumption = assumption; - } - - @Override - public List definitions() { - return List$.MODULE$.empty(); - } - - @Override - public TLAAssumption copy() { - return new TLAAssumption(getLocation(), assumption.copy()); - } - - public TLAExpression getAssumption() { - return assumption; - } - - @Override - public T accept(TLAUnitVisitor v) throws E { - return v.visit(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((assumption == null) ? 0 : assumption.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; - TLAAssumption other = (TLAAssumption) obj; - if (assumption == null) { - return other.assumption == null; - } else return assumption.equals(other.assumption); - } - -} diff --git a/src/pgo/model/tla/TLABinOp.java b/src/pgo/model/tla/TLABinOp.java deleted file mode 100644 index 291ccb85a..000000000 --- a/src/pgo/model/tla/TLABinOp.java +++ /dev/null @@ -1,105 +0,0 @@ -package pgo.model.tla; - -import pgo.util.SourceLocation; - -import java.util.List; -import java.util.stream.Collectors; - -/** - * - * AST PlusCalNode: - * - * lhs rhs - * - */ -public class TLABinOp extends TLAExpression { - - private final TLAExpression lhs; - private final TLAExpression rhs; - private final TLASymbol op; - private final List prefix; - private TLADefinitionOne refersTo; - - public TLABinOp(SourceLocation location, TLASymbol op, List prefix, TLAExpression lhs, TLAExpression rhs) { - super(location); - this.lhs = lhs; - this.rhs = rhs; - this.op = op; - this.prefix = prefix; - } - - public void setRefersTo(TLADefinitionOne refersTo) { - this.refersTo = refersTo; - } - - public TLADefinitionOne getRefersTo() { - return refersTo; - } - - @Override - public TLABinOp copy() { - return new TLABinOp(getLocation(), op, prefix.stream().map(TLAGeneralIdentifierPart::copy).collect(Collectors.toList()), lhs.copy(), rhs.copy()); - } - - public TLASymbol getOperation() { - return op; - } - - public TLAExpression getLHS() { - return lhs; - } - - public TLAExpression getRHS() { - return rhs; - } - - public List getPrefix(){ - return prefix; - } - - @Override - public T accept(TLAExpressionVisitor v) throws E { - return v.visit(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((lhs == null) ? 0 : lhs.hashCode()); - result = prime * result + ((op == null) ? 0 : op.hashCode()); - result = prime * result + ((prefix == null) ? 0 : prefix.hashCode()); - result = prime * result + ((rhs == null) ? 0 : rhs.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; - TLABinOp other = (TLABinOp) obj; - if (lhs == null) { - if (other.lhs != null) - return false; - } else if (!lhs.equals(other.lhs)) - return false; - if (op == null) { - if (other.op != null) - return false; - } else if (!op.equals(other.op)) - return false; - if (prefix == null) { - if (other.prefix != null) - return false; - } else if (!prefix.equals(other.prefix)) - return false; - if (rhs == null) { - return other.rhs == null; - } else return rhs.equals(other.rhs); - } - -} diff --git a/src/pgo/model/tla/TLABool.java b/src/pgo/model/tla/TLABool.java deleted file mode 100644 index 2f5c264b4..000000000 --- a/src/pgo/model/tla/TLABool.java +++ /dev/null @@ -1,48 +0,0 @@ -package pgo.model.tla; - -import pgo.util.SourceLocation; - -public class TLABool extends TLAExpression { - - private final boolean value; - - public TLABool(SourceLocation location, boolean value) { - super(location); - this.value = value; - } - - @Override - public TLABool copy() { - return new TLABool(getLocation(), value); - } - - public boolean getValue() { - return value; - } - - @Override - public T accept(TLAExpressionVisitor v) throws E { - return v.visit(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + (value ? 1231 : 1237); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - TLABool other = (TLABool) obj; - return value == other.value; - } - -} diff --git a/src/pgo/model/tla/TLABuilder.java b/src/pgo/model/tla/TLABuilder.java deleted file mode 100644 index 6a3a08b3d..000000000 --- a/src/pgo/model/tla/TLABuilder.java +++ /dev/null @@ -1,245 +0,0 @@ -package pgo.model.tla; - -import pgo.util.SourceLocation; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -public class TLABuilder { - private TLABuilder() {} - - public static TLASpecialVariableVariable DOLLAR_VARIABLE = new TLASpecialVariableVariable(SourceLocation.unknown()); - public static TLASpecialVariableValue DOLLAR_VALUE = new TLASpecialVariableValue(SourceLocation.unknown()); - - public static TLAFunction function(List args, TLAExpression body) { - return new TLAFunction(SourceLocation.unknown(), args, body); - } - - public static List bounds(TLAQuantifierBound... bounds){ - return Arrays.asList(bounds); - } - - public static List ids(TLAIdentifier... ids){ - return Arrays.asList(ids); - } - - public static TLAQuantifierBound qbIds(List ids, TLAExpression set) { - return new TLAQuantifierBound(SourceLocation.unknown(), TLAQuantifierBound.Type$.MODULE$.ids(), ids, set); - } - - public static TLAQuantifierBound qbTuple(List ids, TLAExpression set) { - return new TLAQuantifierBound(SourceLocation.unknown(), TLAQuantifierBound.Type$.MODULE$.tuple(), ids, set); - } - - public static TLAIdentifier id(String name) { - return new TLAIdentifier(SourceLocation.unknown(), name); - } - - public static TLAGeneralIdentifierPart idpart(TLAIdentifier id, TLAExpression... args) { - return new TLAGeneralIdentifierPart(SourceLocation.unknown(), id, Arrays.asList(args)); - } - - public static TLAGeneralIdentifierPart idpart(String id, TLAExpression... args) { - return idpart(id(id), args); - } - - public static List prefix(TLAGeneralIdentifierPart... parts){ - return Arrays.asList(parts); - } - - // expressions - - public static TLAGeneralIdentifier idexp(List prefix, TLAIdentifier name) { - return new TLAGeneralIdentifier(SourceLocation.unknown(), name, prefix); - } - - public static TLAGeneralIdentifier idexp(List prefix, String name) { - return idexp(prefix, id(name)); - } - - public static TLAGeneralIdentifier idexp(String name) { - return idexp(prefix(), id(name)); - } - - public static TLAString str(String contents) { - return new TLAString(SourceLocation.unknown(), contents); - } - - public static TLANumber num(int value) { - return new TLANumber(SourceLocation.unknown(), Integer.toString(value), TLANumber.Base.DECIMAL); - } - - public static TLASetConstructor set(TLAExpression... members) { - return new TLASetConstructor(SourceLocation.unknown(), Arrays.asList(members)); - } - - public static TLALet let(List units, TLAExpression body) { - return new TLALet(SourceLocation.unknown(), units, body); - } - - public static TLAOperatorCall opcall(List prefix, TLAIdentifier name, TLAExpression... args) { - return new TLAOperatorCall(SourceLocation.unknown(), name, prefix, Arrays.asList(args)); - } - - public static TLAOperatorCall opcall(String name, TLAExpression... args) { - return opcall(prefix(), id(name), args); - } - - public static TLAFunctionCall fncall(TLAExpression fn, TLAExpression... args) { - return new TLAFunctionCall(SourceLocation.unknown(), fn, Arrays.asList(args)); - } - - public static TLAFunctionSubstitution fnSubst(TLAExpression source, TLAFunctionSubstitutionPair... subs) { - return new TLAFunctionSubstitution(SourceLocation.unknown(), source, Arrays.asList(subs)); - } - - public static TLAFunctionSubstitutionPair fnSubstPair(List keys, TLAExpression value) { - return new TLAFunctionSubstitutionPair(SourceLocation.unknown(), keys, value); - } - - public static TLASubstitutionKey substKey(TLAExpression... indices) { - return new TLASubstitutionKey(SourceLocation.unknown(), Arrays.asList(indices)); - } - - public static TLASetRefinement setRefinement(String id, TLAExpression set, TLAExpression condition) { - return new TLASetRefinement(SourceLocation.unknown(), qbIds(Collections.singletonList(id(id)), set), condition); - } - - public static TLAFunctionSet functionSet(TLAExpression from, TLAExpression to) { - return new TLAFunctionSet(SourceLocation.unknown(), from, to); - } - - public static TLABinOp conjunct(TLAExpression lhs, TLAExpression rhs) { - return new TLABinOp(SourceLocation.unknown(), new TLASymbol(SourceLocation.unknown(), "/\\"), prefix(), lhs, rhs); - } - - public static TLACaseArm arm(TLAExpression cond, TLAExpression result) { - return new TLACaseArm(SourceLocation.unknown(), cond, result); - } - - public static List arms(TLACaseArm... arms){ - return Arrays.asList(arms); - } - - public static TLACase caseexp(List arms, TLAExpression other) { - return new TLACase(SourceLocation.unknown(), arms, other); - } - - public static TLASubstitutionKey key(TLAExpression... indices) { - return new TLASubstitutionKey(SourceLocation.unknown(), Arrays.asList(indices)); - } - - public static List keys(TLASubstitutionKey... keys){ - return Arrays.asList(keys); - } - - public static List keys(TLAExpression... keys){ - List result = new ArrayList<>(); - for(TLAExpression key : keys) { - result.add(key(key)); - } - return result; - } - - public static TLAFunctionSubstitutionPair sub(List keys, TLAExpression value) { - return new TLAFunctionSubstitutionPair(SourceLocation.unknown(), keys, value); - } - - public static TLAFunctionSubstitution except(TLAExpression f, TLAFunctionSubstitutionPair... subs) { - return new TLAFunctionSubstitution(SourceLocation.unknown(), f, Arrays.asList(subs)); - } - - public static TLAUnary unary(List prefix, String op, TLAExpression arg) { - return new TLAUnary(SourceLocation.unknown(), new TLASymbol(SourceLocation.unknown(), op), prefix, arg); - } - - public static TLAUnary unary(String op, TLAExpression arg) { - return unary(prefix(), op, arg); - } - - public static TLAQuantifiedUniversal universal(List bounds, TLAExpression expr) { - return new TLAQuantifiedUniversal(SourceLocation.unknown(), bounds, expr); - } - - public static TLAExistential uqExistential(List ids, TLAExpression expr) { - return new TLAExistential(SourceLocation.unknown(), ids, expr); - } - - public static TLAQuantifiedExistential existential(List bounds, TLAExpression expr) { - return new TLAQuantifiedExistential(SourceLocation.unknown(), bounds, expr); - } - - public static TLAModule module(String name, List exts, List units) { - return new TLAModule(SourceLocation.unknown(), id(name), exts, units); - } - - public static List opdecls(TLAOpDecl... opdecls){ - return Arrays.asList(opdecls); - } - - public static TLAOpDecl opdecl(TLAIdentifier name) { - return TLAOpDecl.Id(SourceLocation.unknown(), name); - } - - public static TLAOpDecl opdeclPrefix(TLAIdentifier name) { - return TLAOpDecl.Prefix(SourceLocation.unknown(), name); - } - - public static TLAOpDecl opdeclPostfix(TLAIdentifier name) { - return TLAOpDecl.Postfix(SourceLocation.unknown(), name); - } - - public static TLAOpDecl opdeclInfix(TLAIdentifier name) { - return TLAOpDecl.Infix(SourceLocation.unknown(), name); - } - - public static TLAOpDecl opdeclNamed(TLAIdentifier name, int arity) { - return TLAOpDecl.Named(SourceLocation.unknown(), name, arity); - } - - public static TLAOperatorDefinition opdef(boolean isLocal, TLAIdentifier id, List args, TLAExpression body) { - return new TLAOperatorDefinition(SourceLocation.unknown(), id, args, body, isLocal); - } - - public static TLAConstantDeclaration constants(TLAOpDecl... constants) { - return new TLAConstantDeclaration(SourceLocation.unknown(), Arrays.asList(constants)); - } - - public static TLABinOp binop(String op, TLAExpression lhs, TLAExpression rhs) { - return new TLABinOp(SourceLocation.unknown(), new TLASymbol(SourceLocation.unknown(), op), Collections.emptyList(), lhs, rhs); - } - - public static TLATuple tuple(TLAExpression... expressions) { - return new TLATuple(SourceLocation.unknown(), Arrays.asList(expressions)); - } - - public static TLAIf ifexp(TLAExpression cond, TLAExpression tval, TLAExpression fval) { - return new TLAIf(SourceLocation.unknown(), cond, tval, fval); - } - - public static TLAFairness fairness(TLAFairness.Type type, TLAExpression vars, TLAExpression expression){ - return new TLAFairness(SourceLocation.unknown(), type, vars, expression); - } - - public static TLABool bool(boolean val) { - return new TLABool(SourceLocation.unknown(), val); - } - - public static TLARef ref(String name) { - return new TLARef(SourceLocation.unknown(), name); - } - - public static TLARecordConstructor.Field field(TLAIdentifier name, TLAExpression expression) { - return new TLARecordConstructor.Field(SourceLocation.unknown(), name, expression); - } - - public static TLARecordConstructor record(TLARecordConstructor.Field... fields) { - return new TLARecordConstructor(SourceLocation.unknown(), Arrays.asList(fields)); - } - - public static TLADot dot(TLAExpression expression, String field) { - return new TLADot(SourceLocation.unknown(), expression, field); - } -} diff --git a/src/pgo/model/tla/TLABuiltinModules.scala b/src/pgo/model/tla/TLABuiltinModules.scala deleted file mode 100644 index 8608b26a6..000000000 --- a/src/pgo/model/tla/TLABuiltinModules.scala +++ /dev/null @@ -1,194 +0,0 @@ -package pgo.model.tla - -import pgo.scope.UID -import pgo.util.SourceLocation - -object TLABuiltinModules { - abstract class TLABuiltinModule(id: String) extends TLADefinitionOne { - override val getUID: UID = new UID() - override val identifier: TLAIdentifier = new TLAIdentifier(SourceLocation.unknown(), id) - - def members: List[TLABuiltinOperator] - lazy val memberMap: Map[TLAIdentifier,TLABuiltinOperator] = - members.flatMap(m => (m.identifier -> m) :: m.aliasIDs.map(a => a -> m)).toMap - - def member(id: String): TLABuiltinOperator = - memberMap(new TLAIdentifier(SourceLocation.unknown(), id)) - - override def arity: Int = 0 - - override def isModuleInstance: Boolean = false - - override def scope: Map[TLAIdentifier, TLADefinitionOne] = Map.empty - } - - final class TLABuiltinOperator(id: String, override val arity: Int, aliases: String*) extends TLADefinitionOne { - override val getUID: UID = new UID() - override val identifier: TLAIdentifier = new TLAIdentifier(SourceLocation.unknown(), id) - val aliasIDs: List[TLAIdentifier] = aliases.map(new TLAIdentifier(SourceLocation.unknown(), _)).toList - - override def isModuleInstance: Boolean = false - - override def scope: Map[TLAIdentifier, TLADefinitionOne] = Map.empty - } - - // these operators are always available - object Intrinsics extends TLABuiltinModule("") { - override val members: List[TLABuiltinOperator] = List( - // logic - new TLABuiltinOperator("/\\", 2, aliases = "\\land"), - new TLABuiltinOperator("\\/", 2, aliases = "\\lor"), - new TLABuiltinOperator("\\lnot", 1, aliases = "~", "\\neg"), - new TLABuiltinOperator("=>", 2), - new TLABuiltinOperator("<=>", 2, aliases = "\\equiv"), - new TLABuiltinOperator("TRUE", 0), - new TLABuiltinOperator("FALSE", 0), - new TLABuiltinOperator("BOOLEAN", 0), - - // sets - new TLABuiltinOperator("=", 2), - new TLABuiltinOperator("#", 2), // /= - new TLABuiltinOperator("\\in", 2), - new TLABuiltinOperator("\\notin", 2), - new TLABuiltinOperator("\\cap", 2, aliases = "\\intersect"), - new TLABuiltinOperator("\\cup", 2, aliases = "\\union"), - new TLABuiltinOperator("\\subseteq", 2), - new TLABuiltinOperator("\\", 2), - new TLABuiltinOperator("SUBSET", 1), - new TLABuiltinOperator("UNION", 1), - - // functions - new TLABuiltinOperator("DOMAIN", 1), - - // strings - new TLABuiltinOperator("STRING", 0), - - // action - new TLABuiltinOperator("'", 1), - new TLABuiltinOperator("ENABLED", 1), - new TLABuiltinOperator("UNCHANGED", 1), - new TLABuiltinOperator("\\cdot", 2), - - // temporal - new TLABuiltinOperator("[]", 1), - new TLABuiltinOperator("<>", 1), - new TLABuiltinOperator("~>", 2), - new TLABuiltinOperator("-+->", 2), - ) - } - - val builtinModules: Map[TLAIdentifier,TLABuiltinModule] = List( - TLC, - Sequences, FiniteSets, Bags, - Peano, ProtoReals, Naturals, Integers, Reals, - ).map(mod => mod.identifier -> mod).toMap - - object TLC extends TLABuiltinModule("TLC") { - override val members: List[TLABuiltinOperator] = List( - new TLABuiltinOperator("Print", 2), - new TLABuiltinOperator("PrintT", 1), - new TLABuiltinOperator("Assert", 2), - new TLABuiltinOperator("JavaTime", 0), - new TLABuiltinOperator(":>", 2), - new TLABuiltinOperator("@@", 2), - new TLABuiltinOperator("Permutations", 1), - new TLABuiltinOperator("SortSeq", 2), - ) - } - - object Sequences extends TLABuiltinModule("Sequences") { - override val members: List[TLABuiltinOperator] = List( - new TLABuiltinOperator("Seq", 1), - new TLABuiltinOperator("Len", 1), - new TLABuiltinOperator("\\o", 2, aliases = "\\circ"), - new TLABuiltinOperator("Append", 2), - new TLABuiltinOperator("Head", 1), - new TLABuiltinOperator("Tail", 1), - new TLABuiltinOperator("SubSeq", 3), - new TLABuiltinOperator("SelectSeq", 2), - ) - } - - object FiniteSets extends TLABuiltinModule("FiniteSets") { - override val members: List[TLABuiltinOperator] = List( - new TLABuiltinOperator("IsFiniteSet", 1), - new TLABuiltinOperator("Cardinality", 1), - ) - } - - object Bags extends TLABuiltinModule("Bags") { - override val members: List[TLABuiltinOperator] = List( - new TLABuiltinOperator("IsABag", 1), - new TLABuiltinOperator("BagToSet", 1), - new TLABuiltinOperator("SetToBag", 1), - new TLABuiltinOperator("BagIn", 2), - new TLABuiltinOperator("EmptyBag", 0), - new TLABuiltinOperator("CopiesIn", 2), - new TLABuiltinOperator("\\oplus", 2, aliases = "(+)"), - new TLABuiltinOperator("\\ominus", 2, aliases = "(-)"), - new TLABuiltinOperator("BagUnion", 1), - new TLABuiltinOperator("\\sqsubseteq", 2), - new TLABuiltinOperator("SubBag", 1), - new TLABuiltinOperator("BagOfAll", 2), - new TLABuiltinOperator("BagCardinality", 1), - ) - } - - object Peano extends TLABuiltinModule("Peano") { - override val members: List[TLABuiltinOperator] = List( - new TLABuiltinOperator("PeanoAxioms", 3), - new TLABuiltinOperator("Succ", 0), - new TLABuiltinOperator("Nat", 0), - new TLABuiltinOperator("Zero", 0), - ) - } - - object ProtoReals extends TLABuiltinModule("ProtoReals") { - override val members: List[TLABuiltinOperator] = Peano.members ++ List( - new TLABuiltinOperator("IsModelOfReals", 4), - new TLABuiltinOperator("RM", 0), - new TLABuiltinOperator("Real", 0), - new TLABuiltinOperator("Infinity", 0), - new TLABuiltinOperator("MinusInfinity", 0), - new TLABuiltinOperator("+", 2), - new TLABuiltinOperator("*", 2), - new TLABuiltinOperator("\\leq", 2, aliases = "<=", "=<"), - new TLABuiltinOperator("-", 2), - new TLABuiltinOperator("/", 2), - new TLABuiltinOperator("Int", 0), - new TLABuiltinOperator("^", 2), - ) - } - - object Naturals extends TLABuiltinModule("Naturals") { - override val members: List[TLABuiltinOperator] = List( - ProtoReals.member("Nat"), - ProtoReals.member("+"), - ProtoReals.member("-"), - ProtoReals.member("*"), - ProtoReals.member("^"), - ProtoReals.member("\\leq"), - new TLABuiltinOperator("\\geq", 2, aliases = ">="), - new TLABuiltinOperator("<", 2), - new TLABuiltinOperator(">", 2), - new TLABuiltinOperator("..", 2), - new TLABuiltinOperator("\\div", 2), - new TLABuiltinOperator("%", 2), - ) - } - - object Integers extends TLABuiltinModule("Integers") { - override val members: List[TLABuiltinOperator] = Naturals.members ++ List( - ProtoReals.member("Int"), - new TLABuiltinOperator("-_", 1), - ) - } - - object Reals extends TLABuiltinModule("Reals") { - override val members: List[TLABuiltinOperator] = Integers.members ++ List( - ProtoReals.member("Real"), - ProtoReals.member("/"), - ProtoReals.member("Infinity"), - ) - } -} diff --git a/src/pgo/model/tla/TLACase.java b/src/pgo/model/tla/TLACase.java deleted file mode 100644 index ded46289b..000000000 --- a/src/pgo/model/tla/TLACase.java +++ /dev/null @@ -1,78 +0,0 @@ -package pgo.model.tla; - -import pgo.util.SourceLocation; - -import java.util.List; -import java.util.stream.Collectors; - -/** - * - * PGo TLA AST: - * - * CASE x -> y - * [] z -> p - * [] OTHER -> other - * - */ -public class TLACase extends TLAExpression { - - private final List arms; - private final TLAExpression other; - - public TLACase(SourceLocation location, List arms, TLAExpression other) { - super(location); - this.arms = arms; - this.other = other; - } - - @Override - public TLACase copy() { - return new TLACase(getLocation(), arms.stream().map(TLACaseArm::copy).collect(Collectors.toList()), other != null ? other.copy() : null); - } - - public List getArms(){ - return arms; - } - - /** - * - * @return the default expression for the case expression, null if there isn't one - */ - public TLAExpression getOther() { - return other; - } - - @Override - public T accept(TLAExpressionVisitor v) throws E { - return v.visit(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((arms == null) ? 0 : arms.hashCode()); - result = prime * result + ((other == null) ? 0 : other.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; - TLACase other = (TLACase) obj; - if (arms == null) { - if (other.arms != null) - return false; - } else if (!arms.equals(other.arms)) - return false; - if (this.other == null) { - return other.other == null; - } else return this.other.equals(other.other); - } - -} diff --git a/src/pgo/model/tla/TLACaseArm.java b/src/pgo/model/tla/TLACaseArm.java deleted file mode 100644 index 6d23f177c..000000000 --- a/src/pgo/model/tla/TLACaseArm.java +++ /dev/null @@ -1,62 +0,0 @@ -package pgo.model.tla; - -import pgo.util.SourceLocation; - -public class TLACaseArm extends TLANode { - - private final TLAExpression cond; - private final TLAExpression result; - - public TLACaseArm(SourceLocation location, TLAExpression cond, TLAExpression result) { - super(location); - this.cond = cond; - this.result = result; - } - - @Override - public TLACaseArm copy() { - return new TLACaseArm(getLocation(), cond.copy(), result.copy()); - } - - public TLAExpression getCondition() { - return cond; - } - - public TLAExpression getResult() { - return result; - } - - @Override - public T accept(TLANodeVisitor v) throws E { - return v.visit(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((cond == null) ? 0 : cond.hashCode()); - result = prime * result + ((this.result == null) ? 0 : this.result.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; - TLACaseArm other = (TLACaseArm) obj; - if (cond == null) { - if (other.cond != null) - return false; - } else if (!cond.equals(other.cond)) - return false; - if (result == null) { - return other.result == null; - } else return result.equals(other.result); - } - -} diff --git a/src/pgo/model/tla/TLAConstantDeclaration.scala b/src/pgo/model/tla/TLAConstantDeclaration.scala deleted file mode 100644 index d07ee41c8..000000000 --- a/src/pgo/model/tla/TLAConstantDeclaration.scala +++ /dev/null @@ -1,29 +0,0 @@ -package pgo.model.tla - -import pgo.util.SourceLocation - -import scala.jdk.CollectionConverters._ - -final class TLAConstantDeclaration(loc: SourceLocation, val constants: List[TLAOpDecl]) extends TLAUnit(loc) with TLADefinitionComposite { - def this(loc: SourceLocation, constants: java.util.List[TLAOpDecl]) = - this(loc, constants.asScala.toList) - - override val definitions: List[TLADefinition] = List(this) - - @Deprecated - def getConstants: java.util.List[TLAOpDecl] = constants.asJava - - override def copy: TLAConstantDeclaration = new TLAConstantDeclaration(loc, constants.map(_.copy)) - - override def accept[T, E <: Throwable](v: TLAUnitVisitor[T, E]): T = v.visit(this) - - override def members: List[TLADefinition] = constants - - override def equals(other: Any): Boolean = other match { - case that: TLAConstantDeclaration => - constants == that.constants - case _ => false - } - - override def hashCode(): Int = constants.hashCode -} diff --git a/src/pgo/model/tla/TLADot.java b/src/pgo/model/tla/TLADot.java deleted file mode 100644 index e5fe2bce1..000000000 --- a/src/pgo/model/tla/TLADot.java +++ /dev/null @@ -1,52 +0,0 @@ -package pgo.model.tla; - -import pgo.util.SourceLocation; - -/* - * Represents `expr.field`. - */ -public class TLADot extends TLAExpression { - private final TLAExpression expression; - private final String field; - - public TLADot(SourceLocation location, TLAExpression expression, String field) { - super(location); - this.expression = expression; - this.field = field; - } - - @Override - public int hashCode() { - return expression.hashCode() * 17 + field.hashCode() * 19 + 3; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!(obj instanceof TLADot)) { - return false; - } - TLADot other = (TLADot) obj; - return expression.equals(other.expression) && field.equals(other.field); - } - - @Override - public TLAExpression copy() { - return new TLADot(getLocation(), expression.copy(), field); - } - - @Override - public T accept(TLAExpressionVisitor v) throws E { - return v.visit(this); - } - - public TLAExpression getExpression() { - return expression; - } - - public String getField() { - return field; - } -} diff --git a/src/pgo/model/tla/TLAExistential.java b/src/pgo/model/tla/TLAExistential.java deleted file mode 100644 index 310547b85..000000000 --- a/src/pgo/model/tla/TLAExistential.java +++ /dev/null @@ -1,73 +0,0 @@ -package pgo.model.tla; - -import pgo.util.SourceLocation; - -import java.util.List; -import java.util.stream.Collectors; - -/* - * TLA AST PlusCalNode: - * - * \E a, b, c : - * or - * \EE a, b, c : - * - */ -public class TLAExistential extends TLAExpression { - - private final List ids; - private final TLAExpression body; - - public TLAExistential(SourceLocation location, List ids, TLAExpression body) { - super(location); - this.ids = ids; - this.body = body; - } - - @Override - public TLAExistential copy() { - return new TLAExistential(getLocation(), ids.stream().map(TLAIdentifier::copy).collect(Collectors.toList()), body.copy()); - } - - public List getIds(){ - return ids; - } - - public TLAExpression getBody() { - return body; - } - - @Override - public T accept(TLAExpressionVisitor v) throws E { - return v.visit(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((body == null) ? 0 : body.hashCode()); - result = prime * result + ((ids == null) ? 0 : ids.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; - TLAExistential other = (TLAExistential) obj; - if (body == null) { - if (other.body != null) - return false; - } else if (!body.equals(other.body)) - return false; - if (ids == null) { - return other.ids == null; - } else return ids.equals(other.ids); - } - -} diff --git a/src/pgo/model/tla/TLAExpression.java b/src/pgo/model/tla/TLAExpression.java deleted file mode 100644 index 16a8171d2..000000000 --- a/src/pgo/model/tla/TLAExpression.java +++ /dev/null @@ -1,25 +0,0 @@ -package pgo.model.tla; - -import pgo.util.SourceLocation; - -/** - * Base TLA GoExpression representation - * - */ -public abstract class TLAExpression extends TLANode { - - public TLAExpression(SourceLocation location) { - super(location); - } - - @Override - public abstract TLAExpression copy(); - - @Override - public T accept(TLANodeVisitor v) throws E { - return v.visit(this); - } - - public abstract T accept(TLAExpressionVisitor v) throws E; - -} diff --git a/src/pgo/model/tla/TLAExpressionVisitor.java b/src/pgo/model/tla/TLAExpressionVisitor.java deleted file mode 100644 index d3d753397..000000000 --- a/src/pgo/model/tla/TLAExpressionVisitor.java +++ /dev/null @@ -1,36 +0,0 @@ -package pgo.model.tla; - -public abstract class TLAExpressionVisitor{ - public abstract T visit(TLAFunctionCall tlaFunctionCall) throws E; - public abstract T visit(TLABinOp tlaBinOp) throws E; - public abstract T visit(TLABool tlaBool) throws E; - public abstract T visit(TLACase tlaCase) throws E; - public abstract T visit(TLADot tlaDot) throws E; - public abstract T visit(TLAExistential tlaExistential) throws E; - public abstract T visit(TLAFairness tlaFairness) throws E; - public abstract T visit(TLAFunction tlaFunction) throws E; - public abstract T visit(TLAFunctionSet tlaFunctionSet) throws E; - public abstract T visit(TLAFunctionSubstitution tlaFunctionSubstitution) throws E; - public abstract T visit(TLAIf tlaIf) throws E; - public abstract T visit(TLALet tlaLet) throws E; - public abstract T visit(TLAGeneralIdentifier tlaGeneralIdentifier) throws E; - public abstract T visit(TLATuple tlaTuple) throws E; - public abstract T visit(TLAMaybeAction tlaMaybeAction) throws E; - public abstract T visit(TLANumber tlaNumber) throws E; - public abstract T visit(TLAOperatorCall tlaOperatorCall) throws E; - public abstract T visit(TLAQuantifiedExistential tlaQuantifiedExistential) throws E; - public abstract T visit(TLAQuantifiedUniversal tlaQuantifiedUniversal) throws E; - public abstract T visit(TLARecordConstructor tlaRecordConstructor) throws E; - public abstract T visit(TLARecordSet tlaRecordSet) throws E; - public abstract T visit(TLARef tlaRef) throws E; - public abstract T visit(TLARequiredAction tlaRequiredAction) throws E; - public abstract T visit(TLASetConstructor tlaSetConstructor) throws E; - public abstract T visit(TLASetComprehension tlaSetComprehension) throws E; - public abstract T visit(TLASetRefinement tlaSetRefinement) throws E; - public abstract T visit(TLASpecialVariableVariable tlaSpecialVariableVariable) throws E; - public abstract T visit(TLASpecialVariableValue tlaSpecialVariableValue) throws E; - public abstract T visit(TLAString tlaString) throws E; - public abstract T visit(TLAUnary tlaUnary) throws E; - public abstract T visit(TLAUniversal tlaUniversal) throws E; - public abstract T visit(PlusCalDefaultInitValue plusCalDefaultInitValue) throws E; -} diff --git a/src/pgo/model/tla/TLAFairness.java b/src/pgo/model/tla/TLAFairness.java deleted file mode 100644 index 93fcfd696..000000000 --- a/src/pgo/model/tla/TLAFairness.java +++ /dev/null @@ -1,61 +0,0 @@ -package pgo.model.tla; - -import pgo.util.SourceLocation; - -import java.util.Objects; - -public class TLAFairness extends TLAExpression { - - public enum Type { - STRONG, - WEAK, - } - - private final Type type; - private final TLAExpression vars; - private final TLAExpression expression; - - public TLAFairness(SourceLocation location, Type type, TLAExpression vars, TLAExpression expression){ - super(location); - this.type = type; - this.vars = vars; - this.expression = expression; - } - - public Type getType(){ - return type; - } - - public TLAExpression getVars(){ - return vars; - } - - public TLAExpression getExpression(){ - return expression; - } - - @Override - public TLAExpression copy() { - return new TLAFairness(getLocation(), type, vars.copy(), expression.copy()); - } - - @Override - public T accept(TLAExpressionVisitor v) throws E { - return v.visit(this); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - TLAFairness that = (TLAFairness) o; - return type == that.type && - Objects.equals(vars, that.vars) && - Objects.equals(expression, that.expression); - } - - @Override - public int hashCode() { - return Objects.hash(type, vars, expression); - } -} diff --git a/src/pgo/model/tla/TLAFunction.java b/src/pgo/model/tla/TLAFunction.java deleted file mode 100644 index ec032008a..000000000 --- a/src/pgo/model/tla/TLAFunction.java +++ /dev/null @@ -1,72 +0,0 @@ -package pgo.model.tla; - -import pgo.util.SourceLocation; - -import java.util.List; -import java.util.stream.Collectors; - -/** - * - * TLA AST PlusCalNode: - * - * [ a \in B, << c, d >> \in E |-> ] - * - */ -public class TLAFunction extends TLAExpression { - - private final List args; - private final TLAExpression body; - - public TLAFunction(SourceLocation location, List args, TLAExpression body) { - super(location); - this.args = args; - this.body = body; - } - - @Override - public TLAFunction copy() { - return new TLAFunction(getLocation(), args.stream().map(TLAQuantifierBound::copy).collect(Collectors.toList()), body.copy()); - } - - public List getArguments(){ - return args; - } - - public TLAExpression getBody() { - return body; - } - - @Override - public T accept(TLAExpressionVisitor v) throws E { - return v.visit(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((args == null) ? 0 : args.hashCode()); - result = prime * result + ((body == null) ? 0 : body.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; - TLAFunction other = (TLAFunction) obj; - if (args == null) { - if (other.args != null) - return false; - } else if (!args.equals(other.args)) - return false; - if (body == null) { - return other.body == null; - } else return body.equals(other.body); - } - -} diff --git a/src/pgo/model/tla/TLAFunctionCall.java b/src/pgo/model/tla/TLAFunctionCall.java deleted file mode 100644 index b265b0d4e..000000000 --- a/src/pgo/model/tla/TLAFunctionCall.java +++ /dev/null @@ -1,73 +0,0 @@ -package pgo.model.tla; - -import pgo.util.SourceLocation; - -import java.util.List; -import java.util.stream.Collectors; - -/** - * - * When returned by TLAParser, this can only mean this construct: - * - * fn[, ...] - * - */ -public class TLAFunctionCall extends TLAExpression { - - // the function called - private final TLAExpression function; - private final List params; - - public TLAFunctionCall(SourceLocation location, TLAExpression function, List params) { - super(location); - this.function = function; - this.params = params; - } - - @Override - public TLAFunctionCall copy() { - return new TLAFunctionCall(getLocation(), function.copy(), params.stream().map(TLAExpression::copy).collect(Collectors.toList())); - } - - public TLAExpression getFunction() { - return function; - } - - public List getParams() { - return params; - } - - @Override - public T accept(TLAExpressionVisitor v) throws E { - return v.visit(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((function == null) ? 0 : function.hashCode()); - result = prime * result + ((params == null) ? 0 : params.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; - TLAFunctionCall other = (TLAFunctionCall) obj; - if (function == null) { - if (other.function != null) - return false; - } else if (!function.equals(other.function)) - return false; - if (params == null) { - return other.params == null; - } else return params.equals(other.params); - } - -} diff --git a/src/pgo/model/tla/TLAFunctionDefinition.java b/src/pgo/model/tla/TLAFunctionDefinition.java deleted file mode 100644 index 6b57dcbec..000000000 --- a/src/pgo/model/tla/TLAFunctionDefinition.java +++ /dev/null @@ -1,96 +0,0 @@ -package pgo.model.tla; - -import pgo.util.SourceLocation; -import scala.collection.immutable.*; - -public class TLAFunctionDefinition extends TLAUnit implements TLADefinitionOne { - - private final TLAIdentifier name; - private final TLAFunction function; - private final boolean local; - - public TLAFunctionDefinition(SourceLocation location, TLAIdentifier name, TLAFunction function, boolean isLocal) { - super(location); - this.name = name; - this.function = function; - this.local = isLocal; - } - - @Override - public List definitions() { - return new $colon$colon<>(this, List$.MODULE$.empty()); - } - - @Override - public TLAFunctionDefinition copy() { - return new TLAFunctionDefinition(getLocation(), name.copy(), function.copy(), local); - } - - public TLAIdentifier getName() { - return name; - } - - public TLAFunction getFunction() { - return function; - } - - public boolean isLocal() { - return local; - } - - @Override - public int arity() { - return 0; - } - - @Override - public boolean isModuleInstance() { - return false; - } - - @Override - public TLAIdentifier identifier() { - return name; - } - - @Override - public Map scope() { - return Map$.MODULE$.empty(); - } - - @Override - public T accept(TLAUnitVisitor v) throws E { - return v.visit(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((function == null) ? 0 : function.hashCode()); - result = prime * result + (local ? 1231 : 1237); - result = prime * result + ((name == null) ? 0 : name.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; - TLAFunctionDefinition other = (TLAFunctionDefinition) obj; - if (function == null) { - if (other.function != null) - return false; - } else if (!function.equals(other.function)) - return false; - if (local != other.local) - return false; - if (name == null) { - return other.name == null; - } else return name.equals(other.name); - } -} diff --git a/src/pgo/model/tla/TLAFunctionSet.java b/src/pgo/model/tla/TLAFunctionSet.java deleted file mode 100644 index 36e3c714d..000000000 --- a/src/pgo/model/tla/TLAFunctionSet.java +++ /dev/null @@ -1,72 +0,0 @@ -package pgo.model.tla; - -import pgo.util.SourceLocation; - -/** - * - * TLA AST PlusCalNode: - * - * [ -> ] - * - * PlusCalWhile not required at the parsing level, each expr must result in a set. - * Defines the set of all functions having this signature. - * - */ -public class TLAFunctionSet extends TLAExpression { - - private final TLAExpression from; - private final TLAExpression to; - - public TLAFunctionSet(SourceLocation location, TLAExpression from, TLAExpression to) { - super(location); - this.from = from; - this.to = to; - } - - @Override - public TLAFunctionSet copy() { - return new TLAFunctionSet(getLocation(), from.copy(), to.copy()); - } - - public TLAExpression getFrom() { - return from; - } - - public TLAExpression getTo() { - return to; - } - - @Override - public T accept(TLAExpressionVisitor v) throws E { - return v.visit(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((from == null) ? 0 : from.hashCode()); - result = prime * result + ((to == null) ? 0 : to.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; - TLAFunctionSet other = (TLAFunctionSet) obj; - if (from == null) { - if (other.from != null) - return false; - } else if (!from.equals(other.from)) - return false; - if (to == null) { - return other.to == null; - } else return to.equals(other.to); - } - -} diff --git a/src/pgo/model/tla/TLAFunctionSubstitution.java b/src/pgo/model/tla/TLAFunctionSubstitution.java deleted file mode 100644 index 04b8d9536..000000000 --- a/src/pgo/model/tla/TLAFunctionSubstitution.java +++ /dev/null @@ -1,72 +0,0 @@ -package pgo.model.tla; - -import pgo.util.SourceLocation; - -import java.util.List; -import java.util.stream.Collectors; - -/** - * - * PGo TLA AST: - * - * [ Fn EXCEPT !.a = 2, ![1,2,3] = e, !.a.b[2].c = q, ... ] - * - */ -public class TLAFunctionSubstitution extends TLAExpression { - - private final TLAExpression source; - private final List subs; - - public TLAFunctionSubstitution(SourceLocation location, TLAExpression source, List subs) { - super(location); - this.source = source; - this.subs = subs; - } - - @Override - public TLAFunctionSubstitution copy() { - return new TLAFunctionSubstitution(getLocation(), source.copy(), subs.stream().map(TLAFunctionSubstitutionPair::copy).collect(Collectors.toList())); - } - - public TLAExpression getSource() { - return source; - } - - public List getSubstitutions(){ - return subs; - } - - @Override - public T accept(TLAExpressionVisitor v) throws E { - return v.visit(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((source == null) ? 0 : source.hashCode()); - result = prime * result + ((subs == null) ? 0 : subs.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; - TLAFunctionSubstitution other = (TLAFunctionSubstitution) obj; - if (source == null) { - if (other.source != null) - return false; - } else if (!source.equals(other.source)) - return false; - if (subs == null) { - return other.subs == null; - } else return subs.equals(other.subs); - } - -} diff --git a/src/pgo/model/tla/TLAFunctionSubstitutionPair.java b/src/pgo/model/tla/TLAFunctionSubstitutionPair.java deleted file mode 100644 index 1e9a12fd0..000000000 --- a/src/pgo/model/tla/TLAFunctionSubstitutionPair.java +++ /dev/null @@ -1,65 +0,0 @@ -package pgo.model.tla; - -import pgo.util.SourceLocation; - -import java.util.List; -import java.util.stream.Collectors; - -public class TLAFunctionSubstitutionPair extends TLANode { - - private final List keys; - private final TLAExpression value; - - public TLAFunctionSubstitutionPair(SourceLocation location, List keys, TLAExpression value) { - super(location); - this.keys = keys; - this.value = value; - } - - @Override - public TLAFunctionSubstitutionPair copy() { - return new TLAFunctionSubstitutionPair(getLocation(), keys.stream().map(TLASubstitutionKey::copy).collect(Collectors.toList()), value.copy()); - } - - @Override - public T accept(TLANodeVisitor v) throws E { - return v.visit(this); - } - - public List getKeys(){ - return keys; - } - - public TLAExpression getValue() { - return value; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((keys == null) ? 0 : keys.hashCode()); - result = prime * result + ((value == null) ? 0 : value.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; - TLAFunctionSubstitutionPair other = (TLAFunctionSubstitutionPair) obj; - if (keys == null) { - if (other.keys != null) - return false; - } else if (!keys.equals(other.keys)) - return false; - if (value == null) { - return other.value == null; - } else return value.equals(other.value); - } - -} diff --git a/src/pgo/model/tla/TLAGeneralIdentifier.scala b/src/pgo/model/tla/TLAGeneralIdentifier.scala deleted file mode 100644 index c961454ed..000000000 --- a/src/pgo/model/tla/TLAGeneralIdentifier.scala +++ /dev/null @@ -1,50 +0,0 @@ -package pgo.model.tla - -import pgo.util.SourceLocation - -import scala.jdk.CollectionConverters._ - -/** - * Variable access in TLA Expr - * - */ -final class TLAGeneralIdentifier(loc: SourceLocation, val name: TLAIdentifier, val prefix: List[TLAGeneralIdentifierPart]) extends TLAExpression(loc) { - private var refersTo: Option[TLADefinitionOne] = None - - def this(loc: SourceLocation, name: TLAIdentifier, prefix: java.util.List[TLAGeneralIdentifierPart]) = - this(loc, name, prefix.asScala.toList) - - def setRefersTo(refersTo: TLADefinitionOne): Unit = { - this.refersTo match { - case Some(ref) => assert(ref eq refersTo) - case None => - this.refersTo = Some(refersTo) - } - } - - def getRefersTo: TLADefinitionOne = refersTo.get - - override def copy: TLAGeneralIdentifier = { - val result = new TLAGeneralIdentifier(getLocation, name.copy, prefix.map(_.copy())) - result.setRefersTo(getRefersTo) // so that wanton copying doesn't break references - result - } - - def getName: TLAIdentifier = name - - def getGeneralIdentifierPrefix: java.util.List[TLAGeneralIdentifierPart] = prefix.asJava - - override def accept[T, E <: Throwable](v: TLAExpressionVisitor[T, E]): T = v.visit(this) - - override def equals(other: Any): Boolean = other match { - case that: TLAGeneralIdentifier => - name == that.name && - prefix == that.prefix - case _ => false - } - - override def hashCode(): Int = { - val state = Seq(name, prefix) - state.map(_.hashCode()).foldLeft(0)((a, b) => 31 * a + b) - } -} \ No newline at end of file diff --git a/src/pgo/model/tla/TLAGeneralIdentifierPart.java b/src/pgo/model/tla/TLAGeneralIdentifierPart.java deleted file mode 100644 index dd4330d50..000000000 --- a/src/pgo/model/tla/TLAGeneralIdentifierPart.java +++ /dev/null @@ -1,68 +0,0 @@ -package pgo.model.tla; - -import pgo.util.SourceLocation; - -import java.util.List; -import java.util.stream.Collectors; - -public class TLAGeneralIdentifierPart extends TLANode { - - private final TLAIdentifier id; - private final List parameters; - - public TLAGeneralIdentifierPart(SourceLocation location, TLAIdentifier id, List parameters) { - super(location); - this.id = id; - this.parameters = parameters; - } - - @Override - public TLAGeneralIdentifierPart copy() { - return new TLAGeneralIdentifierPart( - getLocation(), - id.copy(), - parameters.stream().map(TLAExpression::copy).collect(Collectors.toList())); - } - - @Override - public T accept(TLANodeVisitor v) throws E { - return v.visit(this); - } - - public TLAIdentifier getIdentifier() { - return id; - } - - public List getParameters(){ - return parameters; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((id == null) ? 0 : id.hashCode()); - result = prime * result + ((parameters == null) ? 0 : parameters.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; - TLAGeneralIdentifierPart other = (TLAGeneralIdentifierPart) obj; - if (id == null) { - if (other.id != null) - return false; - } else if (!id.equals(other.id)) - return false; - if (parameters == null) { - return other.parameters == null; - } else return parameters.equals(other.parameters); - } - -} diff --git a/src/pgo/model/tla/TLAIdentifier.java b/src/pgo/model/tla/TLAIdentifier.java deleted file mode 100644 index b9e2b14f1..000000000 --- a/src/pgo/model/tla/TLAIdentifier.java +++ /dev/null @@ -1,78 +0,0 @@ -package pgo.model.tla; - -import pgo.util.SourceLocation; -import scala.collection.immutable.Map$; -import scala.collection.immutable.Map; - -/** - * - * AST PlusCalNode representing a single identifier. This allows us to attach metadata at - * the identifier level. - * - */ -public class TLAIdentifier extends TLANode implements TLADefinitionOne { - - private final String id; - - public TLAIdentifier(SourceLocation location, String id) { - super(location); - this.id = id; - } - - @Override - public TLAIdentifier copy() { - throw new RuntimeException("bad"); - //return new TLAIdentifier(getLocation(), id); - } - - @Override - public T accept(TLANodeVisitor v) throws E { - return v.visit(this); - } - - public String getId() { - return id; - } - - @Override - public int arity() { - return 0; - } - - @Override - public boolean isModuleInstance() { - return false; - } - - @Override - public TLAIdentifier identifier() { - return this; - } - - @Override - public Map scope() { - return Map$.MODULE$.empty(); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((id == null) ? 0 : id.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; - TLAIdentifier other = (TLAIdentifier) obj; - if (id == null) { - return other.id == null; - } else return id.equals(other.id); - } -} diff --git a/src/pgo/model/tla/TLAIdentifierOrTuple.java b/src/pgo/model/tla/TLAIdentifierOrTuple.java deleted file mode 100644 index 6990ea6bc..000000000 --- a/src/pgo/model/tla/TLAIdentifierOrTuple.java +++ /dev/null @@ -1,93 +0,0 @@ -package pgo.model.tla; - -import pgo.util.SourceLocation; - -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; - -/** - * - * Some parts of the grammar can either result in a single identifier or - * a tuple of identifiers. This allows parts of the parser to return - * the sum type-like result they expect. - * - * a - * or - * << a, b, c >> - * - */ -public class TLAIdentifierOrTuple extends TLANode { - - private final List ids; - private final boolean tuple; - - private TLAIdentifierOrTuple(SourceLocation location, List ids, boolean isTuple) { - super(location); - this.ids = ids; - this.tuple = isTuple; - } - - @Override - public TLAIdentifierOrTuple copy() { - return new TLAIdentifierOrTuple(getLocation(), ids.stream().map(TLAIdentifier::copy).collect(Collectors.toList()), tuple); - } - - @Override - public T accept(TLANodeVisitor v) throws E { - return v.visit(this); - } - - public static TLAIdentifierOrTuple Identifier(TLAIdentifier id) { - return new TLAIdentifierOrTuple(id.getLocation(), Collections.singletonList(id), false); - } - - public static TLAIdentifierOrTuple Tuple(SourceLocation location, List ids) { - return new TLAIdentifierOrTuple(location, ids, true); - } - - public boolean isTuple() { - return tuple; - } - - public TLAIdentifier getId() { - if(ids.size() != 1 || tuple) { - throw new RuntimeException("tried to treat an identifier tuple as an identifier: was "+ids); - } - return ids.get(0); - } - - public List getTuple(){ - if(!tuple) { - throw new RuntimeException("tried to treat an identifier as an identifier tuple: was "+ids); - } - return ids; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((ids == null) ? 0 : ids.hashCode()); - result = prime * result + (tuple ? 1231 : 1237); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - TLAIdentifierOrTuple other = (TLAIdentifierOrTuple) obj; - if (ids == null) { - if (other.ids != null) - return false; - } else if (!ids.equals(other.ids)) - return false; - return tuple == other.tuple; - } - -} diff --git a/src/pgo/model/tla/TLAIf.java b/src/pgo/model/tla/TLAIf.java deleted file mode 100644 index cb2568759..000000000 --- a/src/pgo/model/tla/TLAIf.java +++ /dev/null @@ -1,81 +0,0 @@ -package pgo.model.tla; - -import pgo.util.SourceLocation; - -/** - * - * TLA AST PlusCalNode: - * - * IF THEN ELSE - * - */ -public class TLAIf extends TLAExpression { - - private final TLAExpression cond; - private final TLAExpression tval; - private final TLAExpression fval; - - public TLAIf(SourceLocation location, TLAExpression cond, TLAExpression tval, TLAExpression fval) { - super(location); - this.cond = cond; - this.tval = tval; - this.fval = fval; - } - - @Override - public TLAIf copy() { - return new TLAIf(getLocation(), cond.copy(), tval.copy(), fval.copy()); - } - - @Override - public T accept(TLAExpressionVisitor v) throws E { - return v.visit(this); - } - - public TLAExpression getCond() { - return cond; - } - - public TLAExpression getTval() { - return tval; - } - - public TLAExpression getFval() { - return fval; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((cond == null) ? 0 : cond.hashCode()); - result = prime * result + ((fval == null) ? 0 : fval.hashCode()); - result = prime * result + ((tval == null) ? 0 : tval.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; - TLAIf other = (TLAIf) obj; - if (cond == null) { - if (other.cond != null) - return false; - } else if (!cond.equals(other.cond)) - return false; - if (fval == null) { - if (other.fval != null) - return false; - } else if (!fval.equals(other.fval)) - return false; - if (tval == null) { - return other.tval == null; - } else return tval.equals(other.tval); - } - -} diff --git a/src/pgo/model/tla/TLAInstance.scala b/src/pgo/model/tla/TLAInstance.scala deleted file mode 100644 index f95662f0c..000000000 --- a/src/pgo/model/tla/TLAInstance.scala +++ /dev/null @@ -1,74 +0,0 @@ -package pgo.model.tla - -import pgo.util.SourceLocation - -import scala.jdk.CollectionConverters._ - -final class TLAInstance(loc: SourceLocation, val moduleName: TLAIdentifier, val remappings: List[TLAInstance.Remapping], - val isLocal: Boolean) extends TLAUnit(loc) with TLADefinitionComposite { - var module: Option[TLAModule] = None - - def this(loc: SourceLocation, moduleName: TLAIdentifier, remappings: java.util.List[TLAInstance.Remapping], isLocal: Boolean) = - this(loc, moduleName, remappings.asScala.toList, isLocal) - - override val definitions: List[TLADefinition] = List(this) - - def getModuleName: TLAIdentifier = moduleName - def getRemappings: java.util.List[TLAInstance.Remapping] = remappings.asJava - - override def copy: TLAInstance = - new TLAInstance(loc, moduleName.copy(), remappings.map(_.copy()), isLocal) - - override def members: List[TLADefinition] = - module.get.definitions - - override def accept[T, E <: Throwable](v: TLAUnitVisitor[T, E]): T = v.visit(this) - - def canEqual(other: Any): Boolean = other.isInstanceOf[TLAInstance] - - override def equals(other: Any): Boolean = other match { - case that: TLAInstance => - (that canEqual this) && - moduleName == that.moduleName && - remappings == that.remappings && - isLocal == that.isLocal - case _ => false - } - - override def hashCode(): Int = { - val state = Seq(moduleName, remappings, isLocal) - state.map(_.hashCode()).foldLeft(0)((a, b) => 31 * a + b) - } -} - -object TLAInstance { - final class Remapping(loc: SourceLocation, val from: TLAIdentifier, val to: TLAExpression) extends TLANode(loc) with TLADefinitionOne { - override def copy(): Remapping = - new Remapping(loc, from.copy(), to.copy()) - - def getFrom: TLAIdentifier = from - def getTo: TLAExpression = to - - override def accept[T, E <: Throwable](v: TLANodeVisitor[T, E]): T = v.visit(this) - - override def arity: Int = 0 - - override def isModuleInstance: Boolean = false - - override def identifier: TLAIdentifier = from - - override def scope: Map[TLAIdentifier, TLADefinitionOne] = Map.empty - - override def equals(other: Any): Boolean = other match { - case that: Remapping => - from == that.from && - to == that.to - case _ => false - } - - override def hashCode(): Int = { - val state = Seq(from, to) - state.map(_.hashCode()).foldLeft(0)((a, b) => 31 * a + b) - } - } -} diff --git a/src/pgo/model/tla/TLALet.java b/src/pgo/model/tla/TLALet.java deleted file mode 100644 index 293d7cfc6..000000000 --- a/src/pgo/model/tla/TLALet.java +++ /dev/null @@ -1,77 +0,0 @@ -package pgo.model.tla; - -import pgo.util.SourceLocation; - -import java.util.List; -import java.util.stream.Collectors; - -/** - * - * TLA AST Node: - * - * LET op(a, b, c) == - * fn[d \in D] == - * e + f == - * g == INSTANCE ... - * IN - * - * - */ -public class TLALet extends TLAExpression { - - private final TLAExpression body; - private final List defs; - - public TLALet(SourceLocation location, List defs, TLAExpression body) { - super(location); - this.defs = defs; - this.body = body; - } - - @Override - public TLALet copy() { - return new TLALet(getLocation(), defs.stream().map(TLAUnit::copy).collect(Collectors.toList()), body.copy()); - } - - public List getDefinitions(){ - return defs; - } - - public TLAExpression getBody() { - return body; - } - - @Override - public T accept(TLAExpressionVisitor v) throws E { - return v.visit(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((body == null) ? 0 : body.hashCode()); - result = prime * result + ((defs == null) ? 0 : defs.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; - TLALet other = (TLALet) obj; - if (body == null) { - if (other.body != null) - return false; - } else if (!body.equals(other.body)) - return false; - if (defs == null) { - return other.defs == null; - } else return defs.equals(other.defs); - } - -} diff --git a/src/pgo/model/tla/TLAMaybeAction.java b/src/pgo/model/tla/TLAMaybeAction.java deleted file mode 100644 index 4d2dbfa91..000000000 --- a/src/pgo/model/tla/TLAMaybeAction.java +++ /dev/null @@ -1,69 +0,0 @@ -package pgo.model.tla; - -import pgo.util.SourceLocation; - -/** - * - * TLA AST PlusCalNode: - * - * [ ]_ - * - */ -public class TLAMaybeAction extends TLAExpression { - - private final TLAExpression body; - private final TLAExpression vars; - - public TLAMaybeAction(SourceLocation location, TLAExpression body, TLAExpression vars) { - super(location); - this.body = body; - this.vars = vars; - } - - @Override - public TLAMaybeAction copy() { - return new TLAMaybeAction(getLocation(), body.copy(), vars.copy()); - } - - @Override - public T accept(TLAExpressionVisitor v) throws E { - return v.visit(this); - } - - public TLAExpression getBody() { - return body; - } - - public TLAExpression getVars() { - return vars; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((body == null) ? 0 : body.hashCode()); - result = prime * result + ((vars == null) ? 0 : vars.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; - TLAMaybeAction other = (TLAMaybeAction) obj; - if (body == null) { - if (other.body != null) - return false; - } else if (!body.equals(other.body)) - return false; - if (vars == null) { - return other.vars == null; - } else return vars.equals(other.vars); - } - -} diff --git a/src/pgo/model/tla/TLAModule.scala b/src/pgo/model/tla/TLAModule.scala deleted file mode 100644 index 308b0d4cb..000000000 --- a/src/pgo/model/tla/TLAModule.scala +++ /dev/null @@ -1,46 +0,0 @@ -package pgo.model.tla - -import pgo.util.SourceLocation - -import scala.jdk.CollectionConverters._ - -class TLAModule(loc: SourceLocation, val name: TLAIdentifier, val exts: List[TLAModuleExtends], - val units: List[TLAUnit]) extends TLAUnit(loc) with TLADefinitionOne { - def this(loc: SourceLocation, name: TLAIdentifier, exts: java.util.List[TLAIdentifier], units: java.util.List[TLAUnit]) = - this(loc, name, exts.asScala.map(ext => TLAModuleExtendsBuiltin(TLABuiltinModules.builtinModules(ext))).toList, units.asScala.toList) - - def getName: TLAIdentifier = name - def getExtends: java.util.List[TLAModuleExtends] = exts.asJava - def getUnits: java.util.List[TLAUnit] = units.asJava - - override def arity: Int = 0 - - override def isModuleInstance: Boolean = false - - override def identifier: TLAIdentifier = name - - override def scope: Map[TLAIdentifier, TLADefinitionOne] = Map.empty - - override lazy val definitions: List[TLADefinition] = List(this) - - override def copy: TLAModule = - new TLAModule(loc, name.copy(), exts, units.map(_.copy())) - - override def accept[T, E <: Throwable](v: TLAUnitVisitor[T, E]): T = v.visit(this) - - def canEqual(other: Any): Boolean = other.isInstanceOf[TLAModule] - - override def equals(other: Any): Boolean = other match { - case that: TLAModule => - (that canEqual this) && - name == that.name && - exts == that.exts && - units == that.units - case _ => false - } - - override def hashCode(): Int = { - val state = Seq(name, exts, units) - state.map(_.hashCode()).foldLeft(0)((a, b) => 31 * a + b) - } -} diff --git a/src/pgo/model/tla/TLAModuleDefinition.scala b/src/pgo/model/tla/TLAModuleDefinition.scala deleted file mode 100644 index 8f70b3035..000000000 --- a/src/pgo/model/tla/TLAModuleDefinition.scala +++ /dev/null @@ -1,55 +0,0 @@ -package pgo.model.tla - -import pgo.util.SourceLocation - -import scala.jdk.CollectionConverters._ - -final class TLAModuleDefinition(loc: SourceLocation, val name: TLAIdentifier, val args: List[TLAOpDecl], val instance: TLAInstance, - val isLocal: Boolean) extends TLAUnit(loc) with TLADefinitionOne { - def this(loc: SourceLocation, name: TLAIdentifier, args: java.util.List[TLAOpDecl], instance: TLAInstance, isLocal: Boolean) = - this(loc, name, args.asScala.toList, instance, isLocal) - - override val definitions: List[TLADefinition] = List(this) - - override def copy: TLAModuleDefinition = - new TLAModuleDefinition(loc, name.copy(), args.map(_.copy()), instance.copy(), isLocal) - - def getName: TLAIdentifier = name - - def getArgs: java.util.List[TLAOpDecl] = args.asJava - - def getInstance: TLAInstance = instance - - override def arity: Int = args.length - - override def isModuleInstance = true - - override def identifier: TLAIdentifier = name - - override lazy val scope: Map[TLAIdentifier, TLADefinitionOne] = { - def impl(members: List[TLADefinition]): List[(TLAIdentifier,TLADefinitionOne)] = - members.flatMap { - case defn: TLADefinitionOne => List(defn.identifier -> defn) - case defn: TLADefinitionComposite => impl(defn.members) - } - impl(instance.members).toMap - } - - override def accept[T, E <: Throwable](v: TLAUnitVisitor[T, E]): T = - v.visit(this) - - - override def equals(other: Any): Boolean = other match { - case that: TLAModuleDefinition => - name == that.name && - args == that.args && - instance == that.instance && - isLocal == that.isLocal - case _ => false - } - - override def hashCode(): Int = { - val state = Seq(name, args, instance, isLocal) - state.map(_.hashCode()).foldLeft(0)((a, b) => 31 * a + b) - } -} diff --git a/src/pgo/model/tla/TLAModuleExtends.scala b/src/pgo/model/tla/TLAModuleExtends.scala deleted file mode 100644 index e84dc2170..000000000 --- a/src/pgo/model/tla/TLAModuleExtends.scala +++ /dev/null @@ -1,16 +0,0 @@ -package pgo.model.tla - -sealed abstract class TLAModuleExtends extends TLADefinitionComposite { - def identifier: TLAIdentifier -} - -final case class TLAModuleExtendsBuiltin(module: TLABuiltinModules.TLABuiltinModule) extends TLAModuleExtends { - override def identifier: TLAIdentifier = module.identifier - - override def members: List[TLADefinition] = module.members -} -final case class TLAModuleExtendsModule(module: TLAModule) extends TLAModuleExtends { - override def identifier: TLAIdentifier = module.name - - override def members: List[TLADefinition] = module.definitions -} diff --git a/src/pgo/model/tla/TLANode.java b/src/pgo/model/tla/TLANode.java deleted file mode 100644 index e6cdf8899..000000000 --- a/src/pgo/model/tla/TLANode.java +++ /dev/null @@ -1,60 +0,0 @@ -package pgo.model.tla; - -import pgo.formatters.IndentingWriter; -import pgo.formatters.TLANodeFormattingVisitor; -import pgo.scope.UID; -import pgo.util.SourceLocatable; -import pgo.util.SourceLocation; - -import java.io.IOException; -import java.io.StringWriter; - -/** - * - * The base class for any TLA AST node. Usually too vague to be useful, - * but can be useful in error reporting as it defines every TLA AST node - * as knowing their source file location. - * - */ -public abstract class TLANode extends SourceLocatable { - private final SourceLocation location; - private final UID uid; - - public TLANode(SourceLocation location) { - this.location = location; - this.uid = new UID(); - this.uid.addOrigin(this); - } - - @Override - public SourceLocation getLocation() { - return location; - } - - public UID getUID() { - return uid; - } - - @Override - public abstract int hashCode(); - - @Override - public abstract boolean equals(Object obj); - - @Override - public String toString() { - StringWriter out = new StringWriter(); - try { - accept(new TLANodeFormattingVisitor(new IndentingWriter(out))); - } catch (IOException e) { - RuntimeException ex = new RuntimeException("You should never get an IO error from a StringWriter", e); - throw ex; - } - return out.toString(); - } - - public abstract TLANode copy(); - - public abstract T accept(TLANodeVisitor v) throws E; - -} diff --git a/src/pgo/model/tla/TLANodeVisitor.java b/src/pgo/model/tla/TLANodeVisitor.java deleted file mode 100644 index 0d6737497..000000000 --- a/src/pgo/model/tla/TLANodeVisitor.java +++ /dev/null @@ -1,18 +0,0 @@ -package pgo.model.tla; - -public abstract class TLANodeVisitor{ - public abstract T visit(TLAExpression TLAExpression) throws E; - public abstract T visit(TLAUnit pGoTLAUnit) throws E; - public abstract T visit(TLACaseArm TLACaseArm) throws E; - public abstract T visit(TLAOpDecl pGoTLAOpDecl) throws E; - public abstract T visit(TLASubstitutionKey pGoTLASubstitutionKey) throws E; - public abstract T visit(TLARecordSet.Field field) throws E; - public abstract T visit(TLARecordConstructor.Field field) throws E; - public abstract T visit(TLAQuantifierBound pGoTLAQuantifierBound) throws E; - public abstract T visit(TLAInstance.Remapping remapping) throws E; - public abstract T visit(TLAIdentifierOrTuple pGoTLAIdentifierOrTuple) throws E; - public abstract T visit(TLAIdentifier pGoTLAIdentifier) throws E; - public abstract T visit(TLAGeneralIdentifierPart pGoTLAGeneralIdentifierPart) throws E; - public abstract T visit(TLAFunctionSubstitutionPair pGoTLAFunctionSubstitutionPair) throws E; - public abstract T visit(TLASymbol pGoTLASymbol) throws E; -} \ No newline at end of file diff --git a/src/pgo/model/tla/TLANumber.java b/src/pgo/model/tla/TLANumber.java deleted file mode 100644 index aaa71c67c..000000000 --- a/src/pgo/model/tla/TLANumber.java +++ /dev/null @@ -1,64 +0,0 @@ -package pgo.model.tla; - -import pgo.util.SourceLocation; - -/** - * Represents a tla token for a number - * - */ -public class TLANumber extends TLAExpression { - - public enum Base { - DECIMAL, - BINARY, - OCTAL, - HEXADECIMAL - } - - private final String val; - private final Base base; - - public TLANumber(SourceLocation location, String val, Base base) { - super(location); - this.val = val; - this.base = base; - } - - @Override - public TLANumber copy() { - return new TLANumber(getLocation(), val, base); - } - - public String getVal() { - return val; - } - - public Base getBase() { return base; } - - @Override - public T accept(TLAExpressionVisitor v) throws E { - return v.visit(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((val == null) ? 0 : val.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; - TLANumber other = (TLANumber) obj; - if (val == null) { - return other.val == null; - } else return val.equals(other.val); - } -} diff --git a/src/pgo/model/tla/TLAOpDecl.java b/src/pgo/model/tla/TLAOpDecl.java deleted file mode 100644 index f394b2d75..000000000 --- a/src/pgo/model/tla/TLAOpDecl.java +++ /dev/null @@ -1,137 +0,0 @@ -package pgo.model.tla; - -import pgo.util.SourceLocation; -import scala.collection.immutable.Map$; -import scala.collection.immutable.Map; - -/** - * - * TLA AST PlusCalNode, representing the kinds of things you can find in - * TLA operator definition parameter lists. The special cases are usually - * used for higher-order operators. - * - */ -public class TLAOpDecl extends TLANode implements TLADefinitionOne { - - public enum Type{ - INFIX, - PREFIX, - POSTFIX, - NAMED, - ID, - } - - private final TLAIdentifier name; - private final Type type; - private final int arity; - - private TLAOpDecl(SourceLocation location, TLAIdentifier name, Type type, int arity) { - super(location); - this.name = name; - this.type = type; - this.arity = arity; - } - - @Override - public int arity() { - switch(type) { - case INFIX: - return 2; - case PREFIX: - case POSTFIX: - return 1; - case NAMED: - return arity; - case ID: - return 0; - } - return -1; // unreachable - } - - @Override - public boolean isModuleInstance() { - return false; - } - - @Override - public TLAIdentifier identifier() { - return name; - } - - @Override - public Map scope() { - return Map$.MODULE$.empty(); - } - - @Override - public TLAOpDecl copy() { - return new TLAOpDecl(getLocation(), name.copy(), type, arity); - } - - @Override - public T accept(TLANodeVisitor v) throws E { - return v.visit(this); - } - - public static TLAOpDecl Infix(SourceLocation location, TLAIdentifier name) { - return new TLAOpDecl(location, name, Type.INFIX, 2); - } - - public static TLAOpDecl Prefix(SourceLocation location, TLAIdentifier name) { - return new TLAOpDecl(location, name, Type.PREFIX, 1); - } - - public static TLAOpDecl Postfix(SourceLocation location, TLAIdentifier name) { - return new TLAOpDecl(location, name, Type.POSTFIX, 1); - } - - public static TLAOpDecl Named(SourceLocation location, TLAIdentifier name, int arity) { - return new TLAOpDecl(location, name, Type.NAMED, arity); - } - - public static TLAOpDecl Id(SourceLocation location, TLAIdentifier name) { - return new TLAOpDecl(location, name, Type.ID, 0); - } - - public TLAIdentifier getName() { - return name; - } - - public Type getType() { - return type; - } - - public int getArity() { - return arity; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + arity; - result = prime * result + ((name == null) ? 0 : name.hashCode()); - result = prime * result + ((type == null) ? 0 : type.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; - TLAOpDecl other = (TLAOpDecl) obj; - if (arity != other.arity) - return false; - if (name == null) { - if (other.name != null) - return false; - } else if (!name.equals(other.name)) - return false; - return type == other.type; - } - -} diff --git a/src/pgo/model/tla/TLAOperatorCall.java b/src/pgo/model/tla/TLAOperatorCall.java deleted file mode 100644 index dd69e01b5..000000000 --- a/src/pgo/model/tla/TLAOperatorCall.java +++ /dev/null @@ -1,86 +0,0 @@ -package pgo.model.tla; - -import pgo.util.SourceLocation; - -import java.util.List; -import java.util.Objects; -import java.util.stream.Collectors; - -/** - * - * TLA AST PlusCalNode: - * - * op(, , ...) - * - */ -public class TLAOperatorCall extends TLAExpression { - - private final TLAIdentifier name; - private final List args; - private final List prefix; - private TLADefinitionOne refersTo; - - public TLAOperatorCall(SourceLocation location, TLAIdentifier name, List prefix, List args) { - super(location); - this.name = name; - this.args = args; - this.prefix = prefix; - } - - public void setRefersTo(TLADefinitionOne refersTo) { - this.refersTo = refersTo; - } - - public TLADefinitionOne getRefersTo() { - return refersTo; - } - - @Override - public TLAOperatorCall copy() { - return new TLAOperatorCall(getLocation(), name.copy(), - prefix.stream().map(TLAGeneralIdentifierPart::copy).collect(Collectors.toList()), - args.stream().map(TLAExpression::copy).collect(Collectors.toList())); - } - - public TLAIdentifier getName() { - return name; - } - - public List getArgs(){ - return args; - } - - public List getPrefix(){ - return prefix; - } - - @Override - public T accept(TLAExpressionVisitor v) throws E { - return v.visit(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((args == null) ? 0 : args.hashCode()); - result = prime * result + ((name == null) ? 0 : name.hashCode()); - result = prime * result + ((prefix == null) ? 0 : prefix.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; - TLAOperatorCall other = (TLAOperatorCall) obj; - return this.getName().equals(other.getName()) && - Objects.equals(this.getArgs(), other.getArgs()) && - Objects.equals(this.getPrefix(), other.getPrefix()); - } - -} diff --git a/src/pgo/model/tla/TLAOperatorDefinition.scala b/src/pgo/model/tla/TLAOperatorDefinition.scala deleted file mode 100644 index eb5906eba..000000000 --- a/src/pgo/model/tla/TLAOperatorDefinition.scala +++ /dev/null @@ -1,44 +0,0 @@ -package pgo.model.tla - -import pgo.util.SourceLocation - -import scala.jdk.CollectionConverters._ - -final class TLAOperatorDefinition(loc: SourceLocation, val name: TLAIdentifier, val args: List[TLAOpDecl], - val body: TLAExpression, val isLocal: Boolean) extends TLAUnit(loc) with TLADefinitionOne { - def this(loc: SourceLocation, name: TLAIdentifier, args: java.util.List[TLAOpDecl], body: TLAExpression, isLocal: Boolean) = - this(loc, name, args.asScala.toList, body, isLocal) - - override def copy: TLAOperatorDefinition = - new TLAOperatorDefinition(loc, name.copy(), args.map(_.copy()), body.copy(), isLocal) - - override val definitions: List[TLADefinition] = List(this) - - def getName: TLAIdentifier = name - def getArgs: java.util.List[TLAOpDecl] = args.asJava - def getBody: TLAExpression = body - - override def arity: Int = args.length - - override def isModuleInstance: Boolean = false - - override def identifier: TLAIdentifier = name - - override def scope: Map[TLAIdentifier, TLADefinitionOne] = Map.empty - - override def accept[T, E <: Throwable](v: TLAUnitVisitor[T, E]): T = v.visit(this) - - override def equals(other: Any): Boolean = other match { - case that: TLAOperatorDefinition => - name == that.name && - args == that.args && - body == that.body && - isLocal == that.isLocal - case _ => false - } - - override def hashCode(): Int = { - val state = Seq(name, args, body, isLocal) - state.map(_.hashCode()).foldLeft(0)((a, b) => 31 * a + b) - } -} diff --git a/src/pgo/model/tla/TLAQuantifiedExistential.java b/src/pgo/model/tla/TLAQuantifiedExistential.java deleted file mode 100644 index 72a186ee4..000000000 --- a/src/pgo/model/tla/TLAQuantifiedExistential.java +++ /dev/null @@ -1,72 +0,0 @@ -package pgo.model.tla; - -import pgo.util.SourceLocation; - -import java.util.List; -import java.util.stream.Collectors; - -/** - * - * TLA AST PlusCalNode: - * - * \E a, b, c : - * - */ -public class TLAQuantifiedExistential extends TLAExpression { - - private final TLAExpression body; - private final List ids; - - public TLAQuantifiedExistential(SourceLocation location, List ids, TLAExpression body) { - super(location); - this.ids = ids; - this.body = body; - } - - @Override - public TLAQuantifiedExistential copy() { - return new TLAQuantifiedExistential(getLocation(), ids.stream().map(TLAQuantifierBound::copy).collect(Collectors.toList()), body.copy()); - } - - public List getIds(){ - return ids; - } - - public TLAExpression getBody() { - return body; - } - - @Override - public T accept(TLAExpressionVisitor v) throws E { - return v.visit(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((body == null) ? 0 : body.hashCode()); - result = prime * result + ((ids == null) ? 0 : ids.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; - TLAQuantifiedExistential other = (TLAQuantifiedExistential) obj; - if (body == null) { - if (other.body != null) - return false; - } else if (!body.equals(other.body)) - return false; - if (ids == null) { - return other.ids == null; - } else return ids.equals(other.ids); - } - -} diff --git a/src/pgo/model/tla/TLAQuantifiedUniversal.java b/src/pgo/model/tla/TLAQuantifiedUniversal.java deleted file mode 100644 index 4182494fc..000000000 --- a/src/pgo/model/tla/TLAQuantifiedUniversal.java +++ /dev/null @@ -1,72 +0,0 @@ -package pgo.model.tla; - -import pgo.util.SourceLocation; - -import java.util.List; -import java.util.stream.Collectors; - -/** - * - * TLA AST PlusCalNode: - * - * \A a, b, c : - * - */ -public class TLAQuantifiedUniversal extends TLAExpression { - - private final List ids; - private final TLAExpression body; - - public TLAQuantifiedUniversal(SourceLocation location, List ids, TLAExpression body) { - super(location); - this.ids = ids; - this.body = body; - } - - @Override - public TLAQuantifiedUniversal copy() { - return new TLAQuantifiedUniversal(getLocation(), ids.stream().map(TLAQuantifierBound::copy).collect(Collectors.toList()), body.copy()); - } - - public List getIds(){ - return ids; - } - - public TLAExpression getBody() { - return body; - } - - @Override - public T accept(TLAExpressionVisitor v) throws E { - return v.visit(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((body == null) ? 0 : body.hashCode()); - result = prime * result + ((ids == null) ? 0 : ids.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; - TLAQuantifiedUniversal other = (TLAQuantifiedUniversal) obj; - if (body == null) { - if (other.body != null) - return false; - } else if (!body.equals(other.body)) - return false; - if (ids == null) { - return other.ids == null; - } else return ids.equals(other.ids); - } - -} diff --git a/src/pgo/model/tla/TLAQuantifierBound.scala b/src/pgo/model/tla/TLAQuantifierBound.scala deleted file mode 100644 index f5028c48e..000000000 --- a/src/pgo/model/tla/TLAQuantifierBound.scala +++ /dev/null @@ -1,49 +0,0 @@ -package pgo.model.tla - -import scala.jdk.CollectionConverters._ - -import pgo.util.SourceLocation - -final class TLAQuantifierBound(loc: SourceLocation, val tpe: TLAQuantifierBound.Type, val ids: List[TLAIdentifier], val set: TLAExpression) extends TLANode(loc) with TLADefinitionComposite { - def getType: TLAQuantifierBound.Type = tpe - def getIds: java.util.List[TLAIdentifier] = ids.asJava - def getSet: TLAExpression = set - - lazy val identifierOrTuple: TLAIdentifierOrTuple = - tpe match { - case TLAQuantifierBound.Type.IDS => - assert(ids.length == 1) - TLAIdentifierOrTuple.Identifier(ids.head) - case TLAQuantifierBound.Type.TUPLE => - TLAIdentifierOrTuple.Tuple(loc, ids.asJava) - } - - def this(loc: SourceLocation, tpe: TLAQuantifierBound.Type, ids: java.util.List[TLAIdentifier], set: TLAExpression) = - this(loc, tpe, ids.asScala.toList, set) - - override def copy: TLAQuantifierBound = new TLAQuantifierBound(loc, tpe, ids.map(_.copy), set.copy()) - - override def accept[T, E <: Throwable](v: TLANodeVisitor[T, E]): T = v.visit(this) - - override val members: List[TLADefinition] = ids - - override def equals(other: Any): Boolean = other match { - case that: TLAQuantifierBound => - tpe == that.tpe && - ids == that.ids && - set == that.set - case _ => false - } - - override def hashCode(): Int = Seq(tpe, ids, set).hashCode() -} - -object TLAQuantifierBound { - sealed abstract class Type - object Type { - final case object IDS extends Type - def ids: IDS.type = IDS - final case object TUPLE extends Type - def tuple: TUPLE.type = TUPLE - } -} diff --git a/src/pgo/model/tla/TLARecordConstructor.java b/src/pgo/model/tla/TLARecordConstructor.java deleted file mode 100644 index b5f5176c6..000000000 --- a/src/pgo/model/tla/TLARecordConstructor.java +++ /dev/null @@ -1,110 +0,0 @@ -package pgo.model.tla; - -import pgo.util.SourceLocation; - -import java.util.List; -import java.util.stream.Collectors; - -/** - * - * TLA AST PlusCalNode: - * - * [ a |-> , b |-> , ... ] - * - */ -public class TLARecordConstructor extends TLAExpression { - - private final List fields; - - public TLARecordConstructor(SourceLocation location, List fields) { - super(location); - this.fields = fields; - } - - @Override - public TLARecordConstructor copy() { - return new TLARecordConstructor(getLocation(), fields.stream().map(Field::copy).collect(Collectors.toList())); - } - - public static class Field extends TLANode { - private final TLAIdentifier name; - private final TLAExpression value; - public Field(SourceLocation location, TLAIdentifier name, TLAExpression value) { - super(location); - this.name = name; - this.value = value; - } - @Override - public Field copy() { - return new Field(getLocation(), name.copy(), value.copy()); - } - public TLAIdentifier getName() { - return name; - } - public TLAExpression getValue() { - return value; - } - @Override - public T accept(TLANodeVisitor v) throws E { - return v.visit(this); - } - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((name == null) ? 0 : name.hashCode()); - result = prime * result + ((value == null) ? 0 : value.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; - Field other = (Field) obj; - if (name == null) { - if (other.name != null) - return false; - } else if (!name.equals(other.name)) - return false; - if (value == null) { - return other.value == null; - } else return value.equals(other.value); - } - } - - public List getFields(){ - return fields; - } - - @Override - public T accept(TLAExpressionVisitor v) throws E { - return v.visit(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((fields == null) ? 0 : fields.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; - TLARecordConstructor other = (TLARecordConstructor) obj; - if (fields == null) { - return other.fields == null; - } else return fields.equals(other.fields); - } - -} diff --git a/src/pgo/model/tla/TLARecordSet.java b/src/pgo/model/tla/TLARecordSet.java deleted file mode 100644 index c406bb79f..000000000 --- a/src/pgo/model/tla/TLARecordSet.java +++ /dev/null @@ -1,113 +0,0 @@ -package pgo.model.tla; - -import pgo.util.SourceLocation; - -import java.util.List; -import java.util.stream.Collectors; - -/** - * - * TLA AST PlusCalNode: - * - * [ a : S1, b : S2, ... ] - * - * the set of all records with a given signature - * (similar to PGoTLARecord, but S1, S2 are expected to be sets) - * - */ -public class TLARecordSet extends TLAExpression { - - private final List fields; - - public TLARecordSet(SourceLocation location, List fields) { - super(location); - this.fields = fields; - } - - @Override - public TLARecordSet copy() { - return new TLARecordSet(getLocation(), fields.stream().map(Field::copy).collect(Collectors.toList())); - } - - public static class Field extends TLANode { - private final TLAIdentifier name; - private final TLAExpression set; - public Field(SourceLocation location, TLAIdentifier name, TLAExpression set) { - super(location); - this.name = name; - this.set = set; - } - @Override - public Field copy() { - return new Field(getLocation(), name.copy(), set.copy()); - } - public TLAIdentifier getName() { - return name; - } - public TLAExpression getSet() { - return set; - } - @Override - public T accept(TLANodeVisitor v) throws E { - return v.visit(this); - } - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((name == null) ? 0 : name.hashCode()); - result = prime * result + ((set == null) ? 0 : set.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; - Field other = (Field) obj; - if (name == null) { - if (other.name != null) - return false; - } else if (!name.equals(other.name)) - return false; - if (set == null) { - return other.set == null; - } else return set.equals(other.set); - } - } - - public List getFields(){ - return fields; - } - - @Override - public T accept(TLAExpressionVisitor v) throws E { - return v.visit(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((fields == null) ? 0 : fields.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; - TLARecordSet other = (TLARecordSet) obj; - if (fields == null) { - return other.fields == null; - } else return fields.equals(other.fields); - } - -} diff --git a/src/pgo/model/tla/TLARef.java b/src/pgo/model/tla/TLARef.java deleted file mode 100644 index 5fbd0164a..000000000 --- a/src/pgo/model/tla/TLARef.java +++ /dev/null @@ -1,54 +0,0 @@ -package pgo.model.tla; - -import pgo.util.SourceLocation; - -import java.util.Objects; - -public class TLARef extends TLAExpression { - private final String target; - private TLADefinitionOne refersTo; - - public TLARef(SourceLocation location, String target) { - super(location); - this.target = target; - } - - public void setRefersTo(TLADefinitionOne refersTo) { - this.refersTo = refersTo; - } - - public TLADefinitionOne getRefersTo() { - return refersTo; - } - - @Override - public int hashCode() { - return Objects.hash(target); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null || obj.getClass() != getClass()) { - return false; - } - TLARef that = (TLARef) obj; - return target.equals(that.target); - } - - @Override - public TLARef copy() { - return new TLARef(getLocation(), target); - } - - @Override - public T accept(TLAExpressionVisitor v) throws E { - return v.visit(this); - } - - public String getTarget() { - return target; - } -} diff --git a/src/pgo/model/tla/TLARequiredAction.java b/src/pgo/model/tla/TLARequiredAction.java deleted file mode 100644 index e8dcc05c2..000000000 --- a/src/pgo/model/tla/TLARequiredAction.java +++ /dev/null @@ -1,69 +0,0 @@ -package pgo.model.tla; - -import pgo.util.SourceLocation; - -/** - * - * TLA AST PlusCalNode: - * - * << >>_ - * - */ -public class TLARequiredAction extends TLAExpression { - - private final TLAExpression body; - private final TLAExpression vars; - - public TLARequiredAction(SourceLocation location, TLAExpression body, TLAExpression vars) { - super(location); - this.body = body; - this.vars = vars; - } - - @Override - public TLARequiredAction copy() { - return new TLARequiredAction(getLocation(), body.copy(), vars.copy()); - } - - @Override - public T accept(TLAExpressionVisitor v) throws E { - return v.visit(this); - } - - public TLAExpression getBody() { - return body; - } - - public TLAExpression getVars() { - return vars; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((body == null) ? 0 : body.hashCode()); - result = prime * result + ((vars == null) ? 0 : vars.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; - TLARequiredAction other = (TLARequiredAction) obj; - if (body == null) { - if (other.body != null) - return false; - } else if (!body.equals(other.body)) - return false; - if (vars == null) { - return other.vars == null; - } else return vars.equals(other.vars); - } - -} diff --git a/src/pgo/model/tla/TLASetComprehension.java b/src/pgo/model/tla/TLASetComprehension.java deleted file mode 100644 index 7fca11f7a..000000000 --- a/src/pgo/model/tla/TLASetComprehension.java +++ /dev/null @@ -1,72 +0,0 @@ -package pgo.model.tla; - -import pgo.util.SourceLocation; - -import java.util.List; -import java.util.stream.Collectors; - -/** - * - * TLA AST PlusCalNode: - * - * { : a \in S1, << a, b >> \in S2, ... } - * - */ -public class TLASetComprehension extends TLAExpression { - - private final TLAExpression body; - private final List bounds; - - public TLASetComprehension(SourceLocation location, TLAExpression body, List bounds) { - super(location); - this.body = body; - this.bounds = bounds; - } - - @Override - public TLASetComprehension copy() { - return new TLASetComprehension(getLocation(), body.copy(), bounds.stream().map(TLAQuantifierBound::copy).collect(Collectors.toList())); - } - - public TLAExpression getBody() { - return body; - } - - public List getBounds(){ - return bounds; - } - - @Override - public T accept(TLAExpressionVisitor v) throws E { - return v.visit(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((body == null) ? 0 : body.hashCode()); - result = prime * result + ((bounds == null) ? 0 : bounds.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; - TLASetComprehension other = (TLASetComprehension) obj; - if (body == null) { - if (other.body != null) - return false; - } else if (!body.equals(other.body)) - return false; - if (bounds == null) { - return other.bounds == null; - } else return bounds.equals(other.bounds); - } - -} diff --git a/src/pgo/model/tla/TLASetConstructor.java b/src/pgo/model/tla/TLASetConstructor.java deleted file mode 100644 index 4f929553c..000000000 --- a/src/pgo/model/tla/TLASetConstructor.java +++ /dev/null @@ -1,60 +0,0 @@ -package pgo.model.tla; - -import pgo.util.SourceLocation; - -import java.util.List; -import java.util.stream.Collectors; - -/** - * - * PlusCalWith TLAParser, this will always be the result of parsing an explicit set constructor: - * - * { , , ... } - * - */ -public class TLASetConstructor extends TLAExpression { - - private final List contents; - - public TLASetConstructor(SourceLocation location, List contents) { - super(location); - this.contents = contents; - } - - @Override - public TLASetConstructor copy() { - return new TLASetConstructor(getLocation(), contents.stream().map(TLAExpression::copy).collect(Collectors.toList())); - } - - public List getContents() { - return contents; - } - - @Override - public T accept(TLAExpressionVisitor v) throws E { - return v.visit(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((contents == null) ? 0 : contents.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; - TLASetConstructor other = (TLASetConstructor) obj; - if (contents == null) { - return other.contents == null; - } else return contents.equals(other.contents); - } - -} diff --git a/src/pgo/model/tla/TLASetRefinement.java b/src/pgo/model/tla/TLASetRefinement.java deleted file mode 100644 index 68486320b..000000000 --- a/src/pgo/model/tla/TLASetRefinement.java +++ /dev/null @@ -1,66 +0,0 @@ -package pgo.model.tla; - -import pgo.util.SourceLocation; - -/** - * - * TLA AST Node: - * - * { a \in : } - * { <> \in : } - * - */ -public class TLASetRefinement extends TLAExpression { - - private final TLAQuantifierBound binding; - private final TLAExpression when; - - public TLASetRefinement(SourceLocation location, TLAQuantifierBound binding, TLAExpression when) { - super(location); - this.binding = binding; - this.when = when; - } - - @Override - public TLASetRefinement copy() { - return new TLASetRefinement(getLocation(), binding.copy(), when.copy()); - } - - public TLAQuantifierBound getBinding() { - return binding; - } - - public TLAIdentifierOrTuple getIdent() { - return binding.identifierOrTuple(); - } - - public TLAExpression getFrom() { - return binding.getSet(); - } - - public TLAExpression getWhen() { - return when; - } - - @Override - public T accept(TLAExpressionVisitor v) throws E { - return v.visit(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((binding == null) ? 0 : binding.hashCode()); - result = prime * result + ((when == null) ? 0 : when.hashCode()); - return result; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - TLASetRefinement that = (TLASetRefinement) o; - return binding.equals(that.binding) && when.equals(that.when); - } -} diff --git a/src/pgo/model/tla/TLASpecialVariableValue.java b/src/pgo/model/tla/TLASpecialVariableValue.java deleted file mode 100644 index 01b1aae9b..000000000 --- a/src/pgo/model/tla/TLASpecialVariableValue.java +++ /dev/null @@ -1,29 +0,0 @@ -package pgo.model.tla; - -import pgo.util.SourceLocation; - -public class TLASpecialVariableValue extends TLAExpression { - public TLASpecialVariableValue(SourceLocation location) { - super(location); - } - - @Override - public int hashCode() { - return 0; - } - - @Override - public boolean equals(Object obj) { - return obj instanceof TLASpecialVariableValue; - } - - @Override - public TLASpecialVariableValue copy() { - return new TLASpecialVariableValue(getLocation()); - } - - @Override - public T accept(TLAExpressionVisitor v) throws E { - return v.visit(this); - } -} diff --git a/src/pgo/model/tla/TLASpecialVariableVariable.java b/src/pgo/model/tla/TLASpecialVariableVariable.java deleted file mode 100644 index d34a437c0..000000000 --- a/src/pgo/model/tla/TLASpecialVariableVariable.java +++ /dev/null @@ -1,29 +0,0 @@ -package pgo.model.tla; - -import pgo.util.SourceLocation; - -public class TLASpecialVariableVariable extends TLAExpression { - public TLASpecialVariableVariable(SourceLocation location) { - super(location); - } - - @Override - public int hashCode() { - return 0; - } - - @Override - public boolean equals(Object obj) { - return obj instanceof TLASpecialVariableVariable; - } - - @Override - public TLASpecialVariableVariable copy() { - return new TLASpecialVariableVariable(getLocation()); - } - - @Override - public T accept(TLAExpressionVisitor v) throws E { - return v.visit(this); - } -} diff --git a/src/pgo/model/tla/TLAString.java b/src/pgo/model/tla/TLAString.java deleted file mode 100644 index 2ec90504d..000000000 --- a/src/pgo/model/tla/TLAString.java +++ /dev/null @@ -1,54 +0,0 @@ -package pgo.model.tla; - -import pgo.util.SourceLocation; - -/** - * Represents a TLA token string - * - */ -public class TLAString extends TLAExpression { - - private final String value; - - public TLAString(SourceLocation location, String value) { - super(location); - this.value = value; - } - - @Override - public TLAString copy() { - return new TLAString(getLocation(), value); - } - - public String getValue() { - return value; - } - - @Override - public T accept(TLAExpressionVisitor v) throws E { - return v.visit(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((value == null) ? 0 : value.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; - TLAString other = (TLAString) obj; - if (value == null) { - return other.value == null; - } else return value.equals(other.value); - } - -} diff --git a/src/pgo/model/tla/TLASubstitutionKey.java b/src/pgo/model/tla/TLASubstitutionKey.java deleted file mode 100644 index 2f09acd02..000000000 --- a/src/pgo/model/tla/TLASubstitutionKey.java +++ /dev/null @@ -1,60 +0,0 @@ -package pgo.model.tla; - -import pgo.util.SourceLocation; - -import java.util.List; -import java.util.stream.Collectors; - -/** - * - * Represents a substitution in an EXCEPT expression. - * - * GoFor simplicity, the !.id version is represented as !["id"]. Both are formally equivalent. - * - */ -public class TLASubstitutionKey extends TLANode { - - List indices; - - public TLASubstitutionKey(SourceLocation location, List indices) { - super(location); - this.indices = indices; - } - - @Override - public TLASubstitutionKey copy() { - return new TLASubstitutionKey(getLocation(), indices.stream().map(TLAExpression::copy).collect(Collectors.toList())); - } - - public List getIndices(){ - return indices; - } - - @Override - public T accept(TLANodeVisitor v) throws E { - return v.visit(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((indices == null) ? 0 : indices.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; - TLASubstitutionKey other = (TLASubstitutionKey) obj; - if (indices == null) { - return other.indices == null; - } else return indices.equals(other.indices); - } - -} diff --git a/src/pgo/model/tla/TLASymbol.java b/src/pgo/model/tla/TLASymbol.java deleted file mode 100644 index 47cbfd96a..000000000 --- a/src/pgo/model/tla/TLASymbol.java +++ /dev/null @@ -1,57 +0,0 @@ -package pgo.model.tla; - -import pgo.util.SourceLocation; - -public class TLASymbol extends TLANode { - - private final String value; - private final TLAIdentifier identifier; - - public TLASymbol(SourceLocation location, String value) { - super(location); - this.value = value; - this.identifier = new TLAIdentifier(location, value); - } - - public TLAIdentifier getIdentifier() { - return identifier; - } - - public String getValue() { - return value; - } - - @Override - public TLANode copy() { - throw new RuntimeException("bad"); - //return new TLASymbol(getLocation(), value); - } - - @Override - public T accept(TLANodeVisitor v) throws E { - return v.visit(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((value == null) ? 0 : value.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; - TLASymbol other = (TLASymbol) obj; - if (value == null) { - return other.value == null; - } else return value.equals(other.value); - } - -} diff --git a/src/pgo/model/tla/TLATheorem.java b/src/pgo/model/tla/TLATheorem.java deleted file mode 100644 index 9a4172d46..000000000 --- a/src/pgo/model/tla/TLATheorem.java +++ /dev/null @@ -1,57 +0,0 @@ -package pgo.model.tla; - -import pgo.util.SourceLocation; -import scala.collection.immutable.List; -import scala.collection.immutable.List$; - -public class TLATheorem extends TLAUnit { - - private final TLAExpression theorem; - - @Override - public List definitions() { - return List$.MODULE$.empty(); - } - - public TLATheorem(SourceLocation location, TLAExpression theorem) { - super(location); - this.theorem = theorem; - } - - @Override - public TLATheorem copy() { - return new TLATheorem(getLocation(), theorem.copy()); - } - - public TLAExpression getTheorem() { - return theorem; - } - - @Override - public T accept(TLAUnitVisitor v) throws E { - return v.visit(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((theorem == null) ? 0 : theorem.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; - TLATheorem other = (TLATheorem) obj; - if (theorem == null) { - return other.theorem == null; - } else return theorem.equals(other.theorem); - } - -} diff --git a/src/pgo/model/tla/TLATuple.java b/src/pgo/model/tla/TLATuple.java deleted file mode 100644 index 24248bed7..000000000 --- a/src/pgo/model/tla/TLATuple.java +++ /dev/null @@ -1,60 +0,0 @@ -package pgo.model.tla; - -import pgo.util.SourceLocation; - -import java.util.List; -import java.util.stream.Collectors; - -/** - * - * TLA AST PlusCalNode: - * - * << , , ... >> - * - */ -public class TLATuple extends TLAExpression { - - private final List elements; - - public TLATuple(SourceLocation location, List elements) { - super(location); - this.elements = elements; - } - - @Override - public TLATuple copy() { - return new TLATuple(getLocation(), elements.stream().map(TLAExpression::copy).collect(Collectors.toList())); - } - - public List getElements(){ - return elements; - } - - @Override - public T accept(TLAExpressionVisitor v) throws E { - return v.visit(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((elements == null) ? 0 : elements.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; - TLATuple other = (TLATuple) obj; - if (elements == null) { - return other.elements == null; - } else return elements.equals(other.elements); - } - -} diff --git a/src/pgo/model/tla/TLAUnary.java b/src/pgo/model/tla/TLAUnary.java deleted file mode 100644 index 754552871..000000000 --- a/src/pgo/model/tla/TLAUnary.java +++ /dev/null @@ -1,90 +0,0 @@ -package pgo.model.tla; - -import pgo.util.SourceLocation; - -import java.util.List; -import java.util.stream.Collectors; - -/** - * - * This represents a TLA+ unary operator call. - * - */ -public class TLAUnary extends TLAExpression { - private final TLASymbol operation; - private final TLAExpression operand; - private final List prefix; - private TLADefinitionOne refersTo; - - public TLAUnary(SourceLocation location, TLASymbol operation, List prefix, TLAExpression operand) { - super(location); - this.operation = operation; - this.prefix = prefix; - this.operand = operand; - } - - public void setRefersTo(TLADefinitionOne refersTo) { - this.refersTo = refersTo; - } - - public TLADefinitionOne getRefersTo() { - return refersTo; - } - - @Override - public TLAUnary copy() { - return new TLAUnary(getLocation(), operation, prefix.stream().map(TLAGeneralIdentifierPart::copy).collect(Collectors.toList()), operand.copy()); - } - - public TLASymbol getOperation() { - return operation; - } - - public TLAExpression getOperand() { - return operand; - } - - public List getPrefix(){ - return prefix; - } - - @Override - public T accept(TLAExpressionVisitor v) throws E { - return v.visit(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((operand == null) ? 0 : operand.hashCode()); - result = prime * result + ((operation == null) ? 0 : operation.hashCode()); - result = prime * result + ((prefix == null) ? 0 : prefix.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; - TLAUnary other = (TLAUnary) obj; - if (operand == null) { - if (other.operand != null) - return false; - } else if (!operand.equals(other.operand)) - return false; - if (operation == null) { - if (other.operation != null) - return false; - } else if (!operation.equals(other.operation)) - return false; - if (prefix == null) { - return other.prefix == null; - } else return prefix.equals(other.prefix); - } - -} diff --git a/src/pgo/model/tla/TLAUnit.scala b/src/pgo/model/tla/TLAUnit.scala deleted file mode 100644 index 44f15f71b..000000000 --- a/src/pgo/model/tla/TLAUnit.scala +++ /dev/null @@ -1,25 +0,0 @@ -package pgo.model.tla - -import pgo.scope.UID -import pgo.util.SourceLocation - -sealed trait TLADefinition -trait TLADefinitionOne extends TLADefinition { - def getUID: UID - def arity: Int - def isModuleInstance: Boolean - def identifier: TLAIdentifier - def scope: Map[TLAIdentifier,TLADefinitionOne] -} -trait TLADefinitionComposite extends TLADefinition { - def members: List[TLADefinition] -} - -abstract class TLAUnit(loc: SourceLocation) extends TLANode(loc) with TLAUnitVisitorThrowsHack { - override def accept[T, E <: Throwable](v: TLANodeVisitor[T, E]): T = - v.visit(this) - - override def copy: TLAUnit - - def definitions: List[TLADefinition] -} diff --git a/src/pgo/model/tla/TLAUnitVisitor.java b/src/pgo/model/tla/TLAUnitVisitor.java deleted file mode 100644 index 9d85d0152..000000000 --- a/src/pgo/model/tla/TLAUnitVisitor.java +++ /dev/null @@ -1,13 +0,0 @@ -package pgo.model.tla; - -public abstract class TLAUnitVisitor { - public abstract T visit(TLAInstance pGoTLAInstance) throws E; - public abstract T visit(TLAFunctionDefinition pGoTLAFunctionDefinition) throws E; - public abstract T visit(TLAOperatorDefinition pGoTLAOperator) throws E; - public abstract T visit(TLATheorem pGoTLATheorem) throws E; - public abstract T visit(TLAModule pGoTLAModule) throws E; - public abstract T visit(TLAVariableDeclaration pGoTLAVariableDeclaration) throws E; - public abstract T visit(TLAConstantDeclaration tlaConstantDeclaration) throws E; - public abstract T visit(TLAModuleDefinition pGoTLAModuleDefinition) throws E; - public abstract T visit(TLAAssumption tlaAssumption) throws E; -} diff --git a/src/pgo/model/tla/TLAUnitVisitorThrowsHack.java b/src/pgo/model/tla/TLAUnitVisitorThrowsHack.java deleted file mode 100644 index 25fda3f27..000000000 --- a/src/pgo/model/tla/TLAUnitVisitorThrowsHack.java +++ /dev/null @@ -1,9 +0,0 @@ -package pgo.model.tla; - -/** - * In Scala, checked exceptions don't exist. To avoid massive (unnecessary) API breakage, - * this interface escapes to Java to implement TLAUnit#accept with checked exceptions. - */ -interface TLAUnitVisitorThrowsHack { - T accept(TLAUnitVisitor v) throws E; -} diff --git a/src/pgo/model/tla/TLAUniversal.java b/src/pgo/model/tla/TLAUniversal.java deleted file mode 100644 index 8425f459f..000000000 --- a/src/pgo/model/tla/TLAUniversal.java +++ /dev/null @@ -1,73 +0,0 @@ -package pgo.model.tla; - -import pgo.util.SourceLocation; - -import java.util.List; -import java.util.stream.Collectors; - -/* - * TLA AST PlusCalNode: - * - * \A a, b, c : - * or - * \AA a, b, c : - * - */ -public class TLAUniversal extends TLAExpression { - - private final List ids; - private final TLAExpression body; - - public TLAUniversal(SourceLocation location, List ids, TLAExpression body) { - super(location); - this.ids = ids; - this.body = body; - } - - @Override - public TLAUniversal copy() { - return new TLAUniversal(getLocation(), ids.stream().map(TLAIdentifier::copy).collect(Collectors.toList()), body.copy()); - } - - public List getIds(){ - return ids; - } - - public TLAExpression getBody() { - return body; - } - - @Override - public T accept(TLAExpressionVisitor v) throws E { - return v.visit(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((body == null) ? 0 : body.hashCode()); - result = prime * result + ((ids == null) ? 0 : ids.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; - TLAUniversal other = (TLAUniversal) obj; - if (body == null) { - if (other.body != null) - return false; - } else if (!body.equals(other.body)) - return false; - if (ids == null) { - return other.ids == null; - } else return ids.equals(other.ids); - } - -} diff --git a/src/pgo/model/tla/TLAUtils.scala b/src/pgo/model/tla/TLAUtils.scala deleted file mode 100644 index 51c4e42f9..000000000 --- a/src/pgo/model/tla/TLAUtils.scala +++ /dev/null @@ -1,239 +0,0 @@ -package pgo.model.tla - -import pgo.parser.TLAParserContext -import pgo.trans.intermediate.DefinitionRegistry - -import scala.jdk.CollectionConverters._ - -object TLAUtils { - def fillContextFromModule(ctx: TLAParserContext, tlaModule: TLAModule, captureLocal: Boolean): TLAParserContext = { - val ctxWithExts = tlaModule.exts.foldLeft(ctx) { (ctx, ext) => ext.members.foldLeft(ctx)(_.withDefinition(_)) } - val iter = - if( captureLocal ) { - tlaModule.units.iterator - } else { - tlaModule.units.iterator.filter { unit => - unit.accept(new TLAUnitVisitor[Boolean,RuntimeException] { - override def visit(pGoTLAInstance: TLAInstance): Boolean = - !pGoTLAInstance.isLocal - - override def visit(pGoTLAFunctionDefinition: TLAFunctionDefinition): Boolean = - !pGoTLAFunctionDefinition.isLocal - - override def visit(pGoTLAOperator: TLAOperatorDefinition): Boolean = - !pGoTLAOperator.isLocal - - override def visit(pGoTLATheorem: TLATheorem): Boolean = true - - override def visit(pGoTLAModule: TLAModule): Boolean = ??? // TODO: which? - - override def visit(pGoTLAVariableDeclaration: TLAVariableDeclaration): Boolean = ??? // TODO: which? - - override def visit(tlaConstantDeclaration: TLAConstantDeclaration): Boolean = true - - override def visit(pGoTLAModuleDefinition: TLAModuleDefinition): Boolean = - !pGoTLAModuleDefinition.isLocal - - override def visit(tlaAssumption: TLAAssumption): Boolean = true - }) - } - } - iter.foldLeft(ctxWithExts) { (ctx, unit) => - unit.definitions.foldLeft(ctx)(_.withDefinition(_)) - } - } - - def fillDefinitionRegistryFromModule(definitionRegistry: DefinitionRegistry, module: TLAModule): Unit = { - module.exts.foreach { - case TLAModuleExtendsBuiltin(_) => // registry should always have all builtins pre-added - case TLAModuleExtendsModule(extendedModule) => - fillDefinitionRegistryFromModule(definitionRegistry, extendedModule) - } - module.units.foreach(fillDefinitionRegistryFromUnit(definitionRegistry,_)) - } - - def fillDefinitionRegistryFromUnit(definitionRegistry: DefinitionRegistry, unit: TLAUnit): Unit = { - unit.accept(new TLAUnitVisitor[Unit,RuntimeException] { - override def visit(pGoTLAInstance: TLAInstance): Unit = () - - override def visit(pGoTLAFunctionDefinition: TLAFunctionDefinition): Unit = { - definitionRegistry.addFunctionDefinition(pGoTLAFunctionDefinition) - fillDefinitionRegistryFromExpression(definitionRegistry, pGoTLAFunctionDefinition.getFunction) - } - - override def visit(pGoTLAOperator: TLAOperatorDefinition): Unit = { - definitionRegistry.addOperatorDefinition(pGoTLAOperator) - pGoTLAOperator.args.foreach { opdecl => - definitionRegistry.addLocalVariable(opdecl.getUID) - } - fillDefinitionRegistryFromExpression(definitionRegistry, pGoTLAOperator.body) - } - - override def visit(pGoTLATheorem: TLATheorem): Unit = () - - override def visit(pGoTLAModule: TLAModule): Unit = () - - override def visit(pGoTLAVariableDeclaration: TLAVariableDeclaration): Unit = - pGoTLAVariableDeclaration.variables.foreach(v => definitionRegistry.addGlobalVariable(v.getUID)) - - override def visit(tlaConstantDeclaration: TLAConstantDeclaration): Unit = - tlaConstantDeclaration.constants.foreach(c => definitionRegistry.addConstant(c.getUID, c.getName.getId)) - - override def visit(pGoTLAModuleDefinition: TLAModuleDefinition): Unit = ??? // TODO: ? - - override def visit(tlaAssumption: TLAAssumption): Unit = () - }) - } - - def fillDefinitionRegistryFromQuantifierBound(definitionRegistry: DefinitionRegistry, quantifierBound: TLAQuantifierBound): Unit = { - quantifierBound.ids.foreach { id => - definitionRegistry.addLocalVariable(id.getUID) - } - fillDefinitionRegistryFromExpression(definitionRegistry, quantifierBound.set) - } - - def fillDefinitionRegistryFromExpression(definitionRegistry: DefinitionRegistry, expr: TLAExpression): Unit = { - expr.accept(new TLAExpressionVisitor[Unit,RuntimeException] { - override def visit(tlaFunctionCall: TLAFunctionCall): Unit = { - tlaFunctionCall.getFunction.accept(this) - tlaFunctionCall.getParams.asScala.foreach(_.accept(this)) - } - - override def visit(tlaBinOp: TLABinOp): Unit = { - tlaBinOp.getLHS.accept(this) - definitionRegistry.getReferences.put(tlaBinOp.getUID, tlaBinOp.getRefersTo.getUID) - assert(definitionRegistry.findOperator(tlaBinOp.getRefersTo.getUID) ne null) - tlaBinOp.getRHS.accept(this) - } - - override def visit(tlaBool: TLABool): Unit = () - - override def visit(tlaCase: TLACase): Unit = { - tlaCase.getArms.asScala.foreach { arm => - arm.getCondition.accept(this) - arm.getResult.accept(this) - } - if(tlaCase.getOther ne null) { - tlaCase.getOther.accept(this) - } - } - - override def visit(tlaDot: TLADot): Unit = { - tlaDot.getExpression.accept(this) - } - - override def visit(tlaExistential: TLAExistential): Unit = { - tlaExistential.getIds.asScala.foreach(id => definitionRegistry.addLocalVariable(id.getUID)) - tlaExistential.getBody.accept(this) - } - - override def visit(tlaFairness: TLAFairness): Unit = { - tlaFairness.getExpression.accept(this) - tlaFairness.getVars.accept(this) - } - - override def visit(tlaFunction: TLAFunction): Unit = { - tlaFunction.getArguments.asScala.foreach(fillDefinitionRegistryFromQuantifierBound(definitionRegistry,_)) - tlaFunction.getBody.accept(this) - } - - override def visit(tlaFunctionSet: TLAFunctionSet): Unit = { - tlaFunctionSet.getFrom.accept(this) - tlaFunctionSet.getTo.accept(this) - } - - override def visit(tlaFunctionSubstitution: TLAFunctionSubstitution): Unit = { - tlaFunctionSubstitution.getSource.accept(this) - tlaFunctionSubstitution.getSubstitutions.asScala.foreach { subst => - subst.getKeys.asScala.foreach(key => key.indices.forEach(_.accept(this))) - subst.getValue.accept(this) - } - } - - override def visit(tlaIf: TLAIf): Unit = { - tlaIf.getCond.accept(this) - tlaIf.getTval.accept(this) - tlaIf.getFval.accept(this) - } - - override def visit(tlaLet: TLALet): Unit = { - tlaLet.getDefinitions.asScala.foreach(fillDefinitionRegistryFromUnit(definitionRegistry, _)) - tlaLet.getBody.accept(this) - } - - override def visit(tlaGeneralIdentifier: TLAGeneralIdentifier): Unit = { - definitionRegistry.getReferences.put(tlaGeneralIdentifier.getUID, tlaGeneralIdentifier.getRefersTo.getUID) - } - - override def visit(tlaTuple: TLATuple): Unit = - tlaTuple.getElements.asScala.foreach(_.accept(this)) - - override def visit(tlaMaybeAction: TLAMaybeAction): Unit = - tlaMaybeAction.getBody.accept(this) - - override def visit(tlaNumber: TLANumber): Unit = () - - override def visit(tlaOperatorCall: TLAOperatorCall): Unit = { - definitionRegistry.getReferences.put(tlaOperatorCall.getUID, tlaOperatorCall.getRefersTo.getUID) - assert(definitionRegistry.findOperator(tlaOperatorCall.getRefersTo.getUID) ne null) - tlaOperatorCall.getArgs.asScala.foreach(_.accept(this)) - } - - override def visit(tlaQuantifiedExistential: TLAQuantifiedExistential): Unit = { - tlaQuantifiedExistential.getIds.asScala.foreach(fillDefinitionRegistryFromQuantifierBound(definitionRegistry,_)) - tlaQuantifiedExistential.getBody.accept(this) - } - - override def visit(tlaQuantifiedUniversal: TLAQuantifiedUniversal): Unit = { - tlaQuantifiedUniversal.getIds.forEach(fillDefinitionRegistryFromQuantifierBound(definitionRegistry,_)) - tlaQuantifiedUniversal.getBody.accept(this) - } - - override def visit(tlaRecordConstructor: TLARecordConstructor): Unit = - tlaRecordConstructor.getFields.asScala.foreach(_.getValue.accept(this)) - - override def visit(tlaRecordSet: TLARecordSet): Unit = - tlaRecordSet.getFields.asScala.foreach(_.getSet.accept(this)) - - override def visit(tlaRef: TLARef): Unit = { - definitionRegistry.getReferences.put(tlaRef.getUID, tlaRef.getRefersTo.getUID) - } - - override def visit(tlaRequiredAction: TLARequiredAction): Unit = - tlaRequiredAction.getBody.accept(this) - - override def visit(tlaSetConstructor: TLASetConstructor): Unit = - tlaSetConstructor.getContents.asScala.foreach(_.accept(this)) - - override def visit(tlaSetComprehension: TLASetComprehension): Unit = { - tlaSetComprehension.getBounds.asScala.foreach(fillDefinitionRegistryFromQuantifierBound(definitionRegistry,_)) - tlaSetComprehension.getBody.accept(this) - } - - override def visit(tlaSetRefinement: TLASetRefinement): Unit = { - // TODO: what about the alt. version? - fillDefinitionRegistryFromQuantifierBound(definitionRegistry, tlaSetRefinement.getBinding) - tlaSetRefinement.getWhen.accept(this) - } - - override def visit(tlaSpecialVariableVariable: TLASpecialVariableVariable): Unit = () // TODO: anything here? - - override def visit(tlaSpecialVariableValue: TLASpecialVariableValue): Unit = () // TODO: anything here? - - override def visit(tlaString: TLAString): Unit = () - - override def visit(tlaUnary: TLAUnary): Unit = { - definitionRegistry.getReferences.put(tlaUnary.getUID, tlaUnary.getRefersTo.getUID) - assert(definitionRegistry.findOperator(tlaUnary.getRefersTo.getUID) ne null) - tlaUnary.getOperand.accept(this) - } - - override def visit(tlaUniversal: TLAUniversal): Unit = { - tlaUniversal.getIds.asScala.foreach(id => definitionRegistry.addLocalVariable(id.getUID)) - tlaUniversal.getBody.accept(this) - } - - override def visit(plusCalDefaultInitValue: PlusCalDefaultInitValue): Unit = () - }) - } -} diff --git a/src/pgo/model/tla/TLAVariableDeclaration.scala b/src/pgo/model/tla/TLAVariableDeclaration.scala deleted file mode 100644 index 380e9e381..000000000 --- a/src/pgo/model/tla/TLAVariableDeclaration.scala +++ /dev/null @@ -1,29 +0,0 @@ -package pgo.model.tla - -import scala.jdk.CollectionConverters._ -import pgo.util.SourceLocation - -final class TLAVariableDeclaration(loc: SourceLocation, val variables: List[TLAIdentifier]) extends TLAUnit(loc) with TLADefinitionComposite { - def this(loc: SourceLocation, variables: java.util.List[TLAIdentifier]) = - this(loc, variables.asScala.toList) - - def getVariables: java.util.List[TLAIdentifier] = variables.asJava - - override val definitions: List[TLADefinition] = List(this) - - override def copy: TLAVariableDeclaration = new TLAVariableDeclaration(loc, variables.map(_.copy())) - - override val members: List[TLADefinition] = variables - - override def accept[T, E <: Throwable](v: TLAUnitVisitor[T, E]): T = v.visit(this) - - override def equals(other: Any): Boolean = other match { - case that: TLAVariableDeclaration => - variables == that.variables - case _ => false - } - - override def hashCode(): Int = variables.hashCode - - override def toString: String = s"VARIABLES ${variables.mkString(",")}" -} diff --git a/src/pgo/model/type/AbstractRecordType.java b/src/pgo/model/type/AbstractRecordType.java deleted file mode 100644 index 1b35e5369..000000000 --- a/src/pgo/model/type/AbstractRecordType.java +++ /dev/null @@ -1,34 +0,0 @@ -package pgo.model.type; - -import pgo.util.Origin; - -import java.util.List; - -public class AbstractRecordType extends Type { - private final String name; - - /** - * The constructor must be kept package-protected so that PGoTypeGenerator can safely do its job - * @param name the name of the record - * @param origins track where this type come from - */ - AbstractRecordType(String name, List origins) { - super(origins); - this.name = name; - } - - @Override - public int hashCode() { - return name.hashCode() * 31 + 17; - } - - @Override - public boolean equals(Object obj) { - return this == obj; - } - - @Override - public T accept(TypeVisitor v) throws E { - return v.visit(this); - } -} diff --git a/src/pgo/model/type/ArchetypeResourceCollectionType.java b/src/pgo/model/type/ArchetypeResourceCollectionType.java deleted file mode 100644 index aebb1bd5f..000000000 --- a/src/pgo/model/type/ArchetypeResourceCollectionType.java +++ /dev/null @@ -1,71 +0,0 @@ -package pgo.model.type; - -import pgo.util.Origin; - -import java.util.List; -import java.util.Objects; - -public class ArchetypeResourceCollectionType extends Type { - private Type keyType; - private Type readType; - private Type writeType; - - /** - * @param keyType - * @param readType - * @param writeType - * @param origins track where this type come from - */ - public ArchetypeResourceCollectionType(Type keyType, Type readType, Type writeType, List origins) { - super(origins); - this.keyType = keyType; - this.readType = readType; - this.writeType = writeType; - } - - @Override - public int hashCode() { - return Objects.hash(keyType, readType, writeType); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!(obj instanceof ArchetypeResourceCollectionType)) { - return false; - } - ArchetypeResourceCollectionType other = (ArchetypeResourceCollectionType) obj; - return keyType.equals(other.keyType) && readType.equals(other.readType) && writeType.equals(other.writeType); - } - - @Override - public T accept(TypeVisitor v) throws E { - return v.visit(this); - } - - public Type getKeyType() { - return keyType; - } - - void setKeyType(Type keyType) { - this.keyType = keyType; - } - - public Type getReadType() { - return readType; - } - - void setReadType(Type readType) { - this.readType = readType; - } - - public Type getWriteType() { - return writeType; - } - - void setWriteType(Type writeType) { - this.writeType = writeType; - } -} diff --git a/src/pgo/model/type/ArchetypeResourceType.java b/src/pgo/model/type/ArchetypeResourceType.java deleted file mode 100644 index 84b32e62d..000000000 --- a/src/pgo/model/type/ArchetypeResourceType.java +++ /dev/null @@ -1,59 +0,0 @@ -package pgo.model.type; - -import pgo.util.Origin; - -import java.util.List; -import java.util.Objects; - -public class ArchetypeResourceType extends Type { - private Type readType; - private Type writeType; - /** - * @param readType - * @param writeType - * @param origins track where this type come from - */ - public ArchetypeResourceType(Type readType, Type writeType, List origins) { - super(origins); - this.readType = readType; - this.writeType = writeType; - } - - @Override - public int hashCode() { - return Objects.hash(readType, writeType); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!(obj instanceof ArchetypeResourceType)) { - return false; - } - ArchetypeResourceType other = (ArchetypeResourceType) obj; - return readType.equals(other.readType) && writeType.equals(other.writeType); - } - - @Override - public T accept(TypeVisitor v) throws E { - return v.visit(this); - } - - public Type getReadType() { - return readType; - } - - void setReadType(Type readType) { - this.readType = readType; - } - - public Type getWriteType() { - return writeType; - } - - void setWriteType(Type writeType) { - this.writeType = writeType; - } -} diff --git a/src/pgo/model/type/BacktrackingFailureIssue.java b/src/pgo/model/type/BacktrackingFailureIssue.java deleted file mode 100644 index 9d1fbbf0e..000000000 --- a/src/pgo/model/type/BacktrackingFailureIssue.java +++ /dev/null @@ -1,22 +0,0 @@ -package pgo.model.type; - -import pgo.errors.Issue; -import pgo.errors.IssueVisitor; -import pgo.model.type.constraint.PolymorphicConstraint; - -public class BacktrackingFailureIssue extends Issue { - private final PolymorphicConstraint polymorphicConstraint; - - public BacktrackingFailureIssue(PolymorphicConstraint polymorphicConstraint) { - this.polymorphicConstraint = polymorphicConstraint; - } - - @Override - public T accept(IssueVisitor v) throws E { - return v.visit(this); - } - - public PolymorphicConstraint getPolymorphicConstraint() { - return polymorphicConstraint; - } -} diff --git a/src/pgo/model/type/BoolType.java b/src/pgo/model/type/BoolType.java deleted file mode 100644 index 0a0cb0d23..000000000 --- a/src/pgo/model/type/BoolType.java +++ /dev/null @@ -1,29 +0,0 @@ -package pgo.model.type; - -import pgo.util.Origin; - -import java.util.List; - -/** - * Represents the boolean type. - */ -public class BoolType extends Type { - public BoolType(List origins) { - super(origins); - } - - @Override - public int hashCode() { - return 2; - } - - @Override - public boolean equals(Object obj) { - return obj instanceof BoolType; - } - - @Override - public T accept(TypeVisitor v) throws E { - return v.visit(this); - } -} diff --git a/src/pgo/model/type/ChanType.java b/src/pgo/model/type/ChanType.java deleted file mode 100644 index af9e8e5c9..000000000 --- a/src/pgo/model/type/ChanType.java +++ /dev/null @@ -1,32 +0,0 @@ -package pgo.model.type; - -import pgo.util.Origin; - -import java.util.List; - -/** - * Represents a channel. - */ -public class ChanType extends SimpleContainerType { - public ChanType(Type elementType, List origins) { - super(elementType, origins); - } - - @Override - public int hashCode() { - return super.hashCode() * 17 + 2; - } - - @Override - public boolean equals(Object p) { - if (!(p instanceof ChanType)) { - return false; - } - return super.equals(p); - } - - @Override - public T accept(TypeVisitor v) throws E { - return v.visit(this); - } -} diff --git a/src/pgo/model/type/FunctionType.java b/src/pgo/model/type/FunctionType.java deleted file mode 100644 index af0a3d4bb..000000000 --- a/src/pgo/model/type/FunctionType.java +++ /dev/null @@ -1,55 +0,0 @@ -package pgo.model.type; - -import pgo.util.Origin; - -import java.util.Collections; -import java.util.List; - -/** - * Represents the function type. - */ -public class FunctionType extends Type { - private List paramTypes; - private Type returnType; - - public FunctionType(List paramTypes, Type returnType, List origins) { - super(origins); - this.paramTypes = paramTypes; - this.returnType = returnType; - } - - void setParamTypes(List paramTypes) { - this.paramTypes = paramTypes; - } - - public List getParamTypes() { - return Collections.unmodifiableList(paramTypes); - } - - void setReturnType(Type returnType) { - this.returnType = returnType; - } - - public Type getReturnType() { - return returnType; - } - - @Override - public int hashCode() { - return paramTypes.hashCode() * 17 + returnType.hashCode() * 19 + 2; - } - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof FunctionType)) { - return false; - } - FunctionType fun = (FunctionType) obj; - return paramTypes.equals(fun.paramTypes) && returnType.equals(fun.returnType); - } - - @Override - public T accept(TypeVisitor v) throws E { - return v.visit(this); - } -} diff --git a/src/pgo/model/type/InfiniteTypeIssue.java b/src/pgo/model/type/InfiniteTypeIssue.java deleted file mode 100644 index 364bddcf0..000000000 --- a/src/pgo/model/type/InfiniteTypeIssue.java +++ /dev/null @@ -1,27 +0,0 @@ -package pgo.model.type; - -import pgo.errors.Issue; -import pgo.errors.IssueVisitor; - -public class InfiniteTypeIssue extends Issue { - private final Type lhs; - private final Type rhs; - - public InfiniteTypeIssue(Type lhs, Type rhs) { - this.lhs = lhs; - this.rhs = rhs; - } - - @Override - public T accept(IssueVisitor v) throws E { - return v.visit(this); - } - - public Type getLhs() { - return lhs; - } - - public Type getRhs() { - return rhs; - } -} diff --git a/src/pgo/model/type/IntType.java b/src/pgo/model/type/IntType.java deleted file mode 100644 index f0725a66c..000000000 --- a/src/pgo/model/type/IntType.java +++ /dev/null @@ -1,29 +0,0 @@ -package pgo.model.type; - -import pgo.util.Origin; - -import java.util.List; - -/** - * Represents a fallback integer type. - */ -public class IntType extends Type { - public IntType(List origins) { - super(origins); - } - - @Override - public int hashCode() { - return 3; - } - - @Override - public boolean equals(Object obj) { - return obj instanceof IntType; - } - - @Override - public T accept(TypeVisitor v) throws E { - return v.visit(this); - } -} diff --git a/src/pgo/model/type/InterfaceType.java b/src/pgo/model/type/InterfaceType.java deleted file mode 100644 index 1480bae20..000000000 --- a/src/pgo/model/type/InterfaceType.java +++ /dev/null @@ -1,29 +0,0 @@ -package pgo.model.type; - -import pgo.util.Origin; - -import java.util.List; - -public class InterfaceType extends Type { - /** - * @param origins track where this type come from - */ - public InterfaceType(List origins) { - super(origins); - } - - @Override - public int hashCode() { - return 5; - } - - @Override - public boolean equals(Object obj) { - return obj instanceof InterfaceType; - } - - @Override - public T accept(TypeVisitor v) throws E { - return v.visit(this); - } -} diff --git a/src/pgo/model/type/MapType.java b/src/pgo/model/type/MapType.java deleted file mode 100644 index 2d9bb2fa2..000000000 --- a/src/pgo/model/type/MapType.java +++ /dev/null @@ -1,55 +0,0 @@ -package pgo.model.type; - -import pgo.util.Origin; - -import java.util.List; - -/** - * Represents a map. - */ -public class MapType extends Type { - private Type keyType; - private Type valueType; - - public MapType(Type keyType, Type valueType, List origins) { - super(origins); - this.keyType = keyType; - this.valueType = valueType; - } - - void setKeyType(Type keyType) { - this.keyType = keyType; - } - - public Type getKeyType() { - return keyType; - } - - void setValueType(Type valueType) { - this.valueType = valueType; - } - - public Type getValueType() { - return valueType; - } - - @Override - public int hashCode() { - return keyType.hashCode() * 17 + valueType.hashCode() * 19 + 3; - } - - @Override - public boolean equals(Object p) { - if (!(p instanceof MapType)) { - return false; - } - MapType other = (MapType) p; - return keyType.equals(other.keyType) && valueType.equals(other.valueType); - } - - @Override - public T accept(TypeVisitor v) throws E { - return v.visit(this); - } - -} diff --git a/src/pgo/model/type/NoMatchingFieldIssue.java b/src/pgo/model/type/NoMatchingFieldIssue.java deleted file mode 100644 index e642cf1f0..000000000 --- a/src/pgo/model/type/NoMatchingFieldIssue.java +++ /dev/null @@ -1,28 +0,0 @@ -package pgo.model.type; - -import pgo.errors.Issue; -import pgo.errors.IssueVisitor; - -public class NoMatchingFieldIssue extends Issue { - private final RecordType record; - private final String fieldName; - - public NoMatchingFieldIssue(RecordType record, String fieldName) { - this.record = record; - this.fieldName = fieldName; - } - - @Override - public T accept(IssueVisitor v) throws E { - return v.visit(this); - } - - public RecordType getRecord() { - return record; - } - - public String getFieldName() { - return fieldName; - } - -} diff --git a/src/pgo/model/type/NonEnumerableSetType.java b/src/pgo/model/type/NonEnumerableSetType.java deleted file mode 100644 index 348bf4840..000000000 --- a/src/pgo/model/type/NonEnumerableSetType.java +++ /dev/null @@ -1,32 +0,0 @@ -package pgo.model.type; - -import pgo.util.Origin; - -import java.util.List; - -/** - * Represents a non-enumerable set, e.g. Nat, Int, Real. - */ -public class NonEnumerableSetType extends SimpleContainerType { - public NonEnumerableSetType(Type elementType, List origins) { - super(elementType, origins); - } - - @Override - public int hashCode() { - return super.hashCode() * 17 + 3; - } - - @Override - public boolean equals(Object p) { - if (!(p instanceof NonEnumerableSetType)) { - return false; - } - return super.equals(p); - } - - @Override - public T accept(TypeVisitor v) throws E { - return v.visit(this); - } -} diff --git a/src/pgo/model/type/ProcedureType.java b/src/pgo/model/type/ProcedureType.java deleted file mode 100644 index 839ac16f6..000000000 --- a/src/pgo/model/type/ProcedureType.java +++ /dev/null @@ -1,44 +0,0 @@ -package pgo.model.type; - -import pgo.util.Origin; - -import java.util.Collections; -import java.util.List; - -/** - * Represents a PlusCal procedure. - */ -public class ProcedureType extends Type { - private List paramTypes; - - public ProcedureType(List paramTypes, List origins) { - super(origins); - this.paramTypes = paramTypes; - } - - void setParamTypes(List paramTypes) { - this.paramTypes = paramTypes; - } - - public List getParamTypes() { - return Collections.unmodifiableList(paramTypes); - } - - @Override - public int hashCode() { - return paramTypes.hashCode() * 17 + 2; - } - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof ProcedureType)) { - return false; - } - return paramTypes.equals(((ProcedureType) obj).paramTypes); - } - - @Override - public T accept(TypeVisitor v) throws E { - return v.visit(this); - } -} diff --git a/src/pgo/model/type/RealType.java b/src/pgo/model/type/RealType.java deleted file mode 100644 index 7fdf06c99..000000000 --- a/src/pgo/model/type/RealType.java +++ /dev/null @@ -1,29 +0,0 @@ -package pgo.model.type; - -import pgo.util.Origin; - -import java.util.List; - -/** - * Represents the floating point number type. - */ -public class RealType extends Type { - public RealType(List origins) { - super(origins); - } - - @Override - public int hashCode() { - return 7; - } - - @Override - public boolean equals(Object obj) { - return obj instanceof RealType; - } - - @Override - public T accept(TypeVisitor v) throws E { - return v.visit(this); - } -} diff --git a/src/pgo/model/type/RecordType.java b/src/pgo/model/type/RecordType.java deleted file mode 100644 index 3349d44b8..000000000 --- a/src/pgo/model/type/RecordType.java +++ /dev/null @@ -1,83 +0,0 @@ -package pgo.model.type; - -import pgo.util.Origin; - -import java.util.Collections; -import java.util.List; - -public class RecordType extends Type { - public static class Field { - private final String name; - private final Type type; - - public Field(String name, Type type) { - this.name = name; - this.type = type; - } - - public String getName() { - return name; - } - - public Type getType() { - return type; - } - - @Override - public int hashCode() { - return name.hashCode() * 17 + type.hashCode() * 19 + 11; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!(obj instanceof Field)) { - return false; - } - Field other = (Field) obj; - return name.equals(other.name) && type.equals(other.type); - } - } - - private List fields; - - /** - * @param fields fields this record has - * @param origins track where this type come from - */ - public RecordType(List fields, List origins) { - super(origins); - this.fields = fields; - } - - public List getFields() { - return Collections.unmodifiableList(fields); - } - - void setFields(List fields) { - this.fields = fields; - } - - @Override - public int hashCode() { - return fields.hashCode() * 17 + 11; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!(obj instanceof RecordType)) { - return false; - } - return fields.equals(((RecordType) obj).fields); - } - - @Override - public T accept(TypeVisitor v) throws E { - return v.visit(this); - } -} diff --git a/src/pgo/model/type/RecordTypeEntry.java b/src/pgo/model/type/RecordTypeEntry.java deleted file mode 100644 index a518a2c8f..000000000 --- a/src/pgo/model/type/RecordTypeEntry.java +++ /dev/null @@ -1,149 +0,0 @@ -package pgo.model.type; - -import pgo.InternalCompilerError; -import pgo.model.type.constraint.EqualityConstraint; -import pgo.model.type.constraint.MonomorphicConstraint; - -import java.util.*; -import java.util.stream.Collectors; - -abstract class RecordTypeEntry { - abstract boolean hasVariable(TypeVariable variable); - - RecordTypeEntry unify(TypeSolver solver, RecordTypeEntry entry) throws UnificationException { - if (entry instanceof Abstract) { - return unify(solver, (Abstract) entry); - } - if (entry instanceof Concrete) { - return unify(solver, (Concrete) entry); - } - throw new InternalCompilerError(); - } - - abstract RecordTypeEntry unify(TypeSolver solver, Abstract entry) throws UnificationException; - abstract Concrete unify(TypeSolver solver, Concrete entry) throws UnificationException; - - abstract RecordType toConcreteRecord(); - - static class Abstract extends RecordTypeEntry { - static final Abstract EMPTY_ABSTRACT_RECORD = new Abstract(); - - private final Map fields; - - Abstract() { - this(new HashMap<>()); - } - - Abstract(Map fields) { - this.fields = fields; - } - - @Override - boolean hasVariable(TypeVariable variable) { - TypeHasVariableVisitor visitor = new TypeHasVariableVisitor(variable); - return fields.values().stream().anyMatch(t -> t.accept(visitor)); - } - - @Override - RecordTypeEntry unify(TypeSolver solver, Abstract entry) throws UnificationException { - Map fields = new HashMap<>(this.fields); - entry.fields.forEach((k, v) -> { - if (fields.containsKey(k)) { - solver.addFirst(new MonomorphicConstraint(v, v, fields.get(k))); - } else { - fields.put(k, v); - } - }); - return new Abstract(fields); - } - - private void throwException(Concrete entry) throws UnificationException { - List fs = new ArrayList<>(); - fields.forEach((k, v) -> fs.add(new RecordType.Field(k, v))); - throw new UnificationException(new UnsatisfiableConstraintIssue( - entry.record, - new RecordType( - fs, - fs.stream() - .flatMap(f -> f.getType().getOrigins().stream()) - .collect(Collectors.toList())))); - } - - @Override - Concrete unify(TypeSolver solver, Concrete entry) throws UnificationException { - if (entry.record.getFields().size() < fields.size()) { - throwException(entry); - } - Set keysInAbstractNotConcrete = new HashSet<>(fields.keySet()); - keysInAbstractNotConcrete.removeAll(entry.record.getFields().stream() - .map(RecordType.Field::getName) - .collect(Collectors.toSet())); - if (keysInAbstractNotConcrete.size() > 0) { - throwException(entry); - } - for (RecordType.Field field : entry.record.getFields()) { - if (fields.containsKey(field.getName())) { - solver.addFirst(new MonomorphicConstraint( - entry.record, field.getType(), fields.get(field.getName()))); - } - } - return entry; - } - - @Override - RecordType toConcreteRecord() { - return new RecordType( - fields.entrySet().stream() - .sorted(Comparator.comparing(Map.Entry::getKey)) - .map(e -> new RecordType.Field(e.getKey(), e.getValue())) - .collect(Collectors.toList()), - fields.values().stream().flatMap(t -> t.getOrigins().stream()).collect(Collectors.toList())); - } - } - - static class Concrete extends RecordTypeEntry { - private final RecordType record; - - Concrete(RecordType record) { - this.record = record; - } - - RecordType getRecord() { - return record; - } - - @Override - boolean hasVariable(TypeVariable variable) { - return record.accept(new TypeHasVariableVisitor(variable)); - } - - @Override - RecordTypeEntry unify(TypeSolver solver, Abstract entry) throws UnificationException { - return entry.unify(solver, this); - } - - @Override - Concrete unify(TypeSolver solver, Concrete entry) throws UnificationException { - if (entry.record.getFields().size() != record.getFields().size()) { - throw new UnificationException(new UnsatisfiableConstraintIssue(entry.record, record)); - } - List fields = record.getFields(); - List otherFields = entry.record.getFields(); - for (int i = 0; i < otherFields.size(); i++) { - RecordType.Field field = fields.get(i); - RecordType.Field ofield = otherFields.get(i); - if (!field.getName().equals(ofield.getName())) { - throw new UnificationException(new UnsatisfiableConstraintIssue(entry.record, record)); - } - solver.addFirst(new MonomorphicConstraint( - Collections.emptyList(), new EqualityConstraint(field.getType(), ofield.getType()))); - } - return this; - } - - @Override - RecordType toConcreteRecord() { - return record; - } - } -} diff --git a/src/pgo/model/type/SetType.java b/src/pgo/model/type/SetType.java deleted file mode 100644 index 9bc99b3e2..000000000 --- a/src/pgo/model/type/SetType.java +++ /dev/null @@ -1,32 +0,0 @@ -package pgo.model.type; - -import pgo.util.Origin; - -import java.util.List; - -/** - * Represents an enumerable set. - */ -public class SetType extends SimpleContainerType { - public SetType(Type elementType, List origins) { - super(elementType, origins); - } - - @Override - public int hashCode() { - return super.hashCode() * 17 + 5; - } - - @Override - public boolean equals(Object p) { - if (!(p instanceof SetType)) { - return false; - } - return super.equals(p); - } - - @Override - public T accept(TypeVisitor v) throws E { - return v.visit(this); - } -} diff --git a/src/pgo/model/type/SimpleContainerType.java b/src/pgo/model/type/SimpleContainerType.java deleted file mode 100644 index 7d501e2af..000000000 --- a/src/pgo/model/type/SimpleContainerType.java +++ /dev/null @@ -1,38 +0,0 @@ -package pgo.model.type; - -import pgo.util.Origin; - -import java.util.List; - -/** - * Contains overloaded methods for a container type with only one element type, for convenience. - */ -public abstract class SimpleContainerType extends Type { - protected Type elementType; - - public SimpleContainerType(Type elementType, List origins) { - super(origins); - this.elementType = elementType; - } - - void setElementType(Type elementType) { - this.elementType = elementType; - } - - public Type getElementType() { - return elementType; - } - - @Override - public int hashCode() { - return elementType.hashCode(); - } - - @Override - public boolean equals(Object p) { - if (!(p instanceof SimpleContainerType)) { - return false; - } - return elementType.equals(((SimpleContainerType) p).elementType); - } -} diff --git a/src/pgo/model/type/SliceType.java b/src/pgo/model/type/SliceType.java deleted file mode 100644 index edf6206ca..000000000 --- a/src/pgo/model/type/SliceType.java +++ /dev/null @@ -1,32 +0,0 @@ -package pgo.model.type; - -import pgo.util.Origin; - -import java.util.List; - -/** - * Represents a slice. - */ -public class SliceType extends SimpleContainerType { - public SliceType(Type elementType, List origins) { - super(elementType, origins); - } - - @Override - public int hashCode() { - return super.hashCode() * 17 + 7; - } - - @Override - public boolean equals(Object p) { - if (!(p instanceof SliceType)) { - return false; - } - return super.equals(p); - } - - @Override - public T accept(TypeVisitor v) throws E { - return v.visit(this); - } -} diff --git a/src/pgo/model/type/StringType.java b/src/pgo/model/type/StringType.java deleted file mode 100644 index 83c5ebc10..000000000 --- a/src/pgo/model/type/StringType.java +++ /dev/null @@ -1,29 +0,0 @@ -package pgo.model.type; - -import pgo.util.Origin; - -import java.util.List; - -/** - * Represents the string type. - */ -public class StringType extends Type { - public StringType(List origins) { - super(origins); - } - - @Override - public int hashCode() { - return 11; - } - - @Override - public boolean equals(Object obj) { - return obj instanceof StringType; - } - - @Override - public T accept(TypeVisitor v) throws E { - return v.visit(this); - } -} diff --git a/src/pgo/model/type/TupleType.java b/src/pgo/model/type/TupleType.java deleted file mode 100644 index b5b5d6dde..000000000 --- a/src/pgo/model/type/TupleType.java +++ /dev/null @@ -1,44 +0,0 @@ -package pgo.model.type; - -import pgo.util.Origin; - -import java.util.Collections; -import java.util.List; - -/** - * Represents a realized tuple. - */ -public class TupleType extends Type { - private List elementTypes; - - public TupleType(List elementTypes, List origins) { - super(origins); - this.elementTypes = Collections.unmodifiableList(elementTypes); - } - - void setElementTypes(List elementTypes) { - this.elementTypes = elementTypes; - } - - public List getElementTypes() { - return elementTypes; - } - - @Override - public int hashCode() { - return elementTypes.hashCode() * 17 + 3; - } - - @Override - public boolean equals(Object p) { - if (!(p instanceof TupleType)) { - return false; - } - return elementTypes.equals(((TupleType) p).elementTypes); - } - - @Override - public T accept(TypeVisitor v) throws E { - return v.visit(this); - } -} diff --git a/src/pgo/model/type/Type.java b/src/pgo/model/type/Type.java deleted file mode 100644 index e4d61b898..000000000 --- a/src/pgo/model/type/Type.java +++ /dev/null @@ -1,44 +0,0 @@ -package pgo.model.type; - -import pgo.formatters.IndentingWriter; -import pgo.formatters.TypeFormattingVisitor; -import pgo.util.Derived; -import pgo.util.DerivedVisitor; -import pgo.util.Origin; - -import java.io.IOException; -import java.io.StringWriter; -import java.util.List; - -public abstract class Type extends Derived { - /** - * @param origins track where this type come from - */ - public Type(List origins) { - origins.forEach(this::addOrigin); - } - - @Override - public abstract int hashCode(); - - @Override - public abstract boolean equals(Object obj); - - @Override - public String toString() { - StringWriter writer = new StringWriter(); - try { - this.accept(new TypeFormattingVisitor(new IndentingWriter(writer))); - } catch (IOException e) { - e.printStackTrace(); - } - return writer.toString(); - } - - @Override - public T accept(DerivedVisitor v) throws E{ - return v.visit(this); - } - - public abstract T accept(TypeVisitor v) throws E; -} diff --git a/src/pgo/model/type/TypeCopyVisitor.java b/src/pgo/model/type/TypeCopyVisitor.java deleted file mode 100644 index 3cf5797b2..000000000 --- a/src/pgo/model/type/TypeCopyVisitor.java +++ /dev/null @@ -1,118 +0,0 @@ -package pgo.model.type; - -import java.util.stream.Collectors; - -public class TypeCopyVisitor extends TypeVisitor { - @Override - public Type visit(AbstractRecordType abstractRecordType) throws RuntimeException { - return abstractRecordType; - } - - @Override - public Type visit(ArchetypeResourceType archetypeResourceType) throws RuntimeException { - return new ArchetypeResourceType( - archetypeResourceType.getReadType().accept(this), - archetypeResourceType.getWriteType().accept(this), - archetypeResourceType.getOrigins()); - } - - @Override - public Type visit(ArchetypeResourceCollectionType archetypeResourceCollectionType) throws RuntimeException { - return new ArchetypeResourceCollectionType( - archetypeResourceCollectionType.getKeyType().accept(this), - archetypeResourceCollectionType.getReadType().accept(this), - archetypeResourceCollectionType.getWriteType().accept(this), - archetypeResourceCollectionType.getOrigins()); - } - - @Override - public Type visit(TypeVariable typeVariable) throws RuntimeException { - return typeVariable; - } - - @Override - public Type visit(TupleType tupleType) throws RuntimeException { - return new TupleType( - tupleType.getElementTypes().stream().map(t -> t.accept(this)).collect(Collectors.toList()), - tupleType.getOrigins()); - } - - @Override - public Type visit(StringType stringType) throws RuntimeException { - return stringType; - } - - @Override - public Type visit(SetType setType) throws RuntimeException { - return new SetType(setType.getElementType().accept(this), setType.getOrigins()); - } - - @Override - public Type visit(NonEnumerableSetType nonEnumerableSetType) throws RuntimeException { - return new NonEnumerableSetType( - nonEnumerableSetType.getElementType().accept(this), nonEnumerableSetType.getOrigins()); - } - - @Override - public Type visit(BoolType boolType) throws RuntimeException { - return boolType; - } - - @Override - public Type visit(RealType realType) throws RuntimeException { - return realType; - } - - @Override - public Type visit(FunctionType functionType) throws RuntimeException { - return new FunctionType( - functionType.getParamTypes().stream().map(p -> p.accept(this)).collect(Collectors.toList()), - functionType.getReturnType().accept(this), - functionType.getOrigins()); - } - - @Override - public Type visit(ChanType chanType) throws RuntimeException { - return new ChanType(chanType.getElementType().accept(this), chanType.getOrigins()); - } - - @Override - public Type visit(IntType intType) throws RuntimeException { - return intType; - } - - @Override - public Type visit(InterfaceType interfaceType) throws RuntimeException { - return interfaceType; - } - - @Override - public Type visit(MapType mapType) throws RuntimeException { - return new MapType( - mapType.getKeyType().accept(this), - mapType.getValueType().accept(this), - mapType.getOrigins()); - } - - @Override - public Type visit(SliceType sliceType) throws RuntimeException { - return new SliceType(sliceType.getElementType().accept(this), sliceType.getOrigins()); - } - - @Override - public Type visit(ProcedureType procedureType) throws RuntimeException { - return new ProcedureType( - procedureType.getParamTypes().stream().map(p -> p.accept(this)).collect(Collectors.toList()), - procedureType.getOrigins()); - } - - @Override - public Type visit(RecordType recordType) throws RuntimeException { - return new RecordType( - recordType.getFields() - .stream() - .map(f -> new RecordType.Field(f.getName(), f.getType())) - .collect(Collectors.toList()), - recordType.getOrigins()); - } -} diff --git a/src/pgo/model/type/TypeGenerator.java b/src/pgo/model/type/TypeGenerator.java deleted file mode 100644 index ad3c69935..000000000 --- a/src/pgo/model/type/TypeGenerator.java +++ /dev/null @@ -1,28 +0,0 @@ -package pgo.model.type; - -import pgo.util.Origin; - -import java.util.List; -import java.util.concurrent.atomic.AtomicLong; - -/** - * Generates fresh PGoTypeVariables and PGoAbstractRecords. - */ -public class TypeGenerator { - private final AtomicLong current = new AtomicLong(0); - private final String prefix; - - public TypeGenerator(String prefix) { - this.prefix = prefix; - } - - public TypeVariable getTypeVariable(List origins) { - long c = current.addAndGet(1); - return new TypeVariable(prefix + c, origins); - } - - public AbstractRecordType getAbstractRecord(List origins) { - long c = current.addAndGet(1); - return new AbstractRecordType(prefix + c, origins); - } -} diff --git a/src/pgo/model/type/TypeHasVariableVisitor.java b/src/pgo/model/type/TypeHasVariableVisitor.java deleted file mode 100644 index 1ff2de847..000000000 --- a/src/pgo/model/type/TypeHasVariableVisitor.java +++ /dev/null @@ -1,102 +0,0 @@ -package pgo.model.type; - -public class TypeHasVariableVisitor extends TypeVisitor { - private final TypeVariable typeVariable; - - public TypeHasVariableVisitor(TypeVariable typeVariable) { - this.typeVariable = typeVariable; - } - - @Override - public Boolean visit(AbstractRecordType abstractRecordType) throws RuntimeException { - return false; - } - - @Override - public Boolean visit(ArchetypeResourceType archetypeResourceType) throws RuntimeException { - return archetypeResourceType.getReadType().accept(this) || archetypeResourceType.getWriteType().accept(this); - } - - @Override - public Boolean visit(ArchetypeResourceCollectionType archetypeResourceCollectionType) throws RuntimeException { - return archetypeResourceCollectionType.getKeyType().accept(this) || - archetypeResourceCollectionType.getReadType().accept(this) || - archetypeResourceCollectionType.getWriteType().accept(this); - } - - @Override - public Boolean visit(TypeVariable typeVariable) throws RuntimeException { - return typeVariable.equals(this.typeVariable); - } - - @Override - public Boolean visit(TupleType tupleType) throws RuntimeException { - return tupleType.getElementTypes().stream().anyMatch(t -> t.accept(this)); - } - - @Override - public Boolean visit(StringType stringType) throws RuntimeException { - return false; - } - - @Override - public Boolean visit(SetType setType) throws RuntimeException { - return setType.getElementType().accept(this); - } - - @Override - public Boolean visit(NonEnumerableSetType nonEnumerableSetType) throws RuntimeException { - return nonEnumerableSetType.getElementType().accept(this); - } - - @Override - public Boolean visit(BoolType boolType) throws RuntimeException { - return false; - } - - @Override - public Boolean visit(RealType realType) throws RuntimeException { - return false; - } - - @Override - public Boolean visit(FunctionType functionType) throws RuntimeException { - return functionType.getParamTypes().stream().anyMatch(p -> p.accept(this)) || - functionType.getReturnType().accept(this); - } - - @Override - public Boolean visit(ChanType chanType) throws RuntimeException { - return chanType.getElementType().accept(this); - } - - @Override - public Boolean visit(IntType intType) throws RuntimeException { - return false; - } - - @Override - public Boolean visit(InterfaceType interfaceType) throws RuntimeException { - return false; - } - - @Override - public Boolean visit(MapType mapType) throws RuntimeException { - return mapType.getKeyType().accept(this) || mapType.getValueType().accept(this); - } - - @Override - public Boolean visit(SliceType sliceType) throws RuntimeException { - return sliceType.getElementType().accept(this); - } - - @Override - public Boolean visit(ProcedureType procedureType) throws RuntimeException { - return procedureType.getParamTypes().stream().anyMatch(p -> p.accept(this)); - } - - @Override - public Boolean visit(RecordType recordType) throws RuntimeException { - return recordType.getFields().stream().anyMatch(f -> f.getType().accept(this)); - } -} diff --git a/src/pgo/model/type/TypeSolver.java b/src/pgo/model/type/TypeSolver.java deleted file mode 100644 index a3a2e0417..000000000 --- a/src/pgo/model/type/TypeSolver.java +++ /dev/null @@ -1,451 +0,0 @@ -package pgo.model.type; - -import pgo.InternalCompilerError; -import pgo.Unreachable; -import pgo.errors.Issue; -import pgo.errors.IssueContext; -import pgo.model.type.constraint.*; -import pgo.util.UnionFind; - -import java.util.*; -import java.util.stream.Collectors; - -/** - * A constraint solver for PGo's type system. It does not support recursive types. - */ -public class TypeSolver { - private Deque constraints = new ArrayDeque<>(); - private Map mapping = new HashMap<>(); - private UnionFind variableGroups = new UnionFind<>(); - private UnionFind abstractRecordGroups = new UnionFind<>(); - private Map abstractRecordsToEntries = new HashMap<>(); - private Deque stateStack = new ArrayDeque<>(); - private int lastConstraintsSize = Integer.MAX_VALUE; - private Issue typeInferenceIssue = null; - - private TypeVariableSubstitutionVisitor subs = new TypeVariableSubstitutionVisitor( - new TypeSubstitution(variableGroups, mapping)); - - public TypeSubstitution getSubstitution() { - return new TypeSubstitution(variableGroups, mapping); - } - - public void addConstraint(Constraint constraint) { - constraints.addLast(constraint); - } - - void addFirst(Constraint constraint) { - constraints.addFirst(constraint); - } - - private Optional backtrack(Issue issue) { - if (lastConstraintsSize > constraints.size()) { - lastConstraintsSize = constraints.size(); - typeInferenceIssue = issue; - } - if (stateStack.size() <= 0) { - // unsuccessful - return Optional.of(typeInferenceIssue); - } - TypeSolver old = stateStack.pop(); - constraints = old.constraints; - mapping = old.mapping; - variableGroups = old.variableGroups; - abstractRecordGroups = old.abstractRecordGroups; - abstractRecordsToEntries = old.abstractRecordsToEntries; - stateStack = old.stateStack; - subs = new TypeVariableSubstitutionVisitor( - new TypeSubstitution(variableGroups, mapping)); - return Optional.empty(); - } - - private TypeSolver copy() { - TypeSolver copy = new TypeSolver(); - copy.stateStack = new ArrayDeque<>(stateStack); - copy.constraints = constraints.stream() - .map(Constraint::copy) - .collect(Collectors.toCollection(ArrayDeque::new)); - copy.mapping = new HashMap<>(); - copy.variableGroups = variableGroups.copy(); - copy.abstractRecordGroups = abstractRecordGroups.copy(); - copy.abstractRecordsToEntries = new HashMap<>(abstractRecordsToEntries); - TypeCopyVisitor visitor = new TypeCopyVisitor(); - mapping.forEach((k, v) -> copy.mapping.put(k, v.accept(visitor))); - copy.subs = null; - return copy; - } - - private void simplify() { - TypeVariableAbstractRecordSubstitutionVisitor tvarSubs = - new TypeVariableAbstractRecordSubstitutionVisitor( - getSubstitution(), abstractRecordGroups, abstractRecordsToEntries); - boolean changed = true; - while (changed) { - changed = false; - for (Map.Entry entry : mapping.entrySet()) { - TypeVariable k = entry.getKey(); - Type v = entry.getValue(); - Type newV = v.accept(tvarSubs); - if (!newV.equals(v)) { - changed = true; - mapping.put(k, newV); - } - } - } - } - - private Optional unify() { - lastConstraintsSize = constraints.size(); - while (constraints.size() != 0) { - Constraint constraint = constraints.removeFirst(); - if (constraint instanceof PolymorphicConstraint) { - if (!((PolymorphicConstraint) constraint).hasNext()) { - return Optional.of(new BacktrackingFailureIssue((PolymorphicConstraint) constraint)); - } - // extract first constraints - List basicConstraints = ((PolymorphicConstraint) constraint).next(); - // snapshot state if there are any constraints left - if (((PolymorphicConstraint) constraint).hasNext()) { - // push copy with current constraint added at front - TypeSolver copy = copy(); - copy.constraints.addFirst(constraint.copy()); - stateStack.push(copy); - } - // add the first constraints - for (BasicConstraint basicConstraint : basicConstraints) { - constraints.addFirst(new MonomorphicConstraint(constraint.getOrigins(), basicConstraint)); - } - // solve the newly added constraints - continue; - } - if (!(constraint instanceof MonomorphicConstraint)) { - throw new Unreachable(); - } - BasicConstraint basicConstraint = ((MonomorphicConstraint) constraint).getBasicConstraint(); - if (basicConstraint instanceof HasFieldConstraint) { - HasFieldConstraint hasFieldConstraint = (HasFieldConstraint) basicConstraint; - Type expressionType = hasFieldConstraint.getExpressionType(); - String fieldName = hasFieldConstraint.getFieldName(); - Type fieldType = hasFieldConstraint.getFieldType(); - if (expressionType instanceof RecordType) { - if (((RecordType) expressionType).getFields().stream().noneMatch(f -> { - if (f.getName().equals(fieldName)) { - addFirst(new MonomorphicConstraint(constraint, fieldType, f.getType())); - return true; - } - return false; - })) { - Optional optionalIssue = - backtrack(new NoMatchingFieldIssue((RecordType) expressionType, fieldName)); - if (optionalIssue.isPresent()) { - return optionalIssue; - } - continue; - } - continue; - } - if (expressionType instanceof AbstractRecordType) { - AbstractRecordType abstractRecord = - abstractRecordGroups.find((AbstractRecordType) expressionType); - if (abstractRecordsToEntries.containsKey(abstractRecord)) { - try { - abstractRecordsToEntries.put( - abstractRecord, - abstractRecordsToEntries.get(abstractRecord) - .unify( - this, - new RecordTypeEntry.Abstract( - Collections.singletonMap(fieldName, fieldType)))); - } catch (UnificationException e) { - Optional optionalIssue = backtrack(e.getIssue()); - if (optionalIssue.isPresent()) { - return optionalIssue; - } - continue; - } - } else { - abstractRecordsToEntries.put( - abstractRecord, - new RecordTypeEntry.Abstract(Collections.singletonMap(fieldName, fieldType))); - } - continue; - } - throw new InternalCompilerError(); - } - if (!(basicConstraint instanceof EqualityConstraint)) { - throw new InternalCompilerError(); - } - Type a = ((EqualityConstraint) basicConstraint).getLhs(); - Type b = ((EqualityConstraint) basicConstraint).getRhs(); - if (a instanceof TypeVariable && b instanceof TypeVariable) { - // find the variable groups to which a and b belong - a = variableGroups.find((TypeVariable) a); - b = variableGroups.find((TypeVariable) b); - // get the previous types to which a and b maps - Type subbedA = a.accept(subs); - Type subbedB = b.accept(subs); - // union the two groups to which a and b belong - variableGroups.union((TypeVariable) a, (TypeVariable) b); - // add constraints for the group representative - TypeVariable groupRepresentative = variableGroups.find((TypeVariable) a); - if (!a.equals(groupRepresentative)) { - mapping.remove(a); - constraints.addFirst(new MonomorphicConstraint( - Collections.emptyList(), new EqualityConstraint(groupRepresentative, subbedA))); - } - if (!b.equals(groupRepresentative)) { - mapping.remove(b); - constraints.addFirst(new MonomorphicConstraint( - Collections.emptyList(), new EqualityConstraint(groupRepresentative, subbedB))); - } - continue; - } - TypeVariable groupRepresentative = null; - if (a instanceof TypeVariable) { - // find the variable group to which a belongs - groupRepresentative = variableGroups.find((TypeVariable) a); - a = groupRepresentative; - } - if (b instanceof TypeVariable) { - // find the variable group to which b belongs - groupRepresentative = variableGroups.find((TypeVariable) b); - // swap a and b - b = a; - a = groupRepresentative; - } - // a and b are substituted so that we gain more information about their structures - a = a.accept(subs); - b = b.accept(subs); - // resolve abstract records - if (a instanceof AbstractRecordType && b instanceof AbstractRecordType) { - // find the variable groups to which a and b belong - a = abstractRecordGroups.find((AbstractRecordType) a); - b = abstractRecordGroups.find((AbstractRecordType) b); - // get the previous entries to which a and b maps - RecordTypeEntry entryA = abstractRecordsToEntries.getOrDefault( - a, RecordTypeEntry.Abstract.EMPTY_ABSTRACT_RECORD); - RecordTypeEntry entryB = abstractRecordsToEntries.getOrDefault( - b, RecordTypeEntry.Abstract.EMPTY_ABSTRACT_RECORD); - // union the two groups to which a and b belong - abstractRecordGroups.union((AbstractRecordType) a, (AbstractRecordType) b); - // add constraints for the group representative - try { - AbstractRecordType rep = abstractRecordGroups.find((AbstractRecordType) a); - if (!a.equals(rep)) { - abstractRecordsToEntries.remove(a); - entryA = entryA.unify(this, abstractRecordsToEntries.get(rep)); - } - if (!b.equals(rep)) { - abstractRecordsToEntries.remove(b); - entryB = entryB.unify(this, abstractRecordsToEntries.get(rep)); - } - abstractRecordsToEntries.put(rep, entryA.unify(this, entryB)); - } catch (UnificationException e) { - Optional optionalIssue = backtrack(e.getIssue()); - if (optionalIssue.isPresent()) { - return optionalIssue; - } - continue; - } - continue; - } - if (a instanceof AbstractRecordType) { - // swap a and b - AbstractRecordType tmp = abstractRecordGroups.find((AbstractRecordType) a); - a = b; - b = tmp; - } - if (b instanceof AbstractRecordType) { - b = abstractRecordGroups.find((AbstractRecordType) b); - } - if (a.equals(b)) { - // nothing to do - continue; - } - if (a instanceof TypeVariable) { - if (!a.equals(groupRepresentative)) { - throw new InternalCompilerError(); - } - // prevent infinite types - if (b instanceof AbstractRecordType) { - if (abstractRecordsToEntries.containsKey(b) && - abstractRecordsToEntries.get(b).hasVariable((TypeVariable) a)) { - Optional optionalIssue = backtrack(new InfiniteTypeIssue(a, b)); - if (optionalIssue.isPresent()) { - return optionalIssue; - } - continue; - } - } else { - if (b.accept(new TypeHasVariableVisitor((TypeVariable) a))) { - Optional optionalIssue = backtrack(new InfiniteTypeIssue(a, b)); - if (optionalIssue.isPresent()) { - return optionalIssue; - } - continue; - } - } - // the constraint is of the form "a = some type" - // first, unify the type to which a maps with b - if (mapping.containsKey(a)) { - constraints.addFirst(new MonomorphicConstraint(constraint, mapping.get(a), b)); - } - // then, assign a to that type - mapping.put(((TypeVariable) a), b); - constraint.getOrigins().forEach(a::addOrigin); - } else if (a instanceof RecordType && b instanceof AbstractRecordType) { - try { - abstractRecordsToEntries.put( - (AbstractRecordType) b, - abstractRecordsToEntries.getOrDefault(b, RecordTypeEntry.Abstract.EMPTY_ABSTRACT_RECORD) - .unify(this, new RecordTypeEntry.Concrete((RecordType) a))); - } catch (UnificationException e) { - Optional optionalIssue = backtrack(e.getIssue()); - if (optionalIssue.isPresent()) { - return optionalIssue; - } - continue; - } - } else if (a instanceof RecordType && b instanceof RecordType) { - try { - (new RecordTypeEntry.Concrete((RecordType) a)) - .unify(this, new RecordTypeEntry.Concrete((RecordType) b)); - } catch (UnificationException e) { - Optional optionalIssue = backtrack(e.getIssue()); - if (optionalIssue.isPresent()) { - return optionalIssue; - } - continue; - } - } else if (a instanceof ArchetypeResourceType && b instanceof ArchetypeResourceType) { - constraints.addFirst(new MonomorphicConstraint( - constraint, - ((ArchetypeResourceType) a).getReadType(), - ((ArchetypeResourceType) b).getReadType())); - constraints.addFirst(new MonomorphicConstraint( - constraint, - ((ArchetypeResourceType) a).getWriteType(), - ((ArchetypeResourceType) b).getWriteType())); - } else if (a instanceof ArchetypeResourceCollectionType && b instanceof ArchetypeResourceCollectionType) { - constraints.addFirst(new MonomorphicConstraint( - constraint, - ((ArchetypeResourceCollectionType) a).getKeyType(), - ((ArchetypeResourceCollectionType) b).getKeyType())); - constraints.addFirst(new MonomorphicConstraint( - constraint, - ((ArchetypeResourceCollectionType) a).getReadType(), - ((ArchetypeResourceCollectionType) b).getReadType())); - constraints.addFirst(new MonomorphicConstraint( - constraint, - ((ArchetypeResourceCollectionType) a).getWriteType(), - ((ArchetypeResourceCollectionType) b).getWriteType())); - } else if (a instanceof SimpleContainerType && b instanceof SimpleContainerType) { - // a simple container is a container with a single element type, e.g. Set[a], Slice[a], etc. - // in order for SimpleContainer[a] = SimpleContainer[b], - // (1) the container types must be the same, and - if (!a.getClass().equals(b.getClass())) { - Optional optionalIssue = backtrack(new UnsatisfiableConstraintIssue(a, b)); - if (optionalIssue.isPresent()) { - return optionalIssue; - } - continue; - } - // (2) the element types must be the same - constraints.addFirst(new MonomorphicConstraint( - constraint, - ((SimpleContainerType) a).getElementType(), - ((SimpleContainerType) b).getElementType())); - } else if (a instanceof MapType && b instanceof MapType) { - // for two map types to be the same, - // (1) the key types must be the same, and - constraints.addFirst(new MonomorphicConstraint( - constraint, - ((MapType) a).getKeyType(), - ((MapType) b).getKeyType())); - // (2) the value types must be the same - constraints.addFirst(new MonomorphicConstraint( - constraint, - ((MapType) a).getValueType(), - ((MapType) b).getValueType())); - } else if (a instanceof TupleType && b instanceof TupleType) { - // for two tuple types to be the same, - TupleType ta = (TupleType) a; - TupleType tb = (TupleType) b; - // (1) they must have the same number of element types - if (ta.getElementTypes().size() != tb.getElementTypes().size()) { - Optional optionalIssue = backtrack(new UnsatisfiableConstraintIssue(a, b)); - if (optionalIssue.isPresent()) { - return optionalIssue; - } - continue; - } - // (2) each pair of corresponding element types must be the same - for (int i = 0; i < ta.getElementTypes().size(); i++) { - constraints.addFirst(new MonomorphicConstraint( - constraint, - ta.getElementTypes().get(i), - tb.getElementTypes().get(i))); - } - } else if (a instanceof FunctionType && b instanceof FunctionType) { - // in order for two function types to be the same, - FunctionType fa = (FunctionType) a; - FunctionType fb = (FunctionType) b; - // (1) their parameter lists must be of the same size, and - if (fa.getParamTypes().size() != fb.getParamTypes().size()) { - Optional optionalIssue = backtrack(new UnsatisfiableConstraintIssue(a, b)); - if (optionalIssue.isPresent()) { - return optionalIssue; - } - continue; - } - // (2) each pair of corresponding parameter types must be the same, and - for (int i = 0; i < fa.getParamTypes().size(); i++) { - constraints.addFirst(new MonomorphicConstraint( - constraint, - fa.getParamTypes().get(i), - fb.getParamTypes().get(i))); - } - // (3) the return types must be the same - constraints.addFirst(new MonomorphicConstraint( - constraint, - fa.getReturnType(), - fb.getReturnType())); - } else if (a instanceof ProcedureType && b instanceof ProcedureType) { - // in order for two procedure types to be the same, - ProcedureType pa = (ProcedureType) a; - ProcedureType pb = (ProcedureType) b; - // (1) their parameter lists must be of the same size, and - if (pa.getParamTypes().size() != pb.getParamTypes().size()) { - Optional optionalIssue = backtrack(new UnsatisfiableConstraintIssue(a, b)); - if (optionalIssue.isPresent()) { - return optionalIssue; - } - continue; - } - // (2) each pair of corresponding parameter types must be the same - for (int i = 0; i < pa.getParamTypes().size(); i++) { - constraints.addFirst(new MonomorphicConstraint( - constraint, - pa.getParamTypes().get(i), - pb.getParamTypes().get(i))); - } - } else { - Optional optionalIssue = backtrack(new UnsatisfiableConstraintIssue(a, b)); - if (optionalIssue.isPresent()) { - return optionalIssue; - } - } - // we backtracked successfully, continue solving - } - return Optional.empty(); - } - - public void unify(IssueContext ctx) { - Optional issue = unify(); - if (issue.isPresent()) { - ctx.error(issue.get()); - return; - } - simplify(); - } -} diff --git a/src/pgo/model/type/TypeSubstitution.java b/src/pgo/model/type/TypeSubstitution.java deleted file mode 100644 index 20f1f47ac..000000000 --- a/src/pgo/model/type/TypeSubstitution.java +++ /dev/null @@ -1,27 +0,0 @@ -package pgo.model.type; - -import pgo.util.UnionFind; - -import java.util.Map; - -public class TypeSubstitution { - private final UnionFind variableGroups; - private final Map mapping; - - public TypeSubstitution(UnionFind variableGroups, Map mapping) { - this.variableGroups = variableGroups; - this.mapping = mapping; - } - - public boolean containsKey(TypeVariable v) { - return mapping.containsKey(variableGroups.find(v)); - } - - public Type get(TypeVariable v) { - return mapping.get(variableGroups.find(v)); - } - - public Type getOrDefault(TypeVariable v, Type t) { - return mapping.getOrDefault(variableGroups.find(v), t); - } -} diff --git a/src/pgo/model/type/TypeVariable.java b/src/pgo/model/type/TypeVariable.java deleted file mode 100644 index a4eb89b66..000000000 --- a/src/pgo/model/type/TypeVariable.java +++ /dev/null @@ -1,41 +0,0 @@ -package pgo.model.type; - -import pgo.util.Origin; - -import java.util.List; - -/** - * Represents a type variable. - */ -public class TypeVariable extends Type { - private final String name; - - // The constructors must be kept package protected so that - // PGoTypeGenerator can safely do its job - TypeVariable(String name, List origins) { - super(origins); - this.name = name; - } - - public String getName() { - return name; - } - - @Override - public int hashCode() { - return name.hashCode() * 17 + 2; - } - - @Override - public boolean equals(Object obj) { - // since PGoTypeVariable can only be created by - // PGoTypeGenerator, it is safe to compare references - // here - return this == obj; - } - - @Override - public T accept(TypeVisitor v) throws E { - return v.visit(this); - } -} diff --git a/src/pgo/model/type/TypeVariableAbstractRecordSubstitutionVisitor.java b/src/pgo/model/type/TypeVariableAbstractRecordSubstitutionVisitor.java deleted file mode 100644 index 8931a30f9..000000000 --- a/src/pgo/model/type/TypeVariableAbstractRecordSubstitutionVisitor.java +++ /dev/null @@ -1,25 +0,0 @@ -package pgo.model.type; - -import pgo.util.UnionFind; - -import java.util.Map; - -class TypeVariableAbstractRecordSubstitutionVisitor extends TypeVariableSubstitutionVisitor { - private final UnionFind abstractRecordGroups; - private final Map abstractRecordsToEntries; - - TypeVariableAbstractRecordSubstitutionVisitor( - TypeSubstitution substitution, UnionFind abstractRecordGroups, - Map abstractRecordsToEntries) { - super(substitution); - this.abstractRecordGroups = abstractRecordGroups; - this.abstractRecordsToEntries = abstractRecordsToEntries; - } - - @Override - public Type visit(AbstractRecordType abstractRecordType) throws RuntimeException { - return abstractRecordsToEntries.get(abstractRecordGroups.find(abstractRecordType)) - .toConcreteRecord() - .accept(this); - } -} diff --git a/src/pgo/model/type/TypeVariableCollectionVisitor.java b/src/pgo/model/type/TypeVariableCollectionVisitor.java deleted file mode 100644 index 41e683678..000000000 --- a/src/pgo/model/type/TypeVariableCollectionVisitor.java +++ /dev/null @@ -1,132 +0,0 @@ -package pgo.model.type; - -import java.util.Set; - -public class TypeVariableCollectionVisitor extends TypeVisitor { - private final Set output; - - public TypeVariableCollectionVisitor(Set output) { - this.output = output; - } - - @Override - public Void visit(AbstractRecordType abstractRecordType) throws RuntimeException { - // nothing to do - return null; - } - - @Override - public Void visit(ArchetypeResourceType archetypeResourceType) throws RuntimeException { - archetypeResourceType.getReadType().accept(this); - archetypeResourceType.getWriteType().accept(this); - return null; - } - - @Override - public Void visit(ArchetypeResourceCollectionType archetypeResourceCollectionType) throws RuntimeException { - archetypeResourceCollectionType.getKeyType().accept(this); - archetypeResourceCollectionType.getReadType().accept(this); - archetypeResourceCollectionType.getWriteType().accept(this); - return null; - } - - @Override - public Void visit(TypeVariable typeVariable) throws RuntimeException { - output.add(typeVariable); - return null; - } - - @Override - public Void visit(TupleType tupleType) throws RuntimeException { - for (Type elementType : tupleType.getElementTypes()) { - elementType.accept(this); - } - return null; - } - - @Override - public Void visit(StringType stringType) throws RuntimeException { - // nothing to do - return null; - } - - @Override - public Void visit(SetType setType) throws RuntimeException { - setType.getElementType().accept(this); - return null; - } - - @Override - public Void visit(NonEnumerableSetType nonEnumerableSetType) throws RuntimeException { - nonEnumerableSetType.getElementType().accept(this); - return null; - } - - @Override - public Void visit(BoolType boolType) throws RuntimeException { - // nothing to do - return null; - } - - @Override - public Void visit(RealType realType) throws RuntimeException { - // nothing to do - return null; - } - - @Override - public Void visit(FunctionType functionType) throws RuntimeException { - for (Type paramType : functionType.getParamTypes()) { - paramType.accept(this); - } - functionType.getReturnType().accept(this); - return null; - } - - @Override - public Void visit(ChanType chanType) throws RuntimeException { - chanType.getElementType().accept(this); - return null; - } - - @Override - public Void visit(IntType intType) throws RuntimeException { - // nothing to do - return null; - } - - @Override - public Void visit(InterfaceType interfaceType) throws RuntimeException { - // nothing to do - return null; - } - - @Override - public Void visit(MapType mapType) throws RuntimeException { - mapType.getKeyType().accept(this); - mapType.getValueType().accept(this); - return null; - } - - @Override - public Void visit(SliceType sliceType) throws RuntimeException { - sliceType.getElementType().accept(this); - return null; - } - - @Override - public Void visit(ProcedureType procedureType) throws RuntimeException { - for (Type paramType : procedureType.getParamTypes()) { - paramType.accept(this); - } - return null; - } - - @Override - public Void visit(RecordType recordType) throws RuntimeException { - for (RecordType.Field field : recordType.getFields()) { - field.getType().accept(this); - } - return null; - } -} diff --git a/src/pgo/model/type/TypeVariableSubstitutionVisitor.java b/src/pgo/model/type/TypeVariableSubstitutionVisitor.java deleted file mode 100644 index d92ae0363..000000000 --- a/src/pgo/model/type/TypeVariableSubstitutionVisitor.java +++ /dev/null @@ -1,130 +0,0 @@ -package pgo.model.type; - -import java.util.stream.Collectors; - -public class TypeVariableSubstitutionVisitor extends TypeVisitor { - protected final TypeSubstitution substitution; - - public TypeVariableSubstitutionVisitor(TypeSubstitution substitution) { - this.substitution = substitution; - } - - @Override - public Type visit(AbstractRecordType abstractRecordType) throws RuntimeException { - return abstractRecordType; - } - - @Override - public Type visit(ArchetypeResourceType archetypeResourceType) throws RuntimeException { - archetypeResourceType.setReadType(archetypeResourceType.getReadType().accept(this)); - archetypeResourceType.setWriteType(archetypeResourceType.getWriteType().accept(this)); - return archetypeResourceType; - } - - @Override - public Type visit(ArchetypeResourceCollectionType archetypeResourceCollectionType) throws RuntimeException { - archetypeResourceCollectionType.setKeyType(archetypeResourceCollectionType.getKeyType().accept(this)); - archetypeResourceCollectionType.setReadType(archetypeResourceCollectionType.getReadType().accept(this)); - archetypeResourceCollectionType.setWriteType(archetypeResourceCollectionType.getWriteType().accept(this)); - return archetypeResourceCollectionType; - } - - @Override - public Type visit(TypeVariable typeVariable) throws RuntimeException { - Type old = typeVariable; - Type sub = substitution.getOrDefault(typeVariable, typeVariable); - while (!sub.equals(old)) { - old = sub; - sub = sub.accept(this); - } - return sub; - } - - @Override - public Type visit(TupleType tupleType) throws RuntimeException { - tupleType.setElementTypes( - tupleType.getElementTypes().stream().map(t -> t.accept(this)).collect(Collectors.toList())); - return tupleType; - } - - @Override - public Type visit(StringType stringType) throws RuntimeException { - return stringType; - } - - @Override - public Type visit(SetType setType) throws RuntimeException { - setType.setElementType(setType.getElementType().accept(this)); - return setType; - } - - @Override - public Type visit(NonEnumerableSetType nonEnumerableSetType) throws RuntimeException { - nonEnumerableSetType.setElementType(nonEnumerableSetType.getElementType().accept(this)); - return nonEnumerableSetType; - } - - @Override - public Type visit(BoolType boolType) throws RuntimeException { - return boolType; - } - - @Override - public Type visit(RealType realType) throws RuntimeException { - return realType; - } - - @Override - public Type visit(FunctionType functionType) throws RuntimeException { - functionType.setParamTypes( - functionType.getParamTypes().stream().map(t -> t.accept(this)).collect(Collectors.toList())); - functionType.setReturnType(functionType.getReturnType().accept(this)); - return functionType; - } - - @Override - public Type visit(ChanType chanType) throws RuntimeException { - chanType.setElementType(chanType.getElementType().accept(this)); - return chanType; - } - - @Override - public Type visit(IntType intType) throws RuntimeException { - return intType; - } - - @Override - public Type visit(InterfaceType interfaceType) throws RuntimeException { - return interfaceType; - } - - @Override - public Type visit(MapType mapType) throws RuntimeException { - mapType.setKeyType(mapType.getKeyType().accept(this)); - mapType.setValueType(mapType.getValueType().accept(this)); - return mapType; - } - - @Override - public Type visit(SliceType sliceType) throws RuntimeException { - sliceType.setElementType(sliceType.getElementType().accept(this)); - return sliceType; - } - - @Override - public Type visit(ProcedureType procedureType) throws RuntimeException { - procedureType.setParamTypes( - procedureType.getParamTypes().stream().map(t -> t.accept(this)).collect(Collectors.toList())); - return procedureType; - } - - @Override - public Type visit(RecordType recordType) throws RuntimeException { - recordType.setFields( - recordType.getFields() - .stream() - .map(f -> new RecordType.Field(f.getName(), f.getType().accept(this))) - .collect(Collectors.toList())); - return recordType; - } -} diff --git a/src/pgo/model/type/TypeVisitor.java b/src/pgo/model/type/TypeVisitor.java deleted file mode 100644 index f8601d92d..000000000 --- a/src/pgo/model/type/TypeVisitor.java +++ /dev/null @@ -1,22 +0,0 @@ -package pgo.model.type; - -public abstract class TypeVisitor { - public abstract T visit(AbstractRecordType abstractRecordType) throws E; - public abstract T visit(ArchetypeResourceType archetypeResourceType) throws E; - public abstract T visit(ArchetypeResourceCollectionType archetypeResourceCollectionType) throws E; - public abstract T visit(BoolType boolType) throws E; - public abstract T visit(ChanType chanType) throws E; - public abstract T visit(FunctionType functionType) throws E; - public abstract T visit(InterfaceType interfaceType) throws E; - public abstract T visit(IntType intType) throws E; - public abstract T visit(MapType mapType) throws E; - public abstract T visit(NonEnumerableSetType nonEnumerableSetType) throws E; - public abstract T visit(ProcedureType procedureType) throws E; - public abstract T visit(RealType realType) throws E; - public abstract T visit(RecordType recordType) throws E; - public abstract T visit(SetType setType) throws E; - public abstract T visit(SliceType sliceType) throws E; - public abstract T visit(StringType stringType) throws E; - public abstract T visit(TupleType tupleType) throws E; - public abstract T visit(TypeVariable typeVariable) throws E; -} diff --git a/src/pgo/model/type/UnificationException.java b/src/pgo/model/type/UnificationException.java deleted file mode 100644 index 5aac967af..000000000 --- a/src/pgo/model/type/UnificationException.java +++ /dev/null @@ -1,15 +0,0 @@ -package pgo.model.type; - -import pgo.errors.Issue; - -class UnificationException extends Exception { - private final Issue issue; - - UnificationException(Issue issue) { - this.issue = issue; - } - - Issue getIssue() { - return issue; - } -} diff --git a/src/pgo/model/type/UnsatisfiableConstraintIssue.java b/src/pgo/model/type/UnsatisfiableConstraintIssue.java deleted file mode 100644 index f4cc4acb7..000000000 --- a/src/pgo/model/type/UnsatisfiableConstraintIssue.java +++ /dev/null @@ -1,27 +0,0 @@ -package pgo.model.type; - -import pgo.errors.Issue; -import pgo.errors.IssueVisitor; - -public class UnsatisfiableConstraintIssue extends Issue { - private final Type lhs; - private final Type rhs; - - public UnsatisfiableConstraintIssue(Type lhs, Type rhs) { - this.lhs = lhs; - this.rhs = rhs; - } - - public Type getLhs() { - return lhs; - } - - public Type getRhs() { - return rhs; - } - - @Override - public T accept(IssueVisitor v) throws E { - return v.visit(this); - } -} diff --git a/src/pgo/model/type/constraint/BasicConstraint.java b/src/pgo/model/type/constraint/BasicConstraint.java deleted file mode 100644 index b5144fd71..000000000 --- a/src/pgo/model/type/constraint/BasicConstraint.java +++ /dev/null @@ -1,8 +0,0 @@ -package pgo.model.type.constraint; - -public abstract class BasicConstraint { - public abstract BasicConstraint copy(); - - @Override - public abstract String toString(); -} diff --git a/src/pgo/model/type/constraint/Constraint.java b/src/pgo/model/type/constraint/Constraint.java deleted file mode 100644 index e3fb038d7..000000000 --- a/src/pgo/model/type/constraint/Constraint.java +++ /dev/null @@ -1,11 +0,0 @@ -package pgo.model.type.constraint; - -import pgo.util.Derived; - -/** - * Represents a type constraint, along with the line from which this constraint - * originates. - */ -public abstract class Constraint extends Derived { - public abstract Constraint copy(); -} diff --git a/src/pgo/model/type/constraint/EqualityConstraint.java b/src/pgo/model/type/constraint/EqualityConstraint.java deleted file mode 100644 index 16445ec0f..000000000 --- a/src/pgo/model/type/constraint/EqualityConstraint.java +++ /dev/null @@ -1,36 +0,0 @@ -package pgo.model.type.constraint; - -import pgo.model.type.TypeCopyVisitor; -import pgo.model.type.Type; - -/** - * A plain old Java object representing an equality constraint. - */ -public class EqualityConstraint extends BasicConstraint { - private final Type lhs; - private final Type rhs; - - public EqualityConstraint(Type lhs, Type rhs) { - this.lhs = lhs; - this.rhs = rhs; - } - - public Type getLhs() { - return lhs; - } - - public Type getRhs() { - return rhs; - } - - @Override - public EqualityConstraint copy() { - TypeCopyVisitor visitor = new TypeCopyVisitor(); - return new EqualityConstraint(lhs.accept(visitor), rhs.accept(visitor)); - } - - @Override - public String toString() { - return lhs.toString() + " = " + rhs.toString(); - } -} diff --git a/src/pgo/model/type/constraint/HasFieldConstraint.java b/src/pgo/model/type/constraint/HasFieldConstraint.java deleted file mode 100644 index 6e58f8777..000000000 --- a/src/pgo/model/type/constraint/HasFieldConstraint.java +++ /dev/null @@ -1,47 +0,0 @@ -package pgo.model.type.constraint; - -import pgo.model.type.AbstractRecordType; -import pgo.model.type.Type; -import pgo.model.type.RecordType; - -public class HasFieldConstraint extends BasicConstraint { - private final Type expressionType; - private final String fieldName; - private final Type fieldType; - - public HasFieldConstraint(RecordType concreteRecord, String fieldName, Type fieldType) { - this((Type) concreteRecord, fieldName, fieldType); - } - - public HasFieldConstraint(AbstractRecordType abstractRecord, String fieldName, Type fieldType) { - this((Type) abstractRecord, fieldName, fieldType); - } - - private HasFieldConstraint(Type expressionType, String fieldName, Type fieldType) { - this.expressionType = expressionType; - this.fieldName = fieldName; - this.fieldType = fieldType; - } - - public Type getExpressionType() { - return expressionType; - } - - public String getFieldName() { - return fieldName; - } - - public Type getFieldType() { - return fieldType; - } - - @Override - public HasFieldConstraint copy() { - return new HasFieldConstraint(expressionType, fieldName, fieldType); - } - - @Override - public String toString() { - return expressionType.toString() + " has field [" + fieldName + " : " + fieldType.toString() + "]"; - } -} diff --git a/src/pgo/model/type/constraint/MonomorphicConstraint.java b/src/pgo/model/type/constraint/MonomorphicConstraint.java deleted file mode 100644 index 5d12effc2..000000000 --- a/src/pgo/model/type/constraint/MonomorphicConstraint.java +++ /dev/null @@ -1,52 +0,0 @@ -package pgo.model.type.constraint; - -import pgo.model.type.AbstractRecordType; -import pgo.model.type.Type; -import pgo.model.type.RecordType; -import pgo.util.DerivedVisitor; -import pgo.util.Origin; - -import java.util.Collections; -import java.util.List; - -public class MonomorphicConstraint extends Constraint { - private final BasicConstraint basicConstraint; - - public MonomorphicConstraint(Origin origin, Type lhs, Type rhs) { - this(Collections.singletonList(origin), new EqualityConstraint(lhs, rhs)); - } - - public MonomorphicConstraint(Origin origin, AbstractRecordType abstractRecord, String fieldName, - Type fieldType) { - this(Collections.singletonList(origin), new HasFieldConstraint(abstractRecord, fieldName, fieldType)); - } - - public MonomorphicConstraint(Origin origin, RecordType concreteRecord, String fieldName, - Type fieldType) { - this(Collections.singletonList(origin), new HasFieldConstraint(concreteRecord, fieldName, fieldType)); - } - - public MonomorphicConstraint(List origins, BasicConstraint basicConstraint) { - origins.forEach(this::addOrigin); - this.basicConstraint = basicConstraint; - } - - public BasicConstraint getBasicConstraint() { - return basicConstraint; - } - - @Override - public T accept(DerivedVisitor v) throws E { - return v.visit(this); - } - - @Override - public MonomorphicConstraint copy() { - return new MonomorphicConstraint(getOrigins(), basicConstraint.copy()); - } - - @Override - public String toString() { - return basicConstraint.toString(); - } -} diff --git a/src/pgo/model/type/constraint/PolymorphicConstraint.java b/src/pgo/model/type/constraint/PolymorphicConstraint.java deleted file mode 100644 index 889ae4c35..000000000 --- a/src/pgo/model/type/constraint/PolymorphicConstraint.java +++ /dev/null @@ -1,85 +0,0 @@ -package pgo.model.type.constraint; - -import pgo.util.DerivedVisitor; -import pgo.util.Origin; - -import java.util.*; -import java.util.stream.Collectors; - -public class PolymorphicConstraint extends Constraint - implements Iterator>, Iterable> { - private final List> constraints; - private int currentIndex; - - public PolymorphicConstraint(Origin origin, List> constraints) { - this(Collections.singletonList(origin), constraints); - } - - PolymorphicConstraint(List origins, List> constraints) { - origins.forEach(this::addOrigin); - this.constraints = constraints; - this.currentIndex = 0; - } - - @Override - public T accept(DerivedVisitor v) throws E { - return v.visit(this); - } - - @Override - public boolean hasNext() { - return currentIndex < constraints.size(); - } - - @Override - public List next() { - int index = currentIndex; - currentIndex += 1; - try { - return constraints.get(index); - } catch (IndexOutOfBoundsException e) { - throw new NoSuchElementException(); - } - } - - @Override - public PolymorphicConstraint copy() { - List> cs = new ArrayList<>(); - for (List equalityConstraints : constraints) { - cs.add(equalityConstraints.stream().map(BasicConstraint::copy).collect(Collectors.toList())); - } - PolymorphicConstraint copy = new PolymorphicConstraint(getOrigins(), cs); - copy.currentIndex = currentIndex; - return copy; - } - - @Override - public Iterator> iterator() { - return constraints.listIterator(); - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - boolean first = true; - builder.append("("); - for (List constraintList : constraints) { - if (first) { - first = false; - } else { - builder.append(") OR ("); - } - boolean innerFirst = true; - for (BasicConstraint constraint : constraintList) { - if (innerFirst) { - innerFirst = false; - } else { - builder.append(" AND "); - } - builder.append(constraint.toString()); - } - } - builder.append(")"); - return builder.toString(); - } -} diff --git a/src/pgo/parser/LineColumnAwareReader.scala b/src/pgo/parser/LineColumnAwareCharReader.scala similarity index 71% rename from src/pgo/parser/LineColumnAwareReader.scala rename to src/pgo/parser/LineColumnAwareCharReader.scala index 4db79d0aa..fa8117b86 100644 --- a/src/pgo/parser/LineColumnAwareReader.scala +++ b/src/pgo/parser/LineColumnAwareCharReader.scala @@ -1,6 +1,6 @@ package pgo.parser -import pgo.util.SourceLocation +import pgo.model.SourceLocation import scala.util.parsing.input.{Position, Reader} @@ -14,12 +14,10 @@ import scala.util.parsing.input.{Position, Reader} * from which you want to start counting. * @param column the current column. See above. */ -final class LineColumnAwareCharReader(val underlying : Reader[Char], val path: java.nio.file.Path, +final class LineColumnAwareCharReader(val underlying : Reader[Char], val underlyingText: SourceLocation.UnderlyingText, val line : Int = 0, val column : Int = 0) extends Reader[Char] { override def first: Char = underlying.first - def sourceLocation: SourceLocation = new SourceLocation(path, offset, offset, line, line, column, column) - override def toString: String = underlying.toString override lazy val rest: LineColumnAwareCharReader = @@ -27,12 +25,16 @@ final class LineColumnAwareCharReader(val underlying : Reader[Char], val path: j this } else { if (first == '\n') { - new LineColumnAwareCharReader(underlying.rest, path, line + 1, 0) + new LineColumnAwareCharReader(underlying.rest, underlyingText, line + 1, 0) } else { - new LineColumnAwareCharReader(underlying.rest, path, line, column + 1) + new LineColumnAwareCharReader(underlying.rest, underlyingText, line, column + 1) } } + def currentSourceLocation: SourceLocation = + SourceLocation(underlyingText, startOffset = offset, endOffset = offset, + startLine = line, endLine = line, startColumn = column, endColumn = column) + override def pos: Position = underlying.pos override def atEnd: Boolean = underlying.atEnd override def source: CharSequence = underlying.source diff --git a/src/pgo/parser/MPCalParser.scala b/src/pgo/parser/MPCalParser.scala new file mode 100644 index 000000000..915ec14c9 --- /dev/null +++ b/src/pgo/parser/MPCalParser.scala @@ -0,0 +1,282 @@ +package pgo.parser + +import scala.collection.mutable +import pgo.model.{Definition, SourceLocatable, SourceLocation, SourceLocationWithUnderlying, Visitable} +import pgo.model.mpcal._ +import pgo.model.pcal._ +import pgo.model.tla._ + +import pgo.util.Description +import Description._ + +trait MPCalParser extends PCalParser { + import pgo.parser.MPCalParserContext._ + import pgo.parser.PCalParserContext._ + + private def cast[T](p: MPCalParser#Parser[T]): Parser[T] = p.asInstanceOf[Parser[T]] + + def mpcalRefSuffix: Parser[Int] = + "^" ^^^ -1 | repsep("[" ~> ws ~> "_" ~> ws ~> "]", ws).map(_.length) + + def mpcalParam(implicit ctx: MPCalParserContext): Parser[MPCalParam] = + withSourceLocation { + "ref" ~> ws ~> tlaIdentifierExpr ~ (ws ~> mpcalRefSuffix) ^^ { case id ~ mappingCount => MPCalRefParam(id, mappingCount)} | + (tlaIdentifierExpr <~ ws) ~ mpcalRefSuffix ^^ { case id ~ mappingCount => MPCalValParam(id, mappingCount) } + } + + def mpcalArchetype(implicit ctx: MPCalParserContext): Parser[MPCalArchetype] = + withSourceLocation { + val origCtx = ctx + ("archetype" ~> ws ~> tlaIdentifierExpr ~ (ws ~> "(" ~> ws ~> repsep(mpcalParam, ws ~> "," ~> ws) <~ ws <~ ")")).flatMap { + case name ~ params => + val self = TLAIdentifier("self").setSourceLocation(name.sourceLocation).toDefiningIdentifier + implicit val ctx: MPCalParserContext = params.foldLeft(origCtx.withDefinition(self))(_.withDefinition(_)) + val origCtx2 = ctx + opt(ws ~> pcalVarDecls).flatMap { declsOpt => + implicit val ctx: MPCalParserContext = declsOpt.getOrElse(Nil).foldLeft(origCtx2)(_.withDefinition(_)) + (ws ~> pcalCSyntax.pcalCompoundStmt) ^^ ((name, self, params, declsOpt.getOrElse(Nil), _)) + } + } ^^ { + case (name, self, params, decls, body) => MPCalArchetype(name, self, params, decls, body) + } + } + + val mpcalMappingPosition: Parser[Int] = + regex("""[1-9]\d*""".r).map(_.toInt) + def mpcalMapping(positionMappings: Map[String,Int], maxPosition: Int)(implicit ctx: MPCalParserContext): Parser[MPCalMapping] = + withSourceLocation { + "mapping" ~> ws ~> { + withSourceLocation { + tlaIdentifierExpr ~ (ws ~> mpcalRefSuffix) ^^ { + case id ~ mappingCount => + positionMappings.get(id.id) match { + case None => throw MappingLookupError(id) + case Some(position) => + MPCalMappingTarget(position, mappingCount) + } + } + } | + withSourceLocation { + querySourceLocation("@" ~> mpcalMappingPosition) ~ (ws ~> mpcalRefSuffix) ^^ { + case (positionLoc, position) ~ mappingCount => + if(position > maxPosition) { + throw MappingIndexOutOfBounds(positionLoc, position, maxPosition) + } + MPCalMappingTarget(position, mappingCount) + } + } + } ~ (ws ~> "via" ~> ws ~> tlaIdentifierExpr) ^^ { + case target ~ mappingMacroIdentifier => + ctx.mappingMacros.get(mappingMacroIdentifier) match { + case None => throw MappingMacroLookupError(mappingMacroIdentifier) + case Some(mappingMacro) => + val result = MPCalMapping(target, mappingMacroIdentifier) + result.setRefersTo(mappingMacro) + result + } + } + } + + def mpcalInstance(implicit ctx: MPCalParserContext): Parser[MPCalInstance] = + withSourceLocation { + ((("fair" ~> ws ~> "+" ^^^ PCalFairness.StrongFair) | ("fair" ^^^ PCalFairness.WeakFair) | success(PCalFairness.Unfair)) ~ + (ws ~> "process" ~> ws ~> "(" ~> pcalVarDeclBound <~ ws <~ ")") ~ + (ws ~> "==" ~> ws ~> "instance" ~> ws ~> tlaIdentifierExpr) ~ + (ws ~> "(" ~> ws ~> repsep(mpcalParam ^^ (Left(_)) | tlaExpression ^^ (Right(_)), ws ~> "," ~> ws) <~ ws <~ ")")).flatMap { + case fairness ~ nameDecl ~ target ~ arguments => + val namePosMapping = arguments.view.zipWithIndex.collect { + case (Left(param), idx) => param.name.id -> idx + }.toMap + ws ~> repsep(mpcalMapping(namePosMapping, arguments.size), ws) <~ ws <~ ";" ^^ { mappings => + ctx.archetypes.get(target) match { + case None => throw ArchetypeLookupError(target) + case Some(archetype) => + val result = MPCalInstance(nameDecl, fairness, target, arguments, mappings) + result.setRefersTo(archetype) + result + } + } + } + } + + def mpcalYield(implicit ctx: PCalParserContext): Parser[PCalExtensionStatement] = + withSourceLocation { + withSourceLocation { + "yield" ~> ws ~>! tlaExpression ^^ MPCalYield + } ^^ PCalExtensionStatement + } + + object mpcalMappingMacroBody extends MPCalParser { + def mpcalSpecialVariable(implicit ctx: TLAParserContext): Parser[TLAExpression] = + withSourceLocation { + withSourceLocation { + "$variable" ^^ (_ => MPCalDollarVariable()) | + "$value" ^^ (_ => MPCalDollarValue()) + } ^^ TLAExtensionExpression + } + + override def tlaExpressionNoOperators(implicit ctx: TLAParserContext): Parser[TLAExpression] = + mpcalSpecialVariable | super.tlaExpressionNoOperators + + override def pcalLhsId(implicit ctx: PCalParserContext): Parser[PCalAssignmentLhs] = + (mpcalSpecialVariable ^^ PCalAssignmentLhsExtension) | super.pcalLhsId + + override val pcalCSyntax: PCalCSyntax = new PCalCSyntax { + override def pcalUnlabeledStmt(implicit ctx: PCalParserContext): Parser[PCalStatement] = + mpcalYield | super.pcalUnlabeledStmt + } + } + + def mpcalMappingMacro(implicit ctx: MPCalParserContext): Parser[MPCalMappingMacro] = + withSourceLocation { + val origCtx = ctx + ("mapping" ~> ws ~> "macro" ~> ws ~> tlaIdentifierExpr).flatMap { name => + implicit val ctx: MPCalParserContext = origCtx.withLateBinding + (ws ~> "{" ~> ws ~> "read" ~> ws ~> cast(mpcalMappingMacroBody.pcalCSyntax.pcalCompoundStmt)) ~ + (ws ~> "write" ~> ws ~> cast(mpcalMappingMacroBody.pcalCSyntax.pcalCompoundStmt) <~ ws <~ "}") ^^ + ((name, _, ctx.ctx.ctx.lateBindingStack.head)) + } ^^ { + case (name, readBlock ~ writeBlock, lateBindings) => + val freeVars = lateBindings.keysIterator.map(_.toDefiningIdentifier).toList.sortBy(_.id.id) + freeVars.foreach { v => lateBindings(v.id).foreach(_(v)) } + MPCalMappingMacro(name, readBlock, writeBlock, freeVars) + } + } + + def mpcalProcedure(implicit ctx: MPCalParserContext): Parser[MPCalProcedure] = + withSourceLocation { + val origCtx = ctx + ("procedure" ~> ws ~> tlaIdentifierExpr).flatMap { id => + ((ws ~> "(" ~> ws ~> repsep(mpcalParam, ws ~> "," ~> ws)) ~ + (ws ~> ")" ~> opt(ws ~> ("variables" | "variable") ~> ws ~> rep1sep(pcalPVarDecl, ws ~> (";"|",") ~> ws) <~ opt(ws ~> (";" | ","))).map(_.getOrElse(Nil)))) + .flatMap { + case args ~ locals => + implicit val ctx: MPCalParserContext = locals.foldLeft(args.foldLeft(origCtx)(_.withDefinition(_)))(_.withDefinition(_)) + (ws ~> cast(mpcalWithRefs.pcalCSyntax.pcalCompoundStmt) <~ opt(ws ~> ";")) ^^ ((id, args, locals, _)) + } + } ^^ { + case (id, args, locals, body) => + MPCalProcedure(id, args, locals, body) + } + } + + def mpcalWithRefs(implicit ctx: MPCalParserContext): MPCalParser = + new MPCalParser { + override def pcalCallParam(implicit ctx: PCalParserContext): Parser[TLAExpression] = { + withSourceLocation { + withSourceLocation { + ("ref" ~> ws ~> tlaIdentifierExpr ~ (ws ~> mpcalRefSuffix) ^^ { + case id ~ mappingCount => (id, MPCalRefExpr(id, mappingCount)) + } | + tlaIdentifierExpr ~ (ws ~> mpcalRefSuffix) ^^ { + case id ~ mappingCount => (id, MPCalValExpr(id, mappingCount)) + }) + .map { + case (id, ref) => + ctx.ctx.lookupDefinition(List(Definition.ScopeIdentifierName(id))) match { + case None => + if(ctx.ctx.lateBindingStack.nonEmpty) { + ctx.ctx.lateBindingStack.head.getOrElseUpdate(id, mutable.ArrayBuffer()) += { + case param: MPCalParam => ref.setRefersTo(param) + case _ => throw KindMismatchError(ref.sourceLocation, d"expected procedure or archetype param reference") + } + } else { + throw DefinitionLookupError(Nil, Definition.ScopeIdentifierName(id)) + } + case Some(defn) => + defn match { + case param: MPCalParam => ref.setRefersTo(param) + case _ => throw KindMismatchError(ref.sourceLocation, d"expected procedure or archetype param reference") + } + } + ref + } + } + }.map(TLAExtensionExpression) | super.pcalCallParam + } + } + + def mpcalBlock(implicit ctx: MPCalParserContext): Parser[MPCalBlock] = + withSourceLocation { + val origCtx = ctx + (("--mpcal" ~> ws ~> tlaIdentifierExpr <~ ws <~ "{") ~ opt(ws ~> pcalDefinitions).map(_.getOrElse(Nil))).flatMap { + case name ~ defns => + implicit val ctx: MPCalParserContext = defns.foldLeft(origCtx)((ctx, unit) => unit.definitions.foldLeft(ctx)(_.withDefinition(_))) + val origCtx2 = ctx + ((ws ~> repsep(cast(mpcalWithRefs.pcalCSyntax.pcalMacro), ws)) ~ + (ws ~> repsep(cast(mpcalWithRefs.mpcalProcedure), ws)) ~ + (ws ~> repsep(cast(mpcalWithRefs.mpcalMappingMacro), ws)) ~ + (ws ~> repsep(cast(mpcalWithRefs.mpcalArchetype), ws)) ~ + opt(ws ~> pcalVarDecls).map(_.getOrElse(Nil))).flatMap { + case macros ~ mpcalProcedures ~ mappingMacros ~ archetypes ~ varDecls => + implicit val ctx: MPCalParserContext = { + val tmp1 = archetypes.foldLeft(origCtx2)(_.withArchetype(_)) + val tmp2 = varDecls.foldLeft(tmp1)(_.withDefinition(_)) + mappingMacros.foldLeft(tmp2)(_.withMappingMacro(_)) + } + (ws ~> repsep(mpcalInstance, ws)) ~ + (ws ~> repsep(cast(mpcalWithRefs.pcalCSyntax.pcalProcedure), ws)) ~ { + (ws ~> cast(mpcalWithRefs.pcalCSyntax.pcalCompoundStmt)) ^^ (Left(_)) | + (ws ~> repsep(cast(mpcalWithRefs.pcalCSyntax.pcalProcess), ws)) ^^ (Right(_)) + } <~ ws <~ "}" ^^ ((name, defns, macros, mpcalProcedures, mappingMacros, archetypes, varDecls, _)) + } + } ^^ { + case (name, defns, macros, mpcalProcedures, mappingMacros, archetypes, varDecls, instances ~ pcalProcedures ~ procs) => + val dummyPCalProc = PCalProcedure(TLAIdentifier("dummy"), Nil, Nil, Nil) // a dummy PCal procedure to make auto-rename happy, see below + var result = MPCalBlock(name, defns, macros, mpcalProcedures, mappingMacros, archetypes, varDecls, instances, dummyPCalProc :: pcalProcedures, procs) + val macroMap = macros.view.map(m => m.name -> m).toMap + result.visit() { + case call @PCalMacroCall(target, _) => + macroMap.get(target) match { + case Some(m) => call.setRefersTo(m) + case None => throw MacroLookupError(target) + } + } + val mpcalProcedureMap = mpcalProcedures.view.map(proc => proc.name -> proc).toMap + val pcalProcedureMap = pcalProcedures.view.map((proc: PCalProcedure) => proc.name -> proc).toMap + result.visit() { + case call @PCalCall(target, _) => + pcalProcedureMap.get(target) match { + case Some(procedure) => call.setRefersTo(procedure) + case None if mpcalProcedureMap.contains(target) => + // dummy value, whole AST node is replaced below + call.setRefersTo(dummyPCalProc) + case None => throw ProcedureLookupError(target) + } + } + // rewrite pcal proc calls to mpcal proc calls strictly at the end, to avoid messing up the auto-renaming in rewrite + // like this, even if it's fake, all the parts have a refersTo, and the auto-renaming at least "thinks" it's working correctly + result = result.rewrite() { + case call @PCalCall(target, args) if mpcalProcedureMap.contains(target) => + PCalExtensionStatement(MPCalCall(target, args) + .setSourceLocation(call.sourceLocation) + .setRefersTo(mpcalProcedureMap(target))).setSourceLocation(call.sourceLocation) + } + // now the rewrite is done, drop the dummy PCal proc, which should have no more references + val stableResult = result + stableResult.decorateLike(stableResult.copy(pcalProcedures = result.pcalProcedures.tail).asInstanceOf[stableResult.type]) + } + } +} + +object MPCalParser extends MPCalParser with ParsingUtils { + def hasMPCalBlock(underlying: SourceLocation.UnderlyingText, charSeq: CharSequence): Boolean = + findInComment("mpcal", "--mpcal")(buildReader(charSeq, underlying)) match { + case Success(_, _) => true + case NoSuccess(_, _) => false + } + + def readBlock(underlying: SourceLocation.UnderlyingText, charSeq: CharSequence, tlaModule: TLAModule): MPCalBlock = { + implicit val tlaCtx: TLAParserContext = + tlaModule.moduleDefinitions(captureLocal = true).foldLeft( + BuiltinModules.Intrinsics.members.foldLeft(TLAParserContext())(_.withDefinition(_)) + )(_.withDefinition(_)) + implicit val pcalCtx: PCalParserContext = PCalParserContext() + implicit val ctx: MPCalParserContext = MPCalParserContext() + val result = checkResult(phrase(findInComment("mpcal", mpcalBlock))(buildReader(charSeq, underlying))) + result.visit(Visitable.BottomUpFirstStrategy) { + case loc: SourceLocatable => assert(loc.sourceLocation.isInstanceOf[SourceLocationWithUnderlying], s"internal error: did not have source location: $loc") + } + result + } +} diff --git a/src/pgo/parser/MPCalParserContext.scala b/src/pgo/parser/MPCalParserContext.scala new file mode 100644 index 000000000..7295f1112 --- /dev/null +++ b/src/pgo/parser/MPCalParserContext.scala @@ -0,0 +1,24 @@ +package pgo.parser + +import pgo.model.Definition +import pgo.model.mpcal.{MPCalArchetype, MPCalMappingMacro} +import pgo.model.tla.TLAIdentifier + +final case class MPCalParserContext(mappingMacros: Map[TLAIdentifier,MPCalMappingMacro] = Map.empty, + archetypes: Map[TLAIdentifier,MPCalArchetype] = Map.empty)(implicit val ctx: PCalParserContext) { + def withDefinition(defn: Definition): MPCalParserContext = + copy()(ctx.withDefinition(defn)) + + def withArchetype(archetype: MPCalArchetype): MPCalParserContext = + copy(archetypes = archetypes.updated(archetype.name, archetype)) + + def withMappingMacro(mappingMacro: MPCalMappingMacro): MPCalParserContext = + copy(mappingMacros = mappingMacros.updated(mappingMacro.name, mappingMacro)) + + def withLateBinding: MPCalParserContext = + copy()(ctx.withLateBinding) +} + +object MPCalParserContext { + implicit def getPCalParserContext(implicit ctx: MPCalParserContext): PCalParserContext = ctx.ctx +} diff --git a/src/pgo/parser/ModularPlusCalParser.scala b/src/pgo/parser/ModularPlusCalParser.scala deleted file mode 100644 index a2d8fa971..000000000 --- a/src/pgo/parser/ModularPlusCalParser.scala +++ /dev/null @@ -1,196 +0,0 @@ -package pgo.parser - -import pgo.model.mpcal._ -import pgo.model.pcal._ -import pgo.model.tla._ - -import scala.jdk.CollectionConverters._ - -trait ModularPlusCalParser extends PlusCalParser { - import pgo.parser.PCalParserContext.tlaCtx - - def mpcalVarDecl(implicit ctx: PCalParserContext): Parser[PlusCalVariableDeclaration] = - withSourceLocation { - opt("ref" ~> ws) ~ tlaIdentifierExpr - } ^^ { - case (loc, refOpt ~ id) => - new PlusCalVariableDeclaration(loc, id, refOpt.nonEmpty, false, new PlusCalDefaultInitValue(loc)) - } - - def mpcalParam(implicit ctx: PCalParserContext): Parser[TLAExpression] = - withSourceLocation("ref" ~> ws ~> tlaIdentifierExpr) ^^ { - case (loc, id) => - val result = new TLARef(loc, id.getId) - ctx.ctx.lookupDefinition(List(id)) match { - case None => - throw DefinitionLookupError(loc, Nil, id) - case Some(defn) => result.setRefersTo(defn) - } - result - } | tlaExpression - - def mpcalArchetype(implicit ctx: PCalParserContext): Parser[ModularPlusCalArchetype] = - withSourceLocation { - val origCtx = ctx - ("archetype" ~> ws ~> tlaIdentifierExpr ~ (ws ~> "(" ~> ws ~> repsep(mpcalVarDecl, ws ~> "," ~> ws) <~ ws <~ ")")).flatMap { - case name ~ args => - implicit val ctx = args.foldLeft(origCtx.withSelf(name.getLocation, name))(_.withDefinition(_)) - val origCtx2 = ctx - opt(ws ~> pcalVarDecls).flatMap { declsOpt => - implicit val ctx = declsOpt.getOrElse(Nil).foldLeft(origCtx2)(_.withDefinition(_)) - (ws ~> pcalCSyntax.pcalCompoundStmt) ^^ ((name, args, declsOpt.getOrElse(Nil), _)) - } - } - } ^^ { - case (loc, (name, args, decls, body)) => - new ModularPlusCalArchetype(loc, name, args.asJava, decls.asJava, body.asJava) - } - - val mpcalMappingPosition: Parser[Int] = - regex("""[1-9]\d*""".r).map(_.toInt) - def mpcalMapping(implicit ctx: PCalParserContext): Parser[ModularPlusCalMapping] = - withSourceLocation { - "mapping" ~> ws ~> { - withSourceLocation(tlaIdentifierExpr ~ opt(ws ~> "[_]")) ^^ { - case (loc, id ~ paramOpt) => - val result = new ModularPlusCalMappingVariableName(loc, id, paramOpt.nonEmpty) - ctx.ctx.lookupDefinition(List(id)) match { - case None => throw DefinitionLookupError(loc, Nil, id) - case Some(defn) => result.setRefersTo(defn) - } - result - } | - withSourceLocation("@" ~> mpcalMappingPosition ~ opt(ws ~> "[_]")) ^^ { - case (loc, pos ~ paramOpt) => // note: we leave setRefersTo for DefinitionRegistry - new ModularPlusCalMappingVariablePosition(loc, pos, paramOpt.nonEmpty) - } - } ~ (ws ~> "via" ~> ws ~> tlaIdentifierExpr) - } ^^ { - case (loc, vrble ~ via) => - new ModularPlusCalMapping(loc, vrble, new ModularPlusCalMappingTarget(via.getLocation, via.getId)) - } - - def mpcalInstance(implicit ctx: PCalParserContext): Parser[ModularPlusCalInstance] = - withSourceLocation { - (("fair" ~> ws ~> "+" ^^^ PlusCalFairness.STRONG_FAIR) | ("fair" ^^^ PlusCalFairness.WEAK_FAIR) | success(PlusCalFairness.UNFAIR)) ~ - (ws ~> "process" ~> ws ~> "(" ~> pcalVarDecl <~ ws <~ ")") ~ - (ws ~> "==" ~> ws ~> "instance" ~> ws ~> tlaIdentifierExpr) ~ - (ws ~> "(" ~> ws ~> repsep(mpcalParam, ws ~> "," ~> ws) <~ ws <~ ")") ~ - (ws ~> repsep(mpcalMapping, ws) <~ ws <~ ";") - } ^^ { - case (loc, fairness ~ nameDecl ~ target ~ params ~ mappings) => - ctx.archetypes.get(target.getId) match { - case None => throw DefinitionLookupError(target.getLocation, Nil, target) - case Some(arch) => - mappings.foreach { mapping => - mapping.getVariable match { - case name: ModularPlusCalMappingVariableName => - case position: ModularPlusCalMappingVariablePosition if 0 < position.getPosition && position.getPosition <= arch.getParams.size() => - // bizarre edge case: indexed mappings refer to _the archetype's parameter at the correct position_, not the expression they map over - // in the instance param list - position.setRefersTo(arch.getParams.asScala(position.getPosition - 1)) - case v => - throw DefinitionLookupError(v.getLocation, Nil, new TLAIdentifier(v.getLocation, v.toString)) - } - } - } - new ModularPlusCalInstance(loc, nameDecl, fairness, target, params.asJava, mappings.asJava) - } - - def mpcalYield(implicit ctx: PCalParserContext): Parser[ModularPlusCalYield] = - withSourceLocation { - "yield" ~> ws ~>! tlaExpression - } ^^ { case (loc, expr) => new ModularPlusCalYield(loc, expr) } - - object mpcalMappingMacroBody extends ModularPlusCalParser { - def mpcalSpecialVariable(implicit ctx: TLAParserContext): Parser[TLAExpression] = - withSourceLocation("$variable") ^^ { case (loc, _) => new TLASpecialVariableVariable(loc) } | - withSourceLocation("$value") ^^ { case (loc, _) => new TLASpecialVariableValue(loc) } - - override def tlaExpressionNoOperators(implicit ctx: TLAParserContext): Parser[TLAExpression] = - mpcalSpecialVariable | super.tlaExpressionNoOperators - - override def pcalLhsId(implicit ctx: PCalParserContext): Parser[TLAExpression] = - mpcalSpecialVariable | super.pcalLhsId - - override val pcalCSyntax: PCalCSyntax = new PCalCSyntax { - override def pcalUnlabeledStmt(implicit ctx: PCalParserContext): Parser[PlusCalStatement] = - mpcalYield | super.pcalUnlabeledStmt - } - } - - implicit class mpcalMappingMacroBodyParserToParser[T](p: mpcalMappingMacroBody.Parser[T]) { - def cast: Parser[T] = p.asInstanceOf[Parser[T]] - } - - def mpcalMappingMacro(implicit ctx: PCalParserContext): Parser[ModularPlusCalMappingMacro] = - withSourceLocation { - val origCtx = ctx - ("mapping" ~> ws ~> "macro" ~> ws ~> tlaIdentifierExpr).flatMap { name => - implicit val ctx = origCtx.withSelf(name.getLocation, name) - (ws ~> "{" ~> ws ~> "read" ~> ws ~> mpcalMappingMacroBody.pcalCSyntax.pcalCompoundStmt.cast) ~ - (ws ~> "write" ~> ws ~> mpcalMappingMacroBody.pcalCSyntax.pcalCompoundStmt.cast <~ ws <~ "}") ^^ - ((name, _)) - } - } ^^ { - case (loc, (name, readBlock ~ writeBlock)) => - new ModularPlusCalMappingMacro(loc, name, readBlock.asJava, writeBlock.asJava) - } - - object mpcalWithRefs extends ModularPlusCalParser { - override def pcalCallParam(implicit ctx: PCalParserContext): Parser[TLAExpression] = mpcalParam - - override val pcalCSyntax: PCalCSyntax = new PCalCSyntax { - override def pcalProcedureParam(implicit ctx: PCalParserContext): Parser[PlusCalVariableDeclaration] = - mpcalVarDecl | super.pcalProcedureParam - } - } - - implicit class mpcalWithRefsToParser[T](p: mpcalWithRefs.Parser[T]) { - def cast: Parser[T] = p.asInstanceOf[Parser[T]] - } - - def mpcalBlock(implicit ctx: PCalParserContext): Parser[ModularPlusCalBlock] = - withSourceLocation { - val origCtx = ctx - (("--mpcal" ~> ws ~> tlaIdentifierExpr <~ ws <~ "{") ~ opt(ws ~> pcalCSyntax.pcalDefinitions).map(_.getOrElse(Nil))).flatMap { - case name ~ defns => - implicit val ctx = defns.foldLeft(origCtx)((ctx, unit) => unit.definitions.foldLeft(ctx)(_.withDefinition(_))) - val origCtx2 = ctx - (rep(ws ~> pcalCSyntax.pcalMacro) ~ - rep(ws ~> mpcalWithRefs.pcalCSyntax.pcalProcedure.cast) ~ - rep(ws ~> mpcalWithRefs.mpcalMappingMacro.cast) ~ - rep(ws ~> mpcalWithRefs.mpcalArchetype.cast) ~ - opt(ws ~> pcalVarDecls).map(_.getOrElse(Nil))).flatMap { - case macros ~ procedures ~ mappingMacros ~ archetypes ~ varDecls => - implicit val ctx = { - val tmp = archetypes.foldLeft(origCtx2)(_.withArchetype(_)) - varDecls.foldLeft(tmp)(_.withDefinition(_)) - } - rep(ws ~> mpcalInstance) ~ { - (ws ~> withSourceLocation(mpcalWithRefs.pcalCSyntax.pcalCompoundStmt.cast)) ^^ { case (loc, stmts) => new PlusCalSingleProcess(loc, stmts.asJava) } | - (ws ~> withSourceLocation(repsep(mpcalWithRefs.pcalCSyntax.pcalProcess.cast, ws))) ^^ { case (loc, procs) => new PlusCalMultiProcess(loc, procs.asJava) } - } <~ ws <~ "}" ^^ ((name, defns, macros, procedures, mappingMacros, archetypes, varDecls, _)) - } - } - } ^^ { - case (loc, (name, defns, macros, procedures, mappingMacros, archetypes, varDecls, instances ~ procs)) => - new ModularPlusCalBlock(loc, name, defns, macros, procedures, mappingMacros, archetypes, varDecls, instances, procs) - } -} - -object ModularPlusCalParser extends ModularPlusCalParser with ParsingUtils { - def hasModularPlusCalBlock(path: java.nio.file.Path, charSeq: CharSequence): Boolean = - findInComment("mpcal", "--mpcal")(buildReader(path, charSeq)) match { - case Success(_, _) => true - case NoSuccess(_, _) => false - } - - def readBlock(path: java.nio.file.Path, charSeq: CharSequence, tlaModule: TLAModule): ModularPlusCalBlock = { - implicit val tlaCtx = TLAUtils.fillContextFromModule( - TLABuiltinModules.Intrinsics.members.foldLeft(TLAParserContext())(_.withDefinition(_)), - tlaModule, captureLocal = true) - implicit val ctx = PCalParserContext() - checkResult(phrase(findInComment("mpcal", mpcalBlock))(buildReader(path, charSeq))) - } -} diff --git a/src/pgo/parser/PCalParser.scala b/src/pgo/parser/PCalParser.scala new file mode 100644 index 000000000..54ba6ca31 --- /dev/null +++ b/src/pgo/parser/PCalParser.scala @@ -0,0 +1,435 @@ +package pgo.parser + +import pgo.model.{Definition, SourceLocation} +import pgo.model.pcal._ +import pgo.model.tla._ + +import scala.collection.mutable + +trait PCalParser extends TLAParser { + import PCalParserContext._ + + def findInComment[T](tag: =>Parser[Any], p: =>Parser[T]): Parser[T] = { + val commentDelimiter: Parser[Any] = "(*" | "\\*" | "*)" + val findComment: Parser[Any] = rep((not(commentDelimiter) ~> anything) | tlaLineComment) ^^^ () + val taggedComment: Parser[T] = + "(*" ~> rep(tlaMultilineComment | tlaLineComment | (not(commentDelimiter | ("--" ~> tag)) ~> anything)) ~> guard("--" ~> tag) ~> commit(p) <~ + rep(tlaMultilineComment | tlaLineComment | (not(commentDelimiter) ~> anything)) <~ "*)" + val emptyComment: Parser[Any] = "(*" ~> rep((not(commentDelimiter) ~> anything) | tlaLineComment | tlaMultilineComment) ~> "*)" + + lazy val search: Parser[T] = + findComment ~> (taggedComment | (emptyComment ~> search)) + + search <~ rep(anything) + } + + override def tlaInfixOperator: Parser[TLASymbol] = + not("||" | ":=") ~> super.tlaInfixOperator + + val ws: Parser[Unit] = tlaWhitespace + + def pcalVarDeclBound(implicit ctx: PCalParserContext): Parser[PCalVariableDeclarationBound] = + withSourceLocation { + tlaIdentifierExpr ~ (ws ~> ("\\in" ^^^ true | "=" ^^^ false)) ~ (ws ~> tlaExpression) ^^ { + case id ~ true ~ v => + PCalVariableDeclarationSet(id, v) + case id ~ false ~ v => + PCalVariableDeclarationValue(id, v) + } + } + + def pcalVarDecl(implicit ctx: PCalParserContext): Parser[PCalVariableDeclaration] = + pcalVarDeclBound | withSourceLocation { tlaIdentifierExpr ^^ PCalVariableDeclarationEmpty } + + def pcalPVarDecl(implicit ctx: PCalParserContext): Parser[PCalPVariableDeclaration] = + withSourceLocation { + tlaIdentifierExpr ~ opt(ws ~> "=" ~> ws ~> tlaExpression) ^^ { + case id ~ valueOpt => PCalPVariableDeclaration(id, valueOpt) + } + } + + def pcalVarDecls(implicit ctx: PCalParserContext): Parser[List[PCalVariableDeclaration]] = + ("variables" | "variable") ~> ws ~> { + def rec(implicit ctx: PCalParserContext): Parser[List[PCalVariableDeclaration]] = { + val origCtx = ctx + (ws ~> pcalVarDecl <~ ws <~ (";" | ",")).flatMap { decl => + implicit val ctx: PCalParserContext = origCtx.withDefinition(decl) + rec ^^ (decl :: _) | success(List(decl)) + } + } + rec | success(Nil) + } + + def pcalLhsId(implicit ctx: PCalParserContext): Parser[PCalAssignmentLhs] = + withSourceLocation { + tlaIdentifierExpr <~ guard(ws ~> (":=" | "[" | ".")) ^^ { id => // avoid accidentally matching labels + ctx.ctx.lookupDefinition(List(Definition.ScopeIdentifierName(id))) match { + case Some(defn) => + val result = PCalAssignmentLhsIdentifier(id) + result.setRefersTo(defn) + result + case None if ctx.ctx.lateBindingStack.nonEmpty => + val lateBindings = ctx.ctx.lateBindingStack.head + val result = PCalAssignmentLhsIdentifier(id) + lateBindings.getOrElseUpdate(id, mutable.ArrayBuffer.empty) += result.setRefersTo + result + case None => + throw DefinitionLookupError(Nil, Definition.ScopeIdentifierName(id)) + } + } + } + + def pcalLhs(implicit ctx: PCalParserContext): Parser[PCalAssignmentLhs] = { + def rec(lhs: PCalAssignmentLhs): Parser[PCalAssignmentLhs] = + opt(ws ~> withSourceLocation { + "." ~> ws ~> tlaIdentifierExpr ^^ (id => PCalAssignmentLhsProjection(lhs, List(TLAString(id.id).setSourceLocation(id.sourceLocation)))) | + "[" ~> ws ~> rep1sep(tlaExpression, ws ~> "," ~> ws) <~ ws <~ "]" ^^ (PCalAssignmentLhsProjection(lhs, _)) + }.flatMap(rec)).map(_.getOrElse(lhs)) + + pcalLhsId.flatMap(rec) + } + + def pcalAssignment(implicit ctx: PCalParserContext): Parser[PCalAssignment] = + withSourceLocation { + rep1sep(withSourceLocation { + pcalLhs ~ (ws ~> ":=" ~> ws ~> tlaExpression) ^^ { + case lhs ~ rhs => PCalAssignmentPair(lhs, rhs) + } + }, ws ~> "||" ~> ws) ^^ PCalAssignment + } + + def pcalAwait(implicit ctx: PCalParserContext): Parser[PCalAwait] = + withSourceLocation { + ("await" | "when") ~> ws ~> tlaExpression ^^ PCalAwait + } + + def pcalPrint(implicit ctx: PCalParserContext): Parser[PCalPrint] = + withSourceLocation { + "print" ~> ws ~> tlaExpression ^^ PCalPrint + } + + def pcalAssert(implicit ctx: PCalParserContext): Parser[PCalAssert] = + withSourceLocation { + "assert" ~> ws ~> tlaExpression ^^ PCalAssert + } + + def pcalSkip(implicit ctx: PCalParserContext): Parser[PCalSkip] = + withSourceLocation("skip" ^^ (_ => PCalSkip())) + + def pcalReturn(implicit ctx: PCalParserContext): Parser[PCalReturn] = + withSourceLocation("return" ^^ (_ => PCalReturn())) + + def pcalGoto(implicit ctx: PCalParserContext): Parser[PCalGoto] = + withSourceLocation { + "goto" ~> ws ~> tlaIdentifier ^^ PCalGoto + } + + def pcalCallParam(implicit ctx: PCalParserContext): Parser[TLAExpression] = tlaExpression + def pcalCall(implicit ctx: PCalParserContext): Parser[PCalCall] = + withSourceLocation { + "call" ~> ws ~> tlaIdentifierExpr ~ (ws ~> "(" ~> ws ~> repsep(pcalCallParam, ws ~> "," ~> ws) <~ ws <~ ")") ^^ { + case id ~ args => PCalCall(id, args) + } + } + + def pcalMacroCall(implicit ctx: PCalParserContext): Parser[PCalMacroCall] = + withSourceLocation { + tlaIdentifierExpr ~ (ws ~> "(" ~> ws ~> repsep(tlaExpression, ws ~> "," ~> ws) <~ ws <~ ")") ^^ { + case id ~ args => PCalMacroCall(id, args) // has refersTo, but will be assigned later when parsing algorithm + } + } + + + def pcalDefinitions(implicit ctx: PCalParserContext): Parser[List[TLAUnit]] = { + "define" ~> ws ~> "{" ~> { + def rec(implicit ctx: PCalParserContext): Parser[List[TLAUnit]] = { + val origCtx = ctx + (ws ~> tlaUnit).flatMap { unit => + implicit val ctx: PCalParserContext = unit.definitions.foldLeft(origCtx)(_.withDefinition(_)) + rec ^^ (unit :: _) | success(List(unit)) + } + } + rec | success(Nil) + } <~ ws <~ "}" <~ opt(ws ~> ";") + } + + trait GenericSyntax { + def pcalIf(implicit ctx: PCalParserContext): Parser[PCalIf] + def pcalWhile(implicit ctx: PCalParserContext): Parser[PCalWhile] + def pcalEither(implicit ctx: PCalParserContext): Parser[PCalEither] + def pcalWith(implicit ctx: PCalParserContext): Parser[PCalWith] + + def pcalUnlabeledStmt(implicit ctx: PCalParserContext): Parser[PCalStatement] = + pcalIf | pcalWhile | pcalEither | pcalWith | pcalAwait | + pcalPrint | pcalAssert | pcalSkip | pcalReturn | pcalGoto | pcalCall | + pcalMacroCall | pcalAssignment + + def pcalStmts(implicit ctx: PCalParserContext): Parser[List[PCalStatement]] + + def pcalBody(pSuffix: String)(implicit ctx: PCalParserContext): Parser[List[PCalStatement]] + + def pcalMacro(implicit ctx: PCalParserContext): Parser[PCalMacro] = + withSourceLocation { + val origCtx = ctx + "macro" ~> ws ~> tlaIdentifierExpr ~ (ws ~> "(" ~> ws ~> repsep(tlaIdentifierExpr, ws ~> "," ~> ws)).flatMap { params => + val definingParams = params.map(_.toDefiningIdentifier) + implicit val ctx: PCalParserContext = definingParams.foldLeft(origCtx)(_.withDefinition(_)).withLateBinding + (ws ~> ")" ~> ws ~> pcalBody("macro") <~ opt(ws ~> ";")) ^^ ((definingParams, _, ctx.ctx.lateBindingStack.head)) + } ^^ { + case id ~ ((params, body, freeVars)) => + val freeVarsList = freeVars.keysIterator.toArray.sortInPlaceBy(_.id).iterator.map(_.toDefiningIdentifier).toList + freeVarsList.foreach { ident => + freeVars(ident.id).foreach(_(ident)) + } + PCalMacro(id, params, body, freeVarsList) + } + } + + def pcalProcedure(implicit ctx: PCalParserContext): Parser[PCalProcedure] = + withSourceLocation { + val origCtx = ctx + ("procedure" ~> ws ~> tlaIdentifierExpr).flatMap { id => + ((ws ~> "(" ~> ws ~> repsep(pcalPVarDecl, ws ~> "," ~> ws)) ~ + (ws ~> ")" ~> opt(ws ~> ("variables" | "variable") ~> ws ~> rep1sep(pcalPVarDecl, ws ~> (";"|",") ~> ws) <~ opt(ws ~> (";" | ","))).map(_.getOrElse(Nil)))) + .flatMap { + case args ~ locals => + implicit val ctx: PCalParserContext = locals.foldLeft(args.foldLeft(origCtx)(_.withDefinition(_)))(_.withDefinition(_)) + (ws ~> pcalBody("procedure") <~ opt(ws ~> ";")) ^^ ((id, args, locals, _)) + } + } ^^ { + case (id, args, locals, body) => + PCalProcedure(id, args, locals, body) + } + } + + def pcalProcessSelf(implicit ctx: PCalParserContext): Parser[PCalVariableDeclarationBound] + def pcalProcess(implicit ctx: PCalParserContext): Parser[PCalProcess] = + withSourceLocation { + val origCtx = ctx + ((("fair" ~> ws ~> "+" ^^^ PCalFairness.StrongFair) | ("fair" ^^^ PCalFairness.WeakFair) | success(PCalFairness.Unfair)) ~ + (ws ~> "process" ~> ws ~> pcalProcessSelf)).flatMap { + case fairness ~ self => + implicit val ctx: PCalParserContext = origCtx.withProcessSelf(self) + val origCtx2 = ctx + opt(ws ~> pcalVarDecls).map(_.getOrElse(Nil)).flatMap { locals => + implicit val ctx: PCalParserContext = locals.foldLeft(origCtx2)(_.withDefinition(_)) + (ws ~> pcalBody("process") <~ opt(ws ~> ";")) ^^ ((fairness, self, locals, _)) + } + } ^^ { + case (fairness, self, locals, body) => PCalProcess(self, fairness, locals, body) + } + } + + def pcalAlgorithmOpenBrace(implicit ctx: PCalParserContext): Parser[Unit] + def pcalAlgorithmCloseBrace(implicit ctx: PCalParserContext): Parser[Unit] + def pcalAlgorithm(implicit ctx: PCalParserContext): Parser[PCalAlgorithm] = + withSourceLocation { + val origCtx = ctx + (("--algorithm" ^^^ PCalFairness.Unfair | "--fair algorithm" ^^^ PCalFairness.WeakFair) ~ + (ws ~> tlaIdentifierExpr) ~ (pcalAlgorithmOpenBrace ~> opt(ws ~> pcalVarDecls).map(_.getOrElse(Nil)))).flatMap { + case fairness ~ name ~ decls => + implicit val ctx: PCalParserContext = decls.foldLeft(origCtx)(_.withDefinition(_)) + val origCtx2 = ctx + opt(ws ~> pcalDefinitions).map(_.getOrElse(Nil)).flatMap { defns => + implicit val ctx: PCalParserContext = defns.foldLeft(origCtx2) { (ctx, unit) => + unit.definitions.foldLeft(ctx)(_.withDefinition(_)) + } + (ws ~> repsep(pcalMacro, ws)) ~ + (ws ~> repsep(pcalProcedure, ws)) ~ + (ws ~> { + pcalBody("algorithm") ^^ (Left(_)) | + rep1sep(pcalProcess, ws) ^^ (Right(_)) + }) ^^ ((fairness, name, decls, defns, _)) + } + } <~ pcalAlgorithmCloseBrace ^^ { + case (fairness, name, decls, defns, macros ~ procedures ~ proc) => + val result = PCalAlgorithm(fairness, name, decls, defns, macros, procedures, proc) + val macroMap = macros.view.map(m => m.name -> m).toMap + result.visit() { + case call @PCalMacroCall(target, _) => + macroMap.get(target) match { + case Some(mcro) => call.setRefersTo(mcro) + case None => throw MacroLookupError(target) + } + } + val procedureMap = procedures.view.map(proc => proc.name -> proc).toMap + result.visit() { + case call @PCalCall(target, _) => + procedureMap.get(target) match { + case Some(procedure) => call.setRefersTo(procedure) + case None => throw ProcedureLookupError(target) + } + } + result + } + } + } + + // make C-syntax overridable + val pcalCSyntax: PCalCSyntax = new PCalCSyntax {} + trait PCalCSyntax extends GenericSyntax { + override def pcalIf(implicit ctx: PCalParserContext): Parser[PCalIf] = + withSourceLocation { + "if" ~> ws ~> "(" ~> tlaExpression ~ (ws ~> ")" ~> ws ~> pcalStmts) ~ + opt(opt(ws ~> ";") ~> ws ~> "else" ~> ws ~> pcalStmts).map(_.getOrElse(Nil)) ^^ { + case cond ~ yes ~ no => PCalIf(cond, yes, no) + } + } + + override def pcalWhile(implicit ctx: PCalParserContext): Parser[PCalWhile] = + withSourceLocation { + "while" ~> ws ~> "(" ~> ws ~> tlaExpression ~ (ws ~> ")" ~> ws ~> pcalStmts) ^^ { + case cond ~ body => PCalWhile(cond, body) + } + } + + override def pcalEither(implicit ctx: PCalParserContext): Parser[PCalEither] = + withSourceLocation { + "either" ~> ws ~> pcalStmts ~ (ws ~> rep1sep("or" ~> ws ~> pcalStmts, ws)) ^^ { + case part1 ~ parts => PCalEither(part1 :: parts) + } + } + + override def pcalWith(implicit ctx: PCalParserContext): Parser[PCalWith] = + withSourceLocation { + "with" ~> ws ~> "(" ~> { + def rec(rest: Boolean)(implicit ctx: PCalParserContext): Parser[(List[PCalVariableDeclarationBound],List[PCalStatement])] = { + val origCtx = ctx + (if(rest) { + ws ~> (";" | ",") + } else { + ws + }) ~> pcalVarDeclBound.flatMap { decl => + implicit val ctx: PCalParserContext = origCtx.withDefinition(decl) + rec(true) ^^ (p => (decl :: p._1, p._2)) | (ws ~> ")" ~> ws ~> pcalStmts) ^^ ((List(decl), _)) + } + } + rec(false) + } ^^ { + case (decls, body) => PCalWith(decls, body) + } + } + + def pcalCompoundStmt(implicit ctx: PCalParserContext): Parser[List[PCalStatement]] = + "{" ~> ws ~> rep1sep(pcalStmts, ws ~> ";" ~> ws) <~ opt(ws ~> ";") <~ ws <~ "}" ^^ (_.flatten) + + def pcalLabeledStmt(implicit ctx: PCalParserContext): Parser[PCalLabeledStatements] = + withSourceLocation { + querySourceLocation { + tlaIdentifier ~ (ws ~> not(":=") ~> ":" ~> ws ~> ("+" ^^^ PCalLabel.PlusModifier | "-" ^^^ PCalLabel.MinusModifier | success(PCalLabel.NoModifier))) + } ~! (ws ~> (rep1sep(pcalUnlabeledStmt, ws ~> ";" ~> ws) | pcalCompoundStmt)) ^^ { + case (labelLoc, label ~ modifier) ~ body => + PCalLabeledStatements(PCalLabel(label, modifier).setSourceLocation(labelLoc), body) + } + } + + override def pcalStmts(implicit ctx: PCalParserContext): Parser[List[PCalStatement]] = + pcalUnlabeledStmt.map(List(_)) | pcalLabeledStmt.map(List(_)) | pcalCompoundStmt + + override def pcalBody(pSuffix: String)(implicit ctx: PCalParserContext): Parser[List[PCalStatement]] = + pcalCompoundStmt + + override def pcalProcessSelf(implicit ctx: PCalParserContext): Parser[PCalVariableDeclarationBound] = + "(" ~> ws ~> pcalVarDeclBound <~ ws <~ ")" + + override def pcalAlgorithmOpenBrace(implicit ctx: PCalParserContext): Parser[Unit] = + ws ~> "{" ^^^ () + + override def pcalAlgorithmCloseBrace(implicit ctx: PCalParserContext): Parser[Unit] = + ws ~> "}" ^^^ () + } + + val pcalPSyntax: PCalPSyntax = new PCalPSyntax {} + trait PCalPSyntax extends GenericSyntax { + override def pcalIf(implicit ctx: PCalParserContext): Parser[PCalIf] = { + lazy val elsePart: Parser[List[PCalStatement]] = { + val elsif = withSourceLocation { + "elsif" ~> ws ~> tlaExpression ~ (ws ~> "then" ~> ws ~> rep1sep(pcalStmt, ws)) ~ (ws ~> elsePart) ^^ { + case cond ~ yes ~ no => PCalIf(cond, yes, no) + } + } ^^ (List(_)) + val els = "else" ~> ws ~> rep1sep(pcalStmt, ws) + + elsif | els | success(Nil) + } + + withSourceLocation { + "if" ~> ws ~> tlaExpression ~ (ws ~> "then" ~> ws ~> rep1sep(pcalStmt, ws) <~ ws) ~ elsePart <~ ws <~ "end" <~ ws <~ "if" ^^ { + case cond ~ yes ~ no => PCalIf(cond, yes, no) + } + } + } + + override def pcalWhile(implicit ctx: PCalParserContext): Parser[PCalWhile] = + withSourceLocation { + "while" ~> ws ~> tlaExpression ~ (ws ~> "do" ~> ws ~> rep1sep(pcalStmt, ws) <~ ws <~ "end" <~ ws <~ "while") ^^ { + case cond ~ body => PCalWhile(cond, body) + } + } + + override def pcalEither(implicit ctx: PCalParserContext): Parser[PCalEither] = + withSourceLocation { + "either" ~> ws ~> rep1sep(rep1sep(pcalStmt, ws), ws ~> "or" ~> ws) <~ ws <~ "end" <~ ws <~ "either" ^^ PCalEither + } + + override def pcalWith(implicit ctx: PCalParserContext): Parser[PCalWith] = + withSourceLocation { + "with" ~> { + def rec(rest: Boolean)(implicit ctx: PCalParserContext): Parser[(List[PCalVariableDeclarationBound], List[PCalStatement])] = { + val origCtx = ctx + (if (rest) { + ws ~> (";" | ",") ~> ws + } else { + ws + }) ~> pcalVarDeclBound.flatMap { decl => + implicit val ctx: PCalParserContext = origCtx.withDefinition(decl) + rec(true) ^^ (p => (decl :: p._1, p._2)) | + (opt(ws ~> (";" | ",")) ~> ws ~> "do" ~> ws ~> rep1sep(pcalStmt, ws) <~ ws <~ "end" <~ ws <~ "with") ^^ ((List(decl), _)) + } + } + rec(false) + } ^^ { + case (decls, body) => PCalWith(decls, body) + } + } + + def pcalStmt(implicit ctx: PCalParserContext): Parser[PCalStatement] = { + val labeledStmts: Parser[PCalLabeledStatements] = + withSourceLocation { + querySourceLocation { + tlaIdentifier ~ (ws ~> not(":=") ~> ":" ~> ws ~> ("+" ^^^ PCalLabel.PlusModifier | "-" ^^^ PCalLabel.MinusModifier | success(PCalLabel.NoModifier))) + } ~! (ws ~> rep1sep(pcalUnlabeledStmt, ws ~> ";" ~> ws) <~ ws <~ ";") ^^ { + case (labelLoc, label ~ mod) ~ stmts => + PCalLabeledStatements(PCalLabel(label, mod).setSourceLocation(labelLoc), stmts) + } + } + + (pcalUnlabeledStmt <~ ws <~ ";") | labeledStmts + } + + override def pcalStmts(implicit ctx: PCalParserContext): Parser[List[PCalStatement]] = rep1sep(pcalStmt, ws) + + override def pcalBody(pSuffix: String)(implicit ctx: PCalParserContext): Parser[List[PCalStatement]] = + "begin" ~> ws ~> pcalStmts <~ ws <~ "end" <~ ws <~ pSuffix + + override def pcalProcessSelf(implicit ctx: PCalParserContext): Parser[PCalVariableDeclarationBound] = pcalVarDeclBound + + override def pcalAlgorithmOpenBrace(implicit ctx: PCalParserContext): Parser[Unit] = not(ws ~> "{") + + override def pcalAlgorithmCloseBrace(implicit ctx: PCalParserContext): Parser[Unit] = success(()) + } + + def pcalAlgorithm(implicit ctx: PCalParserContext): Parser[PCalAlgorithm] = + pcalPSyntax.pcalAlgorithm | pcalCSyntax.pcalAlgorithm +} + +object PCalParser extends PCalParser with ParsingUtils { + def readAlgorithm(underlying: SourceLocation.UnderlyingText, contents: CharSequence, tlaModule: TLAModule): PCalAlgorithm = { + implicit val tlaCtx: TLAParserContext = + tlaModule.moduleDefinitions(captureLocal = true).foldLeft( + BuiltinModules.Intrinsics.members.foldLeft(TLAParserContext())(_.withDefinition(_)) + )(_.withDefinition(_)) + implicit val ctx: PCalParserContext = PCalParserContext() + checkResult(phrase(findInComment("fair" | "algorithm", pcalAlgorithm))(buildReader(contents, underlying))) + } +} diff --git a/src/pgo/parser/PCalParserContext.scala b/src/pgo/parser/PCalParserContext.scala new file mode 100644 index 000000000..b868da387 --- /dev/null +++ b/src/pgo/parser/PCalParserContext.scala @@ -0,0 +1,23 @@ +package pgo.parser + +import pgo.model.pcal._ +import pgo.model.Definition +import pgo.model.tla.TLAIdentifier + +final case class PCalParserContext()(implicit val ctx: TLAParserContext) { + def withDefinition(defn: Definition): PCalParserContext = + copy()(ctx.withDefinition(defn)) + + def withProcessSelf(self: PCalVariableDeclarationBound): PCalParserContext = + copy()(ctx.copy( + currentScope = ctx.currentScope.updated( + Definition.ScopeIdentifierName(TLAIdentifier("self").setSourceLocation(self.sourceLocation)), + self))) + + def withLateBinding: PCalParserContext = + copy()(ctx.withLateBinding) +} + +object PCalParserContext { + implicit def getTLAParserContext(implicit ctx: PCalParserContext): TLAParserContext = ctx.ctx +} diff --git a/src/pgo/parser/ParsingErrors.scala b/src/pgo/parser/ParsingErrors.scala index 8a3b0b2c7..9226bee77 100644 --- a/src/pgo/parser/ParsingErrors.scala +++ b/src/pgo/parser/ParsingErrors.scala @@ -1,36 +1,50 @@ package pgo.parser -import pgo.model.mpcal.ModularPlusCalArchetype -import pgo.model.tla.{TLADefinitionOne, TLAGeneralIdentifierPart, TLAIdentifier} -import pgo.util.SourceLocation +import pgo.model.{Definition, DefinitionOne, PGoError, SourceLocation} +import pgo.model.tla.{TLAGeneralIdentifierPart, TLAIdentifier} +import pgo.model.mpcal.MPCalArchetype +import pgo.util.Description +import Description._ -sealed abstract class ParsingError(msg: String) extends RuntimeException(msg) +sealed abstract class ParsingError(override val sourceLocation: SourceLocation, override val description: Description) extends PGoError with PGoError.Error { + override val errors: List[PGoError.Error] = List(this) +} -final case class DefinitionLookupError(loc: SourceLocation, pfx: List[TLAGeneralIdentifierPart], - id: TLAIdentifier) extends ParsingError( - s"""${loc.prettyString} - |identifier ${pfx.mkString("!")}${if(pfx.nonEmpty){"!"} else {""}}$id does not refer to a known definition""".stripMargin) +final case class DefinitionLookupError(pfx: List[TLAGeneralIdentifierPart], id: Definition.ScopeIdentifier) extends ParsingError( + id.sourceLocation,d"identifier ${pfx.mkString("!")}${if(pfx.nonEmpty){"!"} else {""}}$id does not refer to a known definition") -final case class ModuleNotFoundError(loc: SourceLocation, id: TLAIdentifier) extends ParsingError( - s"""${loc.prettyString} - |module $id not found""".stripMargin) +final case class DoesNotExtendAModuleError(id: Definition.ScopeIdentifierName, badDefn: DefinitionOne) extends ParsingError( + id.sourceLocation,d"${id.name.id} does not refer to a module. actually refers to $badDefn") -final case class DoesNotExtendAModuleError(loc: SourceLocation, id: TLAIdentifier, badDefn: TLADefinitionOne) extends ParsingError( - s"""${loc.prettyString} - |found a definition when looking for module $id, but it is not a module. found $badDefn instead""".stripMargin) +final case class ModuleNotFoundError(id: Definition.ScopeIdentifierName) extends ParsingError( + id.sourceLocation,d"module $id not found") -final case class ArityMismatchError(loc: SourceLocation, defn: TLADefinitionOne, actualArity: Int) extends ParsingError( - s"""${loc.prettyString} - |arity mismatch: expected ${defn.arity}, found $actualArity""".stripMargin) +final case class MacroLookupError(target: TLAIdentifier) extends ParsingError( + target.sourceLocation, d"could not find definition for macro `${target.id}`") -final case class ArchetypeArityMismatchError(loc: SourceLocation, archetype: ModularPlusCalArchetype, actualArity: Int) extends ParsingError( - s"""${loc.prettyString} - |archetype arity mismatch: expected ${archetype.getParams.size()}, found $actualArity""".stripMargin) +final case class ProcedureLookupError(target: TLAIdentifier) extends ParsingError( + target.sourceLocation, d"could not find definition for procedure ${target.id}") -final case class KindMismatchError(loc: SourceLocation) extends ParsingError( - s"""${loc.prettyString} - |kind mismatch""".stripMargin) +final case class ArchetypeLookupError(target: TLAIdentifier) extends ParsingError( + target.sourceLocation, d"could not find referenced archetype ${target.id}") + +final case class MappingLookupError(target: TLAIdentifier) extends ParsingError( + target.sourceLocation,d"could not find referenced instance argument ${target.id}") + +final case class MappingIndexOutOfBounds(loc: SourceLocation, idx: Int, maxIdx: Int) extends ParsingError( + loc, d"index-referenced instance argument out of bounds: $idx, with largest valid index $maxIdx") + +final case class MappingMacroLookupError(target: TLAIdentifier) extends ParsingError( + target.sourceLocation, d"could not find referenced mapping macro ${target.id}") + +final case class ArityMismatchError(loc: SourceLocation, defn: DefinitionOne, actualArity: Int) extends ParsingError( + loc, d" arity mismatch: expected ${defn.arity}, found $actualArity") + +final case class ArchetypeArityMismatchError(loc: SourceLocation, archetype: MPCalArchetype, actualArity: Int) extends ParsingError( + loc, d"archetype arity mismatch: expected ${archetype.params.size}, found $actualArity") + +final case class KindMismatchError(loc: SourceLocation, explanation: Description) extends ParsingError( + loc, d"kind mismatch: $explanation") final case class ParseFailureError(err: String, loc: SourceLocation) extends ParsingError( - s"""${loc.prettyString} - |parsing failed: $err""".stripMargin) + loc, d"parsing failed: $err") diff --git a/src/pgo/parser/ParsingUtils.scala b/src/pgo/parser/ParsingUtils.scala index 3fd6b362c..85b879200 100644 --- a/src/pgo/parser/ParsingUtils.scala +++ b/src/pgo/parser/ParsingUtils.scala @@ -1,12 +1,14 @@ package pgo.parser +import pgo.model.SourceLocation + import scala.util.parsing.combinator.Parsers import scala.util.parsing.input.CharSequenceReader trait ParsingUtils extends Parsers { - def buildReader(path: java.nio.file.Path, seq: CharSequence): LineColumnAwareCharReader = { + def buildReader(seq: CharSequence, underlyingText: SourceLocation.UnderlyingText): LineColumnAwareCharReader = { val reader = new CharSequenceReader(seq) - val lcReader = new LineColumnAwareCharReader(reader, path) + val lcReader = new LineColumnAwareCharReader(reader, underlyingText) lcReader } @@ -14,6 +16,6 @@ trait ParsingUtils extends Parsers { result match { case Success(result, _) => result case NoSuccess(err, in) => - throw ParseFailureError(err, in.asInstanceOf[LineColumnAwareCharReader].sourceLocation) + throw ParseFailureError(err, in.asInstanceOf[LineColumnAwareCharReader].currentSourceLocation) } } diff --git a/src/pgo/parser/PlusCalParser.scala b/src/pgo/parser/PlusCalParser.scala deleted file mode 100644 index 48bc61a80..000000000 --- a/src/pgo/parser/PlusCalParser.scala +++ /dev/null @@ -1,420 +0,0 @@ -package pgo.parser - -import pgo.model.mpcal.ModularPlusCalArchetype -import pgo.model.pcal._ -import pgo.model.tla._ -import pgo.util.SourceLocation - -import scala.jdk.CollectionConverters._ - -final case class PCalParserContext(archetypes: Map[String,ModularPlusCalArchetype]=Map.empty)(implicit val ctx: TLAParserContext) { - def withIdx(loc: SourceLocation, idx: Int, defn: TLADefinitionOne): PCalParserContext = - copy()(ctx.copy(currentScope = ctx.currentScope.updated(new TLAIdentifier(loc, s"@$idx"), defn))) - - def withDefinition(defn: TLADefinition): PCalParserContext = - copy()(ctx.withDefinition(defn)) - - def withSelf(loc: SourceLocation, defn: TLADefinitionOne): PCalParserContext = - copy()(ctx.withSelf(loc, defn)) - - def withArchetype(arch: ModularPlusCalArchetype): PCalParserContext = - copy(archetypes=archetypes.updated(arch.getName, arch)) -} - -object PCalParserContext { - implicit def tlaCtx(implicit ctx: PCalParserContext): TLAParserContext = ctx.ctx -} - -trait PlusCalParser extends TLAParser { - import PCalParserContext.tlaCtx - - def findInComment[T](tag: =>Parser[Any], p: =>Parser[T]): Parser[T] = { - val commentDelimiter: Parser[Any] = "(*" | "\\*" | "*)" - val findComment: Parser[Any] = rep((not(commentDelimiter) ~> anything) | tlaLineComment) ^^^ () - val taggedComment: Parser[T] = - "(*" ~> rep(tlaMultilineComment | tlaLineComment | (not(commentDelimiter | ("--" ~> tag)) ~> anything)) ~> guard("--" ~> tag) ~> commit(p) <~ - rep(tlaMultilineComment | tlaLineComment | (not(commentDelimiter) ~> anything)) <~ "*)" - val emptyComment: Parser[Any] = "(*" ~> rep((not(commentDelimiter) ~> anything) | tlaLineComment | tlaMultilineComment) ~> "*)" - - lazy val search: Parser[T] = - findComment ~> (taggedComment | (emptyComment ~> search)) - - search <~ rep(anything) - } - - override def tlaInfixOperator: Parser[String] = - not("||" | ":=") ~> super.tlaInfixOperator - - val ws: Parser[Unit] = tlaWhitespace - - def pcalVarDecl(implicit ctx: PCalParserContext): Parser[PlusCalVariableDeclaration] = { - val quantified = - withSourceLocation { - tlaIdentifierExpr ~ (ws ~> ("\\in" ^^^ true | "=" ^^^ false)) ~ (ws ~> tlaExpression) - } ^^ { - case (loc, id ~ isSet ~ v) => - new PlusCalVariableDeclaration(loc, id, false, isSet, v) - } - val id = tlaIdentifierExpr ^^ { id => - new PlusCalVariableDeclaration(id.getLocation, id, false, false, new PlusCalDefaultInitValue(id.getLocation)) - } - quantified | id - } - - def pcalPVarDecl(implicit ctx: PCalParserContext): Parser[PlusCalVariableDeclaration] = { - val quantified = - withSourceLocation { - tlaIdentifierExpr ~ (ws ~> "=" ~> ws ~> tlaExpression) - } ^^ { - case (loc, id ~ v) => - new PlusCalVariableDeclaration(loc, id, false, false, v) - } - val id = tlaIdentifierExpr ^^ { id => - new PlusCalVariableDeclaration(id.getLocation, id, false, false, new PlusCalDefaultInitValue(id.getLocation)) - } - quantified | id - } - - def pcalVarDecls(implicit ctx: PCalParserContext): Parser[List[PlusCalVariableDeclaration]] = - ("variables" | "variable") ~> ws ~> { - def rec(implicit ctx: PCalParserContext): Parser[List[PlusCalVariableDeclaration]] = { - val origCtx = ctx - (ws ~> pcalVarDecl <~ ws <~ (";" | ",")).flatMap { decl => - implicit val ctx = origCtx.withDefinition(decl) - rec ^^ (decl :: _) | success(List(decl)) - } - } - rec | success(Nil) - } - - def pcalLhsId(implicit ctx: PCalParserContext): Parser[TLAExpression] = - tlaIdentifierExpr <~ guard(ws ~> (":=" | "[" | ".")) ^^ { id => // avoid accidentally matching labels - ctx.ctx.lookupDefinition(List(id)) match { - case Some(defn) => - val result = new TLAGeneralIdentifier(id.getLocation, id, Nil) - result.setRefersTo(defn) - result - case None => - throw DefinitionLookupError(id.getLocation, Nil, id) - } - } - def pcalLhs(implicit ctx: PCalParserContext): Parser[TLAExpression] = - withSourceLocation(pcalLhsId ~ (ws ~> "[" ~> ws ~> rep1sep(tlaExpression, ws ~> "," ~> ws) <~ ws <~ "]")) ^^ { - case (loc, id ~ args) => new TLAFunctionCall(loc, id, args.asJava) - } | - withSourceLocation(pcalLhsId ~ (ws ~> "." ~> ws ~> tlaIdentifier)) ^^ { - case (loc, id1 ~ id2) => new TLADot(loc, id1, id2) - } | pcalLhsId - - def pcalAssignment(implicit ctx: PCalParserContext): Parser[PlusCalAssignment] = { - val pairs = rep1sep(withSourceLocation(pcalLhs ~ (ws ~> ":=" ~> ws ~> tlaExpression)) ^^ { - case (loc, lhs ~ rhs) => new PlusCalAssignmentPair(loc, lhs, rhs) - }, ws ~> "||" ~> ws) - withSourceLocation(pairs) ^^ { case (loc, pairs) => new PlusCalAssignment(loc, pairs.asJava) } - } - - def pcalAwait(implicit ctx: PCalParserContext): Parser[PlusCalAwait] = - withSourceLocation { - ("await" | "when") ~> ws ~> tlaExpression - } ^^ { case (loc, cond) => new PlusCalAwait(loc, cond) } - - def pcalPrint(implicit ctx: PCalParserContext): Parser[PlusCalPrint] = - withSourceLocation { - "print" ~> ws ~> tlaExpression - } ^^ { case (loc, expr) => new PlusCalPrint(loc, expr) } - - def pcalAssert(implicit ctx: PCalParserContext): Parser[PlusCalAssert] = - withSourceLocation { - "assert" ~> ws ~> tlaExpression - } ^^ { case (loc, cond) => new PlusCalAssert(loc, cond) } - - def pcalSkip(implicit ctx: PCalParserContext): Parser[PlusCalSkip] = - withSourceLocation("skip") ^^ { case (loc, _) => new PlusCalSkip(loc) } - - def pcalReturn(implicit ctx: PCalParserContext): Parser[PlusCalReturn] = - withSourceLocation("return") ^^ { case (loc, _) => new PlusCalReturn(loc) } - - def pcalGoto(implicit ctx: PCalParserContext): Parser[PlusCalGoto] = - withSourceLocation("goto" ~> ws ~> tlaIdentifier) ^^ { - case (loc, label) => new PlusCalGoto(loc, label) - } - - def pcalCallParam(implicit ctx: PCalParserContext): Parser[TLAExpression] = tlaExpression - def pcalCall(implicit ctx: PCalParserContext): Parser[PlusCalCall] = - withSourceLocation { - "call" ~> ws ~> tlaIdentifier ~ (ws ~> "(" ~> ws ~> repsep(pcalCallParam, ws ~> "," ~> ws) <~ ws <~ ")") - } ^^ { - case (loc, id ~ args) => new PlusCalCall(loc, id, args.asJava) - } - - def pcalMacroCall(implicit ctx: PCalParserContext): Parser[PlusCalMacroCall] = - withSourceLocation { - tlaIdentifier ~ (ws ~> "(" ~> ws ~> repsep(tlaExpression, ws ~> "," ~> ws) <~ ws <~ ")") - } ^^ { case (loc, id ~ args) => new PlusCalMacroCall(loc, id, args.asJava) } - - trait GenericSyntax { - def pcalIf(implicit ctx: PCalParserContext): Parser[PlusCalIf] - def pcalWhile(implicit ctx: PCalParserContext): Parser[PlusCalWhile] - def pcalEither(implicit ctx: PCalParserContext): Parser[PlusCalEither] - def pcalWith(implicit ctx: PCalParserContext): Parser[PlusCalWith] - - def pcalUnlabeledStmt(implicit ctx: PCalParserContext): Parser[PlusCalStatement] = - pcalIf | pcalWhile | pcalEither | pcalWith | pcalAwait | - pcalPrint | pcalAssert | pcalSkip | pcalReturn | pcalGoto | pcalCall | - pcalMacroCall | pcalAssignment - - def pcalStmts(implicit ctx: PCalParserContext): Parser[List[PlusCalStatement]] - - def pcalBody(pSuffix: String)(implicit ctx: PCalParserContext): Parser[List[PlusCalStatement]] - - def pcalDefinitions(implicit ctx: PCalParserContext): Parser[List[TLAUnit]] = { - "define" ~> ws ~> "{" ~> { - def rec(implicit ctx: PCalParserContext): Parser[List[TLAUnit]] = { - val origCtx = ctx - (ws ~> tlaUnit).flatMap { unit => - implicit val ctx = unit.definitions.foldLeft(origCtx)(_.withDefinition(_)) - rec ^^ (unit :: _) | success(List(unit)) - } - } - rec | success(Nil) - } <~ ws <~ "}" <~ opt(ws ~> ";") - } - - def pcalMacro(implicit ctx: PCalParserContext): Parser[PlusCalMacro] = - withSourceLocation { - val origCtx = ctx - "macro" ~> ws ~> tlaIdentifier ~ (ws ~> "(" ~> ws ~> repsep(tlaIdentifierExpr, ws ~> "," ~> ws)).flatMap { args => - implicit val ctx = args.foldLeft(origCtx)(_.withDefinition(_)) - (ws ~> ")" ~> ws ~> pcalBody("macro") <~ opt(ws ~> ";")) ^^ ((args, _)) - } - } ^^ { - case (loc, id ~ ((args, body))) => new PlusCalMacro(loc, id, args.asJava, body.asJava) - } - - def pcalProcedureParam(implicit ctx: PCalParserContext): Parser[PlusCalVariableDeclaration] = pcalPVarDecl - def pcalProcedure(implicit ctx: PCalParserContext): Parser[PlusCalProcedure] = - withSourceLocation { - val origCtx = ctx - ("procedure" ~> ws ~> tlaIdentifier ~ (ws ~> "(" ~> ws ~> repsep(pcalProcedureParam, ws ~> "," ~> ws)) ~ - (ws ~> ")" ~> opt(ws ~> ("variables" | "variable") ~> ws ~> rep1sep(pcalPVarDecl, ws ~> (";"|",") ~> ws) <~ opt(ws ~> (";" | ","))))).flatMap { - case id ~ args ~ locals => - implicit val ctx = locals.getOrElse(Nil).foldLeft(args.foldLeft(origCtx)(_.withDefinition(_)))(_.withDefinition(_)) - (ws ~> pcalBody("procedure") <~ opt(ws ~> ";")) ^^ ((id, args, locals, _)) - } - } ^^ { - case (loc, (id, args, locals, body)) => - new PlusCalProcedure(loc, id, args.asJava, locals.getOrElse(Nil).asJava, body.asJava) - } - - def pcalProcessSelf(implicit ctx: PCalParserContext): Parser[PlusCalVariableDeclaration] - def pcalProcess(implicit ctx: PCalParserContext): Parser[PlusCalProcess] = - withSourceLocation { - val origCtx = ctx - ((("fair" ~> ws ~> "+" ^^^ PlusCalFairness.STRONG_FAIR) | ("fair" ^^^ PlusCalFairness.WEAK_FAIR) | success(PlusCalFairness.UNFAIR)) ~ - (ws ~> "process" ~> ws ~> pcalProcessSelf) ~ opt(ws ~> pcalVarDecls)).flatMap { - case fairness ~ self ~ localsOpt => - implicit val ctx = localsOpt.getOrElse(Nil).foldLeft(origCtx.withSelf(self.getLocation, self))(_.withDefinition(_)) - (ws ~> pcalBody("process") <~ opt(ws ~> ";")) ^^ ((fairness, self, localsOpt.getOrElse(Nil), _)) - } - } ^^ { - case (loc, (fairness, self, locals, body)) => - new PlusCalProcess(loc, self, fairness, locals.asJava, body.asJava) - } - - def pcalAlgorithmOpenBrace(implicit ctx: PCalParserContext): Parser[Unit] - def pcalAlgorithmCloseBrace(implicit ctx: PCalParserContext): Parser[Unit] - def pcalAlgorithm(implicit ctx: PCalParserContext): Parser[PlusCalAlgorithm] = - withSourceLocation { - val origCtx = ctx - (("--algorithm" ^^^ PlusCalFairness.UNFAIR | "--fair algorithm" ^^^ PlusCalFairness.WEAK_FAIR) ~ - (ws ~> tlaIdentifierExpr) ~ (pcalAlgorithmOpenBrace ~> opt(ws ~> pcalVarDecls))).flatMap { - case fairness ~ name ~ declsOpt => - implicit val ctx = declsOpt.getOrElse(Nil).foldLeft(origCtx)(_.withDefinition(_)) - val origCtx2 = ctx - opt(ws ~> pcalDefinitions).flatMap { defnsOpt => - implicit val ctx = defnsOpt.getOrElse(Nil).foldLeft(origCtx2) { (ctx, unit) => - unit.definitions.foldLeft(ctx)(_.withDefinition(_)) - } - (ws ~> repsep(pcalMacro, ws)) ~ (ws ~> repsep(pcalProcedure, ws)) ~ (ws ~> { - withSourceLocation(pcalBody("algorithm")) ^^ { case (loc, stmts) => new PlusCalSingleProcess(loc, stmts.asJava) } | - withSourceLocation(rep1sep(pcalProcess, ws)) ^^ { case (loc, procs) => new PlusCalMultiProcess(loc, procs.asJava) } - }) ^^ ((fairness, name, declsOpt, defnsOpt, _)) - } - } <~ pcalAlgorithmCloseBrace - } ^^ { - case (loc, (fairness, name, declsOpt, defnsOpt, macros ~ procedures ~ proc)) => - new PlusCalAlgorithm(loc, fairness, name, declsOpt.getOrElse(Nil).asJava, macros.asJava, procedures.asJava, defnsOpt.getOrElse(Nil).asJava, proc) - } - } - - // make C-syntax overridable - val pcalCSyntax: PCalCSyntax = new PCalCSyntax {} - trait PCalCSyntax extends GenericSyntax { - override def pcalIf(implicit ctx: PCalParserContext): Parser[PlusCalIf] = - withSourceLocation { - "if" ~> ws ~> "(" ~> tlaExpression ~ (ws ~> ")" ~> ws ~> pcalStmts) ~ - opt(opt(ws ~> ";") ~> ws ~> "else" ~> ws ~> pcalStmts) - } ^^ { - case (loc, cond ~ yes ~ noOpt) => new PlusCalIf(loc, cond, yes.asJava, noOpt.getOrElse(Nil).asJava) - } - - override def pcalWhile(implicit ctx: PCalParserContext): Parser[PlusCalWhile] = - withSourceLocation { - "while" ~> ws ~> "(" ~> ws ~> tlaExpression ~ (ws ~> ")" ~> ws ~> pcalStmts) - } ^^ { - case (loc, cond ~ body) => new PlusCalWhile(loc, cond, body.asJava) - } - - override def pcalEither(implicit ctx: PCalParserContext): Parser[PlusCalEither] = - withSourceLocation { - "either" ~> ws ~> pcalStmts ~ (ws ~> rep1sep("or" ~> ws ~> pcalStmts, ws)) - } ^^ { - case (loc, part1 ~ parts) => - val convParts = part1.asJava :: parts.map(_.asJava) - new PlusCalEither(loc, convParts.asJava) - } - - override def pcalWith(implicit ctx: PCalParserContext): Parser[PlusCalWith] = - withSourceLocation { - "with" ~> ws ~> "(" ~> { - def rec(rest: Boolean)(implicit ctx: PCalParserContext): Parser[(List[PlusCalVariableDeclaration],List[PlusCalStatement])] = { - val origCtx = ctx - (if(rest) { - ws ~> (";" | ",") - } else { - ws - }) ~> pcalVarDecl.flatMap { decl => - implicit val ctx = origCtx.withDefinition(decl) - rec(true) ^^ (p => (decl :: p._1, p._2)) | (ws ~> ")" ~> ws ~> pcalStmts) ^^ ((List(decl), _)) - } - } - rec(false) - } - } ^^ { - case (loc, (decls, body)) => new PlusCalWith(loc, decls.asJava, body.asJava) - } - - def pcalCompoundStmt(implicit ctx: PCalParserContext): Parser[List[PlusCalStatement]] = - "{" ~> ws ~> rep1sep(pcalStmts, ws ~> ";" ~> ws) <~ opt(ws ~> ";") <~ ws <~ "}" ^^ (_.flatten) - - def pcalLabeledStmt(implicit ctx: PCalParserContext): Parser[PlusCalLabeledStatements] = - withSourceLocation { - withSourceLocation { - tlaIdentifier ~ (ws ~> ":" ~> ws ~> ("+" ^^^ PlusCalLabel.Modifier.PLUS | "-" ^^^ PlusCalLabel.Modifier.MINUS | success(PlusCalLabel.Modifier.NONE))) - } ~! (ws ~> (rep1sep(pcalUnlabeledStmt, ws ~> ";" ~> ws) | pcalCompoundStmt)) - } ^^ { - case (loc, (labelLoc, label ~ modifier) ~ body) => - new PlusCalLabeledStatements(loc, new PlusCalLabel(labelLoc, label, modifier), body.asJava) - } - - override def pcalStmts(implicit ctx: PCalParserContext): Parser[List[PlusCalStatement]] = - pcalUnlabeledStmt.map(List(_)) | pcalLabeledStmt.map(List(_)) | pcalCompoundStmt - - override def pcalBody(pSuffix: String)(implicit ctx: PCalParserContext): Parser[List[PlusCalStatement]] = - pcalCompoundStmt - - override def pcalProcessSelf(implicit ctx: PCalParserContext): Parser[PlusCalVariableDeclaration] = - "(" ~> ws ~> pcalVarDecl <~ ws <~ ")" - - override def pcalAlgorithmOpenBrace(implicit ctx: PCalParserContext): Parser[Unit] = - ws ~> "{" ^^^ () - - override def pcalAlgorithmCloseBrace(implicit ctx: PCalParserContext): Parser[Unit] = - ws ~> "}" ^^^ () - } - - val pcalPSyntax: PCalPSyntax = new PCalPSyntax {} - trait PCalPSyntax extends GenericSyntax { - override def pcalIf(implicit ctx: PCalParserContext): Parser[PlusCalIf] = { - lazy val elsePart: Parser[List[PlusCalStatement]] = { - val elsif = withSourceLocation { - "elsif" ~> ws ~> tlaExpression ~ (ws ~> "then" ~> ws ~> rep1sep(pcalStmt, ws)) ~ (ws ~> elsePart) - } ^^ { - case (loc, cond ~ yes ~ no) => List(new PlusCalIf(loc, cond, yes.asJava, no.asJava)) - } - val els = "else" ~> ws ~> rep1sep(pcalStmt, ws) - - elsif | els | success(Nil) - } - - withSourceLocation { - "if" ~> ws ~> tlaExpression ~ (ws ~> "then" ~> ws ~> rep1sep(pcalStmt, ws) <~ ws) ~ elsePart <~ ws <~ "end" <~ ws <~ "if" - } ^^ { - case (loc, cond ~ yes ~ no) => new PlusCalIf(loc, cond, yes.asJava, no.asJava) - } - } - - override def pcalWhile(implicit ctx: PCalParserContext): Parser[PlusCalWhile] = - withSourceLocation { - "while" ~> ws ~> tlaExpression ~ (ws ~> "do" ~> ws ~> rep1sep(pcalStmt, ws) <~ ws <~ "end" <~ ws <~ "while") - } ^^ { - case (loc, cond ~ body) => new PlusCalWhile(loc, cond, body.asJava) - } - - override def pcalEither(implicit ctx: PCalParserContext): Parser[PlusCalEither] = - withSourceLocation { - "either" ~> ws ~> rep1sep(rep1sep(pcalStmt, ws), ws ~> "or" ~> ws) <~ ws <~ "end" <~ ws <~ "either" - } ^^ { - case (loc, parts) => new PlusCalEither(loc, parts.map(_.asJava).asJava) - } - - override def pcalWith(implicit ctx: PCalParserContext): Parser[PlusCalWith] = - withSourceLocation { - "with" ~> { - def rec(rest: Boolean)(implicit ctx: PCalParserContext): Parser[(List[PlusCalVariableDeclaration], List[PlusCalStatement])] = { - val origCtx = ctx - (if (rest) { - ws ~> (";" | ",") ~> ws - } else { - ws - }) ~> pcalVarDecl.flatMap { decl => - implicit val ctx = origCtx.withDefinition(decl) - rec(true) ^^ (p => (decl :: p._1, p._2)) | - (opt(ws ~> (";" | ",")) ~> ws ~> "do" ~> ws ~> rep1sep(pcalStmt, ws) <~ ws <~ "end" <~ ws <~ "with") ^^ ((List(decl), _)) - } - } - rec(false) - } - } ^^ { - case (loc, (decls, body)) => new PlusCalWith(loc, decls.asJava, body.asJava) - } - - def pcalStmt(implicit ctx: PCalParserContext): Parser[PlusCalStatement] = { - val labeledStmts: Parser[PlusCalLabeledStatements] = - withSourceLocation { - withSourceLocation { - tlaIdentifier ~ (ws ~> ":" ~> ws ~> ("+" ^^^ PlusCalLabel.Modifier.PLUS | "-" ^^^ PlusCalLabel.Modifier.MINUS | success(PlusCalLabel.Modifier.NONE))) - } ~! (ws ~> rep1sep(pcalUnlabeledStmt, ws ~> ";" ~> ws) <~ ws <~ ";") - } ^^ { - case (loc, (labelLoc, label ~ mod) ~ stmts) => - new PlusCalLabeledStatements(loc, new PlusCalLabel(labelLoc, label, mod), stmts.asJava) - } - - (pcalUnlabeledStmt <~ ws <~ ";") | labeledStmts - } - - override def pcalStmts(implicit ctx: PCalParserContext): Parser[List[PlusCalStatement]] = rep1sep(pcalStmt, ws) - - override def pcalBody(pSuffix: String)(implicit ctx: PCalParserContext): Parser[List[PlusCalStatement]] = - "begin" ~> ws ~> pcalStmts <~ ws <~ "end" <~ ws <~ pSuffix - - override def pcalProcessSelf(implicit ctx: PCalParserContext): Parser[PlusCalVariableDeclaration] = pcalVarDecl - - override def pcalAlgorithmOpenBrace(implicit ctx: PCalParserContext): Parser[Unit] = not(ws ~> "{") - - override def pcalAlgorithmCloseBrace(implicit ctx: PCalParserContext): Parser[Unit] = success(()) - } - - def pcalAlgorithm(implicit ctx: PCalParserContext): Parser[PlusCalAlgorithm] = - pcalPSyntax.pcalAlgorithm | pcalCSyntax.pcalAlgorithm -} - -object PlusCalParser extends PlusCalParser with ParsingUtils { - def readAlgorithm(path: java.nio.file.Path, contents: CharSequence, tlaModule: TLAModule): PlusCalAlgorithm = { - implicit val tlaCtx = TLAUtils.fillContextFromModule( - TLABuiltinModules.Intrinsics.members.foldLeft(TLAParserContext())(_.withDefinition(_)), - tlaModule, captureLocal = true) - implicit val ctx = PCalParserContext() - checkResult(phrase(findInComment("fair" | "algorithm", pcalAlgorithm))(buildReader(path, contents))) - } -} diff --git a/src/pgo/parser/TLAParser.scala b/src/pgo/parser/TLAParser.scala index 45be39437..ed79f2957 100644 --- a/src/pgo/parser/TLAParser.scala +++ b/src/pgo/parser/TLAParser.scala @@ -1,80 +1,19 @@ package pgo.parser +import pgo.model.{Definition, DefinitionOne, SourceLocatable, SourceLocation, SourceLocationWithUnderlying} import pgo.model.tla._ -import pgo.util.SourceLocation +import pgo.util.Description +import Description._ -import scala.annotation.tailrec import scala.collection.mutable -import scala.jdk.CollectionConverters._ import scala.util.parsing.combinator.RegexParsers -import scala.util.parsing.input.Reader -final case class TLAParserContext(minColumn: Int = -1, - lateBindingStack: List[mutable.Map[TLAIdentifier,mutable.Buffer[TLADefinitionOne=>Unit]]] = Nil, - currentScope: Map[TLAIdentifier,TLADefinitionOne] = Map.empty) { - def withMinColumn(minColumn: Int): TLAParserContext = - copy(minColumn=minColumn) - - def withDefinition(defn: TLADefinition): TLAParserContext = - defn match { - case builtin: TLABuiltinModules.TLABuiltinOperator => // special case: builtins have aliases that refer to the same op - copy(currentScope=builtin.aliasIDs.foldLeft(currentScope.updated(builtin.identifier, builtin)) { (currentScope, id) => - currentScope.updated(id, builtin) - }) - case defn: TLADefinitionOne => copy(currentScope=currentScope.updated(defn.identifier, defn)) - case composite: TLADefinitionComposite => composite.members.foldLeft(this)(_.withDefinition(_)) - } - - def withSelf(loc: SourceLocation, defn: TLADefinitionOne): TLAParserContext = - copy(currentScope=currentScope.updated(new TLAIdentifier(loc, "self"), defn)) - - def withLateBinding: TLAParserContext = - copy(lateBindingStack=mutable.Map.empty[TLAIdentifier,mutable.Buffer[TLADefinitionOne=>Unit]] :: lateBindingStack) - - def lookupModuleExtends(id: TLAIdentifier): TLAModuleExtends = - currentScope.get(id) match { - case Some(defn: TLAModule) => TLAModuleExtendsModule(defn) - case Some(defn) => throw DoesNotExtendAModuleError(id.getLocation, id, defn) - case None => TLABuiltinModules.builtinModules.get(id) match { - case Some(builtin) => TLAModuleExtendsBuiltin(builtin) - case None => throw ModuleNotFoundError(id.getLocation, id) - } - } - - def instantiateModule(id: TLAIdentifier): TLAParserContext = { - currentScope.get(id) match { - case Some(defn: TLAModule) => ??? - case _ => ??? - } - } - - def lookupDefinition(path: List[TLAIdentifier]): Option[TLADefinitionOne] = { - path match { - case Nil => None - case List(id) => currentScope.get(id) - case id :: tl => - currentScope.get(id).flatMap(lookupDefinition(_, tl)) - } - } - - @tailrec - private def lookupDefinition(defn: TLADefinitionOne, path: List[TLAIdentifier]): Option[TLADefinitionOne] = - path match { - case Nil => None - case List(id) => defn.scope.get(id) - case hd :: tl => - defn.scope.get(hd) match { - case None => None - case Some(defn) => lookupDefinition(defn, tl) - } - } -} trait TLAParser extends RegexParsers { override def skipWhitespace: Boolean = false val anything: Parser[Unit] = accept("anything", { case _ => () }) - def checkMinColumn(implicit ctx : TLAParserContext) : Parser[Unit] = (in: Reader[Char]) => { + def checkMinColumn(implicit ctx : TLAParserContext) : Parser[Unit] = { in => val lcIn = in.asInstanceOf[LineColumnAwareCharReader] if (lcIn.column < ctx.minColumn) { Failure(s"insufficient indentation ${lcIn.column}, expected at least ${ctx.minColumn}", in) @@ -83,24 +22,40 @@ trait TLAParser extends RegexParsers { } } - def withSourceLocation[T](p : =>Parser[T]) : Parser[(SourceLocation, T)] = { - lazy val pp = p // ensure p is evaluated at-most-once - (in: Reader[Char]) => { + def querySourceLocation[T](p: Parser[T]): Parser[(SourceLocation,T)] = { + final case class GetSourceLocation[T](value: T) extends SourceLocatable + withSourceLocation(p.map(GetSourceLocation(_))).map { + case getter @GetSourceLocation(value) => + (getter.sourceLocation, value) + } + } + + def withSourceLocation[T <: SourceLocatable](p: =>Parser[T]): Parser[T] = { + lazy val pp: Parser[T] = p // ensure p is evaluated at-most-once + (in: Input) => { val lcIn = in.asInstanceOf[LineColumnAwareCharReader] - pp.apply(in).flatMapWithNext { t => in: Reader[Char] => - val lcNextIn = in.asInstanceOf[LineColumnAwareCharReader] + pp(in).flatMapWithNext[T]((t: T) => (nextIn: Input) => { + val lcNextIn = nextIn.asInstanceOf[LineColumnAwareCharReader] Success( - (new SourceLocation(lcIn.path, lcIn.offset, lcNextIn.offset, lcIn.line, lcNextIn.line, lcIn.column, lcNextIn.column), t), - in) - } + t.setSourceLocation(SourceLocation(lcIn.underlyingText, startOffset = lcIn.offset, endOffset = lcNextIn.offset, + startLine = lcIn.line, endLine = lcNextIn.line, startColumn = lcIn.column, endColumn = lcNextIn.column)), + nextIn) + }) + } + } + + implicit class SymbolParser(sym: TLASymbol.Symbol) extends Parser[TLASymbol] { + private lazy val underlying = withSourceLocation { + sym.representations.foldRight(failure(s"expected $sym"): Parser[String])(_ | _) ^^ (_ => TLASymbol(sym)) } + override def apply(in: Input): ParseResult[TLASymbol] = underlying(in) } val tlaLineComment : Parser[Unit] = ("\\*" ~ rep(acceptIf(_ != '\n')(c => s"'$c' was a new line"))) ^^^ () val tlaMultilineComment : Parser[Unit] = { - val body = rep1(not("(*" | "*)" | "\\*") ~> acceptIf(_ => true)(_ => ???)) + val body = rep1(not("(*" | "*)" | "\\*") ~> anything) ("(*" ~ rep { tlaMultilineComment | tlaLineComment | body } ~ "*)") ^^^ () @@ -129,24 +84,22 @@ trait TLAParser extends RegexParsers { } ^^ { parts => parts.mkString("") }) <~ elem('\"') val tlaIdentifierExpr: Parser[TLAIdentifier] = - withSourceLocation(tlaIdentifier) ^^ { - case (loc, id) => new TLAIdentifier(loc, id) - } + withSourceLocation(tlaIdentifier ^^ TLAIdentifier) val tlaStringExpr : Parser[TLAString] = - withSourceLocation(tlaString) ^^ { - case (loc, str) => new TLAString(loc, str) - } + withSourceLocation(tlaString ^^ TLAString) val tlaNumberExpr: Parser[TLANumber] = withSourceLocation { - regex(raw"\d+".r) ^^ ((_, TLANumber.Base.DECIMAL)) | - regex(raw"\d*\.\d+".r) ^^ ((_, TLANumber.Base.DECIMAL)) | - regex(raw"\\[bB][01]+".r) ^^ ((_, TLANumber.Base.BINARY)) | - regex(raw"\\[oO][0-7]+".r) ^^ ((_, TLANumber.Base.OCTAL)) | - regex(raw"\\[hH][0-9a-fA-F]+".r) ^^ ((_, TLANumber.Base.HEXADECIMAL)) - } ^^ { - case (loc, (str, base)) => new TLANumber(loc, str, base) + { + regex(raw"\d+".r) ^^ { str => (TLANumber.IntValue(BigInt(str)), TLANumber.DecimalSyntax) } | + regex(raw"\d*\.\d+".r) ^^ { str => (TLANumber.DecimalValue(BigDecimal(str)), TLANumber.DecimalSyntax) } | + regex(raw"\\[bB][01]+".r) ^^ { str => (TLANumber.IntValue(BigInt(str.stripPrefix("b").stripPrefix("B"), 2)), TLANumber.BinarySyntax) } | + regex(raw"\\[oO][0-7]+".r) ^^ { str => (TLANumber.IntValue(BigInt(str.stripPrefix("o").stripPrefix("O"), 8)), TLANumber.OctalSyntax) } | + regex(raw"\\[hH][0-9a-fA-F]+".r) ^^ { str => (TLANumber.IntValue(BigInt(str.stripPrefix("h").stripPrefix("H"), 16)), TLANumber.HexadecimalSyntax) } + } ^^ { + case (value, syntax) => TLANumber(value, syntax) + } } def tlaCommaSep[T](p: =>Parser[T])(implicit ctx: TLAParserContext): Parser[List[T]] = @@ -157,129 +110,131 @@ trait TLAParser extends RegexParsers { def tlaIdentifierOrTupleQuantifierBound(implicit ctx: TLAParserContext): Parser[TLAQuantifierBound] = { val idOrTuple: Parser[Either[List[TLAIdentifier],TLAIdentifier]] = - "<<" ~> wsChk ~> tlaCommaSep(tlaIdentifierExpr) <~ wsChk <~ ">>" ^^ ((Left(_))) | tlaIdentifierExpr ^^ ((Right(_))) - withSourceLocation(idOrTuple ~ (wsChk ~> "\\in" ~> wsChk ~> tlaExpression)) ^^ { - case (loc, Left(ids) ~ set) => new TLAQuantifierBound(loc, TLAQuantifierBound.Type.TUPLE, ids, set) - case (loc, Right(id) ~ set) => new TLAQuantifierBound(loc, TLAQuantifierBound.Type.IDS, List(id), set) + "<<" ~> wsChk ~> tlaCommaSep(tlaIdentifierExpr) <~ wsChk <~ ">>" ^^ (Left(_)) | tlaIdentifierExpr ^^ (Right(_)) + withSourceLocation { + idOrTuple ~ (wsChk ~> "\\in" ~> wsChk ~> tlaExpression) ^^ { + case Left(ids) ~ set => TLAQuantifierBound(TLAQuantifierBound.TupleType, ids.map(_.toDefiningIdentifier), set) + case Right(id) ~ set => TLAQuantifierBound(TLAQuantifierBound.IdsType, List(id.toDefiningIdentifier), set) + } } } - def tlaQuantifierBound(implicit ctx: TLAParserContext): Parser[TLAQuantifierBound] = { - withSourceLocation(("<<" ~> wsChk ~> tlaCommaSep(tlaIdentifierExpr) <~ wsChk <~ ">>" <~ wsChk <~ "\\in") ~ (wsChk ~> tlaExpression)) ^^ { - case (loc, ids ~ set) => new TLAQuantifierBound(loc, TLAQuantifierBound.Type.TUPLE, ids, set) - } | - withSourceLocation((tlaComma1Sep(tlaIdentifierExpr) <~ wsChk <~ "\\in") ~ (wsChk ~> tlaExpression)) ^^ { - case (loc, ids ~ set) => new TLAQuantifierBound(loc, TLAQuantifierBound.Type.IDS, ids, set) - } - } + def tlaQuantifierBound(implicit ctx: TLAParserContext): Parser[TLAQuantifierBound] = + withSourceLocation { + (("<<" ~> wsChk ~> tlaCommaSep(tlaIdentifierExpr) <~ wsChk <~ ">>" <~ wsChk <~ "\\in") ~ (wsChk ~> tlaExpression)) ^^ { + case ids ~ set => TLAQuantifierBound(TLAQuantifierBound.TupleType, ids.map(_.toDefiningIdentifier), set) + } | + ((tlaComma1Sep(tlaIdentifierExpr) <~ wsChk <~ "\\in") ~ (wsChk ~> tlaExpression)) ^^ { + case ids ~ set => TLAQuantifierBound(TLAQuantifierBound.IdsType, ids.map(_.toDefiningIdentifier), set) + } + } def tlaInstancePrefix(implicit ctx: TLAParserContext): Parser[List[TLAGeneralIdentifierPart]] = { - def impl(pfx: List[TLAGeneralIdentifierPart]): Parser[List[TLAGeneralIdentifierPart]] = + final case class PrefixPart(part: TLAGeneralIdentifierPart, defn: DefinitionOne) extends SourceLocatable { + override def setSourceLocation(sourceLocation: SourceLocation): this.type = { + part.setSourceLocation(sourceLocation) + super.setSourceLocation(sourceLocation) + } + } + + def impl(pfx: List[TLAGeneralIdentifierPart]): Parser[List[TLAGeneralIdentifierPart]] = { withSourceLocation { - withSourceLocation(tlaIdentifierExpr).flatMap { - case (loc, id) => - ctx.lookupDefinition(pfx.map(_.getIdentifier) :+ id) match { - case None => - failure(s"lookup failed for identifier ${pfx.map(_.getIdentifier).mkString("!")}!$id") - case Some(defn) => - if(defn.arity == 0) { - wsChk ~> "!" ^^^ (id, Nil, defn) - } else { - wsChk ~> "(" ~> wsChk ~> tlaComma1Sep(tlaExpression) <~ wsChk <~ ")" <~ wsChk <~ "!" ^^ ((id, _, defn)) + tlaIdentifierExpr.flatMap { id => + ctx.lookupDefinition(pfx.map(id => Definition.ScopeIdentifierName(id.id)) :+ Definition.ScopeIdentifierName(id)) match { + case None => + failure(s"lookup failed for identifier ${pfx.map(_.id.id).mkString("!")}!$id") + case Some(defn) => + if (defn.arity == 0) { + wsChk ~> "!" ^^^ PrefixPart(TLAGeneralIdentifierPart(id, Nil), defn) + } else { + wsChk ~> "(" ~> wsChk ~> tlaComma1Sep(tlaExpression) <~ wsChk <~ ")" <~ wsChk <~ "!" ^^ { args => + PrefixPart(TLAGeneralIdentifierPart(id, args), defn) } - } + } + } } }.flatMap { - case (loc, (id, params, defn)) => + case PrefixPart(idPart, defn) => if(!defn.isModuleInstance) { - throw KindMismatchError(loc) + throw KindMismatchError(idPart.sourceLocation, d"expected module instance, found operator or variable") } - if(params.length != defn.arity) { - throw ArityMismatchError(loc, defn, params.length) + if(idPart.parameters.length != defn.arity) { + throw ArityMismatchError(idPart.sourceLocation, defn, idPart.parameters.length) } - val part = new TLAGeneralIdentifierPart(loc, id, params.asJava) - val path = pfx :+ part + val path = pfx :+ idPart opt(wsChk ~> impl(path)) ^^ (_.getOrElse(path)) } + } + (impl(Nil) | success(Nil)).withFailureMessage("expected instance prefix") } def tlaTupleExpr(implicit ctx: TLAParserContext): Parser[TLATuple] = withSourceLocation { - "<<" ~> wsChk ~> tlaCommaSep(tlaExpression) <~ wsChk <~ ">>" - } ^^ { - case (loc, exprs) => new TLATuple(loc, exprs.asJava) + "<<" ~> wsChk ~> tlaCommaSep(tlaExpression) <~ wsChk <~ ">>" ^^ TLATuple } def tlaRequiredActionExpr(implicit ctx: TLAParserContext): Parser[TLARequiredAction] = withSourceLocation { - ("<<" ~> wsChk ~> tlaExpression <~ wsChk <~ ">>_") ~! (wsChk ~> tlaExpression) - } ^^ { - case (loc, body ~ vars) => new TLARequiredAction(loc, body, vars) + ("<<" ~> wsChk ~> tlaExpression <~ wsChk <~ ">>_") ~! (wsChk ~> tlaExpression) ^^ { + case body ~ vars => TLARequiredAction(body, vars) + } } def tlaOperatorCallOrGeneralIdentifier(implicit ctx: TLAParserContext): Parser[TLAExpression] = withSourceLocation { - withSourceLocation(tlaInstancePrefix ~ (wsChk ~> tlaIdentifierExpr)).flatMap { - case (loc, pfx ~ id) => - ctx.lookupDefinition(pfx.map(_.getIdentifier) :+ id) match { + (tlaInstancePrefix ~ (wsChk ~> tlaIdentifierExpr)).flatMap { + case pfx ~ id => + val name = Definition.ScopeIdentifierName(id) + ctx.lookupDefinition(pfx.map(id => Definition.ScopeIdentifierName(id.id)) :+ name) match { case None => ctx.lateBindingStack match { case lateBindings :: _ if pfx.isEmpty => // if the context allows late bindings (i.e names bound to the right) // then assume arity == 0 and defer setRefersTo below - success((pfx, id, Right(lateBindings), Nil)) + val ref = TLAGeneralIdentifier(id, Nil) + lateBindings.getOrElseUpdate(id, mutable.ArrayBuffer()) += ref.setRefersTo + success(ref) case _ => - throw DefinitionLookupError(loc, pfx, id) + throw DefinitionLookupError(pfx, Definition.ScopeIdentifierName(id)) } case Some(defn) => if( defn.arity > 0 ) { - (wsChk ~> "(" ~> wsChk ~> repsep(tlaExpression, wsChk ~> "," <~ wsChk) <~ wsChk <~ ")") ^^ - ((pfx, id, Left(defn), _)) + (wsChk ~> "(" ~> wsChk ~> repsep(tlaExpression, wsChk ~> "," <~ wsChk) <~ wsChk <~ ")") ^^ { args => + if(defn.arity != args.size) { + throw ArityMismatchError(id.sourceLocation, defn, args.size) + } + TLAOperatorCall(name, pfx, args).setRefersTo(defn) + } } else { - success((pfx, id, Left(defn), Nil)) + if(defn.arity != 0) { + throw ArityMismatchError(id.sourceLocation, defn, 0) + } + success(TLAGeneralIdentifier(id, pfx).setRefersTo(defn)) } } } - } ^^ { - case (loc, (Nil, name, Right(lateBindings), Nil)) => - val ref = new TLAGeneralIdentifier(loc, name, Nil) - lateBindings.getOrElseUpdate(name, mutable.ArrayBuffer.empty) += ref.setRefersTo - ref - case (loc, (pfx, name, Left(defn), params)) => - if( defn.arity != params.length) { - throw ArityMismatchError(loc, defn, params.size) - } - if(params.isEmpty) { - val ref = new TLAGeneralIdentifier(loc, name, pfx) - ref.setRefersTo(defn) - ref - } else { - val ref = new TLAOperatorCall(loc, name, pfx.asJava, params.asJava) - ref.setRefersTo(defn) - ref - } } def tlaConjunctOrDisjunct(which: String)(implicit ctx: TLAParserContext): Parser[TLAExpression] = { val origCtx = ctx - guard(withSourceLocation(which)).flatMap { - case (loc, _) => - val lCtx = origCtx.withMinColumn(loc.getStartColumn) - val rCtx = origCtx.withMinColumn(loc.getStartColumn + 1) - implicit val ctx = rCtx + guard(querySourceLocation(which)).flatMap { + case (loc: SourceLocationWithUnderlying @unchecked, _) => + val lCtx = origCtx.withMinColumn(loc.startColumn) + val rCtx = origCtx.withMinColumn(loc.startColumn + 1) + implicit val ctx: TLAParserContext = rCtx rep1({ - implicit val ctx = lCtx - wsChk ~> withSourceLocation(which) + implicit val ctx: TLAParserContext = lCtx + wsChk ~> querySourceLocation(which) } ~ (wsChk ~> tlaExpression)) ^^ { parts => val (_, resultExpr) = parts.tail.foldLeft((parts.head._1._1, parts.head._2)) { (acc, part) => val (locationAcc, lhs) = acc val (symLoc, _) ~ rhs = part - val combinedLoc = locationAcc.combine(rhs.getLocation) - val sym = new TLASymbol(symLoc, which) - val binop = new TLABinOp(combinedLoc, sym, Nil.asJava, lhs, rhs) + val combinedLoc = locationAcc ++ rhs.sourceLocation + val sym = TLASymbol(TLASymbol.forString(which)).setSourceLocation(symLoc) + val binop = TLABinOp(sym, Nil, lhs, rhs).setSourceLocation(combinedLoc) // should always succeed, /\ and \/ are built-in - binop.setRefersTo(ctx.lookupDefinition(List(sym.getIdentifier)).get) + binop.setRefersTo(ctx.lookupDefinition(List(Definition.ScopeIdentifierSymbol(sym))).get) (combinedLoc, binop) } resultExpr @@ -293,37 +248,41 @@ trait TLAParser extends RegexParsers { def tlaDisjunctExpr(implicit ctx: TLAParserContext): Parser[TLAExpression] = tlaConjunctOrDisjunct("\\/") - def tlaIfExpr(implicit ctx: TLAParserContext): Parser[TLAIf] = { + def tlaIfExpr(implicit ctx: TLAParserContext): Parser[TLAIf] = withSourceLocation { ("IF" ~>! wsChk ~> tlaExpression) ~ (wsChk ~> "THEN" ~>! wsChk ~> tlaExpression) ~ - (wsChk ~> "ELSE" ~>! wsChk ~> tlaExpression) - } ^^ { - case (loc, cond ~ yes ~ no) => new TLAIf(loc, cond, yes, no) + (wsChk ~> "ELSE" ~>! wsChk ~> tlaExpression) ^^ { + case cond ~ yes ~ no => TLAIf(cond, yes, no) + } } - } def tlaCaseExpr(implicit ctx: TLAParserContext): Parser[TLACase] = withSourceLocation { - ("CASE" ~>! wsChk ~> withSourceLocation(tlaExpression ~ (wsChk ~> "->" ~> wsChk ~> tlaExpression ))) ~ - (wsChk ~> repsep(withSourceLocation("[]" ~> wsChk ~> tlaExpression ~ (wsChk ~> "->" ~> wsChk ~> tlaExpression)), wsChk)) ~ - opt(wsChk ~> "[]" ~> wsChk ~> "OTHER" ~>! wsChk ~> "->" ~> wsChk ~> tlaExpression) - } ^^ { - case (loc, (loc1, cond1 ~ res1) ~ arms ~ other) => - new TLACase( - loc, - (new TLACaseArm(loc1, cond1, res1) :: arms.map { case (loc, cond ~ res) => new TLACaseArm(loc, cond, res) }).asJava, - other.orNull) + locally { + withSourceLocation { + "CASE" ~>! wsChk ~> tlaExpression ~ (wsChk ~> "->" ~> wsChk ~> tlaExpression) ^^ { + case cond1 ~ res1 => TLACaseArm(cond1, res1) + } + } ~ + (wsChk ~> repsep(withSourceLocation("[]" ~> wsChk ~> tlaExpression ~ (wsChk ~> "->" ~> wsChk ~> tlaExpression) ^^ { + case cond ~ res => TLACaseArm(cond, res) + }), wsChk)) ~ + opt(wsChk ~> "[]" ~> wsChk ~> "OTHER" ~>! wsChk ~> "->" ~> wsChk ~> tlaExpression) + } ^^ { + case arm1 ~ arms ~ other => + TLACase(arm1 :: arms, other) + } } def tlaFunctionExpr(implicit ctx: TLAParserContext): Parser[TLAFunction] = { val origCtx = ctx withSourceLocation { ("[" ~> wsChk ~> tlaComma1Sep(tlaQuantifierBound) <~ wsChk <~ "|->" <~! wsChk).flatMap { bounds => - implicit val ctx = bounds.foldLeft(origCtx)(_.withDefinition(_)) + implicit val ctx: TLAParserContext = bounds.foldLeft(origCtx)(_.withDefinition(_)) (tlaExpression <~ wsChk <~ "]") ^^ ((bounds, _)) + } ^^ { + case (qbs, expr) => TLAFunction(qbs, expr) } - } ^^ { - case (loc, (qbs, expr)) => new TLAFunction(loc, qbs.asJava, expr) } } @@ -331,38 +290,36 @@ trait TLAParser extends RegexParsers { withSourceLocation { "[" ~> wsChk ~> tlaComma1Sep { withSourceLocation { - tlaIdentifierExpr ~ (wsChk ~> ":" ~>! wsChk ~> tlaExpression) - } ^^ { case (loc, name ~ set) => new TLARecordSet.Field(loc, name, set) } - } <~ wsChk <~ "]" - } ^^ { - case (loc, fields) => new TLARecordSet(loc, fields.asJava) + tlaIdentifierExpr ~ (wsChk ~> ":" ~>! wsChk ~> tlaExpression) ^^ { + case name ~ set => TLARecordSetField(name, set) + } + } + } <~ wsChk <~ "]" ^^ TLARecordSet } def tlaRecordConstructorExpr(implicit ctx: TLAParserContext): Parser[TLARecordConstructor] = withSourceLocation { "[" ~> wsChk ~> tlaComma1Sep { withSourceLocation { - tlaIdentifierExpr ~ (wsChk ~> "|->" ~>! wsChk ~> tlaExpression) - } ^^ { - case (loc, label ~ value) => new TLARecordConstructor.Field(loc, label, value) + tlaIdentifierExpr ~ (wsChk ~> "|->" ~>! wsChk ~> tlaExpression) ^^ { + case label ~ value => TLARecordConstructorField(label, value) + } } - } <~ wsChk <~ "]" - } ^^ { - case (loc, fields) => new TLARecordConstructor(loc, fields.asJava) + } <~ wsChk <~ "]" ^^ TLARecordConstructor } def tlaFunctionSetExpr(implicit ctx: TLAParserContext): Parser[TLAFunctionSet] = withSourceLocation { - "[" ~> wsChk ~> tlaExpression ~ (wsChk ~> "->" ~>! wsChk ~> tlaExpression <~ wsChk <~ "]") - } ^^ { - case (loc, from ~ to) => new TLAFunctionSet(loc, from, to) + "[" ~> wsChk ~> tlaExpression ~ (wsChk ~> "->" ~>! wsChk ~> tlaExpression <~ wsChk <~ "]") ^^ { + case from ~ to => TLAFunctionSet(from, to) + } } def tlaMaybeActionExpr(implicit ctx: TLAParserContext): Parser[TLAMaybeAction] = withSourceLocation { - "[" ~> wsChk ~> tlaExpression ~ (wsChk ~> "]_" ~>! wsChk ~> tlaExpression) - } ^^ { - case (loc, body ~ vars) => new TLAMaybeAction(loc, body, vars) + "[" ~> wsChk ~> tlaExpression ~ (wsChk ~> "]_" ~>! wsChk ~> tlaExpression) ^^ { + case body ~ vars => TLAMaybeAction(body, vars) + } } def tlaFunctionSubstitutionExpr(implicit ctx: TLAParserContext): Parser[TLAFunctionSubstitution] = @@ -371,30 +328,32 @@ trait TLAParser extends RegexParsers { withSourceLocation { "!" ~>! rep1 { wsChk ~> ( - withSourceLocation("." ~> wsChk ~> tlaIdentifierExpr) ^^ { - case (loc, id) => new TLASubstitutionKey(loc, List(new TLAString(loc, id.getId): TLAExpression).asJava) + withSourceLocation { + "." ~> wsChk ~> tlaIdentifierExpr ^^ { id: TLAIdentifier => + TLAFunctionSubstitutionKey(List(TLAString(id.id).setSourceLocation(id.sourceLocation))) + } } | - withSourceLocation("[" ~> wsChk ~> tlaComma1Sep(tlaExpression) <~ wsChk <~ "]") ^^ { - case (loc, idxs) => new TLASubstitutionKey(loc, idxs.asJava) + withSourceLocation { + "[" ~> wsChk ~> tlaComma1Sep(tlaExpression) <~ wsChk <~ "]" ^^ TLAFunctionSubstitutionKey }) - } ~ (wsChk ~> "=" ~> wsChk ~> tlaExpression) - } ^^ { - case (loc, path ~ value) => new TLAFunctionSubstitutionPair(loc, path.asJava, value) + } ~ (wsChk ~> "=" ~> wsChk ~> tlaExpression) ^^ { + case path ~ value => TLAFunctionSubstitutionPair(path, value) + } } - } <~ wsChk <~ "]") - } ^^ { - case (loc, fn ~ pairs) => new TLAFunctionSubstitution(loc, fn, pairs.asJava) + } <~ wsChk <~ "]") ^^ { + case fn ~ pairs => TLAFunctionSubstitution(fn, pairs) + } } def tlaQuantifiedExistentialExpr(implicit ctx: TLAParserContext): Parser[TLAQuantifiedExistential] = { val origCtx = ctx withSourceLocation { ("\\E" ~> wsChk ~> tlaComma1Sep(tlaQuantifierBound)).flatMap(bounds => { - implicit val ctx = bounds.foldLeft(origCtx)(_.withDefinition(_)) + implicit val ctx: TLAParserContext = bounds.foldLeft(origCtx)(_.withDefinition(_)) (wsChk ~> ":" ~>! wsChk ~> tlaExpression) ^^ ((bounds, _)) - }) - } ^^ { - case (loc, (bounds, predicate)) => new TLAQuantifiedExistential(loc, bounds.asJava, predicate) + }) ^^ { + case (bounds, predicate) => TLAQuantifiedExistential(bounds, predicate) + } } } @@ -402,168 +361,169 @@ trait TLAParser extends RegexParsers { val origCtx = ctx withSourceLocation { ("\\A" ~> wsChk ~> tlaComma1Sep(tlaQuantifierBound)).flatMap { bounds => - implicit val ctx = bounds.foldLeft(origCtx)(_.withDefinition(_)) + implicit val ctx: TLAParserContext = bounds.foldLeft(origCtx)(_.withDefinition(_)) wsChk ~> ":" ~>! wsChk ~> tlaExpression ^^ ((bounds, _)) + } ^^ { + case (bounds, predicate) => TLAQuantifiedUniversal(bounds, predicate) } - } ^^ { - case (loc, (bounds, predicate)) => new TLAQuantifiedUniversal(loc, bounds.asJava, predicate) } } def tlaUnquantifiedExistentialExpr(implicit ctx: TLAParserContext): Parser[TLAExistential] = { val origCtx = ctx withSourceLocation { - (("\\EE" | "\\E") ~> wsChk ~> tlaComma1Sep(tlaIdentifierExpr)).flatMap { ids => - implicit val ctx = ids.foldLeft(origCtx)(_.withDefinition(_)) + (("\\EE" | "\\E") ~> wsChk ~> tlaComma1Sep(tlaIdentifierExpr)).map(_.map(_.toDefiningIdentifier)).flatMap { ids => + implicit val ctx: TLAParserContext = ids.foldLeft(origCtx)(_.withDefinition(_)) wsChk ~> ":" ~>! wsChk ~> tlaExpression ^^ ((ids, _)) + } ^^ { + case (ids, predicate) => TLAExistential(ids, predicate) } - } ^^ { - case (loc, (ids, predicate)) => new TLAExistential(loc, ids.asJava, predicate) } } def tlaUnquantifiedUniversalExpr(implicit ctx: TLAParserContext): Parser[TLAUniversal] = { val origCtx = ctx withSourceLocation { - (("\\AA" | "\\A") ~> wsChk ~> tlaComma1Sep(tlaIdentifierExpr)).flatMap { ids => - implicit val ctx = ids.foldLeft(origCtx)(_.withDefinition(_)) + (("\\AA" | "\\A") ~> wsChk ~> tlaComma1Sep(tlaIdentifierExpr)).map(_.map(_.toDefiningIdentifier)).flatMap { ids => + implicit val ctx: TLAParserContext = ids.foldLeft(origCtx)(_.withDefinition(_)) wsChk ~> ":" ~>! wsChk ~> tlaExpression ^^ ((ids, _)) + } ^^ { + case (ids, predicate) => TLAUniversal(ids, predicate) } - } ^^ { - case (loc, (ids, predicate)) => new TLAUniversal(loc, ids.asJava, predicate) } } def tlaSetConstructorExpr(implicit ctx: TLAParserContext): Parser[TLASetConstructor] = withSourceLocation { - "{" ~> wsChk ~> tlaCommaSep(tlaExpression) <~ wsChk <~ "}" - } ^^ { - case (loc, members) => new TLASetConstructor(loc, members.asJava) + "{" ~> wsChk ~> tlaCommaSep(tlaExpression) <~ wsChk <~ "}" ^^ TLASetConstructor } def tlaSetRefinementExpr(implicit ctx: TLAParserContext): Parser[TLASetRefinement] = withSourceLocation { val origCtx = ctx ("{" ~> wsChk ~> tlaIdentifierOrTupleQuantifierBound <~ wsChk <~ ":").flatMap { binding => - implicit val ctx = origCtx.withDefinition(binding) + implicit val ctx: TLAParserContext = origCtx.withDefinition(binding) (wsChk ~> tlaExpression <~ wsChk <~ "}") ^^ ((binding, _)) + } ^^ { + case (binding, whenExpr) => TLASetRefinement(binding, whenExpr) } - } ^^ { - case (loc, (binding, whenExpr)) => new TLASetRefinement(loc, binding, whenExpr) } def tlaSetComprehensionExpr(implicit ctx: TLAParserContext): Parser[TLASetComprehension] = { val origCtx = ctx withSourceLocation { ("{" ~> wsChk ~> { - implicit val ctx = origCtx.withLateBinding + implicit val ctx: TLAParserContext = origCtx.withLateBinding (tlaExpression <~ wsChk <~ ":") ^^ ((_, ctx.lateBindingStack.head)) - }) ~ (wsChk ~> tlaComma1Sep(tlaQuantifierBound) <~ wsChk <~ "}") - } ^^ { - case (loc, (expr, lateBindings) ~ bounds) => - // extract all late bindings from bounds, and match them up with any relevant elements - // of lateBindings, removing them in the process - def extractMembers(members: List[TLADefinition]): List[TLADefinitionOne] = - members.flatMap { - case defn: TLADefinitionOne => List(defn) - case defn: TLADefinitionComposite => extractMembers(defn.members) - } - val defns: List[TLADefinitionOne] = bounds.flatMap(bind => extractMembers(bind.members)) - defns.foreach { defn => - lateBindings.get(defn.identifier) match { - case Some(lateBind) => - lateBind.foreach(_(defn)) - lateBindings -= defn.identifier - case None => + }) ~ (wsChk ~> tlaComma1Sep(tlaQuantifierBound) <~ wsChk <~ "}") ^^ { + case (expr, lateBindings) ~ bounds => + // extract all late bindings from bounds, and match them up with any relevant elements + // of lateBindings, removing them in the process + val defns: List[DefinitionOne] = bounds.flatMap(bind => bind.singleDefinitions) + defns.foreach { defn => + val defnName = defn.identifier.asInstanceOf[Definition.ScopeIdentifierName].name + lateBindings.get(defnName) match { + case Some(lateBind) => + lateBind.foreach(_(defn)) + lateBindings -= defnName + case None => + } } - } - // if lateBindings is not empty after this (i.e we didn't match all the contained bindings) - // then either these should be bound even later (add to the next late bindings map in the stack) - // or we're out of possible late bindings, in which case raise an error indicating the location - // of one of the remaining identifiers (alphabetically least, for consistency) - if(lateBindings.nonEmpty) { - ctx.lateBindingStack match { - case Nil => - val id = lateBindings.keys.minBy(_.getId) - throw DefinitionLookupError(id.getLocation, Nil, id) - case outerBindings :: _ => - lateBindings.foreach { - case (key, bindings) => - outerBindings.getOrElseUpdate(key, mutable.ArrayBuffer.empty) ++= bindings - } - lateBindings.clear() + // if lateBindings is not empty after this (i.e we didn't match all the contained bindings) + // then either these should be bound even later (add to the next late bindings map in the stack) + // or we're out of possible late bindings, in which case raise an error indicating the location + // of one of the remaining identifiers (alphabetically least, for consistency) + if(lateBindings.nonEmpty) { + ctx.lateBindingStack match { + case Nil => + val id = lateBindings.keysIterator.minBy(_.id) + throw DefinitionLookupError(Nil, Definition.ScopeIdentifierName(id)) + case outerBindings :: _ => + lateBindings.foreach { + case (key, bindings) => + outerBindings.getOrElseUpdate(key, mutable.ArrayBuffer.empty) ++= bindings + } + lateBindings.clear() + } } - } - new TLASetComprehension(loc, expr, bounds.asJava) + TLASetComprehension(expr, bounds) + } } } def tlaLetExpr(implicit ctx: TLAParserContext): Parser[TLALet] = withSourceLocation { "LET" ~>! wsChk ~> { - def impl(pfx: List[TLAUnit with TLADefinition])(implicit ctx: TLAParserContext): Parser[(List[TLAUnit with TLADefinition],TLAExpression)] = { + def impl(pfx: List[TLAUnit with Definition])(implicit ctx: TLAParserContext): Parser[(List[TLAUnit with Definition],TLAExpression)] = { val origCtx = ctx - (tlaOperatorDefinition(isLocal=false) | tlaFunctionDefinition(isLocal=false) | tlaModuleDefinition(isLocal=false)).flatMap { (defn: TLAUnit with TLADefinition) => - implicit val ctx = origCtx.withDefinition(defn) + (tlaOperatorDefinition(isLocal=false) | tlaFunctionDefinition(isLocal=false) | tlaModuleDefinition(isLocal=false)).flatMap { (defn: TLAUnit with Definition) => + implicit val ctx: TLAParserContext = origCtx.withDefinition(defn) val nextPfx = pfx :+ defn wsChk ~> (impl(nextPfx) | (("IN" ~>! wsChk ~> tlaExpression) ^^ ((nextPfx, _)))) } } impl(Nil) + } ^^ { + case (units, body) => TLALet(units, body) } - } ^^ { - case (loc, (units, body)) => new TLALet(loc, units.map(u => u: TLAUnit).asJava, body) } def tlaFairnessConstraintExpr(implicit ctx: TLAParserContext): Parser[TLAFairness] = withSourceLocation { - ("WF_" ^^^ TLAFairness.Type.WEAK | "SF_" ^^^ TLAFairness.Type.STRONG) ~! + ("WF_" ^^^ TLAFairness.WeakFairness | "SF_" ^^^ TLAFairness.StrongFairness) ~! (wsChk ~> tlaExpression) ~! - (wsChk ~> "(" ~> wsChk ~>! tlaExpression <~ wsChk <~ ")") - } ^^ { - case (loc, tpe ~ vars ~ expr) => new TLAFairness(loc, tpe, vars, expr) - } - - val tlaPrefixOperator: Parser[String] = - TLAMeta.prefixOperators.keys.toList.sorted.sortWith(_.length > _.length) - .foldRight(failure("not a prefix operator"): Parser[String]) { (pfx, otherwise) => - if(pfx == "-_") { // special-case the syntactic anomaly that is "-" - "-" ^^^ "-_" | otherwise - } else { - pfx | otherwise - } + (wsChk ~> "(" ~> wsChk ~>! tlaExpression <~ wsChk <~ ")") ^^ { + case tpe ~ vars ~ expr => TLAFairness(tpe, vars, expr) } + } + + val tlaPrefixOperator: Parser[TLASymbol] = + withSourceLocation { + TLAMeta.prefixOperators.keys.toList.sorted.sortWith(_.length > _.length) + .foldRight(failure("not a prefix operator"): Parser[TLASymbol]) { (pfx, otherwise) => + if (pfx == "-_") { // special-case the syntactic anomaly that is "-" + "-" ^^^ TLASymbol(TLASymbol.forString("-_")) | otherwise + } else { + pfx ^^^ TLASymbol(TLASymbol.forString(pfx)) | otherwise + } + } + } // same as tlaPrefixOperator, but will read -. instead of just - - val tlaPrefixOperatorDef: Parser[String] = - TLAMeta.prefixOperators.keys.toList.sorted.sortWith(_.length > _.length) - .foldRight(failure("not a prefix operator"): Parser[String]) { (pfx, otherwise) => - if(pfx == "-_") { // special-case the syntactic anomaly that is "-" - "-." ^^^ "-_" | otherwise - } else { - pfx | otherwise + val tlaPrefixOperatorDef: Parser[TLASymbol] = + withSourceLocation { + TLAMeta.prefixOperators.keys.toList.sorted.sortWith(_.length > _.length) + .foldRight(failure("not a prefix operator"): Parser[TLASymbol]) { (pfx, otherwise) => + if (pfx == "-_") { // special-case the syntactic anomaly that is "-" + "-." ^^ (_ => TLASymbol(TLASymbol.forString("-_"))) | otherwise + } else { + pfx ^^ (_ => TLASymbol(TLASymbol.forString(pfx))) | otherwise + } } - } + } - private lazy val tlaInfixOperatorV: Parser[String] = + private lazy val tlaInfixOperatorV: Parser[TLASymbol] = TLAMeta.infixOperators.keys.toList.sorted.sortWith(_.length > _.length) - .foldRight(failure("not an infix operator"): Parser[String])(_ | _) - def tlaInfixOperator: Parser[String] = tlaInfixOperatorV + .foldRight(failure("not an infix operator"): Parser[TLASymbol]) { (str, otherwise) => + str ^^ (_ => TLASymbol(TLASymbol.forString(str))) | otherwise + } + def tlaInfixOperator: Parser[TLASymbol] = tlaInfixOperatorV - val tlaPostfixOperator: Parser[String] = + val tlaPostfixOperator: Parser[TLASymbol] = TLAMeta.postfixOperators.keys.toList.sorted.sortWith(_.length > _.length) - .foldRight(failure("not a postfix operator"): Parser[String])(_ | _) + .foldRight(failure("not a postfix operator"): Parser[TLASymbol]) { (str, otherwise) => + str ^^ (_ => TLASymbol(TLASymbol.forString(str))) | otherwise + } def tlaExpressionMinPrecedence(minPrecedence: Int)(implicit ctx: TLAParserContext): Parser[TLAExpression] = { - val lhsWithPrefix = withSourceLocation(tlaInstancePrefix ~ (wsChk ~> withSourceLocation(tlaPrefixOperator))).flatMap { - case (loc, pfx ~ ((symLoc, op))) => - val (lowPrec, highPrec) = TLAMeta.prefixOperators(op) - wsChk ~> withSourceLocation(tlaExpressionMinPrecedence(highPrec + 1)) ^^ { + val lhsWithPrefix = querySourceLocation(tlaInstancePrefix ~ (wsChk ~> tlaPrefixOperator)).flatMap { + case (loc, pfx ~ opSym) => + val (lowPrec, highPrec) = (opSym.symbol.precedenceLow, opSym.symbol.precedenceHigh) + wsChk ~> querySourceLocation(tlaExpressionMinPrecedence(highPrec + 1)) ^^ { case (loc2, innerExpr) => - val sym = new TLASymbol(symLoc, op) - val result = new TLAUnary(loc.combine(loc2), sym, pfx.asJava, innerExpr) - ctx.lookupDefinition(pfx.map(_.getIdentifier) :+ sym.getIdentifier) match { - case None => throw DefinitionLookupError(loc, pfx, sym.getIdentifier) + val result = TLAUnary(opSym, pfx, innerExpr).setSourceLocation(loc ++ loc2) + ctx.lookupDefinition(pfx.map(id => Definition.ScopeIdentifierName(id.id)) :+ Definition.ScopeIdentifierSymbol(opSym)) match { + case None => throw DefinitionLookupError(pfx, Definition.ScopeIdentifierSymbol(opSym)) case Some(defn) => result.setRefersTo(defn) } result @@ -576,18 +536,17 @@ trait TLAParser extends RegexParsers { success(lhs) def withPostfix(lhsLoc: SourceLocation, lhs: TLAExpression, maxPrecedence: Int): Parser[TLAExpression] = - withSourceLocation { - (wsChk ~> tlaInstancePrefix) ~ (wsChk ~> withSourceLocation(tlaPostfixOperator)) ^? { - case pfx ~ ((symLoc, op)) if TLAMeta.postfixOperators(op) >= minPrecedence => - (pfx, symLoc, op) + querySourceLocation { + (wsChk ~> tlaInstancePrefix) ~ (wsChk ~> tlaPostfixOperator) ^? { + case pfx ~ opSym if opSym.symbol.precedence >= minPrecedence => + (pfx, opSym) } }.flatMap { - case (loc, (pfx, symLoc, op)) => - val combinedLoc = lhsLoc.combine(loc) - val sym = new TLASymbol(symLoc, op) - val result = new TLAUnary(combinedLoc, sym, pfx.asJava, lhs) - ctx.lookupDefinition(pfx.map(_.getIdentifier) :+ sym.getIdentifier) match { - case None => throw DefinitionLookupError(loc, pfx, sym.getIdentifier) + case (loc, (pfx, opSym)) => + val combinedLoc = lhsLoc ++ loc + val result = TLAUnary(opSym, pfx, lhs).setSourceLocation(combinedLoc) + ctx.lookupDefinition(pfx.map(id => Definition.ScopeIdentifierName(id.id)) :+ Definition.ScopeIdentifierSymbol(opSym)) match { + case None => throw DefinitionLookupError(pfx, Definition.ScopeIdentifierSymbol(opSym)) case Some(defn) => result.setRefersTo(defn) } withPartOpt(combinedLoc, result, maxPrecedence) @@ -595,10 +554,10 @@ trait TLAParser extends RegexParsers { def withFunctionCall(lhsLoc: SourceLocation, lhs: TLAExpression, maxPrecedence: Int): Parser[TLAExpression] = if(minPrecedence <= 16) { - withSourceLocation("[" ~> wsChk ~> tlaComma1Sep(tlaExpression) <~ wsChk <~ "]").flatMap { + querySourceLocation("[" ~> wsChk ~> tlaComma1Sep(tlaExpression) <~ wsChk <~ "]").flatMap { case (loc, args) => - val combinedLoc = lhsLoc.combine(loc) - withPartOpt(combinedLoc, new TLAFunctionCall(combinedLoc, lhs, args.asJava), 15) + val combinedLoc = lhsLoc ++ loc + withPartOpt(combinedLoc, TLAFunctionCall(lhs, args).setSourceLocation(combinedLoc), 15) } } else { failure("not at precedence 16") @@ -606,12 +565,11 @@ trait TLAParser extends RegexParsers { def withDot(lhsLoc: SourceLocation, lhs: TLAExpression, maxPrecedence: Int): Parser[TLAExpression] = if(minPrecedence <= 17) { - rep1sep(withSourceLocation("." ~> wsChk ~> tlaIdentifierExpr), wsChk).flatMap { dots => - val (combinedLoc, result) = dots.foldLeft((lhsLoc, lhs)) { (acc, dot) => + rep1sep("." ~> wsChk ~> tlaIdentifierExpr, wsChk).flatMap { dots => + val (combinedLoc, result) = dots.foldLeft((lhsLoc, lhs)) { (acc, dotId) => val (lhsLoc, lhs) = acc - val (loc, id) = dot - val combinedLoc = lhsLoc.combine(loc) - (combinedLoc, new TLADot(combinedLoc, lhs, id.getId)) + val combinedLoc = lhsLoc ++ dotId.sourceLocation + (combinedLoc, TLADot(lhs, dotId).setSourceLocation(combinedLoc)) } withPartOpt(combinedLoc, result, 16) } @@ -620,32 +578,30 @@ trait TLAParser extends RegexParsers { } def withInfix(lhsLoc: SourceLocation, lhs: TLAExpression, maxPrecedence: Int): Parser[TLAExpression] = - withSourceLocation((wsChk ~> tlaInstancePrefix) ~ (wsChk ~> withSourceLocation(tlaInfixOperator)) ^? { - case pfx ~ ((symLoc, op)) if TLAMeta.infixOperators(op)._1 >= minPrecedence && TLAMeta.infixOperators(op)._2 <= maxPrecedence => - (pfx, symLoc, op) + querySourceLocation((wsChk ~> tlaInstancePrefix) ~ (wsChk ~> withSourceLocation(tlaInfixOperator)) ^? { + case pfx ~ opSym if opSym.symbol.precedenceLow >= minPrecedence && opSym.symbol.precedenceHigh <= maxPrecedence => + (pfx, opSym) }).flatMap { - case (loc, (pfx, symLoc, op)) => - val (lowPrec, highPrec, leftAssoc) = TLAMeta.infixOperators(op) - withSourceLocation(wsChk ~> tlaExpressionMinPrecedence(highPrec + 1)).flatMap { + case (loc, (pfx, opSym)) => + val (lowPrec, highPrec, leftAssoc) = (opSym.symbol.precedenceLow, opSym.symbol.precedenceHigh, opSym.symbol.isAssociative) + querySourceLocation(wsChk ~> tlaExpressionMinPrecedence(highPrec + 1)).flatMap { case (rhsLoc, rhs) => - val combinedLoc = lhsLoc.combine(loc.combine(rhsLoc)) - val sym = new TLASymbol(symLoc, op) - val result = new TLABinOp(combinedLoc, sym, pfx.asJava, lhs, rhs) - ctx.lookupDefinition(pfx.map(_.getIdentifier) :+ sym.getIdentifier) match { - case None => throw DefinitionLookupError(loc, pfx, sym.getIdentifier) + val combinedLoc = lhsLoc ++ loc ++ rhsLoc + val result = TLABinOp(opSym, pfx, lhs, rhs).setSourceLocation(combinedLoc) + ctx.lookupDefinition(pfx.map(id => Definition.ScopeIdentifierName(id.id)) :+ Definition.ScopeIdentifierSymbol(opSym)) match { + case None => throw DefinitionLookupError(pfx, Definition.ScopeIdentifierSymbol(opSym)) case Some(defn) => result.setRefersTo(defn) } if (leftAssoc) { def assoc(lhsLoc: SourceLocation, lhs: TLAExpression): Parser[TLAExpression] = - withSourceLocation { - (wsChk ~> tlaInstancePrefix) ~ (wsChk ~> withSourceLocation(op)) ~ (wsChk ~> tlaExpressionMinPrecedence(highPrec + 1)) + querySourceLocation { + (wsChk ~> tlaInstancePrefix) ~ (wsChk ~> opSym.symbol) ~ (wsChk ~> tlaExpressionMinPrecedence(highPrec + 1)) }.flatMap { - case (loc, pfx ~ ((symLoc, _)) ~ rhs) => - val combinedLoc = lhsLoc.combine(loc) - val sym = new TLASymbol(symLoc, op) - val nextLhs = new TLABinOp(combinedLoc, sym, pfx.asJava, lhs, rhs) - ctx.lookupDefinition(pfx.map(_.getIdentifier) :+ sym.getIdentifier) match { - case None => throw DefinitionLookupError(loc, pfx, sym.getIdentifier) + case (loc, pfx ~ opSym ~ rhs) => + val combinedLoc = lhsLoc ++ loc + val nextLhs = TLABinOp(opSym, pfx, lhs, rhs).setSourceLocation(combinedLoc) + ctx.lookupDefinition(pfx.map(id => Definition.ScopeIdentifierName(id.id)) :+ Definition.ScopeIdentifierSymbol(opSym)) match { + case None => throw DefinitionLookupError(pfx, Definition.ScopeIdentifierSymbol(opSym)) case Some(defn) => nextLhs.setRefersTo(defn) } assoc(combinedLoc, nextLhs) | withPartOpt(combinedLoc, nextLhs, lowPrec-1) @@ -657,13 +613,12 @@ trait TLAParser extends RegexParsers { } } - withSourceLocation(lhsWithPrefix).flatMap { case (loc, lhs) => withPartOpt(loc, lhs, 18) } + querySourceLocation(lhsWithPrefix).flatMap { case (loc, lhs) => withPartOpt(loc, lhs, 18) } } def tlaExpressionNoOperators(implicit ctx: TLAParserContext): Parser[TLAExpression] = tlaNumberExpr | tlaStringExpr | - withSourceLocation("TRUE" | "FALSE") ^^ { case (loc, str) => new TLABool(loc, str == "TRUE") } | ("(" ~>! wsChk ~> tlaExpression <~ wsChk <~ ")") | tlaTupleExpr | tlaRequiredActionExpr | @@ -685,88 +640,81 @@ trait TLAParser extends RegexParsers { def tlaExpression(implicit ctx: TLAParserContext): Parser[TLAExpression] = tlaExpressionMinPrecedence(0) - def tlaOpDecl(implicit ctx: TLAParserContext): Parser[TLAOpDecl] = { - val named = - withSourceLocation { - tlaIdentifierExpr ~ (wsChk ~> "(" ~> tlaComma1Sep("_") <~ wsChk <~ ")") - } ^^ { - case (loc, id ~ args) => TLAOpDecl.Named(loc, id, args.length) + def tlaOpDecl(implicit ctx: TLAParserContext): Parser[TLAOpDecl] = + withSourceLocation { + val named = tlaIdentifierExpr ~ (wsChk ~> "(" ~> tlaComma1Sep("_") <~ wsChk <~ ")") ^^ { + case id ~ args => TLAOpDecl.NamedVariant(id, args.length) } - val id = tlaIdentifierExpr ^^ { id => TLAOpDecl.Id(id.getLocation, id) } - val prefix = withSourceLocation(withSourceLocation(tlaPrefixOperatorDef) <~ wsChk <~ "_") ^^ { - case (loc, (opLoc, op)) => TLAOpDecl.Prefix(loc, new TLAIdentifier(opLoc, op)) - } - val infix = withSourceLocation("_" ~> wsChk ~> withSourceLocation(tlaInfixOperator) <~ wsChk <~ "_") ^^ { - case (loc, (opLoc, op)) => TLAOpDecl.Infix(loc, new TLAIdentifier(opLoc, op)) - } - val postfix = withSourceLocation("_" ~> wsChk ~> withSourceLocation(tlaPostfixOperator)) ^^ { - case (loc, (opLoc, op)) => TLAOpDecl.Postfix(loc, new TLAIdentifier(opLoc, op)) + val id = tlaIdentifierExpr ^^ (TLAOpDecl.NamedVariant(_, 0)) + val prefix = tlaPrefixOperatorDef <~ wsChk <~ "_" ^^ TLAOpDecl.SymbolVariant + val infix = "_" ~> wsChk ~> tlaInfixOperator <~ wsChk <~ "_" ^^ TLAOpDecl.SymbolVariant + val postfix = "_" ~> wsChk ~> tlaPostfixOperator ^^ TLAOpDecl.SymbolVariant + + (named | id | prefix | infix | postfix) ^^ (TLAOpDecl(_)) } - named | id | prefix | infix | postfix - } def tlaOperatorDefinition(isLocal: Boolean)(implicit ctx: TLAParserContext): Parser[TLAOperatorDefinition] = { val origCtx = ctx val prefix = withSourceLocation { - (withSourceLocation(tlaPrefixOperatorDef) ~ (wsChk ~> tlaIdentifierExpr)).flatMap { - case (opLoc, op) ~ id => - implicit val ctx = origCtx.withDefinition(id) - (wsChk ~> "==" ~> wsChk ~> tlaExpression) ^^ ((opLoc, op, id, _)) + (tlaPrefixOperatorDef ~ (wsChk ~> tlaIdentifierExpr)).flatMap { + case opSym ~ id => + val opDecl = TLAOpDecl(TLAOpDecl.NamedVariant(id, 0)).setSourceLocation(id.sourceLocation) + implicit val ctx: TLAParserContext = origCtx.withDefinition(opDecl) + (wsChk ~> "==" ~> wsChk ~> tlaExpression) ^^ ((opSym, opDecl, _)) + } ^^ { + case (opSym, opDecl, body) => + TLAOperatorDefinition(Definition.ScopeIdentifierSymbol(opSym), List(opDecl), body, isLocal) } - } ^^ { - case (loc, (opLoc, op, id, body)) => - new TLAOperatorDefinition( - loc, new TLAIdentifier(opLoc, op), List(TLAOpDecl.Id(id.getLocation, id)), body, isLocal) } val infix = withSourceLocation { - (tlaIdentifierExpr ~ (wsChk ~> withSourceLocation(tlaInfixOperator)) ~ (wsChk ~> tlaIdentifierExpr)).flatMap { - case lhsId ~ ((opLoc, op)) ~ rhsId => - implicit val ctx = origCtx.withDefinition(lhsId).withDefinition(rhsId) - (wsChk ~> "==" ~> wsChk ~> tlaExpression) ^^ ((lhsId, opLoc, op, rhsId, _)) - } - } ^^ { - case (loc, (lhsId, opLoc, op, rhsId, body)) => - new TLAOperatorDefinition( - loc, new TLAIdentifier(opLoc, op), List( - TLAOpDecl.Id(lhsId.getLocation, lhsId), TLAOpDecl.Id(rhsId.getLocation, rhsId)), - body, isLocal) + (tlaIdentifierExpr ~ (wsChk ~> tlaInfixOperator) ~ (wsChk ~> tlaIdentifierExpr)).flatMap { + case lhsId ~ opSym ~ rhsId => + val lhsOpDecl = TLAOpDecl(TLAOpDecl.NamedVariant(lhsId, 0)).setSourceLocation(lhsId.sourceLocation) + val rhsOpDecl = TLAOpDecl(TLAOpDecl.NamedVariant(rhsId, 0)).setSourceLocation(rhsId.sourceLocation) + implicit val ctx: TLAParserContext = origCtx.withDefinition(lhsOpDecl).withDefinition(rhsOpDecl) + (wsChk ~> "==" ~> wsChk ~> tlaExpression) ^^ ((lhsOpDecl, opSym, rhsOpDecl, _)) + } ^^ { + case (lhsOpDecl, opSym, rhsOpDecl, body) => + TLAOperatorDefinition(Definition.ScopeIdentifierSymbol(opSym), List(lhsOpDecl, rhsOpDecl), body, isLocal) + } } val postfix = withSourceLocation { - (tlaIdentifierExpr ~ (wsChk ~> withSourceLocation(tlaPostfixOperator))).flatMap { - case id ~ ((opLoc, op)) => - implicit val ctx = origCtx.withDefinition(id) - (wsChk ~> "==" ~> wsChk ~> tlaExpression) ^^ ((id, opLoc, op, _)) + (tlaIdentifierExpr ~ (wsChk ~> tlaPostfixOperator)).flatMap { + case id ~ opSym => + val opDecl = TLAOpDecl(TLAOpDecl.NamedVariant(id, 0)).setSourceLocation(id.sourceLocation) + implicit val ctx: TLAParserContext = origCtx.withDefinition(opDecl) + (wsChk ~> "==" ~> wsChk ~> tlaExpression) ^^ ((opDecl, opSym, _)) + } ^^ { + case (opDecl, opSym, body) => + TLAOperatorDefinition(Definition.ScopeIdentifierSymbol(opSym), List(opDecl), body, isLocal) } - } ^^ { - case (loc, (id, opLoc, op, body)) => - new TLAOperatorDefinition( - loc, new TLAIdentifier(opLoc, op), List(TLAOpDecl.Id(id.getLocation, id)), body, isLocal) } val nonfix = withSourceLocation { (tlaIdentifierExpr ~ opt(wsChk ~> "(" ~> tlaComma1Sep(tlaOpDecl) <~ wsChk <~ ")") <~ wsChk <~ "==" <~ wsChk).flatMap { case id ~ None => tlaExpression ^^ ((id, Nil, _)) case id ~ Some(opDecls) => - implicit val ctx = opDecls.foldLeft(origCtx)(_.withDefinition(_)) + implicit val ctx: TLAParserContext = opDecls.foldLeft(origCtx)(_.withDefinition(_)) tlaExpression ^^ ((id, opDecls, _)) + } ^^ { + case (id, opDecls, body) => + TLAOperatorDefinition(Definition.ScopeIdentifierName(id), opDecls, body, isLocal) } - } ^^ { - case (loc, (id, opDecls, body)) => new TLAOperatorDefinition(loc, id, opDecls, body, isLocal) } prefix | infix | postfix | nonfix } - def tlaFunctionDefinition(isLocal: Boolean)(implicit ctx: TLAParserContext): Parser[TLAFunctionDefinition] = { + def tlaFunctionDefinition(isLocal: Boolean)(implicit ctx: TLAParserContext): Parser[TLAOperatorDefinition] = { val origCtx = ctx withSourceLocation { - (tlaIdentifierExpr ~ (wsChk ~> "[" ~> wsChk ~> tlaComma1Sep(tlaQuantifierBound) <~ wsChk <~ "]" <~ wsChk <~ "==")).flatMap { - case id ~ bounds => - implicit val ctx = bounds.foldLeft(origCtx)(_.withDefinition(_)) - (wsChk ~> tlaExpression) ^^ ((id, bounds, _)) + tlaIdentifierExpr ~ withSourceLocation { + (wsChk ~> "[" ~> wsChk ~> tlaComma1Sep(tlaQuantifierBound) <~ wsChk <~ "]" <~ wsChk <~ "==").flatMap { bounds => + implicit val ctx: TLAParserContext = bounds.foldLeft(origCtx)(_.withDefinition(_)) + (wsChk ~> tlaExpression) ^^ (TLAFunction(bounds, _)) + } + } ^^ { + case id ~ function => TLAOperatorDefinition(Definition.ScopeIdentifierName(id), Nil, function, isLocal) } - } ^^ { - case (loc, (id, bounds, body)) => - new TLAFunctionDefinition(loc, id, new TLAFunction(loc, bounds.asJava, body), isLocal) } } @@ -774,30 +722,29 @@ trait TLAParser extends RegexParsers { withSourceLocation { "INSTANCE" ~> wsChk ~> tlaIdentifierExpr ~ opt(wsChk ~> "WITH" ~> tlaComma1Sep( - withSourceLocation(withSourceLocation(tlaIdentifier | tlaPrefixOperatorDef | tlaInfixOperator | tlaPostfixOperator) ~ - (wsChk ~> "<-" ~> wsChk ~> tlaExpression)))) - } ^^ { - case (loc, moduleId ~ substitutionsOpt) => - val substitutions = substitutionsOpt.getOrElse(Nil).map { - case (loc, (idLoc, id) ~ expr) => - new TLAInstance.Remapping(loc, new TLAIdentifier(idLoc, id), expr) - } - // TODO: load the module data - new TLAInstance(loc, moduleId, substitutions, isLocal) + withSourceLocation { + (tlaIdentifierExpr.map(Definition.ScopeIdentifierName) | (tlaPrefixOperatorDef | tlaInfixOperator | tlaPostfixOperator).map(Definition.ScopeIdentifierSymbol)) ~ + (wsChk ~> "<-" ~> wsChk ~> tlaExpression) ^^ { + case from ~ to => TLAInstanceRemapping(from, to) + } + })).map(_.getOrElse(Nil)) ^^ { + case moduleId ~ substitutions => + // TODO: load the module data + TLAInstance(moduleId, substitutions, isLocal) + } } - def tlaModuleDefinition(isLocal: Boolean)(implicit ctx: TLAParserContext): Parser[TLAModuleDefinition] = { + def tlaModuleDefinition(isLocal: Boolean)(implicit ctx: TLAParserContext): Parser[TLAModuleDefinition] = withSourceLocation { val origCtx = ctx (tlaIdentifierExpr ~ opt(wsChk ~> "(" ~> tlaComma1Sep(tlaOpDecl) <~ wsChk <~ ")")).flatMap { case id ~ argsOpt => - implicit val ctx = argsOpt.getOrElse(Nil).foldLeft(origCtx)(_.withDefinition(_)) + implicit val ctx: TLAParserContext = argsOpt.getOrElse(Nil).foldLeft(origCtx)(_.withDefinition(_)) (wsChk ~> "==" ~> wsChk ~> tlaInstance(isLocal)) ^^ ((id, argsOpt.getOrElse(Nil), _)) + } ^^ { + case (id, args, instance) => TLAModuleDefinition(id, args, instance, isLocal) } - } ^^ { - case (loc, (id, args, instance)) => new TLAModuleDefinition(loc, id, args, instance, isLocal) } - } def tlaModule(implicit ctx: TLAParserContext): Parser[TLAModule] = withSourceLocation { @@ -807,31 +754,31 @@ trait TLAParser extends RegexParsers { def unitRec(implicit ctx: TLAParserContext): Parser[List[TLAUnit]] = { val origCtx = ctx opt("----" ~> rep(elem('-')) ~> wsChk) ~> tlaUnit.flatMap { unit => - implicit val ctx = unit.definitions.foldLeft(origCtx)(_.withDefinition(_)) + implicit val ctx: TLAParserContext = unit.definitions.foldLeft(origCtx)(_.withDefinition(_)) (wsChk ~> unitRec ^^ (unit :: _)) | success(List(unit)) } } - val extensions = exts.getOrElse(Nil).map(origCtx.lookupModuleExtends) - implicit val ctx = extensions.foldLeft(origCtx) { (ctx, ext) => ext.members.foldLeft(ctx)(_.withDefinition(_)) } + val extensions = exts.getOrElse(Nil).map(ext => origCtx.lookupModuleExtends(Definition.ScopeIdentifierName(ext))) + implicit val ctx: TLAParserContext = extensions.foldLeft(origCtx) { (ctx, ext) => ext.singleDefinitions.foldLeft(ctx)(_.withDefinition(_)) } (unitRec | success(Nil)) ^^ ((extensions, _)) - } <~ wsChk <~ "====" <~ rep(elem('=')) - } ^^ { - case (loc, name ~ ((exts, units))) => new TLAModule(loc, name, exts, units) + } <~ wsChk <~ "====" <~ rep(elem('=')) ^^ { + case name ~ ((exts, units)) => TLAModule(name, exts, units) + } } def tlaUnit(implicit ctx: TLAParserContext): Parser[TLAUnit] = { - val variableDeclaration = withSourceLocation { - ("VARIABLES" | "VARIABLE") ~>! wsChk ~> tlaComma1Sep(tlaIdentifierExpr) - } ^^ { case (loc, vars) => new TLAVariableDeclaration(loc, vars) } - val constantDeclaration = withSourceLocation { - ("CONSTANTS" | "CONSTANT") ~>! wsChk ~> tlaComma1Sep(tlaOpDecl) - } ^^ { case (loc, decls) => new TLAConstantDeclaration(loc, decls) } - val assumption = withSourceLocation { - ("ASSUME" | "ASSUMPTION" | "AXIOM") ~>! wsChk ~> tlaExpression - } ^^ { case (loc, expr) => new TLAAssumption(loc, expr) } - val theorem = withSourceLocation { - "THEOREM" ~>! wsChk ~> tlaExpression - } ^^ { case (loc, expr) => new TLATheorem(loc, expr) } + val variableDeclaration: Parser[TLAUnit] = withSourceLocation { + ("VARIABLES" | "VARIABLE") ~>! wsChk ~> tlaComma1Sep(tlaIdentifierExpr.map(_.toDefiningIdentifier)) ^^ TLAVariableDeclaration + } + val constantDeclaration: Parser[TLAUnit] = withSourceLocation { + ("CONSTANTS" | "CONSTANT") ~>! wsChk ~> tlaComma1Sep(tlaOpDecl) ^^ TLAConstantDeclaration + } + val assumption: Parser[TLAUnit] = withSourceLocation { + ("ASSUME" | "ASSUMPTION" | "AXIOM") ~>! wsChk ~> tlaExpression ^^ TLAAssumption + } + val theorem: Parser[TLAUnit] = withSourceLocation { + "THEOREM" ~>! wsChk ~> tlaExpression ^^ TLATheorem + } ("LOCAL" ~>! wsChk ~> { tlaInstance(true) | tlaModuleDefinition(true) | tlaFunctionDefinition(true) | @@ -849,7 +796,7 @@ trait TLAParser extends RegexParsers { } val findTLAModule: Parser[Unit] = - rep(not("----") ~> accept("anything", { case _ => () })) ^^^ () + rep(not("----") ~> anything) ^^^ () def tlaModuleBeforeTranslation(implicit ctx: TLAParserContext): Parser[TLAModule] = withSourceLocation { @@ -863,37 +810,39 @@ trait TLAParser extends RegexParsers { def unitRec(implicit ctx: TLAParserContext): Parser[List[TLAUnit]] = { val origCtx = ctx opt("----" ~> rep(elem('-')) ~> wsWithoutTranslationTag) ~> tlaUnit.flatMap { unit => - implicit val ctx = unit.definitions.foldLeft(origCtx)(_.withDefinition(_)) + implicit val ctx: TLAParserContext = unit.definitions.foldLeft(origCtx)(_.withDefinition(_)) (wsWithoutTranslationTag ~> unitRec ^^ (unit :: _)) | success(List(unit)) } } - val extensions = exts.getOrElse(Nil).map(origCtx.lookupModuleExtends) - implicit val ctx = extensions.foldLeft(origCtx) { (ctx, ext) => ext.members.foldLeft(ctx)(_.withDefinition(_)) } + val extensions = exts.getOrElse(Nil).map(ext => origCtx.lookupModuleExtends(Definition.ScopeIdentifierName(ext))) + implicit val ctx: TLAParserContext = extensions.foldLeft(origCtx) { (ctx, ext) => ext.singleDefinitions.foldLeft(ctx)(_.withDefinition(_)) } (unitRec | success(Nil)) ^^ ((extensions, _)) - } <~ wsWithoutTranslationTag <~ translationTag - } ^^ { - case (loc, name ~ ((exts, units))) => new TLAModule(loc, name, exts, units) + } <~ wsWithoutTranslationTag <~ translationTag ^^ { + case name ~ ((exts, units)) => TLAModule(name, exts, units) + } } } object TLAParser extends TLAParser with ParsingUtils { - def readExpression(path: java.nio.file.Path, seq: CharSequence, definitions: Seq[TLADefinition] = Nil): TLAExpression = { - implicit val ctx = definitions.foldLeft( - TLABuiltinModules.Intrinsics.members.foldLeft(TLAParserContext())(_.withDefinition(_)))(_.withDefinition(_)) + def readExpression(underlying: SourceLocation.UnderlyingText, seq: CharSequence, definitions: Seq[Definition] = Nil): TLAExpression = { + implicit val ctx: TLAParserContext = definitions.foldLeft( + BuiltinModules.Intrinsics.members.foldLeft(TLAParserContext())(_.withDefinition(_)))(_.withDefinition(_)) checkResult { - phrase(wsChk ~> tlaExpression <~ wsChk)(buildReader(path, seq)) + phrase(wsChk ~> tlaExpression <~ wsChk)(buildReader(seq, underlying)) } } - def readModule(path: java.nio.file.Path, seq: CharSequence): TLAModule = { - implicit val ctx = TLABuiltinModules.Intrinsics.members.foldLeft(TLAParserContext())(_.withDefinition(_)) + def readModule(underlying: SourceLocation.UnderlyingText, seq: CharSequence): TLAModule = { + implicit val ctx: TLAParserContext = + BuiltinModules.Intrinsics.members.foldLeft(TLAParserContext())(_.withDefinition(_)) checkResult(phrase( - findTLAModule ~> tlaModule <~ rep(accept("anything", { case _ => () })))(buildReader(path, seq))) + findTLAModule ~> tlaModule <~ rep(accept("anything", { case _ => () })))(buildReader(seq, underlying))) } - def readModuleBeforeTranslation(path: java.nio.file.Path, seq: CharSequence): TLAModule = { - implicit val ctx = TLABuiltinModules.Intrinsics.members.foldLeft(TLAParserContext())(_.withDefinition(_)) + def readModuleBeforeTranslation(underlying: SourceLocation.UnderlyingText, seq: CharSequence): TLAModule = { + implicit val ctx: TLAParserContext = + BuiltinModules.Intrinsics.members.foldLeft(TLAParserContext())(_.withDefinition(_)) checkResult(phrase( - findTLAModule ~> tlaModuleBeforeTranslation <~ rep(accept("anything", { case _ => () })))(buildReader(path, seq))) + findTLAModule ~> tlaModuleBeforeTranslation <~ rep(accept("anything", { case _ => () })))(buildReader(seq, underlying))) } } diff --git a/src/pgo/parser/TLAParserContext.scala b/src/pgo/parser/TLAParserContext.scala new file mode 100644 index 000000000..2032d6e57 --- /dev/null +++ b/src/pgo/parser/TLAParserContext.scala @@ -0,0 +1,62 @@ +package pgo.parser + +import pgo.model.{Definition, DefinitionComposite, DefinitionOne} +import pgo.model.tla._ + +import scala.annotation.tailrec +import scala.collection.mutable + +final case class TLAParserContext(minColumn: Int = -1, + lateBindingStack: List[mutable.Map[TLAIdentifier,mutable.Buffer[DefinitionOne=>Unit]]] = Nil, + currentScope: Map[Definition.ScopeIdentifier,DefinitionOne] = Map.empty) { + def withMinColumn(minColumn: Int): TLAParserContext = + copy(minColumn=minColumn) + + def withDefinition(defn: Definition): TLAParserContext = + defn match { + case defn: DefinitionOne => + copy(currentScope=currentScope.updated(defn.identifier, defn)) + case defn: DefinitionComposite => defn.singleDefinitions.foldLeft(this)(_.withDefinition(_)) + } + + def withLateBinding: TLAParserContext = + copy(lateBindingStack=mutable.Map.empty[TLAIdentifier,mutable.Buffer[DefinitionOne=>Unit]] :: lateBindingStack) + + def lookupModuleExtends(id: Definition.ScopeIdentifierName): TLAModuleRef = + currentScope.get(id) match { + case Some(defn: TLAModule) => TLAModuleRefModule(defn).setSourceLocation(id.sourceLocation) + case Some(defn) => throw DoesNotExtendAModuleError(id, defn) + case None => BuiltinModules.builtinModules.get(id) match { + case Some(builtin) => TLAModuleRefBuiltin(builtin).setSourceLocation(id.sourceLocation) + case None => throw ModuleNotFoundError(id) + } + } + + def instantiateModule(id: Definition.ScopeIdentifierName): TLAParserContext = { + currentScope.get(id) match { + case Some(defn: TLAModule) => ??? + case _ => ??? + } + } + + def lookupDefinition(path: List[Definition.ScopeIdentifier]): Option[DefinitionOne] = { + path match { + case Nil => None + case List(id) => currentScope.get(id) + case id :: tl => + currentScope.get(id).flatMap(lookupDefinition(_, tl)) + } + } + + @tailrec + private def lookupDefinition(defn: DefinitionOne, path: List[Definition.ScopeIdentifier]): Option[DefinitionOne] = + path match { + case Nil => None + case List(id) => defn.scope.get(id) + case hd :: tl => + defn.scope.get(hd) match { + case None => None + case Some(defn) => lookupDefinition(defn, tl) + } + } +} diff --git a/src/pgo/scope/ChainMap.java b/src/pgo/scope/ChainMap.java deleted file mode 100644 index 5f8378f3e..000000000 --- a/src/pgo/scope/ChainMap.java +++ /dev/null @@ -1,104 +0,0 @@ -package pgo.scope; - -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; - -/** - * - * A map that extends another map. It is exactly like a normal map, but modifications only affect - * the local map, not the parent. - * - * @param The key used type - * @param The the value type - */ -public class ChainMap implements Map { - private final Map parent; - private final Map members; - - public ChainMap(Map parent) { - this.parent = parent; - this.members = new HashMap<>(); - } - - public Map getParent(){ - return parent; - } - - @Override - public void clear() { - members.clear(); - } - - @Override - public boolean containsKey(Object k) { - return members.containsKey(k) || parent.containsKey(k); - } - - @Override - public boolean containsValue(Object v) { - return members.containsValue(v) || parent.containsValue(v); - } - - @Override - public Set> entrySet() { - // do not overwrite members - Map result = new HashMap<>(members); - Set> parentSet = parent.entrySet(); - for(Entry e : parentSet) { - result.putIfAbsent(e.getKey(), e.getValue()); - } - return result.entrySet(); - } - - @Override - public V get(Object k) { - V result = members.get(k); - if(result == null) { - return parent.get(k); - } - return result; - } - - @Override - public boolean isEmpty() { - return members.isEmpty() && parent.isEmpty(); - } - - @Override - public Set keySet() { - Set result = members.keySet(); - - result.addAll(parent.keySet()); - return result; - } - - @Override - public V put(K k, V v) { - return members.put(k, v); - } - - @Override - public void putAll(Map arg) { - members.putAll(arg); - } - - @Override - public V remove(Object k) { - return members.remove(k); - } - - @Override - public int size() { - return keySet().size(); - } - - @Override - public Collection values() { - return entrySet().stream().map(Entry::getValue).collect(Collectors.toList()); - } - - -} diff --git a/src/pgo/scope/ChainSet.java b/src/pgo/scope/ChainSet.java deleted file mode 100644 index 837de5073..000000000 --- a/src/pgo/scope/ChainSet.java +++ /dev/null @@ -1,70 +0,0 @@ -package pgo.scope; - -import java.util.Collection; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Set; - -public class ChainSet implements Set { - - private final Set union; - - public ChainSet(Set parent) { - this.union = new HashSet<>(parent); - } - - @Override - public boolean add(T e) { - return union.add(e); - } - @Override - public boolean addAll(Collection c) { - return union.addAll(c); - } - @Override - public void clear() { - union.clear(); - } - @Override - public boolean contains(Object o) { - return union.contains(o); - } - @Override - public boolean containsAll(Collection c) { - return union.containsAll(c); - } - @Override - public boolean isEmpty() { - return union.isEmpty(); - } - @Override - public Iterator iterator() { - return union.iterator(); - } - @Override - public boolean remove(Object o) { - return union.remove(o); - } - @Override - public boolean removeAll(Collection c) { - return union.removeAll(c); - } - @Override - public boolean retainAll(Collection c) { - return union.retainAll(c); - } - @Override - public int size() { - return union.size(); - } - @Override - public Object[] toArray() { - return union.toArray(); - } - @Override - public V[] toArray(V[] a) { - return union.toArray(a); - } - - -} diff --git a/src/pgo/scope/Context.java b/src/pgo/scope/Context.java deleted file mode 100644 index e651991f2..000000000 --- a/src/pgo/scope/Context.java +++ /dev/null @@ -1,76 +0,0 @@ -package pgo.scope; - -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - -public class Context implements Map { - - Map map; - - public Context() { - this.map = new HashMap<>(); - } - - @Override - public void clear() { - map.clear(); - } - - @Override - public boolean containsKey(Object key) { - return map.containsKey(key); - } - - @Override - public boolean containsValue(Object value) { - return map.containsValue(value); - } - - @Override - public Set> entrySet() { - return map.entrySet(); - } - - @Override - public V get(Object key) { - return map.get(key); - } - - @Override - public boolean isEmpty() { - return map.isEmpty(); - } - - @Override - public Set keySet() { - return map.keySet(); - } - - @Override - public V put(UID key, V value) { - return map.put(key, value); - } - - @Override - public void putAll(Map m) { - map.putAll(m); - } - - @Override - public V remove(Object key) { - return map.remove(key); - } - - @Override - public int size() { - return map.size(); - } - - @Override - public Collection values() { - return map.values(); - } - -} diff --git a/src/pgo/scope/UID.java b/src/pgo/scope/UID.java deleted file mode 100644 index d76722db2..000000000 --- a/src/pgo/scope/UID.java +++ /dev/null @@ -1,29 +0,0 @@ -package pgo.scope; - -import pgo.util.Derived; -import pgo.util.DerivedVisitor; -import pgo.util.Origin; - -public class UID extends Derived { - @Override - public T accept(DerivedVisitor v) throws E { - return v.visit(this); - } - - @Override - public String toString() { - StringBuilder b = new StringBuilder(super.toString()); - b.append("(from "); - boolean first = true; - for(Origin o : this.getOrigins()) { - if(first) { - first = false; - }else { - b.append(", "); - } - b.append(o); - } - b.append(")"); - return b.toString(); - } -} diff --git a/src/pgo/trans/MPCalGoCodegenPass.scala b/src/pgo/trans/MPCalGoCodegenPass.scala new file mode 100644 index 000000000..ff2a6276d --- /dev/null +++ b/src/pgo/trans/MPCalGoCodegenPass.scala @@ -0,0 +1,10 @@ +package pgo.trans + +import pgo.model.PGoError +import pgo.model.mpcal.MPCalBlock +import pgo.util.Description + +object MPCalGoCodegenPass { + @throws[PGoError] + def apply(mpcalBlock: MPCalBlock, packageName: Option[String]): Description = ??? +} diff --git a/src/pgo/trans/MPCalNormalizePass.scala b/src/pgo/trans/MPCalNormalizePass.scala new file mode 100644 index 000000000..d12415da3 --- /dev/null +++ b/src/pgo/trans/MPCalNormalizePass.scala @@ -0,0 +1,77 @@ +package pgo.trans + +import pgo.model.{PGoError, Rewritable} +import pgo.model.mpcal._ +import pgo.model.pcal._ +import pgo.model.tla._ +import pgo.util.{MPCalPassUtils, NameCleaner} + +import scala.annotation.tailrec + +object MPCalNormalizePass { + @throws[PGoError] + def apply(tlaModule: TLAModule, mpcalBlock: MPCalBlock): MPCalBlock = { + // remove while loops + var block: MPCalBlock = mpcalBlock.rewrite(Rewritable.BottomUpOnceStrategy) { + case labeledStmts @PCalLabeledStatements(label, (whileStmt @PCalWhile(condition, body)) :: restStmts) => + PCalLabeledStatements( + label, + PCalIf( + condition, + body :+ PCalGoto(label.name).setSourceLocation(whileStmt.sourceLocation), + Nil).setSourceLocation(whileStmt.sourceLocation) :: restStmts) + .setSourceLocation(labeledStmts.sourceLocation) + } + + block = MPCalPassUtils.rewriteEachBody(block) { (body, lexicalScope) => + MPCalPassUtils.expandMacroCalls(body, lexicalScope) + } + + val nameCleaner = new NameCleaner + MPCalPassUtils.forEachName(tlaModule, block)(nameCleaner.addKnownName) + + // remove multiple assignment + block = MPCalPassUtils.rewriteEachBody(block) { (body, _) => + def impl(body: List[PCalStatement]): List[PCalStatement] = + body.flatMap { + case PCalAssignment(pairs) if pairs.size > 1 => + @tailrec + def lhsIdentifier(lhs: PCalAssignmentLhs): TLAIdentifier = + lhs match { + case PCalAssignmentLhsIdentifier(identifier) => identifier + case PCalAssignmentLhsProjection(lhs, _) => lhsIdentifier(lhs) + case PCalAssignmentLhsExtension(contents) => ??? + } + val bindings = pairs.map { + case pair @PCalAssignmentPair(lhs, rhs) => + val lhsIdent = lhsIdentifier(lhs) + val lhsName = nameCleaner.cleanName(lhsIdent.id) + PCalVariableDeclarationValue(lhsIdent.withChildren(Iterator(lhsName)), rhs) + .setSourceLocation(pair.sourceLocation) + } + pairs.map { + case pair @PCalAssignmentPair(lhs, rhs) => + PCalAssignment(List(???)) + } + case stmt @PCalEither(cases) => + List(stmt.withChildren(Iterator(cases.mapConserve(impl)))) + case stmt @PCalIf(condition, yes, no) => + List(stmt.withChildren(Iterator( + condition, impl(yes), impl(no)))) + case stmt @PCalLabeledStatements(label, statements) => + List(stmt.withChildren(Iterator( + label, impl(statements)))) + case stmt @PCalWhile(condition, body) => + List(stmt.withChildren(Iterator( + condition, impl(body)))) + case stmt @PCalWith(variables, body) => + List(stmt.withChildren(Iterator( + variables, impl(body)))) + } + + impl(body) + } + + block + } +} diff --git a/src/pgo/trans/MPCalPCalCodegenPass.scala b/src/pgo/trans/MPCalPCalCodegenPass.scala new file mode 100644 index 000000000..dc8cbc6b0 --- /dev/null +++ b/src/pgo/trans/MPCalPCalCodegenPass.scala @@ -0,0 +1,11 @@ +package pgo.trans + +import pgo.model.PGoError +import pgo.model.mpcal.MPCalBlock +import pgo.model.pcal.PCalAlgorithm + +object MPCalPCalCodegenPass { + + @throws[PGoError] + def apply(mpcalBlock: MPCalBlock): PCalAlgorithm = ??? +} diff --git a/src/pgo/trans/MPCalSemanticCheckPass.scala b/src/pgo/trans/MPCalSemanticCheckPass.scala new file mode 100644 index 000000000..66f650099 --- /dev/null +++ b/src/pgo/trans/MPCalSemanticCheckPass.scala @@ -0,0 +1,373 @@ +package pgo.trans + +import pgo.model.{DefinitionOne, PGoError, SourceLocatable, SourceLocation, Visitable} +import pgo.model.mpcal._ +import pgo.model.pcal._ +import pgo.model.tla._ +import pgo.util.{Description, IdMap, IdSet, MPCalPassUtils} + +import Description._ + +import scala.annotation.tailrec +import scala.collection.mutable + +object MPCalSemanticCheckPass { + + final case class SemanticError(override val errors: List[SemanticError.Error]) extends PGoError + + object SemanticError { + sealed abstract class Error(override val sourceLocation: SourceLocation, override val description: Description) extends PGoError.Error + + final case class LabelRequiredError(node: SourceLocatable) extends Error( + node.sourceLocation, d"label required") + + final case class LabelForbiddenError(node: SourceLocatable) extends Error( + node.sourceLocation, d"label forbidden") + + final case class ReservedLabelError(node: SourceLocatable) extends Error( + node.sourceLocation, d"label name is reserved (reserved names are `Done` and `Error`)") + + final case class MultipleAssignmentError(node1: SourceLocatable, node2: SourceLocatable) extends Error( + node2.sourceLocation, d"multiple assignment within same label.\ninitial assignment at ${ + node1.sourceLocation.longDescription + }\nconflicts with other assignment") + + final case class LabelNotDefinedError(node: SourceLocatable) extends Error( + node.sourceLocation, d"label not defined") + + final case class RecursiveMacroError(node: SourceLocatable) extends Error( + node.sourceLocation, d"macro call leads to recursion") + + final case class MPCalKindMismatchError(usage: SourceLocatable, defn: SourceLocatable) extends Error( + usage.sourceLocation, d"reference to kinded definition at ${ + defn.sourceLocation.longDescription + }\n does not match") + } + + @throws[PGoError] + def apply(tlaModule: TLAModule, mpcalBlock: MPCalBlock): Unit = { + val errors = mutable.ListBuffer[SemanticError.Error]() + + // enforce that the first statement / top-level statements in: + // - procedures + // - archetypes + // - processes + // must be labeled + locally { + def checkInBody(body: List[PCalStatement]): Unit = { + body.foreach { + case PCalLabeledStatements(_, _) => // ok + case stmt => + errors += SemanticError.LabelRequiredError(stmt) + } + } + mpcalBlock.visit(Visitable.TopDownFirstStrategy) { + case MPCalArchetype(_, _, _, _, body) => checkInBody(body) + case MPCalProcedure(_, _, _, body) => checkInBody(body) + case PCalProcedure(_, _, _, body) => checkInBody(body) + case PCalProcess(_, _, _, body) => checkInBody(body) + } + } + + // enforce cases where no labels may be present + locally { + def requireNoLabels(visitable: Visitable): Unit = + visitable.visit(Visitable.TopDownFirstStrategy) { + case PCalLabeledStatements(label, _) => + errors += SemanticError.LabelForbiddenError(label) + } + + mpcalBlock.visit(Visitable.TopDownFirstStrategy) { + case m: PCalMacro => requireNoLabels(m) + case mm: MPCalMappingMacro => requireNoLabels(mm) + case w: PCalWith => requireNoLabels(w) + } + } + + // enforce reserved label names + mpcalBlock.visit(Visitable.BottomUpFirstStrategy) { + case PCalLabeledStatements(label, _) if label.name == "Error" || label.name == "Done" => + errors += SemanticError.ReservedLabelError(label) + } + + // enforce non-recursive macros + val hasRecursiveMacro: Boolean = locally { + var hasRecursiveMacro = false + def checkNonRec(visitable: Visitable, macrosBeingExpanded: Map[String,PCalMacroCall]): Unit = + visitable.visit(Visitable.TopDownFirstStrategy) { + case innerCall @PCalMacroCall(target, _) => + macrosBeingExpanded.get(target.id) match { + case Some(outerCall) => + hasRecursiveMacro = true + errors += SemanticError.RecursiveMacroError(outerCall) + case None => + val updatedExpansion = macrosBeingExpanded + .updated(target.id, macrosBeingExpanded.getOrElse(target.id, innerCall)) + innerCall.refersTo.body.foreach(checkNonRec(_, updatedExpansion)) + } + } + + checkNonRec(mpcalBlock, Map.empty) + hasRecursiveMacro + } + + val containsLabels: IdSet[PCalStatement] = locally { + var containsLabels = IdSet.empty[PCalStatement] + def gatherContainsLabels(stmt: PCalStatement): Boolean = { + // note: the seemingly over-engineered map+reduce ensures all sub-statements are reached, + // vs. a more concise but short-circuiting .exists(...) + val result: Boolean = stmt match { + case PCalEither(cases) => cases.view.flatMap(_.view.map(gatherContainsLabels)).foldLeft(false)(_ || _) + case PCalIf(_, yes, no) => + yes.view.map(gatherContainsLabels).foldLeft(false)(_ || _) || + no.view.map(gatherContainsLabels).foldLeft(false)(_ || _) + case PCalLabeledStatements(_, statements) => + statements.foreach(gatherContainsLabels) + true + case PCalWhile(_, body) => body.view.map(gatherContainsLabels).foldLeft(false)(_ || _) + case PCalWith(_, body) => body.view.map(gatherContainsLabels).foldLeft(false)(_ || _) + case _ => false + } + if(result) { + containsLabels += stmt + } + result + } + + mpcalBlock.visit(Visitable.TopDownFirstStrategy) { + case stmt: PCalStatement => gatherContainsLabels(stmt) + } + + containsLabels + } + + val tailStatements: IdMap[PCalStatement,Vector[PCalStatement]] = locally { + var tailStatements = IdMap.empty[PCalStatement,Vector[PCalStatement]] + + def gatherTailStatements(stmt: PCalStatement): Vector[PCalStatement] = { + val result: Vector[PCalStatement] = stmt +: (stmt match { + case PCalEither(cases) => + cases.view.map(_.view.map(gatherTailStatements).last) + .foldLeft(Vector.empty[PCalStatement])(_ ++ _) + case PCalIf(_, yes, no) => + yes.view.map(gatherTailStatements).last ++ + no.view.map(gatherTailStatements).lastOption.getOrElse(Vector.empty) + case PCalLabeledStatements(_, statements) => + statements.view.map(gatherTailStatements).last + case macroCall @PCalMacroCall(_, _) if !hasRecursiveMacro => + macroCall.refersTo.body.view.map(gatherTailStatements).lastOption.getOrElse(Vector.empty) + case PCalWhile(_, body) => + body.view.map(gatherTailStatements).lastOption.getOrElse(Vector.empty) + case PCalWith(_, body) => + body.view.map(gatherTailStatements).lastOption.getOrElse(Vector.empty) + case _ => Vector.empty + }) + tailStatements = tailStatements.updated(stmt, result) + result + } + + mpcalBlock.visit(Visitable.TopDownFirstStrategy) { + case stmt: PCalStatement => + gatherTailStatements(stmt) + } + tailStatements + } + + def checkWhileLabelPlacement(visitable: Visitable): Unit = + visitable.visit(Visitable.TopDownFirstStrategy) { + case PCalLabeledStatements(_, PCalWhile(_, whileBody) :: restBody) => + whileBody.foreach(checkWhileLabelPlacement) + restBody.foreach(checkWhileLabelPlacement) + case stmt @PCalWhile(_, body) => + errors += SemanticError.LabelRequiredError(stmt) + body.foreach(checkWhileLabelPlacement) + } + + checkWhileLabelPlacement(mpcalBlock) + + // check whether statements that must be followed by a label are followed by a label + locally { + def supportsTailCall(stmt: PCalStatement): Boolean = + stmt match { + case _: PCalGoto => true + case _: PCalReturn => true + case _ => false + } + + def checkInBody(body: List[PCalStatement]): Unit = + if(body.size > 1) { + (body.view zip body.tail.view).foreach { + case (_, PCalLabeledStatements(_, _)) => // pass + case (beforeStmt, notLabel) => + + val labelNeedingStatementComesBefore = + tailStatements(beforeStmt).exists { + case ifStmt: PCalIf => containsLabels(ifStmt) + case _: PCalReturn => true + case _: PCalGoto => true + case _: PCalCall => !supportsTailCall(notLabel) + case PCalExtensionStatement(_: MPCalCall) => !supportsTailCall(notLabel) + case _ => false + } + if (labelNeedingStatementComesBefore) { + errors += SemanticError.LabelRequiredError(notLabel) + } + } + } + + // visit all parts of the MPCal block that contain a list of statements + mpcalBlock.visit(Visitable.BottomUpFirstStrategy) { + case MPCalMappingMacro(_, readBody, writeBody, _) => + checkInBody(readBody) + checkInBody(writeBody) + case PCalMacro(_, _, body, _) => checkInBody(body) + case PCalProcedure(_, _, _, body) => checkInBody(body) + case MPCalProcedure(_, _, _, body) => checkInBody(body) + case PCalProcess(_, _, _, body) => checkInBody(body) + case MPCalArchetype(_, _, _, _, body) => checkInBody(body) + + case PCalLabeledStatements(_, body) => checkInBody(body) + case PCalWhile(_, body) => checkInBody(body) + case PCalIf(_, yes, no) => + checkInBody(yes) + checkInBody(no) + case PCalEither(cases) => + cases.foreach(checkInBody) + case PCalWith(_, body) => checkInBody(body) + } + } + + // enforce multiple assignment rules + locally { + def checkInBody(assignedVars: Map[TLAIdentifier,TLAIdentifier], contextualBindings: Map[String,DefinitionOne], body: List[PCalStatement]): Map[TLAIdentifier,TLAIdentifier] = + body.view.scanLeft(assignedVars) { (assignedVars, stmt) => + stmt match { + case PCalAssignment(pairs) => + pairs.view.scanLeft(assignedVars) { (assignedVars, pair) => + val PCalAssignmentPair(lhs, _) = pair + @tailrec + def getId(lhs: PCalAssignmentLhs): TLAIdentifier = + lhs match { + case PCalAssignmentLhsIdentifier(identifier) => identifier + case PCalAssignmentLhsProjection(lhs, _) => getId(lhs) + } + + val lhsId = getId(lhs) + assignedVars.get(lhsId) match { + case Some(conflictingId) => + errors += SemanticError.MultipleAssignmentError(conflictingId, lhsId) + case None => // pass + } + assignedVars.updated(lhsId, lhsId) + }.last + case PCalEither(cases) => + cases.map(checkInBody(assignedVars, contextualBindings, _)).reduce(_ ++ _) + case PCalIf(_, yes, no) => + checkInBody(assignedVars, contextualBindings, yes) ++ checkInBody(assignedVars, contextualBindings, no) + case PCalLabeledStatements(_, statements) => + checkInBody(Map.empty, contextualBindings, statements) + Map.empty + case macroCall: PCalMacroCall if !hasRecursiveMacro => + checkInBody( + assignedVars, + contextualBindings, + MPCalPassUtils.expandMacroCalls(List(macroCall), contextualBindings)) + case PCalWhile(_, body) => checkInBody(assignedVars, contextualBindings, body) + case PCalWith(bindings, body) => + checkInBody( + assignedVars, + bindings.foldLeft(contextualBindings)((contextualBindings, b) => contextualBindings.updated(b.name.id, b)), + body) + case _ => assignedVars + } + }.last + + MPCalPassUtils.forEachBody(mpcalBlock)((body, contextualBindings) => checkInBody(Map.empty, contextualBindings, body)) + } + + // for each PCal "body", every goto must refer to a defined label + locally { + def checkInBody(body: List[PCalStatement]): Unit = { + val labels = mutable.HashSet[String]() + body.foreach(_.visit(Visitable.BottomUpFirstStrategy) { + case PCalLabeledStatements(label, _) => labels += label.name + }) + body.foreach(_.visit(Visitable.BottomUpFirstStrategy) { + case stmt @PCalGoto(label) if !labels(label) => + errors += SemanticError.LabelNotDefinedError(stmt) + }) + } + + MPCalPassUtils.forEachBody(mpcalBlock)((body, _) => checkInBody(body)) + } + + // enforce kind-matching for MPCal params (ref vs. non-ref, number of mappings) + locally { + def checkMPCalParamRefs(body: List[PCalStatement], params: List[MPCalParam]): Unit = { + val paramsMap = params.view.map(p => p -> p).to(IdMap) + body.foreach { stmt => + stmt.visit(Visitable.BottomUpFirstStrategy) { + case ref @MPCalValExpr(_, mappingCount) => + paramsMap(ref.refersTo) match { + case defn @ MPCalRefParam(_, mappingCountP) => + if(mappingCountP > mappingCount) { + errors += SemanticError.MPCalKindMismatchError(usage = ref, defn = defn) + } + case defn @MPCalValParam(_, mappingCountP) => + if(mappingCountP > mappingCount) { + errors += SemanticError.MPCalKindMismatchError(usage = ref, defn = defn) + } + } + case ref @MPCalRefExpr(_, mappingCount) => + paramsMap(ref.refersTo) match { + case defn @ MPCalRefParam(_, mappingCountP) => + if(mappingCountP > mappingCount) { + errors += SemanticError.MPCalKindMismatchError(usage = ref, defn = defn) + } + case defn @MPCalValParam(_, _) => + errors += SemanticError.MPCalKindMismatchError(usage = ref, defn = defn) + } + } + } + } + + mpcalBlock.visit(Visitable.TopDownFirstStrategy) { + case MPCalArchetype(_, _, params, _, body) => + checkMPCalParamRefs(body, params) + case MPCalProcedure(_, params, _, body) => + checkMPCalParamRefs(body, params) + case instance @MPCalInstance(_, _, _, arguments, mappings) => + val archetype = instance.refersTo + mappings.foreach { + case MPCalMapping(target @MPCalMappingTarget(position, mappingCount), id) => + arguments(position) match { + case Left(param) => param match { + case MPCalRefParam(_, mappingCountP) => + if(mappingCount < mappingCountP) { + errors += SemanticError.MPCalKindMismatchError(usage = target, defn = param) + } + case MPCalValParam(_, mappingCountP) => + if(mappingCount < mappingCountP) { + errors += SemanticError.MPCalKindMismatchError(usage = target, defn = param) + } + } + case Right(_) => // any mappings work here, we'll add an underlying variable if we have to; TODO: is this true? + } + } + (archetype.params.view zip arguments.view).foreach { + case (MPCalRefParam(_, mappingCountP), Left(MPCalRefParam(_, mappingCount))) if mappingCount == mappingCountP => // ok + case (MPCalValParam(_, 0), Right(_)) => // ok + case (MPCalValParam(_, mappingCountP), Left(MPCalValParam(_, mappingCount))) if mappingCount == mappingCountP => // ok + case (param, Left(arg)) => + errors += SemanticError.MPCalKindMismatchError(usage = arg, defn = param) + case (param, Right(arg)) => + errors += SemanticError.MPCalKindMismatchError(usage = arg, defn = param) + } + } + } + + if(errors.nonEmpty) { + throw SemanticError(errors.result()) + } + } +} diff --git a/src/pgo/trans/PCalRenderPass.scala b/src/pgo/trans/PCalRenderPass.scala new file mode 100644 index 000000000..61fd5d4c3 --- /dev/null +++ b/src/pgo/trans/PCalRenderPass.scala @@ -0,0 +1,8 @@ +package pgo.trans + +import pgo.model.pcal.PCalAlgorithm +import pgo.util.Description + +object PCalRenderPass { + def apply(pcalAlgorithm: PCalAlgorithm): Description = ??? +} diff --git a/src/pgo/trans/PGoTransException.java b/src/pgo/trans/PGoTransException.java deleted file mode 100644 index f49187ecb..000000000 --- a/src/pgo/trans/PGoTransException.java +++ /dev/null @@ -1,22 +0,0 @@ -package pgo.trans; - -import pgo.PGoException; - -/** - * Exception during PlusCal AST to Golang AST translation - * - */ -public class PGoTransException extends PGoException { - - private static final long serialVersionUID = -1752641749710219477L; - private static final String prefix = "Translation Error"; - - public PGoTransException(String msg) { - super(prefix, msg); - } - - public PGoTransException(String msg, int line) { - super(prefix, msg, line); - } - -} diff --git a/src/pgo/trans/PGoUnsupportedException.java b/src/pgo/trans/PGoUnsupportedException.java deleted file mode 100644 index f610f764b..000000000 --- a/src/pgo/trans/PGoUnsupportedException.java +++ /dev/null @@ -1,13 +0,0 @@ -package pgo.trans; - -import pgo.PGoException; - -public class PGoUnsupportedException extends PGoException { - - private static final String prefix = "Currently Unsupported"; - - public PGoUnsupportedException(String msg) { - super(prefix, msg); - } - -} diff --git a/src/pgo/trans/PlusCalCodeGenPassS.txt b/src/pgo/trans/PlusCalCodeGenPassS.txt new file mode 100644 index 000000000..a2061f673 --- /dev/null +++ b/src/pgo/trans/PlusCalCodeGenPassS.txt @@ -0,0 +1,760 @@ +package pgo.trans + +import pgo.model.tla._ +import pgo.trans.intermediate.UnsupportedFeatureIssue +import pgo.trans.passes.codegen.NameCleaner +import pgo.trans.passes.codegen.pluscal.ExpandedProcedureMatch +import pgo.trans.passes.codegen.pluscal.NameCleanerSeedGatherer.gatherNameCleanerSeed + +import scala.collection.{View, mutable} +import scala.jdk.CollectionConverters._ + +final case class PlusCalCodeGenPassContext(nameCleaner: NameCleaner, + proceduresToExpand: Map[String,PlusCalProcedure], + expandedProcedures: mutable.ListBuffer[PlusCalProcedure], + expandedProcedureCache: mutable.HashMap[ExpandedProcedureMatch,PlusCalProcedure], + mappingMacros: Map[String,ModularPlusCalMappingMacro], + archetypes: Map[String,ModularPlusCalArchetype]) + +object PlusCalCodeGenPassS { + abstract class MappingMacroReadExpander { + def expand(readVar: TLAExpression, readSink: TLAExpression=>List[PlusCalStatement]): List[PlusCalStatement] + } + abstract class MappingMacroWriteExpander { + def expand(writeVar: TLAExpression, writeSink: TLAExpression=>List[PlusCalStatement]): List[PlusCalStatement] + } + final class MappingMacroExpander(val read: MappingMacroReadExpander, val write: MappingMacroWriteExpander, val isFnMapped: Boolean) + + private final case class ProcedureExpansionSignature(procUID: UID, macroParams: List[Option[TLARef]]) + + class ReadWriteReferencesCounter { self => + type CountsMap = Map[TLADefinitionOne,Int] + private val underlying = mutable.HashMap[PlusCalStatement,(CountsMap,CountsMap)]() + private val underlyingAggregates = mutable.HashMap[View[PlusCalStatement],(CountsMap,CountsMap)]() + + private def implExpr(expr: TLAExpression): CountsMap = + TLAUtils.mapReduceExpr(Map.empty: CountsMap) { + case ident: TLAGeneralIdentifier => + join( + Map(ident.getRefersTo -> 1), + ident.prefix.view.flatMap(part => part.getParameters.asScala.view.map(implExpr)).reduce(join)) + case ref: TLARef => + Map(ref.getRefersTo -> 1) + }(join)(expr) + + private def join(left: CountsMap, right: CountsMap): CountsMap = + (View.from(left) ++ right).groupMapReduce(_._1)(_._2)(_ + _) + + private def join(lefts: (CountsMap,CountsMap), rights: (CountsMap,CountsMap)): (CountsMap,CountsMap) = + (join(lefts._1, rights._1), join(lefts._2, rights._2)) + + def apply(stmt: PlusCalStatement): (CountsMap, CountsMap) = + underlying.getOrElseUpdate(stmt, { + stmt.accept(new PlusCalStatementVisitor[(CountsMap,CountsMap),RuntimeException] { + private def emptyPair: (CountsMap,CountsMap) = (Map.empty, Map.empty) + override def visit(plusCalLabeledStatements: PlusCalLabeledStatements): (CountsMap,CountsMap) = + self(plusCalLabeledStatements.statements) + override def visit(plusCalWhile: PlusCalWhile): (CountsMap,CountsMap) = ??? + override def visit(plusCalIf: PlusCalIf): (CountsMap,CountsMap) = ??? + override def visit(plusCalEither: PlusCalEither): (CountsMap,CountsMap) = ??? + override def visit(plusCalAssignment: PlusCalAssignment): (CountsMap,CountsMap) = + plusCalAssignment.getPairs.asScala.view.map { pair => + def implLhs(lhs: TLAExpression): (CountsMap,CountsMap) = + lhs match { + case ident: TLAGeneralIdentifier => + (Map.empty, Map(ident.getRefersTo -> 1)) + case dot: TLADot => implLhs(dot.getExpression) + case fnCall: TLAFunctionCall => + val (innerReads, innerWrites) = implLhs(fnCall.getFunction) + val paramReads = fnCall.getParams.asScala.view.map(implExpr).reduce(join) + (join(paramReads, innerReads), innerWrites) + } + val (lhsReads, lhsWrites) = implLhs(pair.getLhs) + (join(lhsReads, implExpr(pair.getRhs)), lhsWrites) + }.reduce(join) + override def visit(plusCalReturn: PlusCalReturn): (CountsMap,CountsMap) = emptyPair + override def visit(plusCalSkip: PlusCalSkip): (CountsMap,CountsMap) = emptyPair + override def visit(plusCalCall: PlusCalCall): (CountsMap,CountsMap) = ??? + override def visit(macroCall: PlusCalMacroCall): (CountsMap,CountsMap) = ??? + override def visit(plusCalWith: PlusCalWith): (CountsMap,CountsMap) = ??? + override def visit(plusCalPrint: PlusCalPrint): (CountsMap,CountsMap) = ??? + override def visit(plusCalAssert: PlusCalAssert): (CountsMap,CountsMap) = ??? + override def visit(plusCalAwait: PlusCalAwait): (CountsMap,CountsMap) = ??? + override def visit(plusCalGoto: PlusCalGoto): (CountsMap,CountsMap) = ??? + override def visit(modularPlusCalYield: ModularPlusCalYield): (CountsMap,CountsMap) = ??? + }) + }) + + def apply(stmts: Iterable[PlusCalStatement]): (CountsMap,CountsMap) = + underlyingAggregates.getOrElseUpdate(stmts.view, { + if(stmts.isEmpty) { + (Map.empty, Map.empty) + } else { + join(self(stmts.head), self(stmts.view.tail)) + } + }) + } + + private object LhsHead { + def unapply(expr: TLAExpression): Option[TLAGeneralIdentifier] = + expr match { + case ident: TLAGeneralIdentifier => Some(ident) + case dot: TLADot => LhsHead.unapply(dot.getExpression) + case fnCall: TLAFunctionCall => LhsHead.unapply(fnCall.getFunction) + case _ => None + } + } + + def pcalStatementExpandMacros(statement: PlusCalStatement, mappingMacros: Map[TLADefinitionOne, MappingMacroExpander], macros: Map[String,PlusCalMacro], nameCleaner: NameCleaner): List[PlusCalStatement] = { + + def readExprs(exprs: List[TLAExpression], body: List[TLAExpression]=>List[PlusCalStatement]): List[PlusCalStatement] = { + def impl(elems: List[TLAExpression], convertedExprs: List[TLAExpression]): List[PlusCalStatement] = + elems match { + case Nil => + body(convertedExprs.reverse) + case hd :: tl => + implExprRead(hd, { hdRead => + impl(tl, hdRead :: convertedExprs) + }) + } + impl(exprs, Nil) + } + + def readGeneralIdentifierPrefix(parts: List[TLAGeneralIdentifierPart], body: List[TLAGeneralIdentifierPart]=>List[PlusCalStatement]): List[PlusCalStatement] = { + def impl(parts: List[TLAGeneralIdentifierPart], readParts: List[TLAGeneralIdentifierPart]): List[PlusCalStatement] = + parts match { + case Nil => + body(readParts.reverse) + case part :: restParts => + readExprs(part.getParameters.asScala.toList, { paramsRead => + impl(restParts, new TLAGeneralIdentifierPart(part.getLocation, part.getIdentifier, paramsRead.asJava) :: readParts) + }) + } + impl(parts, Nil) + } + + def implExprRead(expr: TLAExpression, body: TLAExpression=>List[PlusCalStatement]): List[PlusCalStatement] = { + object MappingMacroCandidate { + def unapply(expr: TLAExpression): Option[TLAGeneralIdentifier] = + expr match { + case ident: TLAGeneralIdentifier => Some(ident) + case fnCall: TLAFunctionCall => + fnCall.getFunction match { + case ident: TLAGeneralIdentifier => + // match a function call iff the mapping macro is function-mapped + mappingMacros.get(ident.getRefersTo).flatMap { mm => + if(mm.isFnMapped) Some(ident) else None + } + case _ => None + } + case _ => None + } + } + expr match { + case MappingMacroCandidate(ident) if mappingMacros.contains(ident.getRefersTo) => + // edge case: if expr is a function call and its arguments are candidates for mapping macro expansion, + // expand those before the current mapping macro + def preprocessExpr(expr: TLAExpression, body: TLAExpression=>List[PlusCalStatement]): List[PlusCalStatement] = + expr match { + case _: TLAGeneralIdentifier => body(expr) + case fnCall: TLAFunctionCall => + readExprs(fnCall.getParams.asScala.toList, { paramsRead => + body(new TLAFunctionCall(fnCall.getLocation, fnCall.getFunction, paramsRead.asJava)) + }) + } + preprocessExpr(expr, { expr => + val macroExpander = mappingMacros(ident.getRefersTo) + assert(ident.prefix.isEmpty) + macroExpander.read.expand(expr, { expr => + // make sure the value that was read is immediately bound by a with statement, to avoid any assignments + // nested inside `body` interfering with any variable reads nested inside the value's expression + val tmpVarName = new TLAIdentifier(ident.getLocation, nameCleaner.cleanName(ident.name.getId)) + val tmpVarDecl = new PlusCalVariableDeclaration(ident.getLocation, tmpVarName, false, false, expr) + val tmpGeneralIdent = new TLAGeneralIdentifier(ident.getLocation, tmpVarName, Nil) + tmpGeneralIdent.setRefersTo(tmpVarDecl) + List(new PlusCalWith(ident.getLocation, List(tmpVarDecl).asJava, body(tmpGeneralIdent).asJava)) + }) + }) + case _ => + expr.accept(new TLAExpressionVisitor[List[PlusCalStatement],RuntimeException] { + override def visit(tlaFunctionCall: TLAFunctionCall): List[PlusCalStatement] = + readExprs(tlaFunctionCall.getParams.asScala.toList, { readParams => + implExprRead(tlaFunctionCall.getFunction, { fnRead => + body(new TLAFunctionCall(tlaFunctionCall.getLocation, fnRead, readParams.asJava)) + }) + }) + override def visit(tlaBinOp: TLABinOp): List[PlusCalStatement] = + readGeneralIdentifierPrefix(tlaBinOp.getPrefix.asScala.toList, { prefixRead => + readExprs(List(tlaBinOp.getLHS, tlaBinOp.getRHS), { + case List(lhsRead, rhsRead) => + val op = new TLABinOp(tlaBinOp.getLocation, tlaBinOp.getOperation, prefixRead.asJava, lhsRead, rhsRead) + op.setRefersTo(tlaBinOp.getRefersTo) + body(op) + }) + }) + override def visit(tlaBool: TLABool): List[PlusCalStatement] = body(tlaBool) + override def visit(tlaCase: TLACase): List[PlusCalStatement] = ??? + override def visit(tlaDot: TLADot): List[PlusCalStatement] = + implExprRead(tlaDot.getExpression, { exprRead => + body(new TLADot(tlaDot.getLocation, exprRead, tlaDot.getField)) + }) + override def visit(tlaExistential: TLAExistential): List[PlusCalStatement] = ??? + override def visit(tlaFairness: TLAFairness): List[PlusCalStatement] = ??? + override def visit(tlaFunction: TLAFunction): List[PlusCalStatement] = ??? + override def visit(tlaFunctionSet: TLAFunctionSet): List[PlusCalStatement] = ??? + override def visit(tlaFunctionSubstitution: TLAFunctionSubstitution): List[PlusCalStatement] = + implExprRead(tlaFunctionSubstitution.getSource, { sourceRead => + def readSubstitutionPairs(substitutions: List[TLAFunctionSubstitutionPair], substitutionsRead: List[TLAFunctionSubstitutionPair]): List[PlusCalStatement] = + substitutions match { + case Nil => + body(new TLAFunctionSubstitution(tlaFunctionSubstitution.getLocation, sourceRead, substitutionsRead.reverse.asJava)) + case sub :: restSubs => + def readKeys(keys: List[TLASubstitutionKey], readKeysAcc: List[TLASubstitutionKey]): List[PlusCalStatement] = + keys match { + case Nil => + implExprRead(sub.getValue, { readValue => + readSubstitutionPairs(restSubs, new TLAFunctionSubstitutionPair(sub.getLocation, readKeysAcc.reverse.asJava, readValue) :: restSubs) + }) + case key :: restKeys => + readExprs(key.getIndices.asScala.toList, { indicesRead => + readKeys(restKeys, new TLASubstitutionKey(key.getLocation, indicesRead.asJava) :: readKeysAcc) + }) + } + readKeys(sub.getKeys.asScala.toList, Nil) + } + readSubstitutionPairs(tlaFunctionSubstitution.getSubstitutions.asScala.toList, Nil) + }) + override def visit(tlaIf: TLAIf): List[PlusCalStatement] = + readExprs(List(tlaIf.getCond, tlaIf.getTval, tlaIf.getFval), { + case List(readCond, readTVal, readFVal) => + body(new TLAIf(tlaIf.getLocation, readCond, readTVal, readFVal)) + }) + override def visit(tlaLet: TLALet): List[PlusCalStatement] = ??? + override def visit(tlaGeneralIdentifier: TLAGeneralIdentifier): List[PlusCalStatement] = + readGeneralIdentifierPrefix(tlaGeneralIdentifier.prefix, { prefixRead => + body(new TLAGeneralIdentifier(tlaGeneralIdentifier.getLocation, tlaGeneralIdentifier.name, prefixRead)) + }) + override def visit(tlaTuple: TLATuple): List[PlusCalStatement] = + readExprs(tlaTuple.getElements.asScala.toList, { readExprs => + body(new TLATuple(tlaTuple.getLocation, readExprs.reverse.asJava)) + }) + override def visit(tlaMaybeAction: TLAMaybeAction): List[PlusCalStatement] = ??? // makes no sense here + override def visit(tlaNumber: TLANumber): List[PlusCalStatement] = body(tlaNumber) + override def visit(tlaOperatorCall: TLAOperatorCall): List[PlusCalStatement] = ??? + override def visit(tlaQuantifiedExistential: TLAQuantifiedExistential): List[PlusCalStatement] = ??? + override def visit(tlaQuantifiedUniversal: TLAQuantifiedUniversal): List[PlusCalStatement] = ??? + override def visit(tlaRecordConstructor: TLARecordConstructor): List[PlusCalStatement] = ??? + override def visit(tlaRecordSet: TLARecordSet): List[PlusCalStatement] = ??? + override def visit(tlaRef: TLARef): List[PlusCalStatement] = ??? + override def visit(tlaRequiredAction: TLARequiredAction): List[PlusCalStatement] = ??? + override def visit(tlaSetConstructor: TLASetConstructor): List[PlusCalStatement] = ??? + override def visit(tlaSetComprehension: TLASetComprehension): List[PlusCalStatement] = ??? + override def visit(tlaSetRefinement: TLASetRefinement): List[PlusCalStatement] = ??? + override def visit(tlaSpecialVariableVariable: TLASpecialVariableVariable): List[PlusCalStatement] = ??? + override def visit(tlaSpecialVariableValue: TLASpecialVariableValue): List[PlusCalStatement] = ??? + override def visit(tlaString: TLAString): List[PlusCalStatement] = body(tlaString) + override def visit(tlaUnary: TLAUnary): List[PlusCalStatement] = ??? + override def visit(tlaUniversal: TLAUniversal): List[PlusCalStatement] = ??? + override def visit(plusCalDefaultInitValue: PlusCalDefaultInitValue): List[PlusCalStatement] = ??? + }) + } + } + + def substExpr(expr: TLAExpression)(implicit subst: Map[TLADefinitionOne,TLAExpression]): TLAExpression = + TLAUtils.rewriteExprPre { + case ident: TLAGeneralIdentifier if subst.contains(ident.getRefersTo) => + subst(ident.getRefersTo) + case ref: TLARef if subst.contains(ref.getRefersTo) => + ??? + }(expr) + + def implStmt(stmt: PlusCalStatement)(implicit subst: Map[TLADefinitionOne,TLAExpression], visitedMacros: Set[String]): List[PlusCalStatement] = + stmt.accept(new PlusCalStatementVisitor[List[PlusCalStatement],RuntimeException] { + override def visit(plusCalLabeledStatements: PlusCalLabeledStatements): List[PlusCalStatement] = + List(new PlusCalLabeledStatements( + plusCalLabeledStatements.getLocation, + plusCalLabeledStatements.label, + plusCalLabeledStatements.statements.flatMap(implStmt))) + override def visit(plusCalWhile: PlusCalWhile): List[PlusCalStatement] = ??? // unreachable + override def visit(plusCalIf: PlusCalIf): List[PlusCalStatement] = + // note: this, and several other cases, prevents a predictable translation of statements located after a yield + // expression in a mapping macro, due to what might happen if multiple reads occur in one expression. TODO: reject these cases? + implExprRead(substExpr(plusCalIf.getCondition), { readCondition => + List(new PlusCalIf( + plusCalIf.getLocation, + readCondition, + plusCalIf.getYes.asScala.flatMap(implStmt).asJava, + plusCalIf.getNo.asScala.flatMap(implStmt).asJava)) + }) + override def visit(plusCalEither: PlusCalEither): List[PlusCalStatement] = + List(new PlusCalEither(plusCalEither.getLocation, plusCalEither.getCases.asScala.map { caseStmts => + caseStmts.asScala.flatMap(implStmt).asJava + }.asJava)) + override def visit(plusCalAssignment: PlusCalAssignment): List[PlusCalStatement] = + readExprs(plusCalAssignment.getPairs.asScala.iterator.map(_.getRhs).toList, { readExprs => + val bindingVarDecls = readExprs.map { readExpr => + val tmpVarName = new TLAIdentifier(readExpr.getLocation, nameCleaner.cleanName("assignRhs")) + new PlusCalVariableDeclaration(readExpr.getLocation, tmpVarName, false, false, readExpr) + } + val boundRhss = bindingVarDecls.map { varDecl => + val ident = new TLAGeneralIdentifier(varDecl.getLocation, varDecl.getName, Nil) + ident.setRefersTo(varDecl) + ident + } + val body = (plusCalAssignment.getPairs.asScala.iterator zip boundRhss).flatMap { + case (assignmentPair, boundRhs) => + substExpr(assignmentPair.getLhs) match { + case lhsSubst @LhsHead(ident) if mappingMacros.contains(ident.getRefersTo) => + val mappingMacroExpander = mappingMacros(ident.getRefersTo) + mappingMacroExpander.write.expand(lhsSubst, { exprWrite => + List(new PlusCalAssignment( + assignmentPair.getLocation, + List(new PlusCalAssignmentPair(assignmentPair.getLocation, lhsSubst, exprWrite)).asJava)) + }) + case lhsSubst => + List(new PlusCalAssignment( + assignmentPair.getLocation, + List(new PlusCalAssignmentPair(assignmentPair.getLocation, lhsSubst, boundRhs)).asJava)) + } + }.toList + List(new PlusCalWith(plusCalAssignment.getLocation, bindingVarDecls.asJava, body.asJava)) + }) + override def visit(plusCalReturn: PlusCalReturn): List[PlusCalStatement] = List(plusCalReturn) + override def visit(plusCalSkip: PlusCalSkip): List[PlusCalStatement] = List(plusCalSkip) + override def visit(plusCalCall: PlusCalCall): List[PlusCalStatement] = ??? // TODO + override def visit(macroCall: PlusCalMacroCall): List[PlusCalStatement] = { + if(visitedMacros(macroCall.getTarget)) { + ??? + } + val mcr = macros(macroCall.getTarget) + assert(mcr.getParams.asScala.size == macroCall.getArguments.asScala.size) + val innerSubst = subst ++ (mcr.getParams.asScala.view zip macroCall.getArguments.asScala.view.map(substExpr)) + mcr.getBody.asScala.view.flatMap(implStmt(_)(subst = innerSubst, visitedMacros = visitedMacros + mcr.getName)).toList + } + override def visit(plusCalWith: PlusCalWith): List[PlusCalStatement] = + readExprs(plusCalWith.getVariables.asScala.iterator.map(_.getValue).map(substExpr).toList, { exprsRead => + List(new PlusCalWith(plusCalWith.getLocation, (plusCalWith.getVariables.asScala.iterator zip exprsRead).map { + case (decl, valExpr) => new PlusCalVariableDeclaration(decl.getLocation, decl.getName, decl.isRef, decl.isSet, valExpr) + }.toList.asJava, plusCalWith.getBody.asScala.flatMap(implStmt).asJava)) + }) + override def visit(plusCalPrint: PlusCalPrint): List[PlusCalStatement] = + implExprRead(substExpr(plusCalPrint.getValue), { readVal => + List(new PlusCalPrint(plusCalPrint.getLocation, readVal)) + }) + override def visit(plusCalAssert: PlusCalAssert): List[PlusCalStatement] = + implExprRead(substExpr(plusCalAssert.getCondition), { readCond => + List(new PlusCalAssert(plusCalAssert.getLocation, readCond)) + }) + override def visit(plusCalAwait: PlusCalAwait): List[PlusCalStatement] = + implExprRead(substExpr(plusCalAwait.getCondition), { readCond => + List(new PlusCalAwait(plusCalAwait.getLocation, readCond)) + }) + override def visit(plusCalGoto: PlusCalGoto): List[PlusCalStatement] = List(plusCalGoto) + override def visit(modularPlusCalYield: ModularPlusCalYield): List[PlusCalStatement] = ??? // bad + }) + + implStmt(statement)(subst = Map.empty, visitedMacros = Set.empty) + } + + private final case class TailBlock(loc: SourceLocation, label: PlusCalLabel, stmts: List[PlusCalStatement]) + private final case class TailBlockConversion(unlabeledStmts: mutable.ListBuffer[PlusCalStatement], + tailBlocks: mutable.ListBuffer[TailBlock], + hasFallthrough: Boolean) + + private def pcalStatementsToTailBlockForm(stmts: List[PlusCalStatement], fallthroughLabel: Option[PlusCalLabel]): TailBlockConversion = { + def pcalStatementToTailBlockForm(stmt: PlusCalStatement, fallthroughLabel: Option[PlusCalLabel]): TailBlockConversion = + stmt.accept(new PlusCalStatementVisitor[TailBlockConversion,RuntimeException] { + override def visit(plusCalLabeledStatements: PlusCalLabeledStatements): TailBlockConversion = ??? + + override def visit(plusCalWhile: PlusCalWhile): TailBlockConversion = { + // problem: you need to fall through to the label _above_ the while, easier to just desugar into if + goto + // first + ??? + } + + override def visit(plusCalIf: PlusCalIf): TailBlockConversion = { + val TailBlockConversion(unlabeledStmtsYes, tailBlocksYes, hasFallthroughYes) = + pcalStatementsToTailBlockForm(plusCalIf.getYes.asScala.toList, fallthroughLabel = fallthroughLabel) + val TailBlockConversion(unlabeledStmtsNo, tailBlocksNo, hasFallthroughNo) = + pcalStatementsToTailBlockForm(plusCalIf.getNo.asScala.toList, fallthroughLabel = fallthroughLabel) + + TailBlockConversion( + unlabeledStmts = mutable.ListBuffer( + new PlusCalIf(plusCalIf.getLocation, plusCalIf.getCondition, unlabeledStmtsYes.asJava, unlabeledStmtsNo.asJava)), + tailBlocks = tailBlocksYes ++= tailBlocksNo, + hasFallthrough = hasFallthroughYes || hasFallthroughNo) + } + + override def visit(plusCalEither: PlusCalEither): TailBlockConversion = { + val tailBlockConversions = plusCalEither.getCases.asScala.toList.map { branch => + pcalStatementsToTailBlockForm(branch.asScala.toList, fallthroughLabel = fallthroughLabel) + } + TailBlockConversion( + unlabeledStmts = mutable.ListBuffer( + new PlusCalEither(plusCalEither.getLocation, tailBlockConversions.map(_.unlabeledStmts.asJava).asJava)), + tailBlocks = tailBlockConversions.foldLeft(mutable.ListBuffer[TailBlock]())(_ ++= _.tailBlocks), + hasFallthrough = tailBlockConversions.exists(_.hasFallthrough)) + } + + override def visit(plusCalAssignment: PlusCalAssignment): TailBlockConversion = + TailBlockConversion( + unlabeledStmts = mutable.ListBuffer(plusCalAssignment), + tailBlocks = mutable.ListBuffer(), + hasFallthrough = true) + + override def visit(plusCalReturn: PlusCalReturn): TailBlockConversion = + TailBlockConversion( + unlabeledStmts = mutable.ListBuffer(plusCalReturn), + tailBlocks = mutable.ListBuffer(), + hasFallthrough = false) + + override def visit(plusCalSkip: PlusCalSkip): TailBlockConversion = + TailBlockConversion( + unlabeledStmts = mutable.ListBuffer(plusCalSkip), + tailBlocks = mutable.ListBuffer(), + hasFallthrough = true) + + override def visit(plusCalCall: PlusCalCall): TailBlockConversion = + TailBlockConversion( + unlabeledStmts = mutable.ListBuffer(plusCalCall), + tailBlocks = mutable.ListBuffer(), + hasFallthrough = false) + + override def visit(macroCall: PlusCalMacroCall): TailBlockConversion = { + // problem: what if the macro body ends in a goto? unlikely, but a goto is not a label + // easier to expand macros before doing this + ??? + } + + override def visit(plusCalWith: PlusCalWith): TailBlockConversion = { + val TailBlockConversion(unlabeledStmts, mutable.ListBuffer(), hasFallthrough) = + pcalStatementsToTailBlockForm(plusCalWith.getBody.asScala.toList, fallthroughLabel = fallthroughLabel) + TailBlockConversion( + unlabeledStmts = mutable.ListBuffer( + new PlusCalWith(plusCalWith.getLocation, plusCalWith.getVariables, unlabeledStmts.toList.asJava)), + tailBlocks = mutable.ListBuffer(), + hasFallthrough = hasFallthrough) + } + + override def visit(plusCalPrint: PlusCalPrint): TailBlockConversion = + TailBlockConversion( + unlabeledStmts = mutable.ListBuffer(plusCalPrint), + tailBlocks = mutable.ListBuffer(), + hasFallthrough = true) + + override def visit(plusCalAssert: PlusCalAssert): TailBlockConversion = + TailBlockConversion( + unlabeledStmts = mutable.ListBuffer(plusCalAssert), + tailBlocks = mutable.ListBuffer(), + hasFallthrough = true) + + override def visit(plusCalAwait: PlusCalAwait): TailBlockConversion = + TailBlockConversion( + unlabeledStmts = mutable.ListBuffer(plusCalAwait), + tailBlocks = mutable.ListBuffer(), + hasFallthrough = true) + + override def visit(plusCalGoto: PlusCalGoto): TailBlockConversion = + TailBlockConversion( + unlabeledStmts = mutable.ListBuffer(plusCalGoto), + tailBlocks = mutable.ListBuffer(), + hasFallthrough = false) + + override def visit(modularPlusCalYield: ModularPlusCalYield): TailBlockConversion = + TailBlockConversion( + unlabeledStmts = mutable.ListBuffer(modularPlusCalYield), + tailBlocks = mutable.ListBuffer(), + hasFallthrough = true) + }) + + val unlabeledStmts = stmts.filterNot(_.isInstanceOf[PlusCalLabeledStatements]) + val labeledStmts = stmts.collect { case stmt: PlusCalLabeledStatements => stmt } + + // PCal semantics assertion: any labeled statements must follow unlabeled statements + assert(unlabeledStmts.view ++ labeledStmts == stmts.view) + // each statement has a fallthrough label: + // - any unlabeled statement's fallthrough label is + // a) the first labeled statement's label + // b) the fallthrough label passed in + // - any labeled statement's fallthrough label is: + // a) the next labeled statement's label + // b) if there is no next labeled statement, the passed in fallthrough label + val fallthroughLabels: List[Option[PlusCalLabel]] = + unlabeledStmts.map(_ => labeledStmts.headOption.map(_.label).orElse(fallthroughLabel)) ++ + labeledStmts.tail.map(stmt => Some(stmt.label)) :+ fallthroughLabel + // if this isn't true, we have a problem (PlusCal semantics violation) + assert(fallthroughLabels.size == stmts.size) + + (stmts zip fallthroughLabels).foldLeft(TailBlockConversion(mutable.ListBuffer(), mutable.ListBuffer(), true)) { (acc, pair) => + val (stmt, fallthroughLabel) = pair + (acc, stmt) match { + case (tc @TailBlockConversion(unlabeledStmts, tailBlocks @mutable.ListBuffer(), hasFallthrough), stmt: PlusCalLabeledStatements) => + val TailBlockConversion(innerUnlabeledStmts, innerTailBlocks, innerHasFallthrough) = + pcalStatementsToTailBlockForm(stmt.statements, fallthroughLabel = fallthroughLabel) + + // this is our first label, so we generate a trailing goto that points to it + // ... but only if it doesn't already contain some other control flow + if(hasFallthrough) { + unlabeledStmts += new PlusCalGoto(stmt.label.getLocation, stmt.label.getName) + } + // if the label body has a fallthrough, plug it with a goto to the fallthrough label + if(innerHasFallthrough) { + fallthroughLabel match { + case None => innerUnlabeledStmts += new PlusCalGoto(SourceLocation.unknown(), "done") + case Some(fallthroughLabel) => + innerUnlabeledStmts += new PlusCalGoto(fallthroughLabel.getLocation, fallthroughLabel.getName) + } + } + + tailBlocks += TailBlock(stmt.label.getLocation, stmt.label, innerUnlabeledStmts.toList) + tailBlocks ++= innerTailBlocks + tc.copy(hasFallthrough = false) // can't have fallthrough, we prevented it above + case (tc @TailBlockConversion(unlabeledStmts, tailBlocks @mutable.ListBuffer(), hasFallthrough), stmt) => + val TailBlockConversion(innerUnlabeledStmts, innerTailBlocks, innerHasFallthrough) = + pcalStatementToTailBlockForm(stmt, fallthroughLabel = fallthroughLabel) + unlabeledStmts ++= innerUnlabeledStmts + + // innerTailBlocks may or may not be empty. + // if empty, keep gathering unlabeled stmts + // if not, we should only encounter further labeled statements at this level + tailBlocks ++= innerTailBlocks + // if the statement has a fallthrough, so do we; if it doesn't, we don't either + tc.copy(hasFallthrough = hasFallthrough && innerHasFallthrough) + case (tc @TailBlockConversion(_, tailBlocks, false), stmt: PlusCalLabeledStatements) => + // in case a label has already encountered, we know: + // no fallthrough from previous statement (prev was a label, which prevents this) + val TailBlockConversion(innerUnlabeledStmts, innerTailBlocks, innerHasFallthrough) = + pcalStatementsToTailBlockForm(stmt.statements, fallthroughLabel = fallthroughLabel) + // if the label body has a fallthrough, plug it with a goto + if(innerHasFallthrough) { + fallthroughLabel match { + case None => innerUnlabeledStmts += new PlusCalGoto(SourceLocation.unknown(), "done") + case Some(fallthroughLabel) => + innerUnlabeledStmts += new PlusCalGoto(fallthroughLabel.getLocation, fallthroughLabel.getName) + } + } + tailBlocks += TailBlock(stmt.label.getLocation, stmt.label, innerUnlabeledStmts.toList) + tailBlocks ++= innerTailBlocks + tc + } + } + } + + private def mpcalAdjustAssignments(tailBlockForm: TailBlockConversion, nameCleaner: NameCleaner): TailBlockConversion = { + val countReadWriteReferences = new ReadWriteReferencesCounter + + def implStmts(stmts: List[PlusCalStatement])(implicit lifted: Map[TLADefinitionOne,(TLAGeneralIdentifier,TLAGeneralIdentifier)], + renamings: Map[TLADefinitionOne,SourceLocation=>TLAGeneralIdentifier]): List[PlusCalStatement] = { + stmts match { + case Nil => + lifted.toList.sortBy(_._1.identifier.getId).map { + case (_, (tempBinding, underlyingVar)) => + ??? // TODO: assign temp binding of lifted name to the underlying name, to ensure the resulting value is visible at the next step + } + case stmt :: restStmts => + stmt.accept(new PlusCalStatementVisitor[List[PlusCalStatement],RuntimeException] { + override def visit(plusCalLabeledStatements: PlusCalLabeledStatements): List[PlusCalStatement] = ??? // should be unreachable + override def visit(plusCalWhile: PlusCalWhile): List[PlusCalStatement] = ??? // should be unreachable + override def visit(plusCalIf: PlusCalIf): List[PlusCalStatement] = + List(new PlusCalIf( + plusCalIf.getLocation, + ??? /* TODO: renaming in cond */, + implStmts(plusCalIf.getYes.asScala.toList ::: restStmts).asJava, + implStmts(plusCalIf.getNo.asScala.toList ::: restStmts).asJava)) + override def visit(plusCalEither: PlusCalEither): List[PlusCalStatement] = + List(new PlusCalEither( + plusCalEither.getLocation, + plusCalEither.getCases.asScala.map { cse => + implStmts(cse.asScala.toList ::: restStmts).asJava + }.asJava)) + override def visit(plusCalAssignment: PlusCalAssignment): List[PlusCalStatement] = { + assert(plusCalAssignment.getPairs.asScala.size == 1) + val pair = plusCalAssignment.getPairs.asScala.head + val (readCounts, writeCounts) = countReadWriteReferences(restStmts) + val LhsHead(headIdent) = pair.getLhs + val renamedRhs = ??? // renamed RHS + if(writeCounts.getOrElse(headIdent.getRefersTo, 0) > 0) { + ??? // TODO: insert clean with-binding + // also, ensure the binding is reflected in lifted, so it can be tracked / reverted later, if needed. + // and also, flatten out function-assignment semantics into the appropriate pure record update ops + } else { + val renamedLhs = ??? // renamed RHS + val renamedAssignment = new PlusCalAssignment(plusCalAssignment.getLocation, List( + new PlusCalAssignmentPair(pair.getLocation, renamedLhs, renamedRhs) + ).asJava) + // lifted tracks which names we still need to assign to when we're done. if this counts as a last + // assignment, we're done with it and can discard it. + // this won't happen e.g if one branch of a conditional makes another assignment, but the other does not + renamedAssignment :: implStmts(restStmts)(lifted = lifted.removed(headIdent.getRefersTo), renamings = renamings) + } + } + override def visit(plusCalReturn: PlusCalReturn): List[PlusCalStatement] = + plusCalReturn :: implStmts(restStmts) + override def visit(plusCalSkip: PlusCalSkip): List[PlusCalStatement] = + plusCalSkip :: implStmts(restStmts) + override def visit(plusCalCall: PlusCalCall): List[PlusCalStatement] = ??? + override def visit(macroCall: PlusCalMacroCall): List[PlusCalStatement] = ??? // unreachable + override def visit(plusCalWith: PlusCalWith): List[PlusCalStatement] = { + ??? // TODO: blindly rename the bound name to avoid scoping conflicts, absorb all subsequent stmts + } + override def visit(plusCalPrint: PlusCalPrint): List[PlusCalStatement] = ??? + override def visit(plusCalAssert: PlusCalAssert): List[PlusCalStatement] = ??? + override def visit(plusCalAwait: PlusCalAwait): List[PlusCalStatement] = ??? + override def visit(plusCalGoto: PlusCalGoto): List[PlusCalStatement] = + plusCalGoto :: implStmts(restStmts) + override def visit(modularPlusCalYield: ModularPlusCalYield): List[PlusCalStatement] = ??? // unreachable + }) + } + } + + TailBlockConversion( + unlabeledStmts = implStmts(tailBlockForm.unlabeledStmts.result())(lifted = Map.empty, renamings = Map.empty).to(mutable.ListBuffer), + tailBlocks = tailBlockForm.tailBlocks.mapInPlace { + case TailBlock(loc, label, stmts) => TailBlock(loc, label, implStmts(stmts)(lifted = Map.empty, renamings = Map.empty)) + }, + hasFallthrough = tailBlockForm.hasFallthrough) + } + + def mpcalExpandArchetype(archetype: ModularPlusCalArchetype, instance: ModularPlusCalInstance, + mappingMacros: Map[String, ModularPlusCalMappingMacro], + macros: Map[String,PlusCalMacro], + nameCleaner: NameCleaner): PlusCalProcess = { + val instanceVariables = mutable.ListBuffer[PlusCalVariableDeclaration]() + val exprSubstitutionsBuilder = Map.newBuilder[UID,SourceLocation=>TLAExpression] + + // TODO: add way to avoid adding dummy locals when archetype is well-behaved and doesn't write to a non-ref input + + (archetype.getParams.asScala.iterator zip instance.getArguments.asScala.iterator).foreach { + case (decl, arg: TLARef) => + exprSubstitutionsBuilder += ((decl.getUID, { loc => + val id = new TLAGeneralIdentifier(loc, new TLAIdentifier(loc, arg.getTarget), Nil) + id.setRefersTo(arg.getRefersTo) + id + })) + case (decl, arg: TLAGeneralIdentifier) => + ??? + case (decl, expr) => + val freshName = nameCleaner.cleanName(decl.getName.getId) + val freshId = new TLAIdentifier(expr.getLocation, freshName) + val instanceDecl = new PlusCalVariableDeclaration(expr.getLocation, freshId, false, false, expr) + instanceVariables += instanceDecl + exprSubstitutionsBuilder += ((decl.getUID, { loc => + val id = new TLAGeneralIdentifier(loc, new TLAIdentifier(loc, freshName), Nil) + id.setRefersTo(instanceDecl) + id + })) + } + + val exprSubstitutions = exprSubstitutionsBuilder.result() + + instance.getMappings.asScala.foreach { mapping => + mappingMacros.get(mapping.getTarget.getName) match { + case None => ??? + case Some(mcr) => + val param = mapping.getVariable match { + case name: ModularPlusCalMappingVariableName => + archetype.getParams.asScala.find(_.getName.getId == name.getName).get + case position: ModularPlusCalMappingVariablePosition => + archetype.getParams.asScala.apply(position.getPosition - 1) + case _ => ??? + } + ??? // TODO + } + } + + val mappingMacroExpanders: Map[TLADefinitionOne,MappingMacroExpander] = ??? + + new PlusCalProcess( + instance.getLocation, + instance.getName, + instance.getFairness, + (archetype.getVariables.asScala.toList ++ instanceVariables.toList).asJava, + archetype.getBody.asScala.flatMap(pcalStatementExpandMacros(_, mappingMacroExpanders, macros, nameCleaner)).asJava) + } + + def perform(ctx: IssueContext, tlaModule: TLAModule, modularPlusCalBlock: ModularPlusCalBlock): PlusCalAlgorithm = { + val nameCleanerSeed = (gatherNameCleanerSeed(tlaModule) ++ gatherNameCleanerSeed(modularPlusCalBlock)) + .to(mutable.HashSet) + val nameCleaner = new NameCleaner(nameCleanerSeed.asJava) + + // procedures with `ref` in their arguments need macro expansion; those without do not + val (proceduresWithRefs,proceduresWithoutRefs) = + modularPlusCalBlock.procedures.partition(_.getParams.asScala.exists(_.isRef)) + + val proceduresToExpand = proceduresWithRefs.iterator.map(proc => proc.getName -> proc).toMap + val archetypes = modularPlusCalBlock.archetypes.iterator.map(arch => arch.getName -> arch).toMap + val mappingMacros = modularPlusCalBlock.mappingMacros.iterator.map(m => m.getName -> m).toMap + val macros = modularPlusCalBlock.macros.iterator.map(m => m.getName -> m).toMap + + val expandedProcedures = mutable.ListBuffer[PlusCalProcedure]() + val expandedProcedureCache = mutable.HashMap[ExpandedProcedureMatch,PlusCalProcedure]() + + val expandedMPCalInstances = + modularPlusCalBlock.instances.map { instance => + archetypes.get(instance.getTarget) match { + case None => ??? + case Some(archetype) => + mpcalExpandArchetype(archetype, instance, mappingMacros, macros, nameCleaner) + } + } + + val adjustedMPCalInstances = + expandedMPCalInstances.map { instance => + val initialTailBlockConversion = + pcalStatementsToTailBlockForm(instance.getBody.asScala.toList, fallthroughLabel = None) + val adjustedTailBlockConversion = mpcalAdjustAssignments(initialTailBlockConversion, nameCleaner) + new PlusCalProcess( + instance.getLocation, + instance.getName, + instance.getFairness, + instance.getVariables, + (adjustedTailBlockConversion.unlabeledStmts.view ++ adjustedTailBlockConversion.tailBlocks.view.map { + case TailBlock(loc, label, stmts) => + new PlusCalLabeledStatements(loc, label, stmts) + }).toList.asJava) + } + + val expandedPCalProcesses = + modularPlusCalBlock.processes.accept(new PlusCalProcessesVisitor[List[PlusCalProcess],RuntimeException] { + override def visit(singleProcess: PlusCalSingleProcess): List[PlusCalProcess] = Nil // catch this special case below + + override def visit(multiProcess: PlusCalMultiProcess): List[PlusCalProcess] = + multiProcess.getProcesses.asScala.view.map { proc => + new PlusCalProcess( + proc.getLocation, + proc.getName, + proc.getFairness, + proc.getVariables, + proc.getBody.asScala.flatMap(pcalStatementExpandMacros(_, Map.empty, macros, nameCleaner)).asJava) + }.toList + }) + + // rearrange the list of processes back into a PlusCalProcesses structure, and optionally handle the single-process + // form that was skipped above, if no additional processes were generated during expansion (from instances) + val expandedProcesses = modularPlusCalBlock.processes.accept(new PlusCalProcessesVisitor[PlusCalProcesses,RuntimeException] { + override def visit(singleProcess: PlusCalSingleProcess): PlusCalProcesses = + if(expandedMPCalInstances.nonEmpty) { + throw new UnsupportedFeatureIssue("single process with instances") + } else { + new PlusCalSingleProcess( + singleProcess.getLocation, + singleProcess.getBody.asScala.flatMap(pcalStatementExpandMacros(_, Map.empty, macros, nameCleaner)).asJava) + } + + override def visit(multiProcess: PlusCalMultiProcess): PlusCalProcesses = + new PlusCalMultiProcess( + multiProcess.getLocation, + (expandedMPCalInstances.view ++ expandedPCalProcesses).toList.asJava) + }) + + new PlusCalAlgorithm( + modularPlusCalBlock.getLocation, + PlusCalFairness.UNFAIR, + modularPlusCalBlock.name, + modularPlusCalBlock.variables.asJava, + Nil.asJava, + (proceduresWithoutRefs ++ expandedProcedures.toList).asJava, + modularPlusCalBlock.units.asJava, + expandedProcesses) + } +} diff --git a/src/pgo/trans/intermediate/BuiltinModule.java b/src/pgo/trans/intermediate/BuiltinModule.java deleted file mode 100644 index c6c966ab7..000000000 --- a/src/pgo/trans/intermediate/BuiltinModule.java +++ /dev/null @@ -1,35 +0,0 @@ -package pgo.trans.intermediate; - -import pgo.scope.ChainMap; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class BuiltinModule { - - Map operators; - - public BuiltinModule() { - this.operators = new HashMap<>(); - } - - public BuiltinModule(BuiltinModule exts) { - this.operators = new ChainMap<>(exts.operators); - } - - public void addOperator(String name, OperatorAccessor op) { - operators.put(name, op); - } - - public void addOperators(List names, OperatorAccessor op) { - for (String name : names) { - addOperator(name, op); - } - } - - public Map getOperators(){ - return operators; - } - -} diff --git a/src/pgo/trans/intermediate/BuiltinOperator.java b/src/pgo/trans/intermediate/BuiltinOperator.java deleted file mode 100644 index 38c08d158..000000000 --- a/src/pgo/trans/intermediate/BuiltinOperator.java +++ /dev/null @@ -1,61 +0,0 @@ -package pgo.trans.intermediate; - -import pgo.InternalCompilerError; -import pgo.model.golang.GoExpression; -import pgo.model.golang.builder.GoBlockBuilder; -import pgo.model.tla.TLAExpression; -import pgo.model.type.Type; -import pgo.model.type.TypeGenerator; -import pgo.model.type.TypeSolver; -import pgo.model.type.TypeVariable; -import pgo.scope.UID; -import pgo.trans.passes.codegen.go.GlobalVariableStrategy; -import pgo.trans.passes.codegen.go.LocalVariableStrategy; -import pgo.util.Origin; - -import java.util.List; -import java.util.Map; - -public class BuiltinOperator extends OperatorAccessor { - - public interface TypeConstraintGenerator { - Type generate(Origin origin, List argTypes, TypeSolver solver, - TypeGenerator generator); - } - public interface GoGenerator { - GoExpression generate(GoBlockBuilder builder, TLAExpression expr, DefinitionRegistry registry, List arguments, - Map typeMap, LocalVariableStrategy localSrtrategy, GlobalVariableStrategy globalStrategy); - } - - private final int argumentCount; - private final TypeConstraintGenerator typeConstraintGenerator; - private final GoGenerator goGenerator; - - public BuiltinOperator(int argumentCount, TypeConstraintGenerator typeConstraintGenerator, GoGenerator goGenerator) { - this.argumentCount = argumentCount; - this.typeConstraintGenerator = typeConstraintGenerator; - this.goGenerator = goGenerator; - } - - public UID getUID() { - throw new InternalCompilerError(); - } - - @Override - public int getArgumentCount() { - return argumentCount; - } - - @Override - public Type constrainTypes(Origin origin, DefinitionRegistry registry, List argTypes, TypeSolver solver, - TypeGenerator generator, Map mapping) { - return typeConstraintGenerator.generate(origin, argTypes, solver, generator); - } - - @Override - public GoExpression generateGo(GoBlockBuilder builder, TLAExpression origin, DefinitionRegistry registry, List args, - Map typeMap, LocalVariableStrategy localStrategy, GlobalVariableStrategy globalStrategy) { - return goGenerator.generate(builder, origin, registry, args, typeMap, localStrategy, globalStrategy); - } - -} diff --git a/src/pgo/trans/intermediate/CheckOptionsPass.java b/src/pgo/trans/intermediate/CheckOptionsPass.java deleted file mode 100644 index 346c5363f..000000000 --- a/src/pgo/trans/intermediate/CheckOptionsPass.java +++ /dev/null @@ -1,38 +0,0 @@ -package pgo.trans.intermediate; - -import pgo.PGoOptions; -import pgo.errors.IssueContext; -import pgo.model.mpcal.ModularPlusCalBlock; -import pgo.model.pcal.PlusCalAlgorithm; -import pgo.model.pcal.PlusCalMultiProcess; -import pgo.model.pcal.PlusCalProcessesVisitor; -import pgo.model.pcal.PlusCalSingleProcess; - -public class CheckOptionsPass { - - private CheckOptionsPass() {} - - public static void perform(IssueContext ctx, ModularPlusCalBlock modularPlusCalBlock, PGoOptions options) { - modularPlusCalBlock.getProcesses().accept(new PlusCalProcessesVisitor() { - - @Override - public Void visit(PlusCalSingleProcess singleProcess) throws RuntimeException { - if (options.net.isEnabled()) { - ctx.error(new UnsupportedFeatureIssue("networked single process")); - } - if (!modularPlusCalBlock.getInstances().isEmpty()) { - ctx.error(new UnsupportedFeatureIssue("single process with instances")); - } - return null; - } - - @Override - public Void visit(PlusCalMultiProcess multiProcess) throws RuntimeException { - // pass - return null; - } - - }); - } - -} diff --git a/src/pgo/trans/intermediate/CompiledOperatorAccessor.java b/src/pgo/trans/intermediate/CompiledOperatorAccessor.java deleted file mode 100644 index c72d04141..000000000 --- a/src/pgo/trans/intermediate/CompiledOperatorAccessor.java +++ /dev/null @@ -1,112 +0,0 @@ -package pgo.trans.intermediate; - -import pgo.model.golang.GoCall; -import pgo.model.golang.GoExpression; -import pgo.model.golang.GoVariableName; -import pgo.model.golang.builder.GoBlockBuilder; -import pgo.model.golang.builder.GoFunctionDeclarationBuilder; -import pgo.model.golang.type.GoType; -import pgo.model.tla.TLAExpression; -import pgo.model.tla.TLAOpDecl; -import pgo.model.tla.TLAOperatorDefinition; -import pgo.model.type.*; -import pgo.model.type.constraint.MonomorphicConstraint; -import pgo.scope.UID; -import pgo.trans.passes.codegen.go.GlobalVariableStrategy; -import pgo.trans.passes.codegen.go.LocalVariableStrategy; -import pgo.trans.passes.codegen.go.TypeConversionVisitor; -import pgo.trans.passes.codegen.go.TLAExpressionCodeGenVisitor; -import pgo.trans.passes.type.TLAExpressionTypeConstraintVisitor; -import pgo.util.Origin; - -import java.util.*; -import java.util.stream.Collectors; - -public class CompiledOperatorAccessor extends OperatorAccessor { - - private final TLAOperatorDefinition def; - private final Map, GoVariableName> implementations; - - public CompiledOperatorAccessor(TLAOperatorDefinition pGoTLAOperator) { - this.def = pGoTLAOperator; - this.implementations = new HashMap<>(); - } - - @Override - public Type constrainTypes(Origin origin, DefinitionRegistry registry, List args, TypeSolver solver, TypeGenerator generator, - Map mapping) { - // TODO argument-based polymorphism? - List defArgs = def.getArgs(); - for (int i = 0; i < defArgs.size(); ++i) { - TLAOpDecl arg = defArgs.get(i); - if (arg.getType() == TLAOpDecl.Type.ID) { - TypeVariable v = generator.getTypeVariable(Collections.singletonList(origin)); - mapping.put(arg.getName().getUID(), v); - solver.addConstraint(new MonomorphicConstraint(origin, v, args.get(i))); - } else { - // TODO: error - } - } - return new TLAExpressionTypeConstraintVisitor(registry, solver, generator, mapping).wrappedVisit(def.getBody()); - } - - @Override - public int getArgumentCount() { - return def.getArgs().size(); - } - - @Override - public GoExpression generateGo(GoBlockBuilder builder, TLAExpression origin, DefinitionRegistry registry, List args, - Map typeMap, LocalVariableStrategy localStrategy, GlobalVariableStrategy globalStrategy) { - - // construct signature - List signature = new ArrayList<>(); - for (TLAOpDecl arg : def.getArgs()) { - Type argType = typeMap.get(arg.getName().getUID()); - signature.add(argType.accept(new TypeConversionVisitor())); - } - - // return type - GoType returnType = typeMap.get(def.getBody().getUID()).accept(new TypeConversionVisitor()); - signature.add(returnType); - - GoVariableName functionName; - - if (implementations.containsKey(signature)) { - functionName = implementations.get(signature); - } else { - GoFunctionDeclarationBuilder declBuilder = builder.defineFunction(def.getName().getUID(), def.getName().getId()); - - declBuilder.addReturn(returnType); - - // arguments - for (TLAOpDecl arg : def.getArgs()) { - Type argType = typeMap.get(arg.getUID()); - GoType goType = argType.accept(new TypeConversionVisitor()); - GoVariableName name = declBuilder.addParameter(arg.getName().getId(), goType); - builder.linkUID(arg.getUID(), name); - } - - try (GoBlockBuilder fnBuilder = declBuilder.getBlockBuilder()){ - fnBuilder.returnStmt( - def.getBody().accept( - new TLAExpressionCodeGenVisitor(fnBuilder, registry, typeMap, localStrategy, globalStrategy))); - } - - functionName = builder.findUID(def.getName().getUID()); - implementations.put(signature, functionName); - } - - return new GoCall( - functionName, - args.stream().map(a -> a.accept( - new TLAExpressionCodeGenVisitor(builder, registry, typeMap, localStrategy, globalStrategy))) - .collect(Collectors.toList())); - } - - @Override - public UID getUID() { - return def.getUID(); - } - -} diff --git a/src/pgo/trans/intermediate/DefinitionRegistry.java b/src/pgo/trans/intermediate/DefinitionRegistry.java deleted file mode 100644 index 5d0073dc8..000000000 --- a/src/pgo/trans/intermediate/DefinitionRegistry.java +++ /dev/null @@ -1,267 +0,0 @@ -package pgo.trans.intermediate; - -import pgo.InternalCompilerError; -import pgo.model.golang.type.GoType; -import pgo.model.mpcal.ModularPlusCalArchetype; -import pgo.model.mpcal.ModularPlusCalMappingMacro; -import pgo.model.pcal.PlusCalProcedure; -import pgo.model.tla.*; -import pgo.scope.UID; - -import java.util.*; - -public class DefinitionRegistry { - private final Map modules; - private final Map definitions; - private final Map operators; - private final Map globalVariableTypes; - private final Set localVariables; - private final Map constants; - private final Map constantValues; - private final Map references; - private final Map procedures; - private final Map archetypes; - private final Map mappingMacros; - private final Map labelsToLockGroups; - private final Map> lockGroupsToVariableReads; - private final Map> lockGroupsToVariableWrites; - private final Map> lockGroupsToResourceReads; - private final Map> lockGroupsToResourceWrites; - private final Set protectedGlobalVariables; - private final Map signatures; - private final Map> labelToLocals; - - public DefinitionRegistry() { - this.modules = new HashMap<>(); - this.definitions = new HashMap<>(); - this.operators = new HashMap<>(); - this.references = new HashMap<>(); - this.procedures = new HashMap<>(); - this.archetypes = new HashMap<>(); - this.mappingMacros = new HashMap<>(); - this.globalVariableTypes = new HashMap<>(); - this.localVariables = new HashSet<>(); - this.constants = new HashMap<>(); - this.constantValues = new HashMap<>(); - this.labelsToLockGroups = new HashMap<>(); - this.lockGroupsToVariableReads = new HashMap<>(); - this.lockGroupsToVariableWrites = new HashMap<>(); - this.lockGroupsToResourceReads = new HashMap<>(); - this.lockGroupsToResourceWrites = new HashMap<>(); - this.protectedGlobalVariables = new HashSet<>(); - this.signatures = new HashMap<>(); - this.labelToLocals = new HashMap<>(); - } - - public Map getReferences() { - return references; - } - - public void addModule(TLAModule module) { - if (!modules.containsKey(module.getName().getId())) { - modules.put(module.getName().getId(), module); - } - } - - public void addOperatorDefinition(TLAOperatorDefinition def) { - if (!definitions.containsKey(def.getUID())) { - definitions.put(def.getUID(), def); - addOperator(def.getUID(), new CompiledOperatorAccessor(def)); - } - } - - public void addOperator(UID uid, OperatorAccessor op) { - operators.put(uid, op); - } - - public void addFunctionDefinition(TLAFunctionDefinition def) { - if (!definitions.containsKey(def.getUID())) { - definitions.put(def.getUID(), def); - } - } - - public void addProcedure(PlusCalProcedure proc) { - procedures.put(proc.getName(), proc); - } - - public void addArchetype(ModularPlusCalArchetype archetype) { - archetypes.put(archetype.getName(), archetype); - } - - public void addMappingMacro(ModularPlusCalMappingMacro mappingMacro) { - mappingMacros.put(mappingMacro.getName(), mappingMacro); - } - - public void addGlobalVariable(UID uid) { - globalVariableTypes.put(uid, null); - } - - public void updateGlobalVariableType(UID uid, GoType type) { - if (!globalVariableTypes.containsKey(uid)) { - throw new InternalCompilerError(); - } - globalVariableTypes.put(uid, type); - } - - public void addLocalVariable(UID uid) { - localVariables.add(uid); - } - - public void addConstant(UID uid, String name) { - constants.put(uid, name); - } - - public UID followReference(UID from) { - if (!references.containsKey(from)) { - throw new InternalCompilerError(); - } - return references.get(from); - } - - public OperatorAccessor findOperator(UID id) { - if (!operators.containsKey(id)) { - throw new InternalCompilerError(); - } - return operators.get(id); - } - - public TLAModule findModule(String name) { - return modules.get(name); - } - - public PlusCalProcedure findProcedure(String name) { - return procedures.get(name); - } - - public ModularPlusCalArchetype findArchetype(String name) { - return archetypes.get(name); - } - - public ModularPlusCalMappingMacro findMappingMacro(String name) { - return mappingMacros.get(name); - } - - public boolean isGlobalVariable(UID ref) { - return globalVariableTypes.containsKey(ref); - } - - public GoType getGlobalVariableType(UID uid) { - return globalVariableTypes.get(uid); - } - - public boolean isLocalVariable(UID ref) { - return localVariables.contains(ref); - } - - public boolean isConstant(UID ref) { - return constants.containsKey(ref); - } - - public Set getConstants() { - return constants.keySet(); - } - - public String getConstantName(UID id) { - if (!constants.containsKey(id)) { - throw new InternalCompilerError(); - } - return constants.get(id); - } - - public void setConstantValue(UID id, TLAExpression value) { - constantValues.put(id, value); - } - - public Optional getConstantValue(UID id) { - return Optional.ofNullable(constantValues.get(id)); - } - - public Set globalVariables() { - return globalVariableTypes.keySet(); - } - - public void addLabelToLockGroup(UID labelUID, int lockGroup) { - if (labelsToLockGroups.containsKey(labelUID)) { - throw new InternalCompilerError(); - } - labelsToLockGroups.put(labelUID, lockGroup); - } - - public int getLockGroup(UID labelUID) { - return labelsToLockGroups.get(labelUID); - } - - public int getNumberOfLockGroups() { - return 1 + labelsToLockGroups.values().stream() - .max(Comparator.comparingInt(Integer::intValue)) - .orElse(-1); - } - - public int getLockGroupOrDefault(UID labelUID, int defaultValue) { - return labelsToLockGroups.getOrDefault(labelUID, defaultValue); - } - - public void addVariableReadToLockGroup(UID varUID, int lockGroup) { - lockGroupsToVariableReads.putIfAbsent(lockGroup, new HashSet<>()); - lockGroupsToVariableReads.get(lockGroup).add(varUID); - } - - public void addVariableWriteToLockGroup(UID varUID, int lockGroup) { - lockGroupsToVariableWrites.putIfAbsent(lockGroup, new HashSet<>()); - lockGroupsToVariableWrites.get(lockGroup).add(varUID); - } - - public void addResourceReadToLockGroup(TLAExpression resource, int lockGroup) { - lockGroupsToResourceReads.putIfAbsent(lockGroup, new HashSet<>()); - lockGroupsToResourceReads.get(lockGroup).add(resource); - } - - public void addResourceWriteToLockGroup(TLAExpression resource, int lockGroup) { - lockGroupsToResourceWrites.putIfAbsent(lockGroup, new HashSet<>()); - lockGroupsToResourceWrites.get(lockGroup).add(resource); - } - - public Set getResourceReadsInLockGroup(int lockGroup) { - return Collections.unmodifiableSet(lockGroupsToResourceReads.getOrDefault(lockGroup, Collections.emptySet())); - } - - public Set getResourceWritesInLockGroup(int lockGroup) { - return Collections.unmodifiableSet(lockGroupsToResourceWrites.getOrDefault(lockGroup, Collections.emptySet())); - } - - public Set getVariableReadsInLockGroup(int lockGroup) { - return Collections.unmodifiableSet(lockGroupsToVariableReads.getOrDefault(lockGroup, Collections.emptySet())); - } - - public Set getVariableWritesInLockGroup(int lockGroup) { - return Collections.unmodifiableSet(lockGroupsToVariableWrites.getOrDefault(lockGroup, Collections.emptySet())); - } - - public void addProtectedGlobalVariable(UID varUID) { - protectedGlobalVariables.add(varUID); - } - - public Set protectedGlobalVariables() { - return Collections.unmodifiableSet(protectedGlobalVariables); - } - - public Optional getSignature(UID uid) { - return Optional.ofNullable(signatures.get(uid)); - } - - public void putSignature(UID uid, boolean[] signature) { - if (signatures.containsKey(uid)) { - throw new InternalCompilerError(); - } - signatures.put(uid, signature); - } - - public void addLocalToLabel(UID labelUID, UID ref) { - labelToLocals.putIfAbsent(labelUID, new HashSet<>()); - labelToLocals.get(labelUID).add(ref); - } - - public Set getLocalsInLabel(UID labelUID) { - return labelToLocals.getOrDefault(labelUID, new HashSet<>()); - } -} diff --git a/src/pgo/trans/intermediate/IOErrorIssue.java b/src/pgo/trans/intermediate/IOErrorIssue.java deleted file mode 100644 index 2aab9bfd5..000000000 --- a/src/pgo/trans/intermediate/IOErrorIssue.java +++ /dev/null @@ -1,26 +0,0 @@ -package pgo.trans.intermediate; - -import pgo.errors.Issue; -import pgo.errors.IssueVisitor; - -import java.io.IOException; - -public class IOErrorIssue extends Issue { - - IOException error; - - public IOErrorIssue(IOException e) { - super(); - this.error = e; - } - - public IOException getError() { - return error; - } - - @Override - public T accept(IssueVisitor v) throws E { - return v.visit(this); - } - -} diff --git a/src/pgo/trans/intermediate/OperatorAccessor.java b/src/pgo/trans/intermediate/OperatorAccessor.java deleted file mode 100644 index 7adfb617c..000000000 --- a/src/pgo/trans/intermediate/OperatorAccessor.java +++ /dev/null @@ -1,37 +0,0 @@ -package pgo.trans.intermediate; - -import pgo.model.golang.GoExpression; -import pgo.model.golang.builder.GoBlockBuilder; -import pgo.model.tla.TLAExpression; -import pgo.model.type.*; -import pgo.model.type.TypeVariable; -import pgo.model.type.Type; -import pgo.scope.UID; -import pgo.trans.passes.codegen.go.GlobalVariableStrategy; -import pgo.trans.passes.codegen.go.LocalVariableStrategy; -import pgo.util.Derived; -import pgo.util.DerivedVisitor; -import pgo.util.Origin; - -import java.util.List; -import java.util.Map; - -public abstract class OperatorAccessor extends Derived { - - public abstract Type constrainTypes(Origin origin, DefinitionRegistry registry, List args, TypeSolver solver, - TypeGenerator generator, Map mapping); - - // TODO argument count mismatch - public abstract int getArgumentCount(); - - @Override - public T accept(DerivedVisitor v) throws E { - return v.visit(this); - } - - public abstract UID getUID(); - - public abstract GoExpression generateGo(GoBlockBuilder builder, TLAExpression origin, DefinitionRegistry registry, List args, - Map typeMap, LocalVariableStrategy localStrategy, GlobalVariableStrategy globalStrategy); - -} diff --git a/src/pgo/trans/intermediate/QualifiedName.java b/src/pgo/trans/intermediate/QualifiedName.java deleted file mode 100644 index 7bfc948b1..000000000 --- a/src/pgo/trans/intermediate/QualifiedName.java +++ /dev/null @@ -1,70 +0,0 @@ -package pgo.trans.intermediate; - -import pgo.model.tla.TLAGeneralIdentifierPart; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; - -public class QualifiedName { - String base; - List prefix; - - public QualifiedName(List prefix, String base) { - this.base = base; - this.prefix = prefix; - } - - public QualifiedName(String base) { - this.base = base; - this.prefix = Collections.emptyList(); - } - - public static QualifiedName fromTLAPrefix(List prefix, String base) { - return new QualifiedName(prefix.stream().map(p -> p.getIdentifier().getId()).collect(Collectors.toList()), base); - } - - public QualifiedName withPrefix(String pfx) { - List newPrefix = new ArrayList<>(prefix); - newPrefix.add(0, pfx); - return new QualifiedName(newPrefix, base); - } - - public String getBase() { - return base; - } - - public List getPrefix() { - return prefix; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((base == null) ? 0 : base.hashCode()); - result = prime * result + ((prefix == null) ? 0 : prefix.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; - QualifiedName other = (QualifiedName) obj; - if (base == null) { - if (other.base != null) - return false; - } else if (!base.equals(other.base)) - return false; - if (prefix == null) { - return other.prefix == null; - } else return prefix.equals(other.prefix); - } - -} diff --git a/src/pgo/trans/intermediate/TLABuiltins.java b/src/pgo/trans/intermediate/TLABuiltins.java deleted file mode 100644 index ea91d605b..000000000 --- a/src/pgo/trans/intermediate/TLABuiltins.java +++ /dev/null @@ -1,809 +0,0 @@ -package pgo.trans.intermediate; - -import pgo.InternalCompilerError; -import pgo.TODO; -import pgo.model.golang.*; -import pgo.model.golang.builder.GoAnonymousFunctionBuilder; -import pgo.model.golang.builder.GoBlockBuilder; -import pgo.model.golang.builder.GoForRangeBuilder; -import pgo.model.golang.builder.GoForStatementClauseBuilder; -import pgo.model.golang.type.GoSliceType; -import pgo.model.golang.type.GoType; -import pgo.model.tla.TLABuiltinModules; -import pgo.model.tla.TLAExpression; -import pgo.model.type.*; -import pgo.model.type.constraint.EqualityConstraint; -import pgo.model.type.constraint.MonomorphicConstraint; -import pgo.model.type.constraint.PolymorphicConstraint; -import pgo.scope.UID; -import pgo.trans.passes.codegen.go.*; -import pgo.util.Origin; - -import java.util.*; - -public class TLABuiltins { - private TLABuiltins() {} - - public static GoType getSetElementType(Type setType) { - Type elementType = ((SetType)setType).getElementType(); - return elementType.accept(new TypeConversionVisitor()); - } - - private static GoVariableName getIndexInSet(GoBlockBuilder builder, GoType elementType, GoExpression set, GoExpression val) { - builder.addImport("sort"); - - String searchFunction; - if (elementType.equals(GoBuiltins.Int)) { - searchFunction = "SearchInts"; - } else if (elementType.equals(GoBuiltins.Float64)) { - searchFunction = "SearchFloat64s"; - } else if (elementType.equals(GoBuiltins.String)) { - searchFunction = "SearchStrings"; - } else { - searchFunction = "Search"; - } - - GoVariableName index; - if (searchFunction.equals("Search")) { - GoAnonymousFunctionBuilder checkBuilder = builder.anonymousFunction(); - GoVariableName j = checkBuilder.addArgument("j", GoBuiltins.Int); - checkBuilder.addReturn(GoBuiltins.Bool); - try (GoBlockBuilder checkBody = checkBuilder.getBlockBuilder()) { - checkBody.addStatement( - new GoReturn( - Collections.singletonList( - new GoUnary( - GoUnary.Operation.NOT, - elementType.accept(new LessThanCodeGenVisitor( - checkBody, - new GoIndexExpression(set, j), - val)))))); - } - index = builder.varDecl( - "index", - new GoCall( - new GoSelectorExpression( - new GoVariableName("sort"), "Search"), - Arrays.asList( - new GoCall(new GoVariableName("len"), Collections.singletonList(set)), - checkBuilder.getFunction()))); - } else { - index = builder.varDecl( - "index", - new GoCall( - new GoSelectorExpression(new GoVariableName("sort"), searchFunction), - Arrays.asList(set, val))); - } - - return index; - } - - public static TypeVariable getPolymorphicNumberType(Origin origin, TypeSolver solver, - TypeGenerator generator) { - TypeVariable fresh = generator.getTypeVariable(Collections.singletonList(origin)); - // TODO we do not yet support Reals - solver.addConstraint(new MonomorphicConstraint( - origin, fresh, new IntType(Collections.singletonList(origin)))); - // solver.addConstraint(new PGoTypePolymorphicConstraint(origin, Arrays.asList( - // Collections.singletonList( - // new PGoTypeEqualityConstraint(fresh, new PGoTypeInt(Collections.singletonList(origin)))), - // Collections.singletonList( - // new PGoTypeEqualityConstraint(fresh, new PGoTypeReal(Collections.singletonList(origin))))))); - return fresh; - } - - private static Type constraintNumberOperation(Origin origin, List args, TypeSolver solver, - TypeGenerator generator) { - TypeVariable fresh = getPolymorphicNumberType(origin, solver, generator); - solver.addConstraint(new MonomorphicConstraint(origin, args.get(0), fresh)); - solver.addConstraint(new MonomorphicConstraint(origin, args.get(1), fresh)); - return fresh; - } - - private static Type constraintBooleanNumberOperation(Origin origin, List args, TypeSolver solver, - TypeGenerator generator) { - constraintNumberOperation(origin, args, solver, generator); - return new BoolType(Collections.singletonList(origin)); - } - - public static void ensureSorted(GoBlockBuilder builder, GoType elementType, GoVariableName set) { - builder.addImport("sort"); - String sortFunction; - if (elementType.equals(GoBuiltins.Int)) { - sortFunction = "Ints"; - } else if (elementType.equals(GoBuiltins.Float64)) { - sortFunction = "Float64s"; - } else if (elementType.equals(GoBuiltins.String)) { - sortFunction = "Strings"; - } else { - sortFunction = "Slice"; - } - if (sortFunction.equals("Slice")) { - GoAnonymousFunctionBuilder comparatorBuilder = builder.anonymousFunction(); - GoVariableName i = comparatorBuilder.addArgument("i", GoBuiltins.Int); - GoVariableName j = comparatorBuilder.addArgument("j", GoBuiltins.Int); - comparatorBuilder.addReturn(GoBuiltins.Bool); - try (GoBlockBuilder comparatorBody = comparatorBuilder.getBlockBuilder()) { - comparatorBody.addStatement( - new GoReturn( - Collections.singletonList( - elementType.accept( - new LessThanCodeGenVisitor( - comparatorBody, - new GoIndexExpression(set, i), - new GoIndexExpression(set, j)))))); - } - builder.addStatement(new GoExpressionStatement(new GoCall( - new GoSelectorExpression(new GoVariableName("sort"), sortFunction), - Arrays.asList( - set, - comparatorBuilder.getFunction())))); - } else { - builder.addStatement(new GoExpressionStatement(new GoCall( - new GoSelectorExpression(new GoVariableName("sort"), sortFunction), Collections.singletonList(set)))); - } - } - - public static void ensureUniqueSorted(GoBlockBuilder builder, GoType elementType, GoVariableName set) { - ensureSorted(builder, elementType, set); - // make elements unique with the following GoRoutineStatement code - // - // if len(set) > 1 { - // previousValue := set[0] - // currentIndex := 1 - // for i, v := range set[1:] { - // if v != previousValue { - // set[currentIndex] = v - // currentIndex++ - // } - // previousValue = v - // } - // set = set[:currentIndex] - // } - try (GoIfBuilder ifBuilder = builder.ifStmt(new GoBinop( - GoBinop.Operation.GT, - new GoCall(new GoVariableName("len"), Collections.singletonList(set)), - new GoIntLiteral(1)))) { - try (GoBlockBuilder yes = ifBuilder.whenTrue()) { - GoVariableName previousValue = yes.varDecl( - "previousValue", new GoIndexExpression(set, new GoIntLiteral(0))); - GoVariableName currentIndex = yes.varDecl("currentIndex", new GoIntLiteral(1)); - GoForRangeBuilder forRangeBuilder = yes.forRange(new GoSliceOperator(set, new GoIntLiteral(1), null, null)); - GoVariableName v = forRangeBuilder.initVariables(Arrays.asList("_", "v")).get(1); - try (GoBlockBuilder forBody = forRangeBuilder.getBlockBuilder()) { - try (GoIfBuilder innerIf = forBody.ifStmt(elementType.accept( - new EqCodeGenVisitor(forBody, previousValue, v, true)))) { - try (GoBlockBuilder innerYes = innerIf.whenTrue()) { - innerYes.assign(new GoIndexExpression(set, currentIndex), v); - innerYes.addStatement(new GoIncDec(true, currentIndex)); - } - } - forBody.assign(previousValue, v); - } - yes.assign(set, new GoSliceOperator(set, null, currentIndex, null)); - } - } - } - - private static final BuiltinModule universalBuiltIns = new BuiltinModule(); - static { - universalBuiltIns.addOperator("=", new BuiltinOperator( - 2, - (origin, args, solver, generator) -> { - solver.addConstraint(new MonomorphicConstraint(origin, args.get(0), args.get(1))); - return new BoolType(Collections.singletonList(origin)); - }, - (builder, origin, registry, arguments, typeMap, localStrategy, globalStrategy) -> { - GoExpression lhs = arguments.get(0).accept( - new TLAExpressionCodeGenVisitor(builder, registry, typeMap, localStrategy, globalStrategy)); - GoExpression rhs = arguments.get(1).accept( - new TLAExpressionCodeGenVisitor(builder, registry, typeMap, localStrategy, globalStrategy)); - return typeMap.get(arguments.get(0).getUID()) - .accept(new TypeConversionVisitor()) - .accept(new EqCodeGenVisitor(builder, lhs, rhs, false)); - })); - universalBuiltIns.addOperators(Arrays.asList("#", "/="), new BuiltinOperator( - 2, - (origin, args, solver, generator) -> { - solver.addConstraint(new MonomorphicConstraint(origin, args.get(0), args.get(1))); - return new BoolType(Collections.singletonList(origin)); - }, - (builder, origin, registry, arguments, typeMap, localStrategy, globalStrategy) -> { - GoExpression lhs = arguments.get(0).accept( - new TLAExpressionCodeGenVisitor(builder, registry, typeMap, localStrategy, globalStrategy)); - GoExpression rhs = arguments.get(1).accept( - new TLAExpressionCodeGenVisitor(builder, registry, typeMap, localStrategy, globalStrategy)); - return typeMap.get(arguments.get(0).getUID()) - .accept(new TypeConversionVisitor()) - .accept(new EqCodeGenVisitor(builder, lhs, rhs, true)); - })); - universalBuiltIns.addOperator("\\in", new BuiltinOperator( - 2, - (origin, args, solver, generator) -> { - TypeVariable memberType = generator.getTypeVariable(Collections.singletonList(origin)); - solver.addConstraint(new MonomorphicConstraint(origin, args.get(0), memberType)); - solver.addConstraint(new MonomorphicConstraint( - origin, args.get(1), new SetType(memberType, Collections.singletonList(origin)))); - return new BoolType(Collections.singletonList(origin)); - }, - (builder, origin, registry, arguments, typeMap, localStrategy, globalStrategy) -> { - if (arguments.size() != 2) { - throw new InternalCompilerError(); - } - - // index := sort.SearchType(rhs, lhs) - // index < len(rhs) && rhs[index] == lhs - GoExpression val = arguments.get(0).accept( - new TLAExpressionCodeGenVisitor(builder, registry, typeMap, localStrategy, globalStrategy)); - GoExpression set = arguments.get(1).accept( - new TLAExpressionCodeGenVisitor(builder, registry, typeMap, localStrategy, globalStrategy)); - - GoType elementType = getSetElementType(typeMap.get(arguments.get(1).getUID())); - GoVariableName index = getIndexInSet(builder, elementType, set, val); - - // index < len(set) - GoExpression withinBounds = new GoBinop( - GoBinop.Operation.LT, - index, - new GoCall(new GoVariableName("len"), Collections.singletonList(set))); - - // set[index] == val - GoExpression element = new GoIndexExpression(set, index); - GoExpression equalsVal = elementType.accept(new EqCodeGenVisitor(builder, element, val, false)); - - return new GoBinop(GoBinop.Operation.AND, withinBounds, equalsVal); - } - )); - universalBuiltIns.addOperator("\\notin", new BuiltinOperator( - 2, - (origin, args, solver, generator) -> { - throw new TODO(); - }, - (builder, origin, registry, arguments, typeMap, localStrategy, globalStrategy) -> { - throw new TODO(); - } - )); - universalBuiltIns.addOperator("\\", new BuiltinOperator( - 2, - (origin, args, solver, generator) -> { - Type fresh = new SetType( - generator.getTypeVariable(Collections.singletonList(origin)), - Collections.singletonList(origin)); - solver.addConstraint(new MonomorphicConstraint(origin, args.get(0), fresh)); - solver.addConstraint(new MonomorphicConstraint(origin, args.get(1), fresh)); - return fresh; - }, - (builder, origin, registry, arguments, typeMap, localStrategy, globalStrategy) -> { - // lenLhs = len(lhs) - // tmpSet := make([]type, 0, lenLhs) - // for _, v := range lhs { - // index := sort.SearchType(rhs, v) - // if index < len(rhs) { - // if rhs[index] == v { - // continue - // } - // } - // // keep the element - // tmpSet = append(tmpSet, v) - // } - GoType elementType = getSetElementType(typeMap.get(origin.getUID())); - GoExpression lhs = arguments.get(0).accept( - new TLAExpressionCodeGenVisitor(builder, registry, typeMap, localStrategy, globalStrategy)); - GoExpression rhs = arguments.get(1).accept( - new TLAExpressionCodeGenVisitor(builder, registry, typeMap, localStrategy, globalStrategy)); - - // special case: rhs is an empty literal, compiles to noop - if (rhs instanceof GoSliceLiteral && ((GoSliceLiteral)rhs).getInitializers().size() == 0){ - return lhs; - } - - GoExpression lenLhs = new GoCall(new GoVariableName("len"), Collections.singletonList(lhs)); - GoExpression lenRhs = new GoCall(new GoVariableName("len"), Collections.singletonList(rhs)); - GoVariableName tmpSet = builder.varDecl( - "tmpSet", - new GoMakeExpression( - new GoSliceType(elementType), - new GoIntLiteral(0), - lenLhs)); - GoForRangeBuilder forBuilder = builder.forRange(lhs); - GoVariableName v = forBuilder.initVariables(Arrays.asList("_", "v")).get(1); - try (GoBlockBuilder forBody = forBuilder.getBlockBuilder()) { - // special case where rhs is a slice literal, we just unroll the entire literal instead - // of searching through it - if (rhs instanceof GoSliceLiteral){ - GoSliceLiteral rhsLiteral = (GoSliceLiteral)rhs; - GoExpression condition = null; - for(GoExpression option : rhsLiteral.getInitializers()){ - GoExpression part = elementType.accept(new EqCodeGenVisitor( - forBody, v, option, true)); - if(condition == null){ - condition = part; - }else{ - condition = new GoBinop(GoBinop.Operation.AND, condition, part); - } - } - try (GoIfBuilder shouldIncludeBuilder = forBody.ifStmt(condition)){ - try(GoBlockBuilder shouldIncludeBody = shouldIncludeBuilder.whenTrue()){ - shouldIncludeBody.assign( - tmpSet, new GoCall(new GoVariableName("append"), Arrays.asList(tmpSet, v))); - } - } - return tmpSet; - } - - GoVariableName index = getIndexInSet(forBody, elementType, rhs, v); - try (GoIfBuilder ifBuilder = forBody.ifStmt( - new GoBinop(GoBinop.Operation.LT, index, lenRhs))) { - try (GoBlockBuilder yes = ifBuilder.whenTrue()) { - try (GoIfBuilder isEqBuilder = yes.ifStmt(elementType.accept( - new EqCodeGenVisitor( - yes, - new GoIndexExpression(rhs, index), - v, - false)))) { - try (GoBlockBuilder yes2 = isEqBuilder.whenTrue()) { - yes2.addStatement(new GoContinue()); - } - } - } - } - forBody.assign(tmpSet, new GoCall(new GoVariableName("append"), Arrays.asList(tmpSet, v))); - } - return tmpSet; - })); - universalBuiltIns.addOperators(Arrays.asList("~", "\\lnot", "\\neg"), new TypelessBuiltinOperator( - 1, - (origin, args, solver, generator) -> { - Type fresh = new BoolType(Collections.singletonList(origin)); - solver.addConstraint(new MonomorphicConstraint(origin, args.get(0), fresh)); - return fresh; - }, - (builder, origin, registry, arguments, typeMap) -> new GoUnary( - GoUnary.Operation.NOT, arguments.get(0)) - )); - universalBuiltIns.addOperators(Arrays.asList("\\/", "\\lor"), new TypelessBuiltinOperator( - 2, - (origin, args, solver, generator) -> { - Type fresh = new BoolType(Collections.singletonList(origin)); - solver.addConstraint(new MonomorphicConstraint(origin, args.get(0), fresh)); - solver.addConstraint(new MonomorphicConstraint(origin, args.get(1), fresh)); - return fresh; - }, - (builder, origin, registry, arguments, typeMap) -> new GoBinop( - GoBinop.Operation.OR, arguments.get(0), arguments.get(1)) - )); - universalBuiltIns.addOperators(Arrays.asList("/\\", "\\land"), new TypelessBuiltinOperator( - 2, - (origin, args, solver, generator) -> { - Type fresh = new BoolType(Collections.singletonList(origin)); - solver.addConstraint(new MonomorphicConstraint(origin, args.get(0), fresh)); - solver.addConstraint(new MonomorphicConstraint(origin, args.get(1), fresh)); - return fresh; - }, - (builder, origin, registry, arguments, typeMap) -> new GoBinop( - GoBinop.Operation.AND, arguments.get(0), arguments.get(1)) - )); - universalBuiltIns.addOperators(Arrays.asList("\\union", "\\cup"), new TypelessBuiltinOperator( - 2, - (origin, args, solver, generator) -> { - Type fresh = new SetType( - generator.getTypeVariable(Collections.singletonList(origin)), - Collections.singletonList(origin)); - solver.addConstraint(new MonomorphicConstraint(origin, args.get(0), fresh)); - solver.addConstraint(new MonomorphicConstraint(origin, args.get(1), fresh)); - return fresh; - }, - (builder, origin, registry, arguments, typeMap) -> { - GoType elementType = getSetElementType(typeMap.get(origin.getUID())); - GoExpression lhs = arguments.get(0); - GoExpression rhs = arguments.get(1); - GoExpression lhsLen = new GoCall(new GoVariableName("len"), Collections.singletonList(lhs)); - GoExpression combinedLen = new GoBinop( - GoBinop.Operation.PLUS, - lhsLen, - new GoCall(new GoVariableName("len"), Collections.singletonList(rhs))); - GoVariableName tmpSet = builder.varDecl( - "tmpSet", - new GoMakeExpression(new GoSliceType(elementType), lhsLen, combinedLen)); - // since append may re-use the same memory, we have to copy lhs in order to be sure - // that we are not going to overwrite the original slice when we sort - builder.addStatement(new GoCall(new GoVariableName("copy"), Arrays.asList(tmpSet, lhs))); - builder.assign(tmpSet, new GoCall(new GoVariableName("append"), Arrays.asList(tmpSet, rhs), true)); - ensureUniqueSorted(builder, elementType, tmpSet); - return tmpSet; - })); - } - - private static final Map builtinModules = new HashMap<>(); - static { - BuiltinModule TLC = new BuiltinModule(); - builtinModules.put("TLC", TLC); - - - BuiltinModule Sequences = new BuiltinModule(); - builtinModules.put("Sequences", Sequences); - Sequences.addOperator("Len", new TypelessBuiltinOperator( - 1, - (origin, args, solver, generator) -> { - solver.addConstraint(new PolymorphicConstraint(origin, Arrays.asList( - Collections.singletonList(new EqualityConstraint( - args.get(0), - new SliceType( - generator.getTypeVariable(Collections.singletonList(origin)), - Collections.singletonList(origin)))), - Collections.singletonList(new EqualityConstraint( - args.get(0), new StringType(Collections.singletonList(origin))))))); - return new IntType(Collections.singletonList(origin)); - }, - (builder, origin, registry, arguments, typeMap) -> new GoCall( - new GoVariableName("len"), Collections.singletonList(arguments.get(0))) - )); - Sequences.addOperator("Append", new BuiltinOperator( - 2, - (origin, args, solver, generator) -> { - TypeVariable elementType = generator.getTypeVariable(Collections.singletonList(origin)); - Type fresh = new SliceType(elementType, Collections.singletonList(origin)); - solver.addConstraint(new MonomorphicConstraint(origin, args.get(0), fresh)); - solver.addConstraint(new MonomorphicConstraint(origin, args.get(1), elementType)); - return fresh; - }, - (builder, origin, registry, arguments, typeMap, localStrategy, globalStrategy) -> { - GoType baseType = typeMap.get(arguments.get(0).getUID()).accept(new TypeConversionVisitor()); - GoExpression base = arguments.get(0).accept( - new TLAExpressionCodeGenVisitor(builder, registry, typeMap, localStrategy, globalStrategy)); - GoExpression extra = arguments.get(1).accept( - new TLAExpressionCodeGenVisitor(builder, registry, typeMap, localStrategy, globalStrategy)); - - GoExpression baseLen = new GoCall(new GoVariableName("len"), Collections.singletonList(base)); - // since append may reuse the underlying slice, it is possible that appending two different - // things to the same original slice will causes unintended mutations in the results of previous - // appends. copy the original slice to be sure. - GoVariableName tmpSlice = builder.varDecl( - "tmpSlice", - new GoMakeExpression( - baseType, - baseLen, - new GoBinop(GoBinop.Operation.PLUS, baseLen, new GoIntLiteral(1)))); - builder.addStatement(new GoCall(new GoVariableName("copy"), Arrays.asList(tmpSlice, base))); - builder.assign(tmpSlice, new GoCall(new GoVariableName("append"), Arrays.asList(tmpSlice, extra))); - return tmpSlice; - })); - Sequences.addOperator("Head", new TypelessBuiltinOperator( - 1, - (origin, args, solver, generator) -> { - TypeVariable elementType = generator.getTypeVariable(Collections.singletonList(origin)); - solver.addConstraint(new MonomorphicConstraint( - origin, args.get(0), new SliceType(elementType, Collections.singletonList(origin)))); - return elementType; - }, - (builder, origin, registry, arguments, typeMap) -> - new GoIndexExpression(arguments.get(0), new GoIntLiteral(0)))); - Sequences.addOperator("Tail", new TypelessBuiltinOperator( - 1, - (origin, args, solver, generator) -> { - TypeVariable elementType = generator.getTypeVariable(Collections.singletonList(origin)); - Type fresh = new SliceType(elementType, Collections.singletonList(origin)); - solver.addConstraint(new MonomorphicConstraint(origin, args.get(0), fresh)); - return fresh; - }, - (builder, origin, registry, arguments, typeMap) -> new GoSliceOperator( - arguments.get(0), new GoIntLiteral(1), null, null) - )); - Sequences.addOperator("\\o", new BuiltinOperator( - 2, - (origin, args, solver, generator) -> { - TypeVariable memberType = generator.getTypeVariable(Collections.singletonList(origin)); - Type sliceType = new SliceType(memberType, Collections.singletonList(origin)); - solver.addConstraint(new MonomorphicConstraint(origin, args.get(0), sliceType)); - solver.addConstraint(new MonomorphicConstraint(origin, args.get(1), sliceType)); - return sliceType; - }, - (builder, origin, registry, arguments, typeMap, localStrategy, globalStrategy) -> { - if (arguments.size() != 2) { - throw new InternalCompilerError(); - } - - // s1 = append(s1, s2...) - GoExpression s1 = arguments.get(0).accept(new TLAExpressionCodeGenVisitor(builder, registry, typeMap, localStrategy, globalStrategy)); - GoExpression s2 = arguments.get(1).accept(new TLAExpressionCodeGenVisitor(builder, registry, typeMap, localStrategy, globalStrategy)); - - GoVariableName seqName = builder.varDecl("sequence", s1); - GoExpression append = new GoCall(new GoVariableName("append"), Arrays.asList(seqName, s2), true); - builder.assign(seqName, append); - - return seqName; - } - )); - Sequences.addOperator("SubSeq", new BuiltinOperator( - 3, - (origin, args, solver, generator) -> { - TypeVariable memberType = generator.getTypeVariable(Collections.singletonList(origin)); - Type sliceType = new SliceType(memberType, Collections.singletonList(origin)); - solver.addConstraint(new MonomorphicConstraint(origin, args.get(0), sliceType)); - solver.addConstraint(new MonomorphicConstraint( - origin, args.get(1), new IntType(Collections.singletonList(origin)))); - solver.addConstraint(new MonomorphicConstraint( - origin, args.get(2), new IntType(Collections.singletonList(origin)))); - return sliceType; - }, - (builder, origin, registry, arguments, typeMap, localStrategy, globalStrategy) -> { - if (arguments.size() != 3) { - throw new InternalCompilerError(); - } - - // assuming the call is SubSeq(slice, start, end) - GoExpression slice = arguments.get(0).accept( - new TLAExpressionCodeGenVisitor(builder, registry, typeMap, localStrategy, globalStrategy)); - GoExpression start = builder.varDecl( - "start", - arguments.get(1).accept(new TLAExpressionCodeGenVisitor( - builder, registry, typeMap, localStrategy, globalStrategy))); - GoExpression end = builder.varDecl( - "end", - arguments.get(2).accept(new TLAExpressionCodeGenVisitor( - builder, registry, typeMap, localStrategy, globalStrategy))); - - - GoSliceType sliceType = (GoSliceType) typeMap.get(arguments.get(0).getUID()) - .accept(new TypeConversionVisitor()); - // var tmpSlice []Type - GoVariableName tmpSlice = builder.varDecl( - "tmpSlice", - typeMap.get(arguments.get(0).getUID()).accept(new TypeConversionVisitor())); - // if start > end { - // tmpSlice = []Type{} - // } else { - // tmpSlice = make([]Type, (1+end)-start) - // } - try (GoIfBuilder ifStmt = builder.ifStmt(new GoBinop(GoBinop.Operation.GT, start, end))) { - try (GoBlockBuilder yes = ifStmt.whenTrue()) { - yes.assign( - tmpSlice, new GoSliceLiteral(sliceType.getElementType(), Collections.emptyList())); - } - try (GoBlockBuilder no = ifStmt.whenFalse()) { - no.assign( - tmpSlice, - new GoMakeExpression( - sliceType, - new GoBinop( - GoBinop.Operation.MINUS, - new GoBinop(GoBinop.Operation.PLUS, new GoIntLiteral(1), end), - start))); - } - } - // copy(tmpSlice, slice[start-1:end]) - builder.addStatement(new GoCall( - new GoVariableName("copy"), - Arrays.asList( - tmpSlice, - new GoSliceOperator( - slice, - new GoBinop(GoBinop.Operation.MINUS, start, new GoIntLiteral(1)), - end, - null)))); - - return tmpSlice; - } - )); - - BuiltinModule Naturals = new BuiltinModule(); - builtinModules.put("Naturals", Naturals); - Naturals.addOperator("-", new TypelessBuiltinOperator( - 2, - TLABuiltins::constraintNumberOperation, - (builder, origin, registry, arguments, typeMap) -> new GoBinop( - GoBinop.Operation.MINUS, arguments.get(0), arguments.get(1)) - )); - Naturals.addOperator("+", new TypelessBuiltinOperator( - 2, - TLABuiltins::constraintNumberOperation, - (builder, origin, registry, arguments, typeMap) -> new GoBinop( - GoBinop.Operation.PLUS, arguments.get(0), arguments.get(1)) - )); - Naturals.addOperator("%", new TypelessBuiltinOperator( - 2, - TLABuiltins::constraintNumberOperation, - (builder, origin, registry, arguments, typeMap) -> new GoBinop( - GoBinop.Operation.MOD, arguments.get(0), arguments.get(1)) - )); - Naturals.addOperator("*", new TypelessBuiltinOperator( - 2, - TLABuiltins::constraintNumberOperation, - (builder, origin, registry, arguments, typeMap) -> new GoBinop( - GoBinop.Operation.TIMES, arguments.get(0), arguments.get(1)) - )); - Naturals.addOperator("<", new TypelessBuiltinOperator( - 2, - TLABuiltins::constraintBooleanNumberOperation, - (builder, origin, registry, arguments, typeMap) -> new GoBinop( - GoBinop.Operation.LT, arguments.get(0), arguments.get(1)) - )); - Naturals.addOperator(">", new TypelessBuiltinOperator( - 2, - TLABuiltins::constraintBooleanNumberOperation, - (builder, origin, registry, arguments, typeMap) -> new GoBinop( - GoBinop.Operation.GT, arguments.get(0), arguments.get(1)) - )); - Naturals.addOperators(Arrays.asList("<=", "\\leq"), new TypelessBuiltinOperator( - 2, - TLABuiltins::constraintBooleanNumberOperation, - (builder, origin, registry, arguments, typeMap) -> new GoBinop( - GoBinop.Operation.LEQ, arguments.get(0), arguments.get(1)) - )); - Naturals.addOperators(Arrays.asList(">=", "\\geq"), new TypelessBuiltinOperator( - 2, - TLABuiltins::constraintBooleanNumberOperation, - (builder, origin, registry, arguments, typeMap) -> new GoBinop( - GoBinop.Operation.GEQ, arguments.get(0), arguments.get(1)) - )); - Naturals.addOperator("Nat", new TypelessBuiltinOperator( - 0, - (origin, args, solver, generator) -> new NonEnumerableSetType(new IntType(Collections.singletonList(origin)), Collections.singletonList(origin)), - (builder, origin, registry, arguments, typeMap) -> { - throw new TODO(); - } - )); - Naturals.addOperator("..", new TypelessBuiltinOperator( - 2, - (origin, args, solver, generator) -> { - Type intType = new IntType(Collections.singletonList(origin)); - solver.addConstraint(new MonomorphicConstraint(origin, args.get(0), intType)); - solver.addConstraint(new MonomorphicConstraint(origin, args.get(1), intType)); - return new SetType(intType, Collections.singletonList(origin)); - }, - (builder, origin, registry, arguments, typeMap) -> { - GoExpression from = arguments.get(0); - GoExpression to = arguments.get(1); - GoExpression tmpRange = builder.varDecl("tmpRange", new GoMakeExpression( - new GoSliceType(GoBuiltins.Int), - new GoBinop( - GoBinop.Operation.PLUS, - new GoBinop(GoBinop.Operation.MINUS, to, from), - new GoIntLiteral(1)), - null)); - - GoForStatementClauseBuilder clauseBuilder = builder.forLoopWithClauses(); - GoVariableName acc = clauseBuilder.initVariable("i", from); - clauseBuilder.setCondition(new GoBinop(GoBinop.Operation.LEQ, acc, to)); - clauseBuilder.setInc(new GoIncDec(true, acc)); - - try (GoBlockBuilder body = clauseBuilder.getBlockBuilder()) { - body.assign( - new GoIndexExpression(tmpRange, new GoBinop(GoBinop.Operation.MINUS, acc, from)), - acc); - } - return tmpRange; - })); - - BuiltinModule Integers = new BuiltinModule(Naturals); - builtinModules.put("Integers", Integers); - Integers.addOperator("-_", new TypelessBuiltinOperator( - 1, - (origin, args, solver, generator) -> { - TypeVariable fresh = getPolymorphicNumberType(origin, solver, generator); - solver.addConstraint(new MonomorphicConstraint(origin, args.get(0), fresh)); - return fresh; - }, - (builder, origin, registry, arguments, typeMap) -> - new GoUnary(GoUnary.Operation.NEG, arguments.get(0)))); - Integers.addOperator("Int", new TypelessBuiltinOperator( - 0, - (origin, args, solver, generator) -> new NonEnumerableSetType(new IntType(Collections.singletonList(origin)), Collections.singletonList(origin)), - (builder, origin, registry, arguments, typeMap) -> { - throw new TODO(); - })); - - BuiltinModule FiniteSets = new BuiltinModule(); - builtinModules.put("FiniteSets", FiniteSets); - FiniteSets.addOperator("Cardinality", new TypelessBuiltinOperator( - 1, - (origin, args, solver, generator) -> { - solver.addConstraint(new MonomorphicConstraint( - origin, - args.get(0), - new SetType( - generator.getTypeVariable(Collections.singletonList(origin)), - Collections.singletonList(origin)))); - return new IntType(Collections.singletonList(origin)); - }, - (builder, origin, registry, arguments, typeMap) -> { - // len(set) - if (arguments.size() != 1) { - throw new InternalCompilerError(); - } - - return new GoCall(new GoVariableName("len"), Collections.singletonList(arguments.get(0))); - } - )); - FiniteSets.addOperator("IsFiniteSet", new TypelessBuiltinOperator( - 1, - (origin, args, solver, generator) -> { - throw new TODO(); - }, - (builder, origin, registry, arguments, typeMap) -> { - throw new TODO(); - } - )); - - BuiltinModule Bags = new BuiltinModule(); - builtinModules.put("Bags", Bags); - - BuiltinModule ProtoReals = new BuiltinModule(); - builtinModules.put("ProtoReals", ProtoReals); - - BuiltinModule Peano = new BuiltinModule(); - builtinModules.put("Peano", Peano); - - BuiltinModule Reals = new BuiltinModule(); - builtinModules.put("Reals", Reals); - } - - private static void fillDefinitionRegistryFromBuiltinModule(DefinitionRegistry registry, BuiltinModule module, TLABuiltinModules.TLABuiltinModule tlaModule) { - tlaModule.members().foreach(defn -> { - OperatorAccessor accessor = module.getOperators().get(defn.identifier().getId()); - if(accessor == null) { - final String unsupportedMsg; - if(tlaModule.identifier().getId().equals("")) { - unsupportedMsg = "unsupported TLA+ operator "+defn.identifier().getId(); - } else { - unsupportedMsg = "unsupported TLA+ operator "+tlaModule.identifier().getId()+"!"+defn.identifier().getId(); - } - // add a dummy operator that throws "unsupported!" if we ever try to meaningfully use it - registry.addOperator(defn.getUID(), new OperatorAccessor() { - @Override - public Type constrainTypes(Origin origin, DefinitionRegistry registry, List args, TypeSolver solver, TypeGenerator generator, Map mapping) { - throw new UnsupportedFeatureIssue(unsupportedMsg); - } - - @Override - public int getArgumentCount() { - throw new UnsupportedFeatureIssue(unsupportedMsg); - } - - @Override - public UID getUID() { - throw new UnsupportedFeatureIssue(unsupportedMsg); - } - - @Override - public GoExpression generateGo(GoBlockBuilder builder, TLAExpression origin, DefinitionRegistry registry, List args, Map typeMap, LocalVariableStrategy localStrategy, GlobalVariableStrategy globalStrategy) { - throw new UnsupportedFeatureIssue(unsupportedMsg); - } - }); - } else { - registry.addOperator(defn.getUID(), accessor); - } - return null; - }); - } - - public static void fillDefinitionRegistry(DefinitionRegistry registry) { - fillDefinitionRegistryFromBuiltinModule(registry, universalBuiltIns, TLABuiltinModules.Intrinsics$.MODULE$); - TLABuiltinModules.builtinModules().foreach(pair -> { - String name = pair._1().getId(); - TLABuiltinModules.TLABuiltinModule tlaModule = pair._2(); - fillDefinitionRegistryFromBuiltinModule(registry, Objects.requireNonNull(builtinModules.get(name)), tlaModule); - return null; - }); - } - - public static BuiltinModule getUniversalBuiltIns() { - return universalBuiltIns; - } - - public static BuiltinModule findBuiltinModule(String name) { - return builtinModules.get(name); - } - - public static boolean isBuiltinModule(String name) { - return builtinModules.containsKey(name); - } - - public static Map getInitialDefinitions() { - Map defs = new HashMap<>(); - for(Map.Entry op : universalBuiltIns.getOperators().entrySet()) { - defs.put(new QualifiedName(op.getKey()), op.getValue().getUID()); - } - return defs; - } -} diff --git a/src/pgo/trans/intermediate/TypelessBuiltinOperator.java b/src/pgo/trans/intermediate/TypelessBuiltinOperator.java deleted file mode 100644 index 81b6f4feb..000000000 --- a/src/pgo/trans/intermediate/TypelessBuiltinOperator.java +++ /dev/null @@ -1,42 +0,0 @@ -package pgo.trans.intermediate; - -import pgo.model.golang.GoExpression; -import pgo.model.golang.builder.GoBlockBuilder; -import pgo.model.tla.TLAExpression; -import pgo.model.type.Type; -import pgo.scope.UID; -import pgo.trans.passes.codegen.go.TLAExpressionCodeGenVisitor; - -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -public class TypelessBuiltinOperator extends BuiltinOperator { - - public interface TypelessGoGenerator { - GoExpression generate(GoBlockBuilder builder, TLAExpression expr, DefinitionRegistry registry, - List arguments, Map typeMap); - } - - public TypelessBuiltinOperator(int argumentCount, TypeConstraintGenerator typeConstraintGenerator, - TypelessGoGenerator goGenerator) { - super( - argumentCount, - typeConstraintGenerator, - (builder, origin, registry, arguments, typeMap, localStrategy, globalStrategy) -> - goGenerator.generate( - builder, - origin, - registry, - arguments.stream().map(a -> a.accept( - new TLAExpressionCodeGenVisitor( - builder, - registry, - typeMap, - localStrategy, - globalStrategy))) - .collect(Collectors.toList()), - typeMap)); - } - -} diff --git a/src/pgo/trans/intermediate/UnsupportedFeatureIssue.java b/src/pgo/trans/intermediate/UnsupportedFeatureIssue.java deleted file mode 100644 index 25ecf8b79..000000000 --- a/src/pgo/trans/intermediate/UnsupportedFeatureIssue.java +++ /dev/null @@ -1,24 +0,0 @@ -package pgo.trans.intermediate; - -import pgo.errors.Issue; -import pgo.errors.IssueVisitor; - -public class UnsupportedFeatureIssue extends Issue { - - String message; - - public UnsupportedFeatureIssue(String message) { - super(); - this.message = message; - } - - public String getMessage() { - return message; - } - - @Override - public T accept(IssueVisitor v) throws E { - return v.visit(this); - } - -} diff --git a/src/pgo/trans/intermediate/WhileLoadingUnit.java b/src/pgo/trans/intermediate/WhileLoadingUnit.java deleted file mode 100644 index 3375e19bb..000000000 --- a/src/pgo/trans/intermediate/WhileLoadingUnit.java +++ /dev/null @@ -1,24 +0,0 @@ -package pgo.trans.intermediate; - -import pgo.errors.Context; -import pgo.errors.ContextVisitor; -import pgo.util.SourceLocatable; - -public class WhileLoadingUnit extends Context { - - SourceLocatable unit; - - public WhileLoadingUnit(SourceLocatable unit) { - this.unit = unit; - } - - public SourceLocatable getUnit() { - return unit; - } - - @Override - public T accept(ContextVisitor ctx) throws E { - return ctx.visit(this); - } - -} diff --git a/src/pgo/trans/passes/atomicity/AtomicityInferencePass.java b/src/pgo/trans/passes/atomicity/AtomicityInferencePass.java deleted file mode 100644 index cfca0867f..000000000 --- a/src/pgo/trans/passes/atomicity/AtomicityInferencePass.java +++ /dev/null @@ -1,98 +0,0 @@ -package pgo.trans.passes.atomicity; - -import pgo.InternalCompilerError; -import pgo.model.tla.TLAExpression; -import pgo.model.tla.TLAGeneralIdentifier; -import pgo.util.UnionFind; -import pgo.model.mpcal.ModularPlusCalBlock; -import pgo.model.pcal.*; -import pgo.scope.UID; -import pgo.trans.intermediate.DefinitionRegistry; - -import java.util.*; -import java.util.function.BiConsumer; - -public class AtomicityInferencePass { - private AtomicityInferencePass() {} - - private static void trackGlobalVar(DefinitionRegistry registry, Map> map, TLAExpression expression, UID labelUID) { - // we are only interested in writes to variable expressions. - // Function calls are only dealt with in MPCal - if (expression instanceof TLAGeneralIdentifier) { - UID definitionUID = registry.followReference(expression.getUID()); - if (registry.isGlobalVariable(definitionUID)) { - map.putIfAbsent(definitionUID, new HashSet<>()); - map.get(definitionUID).add(labelUID); - } - } - } - - private static void addToUnionFind(UnionFind unionFind, Map> map) { - for (Map.Entry> entry : map.entrySet()) { - UID varUID = entry.getKey(); - for (UID labelUID : entry.getValue()) { - unionFind.union(labelUID, varUID); - } - } - } - - public static void perform(DefinitionRegistry registry, ModularPlusCalBlock modularPlusCalBlock) { - if (modularPlusCalBlock.getProcesses() instanceof PlusCalMultiProcess) { - Map> globalVarReadsToLabel = new HashMap<>(); - Map> globalVarWritesToLabel = new HashMap<>(); - BiConsumer captureLabelRead = (expression, labelUID) -> - trackGlobalVar(registry, globalVarReadsToLabel, expression, labelUID); - BiConsumer captureLabelWrite = (expression, labelUID) -> - trackGlobalVar(registry, globalVarWritesToLabel, expression, labelUID); - Set foundLabels = new HashSet<>(); - for (PlusCalProcedure p : modularPlusCalBlock.getProcedures()) { - for (PlusCalStatement statements : p.getBody()) { - statements.accept(new PlusCalStatementAtomicityInferenceVisitor( - new UID(), captureLabelRead, captureLabelWrite, foundLabels)); - } - } - for (PlusCalProcess p : ((PlusCalMultiProcess) modularPlusCalBlock.getProcesses()).getProcesses()) { - for (PlusCalStatement statements : p.getBody()) { - statements.accept(new PlusCalStatementAtomicityInferenceVisitor( - new UID(), captureLabelRead, captureLabelWrite, foundLabels)); - } - } - UnionFind unionFind = new UnionFind<>(); - addToUnionFind(unionFind, globalVarReadsToLabel); - addToUnionFind(unionFind, globalVarWritesToLabel); - Map seenRoots = new HashMap<>(); - for (UID labelUID : foundLabels) { - if (unionFind.getRank(labelUID) > 0) { - UID rootUID = unionFind.find(labelUID); - if (!seenRoots.containsKey(rootUID)) { - seenRoots.put(rootUID, seenRoots.size()); - } - registry.addLabelToLockGroup(labelUID, seenRoots.get(rootUID)); - } - } - for (UID varUID : registry.globalVariables()) { - if (unionFind.getRank(varUID) > 0) { - registry.addProtectedGlobalVariable(varUID); - int lockGroup = seenRoots.get(unionFind.find(varUID)); - boolean isRead = globalVarReadsToLabel.getOrDefault(varUID, Collections.emptySet()) - .stream() - .map(registry::getLockGroup) - .anyMatch(i -> i.equals(lockGroup)); - boolean isWritten = globalVarWritesToLabel.getOrDefault(varUID, Collections.emptySet()) - .stream() - .map(registry::getLockGroup) - .anyMatch(i -> i.equals(lockGroup)); - if (!isRead && !isWritten) { - throw new InternalCompilerError(); - } - if (isRead) { - registry.addVariableReadToLockGroup(varUID, lockGroup); - } - if (isWritten) { - registry.addVariableWriteToLockGroup(varUID, lockGroup); - } - } - } - } - } -} diff --git a/src/pgo/trans/passes/atomicity/ModularPlusCalAtomicityInferencePass.java b/src/pgo/trans/passes/atomicity/ModularPlusCalAtomicityInferencePass.java deleted file mode 100644 index d37d2b4a9..000000000 --- a/src/pgo/trans/passes/atomicity/ModularPlusCalAtomicityInferencePass.java +++ /dev/null @@ -1,140 +0,0 @@ -package pgo.trans.passes.atomicity; - -import pgo.InternalCompilerError; -import pgo.Unreachable; -import pgo.model.mpcal.*; -import pgo.model.tla.*; -import pgo.model.pcal.*; -import pgo.scope.UID; -import pgo.trans.intermediate.DefinitionRegistry; - -import java.util.*; -import java.util.function.BiConsumer; -import java.util.stream.Collectors; - -public class ModularPlusCalAtomicityInferencePass { - private ModularPlusCalAtomicityInferencePass() {} - - private static void trackResource(DefinitionRegistry registry, Map mappings, Map> map, Set locals, TLAExpression expression, UID labelUID) { - boolean track = false; - - if (expression instanceof TLAGeneralIdentifier) { - String id = ((TLAGeneralIdentifier) expression).getName().getId(); - - // if the name is a resource and is *not* function-mapped, it needs - // to be tracked. - if (mappings.containsKey(id)) { - track = !mappings.get(id); - } else { - // track locals access per label - UID ref = registry.followReference(expression.getUID()); - - // only keep track of locals declared in the archetype. This filters - // out short-lived local variables like the ones used in - // set refinements or with statements. - if (registry.isLocalVariable(ref) && locals.contains(ref)) { - registry.addLocalToLabel(labelUID, ref); - } - } - - } else if (expression instanceof TLAFunctionCall) { - TLAExpression function = ((TLAFunctionCall) expression).getFunction(); - - if (function instanceof TLAGeneralIdentifier) { - String id = ((TLAGeneralIdentifier) function).getName().getId(); - - // if the function is an archetype resource and *is* function - // mapped, it needs to be tracked - if (mappings.containsKey(id) && mappings.get(id)) { - track = true; - } - } - } else { - throw new InternalCompilerError(); - } - - if (track) { - map.putIfAbsent(labelUID, new HashSet<>()); - map.get(labelUID).add(expression); - } - } - - public static void perform(DefinitionRegistry registry, ModularPlusCalBlock modularPlusCalBlock) { - int lockGroups = 0; - - for (ModularPlusCalArchetype archetype : modularPlusCalBlock.getArchetypes()) { - Map> labelToResourceReads = new HashMap<>(); - Map> labelToResourceWrites = new HashMap<>(); - Map mappings = new HashMap<>(); - - // build a map from resource's name to whether they are function mapped or not - // By default, every archetype resource is non-function mapped - archetype.getParams().forEach(p -> mappings.put(p.getName().getId(), false)); - - // if there is one instantiation where a resource is function mapped, update - // the mappings accordingly - for (ModularPlusCalInstance instance : modularPlusCalBlock.getInstances()) { - if (instance.getTarget().equals(archetype.getName())) { - Map resourceVars = new HashMap<>(); - - ListIterator it = instance.getArguments().listIterator(); - while (it.hasNext()) { - TLAExpression arg = it.next(); - - if (arg instanceof TLAGeneralIdentifier) { - String argName = ((TLAGeneralIdentifier) arg).getName().getId(); - resourceVars.put(argName, it.nextIndex()-1); - } else if (arg instanceof TLARef) { - String refName = ((TLARef) arg).getTarget(); - resourceVars.put(refName, it.nextIndex()-1); - } - } - - for (ModularPlusCalMapping m : instance.getMappings()) { - int pos; - if (m.getVariable() instanceof ModularPlusCalMappingVariableName) { - pos = resourceVars.get(((ModularPlusCalMappingVariableName) m.getVariable()).getName()); - } else if (m.getVariable() instanceof ModularPlusCalMappingVariablePosition) { - // position-mapping is 1-indexed - pos = ((ModularPlusCalMappingVariablePosition) m.getVariable()).getPosition() - 1; - } else { - throw new Unreachable(); - } - mappings.put(archetype.getParams().get(pos).getName().getId(), m.getVariable().isFunctionCall()); - } - } - } - - Set locals = archetype - .getVariables() - .stream() - .map(PlusCalVariableDeclaration::getUID) - .collect(Collectors.toSet()); - - BiConsumer captureLabelRead = (expression, labelUID) -> - trackResource(registry, mappings, labelToResourceReads, locals, expression, labelUID); - - BiConsumer captureLabelWrite = (expression, labelUID) -> - trackResource(registry, mappings, labelToResourceWrites, locals, expression, labelUID); - - Set foundLabels = new HashSet<>(); - for (PlusCalStatement statement : archetype.getBody()) { - statement.accept(new PlusCalStatementAtomicityInferenceVisitor( - new UID(), captureLabelRead, captureLabelWrite, foundLabels)); - } - - for (UID labelUID : foundLabels) { - int lockGroup = lockGroups++; - registry.addLabelToLockGroup(labelUID, lockGroup); - - labelToResourceReads.getOrDefault(labelUID, Collections.emptySet()).forEach(resource -> - registry.addResourceReadToLockGroup(resource, lockGroup) - ); - - labelToResourceWrites.getOrDefault(labelUID, Collections.emptySet()).forEach(resource -> - registry.addResourceWriteToLockGroup(resource, lockGroup) - ); - } - } - } -} \ No newline at end of file diff --git a/src/pgo/trans/passes/atomicity/PlusCalStatementAtomicityInferenceVisitor.java b/src/pgo/trans/passes/atomicity/PlusCalStatementAtomicityInferenceVisitor.java deleted file mode 100644 index 91b723ec3..000000000 --- a/src/pgo/trans/passes/atomicity/PlusCalStatementAtomicityInferenceVisitor.java +++ /dev/null @@ -1,131 +0,0 @@ -package pgo.trans.passes.atomicity; - -import pgo.TODO; -import pgo.Unreachable; -import pgo.model.mpcal.ModularPlusCalYield; -import pgo.model.pcal.*; -import pgo.model.tla.TLAExpression; -import pgo.scope.UID; - -import java.util.Set; -import java.util.function.BiConsumer; - -public class PlusCalStatementAtomicityInferenceVisitor extends PlusCalStatementVisitor { - private final UID currentLabelUID; - private final BiConsumer captureLabelRead; - private final BiConsumer captureLabelWrite; - private final Set foundLabels; - private final TLAExpressionValueAtomicityInferenceVisitor visitor; - - public PlusCalStatementAtomicityInferenceVisitor(UID currentLabelUID, BiConsumer captureLabelRead, - BiConsumer captureLabelWrite, Set foundLabels) { - this.currentLabelUID = currentLabelUID; - this.captureLabelRead = captureLabelRead; - this.captureLabelWrite = captureLabelWrite; - this.foundLabels = foundLabels; - this.visitor = new TLAExpressionValueAtomicityInferenceVisitor(expression -> - captureLabelRead.accept(expression, currentLabelUID)); - } - - @Override - public Void visit(PlusCalLabeledStatements plusCalLabeledStatements) throws RuntimeException { - UID labelUID = plusCalLabeledStatements.getLabel().getUID(); - foundLabels.add(labelUID); - PlusCalStatementAtomicityInferenceVisitor statementVisitor = new PlusCalStatementAtomicityInferenceVisitor( - labelUID, captureLabelRead, captureLabelWrite, foundLabels); - plusCalLabeledStatements.getStatements().forEach(s -> s.accept(statementVisitor)); - return null; - } - - @Override - public Void visit(PlusCalWhile plusCalWhile) throws RuntimeException { - plusCalWhile.getCondition().accept(visitor); - plusCalWhile.getBody().forEach(s -> s.accept(this)); - return null; - } - - @Override - public Void visit(PlusCalIf plusCalIf) throws RuntimeException { - plusCalIf.getCondition().accept(visitor); - plusCalIf.getYes().forEach(s -> s.accept(this)); - plusCalIf.getNo().forEach(s -> s.accept(this)); - return null; - } - - @Override - public Void visit(PlusCalEither plusCalEither) throws RuntimeException { - plusCalEither.getCases().forEach(c -> c.forEach(s -> s.accept(this))); - return null; - } - - @Override - public Void visit(PlusCalAssignment plusCalAssignment) throws RuntimeException { - for (PlusCalAssignmentPair pair : plusCalAssignment.getPairs()) { - pair.getLhs().accept(new TLAExpressionLHSAtomicityInferenceVisitor( - visitor, varUID -> captureLabelWrite.accept(varUID, currentLabelUID))); - pair.getRhs().accept(visitor); - } - return null; - } - - @Override - public Void visit(PlusCalReturn plusCalReturn) throws RuntimeException { - // nothing to do - return null; - } - - @Override - public Void visit(PlusCalSkip plusCalSkip) throws RuntimeException { - // nothing to do - return null; - } - - @Override - public Void visit(PlusCalCall plusCalCall) throws RuntimeException { - plusCalCall.getArguments().forEach(a -> a.accept(visitor)); - return null; - } - - @Override - public Void visit(PlusCalMacroCall macroCall) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(PlusCalWith plusCalWith) throws RuntimeException { - for (PlusCalVariableDeclaration decl : plusCalWith.getVariables()) { - decl.getValue().accept(visitor); - } - plusCalWith.getBody().forEach(s -> s.accept(this)); - return null; - } - - @Override - public Void visit(PlusCalPrint plusCalPrint) throws RuntimeException { - plusCalPrint.getValue().accept(visitor); - return null; - } - - @Override - public Void visit(PlusCalAssert plusCalAssert) throws RuntimeException { - plusCalAssert.getCondition().accept(visitor); - return null; - } - - @Override - public Void visit(PlusCalAwait plusCalAwait) throws RuntimeException { - plusCalAwait.getCondition().accept(visitor); - return null; - } - - @Override - public Void visit(PlusCalGoto plusCalGoto) throws RuntimeException { - // nothing to do - return null; - } - - @Override - public Void visit(ModularPlusCalYield modularPlusCalYield) throws RuntimeException { - throw new TODO(); - } -} diff --git a/src/pgo/trans/passes/atomicity/TLAExpressionLHSAtomicityInferenceVisitor.java b/src/pgo/trans/passes/atomicity/TLAExpressionLHSAtomicityInferenceVisitor.java deleted file mode 100644 index 4e7806fdf..000000000 --- a/src/pgo/trans/passes/atomicity/TLAExpressionLHSAtomicityInferenceVisitor.java +++ /dev/null @@ -1,184 +0,0 @@ -package pgo.trans.passes.atomicity; - -import pgo.TODO; -import pgo.Unreachable; -import pgo.model.tla.*; -import pgo.scope.UID; - -import java.util.function.Consumer; - -public class TLAExpressionLHSAtomicityInferenceVisitor extends TLAExpressionVisitor { - private final TLAExpressionValueAtomicityInferenceVisitor visitor; - private final Consumer captureWrite; - - public TLAExpressionLHSAtomicityInferenceVisitor(TLAExpressionValueAtomicityInferenceVisitor visitor, - Consumer captureWrite) { - this.visitor = visitor; - this.captureWrite = captureWrite; - } - - @Override - public Void visit(TLAFunctionCall tlaFunctionCall) throws RuntimeException { - captureWrite.accept(tlaFunctionCall); - tlaFunctionCall.getFunction().accept(this); - tlaFunctionCall.getParams().forEach(p -> p.accept(visitor)); - return null; - } - - @Override - public Void visit(TLABinOp tlaBinOp) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLABool tlaBool) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLACase tlaCase) throws RuntimeException { - throw new TODO(); - } - - @Override - public Void visit(TLADot tlaDot) throws RuntimeException { - tlaDot.getExpression().accept(this); - return null; - } - - @Override - public Void visit(TLAExistential tlaExistential) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLAFunction tlaFunction) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLAFunctionSet tlaFunctionSet) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLAFunctionSubstitution tlaFunctionSubstitution) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLAIf tlaIf) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLALet tlaLet) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLAGeneralIdentifier tlaGeneralIdentifier) throws RuntimeException { - captureWrite.accept(tlaGeneralIdentifier); - return null; - } - - @Override - public Void visit(TLATuple tlaTuple) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLAMaybeAction tlaMaybeAction) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLANumber tlaNumber) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLAOperatorCall tlaOperatorCall) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLAQuantifiedExistential tlaQuantifiedExistential) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLAQuantifiedUniversal tlaQuantifiedUniversal) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLARecordConstructor tlaRecordConstructor) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLARecordSet tlaRecordSet) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLARequiredAction tlaRequiredAction) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLASetConstructor tlaSetConstructor) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLASetComprehension tlaSetComprehension) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLASetRefinement tlaSetRefinement) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLAString tlaString) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLAUnary tlaUnary) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLAUniversal tlaUniversal) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(PlusCalDefaultInitValue plusCalDefaultInitValue) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLAFairness tlaFairness) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLASpecialVariableVariable tlaSpecialVariableVariable) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLASpecialVariableValue tlaSpecialVariableValue) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLARef tlaRef) throws RuntimeException { - throw new Unreachable(); - } -} diff --git a/src/pgo/trans/passes/atomicity/TLAExpressionValueAtomicityInferenceVisitor.java b/src/pgo/trans/passes/atomicity/TLAExpressionValueAtomicityInferenceVisitor.java deleted file mode 100644 index 01db39018..000000000 --- a/src/pgo/trans/passes/atomicity/TLAExpressionValueAtomicityInferenceVisitor.java +++ /dev/null @@ -1,215 +0,0 @@ -package pgo.trans.passes.atomicity; - -import pgo.TODO; -import pgo.model.tla.*; -import pgo.scope.UID; - -import java.util.function.Consumer; - -public class TLAExpressionValueAtomicityInferenceVisitor extends TLAExpressionVisitor { - protected Consumer captureRead; - - public TLAExpressionValueAtomicityInferenceVisitor(Consumer captureRead) { - this.captureRead = captureRead; - } - - @Override - public Void visit(TLAFunctionCall tlaFunctionCall) throws RuntimeException { - captureRead.accept(tlaFunctionCall); - - tlaFunctionCall.getFunction().accept(this); - tlaFunctionCall.getParams().forEach(e -> e.accept(this)); - return null; - } - - @Override - public Void visit(TLABinOp tlaBinOp) throws RuntimeException { - tlaBinOp.getLHS().accept(this); - tlaBinOp.getRHS().accept(this); - return null; - } - - @Override - public Void visit(TLABool tlaBool) throws RuntimeException { - // nothing to do - return null; - } - - @Override - public Void visit(TLACase tlaCase) throws RuntimeException { - for (TLACaseArm arm : tlaCase.getArms()) { - arm.getCondition().accept(this); - arm.getResult().accept(this); - } - tlaCase.getOther().accept(this); - return null; - } - - @Override - public Void visit(TLADot tlaDot) throws RuntimeException { - tlaDot.getExpression().accept(this); - return null; - } - - @Override - public Void visit(TLAExistential tlaExistential) throws RuntimeException { - tlaExistential.getBody().accept(this); - return null; - } - - @Override - public Void visit(TLAFunction tlaFunction) throws RuntimeException { - tlaFunction.getArguments().forEach(a -> a.getSet().accept(this)); - tlaFunction.getBody().accept(this); - return null; - } - - @Override - public Void visit(TLAFunctionSet tlaFunctionSet) throws RuntimeException { - tlaFunctionSet.getFrom().accept(this); - tlaFunctionSet.getTo().accept(this); - return null; - } - - @Override - public Void visit(TLAFunctionSubstitution tlaFunctionSubstitution) throws RuntimeException { - throw new TODO(); - } - - @Override - public Void visit(TLAIf tlaIf) throws RuntimeException { - tlaIf.getCond().accept(this); - tlaIf.getTval().accept(this); - tlaIf.getFval().accept(this); - return null; - } - - @Override - public Void visit(TLALet tlaLet) throws RuntimeException { - tlaLet.getDefinitions().forEach(def -> def.accept(new TLAUnitAtomicityInferenceVisitor(this))); - tlaLet.getBody().accept(this); - return null; - } - - @Override - public Void visit(TLAGeneralIdentifier tlaGeneralIdentifier) throws RuntimeException { - captureRead.accept(tlaGeneralIdentifier); - return null; - } - - @Override - public Void visit(TLATuple tlaTuple) throws RuntimeException { - tlaTuple.getElements().forEach(e -> e.accept(this)); - return null; - } - - @Override - public Void visit(TLAMaybeAction tlaMaybeAction) throws RuntimeException { - tlaMaybeAction.getBody().accept(this); - return null; - } - - @Override - public Void visit(TLANumber tlaNumber) throws RuntimeException { - // nothing to do - return null; - } - - @Override - public Void visit(TLAOperatorCall tlaOperatorCall) throws RuntimeException { - tlaOperatorCall.getArgs().forEach(a -> a.accept(this)); - return null; - } - - @Override - public Void visit(TLAQuantifiedExistential tlaQuantifiedExistential) throws RuntimeException { - tlaQuantifiedExistential.getBody().accept(this); - return null; - } - - @Override - public Void visit(TLAQuantifiedUniversal tlaQuantifiedUniversal) throws RuntimeException { - return tlaQuantifiedUniversal.getBody().accept(this); - } - - @Override - public Void visit(TLARecordConstructor tlaRecordConstructor) throws RuntimeException { - tlaRecordConstructor.getFields().forEach(f -> f.getValue().accept(this)); - return null; - } - - @Override - public Void visit(TLARecordSet tlaRecordSet) throws RuntimeException { - tlaRecordSet.getFields().forEach(f -> f.getSet().accept(this)); - return null; - } - - @Override - public Void visit(TLARequiredAction tlaRequiredAction) throws RuntimeException { - return tlaRequiredAction.getBody().accept(this); - } - - @Override - public Void visit(TLASetConstructor tlaSetConstructor) throws RuntimeException { - tlaSetConstructor.getContents().forEach(e -> e.accept(this)); - return null; - } - - @Override - public Void visit(TLASetComprehension tlaSetComprehension) throws RuntimeException { - tlaSetComprehension.getBounds().forEach(b -> b.getSet().accept(this)); - tlaSetComprehension.getBody().accept(this); - return null; - } - - @Override - public Void visit(TLASetRefinement tlaSetRefinement) throws RuntimeException { - tlaSetRefinement.getFrom().accept(this); - tlaSetRefinement.getWhen().accept(this); - return null; - } - - @Override - public Void visit(TLAString tlaString) throws RuntimeException { - // nothing to do - return null; - } - - @Override - public Void visit(TLAUnary tlaUnary) throws RuntimeException { - tlaUnary.getOperand().accept(this); - return null; - } - - @Override - public Void visit(TLAUniversal tlaUniversal) throws RuntimeException { - tlaUniversal.getBody().accept(this); - return null; - } - - @Override - public Void visit(PlusCalDefaultInitValue plusCalDefaultInitValue) throws RuntimeException { - // nothing to do - return null; - } - - @Override - public Void visit(TLAFairness fairness) throws RuntimeException{ - throw new TODO(); - } - - @Override - public Void visit(TLASpecialVariableVariable tlaSpecialVariableVariable) throws RuntimeException { - throw new TODO(); - } - - @Override - public Void visit(TLASpecialVariableValue tlaSpecialVariableValue) throws RuntimeException { - throw new TODO(); - } - - @Override - public Void visit(TLARef tlaRef) throws RuntimeException { - throw new TODO(); - } -} diff --git a/src/pgo/trans/passes/atomicity/TLAUnitAtomicityInferenceVisitor.java b/src/pgo/trans/passes/atomicity/TLAUnitAtomicityInferenceVisitor.java deleted file mode 100644 index d33db712f..000000000 --- a/src/pgo/trans/passes/atomicity/TLAUnitAtomicityInferenceVisitor.java +++ /dev/null @@ -1,59 +0,0 @@ -package pgo.trans.passes.atomicity; - -import pgo.Unreachable; -import pgo.model.tla.*; - -public class TLAUnitAtomicityInferenceVisitor extends TLAUnitVisitor { - protected TLAExpressionValueAtomicityInferenceVisitor visitor; - - public TLAUnitAtomicityInferenceVisitor(TLAExpressionValueAtomicityInferenceVisitor visitor) { - this.visitor = visitor; - } - - @Override - public Void visit(TLAInstance pGoTLAInstance) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLAFunctionDefinition pGoTLAFunctionDefinition) throws RuntimeException { - pGoTLAFunctionDefinition.getFunction().accept(visitor); - return null; - } - - @Override - public Void visit(TLAOperatorDefinition pGoTLAOperator) throws RuntimeException { - pGoTLAOperator.getBody().accept(visitor); - return null; - } - - @Override - public Void visit(TLATheorem pGoTLATheorem) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLAModule pGoTLAModule) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLAVariableDeclaration pGoTLAVariableDeclaration) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLAConstantDeclaration TLAConstantDeclaration) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLAModuleDefinition pGoTLAModuleDefinition) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLAAssumption TLAAssumption) throws RuntimeException { - throw new Unreachable(); - } -} diff --git a/src/pgo/trans/passes/codegen/NameCleaner.java b/src/pgo/trans/passes/codegen/NameCleaner.java deleted file mode 100644 index 1216f217f..000000000 --- a/src/pgo/trans/passes/codegen/NameCleaner.java +++ /dev/null @@ -1,46 +0,0 @@ -package pgo.trans.passes.codegen; - -import pgo.InternalCompilerError; -import pgo.scope.ChainSet; - -import java.util.HashSet; -import java.util.Set; - -public class NameCleaner { - - private final Set existingNames; - - public NameCleaner() { - this(new HashSet<>()); - } - - public NameCleaner(Set existingNames) { - this.existingNames = existingNames; - } - - public String cleanName(String nameHint) { - if (nameHint.equals("_")) { - return nameHint; - } - String actualName = nameHint; - int count = 0; - while(existingNames.contains(actualName)) { - actualName = nameHint + count; - ++count; - } - existingNames.add(actualName); - return actualName; - } - - public String requireCleanName(String requiredName) { - if (existingNames.contains(requiredName)) { - throw new InternalCompilerError(); - } - return requiredName; - } - - public NameCleaner child() { - return new NameCleaner(new ChainSet<>(existingNames)); - } - -} diff --git a/src/pgo/trans/passes/codegen/Recycling.java b/src/pgo/trans/passes/codegen/Recycling.java deleted file mode 100644 index 1ae170277..000000000 --- a/src/pgo/trans/passes/codegen/Recycling.java +++ /dev/null @@ -1,78 +0,0 @@ -package pgo.trans.passes.codegen; - -import pgo.InternalCompilerError; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Optional; - -public class Recycling { - public static class Checkpoint { - private final Recycling from; - private final int currentIndex; - - public Checkpoint(Recycling from, int currentIndex) { - this.from = from; - this.currentIndex = currentIndex; - } - } - - private final List items; - private int currentIndex; - - public Recycling() { - this(new ArrayList<>(), -1); - } - - public Recycling(T item) { - this(new ArrayList<>(Collections.singletonList(item)), 0); - } - - private Recycling(List items, int currentIndex) { - this.items = items; - this.currentIndex = currentIndex; - } - - public Checkpoint checkpoint() { - return new Checkpoint<>(this, currentIndex); - } - - public void restore(Checkpoint checkpoint) { - if (checkpoint.from != this) { - throw new InternalCompilerError(); - } - currentIndex = checkpoint.currentIndex; - } - - public boolean add(T item) { - boolean result = items.add(item); - currentIndex = items.size() - 1; - return result; - } - - // fetch only returns the top of the stack - public Optional fetch() { - if (currentIndex < 0 || currentIndex >= items.size()) { - return Optional.empty(); - } - return Optional.of(items.get(currentIndex)); - } - - // use advances the index and then returns the new top of the stack - public Optional use() { - if (currentIndex < items.size()) { - currentIndex += 1; - } - return fetch(); - } - - public void reuse() { - currentIndex = -1; - } - - @Override - public String toString() { - return "{currentIndex=" + currentIndex + ", items=" + items.toString() + "}"; - } -} diff --git a/src/pgo/trans/passes/codegen/go/ArchetypeResourcesGlobalVariableStrategy.java b/src/pgo/trans/passes/codegen/go/ArchetypeResourcesGlobalVariableStrategy.java deleted file mode 100644 index f4cdcee47..000000000 --- a/src/pgo/trans/passes/codegen/go/ArchetypeResourcesGlobalVariableStrategy.java +++ /dev/null @@ -1,471 +0,0 @@ -package pgo.trans.passes.codegen.go; - -import pgo.InternalCompilerError; -import pgo.TODO; -import pgo.Unreachable; -import pgo.model.golang.*; -import pgo.model.golang.builder.GoBlockBuilder; -import pgo.model.golang.builder.GoForRangeBuilder; -import pgo.model.golang.builder.GoModuleBuilder; -import pgo.model.golang.type.*; -import pgo.model.pcal.PlusCalProcess; -import pgo.model.tla.TLAExpression; -import pgo.model.tla.TLAFunctionCall; -import pgo.model.tla.TLAGeneralIdentifier; -import pgo.model.type.Type; -import pgo.scope.UID; -import pgo.trans.intermediate.DefinitionRegistry; - -import java.util.*; -import java.util.function.BiConsumer; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.stream.Collectors; - -public class ArchetypeResourcesGlobalVariableStrategy extends GlobalVariableStrategy { - private final DefinitionRegistry registry; - private final Map typeMap; - private final LocalVariableStrategy localStrategy; - private final UID archetype; - private GoVariableName err; - private GoVariableName acquiredResources; - private int currentLockGroup; - private GoLabelName currentLabel; - private boolean functionMaps; - - private static final String RELEASE = "ReleaseResources"; - private static final String ABORT = "AbortResources"; - - public ArchetypeResourcesGlobalVariableStrategy(DefinitionRegistry registry, Map typeMap, - LocalVariableStrategy localStrategy, UID archetype) { - this.registry = registry; - this.typeMap = typeMap; - this.localStrategy = localStrategy; - this.currentLockGroup = -1; - this.currentLabel = null; - this.functionMaps = false; - this.archetype = archetype; - this.acquiredResources = null; - } - - @Override - public void initPostlude(GoModuleBuilder moduleBuilder, GoBlockBuilder initBuilder) { - throw new TODO(); - } - - @Override - public void processPrelude(GoBlockBuilder builder, PlusCalProcess ignored, String archetypeName, GoVariableName self, GoType selfType) { - this.err = builder.varDecl("err", GoBuiltins.Error); - - if (!registry.getSignature(archetype).isPresent()) { - throw new InternalCompilerError(); - } - - // if the archetype has any resource that is function-mapped, declared archetypeResources - // to keep track of acquired resources for each lock group - boolean[] signature = registry.getSignature(archetype).get(); - for (int i = 0; i < signature.length; i++) { - if (signature[i]) { - functionMaps = true; - break; - } - } - - if (functionMaps) { - GoType type = new GoMapType( - GoBuiltins.String, - new GoMapType(GoBuiltins.UInt64, GoBuiltins.Interface) - ); - - this.acquiredResources = builder.varDecl("acquiredResources", type); - } - } - - @Override - public void mainPrelude(GoBlockBuilder builder) { - throw new TODO(); - } - - @Override - public void startCriticalSection(GoBlockBuilder builder, UID processUID, int lockGroup, UID labelUID, GoLabelName labelName) { - Function, Consumer> generateLocalBinding = s -> e -> { - GoExpression resource; - - if (e instanceof TLAGeneralIdentifier) { - resource = builder.findUID(registry.followReference(e.getUID())); - s.add(resource); - } else if (!(e instanceof TLAFunctionCall)) { - throw new Unreachable(); - } - }; - - Set readExps = new HashSet<>(); - Set writeExps = new HashSet<>(); - - registry.getResourceReadsInLockGroup(lockGroup).forEach(generateLocalBinding.apply(readExps)); - registry.getResourceWritesInLockGroup(lockGroup).forEach(generateLocalBinding.apply(writeExps)); - - // err = distsys.AcquireResources(distys.READ_ACCESS, ...{readExps}) - // if err != nil { return err } - BiConsumer> acquire = (permission, resources) -> { - if (!resources.isEmpty()) { - ArrayList args = new ArrayList<>( - Collections.singletonList(distsys(permission)) - ); - args.addAll(resources); - GoExpression acquireCall = new GoCall(distsys("AcquireResources"), args); - builder.assign(err, acquireCall); - shouldRetry(builder, false); - } - }; - - // reset acquired resources - if (functionMaps) { - builder.assign( - acquiredResources, - new GoMapLiteral( - GoBuiltins.String, - new GoMapType(GoBuiltins.UInt64, GoBuiltins.Interface), Collections.emptyMap() - ) - ); - } - - // keep track of the current lock group so that function-mapped - // resources can be properly acquired when accessed - currentLockGroup = lockGroup; - - // create a Go label for this action. If we need to retry, we need to - // come back to this point - currentLabel = labelName; - - localStrategy.actionPrelude(builder, labelUID); - - acquire.accept("READ_ACCESS", readExps); - acquire.accept("WRITE_ACCESS", writeExps); - } - - @Override - public void abortCriticalSection(GoBlockBuilder builder, UID processUID, int lockGroup, UID labelUID, GoLabelName labelName) { - terminateCriticalSection(builder, lockGroup, ABORT, false); - } - - @Override - public void endCriticalSection(GoBlockBuilder builder, UID processUID, int lockGroup, UID labelUID, GoLabelName labelName) { - terminateCriticalSection(builder, lockGroup, RELEASE, false); - localStrategy.actionPostlude(builder, labelUID); - } - - @Override - public GoExpression readGlobalVariable(GoBlockBuilder builder, UID uid) { - throw new TODO(); - } - - @Override - public GlobalVariableWrite writeGlobalVariable(UID uid) { - throw new TODO(); - } - - @Override - public GoExpression readArchetypeResource(GoBlockBuilder builder, TLAExpression resource) { - UID ref; - boolean isCall = false; - GoExpression target; - - if (resource instanceof TLAGeneralIdentifier) { - ref = registry.followReference(resource.getUID()); - target = builder.findUID(ref); - } else if (resource instanceof TLAFunctionCall) { - ref = registry.followReference(((TLAFunctionCall) resource).getFunction().getUID()); - TLAFunctionCall fnCall = (TLAFunctionCall) resource; - - target = ensureResourceAcquired(builder, fnCall); - isCall = true; - } else { - throw new Unreachable(); - } - - GoType resourceType = typeMap.get(ref).accept(new TypeConversionVisitor()); - - // if this a function call being mapped, the read type used when casting should be - // the value you get out of the slice or map inferred by the type system. - GoType readType; - if (isCall) { - readType = ((GoArchetypeResourceCollectionType) resourceType).getReadType(); - } else { - readType = ((GoArchetypeResourceType) resourceType).getReadType(); - } - - // if the read type is inferred to be a TLA+ record, use a map[string]interface{} - // to represent it instead - if (readType instanceof GoStructType) { - readType = new GoMapType(GoBuiltins.String, GoBuiltins.Interface); - } - - GoExpression readCall = new GoCall( - new GoSelectorExpression(target, "Read"), - Collections.emptyList() - ); - - GoVariableName readTemp = builder.varDecl("readTemp", GoBuiltins.Interface); - GoStatement assignRead = new GoAssignmentStatement( - Arrays.asList(readTemp, err), - false, - Collections.singletonList(readCall) - ); - builder.addStatement(assignRead); - shouldRetry(builder, true); - - // only do type casting if the inferred type is meaningful - if (readType.equals(GoBuiltins.Interface)) { - return readTemp; - } else { - return new GoTypeCast(new GoTypeName(readType.toString()), readTemp); - } - } - - @Override - public GlobalVariableWrite writeArchetypeResource(GoBlockBuilder builder, TLAExpression resource) { - GoExpression target = getResource(builder, resource); - GoVariableName tempVar = builder.varDecl("resourceWrite", GoBuiltins.Interface); - - return new GlobalVariableWrite() { - @Override - public GoExpression getValueSink(GoBlockBuilder builder) { - return tempVar; - } - - @Override - public void writeAfter(GoBlockBuilder builder) { - GoExpression write = new GoCall( - new GoSelectorExpression(target, "Write"), - Collections.singletonList(tempVar) - ); - builder.assign(err, write); - shouldRetry(builder, true); - } - }; - } - - private void fatalErrorCheck(GoBlockBuilder builder) { - GoExpression errNotNil = new GoBinop(GoBinop.Operation.NEQ, err, GoBuiltins.Nil); - try (GoIfBuilder ifBuilder = builder.ifStmt(errNotNil)) { - try (GoBlockBuilder yes = ifBuilder.whenTrue()) { - terminateCriticalSection(yes, currentLockGroup, ABORT, true); - yes.returnStmt(err); - } - } - } - - private void shouldRetry(GoBlockBuilder builder, boolean abort) { - Consumer checkRetry = b -> { - GoExpression check = new GoCall(new GoVariableName("shouldRetry"), Collections.singletonList(err)); - try (GoIfBuilder ifBuilder = b.ifStmt(check)) { - try (GoBlockBuilder yes = ifBuilder.whenTrue()) { - // log whenever an action is aborted - // GoExpression log = new GoCall( - // new GoSelectorExpression(new GoVariableName("fmt"), "Println"), - // Collections.singletonList(new GoStringLiteral("-- Aborted; retrying")) - // ); - // yes.addStatement(log); - - yes.goTo(currentLabel); - } - - try (GoBlockBuilder no = ifBuilder.whenFalse()) { - no.returnStmt(err); - } - } - }; - - GoExpression errNotNil = new GoBinop(GoBinop.Operation.NEQ, err, GoBuiltins.Nil); - try (GoIfBuilder ifBuilder = builder.ifStmt(errNotNil)) { - try (GoBlockBuilder yes = ifBuilder.whenTrue()) { - if (abort) { - terminateCriticalSection(yes, currentLockGroup, ABORT, true); - } - - checkRetry.accept(yes); - } - } - } - - private GoSelectorExpression distsys(String target) { - return new GoSelectorExpression( - new GoVariableName("distsys"), - target - ); - } - - // Releases/aborts resources - private void terminateCriticalSection(GoBlockBuilder builder, int lockGroup, String method, boolean isError) { - Set functionMappedResourceNames = new HashSet<>(); - - // release all non-function mapped resources in order - Set varMapped = new HashSet<>(); - Consumer collectResources = e -> { - if (e instanceof TLAGeneralIdentifier) { - varMapped.add(e); - } else if (e instanceof TLAFunctionCall) { - TLAFunctionCall fnCall = (TLAFunctionCall) e; - - TLAExpression fn = fnCall.getFunction(); - if (!(fn instanceof TLAGeneralIdentifier)) { - throw new TODO(); - } - - TLAGeneralIdentifier name = (TLAGeneralIdentifier) fn; - functionMappedResourceNames.add(name.getName().getId()); - } else { - throw new InternalCompilerError(); - } - }; - - registry.getResourceReadsInLockGroup(lockGroup).forEach(collectResources); - registry.getResourceWritesInLockGroup(lockGroup).forEach(collectResources); - - List varMappedExpressions = varMapped - .stream() - .map(e -> this.getResource(builder, e)) - .collect(Collectors.toList()); - - if (varMapped.size() > 0) { - GoExpression release = new GoCall(distsys(method), varMappedExpressions); - - // do not assign to `err` variable if inside an error handling situation - if (isError) { - builder.addStatement(release); - } else { - builder.assign(err, release); - fatalErrorCheck(builder); - } - } - - // release each function mapped resource used in this label - for (String resourceName : functionMappedResourceNames) { - // for _, r := range acquiredResources["{name}"] { - // releaseResource(r) - // } - - GoExpression resources = new GoIndexExpression(acquiredResources, new GoStringLiteral(resourceName)); - GoForRangeBuilder rangeBuilder = builder.forRange(resources); - GoVariableName r = rangeBuilder.initVariables(Arrays.asList("_", "r")).get(1); - try (GoBlockBuilder rangeBody = rangeBuilder.getBlockBuilder()) { - GoExpression resourceGet = new GoCall( - new GoSelectorExpression(new GoVariableName(resourceName), "Get"), - Collections.singletonList(r) - ); - - GoExpression release = new GoCall(distsys(method), Collections.singletonList(resourceGet)); - - if (isError) { - rangeBody.addStatement(release); - } else { - rangeBody.assign(err, release); - fatalErrorCheck(rangeBody); - } - } - } - } - - // Ensures that a function-mapped resource has been acquired before use: - // - // if ~(arg \in acquiredResources) { - // call distsys.AcquireResources() - // add resource to acquiredResources - // } - private GoExpression ensureResourceAcquired(GoBlockBuilder builder, TLAFunctionCall fnCall) { - // archetype resources are functions with only one argument, - // necessarily - if (fnCall.getParams().size() != 1) { - throw new InternalCompilerError(); - } - - TLAExpression arg = fnCall.getParams().get(0); - GoExpression goArg = codegen(builder, arg); - - String resourceName; - if (fnCall.getFunction() instanceof TLAGeneralIdentifier) { - resourceName = ((TLAGeneralIdentifier) fnCall.getFunction()).getName().getId(); - } else { - throw new InternalCompilerError(); - } - - // if _, ok := acquiredResources["{name}"]; !ok { - // acquiredResources["{name}"] = map[uint64]interface{}{} - // } - // {name}Acquired := acquiredResources["{name}"] - GoExpression currentlyAcquired = new GoIndexExpression(acquiredResources, new GoStringLiteral(resourceName)); - try (GoIfBuilder ifBuilder = builder.ifStmt(null)) { - GoVariableName ok = ifBuilder.initialAssignment(Arrays.asList("_", "ok"), currentlyAcquired).get(1); - ifBuilder.setCondition(new GoUnary(GoUnary.Operation.NOT, ok)); - - try (GoBlockBuilder yes = ifBuilder.whenTrue()) { - yes.assign( - currentlyAcquired, - new GoMapLiteral(GoBuiltins.UInt64, GoBuiltins.Interface, Collections.emptyMap()) - ); - } - } - - GoExpression resourceGet = new GoCall( - new GoSelectorExpression(codegen(builder, fnCall.getFunction()), "Get"), - Collections.singletonList(goArg) - ); - - try (GoIfBuilder ifBuilder = builder.ifStmt(null)) { - GoExpression argHash = new GoCall(distsys("Hash"), Collections.singletonList(goArg)); - GoVariableName resourceHash = builder.varDecl("resourceHash", argHash); - GoExpression argAcquired = new GoIndexExpression(currentlyAcquired, resourceHash); - GoVariableName acquired = ifBuilder.initialAssignment(Arrays.asList("_", "acquired"), argAcquired).get(1); - - ifBuilder.setCondition(new GoUnary(GoUnary.Operation.NOT, acquired)); - - try (GoBlockBuilder yes = ifBuilder.whenTrue()) { - String permission; - - // TODO: GlobalVariableStrategies cannot be stateful, so the code below does not work (currentLockGroup may be wrong) - // TODO: Ideally, what we want to do is to appropriately fork the instance of this class, just like with CriticalSectionTracker - // TODO: For now, we take the pessimistic choice of always acquiring resources with write permissions - permission = "WRITE_ACCESS"; - - // TODO: this is the code that should work with proper branching as described above. - // if (registry.getResourceReadsInLockGroup(currentLockGroup).contains(fnCall)) { - // permission = "READ_ACCESS"; - // } else if (registry.getResourceWritesInLockGroup(currentLockGroup).contains(fnCall)) { - // permission = "WRITE_ACCESS"; - // } else { - // throw new InternalCompilerError(); - // } - - yes.assign(err, new GoCall( - distsys("AcquireResources"), - Arrays.asList( - distsys(permission), - resourceGet - ) - )); - shouldRetry(yes, true); - - yes.assign(argAcquired, goArg); - } - } - - return resourceGet; - } - - private GoExpression getResource(GoBlockBuilder builder, TLAExpression resource) { - if (resource instanceof TLAGeneralIdentifier) { - UID ref = registry.followReference(resource.getUID()); - return builder.findUID(ref); - } else if (resource instanceof TLAFunctionCall) { - TLAFunctionCall fnCall = (TLAFunctionCall) resource; - return ensureResourceAcquired(builder, fnCall); - } else { - throw new Unreachable(); - } - } - - private GoExpression codegen(GoBlockBuilder builder, TLAExpression e) { - return e.accept(new TLAExpressionCodeGenVisitor(builder, registry, typeMap, localStrategy, this)); - } -} \ No newline at end of file diff --git a/src/pgo/trans/passes/codegen/go/CodeGenUtil.java b/src/pgo/trans/passes/codegen/go/CodeGenUtil.java deleted file mode 100644 index 74999e344..000000000 --- a/src/pgo/trans/passes/codegen/go/CodeGenUtil.java +++ /dev/null @@ -1,45 +0,0 @@ -package pgo.trans.passes.codegen.go; - -import pgo.model.golang.*; -import pgo.model.golang.builder.GoBlockBuilder; -import pgo.model.tla.TLAExpression; -import pgo.model.type.Type; -import pgo.scope.UID; -import pgo.trans.intermediate.DefinitionRegistry; - -import java.util.Arrays; -import java.util.Collections; -import java.util.Map; -import java.util.stream.Collectors; - -public class CodeGenUtil { - private CodeGenUtil() {} - - public static GoExpression invertCondition(GoBlockBuilder builder, DefinitionRegistry registry, - Map typeMap, - LocalVariableStrategy localStrategy, - GlobalVariableStrategy globalStrategy, - TLAExpression condition) { - return new GoUnary(GoUnary.Operation.NOT, condition.accept(new TLAExpressionCodeGenVisitor(builder, registry, typeMap, localStrategy, globalStrategy))); - } - - public static GoExpression staticallySortSlice(GoSliceLiteral slice){ - return new GoSliceLiteral( - slice.getElementType(), - slice.getInitializers().stream() - .sorted((lhs, rhs) -> lhs.accept( - new GoExpressionStaticComparisonVisitor(rhs))) - .distinct() - .collect(Collectors.toList())); - } - - static void generateArgumentParsing(GoBlockBuilder builder, GoExpression expression, GoVariableName processName, - GoVariableName processArgument) { - builder.addImport("pgo/distsys"); - builder.assign( - Arrays.asList(processName, processArgument), - new GoCall( - new GoSelectorExpression(new GoVariableName("distsys"), "ParseProcessId"), - Collections.singletonList(expression))); - } -} diff --git a/src/pgo/trans/passes/codegen/go/CopyVisitor.java b/src/pgo/trans/passes/codegen/go/CopyVisitor.java deleted file mode 100644 index e13f27804..000000000 --- a/src/pgo/trans/passes/codegen/go/CopyVisitor.java +++ /dev/null @@ -1,122 +0,0 @@ -package pgo.trans.passes.codegen.go; - -import pgo.InternalCompilerError; -import pgo.TODO; -import pgo.model.golang.*; -import pgo.model.golang.builder.GoBlockBuilder; -import pgo.model.golang.builder.GoForRangeBuilder; -import pgo.model.golang.type.*; - -import java.util.*; -import java.util.stream.Collectors; - -public class CopyVisitor extends GoTypeVisitor { - - private final GoBlockBuilder builder; - private final GoVariableName source; - - public CopyVisitor(GoBlockBuilder builder, GoVariableName source) { - this.builder = builder; - this.source = source; - } - - private GoVariableName createCopy(GoExpression value) { - return builder.varDecl(source.getName() + "Copy", value); - } - - @Override - public GoVariableName visit(GoTypeName typeName) throws RuntimeException { - if (typeName.isBuiltin()) { - return createCopy(source); - } - - throw new TODO(); - } - - @Override - public GoVariableName visit(GoArchetypeResourceType archetypeResourceType) throws RuntimeException { - throw new InternalCompilerError(); - } - - @Override - public GoVariableName visit(GoArchetypeResourceCollectionType archetypeResourceCollectionType) throws RuntimeException { - throw new InternalCompilerError(); - } - - @Override - public GoVariableName visit(GoStructType structType) throws RuntimeException { - Map memberCopies = new HashMap<>(); - for(GoStructTypeField field : structType.getFields()) { - GoVariableName fieldVar = builder.varDecl("field", new GoSelectorExpression(source, field.getName())); - memberCopies.put(field.getName(), field.getType().accept(new CopyVisitor(builder, fieldVar))); - } - - GoExpression copy = new GoStructLiteral( - structType, - structType - .getFields() - .stream() - .map(field -> new GoStructLiteralField(field.getName(), memberCopies.get(field.getName()))) - .collect(Collectors.toList()) - ); - - return createCopy(copy); - } - - @Override - public GoVariableName visit(GoPtrType ptrType) throws RuntimeException { - GoVariableName deref = builder.varDecl("deref", new GoUnary(GoUnary.Operation.DEREF, source)); - return ptrType.getPointee().accept(new CopyVisitor(builder, deref)); - } - - @Override - public GoVariableName visit(GoSliceType sliceType) throws RuntimeException { - GoExpression make = new GoMakeExpression(sliceType, new GoCall(new GoVariableName("len"), Collections.singletonList(source))); - GoVariableName copy = createCopy(make); - - GoForRangeBuilder rangeBuilder = builder.forRange(source); - List initVars = rangeBuilder.initVariables(Arrays.asList("i", "e")); - GoVariableName i = initVars.get(0); - GoVariableName e = initVars.get(1); - - try (GoBlockBuilder rangeBody = rangeBuilder.getBlockBuilder()) { - GoExpression target = new GoIndexExpression(copy, i); - - rangeBody.assign(target, sliceType.getElementType().accept(new CopyVisitor(rangeBody, e))); - } - - return copy; - } - - @Override - public GoVariableName visit(GoChanType chanType) throws RuntimeException { - throw new TODO(); - } - - @Override - public GoVariableName visit(GoMapType mapType) throws RuntimeException { - GoExpression make = new GoMakeExpression(mapType, new GoCall(new GoVariableName("len"), Collections.singletonList(source))); - GoVariableName copy = createCopy(make); - - GoForRangeBuilder rangeBuilder = builder.forRange(source); - List initVars = rangeBuilder.initVariables(Arrays.asList("k", "v")); - GoVariableName k = initVars.get(0); - GoVariableName v = initVars.get(1); - - try (GoBlockBuilder rangeBody = rangeBuilder.getBlockBuilder()) { - GoExpression target = new GoIndexExpression(copy, k); - - rangeBody.assign(target, mapType.getValueType().accept(new CopyVisitor(rangeBody, v))); - } - - return copy; - } - - @Override - public GoVariableName visit(GoInterfaceType interfaceType) throws RuntimeException { - // best effort case: assign to copy. - // Safe copy of interface{} type in Go requires use of the `reflect` package - return createCopy(source); - } - -} \ No newline at end of file diff --git a/src/pgo/trans/passes/codegen/go/CriticalSection.java b/src/pgo/trans/passes/codegen/go/CriticalSection.java deleted file mode 100644 index a01061d74..000000000 --- a/src/pgo/trans/passes/codegen/go/CriticalSection.java +++ /dev/null @@ -1,11 +0,0 @@ -package pgo.trans.passes.codegen.go; - -import pgo.model.golang.GoLabelName; -import pgo.model.golang.builder.GoBlockBuilder; -import pgo.scope.UID; - -public interface CriticalSection { - void startCriticalSection(GoBlockBuilder builder, UID processUID, int lockGroup, UID labelUID, GoLabelName labelName); - void abortCriticalSection(GoBlockBuilder builder, UID processUID, int lockGroup, UID labelUID, GoLabelName labelName); - void endCriticalSection(GoBlockBuilder builder, UID processUID, int lockGroup, UID labelUID, GoLabelName labelName); -} diff --git a/src/pgo/trans/passes/codegen/go/CriticalSectionTracker.java b/src/pgo/trans/passes/codegen/go/CriticalSectionTracker.java deleted file mode 100644 index c26d13379..000000000 --- a/src/pgo/trans/passes/codegen/go/CriticalSectionTracker.java +++ /dev/null @@ -1,118 +0,0 @@ -package pgo.trans.passes.codegen.go; - -import pgo.InternalCompilerError; -import pgo.model.golang.GoLabelName; -import pgo.model.golang.builder.GoBlockBuilder; -import pgo.scope.UID; -import pgo.trans.intermediate.DefinitionRegistry; - -import java.util.function.Consumer; - -public class CriticalSectionTracker { - private final DefinitionRegistry registry; - private final UID processUID; - private final CriticalSection criticalSection; - private int currentLockGroup; - private UID currentLabelUID; - private GoLabelName currentLabelName; - - private CriticalSectionTracker(DefinitionRegistry registry, UID processUID, CriticalSection criticalSection, - int currentLockGroup, UID currentLabelUID, GoLabelName currentLabelName) { - this.registry = registry; - this.processUID = processUID; - this.criticalSection = criticalSection; - this.currentLockGroup = currentLockGroup; - this.currentLabelUID = currentLabelUID; - this.currentLabelName = currentLabelName; - } - - public CriticalSectionTracker(DefinitionRegistry registry, UID processUID, CriticalSection criticalSection) { - this(registry, processUID, criticalSection, -1, null, null); - } - - public GoLabelName getCurrentLabelName() { - return currentLabelName; - } - - public int getCurrentLockGroup() { - return currentLockGroup; - } - - public void start(GoBlockBuilder builder, UID labelUID, GoLabelName labelName) { - start(builder, labelUID, labelName, true); - } - - private void start(GoBlockBuilder builder, UID labelUID, GoLabelName labelName, boolean createLabel) { - // end the current lock group - end(builder); - currentLockGroup = registry.getLockGroupOrDefault(labelUID, -1); - currentLabelUID = labelUID; - currentLabelName = labelName; - - if (createLabel) { - builder.labelIsUnique(labelName.getName()); - } - - if (currentLockGroup < 0) { - // nothing to do - return; - } - // start the new (now current) lock group - criticalSection.startCriticalSection(builder, processUID, currentLockGroup, currentLabelUID, currentLabelName); - } - - public void abort(GoBlockBuilder builder, GoLabelName optionalLabelName) { - if (currentLockGroup >= 0) { - criticalSection.abortCriticalSection( - builder, processUID, currentLockGroup, currentLabelUID, currentLabelName); - } - builder.goTo(optionalLabelName == null ? currentLabelName : optionalLabelName); - currentLockGroup = -1; - currentLabelUID = null; - currentLabelName = null; - } - - public void end(GoBlockBuilder builder) { - if (currentLockGroup < 0) { - // nothing to do - return; - } - criticalSection.endCriticalSection(builder, processUID, currentLockGroup, currentLabelUID, currentLabelName); - currentLockGroup = -1; - currentLabelUID = null; - currentLabelName = null; - } - - public void restore(GoBlockBuilder builder) { - if (currentLockGroup < 0) { - // nothing to do - return; - } - criticalSection.startCriticalSection(builder, processUID, currentLockGroup, currentLabelUID, currentLabelName); - } - - public void checkCompatibility(CriticalSectionTracker other) { - if (registry != other.registry || !criticalSection.equals(other.criticalSection) || currentLockGroup != other.currentLockGroup) { - throw new InternalCompilerError(); - } - } - - public CriticalSectionTracker copy() { - return new CriticalSectionTracker( - registry, processUID, criticalSection, currentLockGroup, currentLabelUID, currentLabelName); - } - - public Consumer actionAtLoopEnd() { - // since we're compiling while loops to infinite loops with a conditional break, we have to reacquire - // the critical section at loop end - int lockGroup = currentLockGroup; - UID labelUID = currentLabelUID; - GoLabelName labelName = currentLabelName; - if (lockGroup < 0) { - return ignored -> {}; - } - - // a new label is not required since we are reacquiring the critical section - return builder -> start(builder, labelUID, labelName, false); - } -} diff --git a/src/pgo/trans/passes/codegen/go/DefaultLocalVariableStrategy.java b/src/pgo/trans/passes/codegen/go/DefaultLocalVariableStrategy.java deleted file mode 100644 index fb153e175..000000000 --- a/src/pgo/trans/passes/codegen/go/DefaultLocalVariableStrategy.java +++ /dev/null @@ -1,37 +0,0 @@ -package pgo.trans.passes.codegen.go; - -import pgo.model.golang.GoExpression; -import pgo.model.golang.GoVariableName; -import pgo.model.golang.builder.GoBlockBuilder; -import pgo.scope.UID; -import pgo.trans.passes.codegen.go.GlobalVariableStrategy.GlobalVariableWrite; - -public class DefaultLocalVariableStrategy extends LocalVariableStrategy { - public void actionPrelude(GoBlockBuilder builder, UID labelUID) { - // nothing to do - } - - public GoExpression readLocalVariable(GoBlockBuilder builder, UID local) { - return builder.findUID(local); - } - - public GlobalVariableWrite writeLocalVariable(GoBlockBuilder builder, UID local) { - GoVariableName name = builder.findUID(local); - - return new GlobalVariableWrite() { - @Override - public GoExpression getValueSink(GoBlockBuilder builder) { - return name; - } - @Override - public void writeAfter(GoBlockBuilder builder) { - // pass - } - }; - } - - public void actionPostlude(GoBlockBuilder builder, UID labelUID) { - // nothing to do - } - -} diff --git a/src/pgo/trans/passes/codegen/go/EqCodeGenVisitor.java b/src/pgo/trans/passes/codegen/go/EqCodeGenVisitor.java deleted file mode 100644 index 6fbe8fb4d..000000000 --- a/src/pgo/trans/passes/codegen/go/EqCodeGenVisitor.java +++ /dev/null @@ -1,96 +0,0 @@ -package pgo.trans.passes.codegen.go; - -import pgo.TODO; -import pgo.model.golang.*; -import pgo.model.golang.builder.GoBlockBuilder; -import pgo.model.golang.builder.GoForRangeBuilder; -import pgo.model.golang.builder.GoForStatementClauseBuilder; -import pgo.model.golang.type.*; -import pgo.trans.intermediate.TLABuiltins; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -public class EqCodeGenVisitor extends GoTypeVisitor { - - private final GoBlockBuilder builder; - private final GoExpression lhs; - private final GoExpression rhs; - private final boolean invert; - - public EqCodeGenVisitor(GoBlockBuilder builder, GoExpression lhs, GoExpression rhs, boolean invert) { - this.builder = builder; - this.lhs = lhs; - this.rhs = rhs; - this.invert = invert; - } - - private GoExpression deepEqual() { - builder.addImport("reflect"); - - GoExpression eq = new GoCall( - new GoSelectorExpression(new GoVariableName("reflect"), "DeepEqual"), - Arrays.asList(lhs, rhs) - ); - - if (invert) { - return new GoUnary(GoUnary.Operation.NOT, eq); - } - - return eq; - } - - @Override - public GoExpression visit(GoTypeName typeName) throws RuntimeException { - if(typeName.isBuiltin()) { - return new GoBinop(invert ? GoBinop.Operation.NEQ : GoBinop.Operation.EQ, lhs, rhs); - } - throw new TODO(); - } - - @Override - public GoExpression visit(GoArchetypeResourceType archetypeResourceType) throws RuntimeException { - throw new TODO(); - } - - @Override - public GoExpression visit(GoArchetypeResourceCollectionType archetypeResourceCollectionType) throws RuntimeException { - throw new TODO(); - } - - @Override - public GoExpression visit(GoStructType structType) throws RuntimeException { - return deepEqual(); - } - - @Override - public GoExpression visit(GoPtrType ptrType) throws RuntimeException { - return ptrType.getPointee().accept(new EqCodeGenVisitor( - builder, - new GoUnary(GoUnary.Operation.DEREF, lhs), - new GoUnary(GoUnary.Operation.DEREF, rhs), invert)); - } - - @Override - public GoExpression visit(GoSliceType sliceType) throws RuntimeException { - return deepEqual(); - } - - @Override - public GoExpression visit(GoChanType chanType) throws RuntimeException { - throw new TODO(); - } - - @Override - public GoExpression visit(GoMapType mapType) throws RuntimeException { - return deepEqual(); - } - - @Override - public GoExpression visit(GoInterfaceType interfaceType) throws RuntimeException { - return deepEqual(); - } - -} diff --git a/src/pgo/trans/passes/codegen/go/EtcdGlobalVariableStrategy.java b/src/pgo/trans/passes/codegen/go/EtcdGlobalVariableStrategy.java deleted file mode 100644 index c3180935e..000000000 --- a/src/pgo/trans/passes/codegen/go/EtcdGlobalVariableStrategy.java +++ /dev/null @@ -1,208 +0,0 @@ -package pgo.trans.passes.codegen.go; - -import pgo.PGoNetOptions; -import pgo.Unreachable; -import pgo.model.golang.*; -import pgo.model.golang.builder.GoBlockBuilder; -import pgo.model.golang.builder.GoModuleBuilder; -import pgo.model.golang.type.GoType; -import pgo.model.golang.type.GoTypeName; -import pgo.model.mpcal.ModularPlusCalBlock; -import pgo.model.pcal.PlusCalProcess; -import pgo.model.type.Type; -import pgo.scope.UID; -import pgo.trans.intermediate.DefinitionRegistry; - -import java.util.*; -import java.util.stream.Collectors; - -public class EtcdGlobalVariableStrategy extends GlobalVariableStrategy { - private final DefinitionRegistry registry; - private final Map typeMap; - private final PGoNetOptions.StateOptions stateOptions; - private final ModularPlusCalBlock modularPlusCalBlock; - private final GoCommandLineArgumentParser commandLineArgumentParser; - private final UID processNameUID; - private final UID processArgumentUID; - private final UID errUID; - private final UID globalStateUID; - - public EtcdGlobalVariableStrategy(DefinitionRegistry registry, Map typeMap, - PGoNetOptions.StateOptions stateOptions, - ModularPlusCalBlock modularPlusCalBlock) { - this.registry = registry; - this.typeMap = typeMap; - this.stateOptions = stateOptions; - this.modularPlusCalBlock = modularPlusCalBlock; - this.commandLineArgumentParser = new GoCommandLineArgumentParser(); - this.processNameUID = new UID(); - this.processArgumentUID = new UID(); - this.errUID = new UID(); - this.globalStateUID = new UID(); - } - - @Override - public void initPostlude(GoModuleBuilder moduleBuilder, GoBlockBuilder initBuilder) { - GoVariableName processName = moduleBuilder.defineGlobal(processNameUID, "processName", GoBuiltins.String); - addVariable(processNameUID, processName); - GoVariableName processArgument = moduleBuilder.defineGlobal(processArgumentUID, "processArgument", GoBuiltins.String); - addVariable(processArgumentUID, processArgument); - commandLineArgumentParser.addPositionalArgument("processPlusArgument", "processName(processArgument)"); - commandLineArgumentParser.addPositionalArgument("ipPort", "ip:port"); - List commandLineArguments = commandLineArgumentParser.generateArgumentParsingCode(initBuilder); - GoVariableName processPlusArgument = commandLineArguments.get(0); - GoVariableName ipPort = commandLineArguments.get(1); - CodeGenUtil.generateArgumentParsing(initBuilder, processPlusArgument, processName, processArgument); - - moduleBuilder.addImport("pgo/distsys"); - GoVariableName err = moduleBuilder.defineGlobal(errUID, "err", GoBuiltins.Error); - addVariable(errUID, err); - GoVariableName globalState = moduleBuilder.defineGlobal( - globalStateUID, "globalState", new GoPtrType(new GoTypeName("distsys.EtcdState"))); - addVariable(globalStateUID, globalState); - GoVariableName peers = initBuilder.varDecl( - "peers", - new GoSliceLiteral( - GoBuiltins.String, - stateOptions.peers.stream().map(GoStringLiteral::new) .collect(Collectors.toList()))); - GoVariableName coordinator = initBuilder.varDecl("coordinator", new GoIndexExpression(peers, new GoIntLiteral(0))); - initBuilder.assign( - Arrays.asList(globalState, err), - new GoCall( - new GoSelectorExpression(new GoVariableName("distsys"), "NewEtcdState"), - Arrays.asList( - new GoSliceLiteral( - GoBuiltins.String, - stateOptions.endpoints.stream() - .map(e -> new GoStringLiteral("http://" + e)) - .collect(Collectors.toList())), - new GoIntLiteral(stateOptions.timeout), - peers, - ipPort, - coordinator, - new GoMapLiteral( - GoBuiltins.String, - GoBuiltins.Interface, - new HashMap() {{ - for (UID varUID : registry.protectedGlobalVariables()) { - GoVariableName variableName = initBuilder.findUID(varUID); - put(new GoStringLiteral(variableName.getName()), variableName); - } - }})))); - try (GoIfBuilder ifBuilder = initBuilder.ifStmt(new GoBinop(GoBinop.Operation.NEQ, err, GoBuiltins.Nil))) { - try (GoBlockBuilder yes = ifBuilder.whenTrue()) { - yes.addPanic(err); - } - } - } - - @Override - public void processPrelude(GoBlockBuilder processBody, PlusCalProcess process, String processName, GoVariableName self, GoType selfType) { - GoVariableName selfStr; - if (selfType.equals(GoBuiltins.Int)) { - // selfStr := "processName(" + strconv.Itoa(self) + ")" - processBody.addImport("strconv"); - selfStr = processBody.varDecl( - "selfStr", - new GoBinop( - GoBinop.Operation.PLUS, - new GoBinop( - GoBinop.Operation.PLUS, - new GoStringLiteral(processName + "("), - new GoCall( - new GoSelectorExpression(new GoVariableName("strconv"), "Itoa"), - Collections.singletonList(self))), - new GoStringLiteral(")"))); - } else if (selfType.equals(GoBuiltins.String)) { - // selfStr := "processName(" + self + ")" - selfStr = processBody.varDecl( - "selfStr", - new GoBinop( - GoBinop.Operation.PLUS, - new GoBinop( - GoBinop.Operation.PLUS, - new GoStringLiteral(processName + "("), - self), - new GoStringLiteral(")"))); - } else { - throw new Unreachable(); - } - addVariable(process.getName().getUID(), selfStr); - } - - @Override - public void mainPrelude(GoBlockBuilder builder) { - StateServerGlobalVariableStrategy.generateProcessSwitch( - typeMap, modularPlusCalBlock, builder, findVariable(processNameUID), findVariable(processArgumentUID)); - } - - @Override - public void startCriticalSection(GoBlockBuilder builder, UID processUID, int lockGroup, UID labelUID, GoLabelName labelName) { - Set readSet = new HashSet<>(registry.getVariableReadsInLockGroup(lockGroup)); - Set writeSet = registry.getVariableWritesInLockGroup(lockGroup); - readSet.removeAll(writeSet); - GoVariableName globalState = findVariable(globalStateUID); - builder.addStatement(new GoCall( - new GoSelectorExpression(findVariable(globalStateUID), "Lock"), - Arrays.asList(findVariable(processUID), new GoStringLiteral(Integer.toString(lockGroup))))); - for (UID varUID : writeSet) { - GoVariableName variableName = builder.findUID(varUID); - builder.addStatement(new GoCall( - new GoSelectorExpression(globalState, "Get"), - Arrays.asList( - new GoStringLiteral(variableName.getName()), - new GoUnary(GoUnary.Operation.ADDR, variableName)))); - } - for (UID varUID : readSet) { - GoVariableName variableName = builder.findUID(varUID); - builder.addStatement(new GoCall( - new GoSelectorExpression(globalState, "Get"), - Arrays.asList( - new GoStringLiteral(variableName.getName()), - new GoUnary(GoUnary.Operation.ADDR, variableName)))); - } - } - - @Override - public void abortCriticalSection(GoBlockBuilder builder, UID processUID, int lockGroup, UID labelUID, GoLabelName labelName) { - builder.addStatement(new GoCall( - new GoSelectorExpression(findVariable(globalStateUID), "Unlock"), - Arrays.asList(findVariable(processUID), new GoStringLiteral(Integer.toString(lockGroup))))); - } - - @Override - public void endCriticalSection(GoBlockBuilder builder, UID processUID, int lockGroup, UID labelUID, GoLabelName labelName) { - GoVariableName globalState = findVariable(globalStateUID); - for (UID varUID : registry.getVariableWritesInLockGroup(lockGroup)) { - GoVariableName variableName = builder.findUID(varUID); - builder.addStatement(new GoCall( - new GoSelectorExpression(globalState, "Set"), - Arrays.asList( - new GoStringLiteral(variableName.getName()), - variableName))); - } - builder.addStatement(new GoCall( - new GoSelectorExpression(findVariable(globalStateUID), "Unlock"), - Arrays.asList(findVariable(processUID), new GoStringLiteral(Integer.toString(lockGroup))))); - } - - @Override - public GoExpression readGlobalVariable(GoBlockBuilder builder, UID uid) { - return builder.findUID(uid); - } - - @Override - public GlobalVariableWrite writeGlobalVariable(UID uid) { - return new GlobalVariableWrite() { - @Override - public GoExpression getValueSink(GoBlockBuilder builder) { - return builder.findUID(uid); - } - - @Override - public void writeAfter(GoBlockBuilder builder) { - - } - }; - } -} diff --git a/src/pgo/trans/passes/codegen/go/GlobalVariableStrategy.java b/src/pgo/trans/passes/codegen/go/GlobalVariableStrategy.java deleted file mode 100644 index dd4c799c9..000000000 --- a/src/pgo/trans/passes/codegen/go/GlobalVariableStrategy.java +++ /dev/null @@ -1,79 +0,0 @@ -package pgo.trans.passes.codegen.go; - -import pgo.InternalCompilerError; -import pgo.Unreachable; -import pgo.model.golang.GoExpression; -import pgo.model.golang.GoLabelName; -import pgo.model.golang.GoVariableName; -import pgo.model.golang.builder.GoBlockBuilder; -import pgo.model.golang.builder.GoModuleBuilder; -import pgo.model.golang.type.GoType; -import pgo.model.pcal.PlusCalProcess; -import pgo.model.tla.TLAExpression; -import pgo.scope.UID; -import pgo.trans.passes.codegen.go.CriticalSection; - -import java.util.HashMap; -import java.util.Map; - -public abstract class GlobalVariableStrategy implements CriticalSection { - private final Map variables = new HashMap<>(); - - protected void addVariable(UID uid, GoVariableName variableName) { - if (variables.containsKey(uid)) { - throw new InternalCompilerError(); - } - variables.put(uid, variableName); - } - - protected GoVariableName findVariable(UID uid) { - if (!variables.containsKey(uid)) { - throw new InternalCompilerError(); - } - return variables.get(uid); - } - - - public abstract void initPostlude(GoModuleBuilder moduleBuilder, GoBlockBuilder initBuilder); - - public abstract void processPrelude(GoBlockBuilder processBody, PlusCalProcess process, String processName, GoVariableName self, GoType selfType); - - public abstract void mainPrelude(GoBlockBuilder builder); - - @Override - public abstract void startCriticalSection(GoBlockBuilder builder, UID processUID, int lockGroup, UID labelUID, GoLabelName labelName); - - @Override - public abstract void abortCriticalSection(GoBlockBuilder builder, UID processUID, int lockGroup, UID labelUID, GoLabelName labelName); - - @Override - public abstract void endCriticalSection(GoBlockBuilder builder, UID processUID, int lockGroup, UID labelUID, GoLabelName labelName); - - public GoExpression readArchetypeResource(GoBlockBuilder builder, TLAExpression expression) { - throw new Unreachable(); - } - - public GlobalVariableWrite writeArchetypeResource(GoBlockBuilder builder, TLAExpression expression) { - throw new Unreachable(); - } - - public abstract GoExpression readGlobalVariable(GoBlockBuilder builder, UID uid); - - public interface GlobalVariableWrite { - GoExpression getValueSink(GoBlockBuilder builder); - void writeAfter(GoBlockBuilder builder); - } - - public abstract GlobalVariableWrite writeGlobalVariable(UID uid); - - // map global variables to locals - // commit on success - // rollback on failure - // inputs to strategy: - // - variables to read - // - variables to write - // - when a section starts - // - when a section ends - // - when a section rolls back - // - ability to inform global var lookups and sets -} diff --git a/src/pgo/trans/passes/codegen/go/GoCommandLineArgumentParser.java b/src/pgo/trans/passes/codegen/go/GoCommandLineArgumentParser.java deleted file mode 100644 index 2f7258e70..000000000 --- a/src/pgo/trans/passes/codegen/go/GoCommandLineArgumentParser.java +++ /dev/null @@ -1,62 +0,0 @@ -package pgo.trans.passes.codegen.go; - -import pgo.model.golang.*; -import pgo.model.golang.builder.GoBlockBuilder; - -import java.util.*; -import java.util.stream.Collectors; - -// TODO add support for GoRoutineStatement's flag package -public class GoCommandLineArgumentParser { - private final Map positionalArguments = new LinkedHashMap<>(); - - public void addPositionalArgument(String name, String display) { - positionalArguments.put(name, display); - } - - public List generateArgumentParsingCode(GoBlockBuilder builder) { - if (positionalArguments.size() == 0) { - // nothing to do - return Collections.emptyList(); - } - builder.addImport("os"); - builder.addImport("fmt"); - // if len(os.Args) < positionalArguments.size() + 1 { - // fmt.Printf("Usage: %s positionalArgs...", os.Args[0]) - // os.Exit(1) - // } - try (GoIfBuilder ifBuilder = builder.ifStmt(new GoBinop( - GoBinop.Operation.NEQ, - new GoCall( - new GoVariableName("len"), - Collections.singletonList(new GoSelectorExpression(new GoVariableName("os"), "Args"))), - new GoIntLiteral(positionalArguments.size() + 1)))) { - try (GoBlockBuilder yes = ifBuilder.whenTrue()) { - yes.addStatement(new GoCall( - new GoSelectorExpression(new GoVariableName("fmt"), "Printf"), - Arrays.asList( - new GoStringLiteral("Usage: %s " + - positionalArguments.values().stream() - .collect(Collectors.joining(" ")) + - "\\n"), - new GoIndexExpression( - new GoSelectorExpression(new GoVariableName("os"), "Args"), - new GoIntLiteral(0))))); - yes.addStatement(new GoCall( - new GoSelectorExpression(new GoVariableName("os"), "Exit"), - Collections.singletonList(new GoIntLiteral(1)))); - } - } - List ret = new ArrayList<>(); - int currentIndex = 1; - for (String name: positionalArguments.keySet()) { - ret.add(builder.varDecl( - name, - new GoIndexExpression( - new GoSelectorExpression(new GoVariableName("os"), "Args"), - new GoIntLiteral(currentIndex)))); - currentIndex += 1; - } - return ret; - } -} diff --git a/src/pgo/trans/passes/codegen/go/GoExpressionIsConstantVisitor.java b/src/pgo/trans/passes/codegen/go/GoExpressionIsConstantVisitor.java deleted file mode 100644 index 5db1d35a5..000000000 --- a/src/pgo/trans/passes/codegen/go/GoExpressionIsConstantVisitor.java +++ /dev/null @@ -1,96 +0,0 @@ -package pgo.trans.passes.codegen.go; - -import pgo.TODO; -import pgo.model.golang.*; - -import java.util.function.Function; - -public class GoExpressionIsConstantVisitor extends GoExpressionVisitor { - @Override - public Boolean visit(GoVariableName v) throws RuntimeException { - return false; - } - - @Override - public Boolean visit(GoBuiltins.BuiltinConstant v) throws RuntimeException { - return true; - } - - @Override - public Boolean visit(GoIntLiteral intLiteral) throws RuntimeException { - return true; - } - - @Override - public Boolean visit(GoMapLiteral mapConstructor) throws RuntimeException { - throw new TODO(); - } - - @Override - public Boolean visit(GoStringLiteral stringLiteral) throws RuntimeException { - return true; - } - - @Override - public Boolean visit(GoIndexExpression index) throws RuntimeException { - return index.getTarget().accept(this) && index.getIndex().accept(this); - } - - @Override - public Boolean visit(GoSliceOperator slice) throws RuntimeException { - Function nullOrConst = exp -> exp != null ? exp.accept(this) : true; - return slice.getTarget().accept(this) && nullOrConst.apply(slice.getLow()) - && nullOrConst.apply(slice.getHigh()) && nullOrConst.apply(slice.getMax()); - } - - @Override - public Boolean visit(GoSliceLiteral sliceConstructor) throws RuntimeException { - return sliceConstructor.getInitializers().stream().allMatch(exp -> exp.accept(this)); - } - - @Override - public Boolean visit(GoTypeAssertion typeAssertion) throws RuntimeException { - return false; - } - - @Override - public Boolean visit(GoAnonymousFunction anonymousFunction) throws RuntimeException { - return false; - } - - @Override - public Boolean visit(GoCall call) throws RuntimeException { - return call.getTarget().accept(this) && call.getArguments().stream().allMatch(exp -> exp.accept(this)); - } - - @Override - public Boolean visit(GoTypeCast typeCast) throws RuntimeException { - return typeCast.getTarget().accept(this); - } - - @Override - public Boolean visit(GoStructLiteral structLiteral) throws RuntimeException { - return structLiteral.getFields().stream().allMatch(field -> field.getValue().accept(this)); - } - - @Override - public Boolean visit(GoBinop binop) throws RuntimeException { - return binop.getLHS().accept(this) && binop.getRHS().accept(this); - } - - @Override - public Boolean visit(GoUnary unary) throws RuntimeException { - return unary.getTarget().accept(this); - } - - @Override - public Boolean visit(GoSelectorExpression dot) throws RuntimeException { - return dot.getLHS().accept(this); - } - - @Override - public Boolean visit(GoMakeExpression make) throws RuntimeException { - return (make.getCapacity() != null ? make.getCapacity().accept(this) : true) - && (make.getSize() != null ? make.getSize().accept(this) : true); - } -} diff --git a/src/pgo/trans/passes/codegen/go/GoExpressionStaticComparisonVisitor.java b/src/pgo/trans/passes/codegen/go/GoExpressionStaticComparisonVisitor.java deleted file mode 100644 index 54d0ee1dc..000000000 --- a/src/pgo/trans/passes/codegen/go/GoExpressionStaticComparisonVisitor.java +++ /dev/null @@ -1,143 +0,0 @@ -package pgo.trans.passes.codegen.go; - -import pgo.InternalCompilerError; -import pgo.TODO; -import pgo.model.golang.*; - -import java.util.List; - -public class GoExpressionStaticComparisonVisitor extends GoExpressionVisitor { - - private final GoExpression rhs; - - public GoExpressionStaticComparisonVisitor(GoExpression rhs) { - this.rhs = rhs; - } - - @Override - public Integer visit(GoVariableName v) throws RuntimeException { - throw new InternalCompilerError(); - } - - private T getRhs(GoExpression lhs){ - if(lhs.getClass().isInstance(rhs)){ - return (T)rhs; - } - throw new InternalCompilerError(); - } - - @Override - public Integer visit(GoBuiltins.BuiltinConstant v) throws RuntimeException { - GoBuiltins.BuiltinConstant rhs = getRhs(v); - if(v.getValue().equals(rhs.getValue())) return 0; - if(rhs.getValue().equals("true")) return -1; - if(rhs.getValue().equals("false")) return 1; - throw new InternalCompilerError(); - } - - @Override - public Integer visit(GoIntLiteral intLiteral) throws RuntimeException { - GoIntLiteral rhs = getRhs(intLiteral); - return intLiteral.getValue() - rhs.getValue(); - } - - @Override - public Integer visit(GoMapLiteral mapConstructor) throws RuntimeException { - throw new TODO(); - } - - @Override - public Integer visit(GoStringLiteral stringLiteral) throws RuntimeException { - GoStringLiteral rhs = getRhs(stringLiteral); - return stringLiteral.getValue().compareTo(rhs.getValue()); - } - - @Override - public Integer visit(GoIndexExpression index) throws RuntimeException { - throw new TODO(); - } - - @Override - public Integer visit(GoSliceOperator slice) throws RuntimeException { - throw new TODO(); - } - - @Override - public Integer visit(GoSliceLiteral sliceConstructor) throws RuntimeException { - GoSliceLiteral rhs = getRhs(sliceConstructor); - List lhsInitializers = sliceConstructor.getInitializers(); - List rhsInitializers = rhs.getInitializers(); - int sizeDiff = lhsInitializers.size() - rhsInitializers.size(); - if(sizeDiff == 0){ - for(int i = 0; i < lhsInitializers.size(); ++i){ - int elementDiff = lhsInitializers.get(i).accept( - new GoExpressionStaticComparisonVisitor(rhsInitializers.get(i))); - if(elementDiff != 0){ - return elementDiff; - } - } - return 0; - }else{ - return sizeDiff; - } - } - - @Override - public Integer visit(GoTypeAssertion typeAssertion) throws RuntimeException { - throw new TODO(); - } - - @Override - public Integer visit(GoAnonymousFunction anonymousFunction) throws RuntimeException { - throw new TODO(); - } - - @Override - public Integer visit(GoCall call) throws RuntimeException { - throw new TODO(); - } - - @Override - public Integer visit(GoTypeCast typeCast) throws RuntimeException { - throw new TODO(); - } - - @Override - public Integer visit(GoStructLiteral structLiteral) throws RuntimeException { - GoStructLiteral rhs = getRhs(structLiteral); - // TODO: this only works is all fields are specified - List lhsFields = structLiteral.getFields(); - List rhsFields = rhs.getFields(); - if(lhsFields.size() != rhsFields.size()){ - throw new InternalCompilerError(); - } - for(int i = 0; i < lhsFields.size(); ++i){ - int elementDiff = lhsFields.get(i).getValue().accept( - new GoExpressionStaticComparisonVisitor(rhsFields.get(i).getValue())); - if(elementDiff != 0){ - return elementDiff; - } - } - return 0; - } - - @Override - public Integer visit(GoBinop binop) throws RuntimeException { - throw new TODO(); - } - - @Override - public Integer visit(GoUnary unary) throws RuntimeException { - throw new TODO(); - } - - @Override - public Integer visit(GoSelectorExpression dot) throws RuntimeException { - throw new TODO(); - } - - @Override - public Integer visit(GoMakeExpression make) throws RuntimeException { - throw new TODO(); - } -} diff --git a/src/pgo/trans/passes/codegen/go/LessThanCodeGenVisitor.java b/src/pgo/trans/passes/codegen/go/LessThanCodeGenVisitor.java deleted file mode 100644 index b8fc559bc..000000000 --- a/src/pgo/trans/passes/codegen/go/LessThanCodeGenVisitor.java +++ /dev/null @@ -1,192 +0,0 @@ -package pgo.trans.passes.codegen.go; - -import pgo.TODO; -import pgo.model.golang.*; -import pgo.model.golang.builder.GoBlockBuilder; -import pgo.model.golang.builder.GoForRangeBuilder; -import pgo.model.golang.builder.GoForStatementClauseBuilder; -import pgo.model.golang.type.*; -import pgo.model.type.RecordType; -import pgo.model.type.Type; -import pgo.scope.UID; -import pgo.trans.intermediate.DefinitionRegistry; -import pgo.trans.intermediate.TLABuiltins; - -import java.util.*; -import java.util.function.Function; - -public class LessThanCodeGenVisitor extends GoTypeVisitor { - - private final GoBlockBuilder builder; - private final GoExpression lhs; - private final GoExpression rhs; - - public LessThanCodeGenVisitor(GoBlockBuilder builder, GoExpression lhs, GoExpression rhs) { - this.builder = builder; - this.lhs = lhs; - this.rhs = rhs; - } - - @Override - public GoExpression visit(GoTypeName typeName) throws RuntimeException { - if (typeName.isBuiltin()) { - return new GoBinop(GoBinop.Operation.LT, lhs, rhs); - } else { - throw new TODO(); - } - } - - @Override - public GoExpression visit(GoArchetypeResourceType archetypeResourceType) throws RuntimeException { - throw new TODO(); - } - - @Override - public GoExpression visit(GoArchetypeResourceCollectionType archetypeResourceCollectionType) throws RuntimeException { - throw new TODO(); - } - - private GoExpression constructStructComparison(int i, List fields){ - GoStructTypeField field = fields.get(i); - if(fields.size() == i+1){ - return field.getType().accept( - new LessThanCodeGenVisitor( - builder, - new GoSelectorExpression(lhs, field.getName()), - new GoSelectorExpression(rhs, field.getName()))); - }else{ - return new GoBinop(GoBinop.Operation.OR, - field.getType().accept( - new LessThanCodeGenVisitor( - builder, - new GoSelectorExpression(lhs, field.getName()), - new GoSelectorExpression(rhs, field.getName()))), - new GoBinop(GoBinop.Operation.AND, - field.getType().accept(new EqCodeGenVisitor( - builder, - new GoSelectorExpression(lhs, field.getName()), - new GoSelectorExpression(rhs, field.getName()), - false)), - constructStructComparison(i+1, fields))); - } - } - - @Override - public GoExpression visit(GoStructType structType) throws RuntimeException { - return constructStructComparison(0, structType.getFields()); - } - - @Override - public GoExpression visit(GoPtrType ptrType) throws RuntimeException { - return ptrType.getPointee().accept( - new LessThanCodeGenVisitor( - builder, - new GoUnary(GoUnary.Operation.DEREF, lhs), - new GoUnary(GoUnary.Operation.DEREF, rhs))); - } - - @Override - public GoExpression visit(GoSliceType sliceType) throws RuntimeException { - GoVariableName less = builder.varDecl("less", new GoBinop( - GoBinop.Operation.LT, - new GoCall(new GoVariableName("len"), Collections.singletonList(lhs)), - new GoCall(new GoVariableName("len"), Collections.singletonList(rhs)))); - try(GoIfBuilder lengthEQ = builder.ifStmt( - new GoBinop( - GoBinop.Operation.EQ, - new GoCall(new GoVariableName("len"), Collections.singletonList(lhs)), - new GoCall(new GoVariableName("len"), Collections.singletonList(rhs))))){ - try(GoBlockBuilder yes = lengthEQ.whenTrue()){ - GoForStatementClauseBuilder loopBuilder = yes.forLoopWithClauses(); - GoVariableName i = loopBuilder.initVariable("i", new GoIntLiteral(0)); - loopBuilder.setCondition( - new GoBinop( - GoBinop.Operation.LT, - i, - new GoCall(new GoVariableName("len"), Collections.singletonList(lhs)))); - loopBuilder.setInc(new GoIncDec(true, i)); - try(GoBlockBuilder loopBody = loopBuilder.getBlockBuilder()) { - loopBody.assign( - less, - sliceType.getElementType().accept( - new LessThanCodeGenVisitor( - loopBody, - new GoIndexExpression(lhs, i), - new GoIndexExpression(rhs, i)))); - try(GoIfBuilder shouldStop = loopBody.ifStmt( - sliceType.getElementType().accept( - new EqCodeGenVisitor(loopBody, new GoIndexExpression(lhs, i), new GoIndexExpression(rhs, i), true)))){ - try(GoBlockBuilder body = shouldStop.whenTrue()){ - body.addStatement(new GoBreak()); - } - } - } - } - } - return less; - } - - @Override - public GoExpression visit(GoChanType chanType) throws RuntimeException { - throw new TODO(); - } - - @Override - public GoExpression visit(GoMapType mapType) throws RuntimeException { - // only comparison of record types are supported - if (!mapType.isRecord()) { - throw new TODO(); - } - - // Go pseudo-code: - // - // less := false - // for { - // // comparisons below in sorted order of keys (record entries) - // - // if !(Eq(lhs[e_1].(valType_1), rhs[e_1].(valType_1)) { - // less = LessThan(lhs[e_1].(valType_1), rhs[e_1].(valType_1)) - // break - // } - // ... - // if !(Eq(lhs[e_N].(valType_N), rhs[e_1].(valType_1)) { - // less = LessThan(lhs[e_1].(valType_1), rhs[e_1].(valType_1)) - // break - // } - // - // break - // } - // return less - - GoVariableName less = builder.varDecl("less", GoBuiltins.False); - try (GoBlockBuilder forLoop = builder.forLoop(null)) { - mapType.getInferredTypes().forEach((f, valType) -> { - Function extractValue = exp -> { - GoExpression index = new GoIndexExpression(exp, new GoStringLiteral(f)); - return new GoTypeCast(new GoTypeName(valType.toString()), index); - }; - - GoExpression lhsVal = extractValue.apply(lhs); - GoExpression rhsVal = extractValue.apply(rhs); - - GoExpression condition = valType.accept(new EqCodeGenVisitor(forLoop, lhsVal, rhsVal, true)); - try (GoIfBuilder notEq = forLoop.ifStmt(condition)) { - try (GoBlockBuilder different = notEq.whenTrue()) { - GoExpression lt = valType.accept(new LessThanCodeGenVisitor(different, lhsVal, rhsVal)); - different.assign(less, lt); - different.addStatement(new GoBreak()); - } - } - }); - - forLoop.addStatement(new GoBreak()); - } - - return less; - } - - @Override - public GoExpression visit(GoInterfaceType interfaceType) throws RuntimeException { - throw new TODO(); - } -} diff --git a/src/pgo/trans/passes/codegen/go/LocalVariableStrategy.java b/src/pgo/trans/passes/codegen/go/LocalVariableStrategy.java deleted file mode 100644 index 2869dfd9a..000000000 --- a/src/pgo/trans/passes/codegen/go/LocalVariableStrategy.java +++ /dev/null @@ -1,13 +0,0 @@ -package pgo.trans.passes.codegen.go; - -import pgo.model.golang.GoExpression; -import pgo.model.golang.builder.GoBlockBuilder; -import pgo.scope.UID; -import pgo.trans.passes.codegen.go.GlobalVariableStrategy.GlobalVariableWrite; - -public abstract class LocalVariableStrategy { - public abstract void actionPrelude(GoBlockBuilder builder, UID labelUID); - public abstract GoExpression readLocalVariable(GoBlockBuilder builder, UID local); - public abstract GlobalVariableWrite writeLocalVariable(GoBlockBuilder builder, UID local); - public abstract void actionPostlude(GoBlockBuilder builder, UID labelUID); -} diff --git a/src/pgo/trans/passes/codegen/go/ModularPlusCalGoCodeGenPass.java b/src/pgo/trans/passes/codegen/go/ModularPlusCalGoCodeGenPass.java deleted file mode 100644 index ff40bdd53..000000000 --- a/src/pgo/trans/passes/codegen/go/ModularPlusCalGoCodeGenPass.java +++ /dev/null @@ -1,284 +0,0 @@ -package pgo.trans.passes.codegen.go; - -import pgo.InternalCompilerError; -import pgo.PGoOptions; -import pgo.model.golang.*; -import pgo.model.golang.builder.GoBlockBuilder; -import pgo.model.golang.builder.GoFunctionDeclarationBuilder; -import pgo.model.golang.builder.GoModuleBuilder; -import pgo.model.golang.type.GoMapType; -import pgo.model.golang.type.GoType; -import pgo.model.golang.type.GoTypeName; -import pgo.model.mpcal.ModularPlusCalArchetype; -import pgo.model.mpcal.ModularPlusCalBlock; -import pgo.model.pcal.PlusCalNode; -import pgo.model.pcal.PlusCalStatement; -import pgo.model.pcal.PlusCalVariableDeclaration; -import pgo.model.tla.PlusCalDefaultInitValue; -import pgo.model.tla.TLAExpression; -import pgo.model.type.*; -import pgo.scope.UID; -import pgo.trans.intermediate.DefinitionRegistry; - -import java.util.*; -import java.util.function.Function; -import java.util.stream.Collectors; - -public class ModularPlusCalGoCodeGenPass { - private ModularPlusCalGoCodeGenPass() {} - - private static void generateLocalVariableDefinitions(DefinitionRegistry registry, Map typeMap, LocalVariableStrategy localStrategy, - GlobalVariableStrategy globalStrategy, GoBlockBuilder processBody, - List variableDeclarations) { - for (PlusCalVariableDeclaration variableDeclaration : variableDeclarations) { - GoVariableName name; - GoType varType; - - if (variableDeclaration.getValue() instanceof PlusCalDefaultInitValue) { - Type inferredType = typeMap.get(variableDeclaration.getUID()); - - varType = inferredType.accept(new TypeConversionVisitor()); - name = processBody.varDecl(variableDeclaration.getName().getId(), varType); - } else { - GoExpression value = variableDeclaration.getValue().accept( - new TLAExpressionCodeGenVisitor(processBody, registry, typeMap, localStrategy, globalStrategy)); - if (variableDeclaration.isSet()) { - value = new GoIndexExpression(value, new GoIntLiteral(0)); - } - - name = processBody.varDecl(variableDeclaration.getName().getId(), value); - } - processBody.linkUID(variableDeclaration.getUID(), name); - } - } - - private static void generateInit(ModularPlusCalBlock modularPlusCalBlock, GoModuleBuilder module, - DefinitionRegistry registry, Map typeMap, - LocalVariableStrategy localStrategy, GlobalVariableStrategy globalStrategy) { - Map constants = new TreeMap<>(); // sort constants for deterministic compiler output - Map constantIds = new HashMap<>(); - for (UID uid : registry.getConstants().stream().filter(c -> registry.getConstantValue(c).isPresent()).collect(Collectors.toSet())) { - String name = registry.getConstantName(uid); - constants.put(name, typeMap.get(uid)); - constantIds.put(name, uid); - } - - try (GoBlockBuilder initBuilder = module.defineFunction("init").getBlockBuilder()) { - // generate constant definitions and initializations - for (Map.Entry pair : constants.entrySet()) { - // get() here is safe by construction - TLAExpression value = registry.getConstantValue(constantIds.get(pair.getKey())).get(); - Type type = typeMap.get(constantIds.get(pair.getKey())); - GoVariableName name = module.defineGlobal( - constantIds.get(pair.getKey()), - pair.getKey(), - type.accept(new TypeConversionVisitor())); - initBuilder.assign( - name, - value.accept(new TLAExpressionCodeGenVisitor(initBuilder, registry, typeMap, localStrategy, globalStrategy))); - } - - // Given an archetype resource type, returns whether or not TLA+ record support should - // be registered with the runtime (i.e.. whether the type itself is a record, or a container - // of records). - Function requiresRecords = type -> { - if (type instanceof ArchetypeResourceType) { - return ((ArchetypeResourceType) type).getReadType() instanceof RecordType || - ((ArchetypeResourceType) type).getWriteType() instanceof RecordType; - } - if (type instanceof ArchetypeResourceCollectionType) { - return ((ArchetypeResourceCollectionType) type).getReadType() instanceof RecordType || - ((ArchetypeResourceCollectionType) type).getWriteType() instanceof RecordType; - } - throw new InternalCompilerError(); - }; - - // if the write type of any archetype resource is a record, define our record representation - // (map[string]interface{}) with the runtime - boolean writesRecord = modularPlusCalBlock - .getInstantiatedArchetypes() - .stream() - .map(ModularPlusCalArchetype::getParams) - .flatMap(Collection::stream) - .map(PlusCalNode::getUID) - .anyMatch(uid -> requiresRecords.apply(typeMap.get(uid))); - - if (writesRecord) { - GoExpression registerRecord = new GoCall( - new GoSelectorExpression(new GoVariableName("distsys"), "DefineCustomType"), - Collections.singletonList( - new GoMapLiteral(GoBuiltins.String, GoBuiltins.Interface, Collections.emptyMap()) - ) - ); - - // TODO: we should only register []map[string]interface{} if this is ever transmitted over the wire - GoExpression registerListOfRecords = new GoCall( - new GoSelectorExpression(new GoVariableName("distsys"), "DefineCustomType"), - Collections.singletonList( - new GoSliceLiteral( - new GoMapType(GoBuiltins.String, GoBuiltins.Interface, Collections.emptyMap()), - Collections.emptyList() - ) - ) - ); - - initBuilder.addStatement(registerRecord); - initBuilder.addStatement(registerListOfRecords); - } - - // sets rand seed for unique random numbers on every execution - GoExpression timeNow = new GoCall( - new GoSelectorExpression(new GoVariableName("time"), "Now"), - Collections.emptyList() - ); - GoExpression unixNano = new GoCall( - new GoSelectorExpression(timeNow, "UnixNano"), - Collections.emptyList() - ); - GoExpression randSeed = new GoCall( - new GoSelectorExpression(new GoVariableName("rand"), "Seed"), - Collections.singletonList(unixNano) - ); - - initBuilder.addStatement(randSeed); - } - } - - // Creates the following function, used to check whether the error - // returned by an archetype resource implementation should cause the - // running action to abort, or the entire process should terminate. - - // func shouldRetry(err error) bool { - // switch err.(type) { - // case *distsys.AbortRetryError: - // t := rand.Intn(sleepMax - sleepMin) + sleepMin - // time.Sleep(time.Duration(t) * time.Millisecond) - // - // return true - // case *distsys.ResourceInternalError: - // return false - // default: - // // Archetype resource should return errors of the previous two types only - // panic(fmt.Sprintf("Invalid error returned by Archetype Resource: %v", err)) - // } - // } - private static void defineShouldRetry(GoModuleBuilder module, GoVariableName sleepMin, GoVariableName sleepMax) { - module.addImport("fmt"); - module.addImport("time"); - module.addImport("math/rand"); - - GoFunctionDeclarationBuilder builder = module.defineFunction("shouldRetry"); - GoVariableName err = builder.addParameter("err", GoBuiltins.Error); - builder.addReturn(GoBuiltins.Bool); - - GoExpression sprintf = new GoCall( - new GoSelectorExpression(new GoVariableName("fmt"), "Sprintf"), - Arrays.asList( - new GoStringLiteral("Invalid error returned by Archetype Resource: %v"), - err - ) - ); - GoExpression panic = new GoCall(new GoVariableName("panic"), Collections.singletonList(sprintf)); - - GoType abortRetry = new GoPtrType(new GoTypeName("distsys.AbortRetryError")); - GoType internalError = new GoPtrType(new GoTypeName("distsys.ResourceInternalError")); - - try (GoBlockBuilder fnBody = builder.getBlockBuilder()) { - GoExpression rand = new GoCall( - new GoSelectorExpression(new GoVariableName("rand"), "Intn"), - Collections.singletonList(new GoBinop(GoBinop.Operation.MINUS, sleepMax, sleepMin)) - ); - GoVariableName t = fnBody.varDecl("t", new GoBinop(GoBinop.Operation.PLUS, rand, sleepMin)); - GoExpression tDuration = new GoCall( - new GoSelectorExpression(new GoVariableName("time"), "Duration"), - Collections.singletonList(t) - ); - GoExpression millisecond = new GoSelectorExpression(new GoVariableName("time"), "Millisecond"); - GoStatement sleep = new GoExpressionStatement(new GoCall( - new GoSelectorExpression(new GoVariableName("time"), "Sleep"), - Collections.singletonList(new GoBinop(GoBinop.Operation.TIMES, tDuration, millisecond)) - )); - - List sleepAndReturn = Arrays.asList( - sleep, - new GoReturn(Collections.singletonList(GoBuiltins.True)) - ); - - fnBody.addStatement(GoSwitch.typeSwitch( - err, - Arrays.asList( - new GoSwitchCase(abortRetry, sleepAndReturn), - new GoSwitchCase(internalError, Collections.singletonList(new GoReturn(Collections.singletonList(GoBuiltins.False)))) - ), - Collections.singletonList(new GoExpressionStatement(panic)) - ) - ); - } - } - - public static GoModule perform(DefinitionRegistry registry, Map typeMap, PGoOptions opts, - ModularPlusCalBlock modularPlusCalBlock) { - GoModuleBuilder module = new GoModuleBuilder(modularPlusCalBlock.getName().getId(), opts.buildPackage); - SnapshottingLocalVariableStrategy localStrategy = new SnapshottingLocalVariableStrategy(registry, typeMap); - GlobalVariableStrategy globalStrategy = new ArchetypeResourcesGlobalVariableStrategy(registry, typeMap, localStrategy, null); - - GoVariableName sleepMin = module.defineGlobal(new UID(), "sleepMin", new GoIntLiteral(10)); - GoVariableName sleepMax = module.defineGlobal(new UID(), "sleepMax", new GoIntLiteral(30)); - - generateInit(modularPlusCalBlock, module, registry, typeMap, localStrategy, globalStrategy); - defineShouldRetry(module, sleepMin, sleepMax); - - for (ModularPlusCalArchetype archetype : modularPlusCalBlock.getInstantiatedArchetypes()) { - globalStrategy = new ArchetypeResourcesGlobalVariableStrategy(registry, typeMap, localStrategy, archetype.getUID()); - - GoFunctionDeclarationBuilder fn = module.defineFunction(archetype.getUID(), archetype.getName()); - fn.addReturn(GoBuiltins.Error); - - Map argMap = new HashMap<>(); - - // all archetypes have a `self` parameter - GoVariableName selfVariable = fn.addParameter("self", GoBuiltins.Int); - - for (PlusCalVariableDeclaration arg : archetype.getParams()) { - module.addImport("pgo/distsys"); - - // find out if archetype resource should be passed as resource collection - // if it is used like a TLA+ function in the archetype's body - GoType argType; - if (typeMap.get(arg.getUID()) instanceof ArchetypeResourceCollectionType) { - argType = new GoTypeName("distsys.ArchetypeResourceCollection"); - } else { - argType = new GoTypeName("distsys.ArchetypeResource"); - } - - argMap.put(arg.getName().getId(), fn.addParameter(arg.getName().getId(), argType)); - } - - try (GoBlockBuilder fnBody = fn.getBlockBuilder()) { - // link the 'self' parameter - fnBody.linkUID(archetype.getSelfVariableUID(), selfVariable); - - for (PlusCalVariableDeclaration arg : archetype.getParams()) { - fnBody.linkUID(arg.getUID(), argMap.get(arg.getName().getId())); - } - - generateLocalVariableDefinitions(registry, typeMap, localStrategy, globalStrategy, fnBody, archetype.getVariables()); - localStrategy.initArchetype(fnBody, archetype); - - // TODO: this should probably be a separate method in GlobalVariableStrategy - globalStrategy.processPrelude(fnBody, null, archetype.getName(), selfVariable, GoBuiltins.Int); - - PlusCalStatementCodeGenVisitor codeGen = new PlusCalStatementCodeGenVisitor( - registry, typeMap, localStrategy, globalStrategy, archetype.getUID(), fnBody - ); - for (PlusCalStatement statement : archetype.getBody()) { - statement.accept(codeGen); - } - - fnBody.returnStmt(GoBuiltins.Nil); - } - } - - return module.getModule(); - } -} \ No newline at end of file diff --git a/src/pgo/trans/passes/codegen/go/MultithreadedProcessGlobalVariableStrategy.java b/src/pgo/trans/passes/codegen/go/MultithreadedProcessGlobalVariableStrategy.java deleted file mode 100644 index 3528f7e64..000000000 --- a/src/pgo/trans/passes/codegen/go/MultithreadedProcessGlobalVariableStrategy.java +++ /dev/null @@ -1,149 +0,0 @@ -package pgo.trans.passes.codegen.go; - -import pgo.model.golang.*; -import pgo.model.golang.builder.GoBlockBuilder; -import pgo.model.golang.builder.GoForRangeBuilder; -import pgo.model.golang.builder.GoModuleBuilder; -import pgo.model.golang.type.GoChanType; -import pgo.model.golang.type.GoSliceType; -import pgo.model.golang.type.GoType; -import pgo.model.golang.type.GoTypeName; -import pgo.model.mpcal.ModularPlusCalBlock; -import pgo.model.pcal.PlusCalMultiProcess; -import pgo.model.pcal.PlusCalProcess; -import pgo.model.type.Type; -import pgo.scope.UID; -import pgo.trans.intermediate.DefinitionRegistry; - -import java.util.Arrays; -import java.util.Collections; -import java.util.Map; -import java.util.Objects; - -// FIXME this strategy, for efficiency reasons, does not implement abortCriticalSection correctly -public class MultithreadedProcessGlobalVariableStrategy extends GlobalVariableStrategy { - private final DefinitionRegistry registry; - private final Map typeMap; - private final LocalVariableStrategy localStrategy; - private final ModularPlusCalBlock modularPlusCalBlock; - private final UID pGoLockUID; - private final UID pGoWaitUID; - private final UID pGoStartUID; - - private static final GoType PGO_LOCK_TYPE = new GoSliceType(new GoTypeName("sync.RWMutex")); - - public MultithreadedProcessGlobalVariableStrategy(DefinitionRegistry registry, Map typeMap, - LocalVariableStrategy localStrategy, ModularPlusCalBlock modularPlusCalBlock) { - this.registry = registry; - this.typeMap = typeMap; - this.localStrategy = localStrategy; - this.modularPlusCalBlock = modularPlusCalBlock; - this.pGoLockUID = new UID(); - this.pGoWaitUID = new UID(); - this.pGoStartUID = new UID(); - } - - @Override - public void initPostlude(GoModuleBuilder moduleBuilder, GoBlockBuilder initBuilder) { - moduleBuilder.addImport("sync"); - GoVariableName pGoStart = moduleBuilder.defineGlobal(pGoStartUID, "pGoStart", new GoChanType(GoBuiltins.Bool)); - addVariable(pGoStartUID, pGoStart); - initBuilder.assign(pGoStart, new GoMakeExpression(new GoChanType(GoBuiltins.Bool), null, null)); - GoVariableName pGoWait = moduleBuilder.defineGlobal(pGoWaitUID, "pGoWait", new GoTypeName("sync.WaitGroup")); - addVariable(pGoWaitUID, pGoWait); - int nLock = registry.getNumberOfLockGroups(); - if (nLock <= 0) { - // no lock to allocate - return; - } - GoVariableName pGoLock = moduleBuilder.defineGlobal(pGoLockUID, "pGoLock", PGO_LOCK_TYPE); - addVariable(pGoLockUID, pGoLock); - initBuilder.assign(pGoLock, new GoMakeExpression(PGO_LOCK_TYPE, new GoIntLiteral(nLock), null)); - } - - @Override - public void processPrelude(GoBlockBuilder processBody, PlusCalProcess process, String processName, GoVariableName self, - GoType selfType) { - processBody.deferStmt(new GoCall( - new GoSelectorExpression(findVariable(pGoWaitUID), "Done"), - Collections.emptyList())); - processBody.addStatement(new GoUnary(GoUnary.Operation.RECV, findVariable(pGoStartUID))); - } - - @Override - public void mainPrelude(GoBlockBuilder builder) { - for (PlusCalProcess process : ((PlusCalMultiProcess) modularPlusCalBlock.getProcesses()).getProcesses()) { - String processName = process.getName().getName().getId(); - GoExpression value = process.getName().getValue().accept( - new TLAExpressionCodeGenVisitor(builder, registry, typeMap, localStrategy, this)); - if (process.getName().isSet()) { - GoForRangeBuilder forRangeBuilder = builder.forRange(value); - GoVariableName v = forRangeBuilder.initVariables(Arrays.asList("_", "v")).get(1); - try (GoBlockBuilder forBody = forRangeBuilder.getBlockBuilder()) { - forBody.addStatement(new GoCall( - new GoSelectorExpression(findVariable(pGoWaitUID), "Add"), - Collections.singletonList(new GoIntLiteral(1)))); - forBody.goStmt(new GoCall(new GoVariableName(processName), Collections.singletonList(v))); - } - continue; - } - builder.addStatement(new GoCall( - new GoSelectorExpression(findVariable(pGoWaitUID), "Add"), - Collections.singletonList(new GoIntLiteral(1)))); - builder.goStmt(new GoCall(new GoVariableName(processName), Collections.singletonList(value))); - } - builder.addStatement(new GoCall( - new GoVariableName("close"), - Collections.singletonList(findVariable(pGoStartUID)))); - GoVariableName pGoWait = findVariable(pGoWaitUID); - builder.addStatement(new GoCall(new GoSelectorExpression(pGoWait, "Wait"), Collections.emptyList())); - } - - @Override - public void startCriticalSection(GoBlockBuilder builder, UID processUID, int lockGroup, UID labelUID, GoLabelName labelName) { - String functionName = "Lock"; - if (registry.getVariableWritesInLockGroup(lockGroup).isEmpty()) { - functionName = "RLock"; - } - builder.addStatement(new GoCall( - new GoSelectorExpression(new GoIndexExpression(findVariable(pGoLockUID), new GoIntLiteral(lockGroup)), functionName), - Collections.emptyList())); - } - - @Override - public void abortCriticalSection(GoBlockBuilder builder, UID processUID, int lockGroup, UID labelUID, GoLabelName labelName) { - // FIXME - endCriticalSection(builder, processUID, lockGroup, labelUID, labelName); - } - - @Override - public void endCriticalSection(GoBlockBuilder builder, UID processUID, int lockGroup, UID labelUID, GoLabelName labelName) { - String functionName = "Unlock"; - if (registry.getVariableWritesInLockGroup(lockGroup).isEmpty()) { - functionName = "RUnlock"; - } - builder.addStatement(new GoCall( - new GoSelectorExpression(new GoIndexExpression(findVariable(pGoLockUID), new GoIntLiteral(lockGroup)), functionName), - Collections.emptyList())); - } - - @Override - public GoExpression readGlobalVariable(GoBlockBuilder builder, UID uid) { - return builder.findUID(uid); - } - - @Override - public GlobalVariableWrite writeGlobalVariable(UID uid) { - return new GlobalVariableWrite() { - @Override - public GoExpression getValueSink(GoBlockBuilder builder) { - return builder.findUID(uid); - } - - @Override - public void writeAfter(GoBlockBuilder builder) { - // pass - } - }; - } -} diff --git a/src/pgo/trans/passes/codegen/go/PlusCalGoCodeGenPass.java b/src/pgo/trans/passes/codegen/go/PlusCalGoCodeGenPass.java deleted file mode 100644 index 54ee3e64b..000000000 --- a/src/pgo/trans/passes/codegen/go/PlusCalGoCodeGenPass.java +++ /dev/null @@ -1,49 +0,0 @@ -package pgo.trans.passes.codegen.go; - -import pgo.PGoNetOptions; -import pgo.PGoOptions; -import pgo.Unreachable; -import pgo.model.golang.GoModule; -import pgo.model.golang.builder.GoModuleBuilder; -import pgo.model.mpcal.ModularPlusCalBlock; -import pgo.model.pcal.PlusCalProcesses; -import pgo.model.pcal.PlusCalSingleProcess; -import pgo.model.type.Type; -import pgo.scope.UID; -import pgo.trans.intermediate.DefinitionRegistry; - -import java.util.Map; - -public class PlusCalGoCodeGenPass { - private PlusCalGoCodeGenPass() {} - - public static GoModule perform(DefinitionRegistry registry, Map typeMap, PGoOptions opts, - ModularPlusCalBlock modularPlusCalBlock) { - GoModuleBuilder moduleBuilder = new GoModuleBuilder(modularPlusCalBlock.getName().getId(), "main"); - PlusCalProcesses processes = modularPlusCalBlock.getProcesses(); - LocalVariableStrategy localStrategy = new DefaultLocalVariableStrategy(); - GlobalVariableStrategy globalVariableStrategy; - if (processes instanceof PlusCalSingleProcess) { - globalVariableStrategy = new SingleThreadedProcessGlobalVariableStrategy(); - } else if (!opts.net.isEnabled()) { - globalVariableStrategy = new MultithreadedProcessGlobalVariableStrategy( - registry, typeMap, localStrategy, modularPlusCalBlock); - } else { - switch (opts.net.getStateOptions().strategy) { - case PGoNetOptions.StateOptions.STATE_ETCD: - globalVariableStrategy = new EtcdGlobalVariableStrategy( - registry, typeMap, opts.net.getStateOptions(), modularPlusCalBlock); - break; - case PGoNetOptions.StateOptions.STATE_SERVER: - globalVariableStrategy = new StateServerGlobalVariableStrategy( - registry, typeMap, opts.net.getStateOptions(), modularPlusCalBlock); - break; - default: - throw new Unreachable(); - } - } - processes.accept(new PlusCalProcessesCodeGenVisitor( - registry, typeMap, localStrategy, globalVariableStrategy, modularPlusCalBlock, moduleBuilder)); - return moduleBuilder.getModule(); - } -} diff --git a/src/pgo/trans/passes/codegen/go/PlusCalProcessesCodeGenVisitor.java b/src/pgo/trans/passes/codegen/go/PlusCalProcessesCodeGenVisitor.java deleted file mode 100644 index 62bb1fb9d..000000000 --- a/src/pgo/trans/passes/codegen/go/PlusCalProcessesCodeGenVisitor.java +++ /dev/null @@ -1,176 +0,0 @@ -package pgo.trans.passes.codegen.go; - -import pgo.model.golang.GoExpression; -import pgo.model.golang.GoIndexExpression; -import pgo.model.golang.GoIntLiteral; -import pgo.model.golang.GoVariableName; -import pgo.model.golang.builder.GoBlockBuilder; -import pgo.model.golang.builder.GoFunctionDeclarationBuilder; -import pgo.model.golang.builder.GoModuleBuilder; -import pgo.model.golang.type.GoType; -import pgo.model.mpcal.ModularPlusCalBlock; -import pgo.model.pcal.*; -import pgo.model.tla.TLAExpression; -import pgo.model.type.Type; -import pgo.scope.UID; -import pgo.trans.intermediate.DefinitionRegistry; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.TreeMap; -import java.util.function.Consumer; -import java.util.stream.Collectors; - -public class PlusCalProcessesCodeGenVisitor extends PlusCalProcessesVisitor { - private final DefinitionRegistry registry; - private final Map typeMap; - private final LocalVariableStrategy localStrategy; - private final GlobalVariableStrategy globalStrategy; - private final ModularPlusCalBlock modularPlusCalBlock; - private final GoModuleBuilder moduleBuilder; - - public PlusCalProcessesCodeGenVisitor(DefinitionRegistry registry, Map typeMap, - LocalVariableStrategy localStrategy, GlobalVariableStrategy globalStrategy, - ModularPlusCalBlock modularPlusCalBlock, GoModuleBuilder moduleBuilder) { - this.registry = registry; - this.typeMap = typeMap; - this.localStrategy = localStrategy; - this.globalStrategy = globalStrategy; - this.modularPlusCalBlock = modularPlusCalBlock; - this.moduleBuilder = moduleBuilder; - } - - private void generateInit(Consumer generateGlobalVariables) { - Map constants = new TreeMap<>(); // sort constants for deterministic compiler output - Map constantIds = new HashMap<>(); - for (UID uid : registry.getConstants().stream().filter(c -> registry.getConstantValue(c).isPresent()).collect(Collectors.toSet())) { - String name = registry.getConstantName(uid); - constants.put(name, typeMap.get(uid)); - constantIds.put(name, uid); - } - - try (GoBlockBuilder initBuilder = moduleBuilder.defineFunction("init").getBlockBuilder()) { - // generate constant definitions and initializations - for (Map.Entry pair : constants.entrySet()) { - // get() is safe here by construction - TLAExpression value = registry.getConstantValue(constantIds.get(pair.getKey())).get(); - Type type = typeMap.get(constantIds.get(pair.getKey())); - GoVariableName name = moduleBuilder.defineGlobal( - constantIds.get(pair.getKey()), - pair.getKey(), - type.accept(new TypeConversionVisitor())); - initBuilder.assign( - name, - value.accept(new TLAExpressionCodeGenVisitor(initBuilder, registry, typeMap, localStrategy, globalStrategy))); - } - generateGlobalVariables.accept(initBuilder); - globalStrategy.initPostlude(moduleBuilder, initBuilder); - } - } - - private void generateProcedures() { - for (PlusCalProcedure procedure : modularPlusCalBlock.getProcedures()) { - Map argMap = new HashMap<>(); - UID uid = procedure.getUID(); - - GoFunctionDeclarationBuilder builder = moduleBuilder.defineFunction( - uid, procedure.getName()); - - for (PlusCalVariableDeclaration arg : procedure.getParams()) { - GoType argType = typeMap.get(arg.getUID()).accept(new TypeConversionVisitor()); - argMap.put(arg.getName().getId(), builder.addParameter(arg.getName().getId(), argType)); - } - - try (GoBlockBuilder procBody = builder.getBlockBuilder()) { - for (PlusCalVariableDeclaration arg : procedure.getParams()) { - procBody.linkUID(arg.getUID(), argMap.get(arg.getName().getId())); - } - - generateLocalVariableDefinitions(registry, typeMap, localStrategy, globalStrategy, procBody, procedure.getVariables()); - for (PlusCalStatement statements : procedure.getBody()) { - statements.accept(new PlusCalStatementCodeGenVisitor( - registry, typeMap, localStrategy, globalStrategy, uid, procBody)); - } - } - } - } - - private static void generateLocalVariableDefinitions(DefinitionRegistry registry, Map typeMap, LocalVariableStrategy localStrategy, - GlobalVariableStrategy globalStrategy, GoBlockBuilder processBody, - List variableDeclarations) { - for (PlusCalVariableDeclaration variableDeclaration : variableDeclarations) { - GoExpression value = variableDeclaration.getValue().accept( - new TLAExpressionCodeGenVisitor(processBody, registry, typeMap, localStrategy, globalStrategy)); - if (variableDeclaration.isSet()) { - value = new GoIndexExpression(value, new GoIntLiteral(0)); - } - GoVariableName name = processBody.varDecl(variableDeclaration.getName().getId(), value); - processBody.linkUID(variableDeclaration.getUID(), name); - } - } - - @Override - public Void visit(PlusCalSingleProcess singleProcess) throws RuntimeException { - generateInit(ignored -> {}); - generateProcedures(); - try (GoBlockBuilder fnBuilder = moduleBuilder.defineFunction("main").getBlockBuilder()) { - globalStrategy.mainPrelude(fnBuilder); - generateLocalVariableDefinitions(registry, typeMap, localStrategy, globalStrategy, fnBuilder, modularPlusCalBlock.getVariables()); - for (PlusCalStatement statements : singleProcess.getBody()) { - statements.accept(new PlusCalStatementCodeGenVisitor( - registry, typeMap, localStrategy, globalStrategy, singleProcess.getUID(), fnBuilder)); - } - } - return null; - } - - @Override - public Void visit(PlusCalMultiProcess multiProcess) throws RuntimeException { - generateInit(initBuilder -> { - // generate global variable definitions and initializations - for (PlusCalVariableDeclaration variableDeclaration : modularPlusCalBlock.getVariables()) { - TLAExpression value = variableDeclaration.getValue(); - GoType type = typeMap.get(variableDeclaration.getUID()).accept(new TypeConversionVisitor()); - GoVariableName name = moduleBuilder.defineGlobal( - variableDeclaration.getUID(), variableDeclaration.getName().getId(), type); - if (variableDeclaration.isSet()) { - initBuilder.assign( - name, - new GoIndexExpression( - value.accept(new TLAExpressionCodeGenVisitor( - initBuilder,registry, typeMap, localStrategy, globalStrategy)), - new GoIntLiteral(0))); - } else { - initBuilder.assign( - name, - value.accept(new TLAExpressionCodeGenVisitor( - initBuilder, registry, typeMap, localStrategy, globalStrategy))); - } - } - }); - - generateProcedures(); - - for (PlusCalProcess process : multiProcess.getProcesses()) { - UID processUID = process.getName().getUID(); - GoFunctionDeclarationBuilder functionBuilder = moduleBuilder.defineFunction( - processUID, process.getName().getName().getId()); - GoType selfType = typeMap.get(processUID).accept(new TypeConversionVisitor()); - GoVariableName self = functionBuilder.addParameter("self", selfType); - try (GoBlockBuilder processBody = functionBuilder.getBlockBuilder()) { - processBody.linkUID(processUID, self); - globalStrategy.processPrelude(processBody, process, process.getName().getName().getId(), self, selfType); - generateLocalVariableDefinitions(registry, typeMap, localStrategy, globalStrategy, processBody, process.getVariables()); - for (PlusCalStatement statements : process.getBody()) { - statements.accept(new PlusCalStatementCodeGenVisitor( - registry, typeMap, localStrategy, globalStrategy, processUID, processBody)); - } - } - } - try (GoBlockBuilder fnBuilder = moduleBuilder.defineFunction("main").getBlockBuilder()) { - globalStrategy.mainPrelude(fnBuilder); - } - return null; - } -} diff --git a/src/pgo/trans/passes/codegen/go/PlusCalStatementCodeGenVisitor.java b/src/pgo/trans/passes/codegen/go/PlusCalStatementCodeGenVisitor.java deleted file mode 100644 index 89b8dfbd6..000000000 --- a/src/pgo/trans/passes/codegen/go/PlusCalStatementCodeGenVisitor.java +++ /dev/null @@ -1,402 +0,0 @@ -package pgo.trans.passes.codegen.go; - -import pgo.InternalCompilerError; -import pgo.Unreachable; -import pgo.model.golang.*; -import pgo.model.golang.builder.GoBlockBuilder; -import pgo.model.mpcal.ModularPlusCalYield; -import pgo.model.pcal.*; -import pgo.model.tla.TLAExpression; -import pgo.model.tla.TLAGeneralIdentifier; -import pgo.model.type.Type; -import pgo.scope.UID; -import pgo.trans.intermediate.DefinitionRegistry; -import pgo.trans.passes.atomicity.PlusCalStatementAtomicityInferenceVisitor; - -import java.util.*; -import java.util.function.Consumer; -import java.util.function.Function; - -public class PlusCalStatementCodeGenVisitor extends PlusCalStatementVisitor { - private final DefinitionRegistry registry; - private final Map typeMap; - private final LocalVariableStrategy localStrategy; - private final GlobalVariableStrategy globalStrategy; - private final UID processUID; - private final GoBlockBuilder builder; - private CriticalSectionTracker criticalSectionTracker; - private Function awaitAction; - - private PlusCalStatementCodeGenVisitor(DefinitionRegistry registry, Map typeMap, LocalVariableStrategy localStrategy, - GlobalVariableStrategy globalStrategy, UID processUID, GoBlockBuilder builder, - CriticalSectionTracker criticalSectionTracker, - Function awaitAction) { - this.registry = registry; - this.typeMap = typeMap; - this.localStrategy = localStrategy; - this.globalStrategy = globalStrategy; - this.processUID = processUID; - this.builder = builder; - this.criticalSectionTracker = criticalSectionTracker; - this.awaitAction = awaitAction; - } - - public PlusCalStatementCodeGenVisitor(DefinitionRegistry registry, Map typeMap, LocalVariableStrategy localStrategy, - GlobalVariableStrategy globalStrategy, UID processUID, GoBlockBuilder builder) { - this(registry, typeMap, localStrategy, globalStrategy, processUID, builder, - new CriticalSectionTracker(registry, processUID, globalStrategy), ignored -> null); - } - - private static void trackLocalVariableWrites(DefinitionRegistry registry, Set tracker, TLAExpression expression) { - if (expression instanceof TLAGeneralIdentifier) { - UID definitionUID = registry.followReference(expression.getUID()); - if (registry.isLocalVariable(definitionUID)) { - tracker.add(definitionUID); - } - } - } - - @Override - public Void visit(PlusCalLabeledStatements plusCalLabeledStatements) throws RuntimeException { - PlusCalLabel label = plusCalLabeledStatements.getLabel(); - builder.addComment(label.getName() + ":"); - - criticalSectionTracker.start(builder, label.getUID(), new GoLabelName(label.getName())); - for (PlusCalStatement stmt : plusCalLabeledStatements.getStatements()) { - stmt.accept(this); - } - criticalSectionTracker.end(builder); - return null; - } - - @Override - public Void visit(PlusCalWhile plusCalWhile) throws RuntimeException { - // note: here we don't directly compile the loop condition into the GoRoutineStatement loop condition due to - // difficulties with intermediate variables and critical sections (if the condition is false - // we may have to end the critical section after checking the condition) - CriticalSectionTracker loopConditionCriticalSectionTracker = criticalSectionTracker.copy(); - Consumer actionAtLoopEnd = criticalSectionTracker.actionAtLoopEnd(); - boolean loopBodyHasLabel = plusCalWhile.accept(new PlusCalStatementContainsLabelVisitor()); - try (GoBlockBuilder fb = builder.forLoop(null)) { - try(GoIfBuilder loopCondition = fb.ifStmt(CodeGenUtil.invertCondition( - fb, registry, typeMap, localStrategy, globalStrategy, plusCalWhile.getCondition()))) { - try (GoBlockBuilder loopConditionBody = loopCondition.whenTrue()) { - // if there are labels inside the loop, ensure that we end the critical section - // when the loop condition fails as there must be a new label after the loop - // if there are no labels inside the loop however, the critical section from before continues - // uninterrupted - if (loopBodyHasLabel) { - loopConditionCriticalSectionTracker.end(loopConditionBody); - } - loopConditionBody.addStatement(new GoBreak()); - } - } - for (PlusCalStatement statement : plusCalWhile.getBody()) { - statement.accept(new PlusCalStatementCodeGenVisitor( - registry, typeMap, localStrategy, globalStrategy, processUID, fb, criticalSectionTracker, awaitAction)); - } - actionAtLoopEnd.accept(fb); - } - // if the loop body has labels, we must not be in any critical condition after the loop - // since loopConditionCriticalSectionTracker was used to end the critical section, - // it is not in any critical section - // therefore, we can use it as criticalSectionTracker - if (loopBodyHasLabel) { - criticalSectionTracker = loopConditionCriticalSectionTracker; - } - return null; - } - - @Override - public Void visit(PlusCalIf plusCalIf) throws RuntimeException { - GoExpression condition = plusCalIf.getCondition().accept( - new TLAExpressionCodeGenVisitor(builder, registry, typeMap, localStrategy, globalStrategy) - ); - boolean containsLabels = plusCalIf.accept(new PlusCalStatementContainsLabelVisitor()); - try (GoIfBuilder b = builder.ifStmt(condition)) { - CriticalSectionTracker noTracker = criticalSectionTracker.copy(); - try (GoBlockBuilder yes = b.whenTrue()) { - for (PlusCalStatement stmt : plusCalIf.getYes()) { - stmt.accept(new PlusCalStatementCodeGenVisitor( - registry, typeMap, localStrategy, globalStrategy, processUID, yes, criticalSectionTracker, awaitAction)); - } - // if an if statement contains a label, then the statement(s) after it must be labeled - // if the statement after must be labeled, we know this critical section ends here (and - // may be different between true and false branches). otherwise, leave the critical section - // as is - if (containsLabels) { - criticalSectionTracker.end(yes); - } - } - try (GoBlockBuilder no = b.whenFalse()) { - for (PlusCalStatement stmt : plusCalIf.getNo()) { - stmt.accept(new PlusCalStatementCodeGenVisitor( - registry, typeMap, localStrategy, globalStrategy, processUID, no, noTracker, awaitAction)); - } - // see description for true case - if (containsLabels) { - noTracker.end(no); - } - } - criticalSectionTracker.checkCompatibility(noTracker); - } - return null; - } - - @Override - public Void visit(PlusCalEither plusCalEither) throws RuntimeException { - // track which local variable is written to - Set localVarWrites = new HashSet<>(); - PlusCalStatementAtomicityInferenceVisitor writeTracker = new PlusCalStatementAtomicityInferenceVisitor( - new UID(), - (ignored1, ignored2) -> {}, - (expression, ignored) -> trackLocalVariableWrites(registry, localVarWrites, expression), - new HashSet<>()); - List> cases = plusCalEither.getCases(); - for (List eitherCase : cases) { - if (eitherCase.size() <= 0) { - continue; - } - if (eitherCase.get(0) instanceof PlusCalLabeledStatements) { - PlusCalStatement statement = eitherCase.get(0); - // we only need to track the first labeled statements - if (statement.accept(new PlusCalStatementContainsAwaitVisitor())) { - statement.accept(writeTracker); - } - } else { - // we only need to track up to, and excluding, the first labeled statements - boolean foundAwait = false; - PlusCalStatementContainsAwaitVisitor awaitChecker = - new PlusCalStatementContainsAwaitVisitor(true); - for (PlusCalStatement statement : eitherCase) { - if (statement instanceof PlusCalLabeledStatements) { - break; - } - foundAwait = foundAwait || statement.accept(awaitChecker); - } - if (foundAwait) { - for (PlusCalStatement statement : eitherCase) { - if (statement instanceof PlusCalLabeledStatements) { - break; - } - statement.accept(writeTracker); - } - } - } - } - // make copies of local variables which are in scope and are written to - Map localVarNames = new HashMap<>(); - for (UID varUID : localVarWrites) { - if (builder.isInScope(varUID)) { - GoVariableName name = builder.findUID(varUID); - GoVariableName copyName = builder.varDecl(name.getName() + "Copy", name); - localVarNames.put(name, copyName); - } - } - // make copies of global variables which are written to - Map globalVarNames = new HashMap<>(); - for (UID varUID : registry.getVariableWritesInLockGroup(criticalSectionTracker.getCurrentLockGroup())) { - GoVariableName name = builder.findUID(varUID); - GoVariableName copyName = builder.varDecl(name.getName() + "Copy", name); - globalVarNames.put(name, copyName); - } - // generate labels - List labels = new ArrayList<>(); - for (int i = 0; i < cases.size(); i++) { - labels.add(builder.newLabel("case" + i)); - } - GoLabelName endEither = builder.newLabel("endEither"); - // start codegen - for (int i = 0; i < cases.size(); i++) { - List eitherCase = cases.get(i); - if (eitherCase.size() <= 0) { - continue; - } - GoLabelName labelName = labels.get(i); - builder.label(labelName); - Function oldAwaitAction; - CriticalSectionTracker tracker = criticalSectionTracker; - PlusCalStatementCodeGenVisitor caseVisitor = this; - if (i != 0) { - // we arrived here via a failure of an await condition - // restore the critical section back to when we first entered case 0 - criticalSectionTracker.restore(builder); - } - if (i != cases.size() - 1) { - int j = i + 1; - tracker = criticalSectionTracker.copy(); - caseVisitor = new PlusCalStatementCodeGenVisitor( - registry, typeMap, localStrategy, globalStrategy, processUID, builder, tracker, builder -> { - // restore variables - localVarNames.forEach(builder::assign); - globalVarNames.forEach(builder::assign); - return labels.get(j); - }); - oldAwaitAction = ignored -> null; - } else { - GoLabelName eitherLabel = tracker.getCurrentLabelName(); - if (eitherLabel == null) { - throw new InternalCompilerError(); - } - oldAwaitAction = awaitAction; - awaitAction = builder -> { - // restore variables - localVarNames.forEach(builder::assign); - globalVarNames.forEach(builder::assign); - return eitherLabel; - }; - } - int nextIndex = 0; - if (eitherCase.get(0) instanceof PlusCalLabeledStatements) { - // we need to special case the first labeled statements - eitherCase.get(0).accept(caseVisitor); - nextIndex = 1; - } else { - // we need to special case statements up to, and excluding, the first labeled statements - for (int k = 0; k < eitherCase.size(); k++, nextIndex = k) { - PlusCalStatement statement = eitherCase.get(k); - if (statement instanceof PlusCalLabeledStatements) { - break; - } - statement.accept(caseVisitor); - } - } - // codegen for the rest of the statements - caseVisitor.awaitAction = oldAwaitAction; - for (PlusCalStatement statement : eitherCase.subList(nextIndex, eitherCase.size())) { - statement.accept(caseVisitor); - } - tracker.end(builder); - if (i != cases.size() - 1) { - builder.goTo(endEither); - } - } - builder.label(endEither); - return null; - } - - @Override - public Void visit(PlusCalAssignment plusCalAssignment) throws RuntimeException { - List lhs = new ArrayList<>(); - List rhs = new ArrayList<>(); - List lhsWrites = new ArrayList<>(); - for (PlusCalAssignmentPair pair : plusCalAssignment.getPairs()) { - GlobalVariableStrategy.GlobalVariableWrite lhsWrite = pair.getLhs().accept( - new TLAExpressionAssignmentLHSCodeGenVisitor(builder, registry, typeMap, localStrategy, globalStrategy)); - lhsWrites.add(lhsWrite); - lhs.add(lhsWrite.getValueSink(builder)); - rhs.add(pair.getRhs().accept( - new TLAExpressionCodeGenVisitor(builder, registry, typeMap, localStrategy, globalStrategy))); - } - builder.assign(lhs, rhs); - for (GlobalVariableStrategy.GlobalVariableWrite lhsWrite : lhsWrites) { - lhsWrite.writeAfter(builder); - } - return null; - } - - @Override - public Void visit(PlusCalReturn plusCalReturn) throws RuntimeException { - builder.addStatement(new GoReturn(Collections.emptyList())); - return null; - } - - @Override - public Void visit(PlusCalSkip plusCalSkip) throws RuntimeException { - // nothing to do here - return null; - } - - @Override - public Void visit(PlusCalCall plusCalCall) throws RuntimeException { - List arguments = new ArrayList<>(); - List args = plusCalCall.getArguments(); - for (int i = 0; i < args.size(); i++) { - TLAExpression arg = args.get(i); - GoExpression e = arg.accept(new TLAExpressionCodeGenVisitor(builder, registry, typeMap, localStrategy, globalStrategy)); - arguments.add(builder.varDecl("arg" + (i + 1), e)); - } - // the critical section ends here because the procedure has to have a label on the first line of its body - criticalSectionTracker.end(builder); - builder.addStatement(new GoExpressionStatement(new GoCall( - new GoVariableName(plusCalCall.getTarget()), - arguments))); - return null; - } - - @Override - public Void visit(PlusCalMacroCall macroCall) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(PlusCalWith plusCalWith) throws RuntimeException { - for(PlusCalVariableDeclaration decl : plusCalWith.getVariables()) { - GoExpression value = decl.getValue().accept( - new TLAExpressionCodeGenVisitor(builder, registry, typeMap, localStrategy, globalStrategy)); - if (decl.isSet()) { - value = new GoIndexExpression(value, new GoIntLiteral(0)); - } - builder.linkUID(decl.getUID(), builder.varDecl(decl.getName().getId(), value)); - } - for (PlusCalStatement statement : plusCalWith.getBody()) { - statement.accept(this); - } - return null; - } - - @Override - public Void visit(PlusCalPrint plusCalPrint) throws RuntimeException { - builder.print(plusCalPrint.getValue().accept( - new TLAExpressionCodeGenVisitor(builder, registry, typeMap, localStrategy, globalStrategy))); - return null; - } - - @Override - public Void visit(PlusCalAssert plusCalAssert) throws RuntimeException { - TLAExpression cond = plusCalAssert.getCondition(); - try (GoIfBuilder ifBuilder = builder.ifStmt(CodeGenUtil.invertCondition( - builder, registry, typeMap, localStrategy, globalStrategy, cond))) { - try (GoBlockBuilder yes = ifBuilder.whenTrue()) { - String msg = cond.toString(); - - // since this is going to be in a string literal, we need to escape - // potential backslashes in the operator to avoid confusing Go - // there are any special characters in the string. - msg = msg.replace("\\", "\\\\"); - yes.addPanic(new GoStringLiteral(msg)); - } - } - return null; - } - - @Override - public Void visit(PlusCalAwait plusCalAwait) throws RuntimeException { - TLAExpression cond = plusCalAwait.getCondition(); - try (GoIfBuilder ifBuilder = builder.ifStmt(CodeGenUtil.invertCondition( - builder, registry, typeMap, localStrategy, globalStrategy, cond))) { - try (GoBlockBuilder yes = ifBuilder.whenTrue()) { - // fork out an execution path for aborting - CriticalSectionTracker tracker = criticalSectionTracker.copy(); - tracker.abort(yes, awaitAction.apply(yes)); - } - } - return null; - } - - @Override - public Void visit(PlusCalGoto plusCalGoto) throws RuntimeException { - // fork out an execution path for this goto - CriticalSectionTracker tracker = criticalSectionTracker.copy(); - // this critical section ends here - tracker.end(builder); - builder.goTo(new GoLabelName(plusCalGoto.getTarget())); - // continue with the previous critical section - return null; - } - - @Override - public Void visit(ModularPlusCalYield modularPlusCalYield) throws RuntimeException { - throw new Unreachable(); - } -} diff --git a/src/pgo/trans/passes/codegen/go/PlusCalStatementContainsAwaitVisitor.java b/src/pgo/trans/passes/codegen/go/PlusCalStatementContainsAwaitVisitor.java deleted file mode 100644 index 1e1448155..000000000 --- a/src/pgo/trans/passes/codegen/go/PlusCalStatementContainsAwaitVisitor.java +++ /dev/null @@ -1,97 +0,0 @@ -package pgo.trans.passes.codegen.go; - -import pgo.Unreachable; -import pgo.model.mpcal.ModularPlusCalYield; -import pgo.model.pcal.*; - -public class PlusCalStatementContainsAwaitVisitor extends PlusCalStatementVisitor { - private boolean foundLabeledStatements; - - public PlusCalStatementContainsAwaitVisitor() { - this(false); - } - - public PlusCalStatementContainsAwaitVisitor(boolean foundLabeledStatements) { - this.foundLabeledStatements = foundLabeledStatements; - } - - @Override - public Boolean visit(PlusCalLabeledStatements plusCalLabeledStatements) throws RuntimeException { - if (foundLabeledStatements) { - return false; - } - foundLabeledStatements = true; - return plusCalLabeledStatements.getStatements().stream().anyMatch(s -> s.accept(this)); - } - - @Override - public Boolean visit(PlusCalWhile while1) throws RuntimeException { - return while1.getBody().stream().anyMatch(s -> s.accept(this)); - } - - @Override - public Boolean visit(PlusCalIf if1) throws RuntimeException { - return if1.getYes().stream().anyMatch(s -> s.accept(this)) || - if1.getNo().stream().anyMatch(s -> s.accept(this)); - } - - @Override - public Boolean visit(PlusCalEither either) throws RuntimeException { - return false; - } - - @Override - public Boolean visit(PlusCalAssignment assignment) throws RuntimeException { - return false; - } - - @Override - public Boolean visit(PlusCalReturn return1) throws RuntimeException { - return false; - } - - @Override - public Boolean visit(PlusCalSkip plusCalSkip) throws RuntimeException { - return false; - } - - @Override - public Boolean visit(PlusCalCall call) throws RuntimeException { - return false; - } - - @Override - public Boolean visit(PlusCalMacroCall macroCall) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Boolean visit(PlusCalWith plusCalWith) throws RuntimeException { - return plusCalWith.getBody().stream().anyMatch(s -> s.accept(this)); - } - - @Override - public Boolean visit(PlusCalPrint print) throws RuntimeException { - return false; - } - - @Override - public Boolean visit(PlusCalAssert assert1) throws RuntimeException { - return false; - } - - @Override - public Boolean visit(PlusCalAwait await) throws RuntimeException { - return true; - } - - @Override - public Boolean visit(PlusCalGoto goto1) throws RuntimeException { - return false; - } - - @Override - public Boolean visit(ModularPlusCalYield modularPlusCalYield) throws RuntimeException { - return false; - } -} diff --git a/src/pgo/trans/passes/codegen/go/PlusCalStatementContainsLabelVisitor.java b/src/pgo/trans/passes/codegen/go/PlusCalStatementContainsLabelVisitor.java deleted file mode 100644 index 4f33e8828..000000000 --- a/src/pgo/trans/passes/codegen/go/PlusCalStatementContainsLabelVisitor.java +++ /dev/null @@ -1,111 +0,0 @@ -package pgo.trans.passes.codegen.go; - -import pgo.Unreachable; -import pgo.model.mpcal.ModularPlusCalYield; -import pgo.model.pcal.*; - -import java.util.List; - -public class PlusCalStatementContainsLabelVisitor extends PlusCalStatementVisitor { - @Override - public Boolean visit(PlusCalLabeledStatements plusCalLabeledStatements) throws RuntimeException { - return true; - } - - @Override - public Boolean visit(PlusCalWhile plusCalWhile) throws RuntimeException { - for(PlusCalStatement stmt : plusCalWhile.getBody()){ - if(stmt.accept(this)){ - return true; - } - } - return false; - } - - @Override - public Boolean visit(PlusCalIf plusCalIf) throws RuntimeException { - for(PlusCalStatement stmt : plusCalIf.getYes()){ - if(stmt.accept(this)){ - return true; - } - } - for(PlusCalStatement stmt : plusCalIf.getNo()){ - if(stmt.accept(this)){ - return true; - } - } - return false; - } - - @Override - public Boolean visit(PlusCalEither plusCalEither) throws RuntimeException { - for(List stmts : plusCalEither.getCases()){ - for(PlusCalStatement stmt : stmts){ - if(stmt.accept(this)){ - return true; - } - } - } - return false; - } - - @Override - public Boolean visit(PlusCalAssignment plusCalAssignment) throws RuntimeException { - return false; - } - - @Override - public Boolean visit(PlusCalReturn plusCalReturn) throws RuntimeException { - return false; - } - - @Override - public Boolean visit(PlusCalSkip plusCalSkip) throws RuntimeException { - return false; - } - - @Override - public Boolean visit(PlusCalCall plusCalCall) throws RuntimeException { - return false; - } - - @Override - public Boolean visit(PlusCalMacroCall macroCall) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Boolean visit(PlusCalWith plusCalWith) throws RuntimeException { - for(PlusCalStatement stmt : plusCalWith.getBody()){ - if(stmt.accept(this)){ - return true; - } - } - return false; - } - - @Override - public Boolean visit(PlusCalPrint plusCalPrint) throws RuntimeException { - return false; - } - - @Override - public Boolean visit(PlusCalAssert plusCalAssert) throws RuntimeException { - return false; - } - - @Override - public Boolean visit(PlusCalAwait plusCalAwait) throws RuntimeException { - return false; - } - - @Override - public Boolean visit(PlusCalGoto plusCalGoto) throws RuntimeException { - return false; - } - - @Override - public Boolean visit(ModularPlusCalYield modularPlusCalYield) throws RuntimeException { - return false; - } -} diff --git a/src/pgo/trans/passes/codegen/go/SingleThreadedProcessGlobalVariableStrategy.java b/src/pgo/trans/passes/codegen/go/SingleThreadedProcessGlobalVariableStrategy.java deleted file mode 100644 index 2d02c46a9..000000000 --- a/src/pgo/trans/passes/codegen/go/SingleThreadedProcessGlobalVariableStrategy.java +++ /dev/null @@ -1,66 +0,0 @@ -package pgo.trans.passes.codegen.go; - -import pgo.InternalCompilerError; -import pgo.model.golang.GoExpression; -import pgo.model.golang.GoLabelName; -import pgo.model.golang.GoStringLiteral; -import pgo.model.golang.GoVariableName; -import pgo.model.golang.builder.GoBlockBuilder; -import pgo.model.golang.builder.GoModuleBuilder; -import pgo.model.golang.type.GoType; -import pgo.model.pcal.PlusCalProcess; -import pgo.scope.UID; - -import java.util.Objects; - -public class SingleThreadedProcessGlobalVariableStrategy extends GlobalVariableStrategy { - @Override - public void initPostlude(GoModuleBuilder moduleBuilder, GoBlockBuilder initBuilder) { - // nothing to do - } - - @Override - public void processPrelude(GoBlockBuilder processBody, PlusCalProcess process, String processName, GoVariableName self, GoType selfType) { - throw new InternalCompilerError(); - } - - @Override - public void mainPrelude(GoBlockBuilder builder) { - // nothing to do - } - - @Override - public void startCriticalSection(GoBlockBuilder builder, UID processUID, int lockGroup, UID labelUID, GoLabelName labelName) { - // pass - } - - @Override - public void abortCriticalSection(GoBlockBuilder builder, UID processUID, int lockGroup, UID labelUID, GoLabelName labelName) { - builder.addPanic(new GoStringLiteral("Something went wrong")); - } - - @Override - public void endCriticalSection(GoBlockBuilder builder, UID processUID, int lockGroup, UID labelUID, GoLabelName labelName) { - // pass - } - - @Override - public GoExpression readGlobalVariable(GoBlockBuilder builder, UID uid) { - return builder.findUID(uid); - } - - @Override - public GlobalVariableWrite writeGlobalVariable(UID uid) { - return new GlobalVariableWrite() { - @Override - public GoExpression getValueSink(GoBlockBuilder builder) { - return builder.findUID(uid); - } - - @Override - public void writeAfter(GoBlockBuilder builder) { - // pass - } - }; - } -} diff --git a/src/pgo/trans/passes/codegen/go/SnapshottingLocalVariableStrategy.java b/src/pgo/trans/passes/codegen/go/SnapshottingLocalVariableStrategy.java deleted file mode 100644 index a80b63a35..000000000 --- a/src/pgo/trans/passes/codegen/go/SnapshottingLocalVariableStrategy.java +++ /dev/null @@ -1,78 +0,0 @@ -package pgo.trans.passes.codegen.go; - -import pgo.model.golang.GoExpression; -import pgo.model.golang.GoVariableName; -import pgo.model.golang.builder.GoBlockBuilder; -import pgo.model.golang.type.GoType; -import pgo.model.mpcal.ModularPlusCalArchetype; -import pgo.model.type.Type; -import pgo.scope.UID; -import pgo.trans.intermediate.DefinitionRegistry; -import pgo.trans.passes.codegen.go.GlobalVariableStrategy.GlobalVariableWrite; - -import java.util.HashMap; -import java.util.Map; - -public class SnapshottingLocalVariableStrategy extends LocalVariableStrategy { - private final DefinitionRegistry registry; - private final Map typeMap; - private ModularPlusCalArchetype archetype; - private final Map localCopies; - - public SnapshottingLocalVariableStrategy(DefinitionRegistry registry, Map typeMap) { - this.registry = registry; - this.typeMap = typeMap; - this.localCopies = new HashMap<>(); - } - - public void initArchetype(GoBlockBuilder builder, ModularPlusCalArchetype archetype) { - this.archetype = archetype; - - localCopies.clear(); - archetype.getVariables().forEach(var -> { - GoType localType = typeMap.get(var.getUID()).accept(new TypeConversionVisitor()); - localCopies.put(var.getUID(), builder.varDecl(var.getName().getId() + "Copy", localType)); - }); - } - - public void actionPrelude(GoBlockBuilder builder, UID labelUID) { - // Create a copy of each local variable used in this action - registry.getLocalsInLabel(labelUID).forEach(local -> { - GoVariableName goLocal = builder.findUID(local); - GoType localType = typeMap.get(local).accept(new TypeConversionVisitor()); - - GoVariableName copy = localType.accept(new CopyVisitor(builder, goLocal)); - GoVariableName dest = localCopies.get(local); - - builder.assign(dest, copy); - }); - } - - public GoExpression readLocalVariable(GoBlockBuilder builder, UID local) { - return localCopies.getOrDefault(local, builder.findUID(local)); - } - - public GlobalVariableWrite writeLocalVariable(GoBlockBuilder builder, UID local) { - GoVariableName copy = localCopies.get(local); - - return new GlobalVariableWrite() { - @Override - public GoExpression getValueSink(GoBlockBuilder builder) { - return copy; - } - @Override - public void writeAfter(GoBlockBuilder builder) { - // nothing to do - } - }; - } - - public void actionPostlude(GoBlockBuilder builder, UID labelUID) { - // assign the original locals to their potentially modified copies - registry.getLocalsInLabel(labelUID).forEach(local -> { - GoVariableName goLocal = builder.findUID(local); - builder.assign(goLocal, localCopies.get(local)); - }); - } - -} diff --git a/src/pgo/trans/passes/codegen/go/StateServerGlobalVariableStrategy.java b/src/pgo/trans/passes/codegen/go/StateServerGlobalVariableStrategy.java deleted file mode 100644 index 9e1d13716..000000000 --- a/src/pgo/trans/passes/codegen/go/StateServerGlobalVariableStrategy.java +++ /dev/null @@ -1,284 +0,0 @@ -package pgo.trans.passes.codegen.go; - -import pgo.PGoNetOptions; -import pgo.Unreachable; -import pgo.model.golang.*; -import pgo.model.golang.builder.GoBlockBuilder; -import pgo.model.golang.builder.GoModuleBuilder; -import pgo.model.golang.builder.GoSwitchBuilder; -import pgo.model.golang.type.GoType; -import pgo.model.golang.type.GoTypeName; -import pgo.model.mpcal.ModularPlusCalBlock; -import pgo.model.pcal.PlusCalMultiProcess; -import pgo.model.pcal.PlusCalProcess; -import pgo.model.type.Type; -import pgo.scope.UID; -import pgo.trans.intermediate.DefinitionRegistry; - -import java.util.*; -import java.util.stream.Collectors; - -public class StateServerGlobalVariableStrategy extends GlobalVariableStrategy { - private final DefinitionRegistry registry; - private final Map typeMap; - private final PGoNetOptions.StateOptions stateOptions; - private final ModularPlusCalBlock modularPlusCalBlock; - private final GoCommandLineArgumentParser commandLineArgumentParser; - private final UID processNameUID; - private final UID processArgumentUID; - private final UID errUID; - private final UID globalStateUID; - private final UID refsUID; - - public StateServerGlobalVariableStrategy(DefinitionRegistry registry, Map typeMap, - PGoNetOptions.StateOptions stateOptions, - ModularPlusCalBlock modularPlusCalBlock) { - this.registry = registry; - this.typeMap = typeMap; - this.stateOptions = stateOptions; - this.modularPlusCalBlock = modularPlusCalBlock; - this.commandLineArgumentParser = new GoCommandLineArgumentParser(); - this.processNameUID = new UID(); - this.processArgumentUID = new UID(); - this.errUID = new UID(); - this.globalStateUID = new UID(); - this.refsUID = new UID(); - } - - static void generateProcessSwitch(Map typeMap, ModularPlusCalBlock modularPlusCalBlock, - GoBlockBuilder builder, GoVariableName processName, - GoVariableName processArgument) { - try (GoSwitchBuilder switchBuilder = builder.switchStmt(processName)) { - for (PlusCalProcess process : ((PlusCalMultiProcess) modularPlusCalBlock.getProcesses()).getProcesses()) { - String name = process.getName().getName().getId(); - GoType type = typeMap.get(process.getName().getUID()).accept(new TypeConversionVisitor()); - try (GoBlockBuilder caseBody = switchBuilder.addCase(new GoStringLiteral(name))) { - if (type.equals(GoBuiltins.Int)) { - builder.addImport("strconv"); - List names = caseBody.varDecl( - Arrays.asList("i", "err"), - new GoCall( - new GoSelectorExpression(new GoVariableName("strconv"), "Atoi"), - Collections.singletonList(processArgument))); - GoVariableName i = names.get(0); - GoVariableName err = names.get(1); - try (GoIfBuilder ifBuilder = caseBody.ifStmt(new GoBinop(GoBinop.Operation.NEQ, err, GoBuiltins.Nil))) { - try (GoBlockBuilder yes = ifBuilder.whenTrue()) { - yes.addPanic(new GoBinop( - GoBinop.Operation.PLUS, - new GoStringLiteral("Process " + name + - " requires an integer argument; err = "), - new GoCall(new GoSelectorExpression(err, "Error"), Collections.emptyList()))); - } - } - caseBody.addStatement(new GoCall(new GoVariableName(name), Collections.singletonList(i))); - } else if (type.equals(GoBuiltins.String)) { - caseBody.addStatement(new GoCall( - new GoVariableName(name), - Collections.singletonList(processArgument))); - } else { - throw new Unreachable(); - } - } - } - try (GoBlockBuilder defaultCaseBody = switchBuilder.defaultCase()) { - defaultCaseBody.addPanic(new GoBinop( - GoBinop.Operation.PLUS, - new GoStringLiteral("Unknown process "), - processName)); - } - } - } - - private void releaseRefs(GoBlockBuilder builder) { - GoVariableName refs = findVariable(refsUID); - GoVariableName err = findVariable(errUID); - builder.assign(err, new GoCall( - new GoSelectorExpression(findVariable(globalStateUID), "Release"), - Collections.singletonList(refs))); - try (GoIfBuilder ifBuilder = builder.ifStmt(new GoBinop(GoBinop.Operation.NEQ, err, GoBuiltins.Nil))) { - try (GoBlockBuilder yes = ifBuilder.whenTrue()) { - yes.addPanic(err); - } - } - } - - @Override - public void initPostlude(GoModuleBuilder moduleBuilder, GoBlockBuilder initBuilder) { - GoVariableName processName = moduleBuilder.defineGlobal(processNameUID, "processName", GoBuiltins.String); - addVariable(processNameUID, processName); - GoVariableName processArgument = moduleBuilder.defineGlobal(processArgumentUID, "processArgument", GoBuiltins.String); - addVariable(processArgumentUID, processArgument); - commandLineArgumentParser.addPositionalArgument("processPlusArgument", "processName(processArgument)"); - commandLineArgumentParser.addPositionalArgument("ipPort", "ip:port"); - List commandLineArguments = commandLineArgumentParser.generateArgumentParsingCode(initBuilder); - GoVariableName processPlusArgument = commandLineArguments.get(0); - GoVariableName ipPort = commandLineArguments.get(1); - CodeGenUtil.generateArgumentParsing(initBuilder, processPlusArgument, processName, processArgument); - - moduleBuilder.addImport("pgo/distsys"); - GoVariableName err = moduleBuilder.defineGlobal(errUID, "err", GoBuiltins.Error); - addVariable(errUID, err); - GoVariableName globalState = moduleBuilder.defineGlobal( - globalStateUID, "globalState", new GoPtrType(new GoTypeName("distsys.StateServer"))); - addVariable(globalStateUID, globalState); - GoVariableName peers = initBuilder.varDecl( - "peers", - new GoSliceLiteral(GoBuiltins.String, stateOptions.peers.stream() - .map(GoStringLiteral::new) - .collect(Collectors.toList()))); - GoVariableName coordinator = initBuilder.varDecl("coordinator", new GoIndexExpression(peers, new GoIntLiteral(0))); - initBuilder.assign( - Arrays.asList(globalState, err), - new GoCall( - new GoSelectorExpression(new GoVariableName("distsys"), "NewStateServer"), - Arrays.asList( - processPlusArgument, - peers, - ipPort, - coordinator, - new GoMapLiteral( - GoBuiltins.String, - GoBuiltins.Interface, - new HashMap() {{ - for (UID varUID : registry.protectedGlobalVariables()) { - GoVariableName variableName = initBuilder.findUID(varUID); - put(new GoStringLiteral(variableName.getName()), variableName); - } - }}), - new GoCall( - new GoSelectorExpression(new GoVariableName("distsys"), "NewRandomMigrate"), - Collections.singletonList(ipPort))))); - try (GoIfBuilder ifBuilder = initBuilder.ifStmt(new GoBinop(GoBinop.Operation.NEQ, err, GoBuiltins.Nil))) { - try (GoBlockBuilder yes = ifBuilder.whenTrue()) { - yes.addPanic(err); - } - } - GoVariableName refs = moduleBuilder.defineGlobal( - refsUID, "refs", new GoTypeName("distsys.VarReferences")); - addVariable(refsUID, refs); - } - - @Override - public void processPrelude(GoBlockBuilder processBody, PlusCalProcess process, String processName, GoVariableName self, GoType selfType) { - // nothing to do - } - - @Override - public void mainPrelude(GoBlockBuilder builder) { - GoVariableName err = findVariable(errUID); - builder.assign( - err, - new GoCall(new GoSelectorExpression(findVariable(globalStateUID), "WaitPeers"), Collections.emptyList())); - try (GoIfBuilder ifBuilder = builder.ifStmt(new GoBinop(GoBinop.Operation.NEQ, err, GoBuiltins.Nil))) { - try (GoBlockBuilder yes = ifBuilder.whenTrue()) { - yes.addPanic(err); - } - } - generateProcessSwitch( - typeMap, modularPlusCalBlock, builder, findVariable(processNameUID), findVariable(processArgumentUID)); - builder.assign( - err, - new GoCall(new GoSelectorExpression(findVariable(globalStateUID), "WaitPeers"), Collections.emptyList())); - try (GoIfBuilder ifBuilder = builder.ifStmt(new GoBinop(GoBinop.Operation.NEQ, err, GoBuiltins.Nil))) { - try (GoBlockBuilder yes = ifBuilder.whenTrue()) { - yes.addPanic(err); - } - } - } - - @Override - public void startCriticalSection(GoBlockBuilder builder, UID processUID, int lockGroup, UID labelUID, GoLabelName labelName) { - Set readSet = new HashSet<>(registry.getVariableReadsInLockGroup(lockGroup)); - Set writeSet = registry.getVariableWritesInLockGroup(lockGroup); - readSet.removeAll(writeSet); - ArrayList readVariableUIDs = new ArrayList<>(readSet); - List readVariableNames = readVariableUIDs.stream().map(builder::findUID).collect(Collectors.toList()); - List readVariableNameStrings = readVariableNames.stream() - .map(v -> new GoStringLiteral(v.getName())) - .collect(Collectors.toList()); - ArrayList writeVariableUIDs = new ArrayList<>(writeSet); - List writeVariableNames = writeVariableUIDs.stream().map(builder::findUID).collect(Collectors.toList()); - List writeVariableNameStrings = writeVariableNames.stream() - .map(v -> new GoStringLiteral(v.getName())) - .collect(Collectors.toList()); - GoVariableName refs = findVariable(refsUID); - GoVariableName err = findVariable(errUID); - builder.assign( - Arrays.asList(refs, err), - new GoCall( - new GoSelectorExpression(findVariable(globalStateUID), "Acquire"), - Collections.singletonList(new GoUnary( - GoUnary.Operation.ADDR, - new GoStructLiteral( - new GoTypeName("distsys.BorrowSpec"), - Arrays.asList( - new GoStructLiteralField( - "ReadNames", - new GoSliceLiteral(GoBuiltins.String, readVariableNameStrings)), - new GoStructLiteralField( - "WriteNames", - new GoSliceLiteral(GoBuiltins.String, writeVariableNameStrings)))))))); - try (GoIfBuilder ifBuilder = builder.ifStmt(new GoBinop(GoBinop.Operation.NEQ, err, GoBuiltins.Nil))) { - try (GoBlockBuilder yes = ifBuilder.whenTrue()) { - yes.addPanic(err); - } - } - // pull all values out of the map and into globals - for (int i = 0; i < writeVariableNames.size(); i++) { - builder.assign( - writeVariableNames.get(i), - new GoTypeAssertion( - new GoCall( - new GoSelectorExpression(refs, "Get"), - Collections.singletonList(new GoStringLiteral(writeVariableNames.get(i).getName()))), - registry.getGlobalVariableType(writeVariableUIDs.get(i)))); - } - for (int i = 0; i < readVariableNames.size(); i++) { - builder.assign( - readVariableNames.get(i), - new GoTypeAssertion( - new GoCall( - new GoSelectorExpression(refs, "Get"), - Collections.singletonList(new GoStringLiteral(readVariableNames.get(i).getName()))), - registry.getGlobalVariableType(readVariableUIDs.get(i)))); - } - } - - @Override - public void abortCriticalSection(GoBlockBuilder builder, UID processUID, int lockGroup, UID labelUID, GoLabelName labelName) { - releaseRefs(builder); - } - - @Override - public void endCriticalSection(GoBlockBuilder builder, UID processUID, int lockGroup, UID labelUID, GoLabelName labelName) { - GoVariableName refs = findVariable(refsUID); - for (UID varUID : registry.getVariableWritesInLockGroup(lockGroup)) { - GoVariableName name = builder.findUID(varUID); - builder.addStatement(new GoCall( - new GoSelectorExpression(refs, "Set"), - Arrays.asList(new GoStringLiteral(name.getName()), name))); - } - releaseRefs(builder); - } - - @Override - public GoExpression readGlobalVariable(GoBlockBuilder builder, UID uid) { - return builder.findUID(uid); - } - - @Override - public GlobalVariableWrite writeGlobalVariable(UID uid) { - return new GlobalVariableWrite() { - @Override - public GoExpression getValueSink(GoBlockBuilder builder) { - return builder.findUID(uid); - } - - @Override - public void writeAfter(GoBlockBuilder builder) { - - } - }; - } -} diff --git a/src/pgo/trans/passes/codegen/go/TLAExpressionAssignmentLHSCodeGenVisitor.java b/src/pgo/trans/passes/codegen/go/TLAExpressionAssignmentLHSCodeGenVisitor.java deleted file mode 100644 index c53a31a40..000000000 --- a/src/pgo/trans/passes/codegen/go/TLAExpressionAssignmentLHSCodeGenVisitor.java +++ /dev/null @@ -1,231 +0,0 @@ -package pgo.trans.passes.codegen.go; - -import pgo.TODO; -import pgo.Unreachable; -import pgo.model.golang.GoExpression; -import pgo.model.golang.GoVariableName; -import pgo.model.golang.builder.GoBlockBuilder; -import pgo.model.tla.*; -import pgo.model.type.ArchetypeResourceCollectionType; -import pgo.model.type.ArchetypeResourceType; -import pgo.model.type.Type; -import pgo.scope.UID; -import pgo.trans.intermediate.DefinitionRegistry; -import pgo.trans.passes.codegen.go.GlobalVariableStrategy.GlobalVariableWrite; - -import java.util.Map; - -public class TLAExpressionAssignmentLHSCodeGenVisitor extends TLAExpressionVisitor { - private final GoBlockBuilder builder; - private final DefinitionRegistry registry; - private final Map typeMap; - private final LocalVariableStrategy localStrategy; - private final GlobalVariableStrategy globalStrategy; - - public TLAExpressionAssignmentLHSCodeGenVisitor(GoBlockBuilder builder, DefinitionRegistry registry, Map typeMap, - LocalVariableStrategy localStrategy, GlobalVariableStrategy globalStrategy) { - this.builder = builder; - this.registry = registry; - this.typeMap = typeMap; - this.localStrategy = localStrategy; - this.globalStrategy = globalStrategy; - } - - @Override - public GlobalVariableWrite visit(TLAGeneralIdentifier tlaGeneralIdentifier) throws RuntimeException { - UID ref = registry.followReference(tlaGeneralIdentifier.getUID()); - - if (registry.isGlobalVariable(ref)) { - return globalStrategy.writeGlobalVariable(ref); - } else if (typeMap.get(ref) instanceof ArchetypeResourceType){ - return globalStrategy.writeArchetypeResource(builder, tlaGeneralIdentifier); - } else if (registry.isLocalVariable(ref)) { - return localStrategy.writeLocalVariable(builder, ref); - } else if (registry.isConstant(ref)) { - GoVariableName name = builder.findUID(ref); - return new GlobalVariableWrite() { - @Override - public GoExpression getValueSink(GoBlockBuilder builder) { - return name; - } - @Override - public void writeAfter(GoBlockBuilder builder) { - // pass - } - }; - } else { - throw new Unreachable(); - } - } - - @Override - public GlobalVariableWrite visit(TLAFunctionCall tlaFunctionCall) throws RuntimeException { - if (typeMap.get(tlaFunctionCall.getFunction().getUID()) instanceof ArchetypeResourceCollectionType) { - return globalStrategy.writeArchetypeResource(builder, tlaFunctionCall); - } - - GoExpression expression = tlaFunctionCall - .accept(new TLAExpressionCodeGenVisitor(builder, registry, typeMap, localStrategy, globalStrategy)); - return new GlobalVariableWrite() { - @Override - public GoExpression getValueSink(GoBlockBuilder builder) { - return expression; - } - - @Override - public void writeAfter(GoBlockBuilder builder) { - // nothing to do - } - }; - } - - @Override - public GlobalVariableWrite visit(TLABinOp tlaBinOp) throws RuntimeException { - throw new TODO(); - } - - @Override - public GlobalVariableWrite visit(TLABool tlaBool) throws RuntimeException { - throw new TODO(); - } - - @Override - public GlobalVariableWrite visit(TLACase tlaCase) throws RuntimeException { - throw new TODO(); - } - - @Override - public GlobalVariableWrite visit(TLADot tlaDot) throws RuntimeException { - throw new TODO(); - } - - @Override - public GlobalVariableWrite visit(TLAExistential tlaExistential) throws RuntimeException { - throw new TODO(); - } - - @Override - public GlobalVariableWrite visit(TLAFunction tlaFunction) throws RuntimeException { - throw new TODO(); - } - - @Override - public GlobalVariableWrite visit(TLAFunctionSet tlaFunctionSet) throws RuntimeException { - throw new TODO(); - } - - @Override - public GlobalVariableWrite visit(TLAFunctionSubstitution tlaFunctionSubstitution) throws RuntimeException { - throw new TODO(); - } - - @Override - public GlobalVariableWrite visit(TLAIf tlaIf) throws RuntimeException { - throw new TODO(); - } - - @Override - public GlobalVariableWrite visit(TLALet tlaLet) throws RuntimeException { - throw new TODO(); - } - - @Override - public GlobalVariableWrite visit(TLATuple tlaTuple) throws RuntimeException { - throw new TODO(); - } - - @Override - public GlobalVariableWrite visit(TLAMaybeAction tlaMaybeAction) throws RuntimeException { - throw new TODO(); - } - - @Override - public GlobalVariableWrite visit(TLANumber tlaNumber) throws RuntimeException { - throw new TODO(); - } - - @Override - public GlobalVariableWrite visit(TLAOperatorCall tlaOperatorCall) throws RuntimeException { - throw new TODO(); - } - - @Override - public GlobalVariableWrite visit(TLAQuantifiedExistential tlaQuantifiedExistential) throws RuntimeException { - throw new TODO(); - } - - @Override - public GlobalVariableWrite visit(TLAQuantifiedUniversal tlaQuantifiedUniversal) throws RuntimeException { - throw new TODO(); - } - - @Override - public GlobalVariableWrite visit(TLARecordConstructor tlaRecordConstructor) throws RuntimeException { - throw new TODO(); - } - - @Override - public GlobalVariableWrite visit(TLARecordSet tlaRecordSet) throws RuntimeException { - throw new TODO(); - } - - @Override - public GlobalVariableWrite visit(TLARequiredAction tlaRequiredAction) throws RuntimeException { - throw new TODO(); - } - - @Override - public GlobalVariableWrite visit(TLASetConstructor tlaSetConstructor) throws RuntimeException { - throw new TODO(); - } - - @Override - public GlobalVariableWrite visit(TLASetComprehension tlaSetComprehension) throws RuntimeException { - throw new TODO(); - } - - @Override - public GlobalVariableWrite visit(TLASetRefinement tlaSetRefinement) throws RuntimeException { - throw new TODO(); - } - - @Override - public GlobalVariableWrite visit(TLAString tlaString) throws RuntimeException { - throw new TODO(); - } - - @Override - public GlobalVariableWrite visit(TLAUnary tlaUnary) throws RuntimeException { - throw new TODO(); - } - - @Override - public GlobalVariableWrite visit(TLAUniversal tlaUniversal) throws RuntimeException { - throw new TODO(); - } - - @Override - public GlobalVariableWrite visit(PlusCalDefaultInitValue plusCalDefaultInitValue) throws RuntimeException { - throw new TODO(); - } - - @Override - public GlobalVariableWrite visit(TLAFairness fairness) throws RuntimeException{ - throw new TODO(); - } - - @Override - public GlobalVariableWrite visit(TLASpecialVariableVariable tlaSpecialVariableVariable) throws RuntimeException { - throw new TODO(); - } - - @Override - public GlobalVariableWrite visit(TLASpecialVariableValue tlaSpecialVariableValue) throws RuntimeException { - throw new TODO(); - } - - @Override - public GlobalVariableWrite visit(TLARef tlaRef) throws RuntimeException { - throw new TODO(); - } -} diff --git a/src/pgo/trans/passes/codegen/go/TLAExpressionCodeGenVisitor.java b/src/pgo/trans/passes/codegen/go/TLAExpressionCodeGenVisitor.java deleted file mode 100644 index 4879d7d04..000000000 --- a/src/pgo/trans/passes/codegen/go/TLAExpressionCodeGenVisitor.java +++ /dev/null @@ -1,560 +0,0 @@ -package pgo.trans.passes.codegen.go; - -import pgo.InternalCompilerError; -import pgo.TODO; -import pgo.model.golang.*; -import pgo.model.golang.builder.GoAnonymousFunctionBuilder; -import pgo.model.golang.builder.GoBlockBuilder; -import pgo.model.golang.builder.GoForRangeBuilder; -import pgo.model.golang.type.GoSliceType; -import pgo.model.golang.type.GoStructType; -import pgo.model.golang.type.GoType; -import pgo.model.golang.type.GoTypeName; -import pgo.model.tla.*; -import pgo.model.type.*; -import pgo.scope.UID; -import pgo.trans.intermediate.*; - -import java.util.*; -import java.util.function.Consumer; -import java.util.stream.Collectors; - -public class TLAExpressionCodeGenVisitor extends TLAExpressionVisitor { - private final GoBlockBuilder builder; - private final DefinitionRegistry registry; - private final Map typeMap; - private final LocalVariableStrategy localStrategy; - private final GlobalVariableStrategy globalStrategy; - - public TLAExpressionCodeGenVisitor(GoBlockBuilder builder, DefinitionRegistry registry, Map typeMap, - LocalVariableStrategy localStrategy, GlobalVariableStrategy globalStrategy) { - this.builder = builder; - this.registry = registry; - this.typeMap = typeMap; - this.localStrategy = localStrategy; - this.globalStrategy = globalStrategy; - } - - private List evaluateQuantifierBoundSets(List bounds) { - List sets = new ArrayList<>(); - for(TLAQuantifierBound qb : bounds) { - sets.add(qb.getSet().accept(this)); - } - return sets; - } - - private static GoType getFunctionKeyType(GoType fnType) { - GoType keyValuePairType = ((GoSliceType)fnType).getElementType(); - return ((GoStructType)keyValuePairType).getFields().get(0).getType(); - } - - private void unfoldQuantifierBounds(List bounds, Consumer action) { - unfoldQuantifierBounds(bounds, evaluateQuantifierBoundSets(bounds), action); - } - - private void unfoldQuantifierBounds(List bounds, List evaluatedSets, Consumer action) { - GoBlockBuilder currentBuilder = builder; - List accumulatedBuilders = new ArrayList<>(); - for (int i = 0; i < bounds.size(); ++i) { - GoExpression set = evaluatedSets.get(i); - TLAQuantifierBound bound = bounds.get(i); - GoForRangeBuilder forRangeBuilder = currentBuilder.forRange(set); - - if (bound.getType() == TLAQuantifierBound.Type$.MODULE$.tuple()) { - GoVariableName v = forRangeBuilder.initVariables(Arrays.asList("_", "v")).get(1); - currentBuilder = forRangeBuilder.getBlockBuilder(); - - // useful for some internal codegen, not needed by user code - currentBuilder.linkUID(bound.getUID(), v); - - List ids = bound.getIds(); - for(int j = 0; j < ids.size(); ++j) { - GoVariableName name = currentBuilder.varDecl(ids.get(j).getId(), new GoIndexExpression(v, new GoIntLiteral(j))); - currentBuilder.linkUID(ids.get(j).getUID(), name); - } - } else { - if (bound.getIds().size() != 1) { - throw new TODO(); - } - - TLAIdentifier id = bound.getIds().get(0); - GoVariableName name = forRangeBuilder.initVariables(Arrays.asList("_", id.getId())).get(1); - currentBuilder.linkUID(id.getUID(), name); - // useful for some internal codegen, not needed by user code - currentBuilder.linkUID(bound.getUID(), name); - - currentBuilder = forRangeBuilder.getBlockBuilder(); - } - accumulatedBuilders.add(currentBuilder); - } - action.accept(currentBuilder); - for (int i = accumulatedBuilders.size() - 1; i >= 0; i--) { - accumulatedBuilders.get(i).close(); - } - } - - @Override - public GoExpression visit(TLAFunctionCall tlaFunctionCall) throws RuntimeException { - if (typeMap.get(tlaFunctionCall.getFunction().getUID()) instanceof ArchetypeResourceCollectionType) { - return globalStrategy.readArchetypeResource(builder, tlaFunctionCall); - } - - Type type = typeMap.get(tlaFunctionCall.getFunction().getUID()); - if (type instanceof MapType) { - builder.addImport("sort"); - GoExpression function = tlaFunctionCall.getFunction().accept(this); - List params = new ArrayList<>(); - for(TLAExpression param : tlaFunctionCall.getParams()) { - params.add(param.accept(this)); - } - - GoType keyType = getFunctionKeyType(type.accept(new TypeConversionVisitor())); - GoVariableName key; - if (tlaFunctionCall.getParams().size() == 1) { - key = builder.varDecl("key", params.get(0)); - } else{ - if (keyType instanceof GoSliceType) { - GoType elementType = ((GoSliceType)keyType).getElementType(); - key = builder.varDecl("key", new GoSliceLiteral(elementType, params)); - } else if (keyType instanceof GoStructType) { - List fields = new ArrayList<>(); - for(GoExpression param : params) { - fields.add(new GoStructLiteralField(null, param)); - } - key = builder.varDecl("key", new GoStructLiteral(keyType, fields)); - } else { - throw new InternalCompilerError(); - } - } - - GoAnonymousFunctionBuilder comparatorBuilder = builder.anonymousFunction(); - GoVariableName i = comparatorBuilder.addArgument("i", GoBuiltins.Int); - comparatorBuilder.addReturn(GoBuiltins.Bool); - try (GoBlockBuilder comparatorBody = comparatorBuilder.getBlockBuilder()) { - comparatorBody.addStatement( - new GoReturn(Collections.singletonList( - new GoUnary( - GoUnary.Operation.NOT, - keyType.accept(new LessThanCodeGenVisitor( - comparatorBody, - new GoSelectorExpression(new GoIndexExpression(function, i), "key"), - key)))))); - } - GoVariableName index = builder.varDecl("index", new GoCall( - new GoSelectorExpression(new GoVariableName("sort"), "Search"), - Arrays.asList( - new GoCall(new GoVariableName("len"), Collections.singletonList(function)), - comparatorBuilder.getFunction()))); - return new GoSelectorExpression(new GoIndexExpression(function, index), "value"); - } else if (type instanceof SliceType) { - if (tlaFunctionCall.getParams().size() != 1) { - throw new InternalCompilerError(); // slices fundamentally cannot be indexed by multiple parameters - } - return new GoIndexExpression( - tlaFunctionCall.getFunction().accept(this), - new GoBinop( - GoBinop.Operation.MINUS, - tlaFunctionCall.getParams().get(0).accept(this), - new GoIntLiteral(1))); - } else{ - throw new InternalCompilerError(); - } - } - - @Override - public GoExpression visit(TLABinOp tlaBinOp) throws RuntimeException { - UID ref = registry.followReference(tlaBinOp.getUID()); - OperatorAccessor op = registry.findOperator(ref); - return op.generateGo( - builder, tlaBinOp, registry, - Arrays.asList( - tlaBinOp.getLHS(), - tlaBinOp.getRHS()), - typeMap, - localStrategy, - globalStrategy); - } - - @Override - public GoExpression visit(TLABool tlaBool) throws RuntimeException { - return tlaBool.getValue() ? GoBuiltins.True : GoBuiltins.False; - } - - @Override - public GoExpression visit(TLACase tlaCase) throws RuntimeException { - UID uid = tlaCase.getArms().get(0).getResult().getUID(); - GoVariableName result = builder.varDecl("result", typeMap.get(uid).accept(new TypeConversionVisitor())); - GoLabelName matched = builder.newLabel("matched"); - - for (TLACaseArm caseArm : tlaCase.getArms()) { - try (GoIfBuilder ifBuilder = builder.ifStmt(caseArm.getCondition().accept(this))) { - try (GoBlockBuilder yes = ifBuilder.whenTrue()) { - yes.assign(result, caseArm.getResult().accept(this)); - yes.goTo(matched); - } - } - } - - if (tlaCase.getOther() == null) { - builder.addPanic(new GoStringLiteral("No matching case!")); - } else { - builder.assign(result, tlaCase.getOther().accept(this)); - } - - builder.label(matched); - - return result; - } - - @Override - public GoExpression visit(TLADot tlaDot) throws RuntimeException { - Type expressionType = typeMap.get(tlaDot.getExpression().getUID()); - if (!(expressionType instanceof RecordType)) { - throw new TODO(); - } - - RecordType mapType = (RecordType) expressionType; - Type fieldType; - - Optional field = mapType - .getFields() - .stream() - .filter(f -> f.getName().equals(tlaDot.getField())) - .findFirst(); - - if (field.isPresent()) { - fieldType = field.get().getType(); - } else { - throw new InternalCompilerError(); - } - - GoType castType = fieldType.accept(new TypeConversionVisitor()); - GoExpression mapGet = new GoIndexExpression( - tlaDot.getExpression().accept(this), - new GoStringLiteral(tlaDot.getField()) - ); - - if (castType.equals(GoBuiltins.Interface)) { - return mapGet; - } else { - return new GoTypeCast(new GoTypeName(castType.toString()), mapGet); - } - } - - @Override - public GoExpression visit(TLAExistential tlaExistential) throws RuntimeException { - throw new TODO(); - } - - @Override - public GoExpression visit(TLAFunction tlaFunction) throws RuntimeException { - GoType mapType = typeMap.get(tlaFunction.getUID()).accept(new TypeConversionVisitor()); - GoExpression capacity = null; - List args = tlaFunction.getArguments(); - List domains = evaluateQuantifierBoundSets(args); - for(int argPos = 0; argPos < args.size(); ++argPos) { - GoExpression domain = domains.get(argPos); - GoExpression currentTerm = new GoCall(new GoVariableName("len"), Collections.singletonList(domain)); - if (capacity == null) { - capacity = currentTerm; - } else { - capacity = new GoBinop(GoBinop.Operation.TIMES, capacity, currentTerm); - } - } - GoVariableName function = builder.varDecl("function", new GoMakeExpression(mapType, new GoIntLiteral(0), capacity)); - unfoldQuantifierBounds(tlaFunction.getArguments(), domains, innerBuilder -> { - GoType keyValuePairType = ((GoSliceType)mapType).getElementType(); - GoExpression key; - if (args.size() == 1) { - key = innerBuilder.findUID(args.get(0).getUID()); - } else{ - GoType keyType = ((GoStructType)keyValuePairType).getFields().get(0).getType(); - List keyFields = new ArrayList<>(); - for(TLAQuantifierBound qb : args) { - keyFields.add(new GoStructLiteralField(null, innerBuilder.findUID(qb.getUID()))); - } - key = new GoStructLiteral(keyType, keyFields); - } - GoExpression value = tlaFunction.getBody().accept( - new TLAExpressionCodeGenVisitor(innerBuilder, registry, typeMap, localStrategy, globalStrategy)); - GoExpression keyValuePair = new GoStructLiteral(keyValuePairType, Arrays.asList( - new GoStructLiteralField("key", key), - new GoStructLiteralField("value", value) - )); - innerBuilder.assign(function, new GoCall(new GoVariableName("append"), Arrays.asList(function, keyValuePair))); - }); - return function; - } - - @Override - public GoExpression visit(TLAFunctionSet tlaFunctionSet) throws RuntimeException { - throw new TODO(); - } - - @Override - public GoExpression visit(TLAFunctionSubstitution tlaFunctionSubstitution) throws RuntimeException { - throw new TODO(); - } - - @Override - public GoExpression visit(TLAIf tlaIf) throws RuntimeException { - GoVariableName result = builder.varDecl("result", typeMap.get(tlaIf.getTval().getUID()).accept(new TypeConversionVisitor())); - try (GoIfBuilder ifBuilder = builder.ifStmt(tlaIf.getCond().accept(this))) { - try (GoBlockBuilder yes = ifBuilder.whenTrue()) { - yes.assign(result, tlaIf.getTval().accept(this)); - try (GoBlockBuilder no = ifBuilder.whenFalse()) { - no.assign(result, tlaIf.getFval().accept(this)); - } - } - } - return result; - } - - @Override - public GoExpression visit(TLALet tlaLet) throws RuntimeException { - throw new TODO(); - } - - @Override - public GoExpression visit(TLAGeneralIdentifier tlaGeneralIdentifier) throws RuntimeException { - UID ref = registry.followReference(tlaGeneralIdentifier.getUID()); - if (registry.isGlobalVariable(ref)) { - return globalStrategy.readGlobalVariable(builder, ref); - } - if (typeMap.get(ref) instanceof ArchetypeResourceType) { - return globalStrategy.readArchetypeResource(builder, tlaGeneralIdentifier); - } - if (typeMap.get(ref) instanceof ArchetypeResourceCollectionType) { - return builder.findUID(ref); - } - if (registry.isLocalVariable(ref)) { - return localStrategy.readLocalVariable(builder, ref); - } - if (registry.isConstant(ref)) { - return builder.findUID(ref); - } - return registry.findOperator(ref).generateGo( - builder, tlaGeneralIdentifier, registry, Collections.emptyList(), typeMap, localStrategy, globalStrategy); - } - - @Override - public GoExpression visit(TLATuple tlaTuple) throws RuntimeException { - GoType sliceType = typeMap.get(tlaTuple.getUID()).accept(new TypeConversionVisitor()); - List elements = new ArrayList<>(); - for (TLAExpression element : tlaTuple.getElements()) { - elements.add(element.accept(this)); - } - return sliceType.accept(new TLATupleCodeGenVisitor(elements)); - } - - @Override - public GoExpression visit(TLAMaybeAction tlaMaybeAction) throws RuntimeException { - throw new TODO(); - } - - @Override - public GoExpression visit(TLANumber tlaNumber) throws RuntimeException { - return new GoIntLiteral(Integer.valueOf(tlaNumber.getVal())); - } - - @Override - public GoExpression visit(TLAOperatorCall tlaOperatorCall) throws RuntimeException { - return registry - .findOperator(registry.followReference(tlaOperatorCall.getUID())) - .generateGo( - builder, tlaOperatorCall, registry, - tlaOperatorCall.getArgs(), - typeMap, localStrategy, globalStrategy); - } - - @Override - public GoExpression visit(TLAQuantifiedExistential tlaQuantifiedExistential) throws RuntimeException { - GoLabelName labelName = builder.newLabel("yes"); - GoVariableName exists = builder.varDecl("exists", GoBuiltins.False); - unfoldQuantifierBounds(tlaQuantifiedExistential.getIds(), innerBlock -> { - // needs a new visitor because we must write to the inner block rather than the outer block - try (GoIfBuilder ifBuilder = innerBlock.ifStmt(tlaQuantifiedExistential.getBody() - .accept(new TLAExpressionCodeGenVisitor(innerBlock, registry, typeMap, localStrategy, globalStrategy)))) { - try (GoBlockBuilder yes = ifBuilder.whenTrue()) { - yes.assign(exists, GoBuiltins.True); - if (tlaQuantifiedExistential.getIds().size() == 1) { - yes.addStatement(new GoBreak()); - } else { - yes.goTo(labelName); - } - } - } - }); - if (tlaQuantifiedExistential.getIds().size() != 1) { - builder.label(labelName); - } - return exists; - } - - @Override - public GoExpression visit(TLAQuantifiedUniversal tlaQuantifiedUniversal) throws RuntimeException { - GoLabelName labelName = builder.newLabel("no"); - GoVariableName forAll = builder.varDecl("forAll", GoBuiltins.True); - unfoldQuantifierBounds(tlaQuantifiedUniversal.getIds(), innerBlock -> { - // needs a new visitor because we must write to the inner block rather than the outer block - try (GoIfBuilder ifBuilder = innerBlock.ifStmt(CodeGenUtil.invertCondition( - innerBlock, registry, typeMap, localStrategy, globalStrategy, tlaQuantifiedUniversal.getBody()))) { - try (GoBlockBuilder yes = ifBuilder.whenTrue()) { - yes.assign(forAll, GoBuiltins.False); - if (tlaQuantifiedUniversal.getIds().size() == 1) { - yes.addStatement(new GoBreak()); - } else { - yes.goTo(labelName); - } - } - } - }); - if (tlaQuantifiedUniversal.getIds().size() != 1) { - builder.label(labelName); - } - return forAll; - } - - @Override - public GoExpression visit(TLARecordConstructor tlaRecordConstructor) throws RuntimeException { - Map kv = new HashMap<>(); - tlaRecordConstructor.getFields().forEach(f -> - kv.put(new GoStringLiteral(f.getName().getId()), f.getValue().accept(this))); - - return new GoMapLiteral(GoBuiltins.String, GoBuiltins.Interface, kv); - } - - @Override - public GoExpression visit(TLARecordSet tlaRecordSet) throws RuntimeException { - throw new TODO(); - } - - @Override - public GoExpression visit(TLARequiredAction tlaRequiredAction) throws RuntimeException { - throw new TODO(); - } - - @Override - public GoExpression visit(TLASetConstructor tlaSetConstructor) throws RuntimeException { - GoType elementType = TLABuiltins.getSetElementType(typeMap.get(tlaSetConstructor.getUID())); - GoSliceLiteral result = new GoSliceLiteral( - elementType, - tlaSetConstructor.getContents().stream() - .map(e -> e.accept(this)) - .collect(Collectors.toList())); - if (tlaSetConstructor.getContents().size() <= 1) { - // single-element or empty sets don't need any sorting or deduplication - return result; - } else { - if (result.accept(new GoExpressionIsConstantVisitor())) { - return CodeGenUtil.staticallySortSlice(result); - } - GoVariableName tmpSet = builder.varDecl("tmpSet", result); - TLABuiltins.ensureUniqueSorted(builder, elementType, tmpSet); - return tmpSet; - } - } - - @Override - public GoExpression visit(TLASetComprehension tlaSetComprehension) throws RuntimeException { - GoType elementType = TLABuiltins.getSetElementType(typeMap.get(tlaSetComprehension.getUID())); - GoVariableName accumulator = builder.varDecl( - "tmpSet", new GoMakeExpression(new GoSliceType(elementType), new GoIntLiteral(0), null)); - unfoldQuantifierBounds(tlaSetComprehension.getBounds(), innerBuilder -> { - GoExpression body = tlaSetComprehension.getBody().accept(new TLAExpressionCodeGenVisitor( - innerBuilder, registry, typeMap, localStrategy, globalStrategy)); - innerBuilder.assign(accumulator, new GoCall(new GoVariableName("append"), Arrays.asList(accumulator, body))); - }); - TLABuiltins.ensureUniqueSorted(builder, elementType, accumulator); - return accumulator; - } - - @Override - public GoExpression visit(TLASetRefinement tlaSetRefinement) throws RuntimeException { - GoType elementType = TLABuiltins.getSetElementType(typeMap.get(tlaSetRefinement.getUID())); - // GoRoutineStatement code - // tmpSet := make([]GoType, 0) - // for _, v := range pGoTLASetRefinement.getFrom() { - // if pGoTLASetRefinement.getWhen() { - // tmpSet = append(tmpSet, v) - // } - // } - GoVariableName tmpSet = builder.varDecl( - "tmpSet", new GoMakeExpression(new GoSliceType(elementType), new GoIntLiteral(0), null)); - GoForRangeBuilder forRangeBuilder = builder.forRange(tlaSetRefinement.getFrom().accept(this)); - - GoVariableName v; - if (tlaSetRefinement.getIdent().isTuple()) { - v = forRangeBuilder.initVariables(Arrays.asList("_", "v")).get(1); - } else { - TLAIdentifier id = tlaSetRefinement.getIdent().getId(); - GoVariableName name = forRangeBuilder.initVariables(Arrays.asList("_", id.getId())).get(1); - v = name; - builder.linkUID(id.getUID(), name); - } - - try (GoBlockBuilder forBody = forRangeBuilder.getBlockBuilder()) { - if (tlaSetRefinement.getIdent().isTuple()) { - List ids = tlaSetRefinement.getIdent().getTuple(); - for(int i = 0; i < ids.size(); ++i) { - GoVariableName elem = forBody.varDecl(ids.get(i).getId(), new GoIndexExpression(v, new GoIntLiteral(i))); - forBody.linkUID(ids.get(i).getUID(), elem); - } - } - - try (GoIfBuilder ifBuilder = forBody.ifStmt(tlaSetRefinement.getWhen().accept( - new TLAExpressionCodeGenVisitor(forBody, registry, typeMap, localStrategy, globalStrategy)))) { - try (GoBlockBuilder yes = ifBuilder.whenTrue()) { - yes.assign(tmpSet, new GoCall(new GoVariableName("append"), Arrays.asList(tmpSet, v))); - } - } - } - // no need to ensure uniqueness and sortedness, we're just removing elements - return tmpSet; - } - - @Override - public GoExpression visit(TLAString tlaString) throws RuntimeException { - return new GoStringLiteral(tlaString.getValue()); - } - - @Override - public GoExpression visit(TLAUnary tlaUnary) throws RuntimeException { - return registry - .findOperator(registry.followReference(tlaUnary.getUID())) - .generateGo( - builder, tlaUnary, registry, - Collections.singletonList(tlaUnary.getOperand()), - typeMap, localStrategy, globalStrategy); - } - - @Override - public GoExpression visit(TLAUniversal tlaUniversal) throws RuntimeException { - throw new TODO(); - } - - @Override - public GoExpression visit(PlusCalDefaultInitValue plusCalDefaultInitValue) throws RuntimeException { - return typeMap.get(plusCalDefaultInitValue.getUID()).accept(new TypeDefaultValueVisitor()); - } - - @Override - public GoExpression visit(TLAFairness fairness) throws RuntimeException { - throw new TODO(); - } - - @Override - public GoExpression visit(TLASpecialVariableVariable tlaSpecialVariableVariable) throws RuntimeException { - throw new TODO(); - } - - @Override - public GoExpression visit(TLASpecialVariableValue tlaSpecialVariableValue) throws RuntimeException { - throw new TODO(); - } - - @Override - public GoExpression visit(TLARef tlaRef) throws RuntimeException { - throw new TODO(); - } -} diff --git a/src/pgo/trans/passes/codegen/go/TLATupleCodeGenVisitor.java b/src/pgo/trans/passes/codegen/go/TLATupleCodeGenVisitor.java deleted file mode 100644 index 802d9e547..000000000 --- a/src/pgo/trans/passes/codegen/go/TLATupleCodeGenVisitor.java +++ /dev/null @@ -1,67 +0,0 @@ -package pgo.trans.passes.codegen.go; - -import pgo.InternalCompilerError; -import pgo.TODO; -import pgo.model.golang.*; -import pgo.model.golang.builder.GoBlockBuilder; -import pgo.model.golang.type.*; - -import java.util.ArrayList; -import java.util.List; - -public class TLATupleCodeGenVisitor extends GoTypeVisitor { - private final List elements; - - public TLATupleCodeGenVisitor(List elements) { - this.elements = elements; - } - - @Override - public GoExpression visit(GoTypeName typeName) throws RuntimeException { - throw new InternalCompilerError(); - } - - @Override - public GoExpression visit(GoArchetypeResourceType archetypeResourceType) throws RuntimeException { - throw new TODO(); - } - - @Override - public GoExpression visit(GoArchetypeResourceCollectionType archetypeResourceCollectionType) throws RuntimeException { - throw new TODO(); - } - - @Override - public GoExpression visit(GoStructType structType) throws RuntimeException { - List fields = new ArrayList<>(); - for(GoExpression element : elements){ - fields.add(new GoStructLiteralField(null, element)); - } - return new GoStructLiteral(structType, fields); - } - - @Override - public GoExpression visit(GoPtrType ptrType) throws RuntimeException { - throw new InternalCompilerError(); - } - - @Override - public GoExpression visit(GoSliceType sliceType) throws RuntimeException { - return new GoSliceLiteral(sliceType.getElementType(), elements); - } - - @Override - public GoExpression visit(GoChanType chanType) throws RuntimeException { - throw new TODO(); - } - - @Override - public GoExpression visit(GoMapType mapType) throws RuntimeException { - throw new TODO(); - } - - @Override - public GoExpression visit(GoInterfaceType interfaceType) throws RuntimeException { - throw new InternalCompilerError(); - } -} diff --git a/src/pgo/trans/passes/codegen/go/TypeConversionVisitor.java b/src/pgo/trans/passes/codegen/go/TypeConversionVisitor.java deleted file mode 100644 index c282ce2f8..000000000 --- a/src/pgo/trans/passes/codegen/go/TypeConversionVisitor.java +++ /dev/null @@ -1,134 +0,0 @@ -package pgo.trans.passes.codegen.go; - -import pgo.InternalCompilerError; -import pgo.TODO; -import pgo.model.golang.GoBuiltins; -import pgo.model.golang.type.*; -import pgo.model.type.*; - -import java.util.*; - -public class TypeConversionVisitor extends TypeVisitor { - @Override - public GoType visit(AbstractRecordType abstractRecordType) throws RuntimeException { - throw new InternalCompilerError(); - } - - @Override - public GoType visit(ArchetypeResourceType archetypeResourceType) throws RuntimeException { - return new GoArchetypeResourceType( - archetypeResourceType.getReadType().accept(this), - archetypeResourceType.getWriteType().accept(this)); - } - - @Override - public GoType visit(ArchetypeResourceCollectionType archetypeResourceCollectionType) throws RuntimeException { - return new GoArchetypeResourceCollectionType( - archetypeResourceCollectionType.getKeyType().accept(this), - archetypeResourceCollectionType.getReadType().accept(this), - archetypeResourceCollectionType.getWriteType().accept(this)); - } - - @Override - public GoType visit(TypeVariable typeVariable) throws RuntimeException { - throw new InternalCompilerError(); - } - - @Override - public GoType visit(TupleType tupleType) throws RuntimeException { - List fields = new ArrayList<>(); - List eTypes = tupleType.getElementTypes(); - for(int i = 0; i < eTypes.size(); ++i){ - fields.add(new GoStructTypeField("e"+i, eTypes.get(i).accept(this))); - } - return new GoStructType(fields); - } - - @Override - public GoType visit(StringType stringType) throws RuntimeException { - return GoBuiltins.String; - } - - @Override - public GoType visit(SetType setType) throws RuntimeException { - return new GoSliceType(setType.getElementType().accept(this)); - } - - @Override - public GoType visit(NonEnumerableSetType nonEnumerableSetType) throws RuntimeException { - throw new TODO(); - } - - @Override - public GoType visit(BoolType boolType) throws RuntimeException { - return GoBuiltins.Bool; - } - - @Override - public GoType visit(RealType realType) throws RuntimeException { - return GoBuiltins.Float64; - } - - @Override - public GoType visit(FunctionType functionType) throws RuntimeException { - List pTypes = functionType.getParamTypes(); - GoType keyType; - if(pTypes.size() == 1){ - keyType = pTypes.get(0).accept(this); - }else { - keyType = new TupleType(pTypes, functionType.getOrigins()).accept(this); - } - return new GoSliceType(new GoStructType(Arrays.asList( - new GoStructTypeField("key", keyType), - new GoStructTypeField("value", functionType.getReturnType().accept(this))))); - } - - @Override - public GoType visit(ChanType chanType) throws RuntimeException { - throw new TODO(); - } - - @Override - public GoType visit(IntType intType) throws RuntimeException { - return GoBuiltins.Int; - } - - @Override - public GoType visit(InterfaceType interfaceType) throws RuntimeException { - return GoBuiltins.Interface; - } - - @Override - public GoType visit(MapType mapType) throws RuntimeException { - return new GoSliceType(new GoStructType(Arrays.asList( - new GoStructTypeField("key", mapType.getKeyType().accept(this)), - new GoStructTypeField("value", mapType.getValueType().accept(this))))); - } - - @Override - public GoType visit(SliceType sliceType) throws RuntimeException { - return new GoSliceType(sliceType.getElementType().accept(this)); - } - - @Override - public GoType visit(ProcedureType procedureType) throws RuntimeException { - throw new TODO(); - } - - @Override - public GoType visit(RecordType recordType) throws RuntimeException { - // if the type of a variable is inferred to be a TLA+ record, use a map[string]interface{} - // to represent it. This avoids issues around sending and receiving of these variables - // through different archetype resources (e.g., RPC-based) and wrong casts - // when we cannot infer the correct type of the message on the receiving end - - // keep track of inferred types in case they are needed later when performing - // type-dependent operations - Map inferredTypes = new TreeMap<>(); - recordType - .getFields() - .forEach(f -> inferredTypes.put(f.getName(), f.getType().accept(new TypeConversionVisitor()))); - - return new GoMapType(GoBuiltins.String, GoBuiltins.Interface, inferredTypes); - } -} diff --git a/src/pgo/trans/passes/codegen/go/TypeDefaultValueVisitor.java b/src/pgo/trans/passes/codegen/go/TypeDefaultValueVisitor.java deleted file mode 100644 index c00a1f6e8..000000000 --- a/src/pgo/trans/passes/codegen/go/TypeDefaultValueVisitor.java +++ /dev/null @@ -1,102 +0,0 @@ -package pgo.trans.passes.codegen.go; - -import pgo.InternalCompilerError; -import pgo.TODO; -import pgo.model.golang.*; -import pgo.model.type.*; - -import java.util.Collections; - -public class TypeDefaultValueVisitor extends TypeVisitor { - @Override - public GoExpression visit(AbstractRecordType abstractRecordType) throws RuntimeException { - throw new TODO(); - } - - @Override - public GoExpression visit(ArchetypeResourceType archetypeResourceType) throws RuntimeException { - throw new TODO(); - } - - @Override - public GoExpression visit(ArchetypeResourceCollectionType archetypeResourceCollectionType) throws RuntimeException { - throw new TODO(); - } - - @Override - public GoExpression visit(TypeVariable typeVariable) throws RuntimeException { - throw new InternalCompilerError(); - } - - @Override - public GoExpression visit(TupleType tupleType) throws RuntimeException { - throw new TODO(); - } - - @Override - public GoExpression visit(StringType stringType) throws RuntimeException { - return new GoStringLiteral(""); - } - - @Override - public GoExpression visit(SetType setType) throws RuntimeException { - return new GoSliceLiteral( - setType.getElementType().accept(new TypeConversionVisitor()), - Collections.emptyList()); - } - - @Override - public GoExpression visit(NonEnumerableSetType nonEnumerableSetType) throws RuntimeException { - throw new TODO(); - } - - @Override - public GoExpression visit(BoolType boolType) throws RuntimeException { - return GoBuiltins.False; - } - - @Override - public GoExpression visit(RealType realType) throws RuntimeException { - throw new TODO(); - } - - @Override - public GoExpression visit(FunctionType functionType) throws RuntimeException { - throw new TODO(); - } - - @Override - public GoExpression visit(ChanType chanType) throws RuntimeException { - throw new TODO(); - } - - @Override - public GoExpression visit(IntType intType) throws RuntimeException { - return new GoIntLiteral(0); - } - - @Override - public GoExpression visit(InterfaceType interfaceType) throws RuntimeException { - return GoBuiltins.Nil; - } - - @Override - public GoExpression visit(MapType mapType) throws RuntimeException { - throw new TODO(); - } - - @Override - public GoExpression visit(SliceType sliceType) throws RuntimeException { - throw new TODO(); - } - - @Override - public GoExpression visit(ProcedureType procedureType) throws RuntimeException { - throw new TODO(); - } - - @Override - public GoExpression visit(RecordType recordType) throws RuntimeException { - throw new TODO(); - } -} diff --git a/src/pgo/trans/passes/codegen/pluscal/ExpandedProcedureMatch.java b/src/pgo/trans/passes/codegen/pluscal/ExpandedProcedureMatch.java deleted file mode 100644 index 1f21cfad7..000000000 --- a/src/pgo/trans/passes/codegen/pluscal/ExpandedProcedureMatch.java +++ /dev/null @@ -1,56 +0,0 @@ -package pgo.trans.passes.codegen.pluscal; - -import pgo.model.mpcal.ModularPlusCalMappingMacro; -import pgo.model.pcal.PlusCalVariableDeclaration; -import pgo.model.tla.TLAGeneralIdentifier; -import pgo.scope.UID; - -import java.util.List; -import java.util.Map; -import java.util.Set; - -class ExpandedProcedureMatch { - private final UID procedureUID; - private final List actualParams; - private final Map arguments; - private final Map mappings; - private final Set refs; - private final Set functionMappedVars; - - ExpandedProcedureMatch(UID procedureUID, List actualParams, - Map arguments, Map mappings, - Set refs, Set functionMappedVars) { - this.procedureUID = procedureUID; - this.actualParams = actualParams; - this.arguments = arguments; - this.mappings = mappings; - this.refs = refs; - this.functionMappedVars = functionMappedVars; - } - - @Override - public int hashCode() { - int result = 17; - result = 31 * result + procedureUID.hashCode(); - result = 31 * result + actualParams.hashCode(); - result = 31 * result + arguments.hashCode(); - result = 31 * result + mappings.hashCode(); - result = 31 * result + refs.hashCode(); - result = 31 * result + functionMappedVars.hashCode(); - return result; - } - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof ExpandedProcedureMatch)) { - return false; - } - ExpandedProcedureMatch other = (ExpandedProcedureMatch) obj; - return other.procedureUID.equals(procedureUID) && - other.actualParams.equals(actualParams) && - other.arguments.equals(arguments) && - other.mappings.equals(mappings) && - other.refs.equals(refs) && - other.functionMappedVars.equals(functionMappedVars); - } -} diff --git a/src/pgo/trans/passes/codegen/pluscal/ModularPlusCalCodeGenVisitor.java b/src/pgo/trans/passes/codegen/pluscal/ModularPlusCalCodeGenVisitor.java deleted file mode 100644 index e40b744fb..000000000 --- a/src/pgo/trans/passes/codegen/pluscal/ModularPlusCalCodeGenVisitor.java +++ /dev/null @@ -1,401 +0,0 @@ -package pgo.trans.passes.codegen.pluscal; - -import pgo.Unreachable; -import pgo.model.mpcal.ModularPlusCalMappingMacro; -import pgo.model.mpcal.ModularPlusCalYield; -import pgo.model.pcal.*; -import pgo.model.tla.*; -import pgo.scope.UID; -import pgo.trans.intermediate.DefinitionRegistry; -import pgo.util.SourceLocation; - -import java.util.*; - -public class ModularPlusCalCodeGenVisitor extends PlusCalStatementVisitor, RuntimeException> { - private final DefinitionRegistry registry; - protected final TemporaryBinding readTemporaryBinding; - protected final TemporaryBinding writeTemporaryBinding; - private final Map params; - private final Map arguments; - private final Map mappings; - private final Set expressionArguments; - private final Set functionMappedVars; - private final ProcedureExpander procedureExpander; - private final TLAExpressionPlusCalCodeGenVisitor visitor; - - ModularPlusCalCodeGenVisitor(DefinitionRegistry registry, Map params, - Map arguments, - Map mappings, Set expressionArguments, - Set functionMappedVars, TemporaryBinding readTemporaryBinding, - TemporaryBinding writeTemporaryBinding, ProcedureExpander procedureExpander, - TLAExpressionPlusCalCodeGenVisitor visitor) { - this.registry = registry; - this.params = params; - this.arguments = arguments; - this.mappings = mappings; - this.expressionArguments = expressionArguments; - this.functionMappedVars = functionMappedVars; - this.readTemporaryBinding = readTemporaryBinding; - this.writeTemporaryBinding = writeTemporaryBinding; - this.procedureExpander = procedureExpander; - this.visitor = visitor; - } - - private List substituteStatements(List statements) { - List result = new ArrayList<>(); - for (PlusCalStatement statement : statements) { - result.addAll(statement.accept(this)); - } - return result; - } - - private List substituteBlock(List statements) { - List result = new ArrayList<>(); - for (int i = 0; i < statements.size(); i++) { - PlusCalStatement statement = statements.get(i); - if (statement instanceof PlusCalLabeledStatements) { - List writeBacks = getWriteBacksAndCleanUp(statement.getLocation()); - if (writeBacks.size() > 0) { - result = WriteBackInsertionVisitor.insertWriteBacks(result, writeBacks); - } - result.addAll(substituteStatements(statements.subList(i, statements.size()))); - return result; - } - result.addAll(statement.accept(this)); - } - return result; - } - - - private List getWriteBacksAndCleanUp(SourceLocation location) { - List writeBacks = new ArrayList<>(); - for (UID varUID : arguments.keySet()) { - // only write back written global variables - TLAGeneralIdentifier variable = arguments.get(varUID); - if (writeTemporaryBinding.lookup(varUID).isPresent()) { - TLAGeneralIdentifier rhs = writeTemporaryBinding.lookup(varUID).get(); - writeBacks.add(new PlusCalAssignment( - location, - Collections.singletonList(new PlusCalAssignmentPair(location, variable, rhs)))); - } - } - // clean up - readTemporaryBinding.reuseAll(); - writeTemporaryBinding.reuseAll(); - return writeBacks; - } - - @Override - public List visit(PlusCalLabeledStatements plusCalLabeledStatements) throws RuntimeException { - for (UID varUID : expressionArguments) { - readTemporaryBinding.declare( - plusCalLabeledStatements.getLocation(), varUID, params.get(varUID).getName().getId() + "Local"); - } - // translate the statements in this labeledStatements - List statements = substituteStatements(plusCalLabeledStatements.getStatements()); - // write back the written values and clean up - List writeBacks = getWriteBacksAndCleanUp(plusCalLabeledStatements.getLabel().getLocation()); - return Collections.singletonList(new PlusCalLabeledStatements( - plusCalLabeledStatements.getLocation(), - plusCalLabeledStatements.getLabel(), - writeBacks.size() > 0 - ? WriteBackInsertionVisitor.insertWriteBacks(statements, writeBacks) - : statements)); - } - - private void declareJoinNames(SourceLocation location, Map varUIDs, - Map output) { - for (UID varUID : varUIDs.keySet()) { - if (arguments.containsKey(varUID) && !output.containsKey(varUID)) { - output.put( - varUID, - writeTemporaryBinding.forceDeclare( - location, varUID, params.get(varUID).getName().getId() + "Write")); - } - } - } - - private List writeJoinAssignments(SourceLocation location, - Map touchedVars, - Map writes, - List output) { - List joinAssignments = new ArrayList<>(); - for (Map.Entry entry : touchedVars.entrySet()) { - UID varUID = entry.getKey(); - TLAGeneralIdentifier writeVar = entry.getValue(); - if (writes.containsKey(varUID)) { - joinAssignments.add(new PlusCalAssignment( - location, - Collections.singletonList(new PlusCalAssignmentPair(location, writeVar, writes.get(varUID))))); - } else { - joinAssignments.add(new PlusCalAssignment( - location, - Collections.singletonList(new PlusCalAssignmentPair( - location, writeVar, arguments.get(varUID))))); - } - } - return WriteBackInsertionVisitor.insertWriteBacks(output, joinAssignments); - } - - @Override - public List visit(PlusCalWhile plusCalWhile) throws RuntimeException { - // all while loops are already desugared into ifs and gotos in the previous desugaring phase - throw new Unreachable(); - } - - @Override - public List visit(PlusCalIf plusCalIf) throws RuntimeException { - SourceLocation location = plusCalIf.getLocation(); - - List result = new ArrayList<>(); - TLAExpression condition = plusCalIf.getCondition().accept(visitor.createWith(result)); - - TemporaryBinding.Checkpoint checkpoint = writeTemporaryBinding.checkpoint(); - Map yesWrites = writeTemporaryBinding.startRecording(); - List yes = substituteBlock(plusCalIf.getYes()); - writeTemporaryBinding.stopRecording(); - writeTemporaryBinding.restore(checkpoint); - - Map noWrites = writeTemporaryBinding.startRecording(); - List no = substituteBlock(plusCalIf.getNo()); - writeTemporaryBinding.stopRecording(); - - Map touchedVars = new LinkedHashMap<>(); - declareJoinNames(location, yesWrites, touchedVars); - declareJoinNames(location, noWrites, touchedVars); - - result.add(new PlusCalIf( - location, - condition, - writeJoinAssignments(location, touchedVars, yesWrites, yes), - writeJoinAssignments(location, touchedVars, noWrites, no))); - return result; - } - - @Override - public List visit(PlusCalEither plusCalEither) throws RuntimeException { - SourceLocation location = plusCalEither.getLocation(); - List> transformedCases = new ArrayList<>(); - List> writesList = new ArrayList<>(); - List> cases = plusCalEither.getCases(); - for (int i = 0; i < cases.size(); i++) { - List aCase = cases.get(i); - TemporaryBinding.Checkpoint checkpoint = writeTemporaryBinding.checkpoint(); - Map touchedVars = writeTemporaryBinding.startRecording(); - transformedCases.add(substituteBlock(aCase)); - writeTemporaryBinding.stopRecording(); - if (i != cases.size() - 1) { - // only restore checkpoint if it's not the last case, so that the state of writeTemporaryBinding is - // correct after translating this either statement - writeTemporaryBinding.restore(checkpoint); - } - writesList.add(touchedVars); - } - Map touchedVars = new LinkedHashMap<>(); - for (Map uids : writesList) { - declareJoinNames(location, uids, touchedVars); - } - for (int i = 0; i < transformedCases.size(); i++) { - List transformedCase = transformedCases.get(i); - Map writes = writesList.get(i); - transformedCases.set(i, writeJoinAssignments(location, touchedVars, writes, transformedCase)); - } - return Collections.singletonList(new PlusCalEither(location, transformedCases)); - } - - private void assignmentHelper(SourceLocation location, TLAExpression lhs, TLAExpression rhs, - List result) { - TLAExpression transformedLHS = lhs.accept(visitor.createWith(result)); - result.add(new PlusCalAssignment( - location, - Collections.singletonList(new PlusCalAssignmentPair(location, transformedLHS, rhs)))); - } - - @Override - public List visit(PlusCalAssignment plusCalAssignment) throws RuntimeException { - List result = new ArrayList<>(); - List pairs = plusCalAssignment.getPairs(); - List rhsList = new ArrayList<>(); - if (pairs.size() > 1) { - TLAExpressionPlusCalCodeGenVisitor v = visitor.createWith(result); - // read the RHS into temporary variables for use later so that parallel assignment works right - for (PlusCalAssignmentPair pair : pairs) { - SourceLocation location = pair.getLocation(); - TLAExpression rhs = pair.getRhs(); - TLAGeneralIdentifier tempVariable = readTemporaryBinding.declare(location, new UID(), "rhsRead"); - TLAExpression transformedRHS = rhs.accept(v); - result.add(new PlusCalAssignment( - location, - Collections.singletonList(new PlusCalAssignmentPair(location, tempVariable, transformedRHS)))); - rhsList.add(tempVariable); - } - } else { - // otherwise, don't create temporary variable for cleaner code - rhsList.add(pairs.get(0).getRhs().accept(visitor.createWith(result))); - } - for (int i = 0; i < pairs.size(); i++) { - PlusCalAssignmentPair pair = pairs.get(i); - SourceLocation location = pair.getLocation(); - TLAExpression lhs = pair.getLhs(); - TLAExpression rhs = rhsList.get(i); - TLAGeneralIdentifier identifier = null; - List accumulatedIndices = new ArrayList<>(); - if (lhs instanceof TLAFunctionCall) { - Optional optionalVariable = - TLAExpressionPlusCalCodeGenVisitor.extractFunctionCallIdentifier( - (TLAFunctionCall) lhs, accumulatedIndices); - if (optionalVariable.isPresent()) { - identifier = optionalVariable.get(); - } - } else if (lhs instanceof TLAGeneralIdentifier) { - identifier = (TLAGeneralIdentifier) lhs; - } - if (identifier == null) { - assignmentHelper(location, lhs, rhs, result); - continue; - } - UID varUID = registry.followReference(identifier.getUID()); - if (!arguments.containsKey(varUID)) { - assignmentHelper(location, lhs, rhs, result); - continue; - } - TLAGeneralIdentifier dollarVariable = arguments.get(varUID); - String nameHint = params.get(varUID).getName().getId() + "Write"; - PlusCalStatementVisitor, RuntimeException> writeVisitor; - if (lhs instanceof TLAFunctionCall) { - TLAExpressionPlusCalCodeGenVisitor v = visitor.createWith(result); - for (int j = accumulatedIndices.size() - 1; j >= 0; j--) { - accumulatedIndices.set(j, accumulatedIndices.get(j).accept(v)); - } - if (!mappings.containsKey(varUID)) { - TLAFunctionSubstitution sub = new TLAFunctionSubstitution( - location, - writeTemporaryBinding.lookup(varUID).orElse(dollarVariable), - Collections.singletonList(new TLAFunctionSubstitutionPair( - location, - Collections.singletonList(new TLASubstitutionKey( - location, accumulatedIndices)), - rhs))); - TLAGeneralIdentifier temp = writeTemporaryBinding.declare(location, varUID, nameHint); - result.add(new PlusCalAssignment( - location, Collections.singletonList(new PlusCalAssignmentPair(location, temp, sub)))); - continue; - } - TLAExpression index = functionMappedVars.contains(varUID) ? accumulatedIndices.get(0) : null; - writeVisitor = new ModularPlusCalMappingMacroFunctionCallWriteExpansionVisitor( - registry, params, arguments, mappings, expressionArguments, functionMappedVars, - readTemporaryBinding, writeTemporaryBinding, procedureExpander, - new TLAExpressionMappingMacroWriteExpansionVisitor( - registry, params, arguments, expressionArguments, mappings, functionMappedVars, - readTemporaryBinding, writeTemporaryBinding, procedureExpander, result, dollarVariable, - rhs, varUID, index), - dollarVariable, varUID, nameHint, index, accumulatedIndices); - } else { - if (!mappings.containsKey(varUID)) { - TLAGeneralIdentifier temp = writeTemporaryBinding.declare(location, varUID, nameHint); - result.add(new PlusCalAssignment( - location, - Collections.singletonList(new PlusCalAssignmentPair(location, temp, rhs)))); - continue; - } - writeVisitor = new ModularPlusCalMappingMacroVariableWriteExpansionVisitor( - registry, params, arguments, mappings, expressionArguments, functionMappedVars, - readTemporaryBinding, writeTemporaryBinding, procedureExpander, - new TLAExpressionMappingMacroWriteExpansionVisitor( - registry, params, arguments, expressionArguments, mappings, functionMappedVars, - readTemporaryBinding, writeTemporaryBinding, procedureExpander, result, dollarVariable, - rhs, varUID, null), - dollarVariable, varUID, nameHint, null); - } - for (PlusCalStatement statement : mappings.get(varUID).getWriteBody()) { - result.addAll(statement.accept(writeVisitor)); - } - } - return result; - } - - @Override - public List visit(PlusCalReturn plusCalReturn) throws RuntimeException { - return Collections.singletonList(new PlusCalReturn(plusCalReturn.getLocation())); - } - - @Override - public List visit(PlusCalSkip plusCalSkip) throws RuntimeException { - return Collections.singletonList(new PlusCalSkip(plusCalSkip.getLocation())); - } - - @Override - public List visit(PlusCalCall plusCalCall) throws RuntimeException { - List result = new ArrayList<>(); - TLAExpressionPlusCalCodeGenVisitor v = visitor.createWith(result); - // the call has to be expanded before we insert the write-backs - PlusCalCall expandedCall = procedureExpander.expand(plusCalCall, v); - result.addAll(WriteBackInsertionVisitor.insertWriteBacks( - result, getWriteBacksAndCleanUp(plusCalCall.getLocation()))); - // after inserting the write-backs, we can now safely insert the call - result.add(expandedCall); - // so now, the result looks like - // - // reads... - // write-backs... - // call Proc(args...) - return result; - } - - @Override - public List visit(PlusCalMacroCall macroCall) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public List visit(PlusCalWith plusCalWith) throws RuntimeException { - List result = new ArrayList<>(); - List declarations = new ArrayList<>(); - TLAExpressionPlusCalCodeGenVisitor v = visitor.createWith(result); - for (PlusCalVariableDeclaration declaration : plusCalWith.getVariables()) { - declarations.add(new PlusCalVariableDeclaration( - declaration.getLocation(), - declaration.getName(), - false, - declaration.isSet(), - declaration.getValue().accept(v))); - } - result.add(new PlusCalWith( - plusCalWith.getLocation(), declarations, substituteStatements(plusCalWith.getBody()))); - return result; - } - - @Override - public List visit(PlusCalPrint plusCalPrint) throws RuntimeException { - List result = new ArrayList<>(); - TLAExpression expression = plusCalPrint.getValue().accept(visitor.createWith(result)); - result.add(new PlusCalPrint(plusCalPrint.getLocation(), expression)); - return result; - } - - @Override - public List visit(PlusCalAssert plusCalAssert) throws RuntimeException { - List result = new ArrayList<>(); - TLAExpression expression = plusCalAssert.getCondition().accept(visitor.createWith(result)); - result.add(new PlusCalAssert(plusCalAssert.getLocation(), expression)); - return result; - } - - @Override - public List visit(PlusCalAwait plusCalAwait) throws RuntimeException { - List result = new ArrayList<>(); - TLAExpression condition = plusCalAwait.getCondition().accept(visitor.createWith(result)); - result.add(new PlusCalAwait(plusCalAwait.getLocation(), condition)); - return result; - } - - @Override - public List visit(PlusCalGoto plusCalGoto) throws RuntimeException { - return Collections.singletonList(plusCalGoto.copy()); - } - - @Override - public List visit(ModularPlusCalYield modularPlusCalYield) throws RuntimeException { - throw new Unreachable(); - } -} diff --git a/src/pgo/trans/passes/codegen/pluscal/ModularPlusCalMappingMacroFunctionCallWriteExpansionVisitor.java b/src/pgo/trans/passes/codegen/pluscal/ModularPlusCalMappingMacroFunctionCallWriteExpansionVisitor.java deleted file mode 100644 index f776dd2fc..000000000 --- a/src/pgo/trans/passes/codegen/pluscal/ModularPlusCalMappingMacroFunctionCallWriteExpansionVisitor.java +++ /dev/null @@ -1,58 +0,0 @@ -package pgo.trans.passes.codegen.pluscal; - -import pgo.model.mpcal.ModularPlusCalMappingMacro; -import pgo.model.mpcal.ModularPlusCalYield; -import pgo.model.pcal.PlusCalAssignment; -import pgo.model.pcal.PlusCalAssignmentPair; -import pgo.model.pcal.PlusCalStatement; -import pgo.model.pcal.PlusCalVariableDeclaration; -import pgo.model.tla.*; -import pgo.scope.UID; -import pgo.trans.intermediate.DefinitionRegistry; -import pgo.util.SourceLocation; - -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Set; - -public class ModularPlusCalMappingMacroFunctionCallWriteExpansionVisitor - extends ModularPlusCalMappingMacroReadExpansionVisitor { - private final List indices; - - ModularPlusCalMappingMacroFunctionCallWriteExpansionVisitor( - DefinitionRegistry registry, Map params, - Map arguments, - Map mappings, Set expressionArguments, - Set functionMappedVars, TemporaryBinding readTemporaryBinding, - TemporaryBinding writeTemporaryBinding, ProcedureExpander procedureExpander, - TLAExpressionPlusCalCodeGenVisitor visitor, TLAGeneralIdentifier dollarVariable, UID varUID, - String nameHint, TLAExpression index, List indices) { - super( - registry, params, arguments, mappings, expressionArguments, functionMappedVars, readTemporaryBinding, - writeTemporaryBinding, procedureExpander, dollarVariable, varUID, nameHint, index, visitor, null); - this.indices = indices; - } - - @Override - public List visit(ModularPlusCalYield modularPlusCalYield) throws RuntimeException { - SourceLocation location = modularPlusCalYield.getLocation(); - TLAGeneralIdentifier var = writeTemporaryBinding.lookup(varUID).orElse(dollarVariable); - // yieldExpr has to be translated before the new temporary variable is declared in order for any $variable - // references in it to be translated to a previous reference of $variable - TLAExpression translatedYieldExpr = modularPlusCalYield.getExpression().accept(visitor); - // the real yield expression is a function substitution - TLAExpression yieldExpr = new TLAFunctionSubstitution( - location, - var, - Collections.singletonList(new TLAFunctionSubstitutionPair( - location, - Collections.singletonList(new TLASubstitutionKey(location, indices)), - translatedYieldExpr))); - TLAGeneralIdentifier temp = writeTemporaryBinding.declare(modularPlusCalYield.getLocation(), varUID, nameHint); - return Collections.singletonList(new PlusCalAssignment( - modularPlusCalYield.getLocation(), - Collections.singletonList(new PlusCalAssignmentPair( - modularPlusCalYield.getLocation(), temp, yieldExpr)))); - } -} diff --git a/src/pgo/trans/passes/codegen/pluscal/ModularPlusCalMappingMacroReadExpansionVisitor.java b/src/pgo/trans/passes/codegen/pluscal/ModularPlusCalMappingMacroReadExpansionVisitor.java deleted file mode 100644 index 5c2742706..000000000 --- a/src/pgo/trans/passes/codegen/pluscal/ModularPlusCalMappingMacroReadExpansionVisitor.java +++ /dev/null @@ -1,189 +0,0 @@ -package pgo.trans.passes.codegen.pluscal; - -import pgo.Unreachable; -import pgo.model.mpcal.ModularPlusCalMappingMacro; -import pgo.model.mpcal.ModularPlusCalYield; -import pgo.model.pcal.*; -import pgo.model.tla.*; -import pgo.scope.UID; -import pgo.trans.intermediate.DefinitionRegistry; -import pgo.util.SourceLocation; - -import java.util.*; - -public class ModularPlusCalMappingMacroReadExpansionVisitor extends ModularPlusCalCodeGenVisitor { - protected final TLAGeneralIdentifier dollarVariable; - protected final UID varUID; - protected final String nameHint; - private final TLAExpression index; - protected final TLAExpressionPlusCalCodeGenVisitor visitor; - private final TLAGeneralIdentifier temporaryVariable; - - ModularPlusCalMappingMacroReadExpansionVisitor( - DefinitionRegistry registry, Map params, - Map arguments, Map mappings, - Set expressionArguments, Set functionMappedVars, TemporaryBinding readTemporaryBinding, - TemporaryBinding writeTemporaryBinding, ProcedureExpander procedureExpander, - TLAGeneralIdentifier dollarVariable, UID varUID, String nameHint, TLAExpression index, - TLAExpressionPlusCalCodeGenVisitor visitor, TLAGeneralIdentifier temporaryVariable) { - super( - registry, params, arguments, mappings, expressionArguments, functionMappedVars, readTemporaryBinding, - writeTemporaryBinding, procedureExpander, visitor); - this.dollarVariable = dollarVariable; - this.varUID = varUID; - this.nameHint = nameHint; - this.index = index; - this.visitor = visitor; - this.temporaryVariable = temporaryVariable; - } - - private List substituteStatements(List statements) { - List result = new ArrayList<>(); - for (PlusCalStatement statement : statements) { - result.addAll(statement.accept(this)); - } - return result; - } - - @Override - public List visit(PlusCalLabeledStatements plusCalLabeledStatements) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public List visit(PlusCalWhile plusCalWhile) throws RuntimeException { - return Collections.singletonList(new PlusCalWhile( - plusCalWhile.getLocation(), - plusCalWhile.getCondition().accept(visitor), - substituteStatements(plusCalWhile.getBody()))); - } - - @Override - public List visit(PlusCalAssignment plusCalAssignment) throws RuntimeException { - List result = new ArrayList<>(); - List pairs = plusCalAssignment.getPairs(); - List rhsList = new ArrayList<>(); - if (pairs.size() > 1) { - for (PlusCalAssignmentPair pair : pairs) { - SourceLocation location = pair.getLocation(); - TLAExpression rhs = pair.getRhs().accept(visitor); - TLAGeneralIdentifier rhsRead = readTemporaryBinding.declare(location, new UID(), "rhsRead"); - result.add(new PlusCalAssignment( - location, - Collections.singletonList(new PlusCalAssignmentPair( - location, rhsRead, rhs)))); - rhsList.add(rhsRead); - } - } else { - rhsList.add(pairs.get(0).getRhs().accept(visitor)); - } - List transformedPairs = new ArrayList<>(); - for (int i = 0; i < pairs.size(); i++) { - PlusCalAssignmentPair pair = pairs.get(i); - SourceLocation location = pair.getLocation(); - TLAExpression lhs = pair.getLhs(); - TLAExpression rhs = rhsList.get(i); - if (lhs instanceof TLASpecialVariableVariable) { - TLAGeneralIdentifier variable = writeTemporaryBinding.lookup(varUID).orElse(dollarVariable); - lhs = writeTemporaryBinding.declare(lhs.getLocation(), varUID, nameHint); - if (index != null) { - rhs = new TLAFunctionSubstitution( - location, - variable, - Collections.singletonList(new TLAFunctionSubstitutionPair( - location, - Collections.singletonList(new TLASubstitutionKey( - location, Collections.singletonList(index))), - rhs))); - } - } else { - lhs = lhs.accept(visitor); - } - transformedPairs.add(new PlusCalAssignmentPair(location, lhs, rhs)); - } - result.add(new PlusCalAssignment(plusCalAssignment.getLocation(), transformedPairs)); - return result; - } - - @Override - public List visit(PlusCalReturn plusCalReturn) throws RuntimeException { - return Collections.singletonList(new PlusCalReturn(plusCalReturn.getLocation())); - } - - @Override - public List visit(PlusCalSkip plusCalSkip) throws RuntimeException { - return Collections.singletonList(new PlusCalSkip(plusCalSkip.getLocation())); - } - - @Override - public List visit(PlusCalCall plusCalCall) throws RuntimeException { - List params = new ArrayList<>(); - for (TLAExpression argument : plusCalCall.getArguments()) { - params.add(argument.accept(visitor)); - } - return Collections.singletonList(new PlusCalCall( - plusCalCall.getLocation(), - plusCalCall.getTarget(), - params)); - } - - @Override - public List visit(PlusCalMacroCall macroCall) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public List visit(PlusCalWith plusCalWith) throws RuntimeException { - List declarations = new ArrayList<>(); - for (PlusCalVariableDeclaration declaration : plusCalWith.getVariables()) { - TLAGeneralIdentifier fresh = readTemporaryBinding.freshVariable( - declaration.getLocation(), declaration.getUID(), declaration.getName().getId()); - declarations.add(new PlusCalVariableDeclaration( - declaration.getLocation(), - new TLAIdentifier(declaration.getName().getLocation(), fresh.getName().getId()), - false, - declaration.isSet(), - declaration.getValue().accept(visitor))); - } - return Collections.singletonList(new PlusCalWith( - plusCalWith.getLocation(), - declarations, - substituteStatements(plusCalWith.getBody()))); - } - - @Override - public List visit(PlusCalPrint plusCalPrint) throws RuntimeException { - return Collections.singletonList(new PlusCalPrint( - plusCalPrint.getLocation(), - plusCalPrint.getValue().accept(visitor))); - } - - @Override - public List visit(PlusCalAssert plusCalAssert) throws RuntimeException { - return Collections.singletonList(new PlusCalAssert( - plusCalAssert.getLocation(), - plusCalAssert.getCondition().accept(visitor))); - } - - @Override - public List visit(PlusCalAwait plusCalAwait) throws RuntimeException { - return Collections.singletonList(new PlusCalAwait( - plusCalAwait.getLocation(), - plusCalAwait.getCondition().accept(visitor))); - } - - @Override - public List visit(PlusCalGoto plusCalGoto) throws RuntimeException { - return Collections.singletonList(new PlusCalGoto(plusCalGoto.getLocation(), plusCalGoto.getTarget())); - } - - @Override - public List visit(ModularPlusCalYield modularPlusCalYield) throws RuntimeException { - return Collections.singletonList(new PlusCalAssignment( - modularPlusCalYield.getLocation(), - Collections.singletonList(new PlusCalAssignmentPair( - modularPlusCalYield.getLocation(), - temporaryVariable, - modularPlusCalYield.getExpression().accept(visitor))))); - } -} diff --git a/src/pgo/trans/passes/codegen/pluscal/ModularPlusCalMappingMacroVariableWriteExpansionVisitor.java b/src/pgo/trans/passes/codegen/pluscal/ModularPlusCalMappingMacroVariableWriteExpansionVisitor.java deleted file mode 100644 index cc3f34611..000000000 --- a/src/pgo/trans/passes/codegen/pluscal/ModularPlusCalMappingMacroVariableWriteExpansionVisitor.java +++ /dev/null @@ -1,46 +0,0 @@ -package pgo.trans.passes.codegen.pluscal; - -import pgo.model.mpcal.ModularPlusCalMappingMacro; -import pgo.model.mpcal.ModularPlusCalYield; -import pgo.model.pcal.PlusCalAssignment; -import pgo.model.pcal.PlusCalAssignmentPair; -import pgo.model.pcal.PlusCalStatement; -import pgo.model.pcal.PlusCalVariableDeclaration; -import pgo.model.tla.TLAExpression; -import pgo.model.tla.TLAExpressionVisitor; -import pgo.model.tla.TLAGeneralIdentifier; -import pgo.scope.UID; -import pgo.trans.intermediate.DefinitionRegistry; - -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Set; - -public class ModularPlusCalMappingMacroVariableWriteExpansionVisitor - extends ModularPlusCalMappingMacroReadExpansionVisitor { - ModularPlusCalMappingMacroVariableWriteExpansionVisitor( - DefinitionRegistry registry, Map params, - Map arguments, - Map mappings, Set expressionArguments, - Set functionMappedVars, TemporaryBinding readTemporaryBinding, - TemporaryBinding writeTemporaryBinding, ProcedureExpander procedureExpander, - TLAExpressionPlusCalCodeGenVisitor visitor, TLAGeneralIdentifier dollarVariable, UID varUID, - String nameHint, TLAExpression index) { - super( - registry, params, arguments, mappings, expressionArguments, functionMappedVars, readTemporaryBinding, - writeTemporaryBinding, procedureExpander, dollarVariable, varUID, nameHint, index, visitor, null); - } - - @Override - public List visit(ModularPlusCalYield modularPlusCalYield) throws RuntimeException { - // yieldExpr has to be translated before the new temporary variable is declared in order for any $variable - // references in it to be translated to a previous reference of $variable - TLAExpression yieldExpr = modularPlusCalYield.getExpression().accept(visitor); - TLAGeneralIdentifier temp = writeTemporaryBinding.declare(modularPlusCalYield.getLocation(), varUID, nameHint); - return Collections.singletonList(new PlusCalAssignment( - modularPlusCalYield.getLocation(), - Collections.singletonList(new PlusCalAssignmentPair( - modularPlusCalYield.getLocation(), temp, yieldExpr)))); - } -} diff --git a/src/pgo/trans/passes/codegen/pluscal/PlusCalCodeGenPass.java b/src/pgo/trans/passes/codegen/pluscal/PlusCalCodeGenPass.java deleted file mode 100644 index 65367d59e..000000000 --- a/src/pgo/trans/passes/codegen/pluscal/PlusCalCodeGenPass.java +++ /dev/null @@ -1,198 +0,0 @@ -package pgo.trans.passes.codegen.pluscal; - -import pgo.Unreachable; -import pgo.errors.IssueContext; -import pgo.model.mpcal.*; -import pgo.model.pcal.*; -import pgo.model.tla.*; -import pgo.scope.UID; -import pgo.trans.intermediate.DefinitionRegistry; -import pgo.trans.intermediate.UnsupportedFeatureIssue; -import pgo.trans.passes.codegen.NameCleaner; -import pgo.trans.passes.validation.NonModularPlusCalNodeValidationVisitor; - -import java.util.*; -import java.util.stream.Stream; - -public class PlusCalCodeGenPass { - private PlusCalCodeGenPass() {} - - private static void recordMapping(DefinitionRegistry registry, Map mappedVars, - UID paramUID, UID mappedUID, Map mappings, - Set functionMappedVars) { - ModularPlusCalMapping mapping = mappedVars.get(mappedUID); - if (mapping != null) { - if (mapping.getVariable().isFunctionCall()){ - functionMappedVars.add(paramUID); - } - mappings.put(paramUID, registry.findMappingMacro(mapping.getTarget().getName())); - } - } - - public static PlusCalAlgorithm perform(IssueContext ctx, DefinitionRegistry registry, - ModularPlusCalBlock modularPlusCalBlock) { - // separate the procedures with ref arguments and ones without - List procedures = new ArrayList<>(); - NonModularPlusCalNodeValidationVisitor nonModularPlusCalNodeValidationVisitor = - new NonModularPlusCalNodeValidationVisitor(); - for (PlusCalProcedure procedure : modularPlusCalBlock.getProcedures()) { - if (procedure.accept(nonModularPlusCalNodeValidationVisitor)) { - procedures.add(procedure); - } - } - Map procedureCache = new HashMap<>(); - - // seed for the name cleaner - Set nameCleanerSeed = new HashSet<>(); - PlusCalStatementNameCollectorVisitor nameCollector = new PlusCalStatementNameCollectorVisitor(nameCleanerSeed); - for (PlusCalProcedure procedure : modularPlusCalBlock.getProcedures()) { - nameCleanerSeed.add(procedure.getName()); - Stream.concat(procedure.getVariables().stream(), procedure.getParams().stream()) - .forEach(v -> nameCleanerSeed.add(v.getName().getId())); - procedure.getBody().forEach(s -> s.accept(nameCollector)); - } - if (modularPlusCalBlock.getProcesses() instanceof PlusCalMultiProcess) { - for (PlusCalProcess process : ((PlusCalMultiProcess) modularPlusCalBlock.getProcesses()).getProcesses()) { - nameCleanerSeed.add(process.getName().getName().getId()); - for (PlusCalVariableDeclaration declaration : process.getVariables()) { - nameCleanerSeed.add(declaration.getName().getId()); - } - process.getBody().forEach(s -> s.accept(nameCollector)); - } - } - for (ModularPlusCalArchetype archetype : modularPlusCalBlock.getArchetypes()) { - nameCleanerSeed.add(archetype.getName()); - Stream.concat(archetype.getParams().stream(), archetype.getParams().stream()) - .forEach(v -> nameCleanerSeed.add(v.getName().getId())); - archetype.getBody().forEach(s -> s.accept(nameCollector)); - } - for (ModularPlusCalMappingMacro mappingMacro : modularPlusCalBlock.getMappingMacros()) { - nameCleanerSeed.add(mappingMacro.getName()); - mappingMacro.getReadBody().forEach(s -> s.accept(nameCollector)); - mappingMacro.getWriteBody().forEach(s -> s.accept(nameCollector)); - } - for (ModularPlusCalInstance instance : modularPlusCalBlock.getInstances()) { - nameCleanerSeed.add(instance.getName().getName().getId()); - } - NameCleaner nameCleaner = new NameCleaner(nameCleanerSeed); - - // expand the instances - List globalVariables = new ArrayList<>(modularPlusCalBlock.getVariables()); - List processList = new ArrayList<>(); - for (ModularPlusCalInstance instance : modularPlusCalBlock.getInstances()) { - Map mappedVars = new HashMap<>(); - for (ModularPlusCalMapping mapping : instance.getMappings()) { - mappedVars.put(registry.followReference(mapping.getVariable().getUID()), mapping); - } - ModularPlusCalArchetype archetype = registry.findArchetype(instance.getTarget()); - Map params = new HashMap<>(); - Map arguments = new LinkedHashMap<>(); - Map mappings = new HashMap<>(); - Set expressionArguments = new HashSet<>(); - Set functionMappedVars = new HashSet<>(); - Set refs = new HashSet<>(); - List localVariables = new ArrayList<>(); - TemporaryBinding readTemporaryBinding = new TemporaryBinding(nameCleaner, globalVariables); - List archetypeParams = archetype.getParams(); - List instanceArguments = instance.getArguments(); - // initialization statements for parameters bound to expressions - List initStatements = new ArrayList<>(); - for (int i = 0; i < archetypeParams.size(); i++) { - PlusCalVariableDeclaration param = archetypeParams.get(i); - UID paramUID = param.getUID(); - TLAExpression value = instanceArguments.get(i); - params.put(paramUID, param); - if (value instanceof TLARef) { - recordMapping( - registry, mappedVars, paramUID, registry.followReference(value.getUID()), mappings, - functionMappedVars); - refs.add(paramUID); - arguments.put( - paramUID, - new TLAGeneralIdentifier( - value.getLocation(), - new TLAIdentifier( - value.getLocation(), - ((TLARef) value).getTarget()), - Collections.emptyList())); - } else if (value instanceof TLAGeneralIdentifier) { - recordMapping( - registry, mappedVars, paramUID, registry.followReference(value.getUID()), mappings, - functionMappedVars); - arguments.put(paramUID, (TLAGeneralIdentifier) value); - } else { - recordMapping(registry, mappedVars, paramUID, paramUID, mappings, functionMappedVars); - if (param.isRef()) { - refs.add(paramUID); - } - String nameHint = param.getName().getId() + "Local"; - // this argument is bound to a TLA+ expression, so we need to add a variable declaration for it - TLAGeneralIdentifier local; - if (value.accept( - new TLAExpressionParamsAccessCheckVisitor(registry, params, Collections.emptyMap()))) { - local = readTemporaryBinding.freshVariable(value.getLocation(), paramUID, nameHint); - localVariables.add(new PlusCalVariableDeclaration( - value.getLocation(), - new TLAIdentifier(value.getLocation(), local.getName().getId()), - false, - false, - new PlusCalDefaultInitValue(value.getLocation()))); - TLAGeneralIdentifier lhs = new TLAGeneralIdentifier( - param.getLocation(), - new TLAIdentifier(param.getLocation(), local.getName().getId()), - Collections.emptyList()); - initStatements.add(new PlusCalAssignment( - value.getLocation(), - Collections.singletonList(new PlusCalAssignmentPair(value.getLocation(),lhs, value)))); - } else { - local = readTemporaryBinding.freshVariable(value.getLocation(), paramUID, nameHint); - localVariables.add(new PlusCalVariableDeclaration( - value.getLocation(), new TLAIdentifier(value.getLocation(), local.getName().getId()), - false, false, value)); - } - arguments.put(paramUID, local); - readTemporaryBinding.reuse(paramUID); - expressionArguments.add(paramUID); - } - } - TemporaryBinding writeTemporaryBinding = new TemporaryBinding(nameCleaner, globalVariables); - ProcedureExpander procedureExpander = new ProcedureExpander( - ctx, registry, nameCleaner, procedureCache, arguments, mappings, refs, functionMappedVars, - procedures); - // initialize the local variables - ModularPlusCalCodeGenVisitor v = new ModularPlusCalCodeGenVisitor( - registry, params, arguments, mappings, expressionArguments, functionMappedVars, - readTemporaryBinding, writeTemporaryBinding, procedureExpander, - new TLAExpressionPlusCalCodeGenVisitor(registry, params, arguments, expressionArguments, mappings, - functionMappedVars, readTemporaryBinding, writeTemporaryBinding, procedureExpander, - Collections.emptyList())); - List body = new ArrayList<>(); - ProcedureExpander.initializeLocalVariables( - registry, archetype.getLocation(), params, archetype.getVariables(), - nameCleaner.cleanName("init"), v, localVariables, initStatements, body); - for (PlusCalStatement statement : archetype.getBody()) { - body.addAll(statement.accept(v)); - } - processList.add(new PlusCalProcess( - instance.getLocation(), instance.getName(), instance.getFairness(), localVariables, body)); - } - PlusCalProcesses processes = modularPlusCalBlock.getProcesses(); - if (processes instanceof PlusCalSingleProcess && processList.size() != 0) { - ctx.error(new UnsupportedFeatureIssue("single process with instances")); - } else if (processes instanceof PlusCalMultiProcess) { - processList.addAll(((PlusCalMultiProcess) processes).getProcesses()); - processes = new PlusCalMultiProcess(processes.getLocation(), processList); - } else { - throw new Unreachable(); - } - return new PlusCalAlgorithm( - modularPlusCalBlock.getLocation(), - PlusCalFairness.UNFAIR, - modularPlusCalBlock.getName(), - globalVariables, - Collections.emptyList(), - procedures, - modularPlusCalBlock.getUnits(), - processes); - } -} diff --git a/src/pgo/trans/passes/codegen/pluscal/PlusCalStatementNameCollectorVisitor.java b/src/pgo/trans/passes/codegen/pluscal/PlusCalStatementNameCollectorVisitor.java deleted file mode 100644 index de0ff0dec..000000000 --- a/src/pgo/trans/passes/codegen/pluscal/PlusCalStatementNameCollectorVisitor.java +++ /dev/null @@ -1,106 +0,0 @@ -package pgo.trans.passes.codegen.pluscal; - -import pgo.model.mpcal.ModularPlusCalYield; -import pgo.model.pcal.*; - -import java.util.Set; - -public class PlusCalStatementNameCollectorVisitor extends PlusCalStatementVisitor { - private final Set names; - - PlusCalStatementNameCollectorVisitor(Set names) { - this.names = names; - } - - @Override - public Void visit(PlusCalLabeledStatements plusCalLabeledStatements) throws RuntimeException { - plusCalLabeledStatements.getStatements().forEach(s -> s.accept(this)); - return null; - } - - @Override - public Void visit(PlusCalWhile plusCalWhile) throws RuntimeException { - plusCalWhile.getBody().forEach(s -> s.accept(this)); - return null; - } - - @Override - public Void visit(PlusCalIf plusCalIf) throws RuntimeException { - plusCalIf.getYes().forEach(s -> s.accept(this)); - plusCalIf.getNo().forEach(s -> s.accept(this)); - return null; - } - - @Override - public Void visit(PlusCalEither plusCalEither) throws RuntimeException { - // nothing to do - return null; - } - - @Override - public Void visit(PlusCalAssignment plusCalAssignment) throws RuntimeException { - // nothing to do - return null; - } - - @Override - public Void visit(PlusCalReturn plusCalReturn) throws RuntimeException { - // nothing to do - return null; - } - - @Override - public Void visit(PlusCalSkip plusCalSkip) throws RuntimeException { - // nothing to do - return null; - } - - @Override - public Void visit(PlusCalCall plusCalCall) throws RuntimeException { - // nothing to do - return null; - } - - @Override - public Void visit(PlusCalMacroCall macroCall) throws RuntimeException { - // nothing to do - return null; - } - - @Override - public Void visit(PlusCalWith plusCalWith) throws RuntimeException { - plusCalWith.getVariables().forEach(v -> names.add(v.getName().getId())); - plusCalWith.getBody().forEach(s -> s.accept(this)); - return null; - } - - @Override - public Void visit(PlusCalPrint plusCalPrint) throws RuntimeException { - // nothing to do - return null; - } - - @Override - public Void visit(PlusCalAssert plusCalAssert) throws RuntimeException { - // nothing to do - return null; - } - - @Override - public Void visit(PlusCalAwait plusCalAwait) throws RuntimeException { - // nothing to do - return null; - } - - @Override - public Void visit(PlusCalGoto plusCalGoto) throws RuntimeException { - // nothing to do - return null; - } - - @Override - public Void visit(ModularPlusCalYield modularPlusCalYield) throws RuntimeException { - // nothing to do - return null; - } -} diff --git a/src/pgo/trans/passes/codegen/pluscal/ProcedureExpander.java b/src/pgo/trans/passes/codegen/pluscal/ProcedureExpander.java deleted file mode 100644 index 382804225..000000000 --- a/src/pgo/trans/passes/codegen/pluscal/ProcedureExpander.java +++ /dev/null @@ -1,160 +0,0 @@ -package pgo.trans.passes.codegen.pluscal; - -import pgo.errors.IssueContext; -import pgo.model.mpcal.ModularPlusCalMappingMacro; -import pgo.model.pcal.*; -import pgo.model.tla.*; -import pgo.scope.UID; -import pgo.trans.intermediate.DefinitionRegistry; -import pgo.trans.passes.codegen.NameCleaner; -import pgo.util.SourceLocation; - -import java.util.*; - -class ProcedureExpander { - private final IssueContext ctx; - private final DefinitionRegistry registry; - private final NameCleaner nameCleaner; - private final Map procedureCache; - private final Map parentArguments; - private final Map parentMappings; - private final Set parentRefs; - private final Set parentFunctionMappedVars; - private final List procedures; - - ProcedureExpander(IssueContext ctx, DefinitionRegistry registry, NameCleaner nameCleaner, - Map procedureCache, - Map parentArguments, - Map parentMappings, Set parentRefs, - Set parentFunctionMappedVars, List procedures) { - this.ctx = ctx; - this.registry = registry; - this.nameCleaner = nameCleaner; - this.procedureCache = procedureCache; - this.parentArguments = parentArguments; - this.parentMappings = parentMappings; - this.parentRefs = parentRefs; - this.parentFunctionMappedVars = parentFunctionMappedVars; - this.procedures = procedures; - } - - static void initializeLocalVariables(DefinitionRegistry registry, SourceLocation location, - Map params, - List variables, String cleanedLabelName, - ModularPlusCalCodeGenVisitor visitor, - List outputVariables, - List initStatements, List output) { - Map variableMap = new HashMap<>(); - for (PlusCalVariableDeclaration variable : variables) { - variableMap.put(variable.getUID(), variable); - } - TLAExpressionParamsAccessCheckVisitor accessCheck = - new TLAExpressionParamsAccessCheckVisitor(registry, params, variableMap); - for (PlusCalVariableDeclaration variable : variables) { - if (variable.getValue() instanceof PlusCalDefaultInitValue || !variable.getValue().accept(accessCheck)) { - outputVariables.add(variable); - } else { - SourceLocation variableLocation = variable.getLocation(); - outputVariables.add(new PlusCalVariableDeclaration( - variableLocation, variable.getName(), variable.isRef(), variable.isSet(), - new PlusCalDefaultInitValue(variableLocation))); - TLAGeneralIdentifier lhs = new TLAGeneralIdentifier( - variableLocation, new TLAIdentifier(variableLocation, variable.getName().getId()), - Collections.emptyList()); - registry.getReferences().put(lhs.getUID(), variable.getUID()); - initStatements.add(new PlusCalAssignment( - variableLocation, - Collections.singletonList(new PlusCalAssignmentPair( - variableLocation, lhs, variable.getValue())))); - } - } - if (initStatements.size() > 0) { - output.addAll(new PlusCalLabeledStatements( - location, new PlusCalLabel(location, cleanedLabelName, PlusCalLabel.Modifier.NONE), - initStatements).accept(visitor)); - } - } - - private void update(UID paramUID, UID valueUID, Map arguments, - Map mappings, Set functionMappedVars) { - ModularPlusCalMappingMacro mappingMacro = parentMappings.get(valueUID); - if (mappingMacro != null) { - mappings.put(paramUID, mappingMacro); - } - if (parentFunctionMappedVars.contains(valueUID)) { - functionMappedVars.add(paramUID); - } - arguments.put(paramUID, parentArguments.get(valueUID)); - } - - PlusCalCall expand(PlusCalCall plusCalCall, TLAExpressionPlusCalCodeGenVisitor visitor) { - PlusCalProcedure procedure = registry.findProcedure(plusCalCall.getTarget()); - Map params = new HashMap<>(); - Map arguments = new LinkedHashMap<>(); - Set functionMappedVars = new HashSet<>(); - Map mappings = new HashMap<>(); - Set refs = new HashSet<>(); - List localVariables = new ArrayList<>(); - List actualParams = new ArrayList<>(); - List actualArguments = new ArrayList<>(); - List procedureParams = procedure.getParams(); - List callArguments = plusCalCall.getArguments(); - for (int i = 0; i < procedureParams.size(); i++) { - PlusCalVariableDeclaration param = procedureParams.get(i); - TLAExpression value = callArguments.get(i); - UID paramUID = param.getUID(); - if (value instanceof TLARef && !param.isRef()) { - ctx.error(new RefMismatchIssue(param, value)); - continue; - } else if (value instanceof TLARef) { - UID valueUID = registry.followReference(value.getUID()); - if (parentRefs.contains(valueUID)) { - refs.add(paramUID); - } - update(paramUID, valueUID, arguments, mappings, functionMappedVars); - } else if (value instanceof TLAGeneralIdentifier) { - UID valueUID = registry.followReference(value.getUID()); - if (!parentArguments.containsKey(valueUID)) { - actualParams.add(param); - actualArguments.add(value.accept(visitor)); - continue; - } - update(paramUID, valueUID, arguments, mappings, functionMappedVars); - } else { - actualParams.add(param); - actualArguments.add(value.accept(visitor)); - } - params.put(paramUID, param); - } - ExpandedProcedureMatch match = new ExpandedProcedureMatch( - procedure.getUID(), actualParams, arguments, mappings, refs, functionMappedVars); - String procedureName; - if (procedureCache.containsKey(match)) { - procedureName = procedureCache.get(match); - } else { - TemporaryBinding readTemporaryBinding = new TemporaryBinding(nameCleaner, localVariables); - TemporaryBinding writeTemporaryBinding = new TemporaryBinding(nameCleaner, localVariables); - ModularPlusCalCodeGenVisitor v = new ModularPlusCalCodeGenVisitor( - registry, params, arguments, mappings, Collections.emptySet(), functionMappedVars, - readTemporaryBinding, writeTemporaryBinding, - new ProcedureExpander( - ctx, registry, nameCleaner, procedureCache, arguments, mappings, refs, functionMappedVars, - procedures), - new TLAExpressionPlusCalCodeGenVisitor( - registry, params, arguments, Collections.emptySet(), mappings, functionMappedVars, - readTemporaryBinding, writeTemporaryBinding, this, Collections.emptyList())); - List body = new ArrayList<>(); - initializeLocalVariables( - registry, procedure.getLocation(), Collections.emptyMap(), procedure.getVariables(), - nameCleaner.cleanName("init"), v, localVariables, new ArrayList<>(), body); - for (PlusCalStatement statement : procedure.getBody()) { - body.addAll(statement.accept(v)); - } - procedureName = nameCleaner.cleanName(procedure.getName()); - procedures.add(new PlusCalProcedure( - procedure.getLocation(), procedureName, actualParams, localVariables, body)); - procedureCache.put(match, procedureName); - } - return new PlusCalCall(plusCalCall.getLocation(), procedureName, actualArguments); - } -} diff --git a/src/pgo/trans/passes/codegen/pluscal/RefMismatchIssue.java b/src/pgo/trans/passes/codegen/pluscal/RefMismatchIssue.java deleted file mode 100644 index f17b8bdfd..000000000 --- a/src/pgo/trans/passes/codegen/pluscal/RefMismatchIssue.java +++ /dev/null @@ -1,29 +0,0 @@ -package pgo.trans.passes.codegen.pluscal; - -import pgo.errors.Issue; -import pgo.errors.IssueVisitor; -import pgo.model.pcal.PlusCalVariableDeclaration; -import pgo.model.tla.TLAExpression; - -public class RefMismatchIssue extends Issue { - private final PlusCalVariableDeclaration param; - private final TLAExpression value; - - public RefMismatchIssue(PlusCalVariableDeclaration param, TLAExpression value) { - this.param = param; - this.value = value; - } - - @Override - public T accept(IssueVisitor v) throws E { - return v.visit(this); - } - - public PlusCalVariableDeclaration getParam() { - return param; - } - - public TLAExpression getValue() { - return value; - } -} diff --git a/src/pgo/trans/passes/codegen/pluscal/TLAExpressionMappingMacroReadExpansionVisitor.java b/src/pgo/trans/passes/codegen/pluscal/TLAExpressionMappingMacroReadExpansionVisitor.java deleted file mode 100644 index 6d489d77e..000000000 --- a/src/pgo/trans/passes/codegen/pluscal/TLAExpressionMappingMacroReadExpansionVisitor.java +++ /dev/null @@ -1,87 +0,0 @@ -package pgo.trans.passes.codegen.pluscal; - -import pgo.model.mpcal.ModularPlusCalMappingMacro; -import pgo.model.pcal.PlusCalStatement; -import pgo.model.pcal.PlusCalVariableDeclaration; -import pgo.model.tla.*; -import pgo.scope.UID; -import pgo.trans.intermediate.DefinitionRegistry; - -import java.util.*; - -public class TLAExpressionMappingMacroReadExpansionVisitor extends TLAExpressionPlusCalCodeGenVisitor { - protected final TLAGeneralIdentifier dollarVariable; - protected final UID varUID; - protected final TLAExpression index; - - TLAExpressionMappingMacroReadExpansionVisitor( - DefinitionRegistry registry, Map params, - Map arguments, Set expressionArguments, - Map mappings, Set functionMappedVars, - TemporaryBinding readTemporaryBinding, TemporaryBinding writeTemporaryBinding, - ProcedureExpander procedureExpander, List output, TLAGeneralIdentifier dollarVariable, - UID varUID, TLAExpression index) { - super( - registry, params, arguments, expressionArguments, mappings, functionMappedVars, readTemporaryBinding, - writeTemporaryBinding, procedureExpander, output); - this.dollarVariable = dollarVariable; - this.varUID = varUID; - this.index = index; - } - - @Override - public TLAExpressionMappingMacroReadExpansionVisitor createWith(List output) { - return new TLAExpressionMappingMacroReadExpansionVisitor( - registry, params, arguments, expressionArguments, mappings, functionMappedVars, readTemporaryBinding, - writeTemporaryBinding, procedureExpander, output, dollarVariable, varUID, index); - } - - private List substituteExpressions(List expressions) { - List result = new ArrayList<>(); - for (TLAExpression expression : expressions) { - result.add(expression.accept(this)); - } - return result; - } - - @Override - public TLAExpression visit(TLAFunctionCall tlaFunctionCall) throws RuntimeException { - return new TLAFunctionCall( - tlaFunctionCall.getLocation(), - tlaFunctionCall.getFunction().accept(this), - substituteExpressions(tlaFunctionCall.getParams())); - } - - @Override - public TLAExpression visit(TLAIf tlaIf) throws RuntimeException { - return new TLAIf( - tlaIf.getLocation(), - tlaIf.getCond().accept(this), - tlaIf.getTval().accept(this), - tlaIf.getFval().accept(this)); - } - - @Override - public TLAExpression visit(TLAGeneralIdentifier tlaGeneralIdentifier) throws RuntimeException { - return readTemporaryBinding - .lookup(registry.followReference(tlaGeneralIdentifier.getUID())) - .orElse(tlaGeneralIdentifier); - } - - @Override - public TLAExpression visit(TLASpecialVariableVariable tlaSpecialVariableVariable) throws RuntimeException { - Optional optionalResult = writeTemporaryBinding.lookup(varUID); - if (optionalResult.isPresent() && index != null) { - return new TLAFunctionCall( - tlaSpecialVariableVariable.getLocation(), optionalResult.get(), Collections.singletonList(index)); - } - if (optionalResult.isPresent()) { - return optionalResult.get(); - } - if (index != null) { - return new TLAFunctionCall( - tlaSpecialVariableVariable.getLocation(), dollarVariable, Collections.singletonList(index)); - } - return dollarVariable; - } -} diff --git a/src/pgo/trans/passes/codegen/pluscal/TLAExpressionMappingMacroWriteExpansionVisitor.java b/src/pgo/trans/passes/codegen/pluscal/TLAExpressionMappingMacroWriteExpansionVisitor.java deleted file mode 100644 index b963a3b92..000000000 --- a/src/pgo/trans/passes/codegen/pluscal/TLAExpressionMappingMacroWriteExpansionVisitor.java +++ /dev/null @@ -1,43 +0,0 @@ -package pgo.trans.passes.codegen.pluscal; - -import pgo.model.mpcal.ModularPlusCalMappingMacro; -import pgo.model.pcal.PlusCalStatement; -import pgo.model.pcal.PlusCalVariableDeclaration; -import pgo.model.tla.TLAExpression; -import pgo.model.tla.TLAGeneralIdentifier; -import pgo.model.tla.TLASpecialVariableValue; -import pgo.scope.UID; -import pgo.trans.intermediate.DefinitionRegistry; - -import java.util.List; -import java.util.Map; -import java.util.Set; - -public class TLAExpressionMappingMacroWriteExpansionVisitor extends TLAExpressionMappingMacroReadExpansionVisitor { - private final TLAExpression dollarValue; - - TLAExpressionMappingMacroWriteExpansionVisitor( - DefinitionRegistry registry, Map params, - Map arguments, Set expressionArguments, - Map mappings, Set functionMappedVars, - TemporaryBinding readTemporaryBinding, TemporaryBinding writeTemporaryBinding, - ProcedureExpander procedureExpander, List output, TLAGeneralIdentifier dollarVariable, - TLAExpression dollarValue, UID varUID, TLAExpression index) { - super( - registry, params, arguments, expressionArguments, mappings, functionMappedVars, readTemporaryBinding, - writeTemporaryBinding, procedureExpander, output, dollarVariable, varUID, index); - this.dollarValue = dollarValue; - } - - @Override - public TLAExpressionMappingMacroWriteExpansionVisitor createWith(List output) { - return new TLAExpressionMappingMacroWriteExpansionVisitor( - registry, params, arguments, expressionArguments, mappings, functionMappedVars, readTemporaryBinding, - writeTemporaryBinding, procedureExpander, output, dollarVariable, dollarValue, varUID, index); - } - - @Override - public TLAExpression visit(TLASpecialVariableValue tlaSpecialVariableValue) { - return dollarValue; - } -} diff --git a/src/pgo/trans/passes/codegen/pluscal/TLAExpressionParamsAccessCheckVisitor.java b/src/pgo/trans/passes/codegen/pluscal/TLAExpressionParamsAccessCheckVisitor.java deleted file mode 100644 index 02020cc6b..000000000 --- a/src/pgo/trans/passes/codegen/pluscal/TLAExpressionParamsAccessCheckVisitor.java +++ /dev/null @@ -1,204 +0,0 @@ -package pgo.trans.passes.codegen.pluscal; - -import pgo.TODO; -import pgo.Unreachable; -import pgo.model.pcal.PlusCalVariableDeclaration; -import pgo.model.tla.*; -import pgo.scope.UID; -import pgo.trans.intermediate.DefinitionRegistry; - -import java.util.Map; - -public class TLAExpressionParamsAccessCheckVisitor extends TLAExpressionVisitor { - private final DefinitionRegistry registry; - private final Map params; - private final Map variables; - - public TLAExpressionParamsAccessCheckVisitor(DefinitionRegistry registry, - Map params, - Map variables) { - this.registry = registry; - this.params = params; - this.variables = variables; - } - - @Override - public Boolean visit(TLAFunctionCall tlaFunctionCall) throws RuntimeException { - return tlaFunctionCall.getFunction().accept(this) || - tlaFunctionCall.getParams().stream().anyMatch(a -> a.accept(this)); - } - - @Override - public Boolean visit(TLABinOp tlaBinOp) throws RuntimeException { - return tlaBinOp.getLHS().accept(this) || tlaBinOp.getRHS().accept(this); - } - - @Override - public Boolean visit(TLABool tlaBool) throws RuntimeException { - return false; - } - - @Override - public Boolean visit(TLACase tlaCase) throws RuntimeException { - return tlaCase.getArms() - .stream() - .anyMatch(a -> a.getCondition().accept(this) || a.getResult().accept(this)) || - (tlaCase.getOther() != null && tlaCase.getOther().accept(this)); - } - - @Override - public Boolean visit(TLADot tlaDot) throws RuntimeException { - return tlaDot.getExpression().accept(this); - } - - @Override - public Boolean visit(TLAExistential tlaExistential) throws RuntimeException { - return tlaExistential.getBody().accept(this); - } - - @Override - public Boolean visit(TLAFunction tlaFunction) throws RuntimeException { - return tlaFunction.getArguments().stream().anyMatch(p -> p.getSet().accept(this)) || - tlaFunction.getBody().accept(this); - } - - @Override - public Boolean visit(TLAFunctionSet tlaFunctionSet) throws RuntimeException { - return tlaFunctionSet.getFrom().accept(this) || tlaFunctionSet.getTo().accept(this); - } - - @Override - public Boolean visit(TLAFunctionSubstitution tlaFunctionSubstitution) throws RuntimeException { - return tlaFunctionSubstitution.getSource().accept(this) || - tlaFunctionSubstitution.getSubstitutions().stream().anyMatch(p -> - p.getValue().accept(this) || - p.getKeys().stream().anyMatch(k -> - k.getIndices() - .stream().anyMatch(i -> i.accept(this)))); - } - - @Override - public Boolean visit(TLAIf tlaIf) throws RuntimeException { - return tlaIf.getCond().accept(this) || tlaIf.getTval().accept(this) || tlaIf.getFval().accept(this); - } - - @Override - public Boolean visit(TLALet tlaLet) throws RuntimeException { - throw new TODO(); - } - - @Override - public Boolean visit(TLAGeneralIdentifier tlaGeneralIdentifier) throws RuntimeException { - UID varUID = registry.followReference(tlaGeneralIdentifier.getUID()); - if (params.containsKey(varUID)) { - return true; - } - if (variables.containsKey(varUID)) { - return variables.get(varUID).getValue().accept(this); - } - return false; - } - - @Override - public Boolean visit(TLATuple tlaTuple) throws RuntimeException { - return tlaTuple.getElements().stream().anyMatch(e -> e.accept(this)); - } - - @Override - public Boolean visit(TLAMaybeAction tlaMaybeAction) throws RuntimeException { - return tlaMaybeAction.getVars().accept(this) || tlaMaybeAction.getBody().accept(this); - } - - @Override - public Boolean visit(TLANumber tlaNumber) throws RuntimeException { - return false; - } - - @Override - public Boolean visit(TLAOperatorCall tlaOperatorCall) throws RuntimeException { - return tlaOperatorCall.getArgs().stream().anyMatch(a -> a.accept(this)); - } - - @Override - public Boolean visit(TLAQuantifiedExistential tlaQuantifiedExistential) throws RuntimeException { - return tlaQuantifiedExistential.getIds().stream().anyMatch(b -> b.getSet().accept(this)) || - tlaQuantifiedExistential.getBody().accept(this); - } - - @Override - public Boolean visit(TLAQuantifiedUniversal tlaQuantifiedUniversal) throws RuntimeException { - return tlaQuantifiedUniversal.getIds().stream().anyMatch(b -> b.getSet().accept(this)) || - tlaQuantifiedUniversal.getBody().accept(this); - } - - @Override - public Boolean visit(TLARecordConstructor tlaRecordConstructor) throws RuntimeException { - return tlaRecordConstructor.getFields().stream().anyMatch(f -> f.getValue().accept(this)); - } - - @Override - public Boolean visit(TLARecordSet tlaRecordSet) throws RuntimeException { - return tlaRecordSet.getFields().stream().anyMatch(f -> f.getSet().accept(this)); - } - - @Override - public Boolean visit(TLARequiredAction tlaRequiredAction) throws RuntimeException { - return tlaRequiredAction.getVars().accept(this) || tlaRequiredAction.getBody().accept(this); - } - - @Override - public Boolean visit(TLASetConstructor tlaSetConstructor) throws RuntimeException { - return tlaSetConstructor.getContents().stream().anyMatch(c -> c.accept(this)); - } - - @Override - public Boolean visit(TLASetComprehension tlaSetComprehension) throws RuntimeException { - return tlaSetComprehension.getBounds().stream().anyMatch(b -> b.getSet().accept(this)) || - tlaSetComprehension.getBody().accept(this); - } - - @Override - public Boolean visit(TLASetRefinement tlaSetRefinement) throws RuntimeException { - return tlaSetRefinement.getWhen().accept(this) || tlaSetRefinement.getFrom().accept(this); - } - - @Override - public Boolean visit(TLAString tlaString) throws RuntimeException { - return false; - } - - @Override - public Boolean visit(TLAUnary tlaUnary) throws RuntimeException { - return tlaUnary.getOperand().accept(this); - } - - @Override - public Boolean visit(TLAUniversal tlaUniversal) throws RuntimeException { - return tlaUniversal.getBody().accept(this); - } - - @Override - public Boolean visit(PlusCalDefaultInitValue plusCalDefaultInitValue) throws RuntimeException { - return false; - } - - @Override - public Boolean visit(TLAFairness tlaFairness) throws RuntimeException { - return false; - } - - @Override - public Boolean visit(TLASpecialVariableVariable tlaSpecialVariableVariable) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Boolean visit(TLASpecialVariableValue tlaSpecialVariableValue) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Boolean visit(TLARef tlaRef) throws RuntimeException { - throw new Unreachable(); - } -} diff --git a/src/pgo/trans/passes/codegen/pluscal/TLAExpressionPlusCalCodeGenVisitor.java b/src/pgo/trans/passes/codegen/pluscal/TLAExpressionPlusCalCodeGenVisitor.java deleted file mode 100644 index 6dcae16af..000000000 --- a/src/pgo/trans/passes/codegen/pluscal/TLAExpressionPlusCalCodeGenVisitor.java +++ /dev/null @@ -1,445 +0,0 @@ -package pgo.trans.passes.codegen.pluscal; - -import pgo.TODO; -import pgo.Unreachable; -import pgo.model.mpcal.ModularPlusCalMappingMacro; -import pgo.model.pcal.*; -import pgo.model.tla.*; -import pgo.scope.UID; -import pgo.trans.intermediate.DefinitionRegistry; -import pgo.util.SourceLocation; - -import java.util.*; - -public class TLAExpressionPlusCalCodeGenVisitor extends TLAExpressionVisitor { - protected final DefinitionRegistry registry; - protected final Map params; - protected final Map arguments; - protected final Set expressionArguments; - protected final Map mappings; - protected final Set functionMappedVars; - protected final TemporaryBinding readTemporaryBinding; - protected final TemporaryBinding writeTemporaryBinding; - protected final ProcedureExpander procedureExpander; - private final List output; - - TLAExpressionPlusCalCodeGenVisitor(DefinitionRegistry registry, Map params, - Map arguments, Set expressionArguments, - Map mappings, Set functionMappedVars, - TemporaryBinding readTemporaryBinding, TemporaryBinding writeTemporaryBinding, - ProcedureExpander procedureExpander, List output) { - this.registry = registry; - this.params = params; - this.arguments = arguments; - this.expressionArguments = expressionArguments; - this.mappings = mappings; - this.functionMappedVars = functionMappedVars; - this.readTemporaryBinding = readTemporaryBinding; - this.writeTemporaryBinding = writeTemporaryBinding; - this.procedureExpander = procedureExpander; - this.output = output; - } - - public TLAExpressionPlusCalCodeGenVisitor createWith(List output) { - return new TLAExpressionPlusCalCodeGenVisitor( - registry, params, arguments, expressionArguments, mappings, functionMappedVars, readTemporaryBinding, - writeTemporaryBinding, procedureExpander, output); - } - - static Optional extractFunctionCallIdentifier(TLAFunctionCall fnCall, - List accumulatedIndices) { - SourceLocation location = fnCall.getLocation(); - TLAExpression fn = fnCall.getFunction(); - List fnParams = fnCall.getParams(); - if (fnParams.size() > 1) { - accumulatedIndices.add(new TLATuple(location, fnParams)); - } else if (fnParams.size() == 1) { - accumulatedIndices.add(fnParams.get(0)); - } else { - accumulatedIndices.add(new TLATuple(location, Collections.emptyList())); - } - if (fn instanceof TLAGeneralIdentifier) { - int size = accumulatedIndices.size(); - for (int i = 0; i < size; i++) { - TLAExpression temp = accumulatedIndices.set(i, accumulatedIndices.get(size - i - 1)); - accumulatedIndices.set(size - i - 1, temp); - } - return Optional.of((TLAGeneralIdentifier) fn); - } - if (fn instanceof TLAFunctionCall) { - return extractFunctionCallIdentifier((TLAFunctionCall) fn, accumulatedIndices); - } - accumulatedIndices.clear(); - return Optional.empty(); - } - - private void substituteReadBody(TLAGeneralIdentifier temp, TLAGeneralIdentifier dollarVariable, UID varUID, - TLAExpression index) { - ModularPlusCalMappingMacroReadExpansionVisitor visitor = - new ModularPlusCalMappingMacroReadExpansionVisitor( - registry, params, arguments, mappings, expressionArguments, functionMappedVars, - readTemporaryBinding, writeTemporaryBinding, procedureExpander, dollarVariable, varUID, - params.get(varUID).getName().getId() + "Write", index, - new TLAExpressionMappingMacroReadExpansionVisitor( - registry, params, arguments, expressionArguments, mappings, functionMappedVars, - readTemporaryBinding, writeTemporaryBinding, procedureExpander, output, dollarVariable, - varUID, index), - temp); - for (PlusCalStatement statement : mappings.get(varUID).getReadBody()) { - output.addAll(statement.accept(visitor)); - } - } - - @Override - public TLAExpression visit(TLAFunctionCall tlaFunctionCall) throws RuntimeException { - List accumulatedIndices = new ArrayList<>(); - Optional optionalVariable = extractFunctionCallIdentifier( - tlaFunctionCall, accumulatedIndices); - if (optionalVariable.isPresent()) { - TLAGeneralIdentifier variable = optionalVariable.get(); - UID varUID = registry.followReference(variable.getUID()); - if (functionMappedVars.contains(varUID)) { - for (int j = accumulatedIndices.size() - 1; j >= 0; j--) { - accumulatedIndices.set(j, accumulatedIndices.get(j).accept(this)); - } - TLAExpression index = accumulatedIndices.get(0); - accumulatedIndices = accumulatedIndices.subList(1, accumulatedIndices.size()); - TLAGeneralIdentifier temp = readTemporaryBinding.declare( - variable.getLocation(), - varUID, - params.get(varUID).getName().getId() + "Read"); - substituteReadBody(temp, arguments.get(varUID), varUID, index); - if (accumulatedIndices.size() > 0) { - return new TLAFunctionCall(tlaFunctionCall.getLocation(), temp, accumulatedIndices); - } - return temp; - } - } - List arguments = new ArrayList<>(); - for (TLAExpression argument : tlaFunctionCall.getParams()) { - arguments.add(argument.accept(this)); - } - return new TLAFunctionCall( - tlaFunctionCall.getLocation(), tlaFunctionCall.getFunction().accept(this), arguments); - } - - @Override - public TLAExpression visit(TLABinOp tlaBinOp) throws RuntimeException { - return new TLABinOp( - tlaBinOp.getLocation(), - tlaBinOp.getOperation(), - tlaBinOp.getPrefix(), - tlaBinOp.getLHS().accept(this), - tlaBinOp.getRHS().accept(this)); - } - - @Override - public TLAExpression visit(TLABool tlaBool) throws RuntimeException { - return tlaBool.copy(); - } - - @Override - public TLAExpression visit(TLACase tlaCase) throws RuntimeException { - // translated as nested ifs - TLAGeneralIdentifier caseResult = readTemporaryBinding.declare(tlaCase.getLocation(), new UID(), "caseResult"); - List currentBlock = output; - for (TLACaseArm arm : tlaCase.getArms()) { - TLAExpression condition = arm.getCondition().accept(new TLAExpressionPlusCalCodeGenVisitor( - registry, params, arguments, expressionArguments, mappings, functionMappedVars, - readTemporaryBinding, writeTemporaryBinding, procedureExpander, currentBlock)); - List yes = new ArrayList<>(); - List no = new ArrayList<>(); - TLAExpression result = arm.getResult().accept(new TLAExpressionPlusCalCodeGenVisitor( - registry, params, arguments, expressionArguments, mappings, functionMappedVars, - readTemporaryBinding, writeTemporaryBinding, procedureExpander, yes)); - yes.add(new PlusCalAssignment( - arm.getResult().getLocation(), - Collections.singletonList(new PlusCalAssignmentPair( - arm.getResult().getLocation(), caseResult, result)))); - currentBlock.add(new PlusCalIf(arm.getLocation(), condition, yes, no)); - currentBlock = no; - } - if (tlaCase.getOther() == null) { - currentBlock.add(new PlusCalAssert(tlaCase.getLocation(), new TLABool(tlaCase.getLocation(), false))); - } else { - TLAExpression other = tlaCase.getOther().accept(new TLAExpressionPlusCalCodeGenVisitor( - registry, params, arguments, expressionArguments, mappings, functionMappedVars, - readTemporaryBinding, writeTemporaryBinding, procedureExpander, currentBlock)); - currentBlock.add(new PlusCalAssignment( - tlaCase.getOther().getLocation(), - Collections.singletonList(new PlusCalAssignmentPair( - tlaCase.getOther().getLocation(), caseResult, other)))); - } - return caseResult; - } - - @Override - public TLAExpression visit(TLADot tlaDot) throws RuntimeException { - return new TLADot(tlaDot.getLocation(), tlaDot.getExpression().accept(this), tlaDot.getField()); - } - - @Override - public TLAExpression visit(TLAExistential tlaExistential) throws RuntimeException { - return new TLAExistential( - tlaExistential.getLocation(), - tlaExistential.getIds(), - tlaExistential.getBody().accept(this)); - } - - private List transformBounds(List bounds) { - List result = new ArrayList<>(); - for (TLAQuantifierBound bound : bounds) { - result.add(new TLAQuantifierBound( - bound.getLocation(), - bound.getType(), - bound.getIds(), - bound.getSet().accept(this))); - } - return result; - } - - @Override - public TLAExpression visit(TLAFunction tlaFunction) throws RuntimeException { - return new TLAFunction( - tlaFunction.getLocation(), - transformBounds(tlaFunction.getArguments()), - tlaFunction.getBody().accept(this)); - } - - @Override - public TLAExpression visit(TLAFunctionSet tlaFunctionSet) throws RuntimeException { - return new TLAFunctionSet( - tlaFunctionSet.getLocation(), - tlaFunctionSet.getFrom().accept(this), - tlaFunctionSet.getTo().accept(this)); - } - - @Override - public TLAExpression visit(TLAFunctionSubstitution tlaFunctionSubstitution) throws RuntimeException { - List pairs = new ArrayList<>(); - for (TLAFunctionSubstitutionPair substitution : tlaFunctionSubstitution.getSubstitutions()) { - List keys = new ArrayList<>(); - for (TLASubstitutionKey key : substitution.getKeys()) { - List indices = new ArrayList<>(); - for (TLAExpression index : key.getIndices()) { - indices.add(index.accept(this)); - } - keys.add(new TLASubstitutionKey(key.getLocation(), indices)); - } - pairs.add(new TLAFunctionSubstitutionPair( - substitution.getLocation(), - keys, - substitution.getValue().accept(this))); - } - return new TLAFunctionSubstitution( - tlaFunctionSubstitution.getLocation(), - tlaFunctionSubstitution.getSource().accept(this), - pairs); - } - - @Override - public TLAExpression visit(TLAIf tlaIf) throws RuntimeException { - TLAGeneralIdentifier ifResult = readTemporaryBinding.declare(tlaIf.getLocation(), new UID(), "ifResult"); - TLAExpression condition = tlaIf.getCond().accept(this); - List yes = new ArrayList<>(); - TLAExpression yesResult = tlaIf.getTval().accept(new TLAExpressionPlusCalCodeGenVisitor( - registry, params, arguments, expressionArguments, mappings, functionMappedVars, readTemporaryBinding, - writeTemporaryBinding, procedureExpander, yes)); - yes.add(new PlusCalAssignment( - tlaIf.getTval().getLocation(), - Collections.singletonList(new PlusCalAssignmentPair( - tlaIf.getTval().getLocation(), ifResult, yesResult)))); - List no = new ArrayList<>(); - TLAExpression noResult = tlaIf.getFval().accept(new TLAExpressionPlusCalCodeGenVisitor( - registry, params, arguments, expressionArguments, mappings, functionMappedVars, readTemporaryBinding, - writeTemporaryBinding, procedureExpander, no)); - no.add(new PlusCalAssignment( - tlaIf.getFval().getLocation(), - Collections.singletonList(new PlusCalAssignmentPair( - tlaIf.getFval().getLocation(), ifResult, noResult)))); - output.add(new PlusCalIf(tlaIf.getLocation(), condition, yes, no)); - return ifResult; - } - - @Override - public TLAExpression visit(TLALet tlaLet) throws RuntimeException { - throw new TODO(); - } - - @Override - public TLAExpression visit(TLAGeneralIdentifier tlaGeneralIdentifier) throws RuntimeException { - SourceLocation location = tlaGeneralIdentifier.getLocation(); - UID varUID = registry.followReference(tlaGeneralIdentifier.getUID()); - if (arguments.containsKey(varUID)) { - TLAGeneralIdentifier dollarVariable = arguments.get(varUID); - TLAGeneralIdentifier temp = readTemporaryBinding.declare( - location, - varUID, - params.get(varUID).getName().getId() + "Read"); - if (mappings.containsKey(varUID)) { - substituteReadBody(temp, dollarVariable, varUID, null); - } else { - output.add(new PlusCalAssignment( - location, - Collections.singletonList(new PlusCalAssignmentPair( - location, temp, writeTemporaryBinding.lookup(varUID).orElse(dollarVariable))))); - } - return temp; - } - return readTemporaryBinding.lookup(varUID).orElse(tlaGeneralIdentifier); - } - - @Override - public TLAExpression visit(TLATuple tlaTuple) throws RuntimeException { - List elements = new ArrayList<>(); - for (TLAExpression expression : tlaTuple.getElements()) { - elements.add(expression.accept(this)); - } - return new TLATuple(tlaTuple.getLocation(), elements); - } - - @Override - public TLAExpression visit(TLAMaybeAction tlaMaybeAction) throws RuntimeException { - return new TLAMaybeAction( - tlaMaybeAction.getLocation(), - tlaMaybeAction.getBody().accept(this), - tlaMaybeAction.getVars().accept(this)); - } - - @Override - public TLAExpression visit(TLANumber tlaNumber) throws RuntimeException { - return tlaNumber.copy(); - } - - @Override - public TLAExpression visit(TLAOperatorCall tlaOperatorCall) throws RuntimeException { - List arguments = new ArrayList<>(); - for (TLAExpression argument : tlaOperatorCall.getArgs()) { - arguments.add(argument.accept(this)); - } - return new TLAOperatorCall( - tlaOperatorCall.getLocation(), - tlaOperatorCall.getName(), - tlaOperatorCall.getPrefix(), - arguments); - } - - @Override - public TLAExpression visit(TLAQuantifiedExistential tlaQuantifiedExistential) throws RuntimeException { - return new TLAQuantifiedExistential( - tlaQuantifiedExistential.getLocation(), - transformBounds(tlaQuantifiedExistential.getIds()), - tlaQuantifiedExistential.getBody().accept(this)); - } - - @Override - public TLAExpression visit(TLAQuantifiedUniversal tlaQuantifiedUniversal) throws RuntimeException { - return new TLAQuantifiedUniversal( - tlaQuantifiedUniversal.getLocation(), - transformBounds(tlaQuantifiedUniversal.getIds()), - tlaQuantifiedUniversal.getBody().accept(this)); - } - - @Override - public TLAExpression visit(TLARecordConstructor tlaRecordConstructor) throws RuntimeException { - List fields = new ArrayList<>(); - for (TLARecordConstructor.Field field : tlaRecordConstructor.getFields()) { - fields.add(new TLARecordConstructor.Field( - field.getLocation(), field.getName(), field.getValue().accept(this))); - } - return new TLARecordConstructor(tlaRecordConstructor.getLocation(), fields); - } - - @Override - public TLAExpression visit(TLARecordSet tlaRecordSet) throws RuntimeException { - List fields = new ArrayList<>(); - for (TLARecordSet.Field field : tlaRecordSet.getFields()) { - fields.add(new TLARecordSet.Field(field.getLocation(), field.getName(), field.getSet().accept(this))); - } - return new TLARecordSet(tlaRecordSet.getLocation(), fields); - } - - @Override - public TLAExpression visit(TLARequiredAction tlaRequiredAction) throws RuntimeException { - return new TLARequiredAction( - tlaRequiredAction.getLocation(), - tlaRequiredAction.getBody().accept(this), - tlaRequiredAction.getVars().accept(this)); - } - - @Override - public TLAExpression visit(TLASetConstructor tlaSetConstructor) throws RuntimeException { - List contents = new ArrayList<>(); - for (TLAExpression expression : tlaSetConstructor.getContents()) { - contents.add(expression.accept(this)); - } - return new TLASetConstructor(tlaSetConstructor.getLocation(), contents); - } - - @Override - public TLAExpression visit(TLASetComprehension tlaSetComprehension) throws RuntimeException { - return new TLASetComprehension( - tlaSetComprehension.getLocation(), - tlaSetComprehension.getBody().accept(this), - transformBounds(tlaSetComprehension.getBounds())); - } - - @Override - public TLAExpression visit(TLASetRefinement tlaSetRefinement) throws RuntimeException { - return new TLASetRefinement( - tlaSetRefinement.getLocation(), - new TLAQuantifierBound( - tlaSetRefinement.getBinding().getLocation(), - tlaSetRefinement.getBinding().getType(), - tlaSetRefinement.getBinding().getIds(), - tlaSetRefinement.getBinding().getSet().accept(this)), - tlaSetRefinement.getWhen().accept(this)); - } - - @Override - public TLAExpression visit(TLAString tlaString) throws RuntimeException { - return tlaString.copy(); - } - - @Override - public TLAExpression visit(TLAUnary tlaUnary) throws RuntimeException { - return new TLAUnary( - tlaUnary.getLocation(), - tlaUnary.getOperation(), - tlaUnary.getPrefix(), - tlaUnary.getOperand().accept(this)); - } - - @Override - public TLAExpression visit(TLAUniversal tlaUniversal) throws RuntimeException { - return new TLAUniversal( - tlaUniversal.getLocation(), - tlaUniversal.getIds(), - tlaUniversal.getBody().accept(this)); - } - - @Override - public TLAExpression visit(PlusCalDefaultInitValue plusCalDefaultInitValue) throws RuntimeException { - return plusCalDefaultInitValue.copy(); - } - - @Override - public TLAExpression visit(TLAFairness tlaFairness) throws RuntimeException { - throw new TODO(); - } - - @Override - public TLAExpression visit(TLASpecialVariableVariable tlaSpecialVariableVariable) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public TLAExpression visit(TLASpecialVariableValue tlaSpecialVariableValue) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public TLAExpression visit(TLARef tlaRef) throws RuntimeException { - throw new Unreachable(); - } -} diff --git a/src/pgo/trans/passes/codegen/pluscal/TemporaryBinding.java b/src/pgo/trans/passes/codegen/pluscal/TemporaryBinding.java deleted file mode 100644 index af44fe90e..000000000 --- a/src/pgo/trans/passes/codegen/pluscal/TemporaryBinding.java +++ /dev/null @@ -1,136 +0,0 @@ -package pgo.trans.passes.codegen.pluscal; - -import pgo.InternalCompilerError; -import pgo.model.pcal.PlusCalVariableDeclaration; -import pgo.model.tla.PlusCalDefaultInitValue; -import pgo.model.tla.TLAExpression; -import pgo.model.tla.TLAGeneralIdentifier; -import pgo.model.tla.TLAIdentifier; -import pgo.scope.UID; -import pgo.trans.passes.codegen.NameCleaner; -import pgo.trans.passes.codegen.Recycling; -import pgo.util.SourceLocation; - -import java.util.*; - -public class TemporaryBinding { - public static class Checkpoint { - private final TemporaryBinding from; - private final Map> checkpoints; - - private Checkpoint(TemporaryBinding from, Map> temporaries) { - this.from = from; - this.checkpoints = new HashMap<>(); - temporaries.forEach((k, v) -> this.checkpoints.put(k, v.checkpoint())); - } - } - - private final NameCleaner nameCleaner; - private final Map> temporaries; - private final List declarations; - private final ArrayDeque> touchedVarsStack; - private LinkedHashMap touchedVars; - - public TemporaryBinding(NameCleaner nameCleaner, List declarations) { - this.nameCleaner = nameCleaner; - this.temporaries = new HashMap<>(); - this.declarations = declarations; - this.touchedVarsStack = new ArrayDeque<>(); - this.touchedVarsStack.push(new LinkedHashMap<>()); - this.touchedVars = touchedVarsStack.peek(); - } - - public Checkpoint checkpoint() { - return new Checkpoint(this, temporaries); - } - - public void restore(Checkpoint checkpoint) { - if (checkpoint.from != this) { - throw new InternalCompilerError(); - } - temporaries.forEach((k, v) -> { - if (checkpoint.checkpoints.containsKey(k)) { - v.restore(checkpoint.checkpoints.get(k)); - } else { - v.reuse(); - } - }); - } - - public TLAGeneralIdentifier freshVariable(SourceLocation location, UID varUID, String nameHint) { - String uniqueName = nameCleaner.cleanName(nameHint); - TLAGeneralIdentifier variableReference = new TLAGeneralIdentifier( - location, - new TLAIdentifier(location, uniqueName), - Collections.emptyList()); - if (temporaries.containsKey(varUID)) { - temporaries.get(varUID).add(variableReference); - } else { - temporaries.put(varUID, new Recycling<>(variableReference)); - } - return variableReference; - } - - public TLAGeneralIdentifier forceDeclare(SourceLocation location, UID varUID, String nameHint, - TLAExpression value) { - TLAGeneralIdentifier fresh = freshVariable(location, varUID, nameHint); - PlusCalVariableDeclaration declaration = new PlusCalVariableDeclaration( - location, new TLAIdentifier(location, fresh.getName().getId()), false, false, value); - declarations.add(declaration); - if (touchedVarsStack.size() > 1) { - touchedVars.put(varUID, fresh); - } - return fresh; - } - - public TLAGeneralIdentifier forceDeclare(SourceLocation location, UID varUID, String nameHint) { - return forceDeclare(location, varUID, nameHint, new PlusCalDefaultInitValue(location)); - } - - public TLAGeneralIdentifier declare(SourceLocation location, UID varUID, String nameHint, TLAExpression value) { - if (temporaries.containsKey(varUID)) { - Optional optionalResult = temporaries.get(varUID).use(); - if (optionalResult.isPresent()) { - if (touchedVarsStack.size() > 1) { - touchedVars.put(varUID, optionalResult.get()); - } - return optionalResult.get(); - } - return forceDeclare(location, varUID, nameHint, value); - } - return forceDeclare(location, varUID, nameHint, value); - } - - public TLAGeneralIdentifier declare(SourceLocation location, UID varUID, String nameHint) { - return declare(location, varUID, nameHint, new PlusCalDefaultInitValue(location)); - } - - public Optional lookup(UID varUID) { - return Optional.ofNullable(temporaries.get(varUID)).flatMap(Recycling::fetch); - } - - public void reuseAll() { - for (Recycling value : temporaries.values()) { - value.reuse(); - } - } - - public void reuse(UID varUID) { - if (temporaries.containsKey(varUID)) { - temporaries.get(varUID).reuse(); - } - // once a variable is reused, it should not be reported back - touchedVars.remove(varUID); - } - - public LinkedHashMap startRecording() { - touchedVars = new LinkedHashMap<>(); - touchedVarsStack.push(touchedVars); - return touchedVars; - } - - public void stopRecording() { - touchedVarsStack.pop(); - touchedVars = touchedVarsStack.peek(); - } -} diff --git a/src/pgo/trans/passes/codegen/pluscal/WriteBackInsertionVisitor.java b/src/pgo/trans/passes/codegen/pluscal/WriteBackInsertionVisitor.java deleted file mode 100644 index 82f55a165..000000000 --- a/src/pgo/trans/passes/codegen/pluscal/WriteBackInsertionVisitor.java +++ /dev/null @@ -1,171 +0,0 @@ -package pgo.trans.passes.codegen.pluscal; - -import pgo.Unreachable; -import pgo.model.mpcal.ModularPlusCalYield; -import pgo.model.pcal.*; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -public class WriteBackInsertionVisitor extends PlusCalStatementVisitor, RuntimeException> { - private final PlusCalStatement previousStatement; - private final List writeBacks; - - private WriteBackInsertionVisitor(PlusCalStatement previousStatement, List writeBacks) { - this.previousStatement = previousStatement; - this.writeBacks = writeBacks; - } - - static List insertWriteBacks(List statements, - List writeBacks) { - if (statements.size() == 0) { - return writeBacks; - } - List result = new ArrayList<>(statements); - PlusCalStatement lastStatement = result.remove(result.size() - 1); - PlusCalStatement nextToLastStatement = result.size() > 0 ? result.remove(result.size() - 1) : null; - result.addAll(lastStatement.accept(new WriteBackInsertionVisitor(nextToLastStatement, writeBacks))); - return result; - } - - private List helper() { - List result = new ArrayList<>(); - if (previousStatement != null) { - result.add(previousStatement); - } - return result; - } - - private List writeBacksAtEnd(PlusCalStatement plusCalStatement) { - List result = helper(); - result.add(plusCalStatement); - result.addAll(writeBacks); - return result; - } - - @Override - public List visit(PlusCalLabeledStatements plusCalLabeledStatements) throws RuntimeException { - // the write backs were already performed - List result = helper(); - result.add(plusCalLabeledStatements); - return result; - } - - @Override - public List visit(PlusCalWhile plusCalWhile) throws RuntimeException { - throw new Unreachable(); - } - - private List handleWriteBacksForAlternativeBlocks(List statements, - List writeBacks) { - if (statements.size() == 0) { - return insertWriteBacks(statements, writeBacks); - } - PlusCalStatement lastStatement = statements.get(statements.size() - 1); - if (lastStatement instanceof PlusCalLabeledStatements || lastStatement instanceof PlusCalCall) { - // write backs were already performed - return statements; - } - return insertWriteBacks(statements, writeBacks); - } - - @Override - public List visit(PlusCalIf plusCalIf) throws RuntimeException { - List result = helper(); - result.add(new PlusCalIf( - plusCalIf.getLocation(), - plusCalIf.getCondition(), - handleWriteBacksForAlternativeBlocks(plusCalIf.getYes(), writeBacks), - handleWriteBacksForAlternativeBlocks(plusCalIf.getNo(), writeBacks))); - return result; - } - - @Override - public List visit(PlusCalEither plusCalEither) throws RuntimeException { - List result = helper(); - List> cases = new ArrayList<>(); - for (List aCase : plusCalEither.getCases()) { - cases.add(handleWriteBacksForAlternativeBlocks(aCase, writeBacks)); - } - result.add(new PlusCalEither(plusCalEither.getLocation(), cases)); - return result; - } - - @Override - public List visit(PlusCalAssignment plusCalAssignment) throws RuntimeException { - return writeBacksAtEnd(plusCalAssignment); - } - - private List handleReturnAndGoto(PlusCalStatement plusCalStatement) { - if (previousStatement instanceof PlusCalCall) { - // write backs were already performed - return Arrays.asList(previousStatement, plusCalStatement); - } - List result = helper(); - result.addAll(writeBacks); - result.add(plusCalStatement); - return result; - } - - @Override - public List visit(PlusCalReturn plusCalReturn) throws RuntimeException { - return handleReturnAndGoto(plusCalReturn); - } - - @Override - public List visit(PlusCalSkip plusCalSkip) throws RuntimeException { - // remove skip - List result = helper(); - result.addAll(writeBacks); - if (result.size() == 0) { - // need to insert skip back to make this block valid - result.add(plusCalSkip); - } - return result; - } - - @Override - public List visit(PlusCalCall plusCalCall) throws RuntimeException { - List result = helper(); - result.addAll(writeBacks); - result.add(plusCalCall); - return result; - } - - @Override - public List visit(PlusCalMacroCall macroCall) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public List visit(PlusCalWith plusCalWith) throws RuntimeException { - return writeBacksAtEnd(plusCalWith); - } - - @Override - public List visit(PlusCalPrint plusCalPrint) throws RuntimeException { - return writeBacksAtEnd(plusCalPrint); - } - - @Override - public List visit(PlusCalAssert plusCalAssert) throws RuntimeException { - return writeBacksAtEnd(plusCalAssert); - } - - @Override - public List visit(PlusCalAwait plusCalAwait) throws RuntimeException { - return writeBacksAtEnd(plusCalAwait); - } - - @Override - public List visit(PlusCalGoto plusCalGoto) throws RuntimeException { - return handleReturnAndGoto(plusCalGoto); - } - - @Override - public List visit(ModularPlusCalYield modularPlusCalYield) throws RuntimeException { - throw new Unreachable(); - } -} - diff --git a/src/pgo/trans/passes/constdef/ConstantDefinitionParsingPass.scala b/src/pgo/trans/passes/constdef/ConstantDefinitionParsingPass.scala deleted file mode 100644 index 29ee2e60a..000000000 --- a/src/pgo/trans/passes/constdef/ConstantDefinitionParsingPass.scala +++ /dev/null @@ -1,29 +0,0 @@ -package pgo.trans.passes.constdef - -import pgo.PGoConstantDef -import pgo.errors.Issue -import pgo.errors.IssueContext -import pgo.model.tla.TLAExpression -import pgo.parser._ -import pgo.trans.passes.parse.ParsingIssue - -import java.util -import scala.jdk.CollectionConverters._ - -object ConstantDefinitionParsingPass { - @throws[Issue] - def perform(defs: util.Map[String, PGoConstantDef]): util.HashMap[String, TLAExpression] = { - val result = new util.HashMap[String, TLAExpression] - defs.asScala.iterator.toList.sortBy(_._1).foreach { - case (key, defn) => - try { - val expr = TLAParser.readExpression(defn.location.getFile, defn.contents) - result.put(key, expr) - } catch { - case e: ParseFailureError => - throw new ParsingIssue("config", e) - } - } - result - } -} \ No newline at end of file diff --git a/src/pgo/trans/passes/desugar/mpcal/GotoInsertionVisitor.java b/src/pgo/trans/passes/desugar/mpcal/GotoInsertionVisitor.java deleted file mode 100644 index 0b5b54cec..000000000 --- a/src/pgo/trans/passes/desugar/mpcal/GotoInsertionVisitor.java +++ /dev/null @@ -1,149 +0,0 @@ -package pgo.trans.passes.desugar.mpcal; - -import pgo.Unreachable; -import pgo.model.mpcal.ModularPlusCalYield; -import pgo.model.pcal.*; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -class GotoInsertionVisitor extends PlusCalStatementVisitor, RuntimeException> { - private final PlusCalStatement previousStatement; - private final PlusCalGoto gotoStatement; - - private GotoInsertionVisitor(PlusCalStatement previousStatement, PlusCalGoto gotoStatement) { - this.gotoStatement = gotoStatement; - this.previousStatement = previousStatement; - } - - static List insertGoto(PlusCalGoto gotoStmt, List statements) { - if (statements.size() == 0) { - return Collections.singletonList(gotoStmt); - } - List result = new ArrayList<>(statements); - PlusCalStatement lastStatement = result.remove(result.size() - 1); - PlusCalStatement nextToLastStatement = result.size() > 0 ? result.remove(result.size() - 1) : null; - result.addAll(lastStatement.accept(new GotoInsertionVisitor(nextToLastStatement, gotoStmt))); - return result; - } - - private List gotoAtEnd(PlusCalStatement currentStatement) { - List result = helper(currentStatement); - result.add(gotoStatement); - return result; - } - - private List helper(PlusCalStatement toInsert) { - List result = new ArrayList<>(); - if (previousStatement != null) { - result.add(previousStatement); - } - result.add(toInsert); - return result; - } - - @Override - public List visit(PlusCalLabeledStatements plusCalLabeledStatements) throws RuntimeException { - List result = new ArrayList<>(); - if (previousStatement != null) { - result.add(previousStatement); - } - result.add(new PlusCalLabeledStatements( - plusCalLabeledStatements.getLocation(), - plusCalLabeledStatements.getLabel(), - insertGoto(gotoStatement, plusCalLabeledStatements.getStatements()))); - return result; - } - - @Override - public List visit(PlusCalWhile plusCalWhile) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public List visit(PlusCalIf plusCalIf) throws RuntimeException { - List result = new ArrayList<>(); - if (previousStatement != null) { - result.add(previousStatement); - } - result.add(new PlusCalIf( - plusCalIf.getLocation(), - plusCalIf.getCondition(), - insertGoto(gotoStatement, plusCalIf.getYes()), - insertGoto(gotoStatement, plusCalIf.getNo()))); - return result; - } - - @Override - public List visit(PlusCalEither plusCalEither) throws RuntimeException { - List result = new ArrayList<>(); - if (previousStatement != null) { - result.add(previousStatement); - } - List> cases = new ArrayList<>(); - for (List aCase : plusCalEither.getCases()) { - cases.add(insertGoto(gotoStatement, aCase)); - } - result.add(new PlusCalEither(plusCalEither.getLocation(), cases)); - return result; - } - - @Override - public List visit(PlusCalAssignment plusCalAssignment) throws RuntimeException { - return gotoAtEnd(plusCalAssignment); - } - - @Override - public List visit(PlusCalReturn plusCalReturn) throws RuntimeException { - // the user wants to return instead. Let that happen. - return helper(plusCalReturn); - } - - @Override - public List visit(PlusCalSkip plusCalSkip) throws RuntimeException { - // remove the skip statement - return helper(gotoStatement); - } - - @Override - public List visit(PlusCalCall plusCalCall) throws RuntimeException { - return gotoAtEnd(plusCalCall); - } - - @Override - public List visit(PlusCalMacroCall macroCall) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public List visit(PlusCalWith plusCalWith) throws RuntimeException { - return gotoAtEnd(plusCalWith); - } - - @Override - public List visit(PlusCalPrint plusCalPrint) throws RuntimeException { - return gotoAtEnd(plusCalPrint); - } - - @Override - public List visit(PlusCalAssert plusCalAssert) throws RuntimeException { - return gotoAtEnd(plusCalAssert); - } - - @Override - public List visit(PlusCalAwait plusCalAwait) throws RuntimeException { - return gotoAtEnd(plusCalAwait); - } - - @Override - public List visit(PlusCalGoto plusCalGoto) throws RuntimeException { - // the user wants to goto somewhere else. Let that happen. - return helper(plusCalGoto); - } - - @Override - public List visit(ModularPlusCalYield modularPlusCalYield) throws RuntimeException { - throw new Unreachable(); - } -} diff --git a/src/pgo/trans/passes/desugar/mpcal/ModularPlusCalDesugarPass.java b/src/pgo/trans/passes/desugar/mpcal/ModularPlusCalDesugarPass.java deleted file mode 100644 index 6a45db634..000000000 --- a/src/pgo/trans/passes/desugar/mpcal/ModularPlusCalDesugarPass.java +++ /dev/null @@ -1,58 +0,0 @@ -package pgo.trans.passes.desugar.mpcal; - -import pgo.model.mpcal.ModularPlusCalArchetype; -import pgo.model.mpcal.ModularPlusCalBlock; -import pgo.model.pcal.PlusCalLabeledStatements; -import pgo.model.pcal.PlusCalProcedure; -import pgo.model.pcal.PlusCalStatement; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -public class ModularPlusCalDesugarPass { - private ModularPlusCalDesugarPass() {} - - private static List desugarLabeledStatements(ModularPlusCalDesugarVisitor visitor, - List labeledStatements) { - List result = new ArrayList<>(); - for (PlusCalStatement statement : labeledStatements) { - PlusCalLabeledStatements lblStmts = (PlusCalLabeledStatements) statement; - result.addAll(lblStmts.accept(visitor)); - } - return result; - } - - public static ModularPlusCalBlock perform(ModularPlusCalBlock modularPlusCalBlock) { - ModularPlusCalDesugarVisitor visitor = new ModularPlusCalDesugarVisitor(); - List archetypes = new ArrayList<>(); - for (ModularPlusCalArchetype archetype : modularPlusCalBlock.getArchetypes()) { - archetypes.add(new ModularPlusCalArchetype( - archetype.getLocation(), - archetype.getId(), - archetype.getParams(), - archetype.getVariables(), - desugarLabeledStatements(visitor, archetype.getBody()))); - } - List procedures = new ArrayList<>(); - for (PlusCalProcedure procedure : modularPlusCalBlock.getProcedures()) { - procedures.add(new PlusCalProcedure( - procedure.getLocation(), - procedure.getName(), - procedure.getParams(), - procedure.getVariables(), - desugarLabeledStatements(visitor, procedure.getBody()))); - } - return new ModularPlusCalBlock( - modularPlusCalBlock.getLocation(), - modularPlusCalBlock.getName(), - modularPlusCalBlock.getUnits(), - Collections.emptyList(), - procedures, - modularPlusCalBlock.getMappingMacros(), - archetypes, - modularPlusCalBlock.getVariables(), - modularPlusCalBlock.getInstances(), - modularPlusCalBlock.getProcesses()); - } -} diff --git a/src/pgo/trans/passes/desugar/mpcal/ModularPlusCalDesugarVisitor.java b/src/pgo/trans/passes/desugar/mpcal/ModularPlusCalDesugarVisitor.java deleted file mode 100644 index cd9ea372f..000000000 --- a/src/pgo/trans/passes/desugar/mpcal/ModularPlusCalDesugarVisitor.java +++ /dev/null @@ -1,168 +0,0 @@ -package pgo.trans.passes.desugar.mpcal; - -import pgo.Unreachable; -import pgo.model.mpcal.ModularPlusCalYield; -import pgo.model.pcal.*; -import pgo.util.SourceLocation; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -class ModularPlusCalDesugarVisitor extends PlusCalStatementVisitor, RuntimeException> { - private List desugarStatements(List statements) { - List result = new ArrayList<>(); - for (PlusCalStatement statement : statements) { - result.addAll(statement.accept(this)); - } - return result; - } - - private PlusCalLabeledStatements desugarWhile(SourceLocation location, PlusCalLabel label, - PlusCalWhile plusCalWhile, List rest) { - // a while loop is desugared into an if and a goto due to the possibility that the condition of the while loop - // might contain a mapped variable read - // - // lb: while (f(a)) { - // stmt... - // }; - // stmt... - // - // is translated into - // - // lb: if (f(a)) { - // stmt... - // goto lb; - // } else { - // stmt... - // }; - // - // so that further codegen can possibly translate that into - // - // lb: aRead := a - // if (f(aRead)) { - // stmt... - // goto lb; - // } else { - // stmt... - // }; - // - // (in this case, a is macro mapped) - return new PlusCalLabeledStatements( - location, - label, - Collections.singletonList(new PlusCalIf( - plusCalWhile.getLocation(), - plusCalWhile.getCondition(), - GotoInsertionVisitor.insertGoto( - new PlusCalGoto(plusCalWhile.getLocation(), label.getName()), - desugarStatements(plusCalWhile.getBody())), - desugarStatements(rest)))); - } - - @Override - public List visit(PlusCalLabeledStatements plusCalLabeledStatements) throws RuntimeException { - // look ahead to handle while statements - SourceLocation location = plusCalLabeledStatements.getLocation(); - PlusCalLabel label = plusCalLabeledStatements.getLabel(); - List statements = plusCalLabeledStatements.getStatements(); - if (plusCalLabeledStatements.getStatements().get(0) instanceof PlusCalWhile) { - PlusCalWhile plusCalWhile = (PlusCalWhile) plusCalLabeledStatements.getStatements().get(0); - List rest = plusCalLabeledStatements.getStatements().subList(1, statements.size()); - return Collections.singletonList(desugarWhile(location, label, plusCalWhile, rest)); - } - List transformedStatements = new ArrayList<>(); - for (PlusCalStatement statement : statements) { - transformedStatements.addAll(statement.accept(new ModularPlusCalDesugarVisitor())); - } - return Collections.singletonList(new PlusCalLabeledStatements( - location, plusCalLabeledStatements.getLabel(), transformedStatements)); - } - - @Override - public List visit(PlusCalWhile plusCalWhile) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public List visit(PlusCalIf plusCalIf) throws RuntimeException { - return Collections.singletonList(new PlusCalIf( - plusCalIf.getLocation(), - plusCalIf.getCondition(), - desugarStatements(plusCalIf.getYes()), - desugarStatements(plusCalIf.getNo()))); - } - - @Override - public List visit(PlusCalEither plusCalEither) throws RuntimeException { - List> cases = new ArrayList<>(); - for (List aCase : plusCalEither.getCases()) { - cases.add(desugarStatements(aCase)); - } - return Collections.singletonList(new PlusCalEither(plusCalEither.getLocation(), cases)); - } - - @Override - public List visit(PlusCalAssignment plusCalAssignment) throws RuntimeException { - // nothing to do - return Collections.singletonList(plusCalAssignment); - } - - @Override - public List visit(PlusCalReturn plusCalReturn) throws RuntimeException { - // nothing to do - return Collections.singletonList(plusCalReturn); - } - - @Override - public List visit(PlusCalSkip plusCalSkip) throws RuntimeException { - // nothing to do - return Collections.singletonList(plusCalSkip); - } - - @Override - public List visit(PlusCalCall plusCalCall) throws RuntimeException { - // nothing to do - return Collections.singletonList(plusCalCall); - } - - @Override - public List visit(PlusCalMacroCall macroCall) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public List visit(PlusCalWith plusCalWith) throws RuntimeException { - return Collections.singletonList(new PlusCalWith( - plusCalWith.getLocation(), plusCalWith.getVariables(), desugarStatements(plusCalWith.getBody()))); - } - - @Override - public List visit(PlusCalPrint plusCalPrint) throws RuntimeException { - // nothing to do - return Collections.singletonList(plusCalPrint); - } - - @Override - public List visit(PlusCalAssert plusCalAssert) throws RuntimeException { - // nothing to do - return Collections.singletonList(plusCalAssert); - } - - @Override - public List visit(PlusCalAwait plusCalAwait) throws RuntimeException { - // nothing to do - return Collections.singletonList(plusCalAwait); - } - - @Override - public List visit(PlusCalGoto plusCalGoto) throws RuntimeException { - // nothing to do - return Collections.singletonList(plusCalGoto); - } - - @Override - public List visit(ModularPlusCalYield modularPlusCalYield) throws RuntimeException { - throw new Unreachable(); - } -} diff --git a/src/pgo/trans/passes/expansion/CircularModuleReferenceIssue.java b/src/pgo/trans/passes/expansion/CircularModuleReferenceIssue.java deleted file mode 100644 index 9f62efb06..000000000 --- a/src/pgo/trans/passes/expansion/CircularModuleReferenceIssue.java +++ /dev/null @@ -1,24 +0,0 @@ -package pgo.trans.passes.expansion; - -import pgo.errors.Issue; -import pgo.errors.IssueVisitor; - -public class CircularModuleReferenceIssue extends Issue { - - private final String moduleName; - - public CircularModuleReferenceIssue(String moduleName) { - super(); - this.moduleName = moduleName; - } - - public String getModuleName() { - return moduleName; - } - - @Override - public T accept(IssueVisitor v) throws E { - return v.visit(this); - } - -} diff --git a/src/pgo/trans/passes/expansion/ExpandingMacroCall.java b/src/pgo/trans/passes/expansion/ExpandingMacroCall.java deleted file mode 100644 index 0ffb3a1f6..000000000 --- a/src/pgo/trans/passes/expansion/ExpandingMacroCall.java +++ /dev/null @@ -1,24 +0,0 @@ -package pgo.trans.passes.expansion; - -import pgo.errors.Context; -import pgo.errors.ContextVisitor; -import pgo.model.pcal.PlusCalMacroCall; - -public class ExpandingMacroCall extends Context { - - private final PlusCalMacroCall macroCall; - - public ExpandingMacroCall(PlusCalMacroCall macroCall) { - this.macroCall = macroCall; - } - - public PlusCalMacroCall getMacroCall() { - return macroCall; - } - - @Override - public T accept(ContextVisitor ctx) throws E { - return ctx.visit(this); - } - -} diff --git a/src/pgo/trans/passes/expansion/InstanceArgumentCountMismatchIssue.java b/src/pgo/trans/passes/expansion/InstanceArgumentCountMismatchIssue.java deleted file mode 100644 index 65b24466f..000000000 --- a/src/pgo/trans/passes/expansion/InstanceArgumentCountMismatchIssue.java +++ /dev/null @@ -1,30 +0,0 @@ -package pgo.trans.passes.expansion; - -import pgo.errors.Issue; -import pgo.errors.IssueVisitor; -import pgo.model.mpcal.ModularPlusCalArchetype; -import pgo.model.mpcal.ModularPlusCalInstance; - -public class InstanceArgumentCountMismatchIssue extends Issue { - private final ModularPlusCalInstance modularPlusCalInstance; - private final ModularPlusCalArchetype modularPlusCalArchetype; - - public InstanceArgumentCountMismatchIssue(ModularPlusCalInstance modularPlusCalInstance, - ModularPlusCalArchetype modularPlusCalArchetype) { - this.modularPlusCalInstance = modularPlusCalInstance; - this.modularPlusCalArchetype = modularPlusCalArchetype; - } - - @Override - public T accept(IssueVisitor v) throws E { - return v.visit(this); - } - - public ModularPlusCalInstance getModularPlusCalInstance() { - return modularPlusCalInstance; - } - - public ModularPlusCalArchetype getModularPlusCalArchetype() { - return modularPlusCalArchetype; - } -} diff --git a/src/pgo/trans/passes/expansion/MacroArgumentCountMismatchIssue.java b/src/pgo/trans/passes/expansion/MacroArgumentCountMismatchIssue.java deleted file mode 100644 index 34fbedaa9..000000000 --- a/src/pgo/trans/passes/expansion/MacroArgumentCountMismatchIssue.java +++ /dev/null @@ -1,31 +0,0 @@ -package pgo.trans.passes.expansion; - -import pgo.errors.Issue; -import pgo.errors.IssueVisitor; -import pgo.model.pcal.PlusCalMacro; -import pgo.model.pcal.PlusCalMacroCall; - -public class MacroArgumentCountMismatchIssue extends Issue { - - private final PlusCalMacroCall macroCall; - private final PlusCalMacro macro; - - public MacroArgumentCountMismatchIssue(PlusCalMacroCall macroCall, PlusCalMacro macro) { - this.macroCall = macroCall; - this.macro = macro; - } - - public PlusCalMacroCall getMacroCall() { - return macroCall; - } - - public PlusCalMacro getMacro() { - return macro; - } - - @Override - public T accept(IssueVisitor v) throws E { - return v.visit(this); - } - -} diff --git a/src/pgo/trans/passes/expansion/MacroArgumentInnerScopeConflictIssue.java b/src/pgo/trans/passes/expansion/MacroArgumentInnerScopeConflictIssue.java deleted file mode 100644 index 148cc42a7..000000000 --- a/src/pgo/trans/passes/expansion/MacroArgumentInnerScopeConflictIssue.java +++ /dev/null @@ -1,24 +0,0 @@ -package pgo.trans.passes.expansion; - -import pgo.errors.Issue; -import pgo.errors.IssueVisitor; -import pgo.model.tla.TLAIdentifier; - -public class MacroArgumentInnerScopeConflictIssue extends Issue { - - private final TLAIdentifier id; - - public MacroArgumentInnerScopeConflictIssue(TLAIdentifier id) { - this.id = id; - } - - public TLAIdentifier getIdentifier() { - return id; - } - - @Override - public T accept(IssueVisitor v) throws E { - return v.visit(this); - } - -} diff --git a/src/pgo/trans/passes/expansion/MacroNameConflictIssue.java b/src/pgo/trans/passes/expansion/MacroNameConflictIssue.java deleted file mode 100644 index 3264f5e2c..000000000 --- a/src/pgo/trans/passes/expansion/MacroNameConflictIssue.java +++ /dev/null @@ -1,28 +0,0 @@ -package pgo.trans.passes.expansion; - -import pgo.errors.Issue; -import pgo.errors.IssueVisitor; -import pgo.model.pcal.PlusCalMacro; - -public class MacroNameConflictIssue extends Issue { - private final PlusCalMacro first; - private final PlusCalMacro second; - - public MacroNameConflictIssue(PlusCalMacro first, PlusCalMacro second) { - this.first = first; - this.second = second; - } - - public PlusCalMacro getFirst() { - return first; - } - - public PlusCalMacro getSecond() { - return second; - } - - @Override - public T accept(IssueVisitor v) throws E { - return v.visit(this); - } -} diff --git a/src/pgo/trans/passes/expansion/ModularPlusCalMacroExpansionPass.java b/src/pgo/trans/passes/expansion/ModularPlusCalMacroExpansionPass.java deleted file mode 100644 index a03bdca52..000000000 --- a/src/pgo/trans/passes/expansion/ModularPlusCalMacroExpansionPass.java +++ /dev/null @@ -1,79 +0,0 @@ -package pgo.trans.passes.expansion; - -import pgo.errors.IssueContext; -import pgo.model.mpcal.*; -import pgo.model.pcal.*; - -import java.util.*; - -public class ModularPlusCalMacroExpansionPass { - private ModularPlusCalMacroExpansionPass() {} - - public static ModularPlusCalBlock perform(IssueContext ctx, ModularPlusCalBlock modularPlusCalBlock) { - Map macros = new HashMap<>(); - for (PlusCalMacro macro : modularPlusCalBlock.getMacros()) { - if (macros.containsKey(macro.getName())) { - ctx.error(new MacroNameConflictIssue(macros.get(macro.getName()), macro)); - continue; - } - - macros.put(macro.getName(), macro); - } - - // Expand macros themselves to allow macro composition - for (PlusCalMacro macro : modularPlusCalBlock.getMacros()) { - PlusCalMacroExpansionVisitor macroExpander = new PlusCalMacroExpansionVisitor(ctx, macros, new HashSet<>(), new HashMap<>()); - List stmts = new ArrayList<>(); - - for (PlusCalStatement s : macro.getBody()) { - stmts.addAll(s.accept(macroExpander)); - } - - PlusCalMacro expanded = new PlusCalMacro(macro.getLocation(), macro.getName(), macro.getParams(), stmts); - macros.put(macro.getName(), expanded); - } - - List procedures = new ArrayList<>(); - PlusCalMacroExpansionVisitor v = new PlusCalMacroExpansionVisitor(ctx, macros, new HashSet<>(), new HashMap<>()); - for (PlusCalProcedure proc : modularPlusCalBlock.getProcedures()) { - List stmts = new ArrayList<>(); - for (PlusCalStatement stmt : proc.getBody()) { - stmts.addAll(stmt.accept(v)); - } - - procedures.add(new PlusCalProcedure( - proc.getLocation(), - proc.getName(), - proc.getParams(), - proc.getVariables(), - stmts)); - } - - List archetypes = new ArrayList<>(); - for (ModularPlusCalArchetype archetype : modularPlusCalBlock.getArchetypes()) { - List stmts = new ArrayList<>(); - for (PlusCalStatement stmt : archetype.getBody()) { - stmts.addAll(stmt.accept(v)); - } - - archetypes.add(new ModularPlusCalArchetype( - archetype.getLocation(), - archetype.getId(), - archetype.getParams(), - archetype.getVariables(), - stmts)); - } - - return new ModularPlusCalBlock( - modularPlusCalBlock.getLocation(), - modularPlusCalBlock.getName(), - modularPlusCalBlock.getUnits(), - Collections.emptyList(), - procedures, - modularPlusCalBlock.getMappingMacros(), - archetypes, - modularPlusCalBlock.getVariables(), - modularPlusCalBlock.getInstances(), - modularPlusCalBlock.getProcesses().accept(new PlusCalProcessesMacroExpansionVisitor(ctx, macros))); - } -} diff --git a/src/pgo/trans/passes/expansion/PlusCalMacroExpansionVisitor.java b/src/pgo/trans/passes/expansion/PlusCalMacroExpansionVisitor.java deleted file mode 100644 index 69c0a9883..000000000 --- a/src/pgo/trans/passes/expansion/PlusCalMacroExpansionVisitor.java +++ /dev/null @@ -1,171 +0,0 @@ -package pgo.trans.passes.expansion; - -import pgo.Unreachable; -import pgo.errors.IssueContext; -import pgo.model.mpcal.ModularPlusCalYield; -import pgo.model.pcal.*; -import pgo.model.tla.TLAExpression; -import pgo.model.tla.TLAGeneralIdentifier; -import pgo.util.SourceLocation; - -import java.util.*; -import java.util.stream.Collectors; - -public class PlusCalMacroExpansionVisitor extends PlusCalStatementVisitor, RuntimeException> { - private final IssueContext ctx; - private final Map macros; - private final Set recursionSet; - private final Map macroArgs; - private final TLAExpressionMacroSubstitutionVisitor macroSubst; - - public PlusCalMacroExpansionVisitor(IssueContext ctx, Map macros, Set recursionSet, Map macroArgs) { - this.ctx = ctx; - this.macros = macros; - this.recursionSet = recursionSet; - this.macroArgs = macroArgs; - this.macroSubst = new TLAExpressionMacroSubstitutionVisitor(ctx, macroArgs); - } - - private List substituteStatements(List stmts) { - List result = new ArrayList<>(); - for (PlusCalStatement stmt : stmts) { - result.addAll(stmt.accept(this)); - } - return result; - } - - @Override - public List visit(PlusCalLabeledStatements plusCalLabeledStatements) throws RuntimeException { - return Collections.singletonList(new PlusCalLabeledStatements(plusCalLabeledStatements.getLocation(), - plusCalLabeledStatements.getLabel(), substituteStatements(plusCalLabeledStatements.getStatements()))); - } - - @Override - public List visit(PlusCalWhile plusCalWhile) throws RuntimeException { - return Collections.singletonList(new PlusCalWhile( - plusCalWhile.getLocation(), plusCalWhile.getCondition().accept(macroSubst), substituteStatements(plusCalWhile.getBody()))); - } - - @Override - public List visit(PlusCalIf plusCalIf) throws RuntimeException { - return Collections.singletonList(new PlusCalIf( - plusCalIf.getLocation(), plusCalIf.getCondition().accept(macroSubst), substituteStatements(plusCalIf.getYes()), substituteStatements(plusCalIf.getNo()))); - } - - @Override - public List visit(PlusCalEither plusCalEither) throws RuntimeException { - return Collections.singletonList(new PlusCalEither( - plusCalEither.getLocation(), plusCalEither.getCases().stream().map(this::substituteStatements).collect(Collectors.toList()))); - } - - @Override - public List visit(PlusCalAssignment plusCalAssignment) throws RuntimeException { - List pairs = new ArrayList<>(); - for (PlusCalAssignmentPair pair : plusCalAssignment.getPairs()) { - pairs.add(new PlusCalAssignmentPair( - pair.getLocation(), - pair.getLhs().accept(macroSubst), - pair.getRhs().accept(macroSubst))); - } - return Collections.singletonList(new PlusCalAssignment( - plusCalAssignment.getLocation(), pairs)); - } - - @Override - public List visit(PlusCalReturn plusCalReturn) throws RuntimeException { - return Collections.singletonList(new PlusCalReturn(plusCalReturn.getLocation())); - } - - @Override - public List visit(PlusCalSkip plusCalSkip) throws RuntimeException { - return Collections.singletonList(new PlusCalSkip(plusCalSkip.getLocation())); - } - - @Override - public List visit(PlusCalCall plusCalCall) throws RuntimeException { - return Collections.singletonList(new PlusCalCall( - plusCalCall.getLocation(), plusCalCall.getTarget(), plusCalCall.getArguments().stream().map(a -> a.accept(macroSubst)).collect(Collectors.toList()))); - } - - @Override - public List visit(PlusCalMacroCall macroCall) throws RuntimeException { - if (recursionSet.contains(macroCall.getTarget())) { - ctx.error(new RecursiveMacroCallIssue(macroCall)); - } else if (macros.containsKey(macroCall.getTarget())) { - PlusCalMacro macro = macros.get(macroCall.getTarget()); - if (macro.getParamIds().size() != macroCall.getArguments().size()) { - ctx.error(new MacroArgumentCountMismatchIssue(macroCall, macro)); - } else { - Map argsMap = new HashMap<>(); - for (int i = 0; i < macroCall.getArguments().size(); ++i) { - argsMap.put(macro.getParamIds().get(i), macroCall.getArguments().get(i)); - } - Set innerRecursionSet = new HashSet<>(recursionSet); - innerRecursionSet.add(macro.getName()); - - PlusCalMacroExpansionVisitor innerVisitor = new PlusCalMacroExpansionVisitor(ctx.withContext(new ExpandingMacroCall(macroCall)), macros, innerRecursionSet, argsMap); - List statements = new ArrayList<>(); - for (PlusCalStatement stmt : macro.getBody()) { - statements.addAll(stmt.accept(innerVisitor)); - } - return statements; - } - } else { - ctx.error(new UnresolvableMacroCallIssue(macroCall)); - } - return Collections.singletonList(new PlusCalSkip(macroCall.getLocation())); - } - - @Override - public List visit(PlusCalWith plusCalWith) throws RuntimeException { - // FIXME: ugly mutation-based hack to correctly handle nested renames - Map recovery = new HashMap<>(); - List result = Collections.singletonList(new PlusCalWith( - plusCalWith.getLocation(), - plusCalWith.getVariables().stream().map(v -> { - if (macroArgs.containsKey(v.getName())) { - // TODO: error reporting in this case? - } - PlusCalVariableDeclaration replacement = new PlusCalVariableDeclaration(v.getLocation(), v.getName(), - v.isRef(), v.isSet(), v.getValue().accept(macroSubst)); - TLAGeneralIdentifier replacementID = new TLAGeneralIdentifier(SourceLocation.unknown(), v.getName(), Collections.emptyList()); - replacementID.setRefersTo(replacement); - recovery.put(v.getName().getId(), macroArgs.put(v.getName().getId(), replacementID)); - return replacement; - }).collect(Collectors.toList()), - substituteStatements(plusCalWith.getBody()))); - for(String recName: recovery.keySet()) { - if(recovery.get(recName) == null) { - macroArgs.remove(recName); - } else { - macroArgs.put(recName, recovery.get(recName)); - } - } - return result; - } - - @Override - public List visit(PlusCalPrint plusCalPrint) throws RuntimeException { - return Collections.singletonList(new PlusCalPrint(plusCalPrint.getLocation(), plusCalPrint.getValue().accept(macroSubst))); - } - - @Override - public List visit(PlusCalAssert plusCalAssert) throws RuntimeException { - return Collections.singletonList(new PlusCalAssert(plusCalAssert.getLocation(), plusCalAssert.getCondition().accept(macroSubst))); - } - - @Override - public List visit(PlusCalAwait plusCalAwait) throws RuntimeException { - return Collections.singletonList(new PlusCalAwait(plusCalAwait.getLocation(), plusCalAwait.getCondition().accept(macroSubst))); - } - - @Override - public List visit(PlusCalGoto plusCalGoto) throws RuntimeException { - return Collections.singletonList(new PlusCalGoto(plusCalGoto.getLocation(), plusCalGoto.getTarget())); - } - - @Override - public List visit(ModularPlusCalYield modularPlusCalYield) throws RuntimeException { - throw new Unreachable(); - } -} diff --git a/src/pgo/trans/passes/expansion/PlusCalProcessesMacroExpansionVisitor.java b/src/pgo/trans/passes/expansion/PlusCalProcessesMacroExpansionVisitor.java deleted file mode 100644 index b4d90e943..000000000 --- a/src/pgo/trans/passes/expansion/PlusCalProcessesMacroExpansionVisitor.java +++ /dev/null @@ -1,47 +0,0 @@ -package pgo.trans.passes.expansion; - -import pgo.errors.IssueContext; -import pgo.model.pcal.*; - -import java.util.*; - -public class PlusCalProcessesMacroExpansionVisitor extends PlusCalProcessesVisitor { - - private final IssueContext ctx; - private final Map macros; - - public PlusCalProcessesMacroExpansionVisitor(IssueContext ctx, Map macros) { - this.ctx = ctx; - this.macros = macros; - } - - @Override - public PlusCalProcesses visit(PlusCalSingleProcess singleProcess) throws RuntimeException { - PlusCalMacroExpansionVisitor v = new PlusCalMacroExpansionVisitor(ctx, macros, new HashSet<>(), new HashMap<>()); - List stmts = new ArrayList<>(); - for(PlusCalStatement stmt : singleProcess.getBody()) { - for(PlusCalStatement s : stmt.accept(v)) { - stmts.add(s); - } - } - return new PlusCalSingleProcess(singleProcess.getLocation(), stmts); - } - - @Override - public PlusCalProcesses visit(PlusCalMultiProcess multiProcess) throws RuntimeException { - PlusCalMacroExpansionVisitor v = new PlusCalMacroExpansionVisitor(ctx, macros, new HashSet<>(), new HashMap<>()); - List procs = new ArrayList<>(); - for(PlusCalProcess proc : multiProcess.getProcesses()) { - List stmts = new ArrayList<>(); - for(PlusCalStatement stmt : proc.getBody()) { - for(PlusCalStatement s : stmt.accept(v)) { - stmts.add(s); - } - } - procs.add(new PlusCalProcess( - proc.getLocation(), proc.getName(), proc.getFairness(), proc.getVariables(), stmts)); - } - return new PlusCalMultiProcess(multiProcess.getLocation(), procs); - } - -} diff --git a/src/pgo/trans/passes/expansion/RecursiveMacroCallIssue.java b/src/pgo/trans/passes/expansion/RecursiveMacroCallIssue.java deleted file mode 100644 index 6b65ba7fa..000000000 --- a/src/pgo/trans/passes/expansion/RecursiveMacroCallIssue.java +++ /dev/null @@ -1,24 +0,0 @@ -package pgo.trans.passes.expansion; - -import pgo.errors.Issue; -import pgo.errors.IssueVisitor; -import pgo.model.pcal.PlusCalMacroCall; - -public class RecursiveMacroCallIssue extends Issue { - - private final PlusCalMacroCall macroCall; - - public RecursiveMacroCallIssue(PlusCalMacroCall macroCall) { - this.macroCall = macroCall; - } - - public PlusCalMacroCall getMacroCall() { - return macroCall; - } - - @Override - public T accept(IssueVisitor v) throws E { - return v.visit(this); - } - -} diff --git a/src/pgo/trans/passes/expansion/TLAExpressionMacroSubstitutionVisitor.java b/src/pgo/trans/passes/expansion/TLAExpressionMacroSubstitutionVisitor.java deleted file mode 100644 index bb433baaf..000000000 --- a/src/pgo/trans/passes/expansion/TLAExpressionMacroSubstitutionVisitor.java +++ /dev/null @@ -1,292 +0,0 @@ -package pgo.trans.passes.expansion; - -import pgo.Unreachable; -import pgo.errors.IssueContext; -import pgo.model.tla.*; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -public class TLAExpressionMacroSubstitutionVisitor extends TLAExpressionVisitor { - - private final IssueContext ctx; - private final Map macroArgs; - - public TLAExpressionMacroSubstitutionVisitor(IssueContext ctx, Map macroArgs) { - this.ctx= ctx; - this.macroArgs = macroArgs; - } - - private List substitutePrefix(List prefix){ - List result = new ArrayList<>(); - for(TLAGeneralIdentifierPart part : prefix) { - // TODO: what would TLC do if the identifier part's name matched an argument? - result.add(new TLAGeneralIdentifierPart(part.getLocation(), part.getIdentifier().copy(), - part.getParameters().stream().map(p -> p.accept(this)).collect(Collectors.toList()))); - } - return result; - } - - private List substituteQuantifierBounds(List bounds){ - List result = new ArrayList<>(); - for(TLAQuantifierBound qb : bounds) { - List ids = substituteIdentifiers(qb.getIds()); - result.add(new TLAQuantifierBound(qb.getLocation(), qb.getType(), ids, qb.getSet().accept(this))); - } - return result; - } - - private List substituteIdentifiers(List ids){ - for(TLAIdentifier id : ids) { - if(macroArgs.containsKey(id.getId())) { - ctx.error(new MacroArgumentInnerScopeConflictIssue(id)); - } - } - return ids; - } - - @Override - public TLAExpression visit(TLAFunctionCall tlaFunctionCall) throws RuntimeException { - return new TLAFunctionCall(tlaFunctionCall.getLocation(), tlaFunctionCall.getFunction().accept(this), - tlaFunctionCall.getParams().stream().map(p -> p.accept(this)).collect(Collectors.toList())); - } - - @Override - public TLAExpression visit(TLABinOp tlaBinOp) throws RuntimeException { - TLABinOp result = new TLABinOp(tlaBinOp.getLocation(), tlaBinOp.getOperation(), - substitutePrefix(tlaBinOp.getPrefix()), tlaBinOp.getLHS().accept(this), - tlaBinOp.getRHS().accept(this)); - result.setRefersTo(tlaBinOp.getRefersTo()); - return result; - } - - @Override - public TLAExpression visit(TLABool tlaBool) throws RuntimeException { - return tlaBool.copy(); - } - - @Override - public TLAExpression visit(TLACase tlaCase) throws RuntimeException { - return new TLACase( - tlaCase.getLocation(), - tlaCase.getArms().stream().map(arm -> - new TLACaseArm( - arm.getLocation(), - arm.getCondition().accept(this), - arm.getResult().accept(this))).collect(Collectors.toList()), - tlaCase.getOther() != null ? tlaCase.getOther().accept(this) : null); - } - - @Override - public TLAExpression visit(TLADot tlaDot) throws RuntimeException { - return new TLADot(tlaDot.getLocation(), tlaDot.getExpression().accept(this), tlaDot.getField()); - } - - @Override - public TLAExpression visit(TLAExistential tlaExistential) throws RuntimeException { - return new TLAExistential(tlaExistential.getLocation(), substituteIdentifiers(tlaExistential.getIds()), - tlaExistential.getBody().accept(this)); - } - - @Override - public TLAExpression visit(TLAFunction tlaFunction) throws RuntimeException { - return new TLAFunction(tlaFunction.getLocation(), substituteQuantifierBounds(tlaFunction.getArguments()), - tlaFunction.getBody().accept(this)); - } - - @Override - public TLAExpression visit(TLAFunctionSet tlaFunctionSet) throws RuntimeException { - return new TLAFunctionSet(tlaFunctionSet.getLocation(), tlaFunctionSet.getFrom().accept(this), tlaFunctionSet.getTo().accept(this)); - } - - @Override - public TLAExpression visit(TLAFunctionSubstitution tlaFunctionSubstitution) throws RuntimeException { - return new TLAFunctionSubstitution( - tlaFunctionSubstitution.getLocation(), - tlaFunctionSubstitution.getSource().accept(this), - tlaFunctionSubstitution.getSubstitutions().stream().map(pair -> { - return new TLAFunctionSubstitutionPair( - pair.getLocation(), - pair.getKeys().stream().map(TLASubstitutionKey::copy).collect(Collectors.toList()), - pair.getValue().accept(this)); - }).collect(Collectors.toList())); - } - - @Override - public TLAExpression visit(TLAIf tlaIf) throws RuntimeException { - return new TLAIf(tlaIf.getLocation(), tlaIf.getCond().accept(this), tlaIf.getTval().accept(this), tlaIf.getFval().accept(this)); - } - - @Override - public TLAExpression visit(TLALet tlaLet) throws RuntimeException { - return new TLALet(tlaLet.getLocation(), null, tlaLet.getBody().accept(this)); - } - - @Override - public TLAExpression visit(TLAGeneralIdentifier tlaGeneralIdentifier) throws RuntimeException { - if(tlaGeneralIdentifier.getGeneralIdentifierPrefix().isEmpty()) { - if(macroArgs.containsKey(tlaGeneralIdentifier.getName().getId())) { - return macroArgs.get(tlaGeneralIdentifier.getName().getId()); - } - }else { - if(macroArgs.containsKey(tlaGeneralIdentifier.getName().getId())) { - ctx.error(new MacroArgumentInnerScopeConflictIssue(tlaGeneralIdentifier.getName())); - } - } - TLAGeneralIdentifier result = new TLAGeneralIdentifier(tlaGeneralIdentifier.getLocation(), tlaGeneralIdentifier.getName(), - substitutePrefix(tlaGeneralIdentifier.getGeneralIdentifierPrefix())); - result.setRefersTo(tlaGeneralIdentifier.getRefersTo()); - return result; - } - - @Override - public TLAExpression visit(TLATuple tlaTuple) throws RuntimeException { - return new TLATuple(tlaTuple.getLocation(), tlaTuple.getElements().stream().map(e -> e.accept(this)).collect(Collectors.toList())); - } - - @Override - public TLAExpression visit(TLAMaybeAction tlaMaybeAction) throws RuntimeException { - return new TLAMaybeAction(tlaMaybeAction.getLocation(), tlaMaybeAction.getBody().accept(this), tlaMaybeAction.getVars().accept(this)); - } - - @Override - public TLAExpression visit(TLANumber tlaNumber) throws RuntimeException { - return tlaNumber.copy(); - } - - @Override - public TLAExpression visit(TLAOperatorCall tlaOperatorCall) throws RuntimeException { - if(macroArgs.containsKey(tlaOperatorCall.getName().getId())) { - ctx.error(new MacroArgumentInnerScopeConflictIssue(tlaOperatorCall.getName())); - } - TLAOperatorCall result = new TLAOperatorCall(tlaOperatorCall.getLocation(), - tlaOperatorCall.getName(), - substitutePrefix(tlaOperatorCall.getPrefix()), - tlaOperatorCall.getArgs().stream().map(a -> a.accept(this)).collect(Collectors.toList())); - result.setRefersTo(tlaOperatorCall.getRefersTo()); - return result; - } - - @Override - public TLAExpression visit(TLAQuantifiedExistential tlaQuantifiedExistential) throws RuntimeException { - return new TLAQuantifiedExistential(tlaQuantifiedExistential.getLocation(), - substituteQuantifierBounds(tlaQuantifiedExistential.getIds()), - tlaQuantifiedExistential.getBody().accept(this)); - } - - @Override - public TLAExpression visit(TLAQuantifiedUniversal tlaQuantifiedUniversal) throws RuntimeException { - return new TLAQuantifiedUniversal(tlaQuantifiedUniversal.getLocation(), - substituteQuantifierBounds(tlaQuantifiedUniversal.getIds()), - tlaQuantifiedUniversal.getBody().accept(this)); - } - - @Override - public TLAExpression visit(TLARecordConstructor tlaRecordConstructor) throws RuntimeException { - return new TLARecordConstructor(tlaRecordConstructor.getLocation(), tlaRecordConstructor.getFields().stream().map(field -> { - if(macroArgs.containsKey(field.getName().getId())) { - ctx.error(new MacroArgumentInnerScopeConflictIssue(field.getName())); - } - return new TLARecordConstructor.Field(field.getLocation(), field.getName(), field.getValue().accept(this)); - }).collect(Collectors.toList())); - } - - @Override - public TLAExpression visit(TLARecordSet tlaRecordSet) throws RuntimeException { - return new TLARecordSet(tlaRecordSet.getLocation(), tlaRecordSet.getFields().stream().map(field -> { - if(macroArgs.containsKey(field.getName().getId())) { - ctx.error(new MacroArgumentInnerScopeConflictIssue(field.getName())); - } - return new TLARecordSet.Field(field.getLocation(), field.getName().copy(), field.getSet().accept(this)); - }).collect(Collectors.toList())); - } - - @Override - public TLAExpression visit(TLARequiredAction tlaRequiredAction) throws RuntimeException { - return new TLARequiredAction( - tlaRequiredAction.getLocation(), - tlaRequiredAction.getBody().accept(this), - tlaRequiredAction.getVars().accept(this)); - } - - @Override - public TLAExpression visit(TLASetConstructor tlaSetConstructor) throws RuntimeException { - return new TLASetConstructor(tlaSetConstructor.getLocation(), - tlaSetConstructor.getContents().stream().map(c -> c.accept(this)).collect(Collectors.toList())); - } - - @Override - public TLAExpression visit(TLASetComprehension tlaSetComprehension) throws RuntimeException { - return new TLASetComprehension(tlaSetComprehension.getLocation(), - tlaSetComprehension.getBody().accept(this), substituteQuantifierBounds(tlaSetComprehension.getBounds())); - } - - @Override - public TLAExpression visit(TLASetRefinement tlaSetRefinement) throws RuntimeException { - TLAIdentifierOrTuple ident = tlaSetRefinement.getIdent(); - if(ident.isTuple()) { - substituteIdentifiers(ident.getTuple()); - }else { - if(macroArgs.containsKey(ident.getId().getId())) { - ctx.error(new MacroArgumentInnerScopeConflictIssue(ident.getId())); - } - } - return new TLASetRefinement( - tlaSetRefinement.getLocation(), - new TLAQuantifierBound( - tlaSetRefinement.getBinding().getLocation(), - tlaSetRefinement.getBinding().getType(), - tlaSetRefinement.getBinding().getIds(), - tlaSetRefinement.getBinding().getSet().accept(this)), - tlaSetRefinement.getWhen().accept(this)); - } - - @Override - public TLAExpression visit(TLAString tlaString) throws RuntimeException { - return tlaString.copy(); - } - - @Override - public TLAExpression visit(TLAUnary tlaUnary) throws RuntimeException { - TLAUnary result = new TLAUnary(tlaUnary.getLocation(), tlaUnary.getOperation(), substitutePrefix(tlaUnary.getPrefix()), - tlaUnary.getOperand().accept(this)); - result.setRefersTo(tlaUnary.getRefersTo()); - return result; - } - - @Override - public TLAExpression visit(TLAUniversal tlaUniversal) throws RuntimeException { - return new TLAUniversal(tlaUniversal.getLocation(), substituteIdentifiers(tlaUniversal.getIds()), tlaUniversal.getBody().accept(this)); - } - - @Override - public TLAExpression visit(PlusCalDefaultInitValue plusCalDefaultInitValue) throws RuntimeException { - return plusCalDefaultInitValue.copy(); - } - - @Override - public TLAExpression visit(TLAFairness fairness) throws RuntimeException { - return new TLAFairness( - fairness.getLocation(), fairness.getType(), fairness.getVars().accept(this), - fairness.getExpression().accept(this)); - } - - @Override - public TLAExpression visit(TLASpecialVariableVariable tlaSpecialVariableVariable) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public TLAExpression visit(TLASpecialVariableValue tlaSpecialVariableValue) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public TLAExpression visit(TLARef tlaRef) throws RuntimeException { - // nothing to do here - return tlaRef; - } - -} diff --git a/src/pgo/trans/passes/expansion/UnresolvableMacroCallIssue.java b/src/pgo/trans/passes/expansion/UnresolvableMacroCallIssue.java deleted file mode 100644 index 991bd6704..000000000 --- a/src/pgo/trans/passes/expansion/UnresolvableMacroCallIssue.java +++ /dev/null @@ -1,24 +0,0 @@ -package pgo.trans.passes.expansion; - -import pgo.errors.Issue; -import pgo.errors.IssueVisitor; -import pgo.model.pcal.PlusCalMacroCall; - -public class UnresolvableMacroCallIssue extends Issue { - - private final PlusCalMacroCall macroCall; - - public UnresolvableMacroCallIssue(PlusCalMacroCall macroCall) { - this.macroCall = macroCall; - } - - public PlusCalMacroCall getMacroCall() { - return macroCall; - } - - @Override - public T accept(IssueVisitor v) throws E { - return v.visit(this); - } - -} diff --git a/src/pgo/trans/passes/normalising/CodeNormalisingPass.java b/src/pgo/trans/passes/normalising/CodeNormalisingPass.java deleted file mode 100644 index b08653943..000000000 --- a/src/pgo/trans/passes/normalising/CodeNormalisingPass.java +++ /dev/null @@ -1,21 +0,0 @@ -package pgo.trans.passes.normalising; - -import pgo.model.golang.GoDeclaration; -import pgo.model.golang.GoModule; - -import java.util.ArrayList; -import java.util.List; - -public class CodeNormalisingPass { - - private CodeNormalisingPass() {} - - public static GoModule perform(GoModule module) { - List decls = new ArrayList<>(); - for(GoDeclaration decl : module.getDeclarations()) { - decls.add(decl.accept(new GoDeclarationNormalisingVisitor())); - } - return new GoModule(module.getName(), module.getPackage(), module.getImports(), decls); - } - -} diff --git a/src/pgo/trans/passes/normalising/GoDeclarationNormalisingVisitor.java b/src/pgo/trans/passes/normalising/GoDeclarationNormalisingVisitor.java deleted file mode 100644 index 3226f53c7..000000000 --- a/src/pgo/trans/passes/normalising/GoDeclarationNormalisingVisitor.java +++ /dev/null @@ -1,33 +0,0 @@ -package pgo.trans.passes.normalising; - -import pgo.model.golang.*; -import pgo.trans.passes.normalising.GoStatementFindUsedLabelsVisitor; -import pgo.trans.passes.normalising.GoStatementRemoveUnusedLabelsVisitor; - -import java.util.Set; - -public class GoDeclarationNormalisingVisitor extends GoDeclarationVisitor { - - @Override - public GoDeclaration visit(GoFunctionDeclaration functionDeclaration) throws RuntimeException { - Set usedLabels = functionDeclaration.getBody().accept(new GoStatementFindUsedLabelsVisitor()); - GoBlock body = (GoBlock)functionDeclaration.getBody().accept(new GoStatementRemoveUnusedLabelsVisitor(usedLabels)); - return new GoFunctionDeclaration( - functionDeclaration.getName(), - functionDeclaration.getReceiver(), - functionDeclaration.getArguments(), - functionDeclaration.getReturnTypes(), - body); - } - - @Override - public GoDeclaration visit(GoTypeDeclaration typeDeclaration) throws RuntimeException { - return typeDeclaration; - } - - @Override - public GoDeclaration visit(GoVariableDeclaration variableDeclaration) throws RuntimeException { - return variableDeclaration; - } - -} diff --git a/src/pgo/trans/passes/normalising/GoStatementFindUsedLabelsVisitor.java b/src/pgo/trans/passes/normalising/GoStatementFindUsedLabelsVisitor.java deleted file mode 100644 index 689f1994d..000000000 --- a/src/pgo/trans/passes/normalising/GoStatementFindUsedLabelsVisitor.java +++ /dev/null @@ -1,127 +0,0 @@ -package pgo.trans.passes.normalising; - -import pgo.model.golang.*; - -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; - -public class GoStatementFindUsedLabelsVisitor extends GoStatementVisitor, RuntimeException> { - - @Override - public Set visit(GoComment comment) throws RuntimeException { - return Collections.emptySet(); - } - - @Override - public Set visit(GoAssignmentStatement assignment) throws RuntimeException { - return Collections.emptySet(); - } - - @Override - public Set visit(GoReturn goReturn) throws RuntimeException { - return Collections.emptySet(); - } - - @Override - public Set visit(GoBlock block) throws RuntimeException { - Set result = new HashSet<>(); - for(GoStatement stmt : block.getStatements()) { - result.addAll(stmt.accept(this)); - } - return result; - } - - @Override - public Set visit(GoFor goFor) throws RuntimeException { - return goFor.getBody().accept(this); - } - - @Override - public Set visit(GoForRange forRange) throws RuntimeException { - return forRange.getBody().accept(this); - } - - @Override - public Set visit(GoIf goIf) throws RuntimeException { - Set result = new HashSet<>(); - result.addAll(goIf.getThen().accept(this)); - if (goIf.getElse() != null) { - result.addAll(goIf.getElse().accept(this)); - } - return result; - } - - @Override - public Set visit(GoSwitch goSwitch) throws RuntimeException { - Set result = new HashSet<>(); - for(GoSwitchCase c : goSwitch.getCases()) { - for(GoStatement stmt : c.getBlock()) { - result.addAll(stmt.accept(this)); - } - } - if(goSwitch.getDefaultBlock() != null) { - for(GoStatement stmt : goSwitch.getDefaultBlock()) { - result.addAll(stmt.accept(this)); - } - } - return result; - } - - @Override - public Set visit(GoLabel label) throws RuntimeException { - return Collections.emptySet(); - } - - @Override - public Set visit(GoSelect select) throws RuntimeException { - Set result = new HashSet<>(); - for(GoSelectCase c : select.getCases()) { - for(GoStatement stmt : c.getBlock()) { - result.addAll(stmt.accept(this)); - } - } - return result; - } - - @Override - public Set visit(GoTo goTo) throws RuntimeException { - return Collections.singleton(goTo.getTo().getName()); - } - - @Override - public Set visit(GoIncDec incDec) throws RuntimeException { - return Collections.emptySet(); - } - - @Override - public Set visit(GoExpressionStatement expressionStatement) throws RuntimeException { - return Collections.emptySet(); - } - - @Override - public Set visit(GoBreak break1) throws RuntimeException { - return Collections.emptySet(); - } - - @Override - public Set visit(GoContinue continue1) throws RuntimeException { - return Collections.emptySet(); - } - - @Override - public Set visit(GoDefer defer) throws RuntimeException { - return Collections.emptySet(); - } - - @Override - public Set visit(GoRoutineStatement go) throws RuntimeException { - return Collections.emptySet(); - } - - @Override - public Set visit(GoVariableDeclarationStatement variableDeclarationStatement) throws RuntimeException { - return Collections.emptySet(); - } - -} diff --git a/src/pgo/trans/passes/normalising/GoStatementRemoveUnusedLabelsVisitor.java b/src/pgo/trans/passes/normalising/GoStatementRemoveUnusedLabelsVisitor.java deleted file mode 100644 index 87b5edcca..000000000 --- a/src/pgo/trans/passes/normalising/GoStatementRemoveUnusedLabelsVisitor.java +++ /dev/null @@ -1,145 +0,0 @@ -package pgo.trans.passes.normalising; - -import pgo.model.golang.*; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Set; - -public class GoStatementRemoveUnusedLabelsVisitor extends GoStatementVisitor { - - private final Set usedLabels; - - public GoStatementRemoveUnusedLabelsVisitor(Set usedLabels) { - this.usedLabels = usedLabels; - } - - private List filterBlock(List block){ - List result = new ArrayList<>(); - for(GoStatement stmt : block) { - GoStatement next = stmt.accept(this); - if(next != null) { - result.add(next); - } - } - return result; - } - - @Override - public GoStatement visit(GoComment comment) throws RuntimeException { - return comment; - } - - @Override - public GoStatement visit(GoAssignmentStatement assignment) throws RuntimeException { - return assignment; - } - - @Override - public GoStatement visit(GoReturn goReturn) throws RuntimeException { - return goReturn; - } - - @Override - public GoStatement visit(GoBlock block) throws RuntimeException { - return new GoBlock(filterBlock(block.getStatements())); - } - - @Override - public GoStatement visit(GoFor goFor) throws RuntimeException { - return new GoFor(goFor.getInit(), goFor.getCondition(), goFor.getIncrement(), (GoBlock) goFor.getBody().accept(this)); - } - - @Override - public GoStatement visit(GoForRange forRange) throws RuntimeException { - return new GoForRange(forRange.getLhs(), forRange.isDefinition(), forRange.getRangeExpr(), - (GoBlock) forRange.getBody().accept(this)); - } - - @Override - public GoStatement visit(GoIf goIf) throws RuntimeException { - return new GoIf( - goIf.getCond(), - goIf.getInitialVariables(), - goIf.getInitialExpression(), - (GoBlock) goIf.getThen().accept(this), - goIf.getElse() != null ? (GoBlock) goIf.getElse().accept(this) : null); - } - - @Override - public GoStatement visit(GoSwitch goSwitch) throws RuntimeException { - List cases = new ArrayList<>(); - for(GoSwitchCase c : goSwitch.getCases()) { - if (c.isTypeCase()) { - cases.add(new GoSwitchCase(c.getType(), filterBlock(c.getBlock()))); - } else { - cases.add(new GoSwitchCase(c.getCondition(), filterBlock(c.getBlock()))); - } - } - List defaultBlock = null; - if(goSwitch.getDefaultBlock() != null) { - defaultBlock = filterBlock(goSwitch.getDefaultBlock()); - } - return new GoSwitch(goSwitch.getCondition(), cases, defaultBlock); - } - - @Override - public GoStatement visit(GoLabel label) throws RuntimeException { - if(usedLabels.contains(label.getName())) { - return label; - }else { - return null; - } - } - - @Override - public GoStatement visit(GoSelect select) throws RuntimeException { - List cases = new ArrayList<>(); - for(GoSelectCase c : select.getCases()) { - cases.add(new GoSelectCase(c.getCondition(), filterBlock(c.getBlock()))); - } - return new GoSelect(cases); - } - - @Override - public GoStatement visit(GoTo goTo) throws RuntimeException { - return goTo; - } - - @Override - public GoStatement visit(GoIncDec incDec) throws RuntimeException { - return incDec; - } - - @Override - public GoStatement visit(GoExpressionStatement expressionStatement) throws RuntimeException { - return expressionStatement; - } - - @Override - public GoStatement visit(GoBreak break1) throws RuntimeException { - return break1; - } - - @Override - public GoStatement visit(GoContinue continue1) throws RuntimeException { - return continue1; - } - - @Override - public GoStatement visit(GoDefer defer) throws RuntimeException { - return defer; - } - - @Override - public GoStatement visit(GoRoutineStatement go) throws RuntimeException { - return go; - } - - @Override - public GoStatement visit(GoVariableDeclarationStatement variableDeclarationStatement) throws RuntimeException { - return variableDeclarationStatement; - } - -} diff --git a/src/pgo/trans/passes/parse/ParsingIssue.java b/src/pgo/trans/passes/parse/ParsingIssue.java deleted file mode 100644 index 6e36902b4..000000000 --- a/src/pgo/trans/passes/parse/ParsingIssue.java +++ /dev/null @@ -1,28 +0,0 @@ -package pgo.trans.passes.parse; - -import pgo.errors.Issue; -import pgo.errors.IssueVisitor; -import pgo.parser.ParsingError; - -public class ParsingIssue extends Issue { - private final String language; - private final ParsingError error; - - public ParsingIssue(String language, ParsingError error) { - initCause(error); - this.language = language; - this.error = error; - } - - public ParsingError getError() { - return error; - } - - public String getLanguage() { return language; } - - @Override - public T accept(IssueVisitor v) throws E { - return v.visit(this); - } - -} diff --git a/src/pgo/trans/passes/parse/mpcal/ModularPlusCalParsingPass.scala b/src/pgo/trans/passes/parse/mpcal/ModularPlusCalParsingPass.scala deleted file mode 100644 index 2d48de93b..000000000 --- a/src/pgo/trans/passes/parse/mpcal/ModularPlusCalParsingPass.scala +++ /dev/null @@ -1,15 +0,0 @@ -package pgo.trans.passes.parse.mpcal - -import pgo.model.mpcal.ModularPlusCalBlock -import pgo.model.tla.TLAModule -import pgo.parser.ModularPlusCalParser - -import java.nio.file.Path - -object ModularPlusCalParsingPass { - def hasModularPlusCalBlock(inputFileName: Path, inputFileContents: CharSequence) = - ModularPlusCalParser.hasModularPlusCalBlock(inputFileName, inputFileContents) - - def perform(inputFileName: Path, inputFileContents: CharSequence, tlaModule: TLAModule): ModularPlusCalBlock = - ModularPlusCalParser.readBlock(inputFileName, inputFileContents, tlaModule) -} \ No newline at end of file diff --git a/src/pgo/trans/passes/parse/option/OptionParserIssue.java b/src/pgo/trans/passes/parse/option/OptionParserIssue.java deleted file mode 100644 index f6e836c52..000000000 --- a/src/pgo/trans/passes/parse/option/OptionParserIssue.java +++ /dev/null @@ -1,21 +0,0 @@ -package pgo.trans.passes.parse.option; - -import pgo.errors.Issue; -import pgo.errors.IssueVisitor; - -public class OptionParserIssue extends Issue { - private final String message; - - public OptionParserIssue(String message) { - this.message = message; - } - - public String getMessage() { - return message; - } - - @Override - public T accept(IssueVisitor v) throws E { - return v.visit(this); - } -} diff --git a/src/pgo/trans/passes/parse/option/OptionParsingPass.java b/src/pgo/trans/passes/parse/option/OptionParsingPass.java deleted file mode 100644 index 51e90f7ca..000000000 --- a/src/pgo/trans/passes/parse/option/OptionParsingPass.java +++ /dev/null @@ -1,30 +0,0 @@ -package pgo.trans.passes.parse.option; - -import pgo.PGoOptionException; -import pgo.PGoOptions; -import pgo.errors.IssueContext; - -import java.util.logging.Level; -import java.util.logging.Logger; - -public class OptionParsingPass { - private OptionParsingPass() {} - - public static PGoOptions perform(IssueContext ctx, Logger logger, String[] args) { - PGoOptions opts = new PGoOptions(args); - try { - opts.parse(); - } catch (PGoOptionException e) { - ctx.error(new OptionParserIssue(e.getMessage())); - } - // set the logger's log level based on command line arguments - if (opts.logLvlQuiet) { - logger.setLevel(Level.WARNING); - } else if (opts.logLvlVerbose) { - logger.setLevel(Level.FINE); - } else { - logger.setLevel(Level.INFO); - } - return opts; - } -} diff --git a/src/pgo/trans/passes/parse/pcal/PlusCalParserIssue.java b/src/pgo/trans/passes/parse/pcal/PlusCalParserIssue.java deleted file mode 100644 index 3ec8952d9..000000000 --- a/src/pgo/trans/passes/parse/pcal/PlusCalParserIssue.java +++ /dev/null @@ -1,21 +0,0 @@ -package pgo.trans.passes.parse.pcal; - -import pgo.errors.Issue; -import pgo.errors.IssueVisitor; - -public class PlusCalParserIssue extends Issue { - private final String message; - - public PlusCalParserIssue(String message) { - this.message = message; - } - - public String getMessage() { - return message; - } - - @Override - public T accept(IssueVisitor v) throws E { - return v.visit(this); - } -} diff --git a/src/pgo/trans/passes/parse/pcal/PlusCalParsingPass.java b/src/pgo/trans/passes/parse/pcal/PlusCalParsingPass.java deleted file mode 100644 index 2c243aa3b..000000000 --- a/src/pgo/trans/passes/parse/pcal/PlusCalParsingPass.java +++ /dev/null @@ -1,22 +0,0 @@ -package pgo.trans.passes.parse.pcal; - -import pgo.errors.Issue; -import pgo.model.pcal.PlusCalAlgorithm; -import pgo.model.tla.TLAModule; -import pgo.parser.ParsingError; -import pgo.parser.PlusCalParser; -import pgo.trans.passes.parse.ParsingIssue; - -import java.nio.file.Path; - -public class PlusCalParsingPass { - private PlusCalParsingPass() {} - - public static PlusCalAlgorithm perform(Path inputFileName, CharSequence inputFileContents, TLAModule tlaModule) throws Issue { - try { - return PlusCalParser.readAlgorithm(inputFileName, inputFileContents, tlaModule); - } catch (ParsingError e) { - throw new ParsingIssue("PlusCal", e); - } - } -} diff --git a/src/pgo/trans/passes/parse/tla/TLAParsingPass.java b/src/pgo/trans/passes/parse/tla/TLAParsingPass.java deleted file mode 100644 index 018f5ca4d..000000000 --- a/src/pgo/trans/passes/parse/tla/TLAParsingPass.java +++ /dev/null @@ -1,21 +0,0 @@ -package pgo.trans.passes.parse.tla; - -import pgo.errors.Issue; -import pgo.model.tla.TLAModule; -import pgo.parser.ParsingError; -import pgo.parser.TLAParser; -import pgo.trans.passes.parse.ParsingIssue; - -import java.nio.file.Path; - -public class TLAParsingPass { - private TLAParsingPass() {} - - public static TLAModule perform(Path inputFileName, CharSequence inputFileContents) throws Issue { - try { - return TLAParser.readModuleBeforeTranslation(inputFileName, inputFileContents); - } catch (ParsingError e) { - throw new ParsingIssue("TLA+", e); - } - } -} diff --git a/src/pgo/trans/passes/type/ArchetypeBodyExpressionTypeConstraintVisitor.java b/src/pgo/trans/passes/type/ArchetypeBodyExpressionTypeConstraintVisitor.java deleted file mode 100644 index 80a9e087a..000000000 --- a/src/pgo/trans/passes/type/ArchetypeBodyExpressionTypeConstraintVisitor.java +++ /dev/null @@ -1,66 +0,0 @@ -package pgo.trans.passes.type; - -import pgo.model.tla.TLAFunctionCall; -import pgo.model.tla.TLAGeneralIdentifier; -import pgo.model.type.*; -import pgo.model.type.constraint.MonomorphicConstraint; -import pgo.scope.UID; -import pgo.trans.intermediate.DefinitionRegistry; - -import java.util.Collections; -import java.util.Map; -import java.util.Set; - -public class ArchetypeBodyExpressionTypeConstraintVisitor extends TLAExpressionTypeConstraintVisitor { - private final Set functionMappedParamUIDs; - private final Set paramUIDs; - - public ArchetypeBodyExpressionTypeConstraintVisitor(DefinitionRegistry registry, TypeSolver solver, - TypeGenerator generator, Map mapping, - Set functionMappedParamUIDs, Set paramUIDs) { - super(registry, solver, generator, mapping); - this.functionMappedParamUIDs = functionMappedParamUIDs; - this.paramUIDs = paramUIDs; - } - - @Override - public Type visit(TLAGeneralIdentifier tlaGeneralIdentifier) throws RuntimeException { - Type type = super.visit(tlaGeneralIdentifier); - UID varUID = registry.followReference(tlaGeneralIdentifier.getUID()); - if (paramUIDs.contains(varUID)) { - TypeVariable returnType = generator.getTypeVariable(Collections.singletonList(tlaGeneralIdentifier)); - solver.addConstraint(new MonomorphicConstraint( - tlaGeneralIdentifier, - mapping.get(varUID), - new ArchetypeResourceType( - returnType, - generator.getTypeVariable(Collections.singletonList(tlaGeneralIdentifier)), - Collections.singletonList(tlaGeneralIdentifier)))); - mapping.put(tlaGeneralIdentifier.getUID(), returnType); - return returnType; - } - return type; - } - - @Override - public Type visit(TLAFunctionCall tlaFunctionCall) { - if (tlaFunctionCall.getParams().size() == 1 && tlaFunctionCall.getFunction() instanceof TLAGeneralIdentifier) { - UID varUID = registry.followReference(tlaFunctionCall.getFunction().getUID()); - if (!functionMappedParamUIDs.contains(varUID)) { - return super.visit(tlaFunctionCall); - } - mapping.put(tlaFunctionCall.getFunction().getUID(), mapping.get(varUID)); - Type returnType = generator.getTypeVariable(Collections.singletonList(tlaFunctionCall)); - solver.addConstraint(new MonomorphicConstraint( - tlaFunctionCall, - mapping.get(varUID), - new ArchetypeResourceCollectionType( - wrappedVisit(tlaFunctionCall.getParams().get(0)), - returnType, - generator.getTypeVariable(Collections.singletonList(tlaFunctionCall)), - Collections.singletonList(tlaFunctionCall)))); - return returnType; - } - return super.visit(tlaFunctionCall); - } -} diff --git a/src/pgo/trans/passes/type/ArchetypeBodyLHSExpressionTypeConstraintVisitor.java b/src/pgo/trans/passes/type/ArchetypeBodyLHSExpressionTypeConstraintVisitor.java deleted file mode 100644 index d36223c34..000000000 --- a/src/pgo/trans/passes/type/ArchetypeBodyLHSExpressionTypeConstraintVisitor.java +++ /dev/null @@ -1,66 +0,0 @@ -package pgo.trans.passes.type; - -import pgo.model.tla.TLAFunctionCall; -import pgo.model.tla.TLAGeneralIdentifier; -import pgo.model.type.*; -import pgo.model.type.constraint.MonomorphicConstraint; -import pgo.scope.UID; -import pgo.trans.intermediate.DefinitionRegistry; - -import java.util.Collections; -import java.util.Map; -import java.util.Set; - -public class ArchetypeBodyLHSExpressionTypeConstraintVisitor extends TLAExpressionTypeConstraintVisitor { - private final Set functionMappedParamUIDs; - private final Set paramUIDs; - - public ArchetypeBodyLHSExpressionTypeConstraintVisitor(DefinitionRegistry registry, TypeSolver solver, - TypeGenerator generator, Map mapping, - Set functionMappedParamUIDs, Set paramUIDs) { - super(registry, solver, generator, mapping); - this.functionMappedParamUIDs = functionMappedParamUIDs; - this.paramUIDs = paramUIDs; - } - - @Override - public Type visit(TLAGeneralIdentifier tlaGeneralIdentifier) throws RuntimeException { - Type type = super.visit(tlaGeneralIdentifier); - UID varUID = registry.followReference(tlaGeneralIdentifier.getUID()); - if (paramUIDs.contains(varUID)) { - TypeVariable returnType = generator.getTypeVariable(Collections.singletonList(tlaGeneralIdentifier)); - solver.addConstraint(new MonomorphicConstraint( - tlaGeneralIdentifier, - mapping.get(varUID), - new ArchetypeResourceType( - generator.getTypeVariable(Collections.singletonList(tlaGeneralIdentifier)), - returnType, - Collections.singletonList(tlaGeneralIdentifier)))); - mapping.put(tlaGeneralIdentifier.getUID(), returnType); - return returnType; - } - return type; - } - - @Override - public Type visit(TLAFunctionCall tlaFunctionCall) { - if (tlaFunctionCall.getParams().size() == 1 && tlaFunctionCall.getFunction() instanceof TLAGeneralIdentifier) { - UID varUID = registry.followReference(tlaFunctionCall.getFunction().getUID()); - if (!functionMappedParamUIDs.contains(varUID)) { - return super.visit(tlaFunctionCall); - } - mapping.put(tlaFunctionCall.getFunction().getUID(), mapping.get(varUID)); - Type returnType = generator.getTypeVariable(Collections.singletonList(tlaFunctionCall)); - solver.addConstraint(new MonomorphicConstraint( - tlaFunctionCall, - mapping.get(varUID), - new ArchetypeResourceCollectionType( - wrappedVisit(tlaFunctionCall.getParams().get(0)), - generator.getTypeVariable(Collections.singletonList(tlaFunctionCall)), - returnType, - Collections.singletonList(tlaFunctionCall)))); - return returnType; - } - return super.visit(tlaFunctionCall); - } -} diff --git a/src/pgo/trans/passes/type/ArchetypeBodyStatementTypeConstraintVisitor.java b/src/pgo/trans/passes/type/ArchetypeBodyStatementTypeConstraintVisitor.java deleted file mode 100644 index f4915e57f..000000000 --- a/src/pgo/trans/passes/type/ArchetypeBodyStatementTypeConstraintVisitor.java +++ /dev/null @@ -1,36 +0,0 @@ -package pgo.trans.passes.type; - -import pgo.model.pcal.PlusCalAssignment; -import pgo.model.pcal.PlusCalAssignmentPair; -import pgo.model.type.TypeGenerator; -import pgo.model.type.constraint.MonomorphicConstraint; -import pgo.model.type.TypeSolver; -import pgo.model.type.TypeVariable; -import pgo.scope.UID; -import pgo.trans.intermediate.DefinitionRegistry; - -import java.util.Map; -import java.util.Set; - -public class ArchetypeBodyStatementTypeConstraintVisitor extends PlusCalStatementTypeConstraintVisitor { - private final ArchetypeBodyLHSExpressionTypeConstraintVisitor lhsVisitor; - - public ArchetypeBodyStatementTypeConstraintVisitor(DefinitionRegistry registry, TypeSolver solver, - TypeGenerator generator, Map mapping, - Set functionMappedParamUIDs, Set paramUIDs) { - super(registry, solver, generator, mapping, - new ArchetypeBodyExpressionTypeConstraintVisitor( - registry, solver, generator, mapping, functionMappedParamUIDs, paramUIDs)); - this.lhsVisitor = new ArchetypeBodyLHSExpressionTypeConstraintVisitor( - registry, solver, generator, mapping, functionMappedParamUIDs, paramUIDs); - } - - @Override - public Void visit(PlusCalAssignment plusCalAssignment) throws RuntimeException { - for (PlusCalAssignmentPair pair : plusCalAssignment.getPairs()) { - solver.addConstraint(new MonomorphicConstraint( - pair, lhsVisitor.wrappedVisit(pair.getLhs()), exprVisitor.wrappedVisit(pair.getRhs()))); - } - return null; - } -} diff --git a/src/pgo/trans/passes/type/PlusCalStatementTypeConstraintVisitor.java b/src/pgo/trans/passes/type/PlusCalStatementTypeConstraintVisitor.java deleted file mode 100644 index 4967eb12b..000000000 --- a/src/pgo/trans/passes/type/PlusCalStatementTypeConstraintVisitor.java +++ /dev/null @@ -1,160 +0,0 @@ -package pgo.trans.passes.type; - -import pgo.Unreachable; -import pgo.model.mpcal.ModularPlusCalYield; -import pgo.model.pcal.*; -import pgo.model.type.*; -import pgo.model.type.constraint.MonomorphicConstraint; -import pgo.scope.UID; -import pgo.trans.intermediate.DefinitionRegistry; - -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -public class PlusCalStatementTypeConstraintVisitor extends PlusCalStatementVisitor { - protected DefinitionRegistry registry; - protected TypeSolver solver; - private final TypeGenerator generator; - protected Map mapping; - protected TLAExpressionTypeConstraintVisitor exprVisitor; - - public PlusCalStatementTypeConstraintVisitor(DefinitionRegistry registry, TypeSolver solver, - TypeGenerator generator, Map mapping) { - this(registry, solver, generator, mapping, - new TLAExpressionTypeConstraintVisitor(registry, solver, generator, mapping)); - } - - protected PlusCalStatementTypeConstraintVisitor(DefinitionRegistry registry, TypeSolver solver, - TypeGenerator generator, Map mapping, - TLAExpressionTypeConstraintVisitor exprVisitor) { - this.registry = registry; - this.solver = solver; - this.generator = generator; - this.mapping = mapping; - this.exprVisitor = exprVisitor; - } - - @Override - public Void visit(PlusCalLabeledStatements plusCalLabeledStatements) throws RuntimeException { - for (PlusCalStatement stmt : plusCalLabeledStatements.getStatements()) { - stmt.accept(this); - } - return null; - } - - @Override - public Void visit(PlusCalWhile plusCalWhile) throws RuntimeException { - solver.addConstraint(new MonomorphicConstraint(plusCalWhile, exprVisitor.wrappedVisit(plusCalWhile.getCondition()), new BoolType(Collections.singletonList(plusCalWhile)))); - for (PlusCalStatement stmt : plusCalWhile.getBody()) { - stmt.accept(this); - } - return null; - } - - @Override - public Void visit(PlusCalIf plusCalIf) throws RuntimeException { - solver.addConstraint(new MonomorphicConstraint(plusCalIf, exprVisitor.wrappedVisit(plusCalIf.getCondition()), new BoolType(Collections.singletonList(plusCalIf)))); - for (PlusCalStatement stmt : plusCalIf.getYes()) { - stmt.accept(this); - } - for (PlusCalStatement stmt : plusCalIf.getNo()) { - stmt.accept(this); - } - return null; - } - - @Override - public Void visit(PlusCalEither plusCalEither) throws RuntimeException { - for (List eitherCase : plusCalEither.getCases()) { - for (PlusCalStatement statement : eitherCase) { - statement.accept(this); - } - } - return null; - } - - @Override - public Void visit(PlusCalAssignment plusCalAssignment) throws RuntimeException { - for(PlusCalAssignmentPair pair : plusCalAssignment.getPairs()) { - solver.addConstraint(new MonomorphicConstraint( - pair, - exprVisitor.wrappedVisit(pair.getLhs()), - exprVisitor.wrappedVisit(pair.getRhs()))); - } - return null; - } - - @Override - public Void visit(PlusCalReturn plusCalReturn) throws RuntimeException { - // pass - return null; - } - - @Override - public Void visit(PlusCalSkip plusCalSkip) throws RuntimeException { - // pass - return null; - } - - @Override - public Void visit(PlusCalCall plusCalCall) throws RuntimeException { - PlusCalProcedure proc = registry.findProcedure(plusCalCall.getTarget()); - List callArgs = plusCalCall.getArguments() - .stream() - .map(e -> exprVisitor.wrappedVisit(e)) - .collect(Collectors.toList()); - solver.addConstraint(new MonomorphicConstraint( - plusCalCall, - mapping.get(proc.getUID()), - new ProcedureType(callArgs, Collections.singletonList(plusCalCall)))); - return null; - } - - @Override - public Void visit(PlusCalMacroCall macroCall) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(PlusCalWith plusCalWith) throws RuntimeException { - for(PlusCalVariableDeclaration declaration : plusCalWith.getVariables()) { - TypeInferencePass.constrainVariableDeclaration(registry, declaration, solver, generator, mapping); - } - for (PlusCalStatement stmt : plusCalWith.getBody()) { - stmt.accept(this); - } - return null; - } - - @Override - public Void visit(PlusCalPrint plusCalPrint) throws RuntimeException { - exprVisitor.wrappedVisit(plusCalPrint.getValue()); - return null; - } - - @Override - public Void visit(PlusCalAssert plusCalAssert) throws RuntimeException { - solver.addConstraint(new MonomorphicConstraint(plusCalAssert, exprVisitor.wrappedVisit(plusCalAssert.getCondition()), new BoolType(Collections.singletonList(plusCalAssert)))); - return null; - } - - @Override - public Void visit(PlusCalAwait plusCalAwait) throws RuntimeException { - solver.addConstraint(new MonomorphicConstraint(plusCalAwait, exprVisitor.wrappedVisit(plusCalAwait.getCondition()), new BoolType(Collections.singletonList(plusCalAwait)))); - return null; - } - - @Override - public Void visit(PlusCalGoto plusCalGoto) throws RuntimeException { - // pass - return null; - } - - @Override - public Void visit(ModularPlusCalYield modularPlusCalYield) throws RuntimeException { - exprVisitor.wrappedVisit(modularPlusCalYield.getExpression()); - return null; - } -} diff --git a/src/pgo/trans/passes/type/TLAExpressionTypeConstraintVisitor.java b/src/pgo/trans/passes/type/TLAExpressionTypeConstraintVisitor.java deleted file mode 100644 index 621f4dc0e..000000000 --- a/src/pgo/trans/passes/type/TLAExpressionTypeConstraintVisitor.java +++ /dev/null @@ -1,466 +0,0 @@ -package pgo.trans.passes.type; - -import pgo.InternalCompilerError; -import pgo.TODO; -import pgo.Unreachable; -import pgo.model.tla.*; -import pgo.model.type.*; -import pgo.model.type.constraint.BasicConstraint; -import pgo.model.type.constraint.EqualityConstraint; -import pgo.model.type.constraint.MonomorphicConstraint; -import pgo.model.type.constraint.PolymorphicConstraint; -import pgo.scope.UID; -import pgo.trans.intermediate.DefinitionRegistry; -import pgo.trans.intermediate.OperatorAccessor; -import pgo.trans.intermediate.TLABuiltins; - -import java.util.*; -import java.util.stream.Collectors; - -public class TLAExpressionTypeConstraintVisitor extends TLAExpressionVisitor { - protected final DefinitionRegistry registry; - protected final TypeSolver solver; - protected final TypeGenerator generator; - protected final Map mapping; - - public TLAExpressionTypeConstraintVisitor(DefinitionRegistry registry, TypeSolver solver, - TypeGenerator generator, Map mapping) { - this.registry = registry; - this.solver = solver; - this.generator = generator; - this.mapping = mapping; - } - - private TypeVariable typeVariableReference(UID reference) { - if (mapping.containsKey(reference)) { - return mapping.get(reference); - } else { - TypeVariable v = generator.getTypeVariable(Collections.singletonList(reference)); - mapping.put(reference, v); - return v; - } - } - - public Type wrappedVisit(TLAExpression expr) { - Type result = expr.accept(this); - if (!mapping.containsKey(expr.getUID())) { - TypeVariable self = generator.getTypeVariable(Collections.singletonList(expr)); - solver.addConstraint(new MonomorphicConstraint(expr, result, self)); - mapping.put(expr.getUID(), self); - } - return result; - } - - public List wrappedVisit(List expressions) { - List result = new ArrayList<>(); - for (TLAExpression expr : expressions) { - result.add(wrappedVisit(expr)); - } - return result; - } - - private Type processQuantifierBound(TLAQuantifierBound qb) { - TypeVariable elementType = generator.getTypeVariable(Collections.singletonList(qb)); - solver.addConstraint(new MonomorphicConstraint( - qb, new SetType(elementType, Collections.singletonList(qb)), wrappedVisit(qb.getSet()))); - TLAQuantifierBound.Type type = qb.getType(); - if (TLAQuantifierBound.Type$.MODULE$.ids().equals(type)) { - for (TLAIdentifier id : qb.getIds()) { - TypeVariable idType = generator.getTypeVariable(Collections.singletonList(id)); - mapping.put(id.getUID(), idType); - solver.addConstraint(new MonomorphicConstraint(qb, elementType, idType)); - } - } else if (TLAQuantifierBound.Type$.MODULE$.tuple().equals(type)) { - List tupleTypes = new ArrayList<>(); - for (TLAIdentifier id : qb.getIds()) { - TypeVariable idType = generator.getTypeVariable(Collections.singletonList(id)); - mapping.put(id.getUID(), idType); - tupleTypes.add(idType); - } - solver.addConstraint(new MonomorphicConstraint( - qb, elementType, new TupleType(tupleTypes, Collections.singletonList(qb)))); - } else { - throw new Unreachable(); - } - return elementType; - } - - @Override - public Type visit(TLAFunctionCall tlaFunctionCall) throws RuntimeException { - Type fnType = wrappedVisit(tlaFunctionCall.getFunction()); - List paramTypes = wrappedVisit(tlaFunctionCall.getParams()); - TypeVariable returnType = generator.getTypeVariable(Collections.singletonList(tlaFunctionCall)); - if (paramTypes.size() == 1) { - solver.addConstraint(new PolymorphicConstraint(tlaFunctionCall, Arrays.asList( - Arrays.asList( - new EqualityConstraint( - fnType, - new SliceType(returnType, Collections.singletonList(tlaFunctionCall))), - new EqualityConstraint( - paramTypes.get(0), - new IntType(Collections.singletonList(tlaFunctionCall)))), - Collections.singletonList(new EqualityConstraint( - fnType, - new MapType(paramTypes.get(0), returnType, Collections.singletonList(tlaFunctionCall)))), - Collections.singletonList(new EqualityConstraint( - fnType, - new FunctionType(paramTypes, returnType, Collections.singletonList(tlaFunctionCall))))))); - } else { - solver.addConstraint(new PolymorphicConstraint(tlaFunctionCall, Arrays.asList( - Collections.singletonList(new EqualityConstraint( - fnType, - new MapType( - new TupleType(paramTypes, Collections.singletonList(tlaFunctionCall)), - returnType, - Collections.singletonList(tlaFunctionCall)))), - Collections.singletonList(new EqualityConstraint( - fnType, - new FunctionType(paramTypes, returnType, Collections.singletonList(tlaFunctionCall))))))); - } - return returnType; - } - - @Override - public Type visit(TLABinOp tlaBinOp) throws RuntimeException { - return registry - .findOperator(registry.followReference(tlaBinOp.getUID())) - .constrainTypes( - tlaBinOp, registry, - Arrays.asList(wrappedVisit(tlaBinOp.getLHS()), wrappedVisit(tlaBinOp.getRHS())), - solver, generator, mapping); - } - - @Override - public Type visit(TLABool tlaBool) throws RuntimeException { - return new BoolType(Collections.singletonList(tlaBool)); - } - - @Override - public Type visit(TLACase tlaCase) throws RuntimeException { - TypeVariable v = generator.getTypeVariable(Collections.singletonList(tlaCase)); - for (TLACaseArm caseArm : tlaCase.getArms()) { - solver.addConstraint(new MonomorphicConstraint( - tlaCase, - wrappedVisit(caseArm.getCondition()), - new BoolType(Collections.singletonList(caseArm.getCondition())))); - solver.addConstraint(new MonomorphicConstraint(tlaCase, wrappedVisit(caseArm.getResult()), v)); - } - - if (tlaCase.getOther() != null) { - solver.addConstraint(new MonomorphicConstraint(tlaCase, wrappedVisit(tlaCase.getOther()), v)); - } - - return v; - } - - @Override - public Type visit(TLADot tlaDot) throws RuntimeException { - Type fresh = generator.getTypeVariable(Collections.singletonList(tlaDot)); - AbstractRecordType abstractRecord = generator.getAbstractRecord(Collections.singletonList(tlaDot)); - solver.addConstraint( - new MonomorphicConstraint(tlaDot, abstractRecord, wrappedVisit(tlaDot.getExpression()))); - solver.addConstraint(new MonomorphicConstraint(tlaDot, abstractRecord, tlaDot.getField(), fresh)); - return fresh; - } - - @Override - public Type visit(TLAExistential tlaExistential) throws RuntimeException { - for (TLAIdentifier id : tlaExistential.getIds()) { - mapping.putIfAbsent(id.getUID(), generator.getTypeVariable(Collections.singletonList(id))); - } - wrappedVisit(tlaExistential.getBody()); - return new BoolType(Collections.singletonList(tlaExistential)); - } - - @Override - public Type visit(TLAFunction tlaFunction) throws RuntimeException { - List keyTypes = new ArrayList<>(); - for (TLAQuantifierBound qb : tlaFunction.getArguments()) { - keyTypes.add(processQuantifierBound(qb)); - } - Type valueType = wrappedVisit(tlaFunction.getBody()); - Type fresh = generator.getTypeVariable(Collections.singletonList(tlaFunction)); - if (keyTypes.size() == 1) { - solver.addConstraint(new PolymorphicConstraint(tlaFunction, Arrays.asList( - Arrays.asList( - new EqualityConstraint( - mapping.get(tlaFunction.getArguments().get(0).getSet().getUID()), - new SetType( - generator.getTypeVariable(Collections.singletonList(tlaFunction)), - Collections.singletonList(tlaFunction))), - new EqualityConstraint( - fresh, - new MapType( - keyTypes.get(0), - valueType, - Collections.singletonList(tlaFunction)))), - Collections.singletonList(new EqualityConstraint( - fresh, - new FunctionType(keyTypes, valueType, Collections.singletonList(tlaFunction))))))); - return fresh; - } - if (keyTypes.size() > 1) { - List constraintsForMap = new ArrayList<>(); - for (TLAQuantifierBound arg : tlaFunction.getArguments()) { - constraintsForMap.add(new EqualityConstraint( - mapping.get(arg.getSet().getUID()), - new SetType( - generator.getTypeVariable(Collections.singletonList(arg)), - Collections.singletonList(tlaFunction)))); - } - constraintsForMap.add(new EqualityConstraint( - fresh, - new MapType( - new TupleType(keyTypes, Collections.singletonList(tlaFunction)), - valueType, - Collections.singletonList(tlaFunction)))); - solver.addConstraint(new PolymorphicConstraint(tlaFunction, Arrays.asList( - constraintsForMap, - Collections.singletonList(new EqualityConstraint( - fresh, - new FunctionType( - keyTypes, - valueType, - Collections.singletonList(tlaFunction))))))); - return fresh; - } - return new FunctionType(keyTypes, valueType, Collections.singletonList(tlaFunction)); - } - - @Override - public Type visit(TLAFunctionSet tlaFunctionSet) throws RuntimeException { - Type from = wrappedVisit(tlaFunctionSet.getFrom()); - Type to = wrappedVisit(tlaFunctionSet.getTo()); - solver.addConstraint(new MonomorphicConstraint( - tlaFunctionSet, - from, - new SetType( - generator.getTypeVariable(Collections.singletonList(tlaFunctionSet.getFrom())), - Collections.singletonList(tlaFunctionSet)))); - solver.addConstraint(new MonomorphicConstraint( - tlaFunctionSet, - to, - new SetType( - generator.getTypeVariable(Collections.singletonList(tlaFunctionSet.getTo())), - Collections.singletonList(tlaFunctionSet)))); - throw new TODO(); - } - - @Override - public Type visit(TLAFunctionSubstitution tlaFunctionSubstitution) throws RuntimeException { - throw new TODO(); - } - - @Override - public Type visit(TLAIf tlaIf) throws RuntimeException { - solver.addConstraint(new MonomorphicConstraint( - tlaIf, wrappedVisit(tlaIf.getCond()), new BoolType(Collections.singletonList(tlaIf.getCond())))); - TypeVariable v = generator.getTypeVariable(Collections.singletonList(tlaIf)); - solver.addConstraint(new MonomorphicConstraint(tlaIf, wrappedVisit(tlaIf.getTval()), v)); - solver.addConstraint(new MonomorphicConstraint(tlaIf, wrappedVisit(tlaIf.getFval()), v)); - return v; - } - - @Override - public Type visit(TLALet tlaLet) throws RuntimeException { - // TODO: let polymorphism - for (TLAUnit unit : tlaLet.getDefinitions()) { - unit.accept(new TLAUnitTypeConstraintVisitor(registry, solver, generator, mapping)); - } - return wrappedVisit(tlaLet.getBody()); - } - - @Override - public Type visit(TLAGeneralIdentifier tlaGeneralIdentifier) throws RuntimeException { - TypeVariable v = typeVariableReference(registry.followReference(tlaGeneralIdentifier.getUID())); - mapping.put(tlaGeneralIdentifier.getUID(), v); - return v; - } - - @Override - public Type visit(TLATuple tlaTuple) throws RuntimeException { - Type fresh = generator.getTypeVariable(Collections.singletonList(tlaTuple)); - Type elementType = generator.getTypeVariable(Collections.singletonList(tlaTuple)); - List contents = tlaTuple.getElements().stream() - .map(this::wrappedVisit) - .collect(Collectors.toList()); - List commonConstraints = contents.stream() - .map(t -> new EqualityConstraint(t, elementType)) - .collect(Collectors.toList()); -// List constraintsForChanType = new ArrayList<>(commonConstraints); -// constraintsForChanType.add(new EqualityConstraint( -// fresh, -// new ChanType(elementType, Collections.singletonList(tlaTuple)))); - List constraintsForSliceType = new ArrayList<>(commonConstraints); - constraintsForSliceType.add(new EqualityConstraint( - fresh, - new SliceType(elementType, Collections.singletonList(tlaTuple)))); - solver.addConstraint(new PolymorphicConstraint(tlaTuple, Arrays.asList( - constraintsForSliceType, -// constraintsForChanType, - Collections.singletonList(new EqualityConstraint( - fresh, - new TupleType(contents, Collections.singletonList(tlaTuple))))))); - return fresh; - } - - @Override - public Type visit(TLAMaybeAction tlaMaybeAction) throws RuntimeException { - throw new TODO(); - } - - @Override - public Type visit(TLANumber tlaNumber) throws RuntimeException { - // TODO this check should be more sophisticated - if (tlaNumber.getVal().contains(".")) { - return new RealType(Collections.singletonList(tlaNumber)); - } - return TLABuiltins.getPolymorphicNumberType(tlaNumber, solver, generator); - } - - @Override - public Type visit(TLAOperatorCall tlaOperatorCall) throws RuntimeException { - return registry - .findOperator(registry.followReference(tlaOperatorCall.getUID())) - .constrainTypes( - tlaOperatorCall, registry, - tlaOperatorCall.getArgs().stream() - .map(this::wrappedVisit) - .collect(Collectors.toList()), - solver, generator, mapping); - } - - @Override - public Type visit(TLAQuantifiedExistential tlaQuantifiedExistential) throws RuntimeException { - for (TLAQuantifierBound qb : tlaQuantifiedExistential.getIds()) { - processQuantifierBound(qb); - } - wrappedVisit(tlaQuantifiedExistential.getBody()); - return new BoolType(Collections.singletonList(tlaQuantifiedExistential)); - } - - @Override - public Type visit(TLAQuantifiedUniversal tlaQuantifiedUniversal) throws RuntimeException { - for (TLAQuantifierBound qb : tlaQuantifiedUniversal.getIds()) { - processQuantifierBound(qb); - } - wrappedVisit(tlaQuantifiedUniversal.getBody()); - return new BoolType(Collections.singletonList(tlaQuantifiedUniversal)); - } - - @Override - public Type visit(TLARecordConstructor tlaRecordConstructor) throws RuntimeException { - List fields = new ArrayList<>(); - for (TLARecordConstructor.Field field : tlaRecordConstructor.getFields()) { - fields.add(new RecordType.Field(field.getName().getId(), wrappedVisit(field.getValue()))); - } - return new RecordType(fields, Collections.singletonList(tlaRecordConstructor)); - } - - @Override - public Type visit(TLARecordSet tlaRecordSet) throws RuntimeException { - throw new TODO(); - } - - @Override - public Type visit(TLARequiredAction tlaRequiredAction) throws RuntimeException { - throw new TODO(); - } - - @Override - public Type visit(TLASetConstructor tlaSetConstructor) throws RuntimeException { - TypeVariable elementType = generator.getTypeVariable(Collections.singletonList(tlaSetConstructor)); - for (TLAExpression element : tlaSetConstructor.getContents()) { - solver.addConstraint(new MonomorphicConstraint( - tlaSetConstructor, elementType, wrappedVisit(element))); - } - return new SetType(elementType, Collections.singletonList(tlaSetConstructor)); - } - - @Override - public Type visit(TLASetComprehension tlaSetComprehension) throws RuntimeException { - for (TLAQuantifierBound qb : tlaSetComprehension.getBounds()) { - processQuantifierBound(qb); - } - Type elementType = wrappedVisit(tlaSetComprehension.getBody()); - return new SetType(elementType, Collections.singletonList(tlaSetComprehension)); - } - - @Override - public Type visit(TLASetRefinement tlaSetRefinement) throws RuntimeException { - Type from = wrappedVisit(tlaSetRefinement.getFrom()); - TypeVariable elementType = generator.getTypeVariable(Collections.singletonList(tlaSetRefinement)); - solver.addConstraint(new MonomorphicConstraint( - tlaSetRefinement, from, new SetType(elementType, Collections.singletonList(tlaSetRefinement)))); - if (tlaSetRefinement.getIdent().isTuple()) { - List elements = new ArrayList<>(); - for (TLAIdentifier id : tlaSetRefinement.getIdent().getTuple()) { - TypeVariable v = generator.getTypeVariable(Collections.singletonList(id)); - mapping.put(id.getUID(), v); - elements.add(v); - } - solver.addConstraint(new MonomorphicConstraint( - tlaSetRefinement, - elementType, - new TupleType(elements, Collections.singletonList(tlaSetRefinement)))); - } else { - TLAIdentifier id = tlaSetRefinement.getIdent().getId(); - mapping.put(id.getUID(), elementType); - } - Type condition = wrappedVisit(tlaSetRefinement.getWhen()); - solver.addConstraint(new MonomorphicConstraint( - tlaSetRefinement, condition, new BoolType(Collections.singletonList(tlaSetRefinement)))); - return new SetType(elementType, Collections.singletonList(tlaSetRefinement)); - } - - @Override - public Type visit(TLAString tlaString) throws RuntimeException { - return new StringType(Collections.singletonList(tlaString)); - } - - @Override - public Type visit(TLAUnary tlaUnary) throws RuntimeException { - UID ref = registry.followReference(tlaUnary.getUID()); - OperatorAccessor op = registry.findOperator(ref); - return op.constrainTypes( - tlaUnary, registry, - Collections.singletonList(wrappedVisit(tlaUnary.getOperand())), - solver, generator, mapping); - } - - @Override - public Type visit(TLAUniversal tlaUniversal) throws RuntimeException { - for (TLAIdentifier id : tlaUniversal.getIds()) { - mapping.putIfAbsent(id.getUID(), generator.getTypeVariable(Collections.singletonList(id))); - } - wrappedVisit(tlaUniversal.getBody()); - return new BoolType(Collections.singletonList(tlaUniversal)); - } - - @Override - public Type visit(PlusCalDefaultInitValue plusCalDefaultInitValue) throws RuntimeException { - TypeVariable v = generator.getTypeVariable(Collections.singletonList(plusCalDefaultInitValue)); - mapping.put(plusCalDefaultInitValue.getUID(), v); - return v; - } - - @Override - public Type visit(TLAFairness fairness) throws RuntimeException{ - throw new InternalCompilerError(); - } - - @Override - public Type visit(TLASpecialVariableVariable tlaSpecialVariableVariable) throws RuntimeException { - return typeVariableReference(registry.followReference(tlaSpecialVariableVariable.getUID())); - } - - @Override - public Type visit(TLASpecialVariableValue tlaSpecialVariableValue) throws RuntimeException { - return typeVariableReference(registry.followReference(tlaSpecialVariableValue.getUID())); - } - - @Override - public Type visit(TLARef tlaRef) throws RuntimeException { - return typeVariableReference(registry.followReference(tlaRef.getUID())); - } -} diff --git a/src/pgo/trans/passes/type/TLAUnitTypeConstraintVisitor.java b/src/pgo/trans/passes/type/TLAUnitTypeConstraintVisitor.java deleted file mode 100644 index 763f9c76a..000000000 --- a/src/pgo/trans/passes/type/TLAUnitTypeConstraintVisitor.java +++ /dev/null @@ -1,93 +0,0 @@ -package pgo.trans.passes.type; - -import pgo.Unreachable; -import pgo.model.tla.*; -import pgo.model.type.TypeGenerator; -import pgo.model.type.constraint.MonomorphicConstraint; -import pgo.model.type.TypeSolver; -import pgo.model.type.TypeVariable; -import pgo.scope.UID; -import pgo.trans.intermediate.DefinitionRegistry; - -import java.util.Collections; -import java.util.Map; - -public class TLAUnitTypeConstraintVisitor extends TLAUnitVisitor { - private final TypeSolver solver; - private final TypeGenerator generator; - private final Map mapping; - private final TLAExpressionTypeConstraintVisitor visitor; - - public TLAUnitTypeConstraintVisitor(DefinitionRegistry registry, TypeSolver solver, TypeGenerator generator, - Map mapping) { - this.solver = solver; - this.generator = generator; - this.mapping = mapping; - this.visitor = new TLAExpressionTypeConstraintVisitor(registry, solver, generator, mapping); - } - - @Override - public Void visit(TLAInstance pGoTLAInstance) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLAFunctionDefinition pGoTLAFunctionDefinition) throws RuntimeException { - UID id = pGoTLAFunctionDefinition.getName().getUID(); - TypeVariable v; - if (mapping.containsKey(id)) { - v = mapping.get(id); - } else { - v = generator.getTypeVariable(Collections.singletonList(pGoTLAFunctionDefinition)); - mapping.put(id, v); - } - solver.addConstraint(new MonomorphicConstraint( - pGoTLAFunctionDefinition, v, visitor.wrappedVisit(pGoTLAFunctionDefinition.getFunction()))); - return null; - } - - @Override - public Void visit(TLAOperatorDefinition pGoTLAOperator) throws RuntimeException { - // TODO: what about polymorphic operators? - // i.e same operator called from two different places with different argument types - for (TLAOpDecl arg : pGoTLAOperator.getArgs()) { - if (!mapping.containsKey(arg.getName().getUID())) { - mapping.put( - arg.getName().getUID(), generator.getTypeVariable(Collections.singletonList(pGoTLAOperator))); - } - } - visitor.wrappedVisit(pGoTLAOperator.getBody()); - return null; - } - - @Override - public Void visit(TLATheorem pGoTLATheorem) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLAModule pGoTLAModule) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLAVariableDeclaration pGoTLAVariableDeclaration) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLAConstantDeclaration TLAConstantDeclaration) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLAModuleDefinition pGoTLAModuleDefinition) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLAAssumption TLAAssumption) throws RuntimeException { - throw new Unreachable(); - } - -} diff --git a/src/pgo/trans/passes/type/TypeInferenceFailureIssue.java b/src/pgo/trans/passes/type/TypeInferenceFailureIssue.java deleted file mode 100644 index 7f38370ac..000000000 --- a/src/pgo/trans/passes/type/TypeInferenceFailureIssue.java +++ /dev/null @@ -1,29 +0,0 @@ -package pgo.trans.passes.type; - -import pgo.errors.Issue; -import pgo.errors.IssueVisitor; -import pgo.model.type.Type; -import pgo.scope.UID; - -public class TypeInferenceFailureIssue extends Issue { - private final UID uid; - private final Type type; - - public TypeInferenceFailureIssue(UID uid, Type type) { - this.uid = uid; - this.type = type; - } - - public UID getUID() { - return uid; - } - - public Type getType() { - return type; - } - - @Override - public T accept(IssueVisitor v) throws E { - return v.visit(this); - } -} diff --git a/src/pgo/trans/passes/type/TypeInferencePass.java b/src/pgo/trans/passes/type/TypeInferencePass.java deleted file mode 100644 index 035c2456f..000000000 --- a/src/pgo/trans/passes/type/TypeInferencePass.java +++ /dev/null @@ -1,220 +0,0 @@ -package pgo.trans.passes.type; - -import pgo.errors.IssueContext; -import pgo.model.mpcal.*; -import pgo.model.pcal.*; -import pgo.model.tla.TLAExpression; -import pgo.model.tla.TLAUnit; -import pgo.model.type.*; -import pgo.model.type.constraint.EqualityConstraint; -import pgo.model.type.constraint.MonomorphicConstraint; -import pgo.model.type.constraint.PolymorphicConstraint; -import pgo.scope.UID; -import pgo.trans.intermediate.DefinitionRegistry; -import pgo.trans.passes.codegen.go.TypeConversionVisitor; -import pgo.util.Origin; -import pgo.util.UnionFind; - -import java.util.*; - -public class TypeInferencePass { - private TypeInferencePass() {} - - static void constrainVariableDeclaration(DefinitionRegistry registry, PlusCalVariableDeclaration var, - TypeSolver solver, TypeGenerator generator, - Map mapping) { - TypeVariable v; - if (mapping.containsKey(var.getUID())) { - v = mapping.get(var.getUID()); - } else { - v = generator.getTypeVariable(Collections.singletonList(var)); - mapping.put(var.getUID(), v); - } - - Type valueType = new TLAExpressionTypeConstraintVisitor(registry, solver, generator, mapping) - .wrappedVisit(var.getValue()); - if (var.isSet()) { - TypeVariable member = generator.getTypeVariable(Collections.singletonList(valueType)); - solver.addConstraint(new MonomorphicConstraint( - var, new SetType(member, Collections.singletonList(valueType)), valueType)); - solver.addConstraint(new MonomorphicConstraint(var, v, member)); - } else { - solver.addConstraint(new MonomorphicConstraint(var, v, valueType)); - } - } - - private static void constrainSelfVariable(Origin origin, UID selfVariableUID, TypeSolver solver, - Map mapping) { - Type selfVariableType = mapping.get(selfVariableUID); - solver.addConstraint(new PolymorphicConstraint(selfVariableUID, Arrays.asList( - Collections.singletonList(new EqualityConstraint( - selfVariableType, - new IntType(Collections.singletonList(origin)))), - Collections.singletonList(new EqualityConstraint( - selfVariableType, - new StringType(Collections.singletonList(origin))))))); - } - - public static Map perform(IssueContext ctx, DefinitionRegistry registry, - ModularPlusCalBlock modularPlusCalBlock) { - TypeSolver solver = new TypeSolver(); - TypeGenerator generator = new TypeGenerator("type"); - Map mapping = new HashMap<>(); - - // make sure the user-provided constant values typecheck - for (UID id : registry.getConstants()) { - TypeVariable fresh = generator.getTypeVariable(Collections.singletonList(id)); - mapping.put(id, fresh); - registry.getConstantValue(id).ifPresent(value -> { - mapping.put(value.getUID(), fresh); - Type type = value.accept(new TLAExpressionTypeConstraintVisitor(registry, solver, generator, mapping)); - solver.addConstraint(new MonomorphicConstraint(value, fresh, type)); - }); - } - - for (PlusCalVariableDeclaration var : modularPlusCalBlock.getVariables()) { - constrainVariableDeclaration(registry, var, solver, generator, mapping); - } - - for (TLAUnit unit : modularPlusCalBlock.getUnits()) { - unit.accept(new TLAUnitTypeConstraintVisitor(registry, solver, generator, mapping)); - } - - for (PlusCalProcedure p : modularPlusCalBlock.getProcedures()) { - List paramTypes = new ArrayList<>(); - for (PlusCalVariableDeclaration var : p.getParams()) { - constrainVariableDeclaration(registry, var, solver, generator, mapping); - paramTypes.add(mapping.get(var.getUID())); - } - for (PlusCalVariableDeclaration declaration : p.getVariables()) { - constrainVariableDeclaration(registry, declaration, solver, generator, mapping); - } - PlusCalStatementTypeConstraintVisitor v = - new PlusCalStatementTypeConstraintVisitor(registry, solver, generator, mapping); - for (PlusCalStatement stmt : p.getBody()) { - stmt.accept(v); - } - TypeVariable fresh = generator.getTypeVariable(Collections.singletonList(p)); - solver.addConstraint(new MonomorphicConstraint( - p, fresh, new ProcedureType(paramTypes, Collections.singletonList(p)))); - mapping.put(p.getUID(), fresh); - } - - for (ModularPlusCalArchetype archetype : modularPlusCalBlock.getInstantiatedArchetypes()) { - boolean[] signature = registry.getSignature(archetype.getUID()) - .orElseGet(() -> new boolean[archetype.getParams().size()]); - List params = archetype.getParams(); - Set paramUIDs = new HashSet<>(); - Set functionMappedParamUIDs = new HashSet<>(); - for (int i = 0; i < params.size(); i++) { - PlusCalVariableDeclaration param = params.get(i); - TypeVariable fresh = generator.getTypeVariable(Collections.singletonList(param)); - mapping.put(param.getUID(), fresh); - paramUIDs.add(param.getUID()); - if (signature[i]) { - solver.addConstraint(new MonomorphicConstraint(param, fresh, new ArchetypeResourceCollectionType( - generator.getTypeVariable(Collections.singletonList(param)), - generator.getTypeVariable(Collections.singletonList(param)), - generator.getTypeVariable(Collections.singletonList(param)), - Collections.singletonList(param)))); - functionMappedParamUIDs.add(param.getUID()); - } else { - solver.addConstraint(new MonomorphicConstraint(param, fresh, new ArchetypeResourceType( - generator.getTypeVariable(Collections.singletonList(param)), - generator.getTypeVariable(Collections.singletonList(param)), - Collections.singletonList(param)))); - } - } - UID selfVariableUID = archetype.getSelfVariableUID(); - mapping.put(selfVariableUID, generator.getTypeVariable(Collections.singletonList(archetype))); - constrainSelfVariable(archetype, selfVariableUID, solver, mapping); - for (PlusCalVariableDeclaration declaration : archetype.getVariables()) { - constrainVariableDeclaration(registry, declaration, solver, generator, mapping); - } - for (PlusCalStatement statement : archetype.getBody()) { - statement.accept(new ArchetypeBodyStatementTypeConstraintVisitor( - registry, solver, generator, mapping, functionMappedParamUIDs, paramUIDs)); - } - } - - for (ModularPlusCalInstance instance : modularPlusCalBlock.getInstances()) { - constrainVariableDeclaration(registry, instance.getName(), solver, generator, mapping); - UID selfVariableUID = instance.getName().getUID(); - constrainSelfVariable(instance, selfVariableUID, solver, mapping); - ModularPlusCalArchetype target = registry.findArchetype(instance.getTarget()); - solver.addConstraint(new MonomorphicConstraint( - instance, mapping.get(selfVariableUID), mapping.get(target.getSelfVariableUID()))); - TLAExpressionTypeConstraintVisitor v = - new TLAExpressionTypeConstraintVisitor(registry, solver, generator, mapping); - for (TLAExpression expression : instance.getArguments()) { - v.wrappedVisit(expression); - } - } - - modularPlusCalBlock.getProcesses().accept(new PlusCalProcessesVisitor(){ - @Override - public Void visit(PlusCalSingleProcess singleProcess) throws RuntimeException { - for (PlusCalStatement statements : singleProcess.getBody()) { - statements.accept(new PlusCalStatementTypeConstraintVisitor(registry, solver, generator, mapping)); - } - return null; - } - - @Override - public Void visit(PlusCalMultiProcess multiProcess) throws RuntimeException { - for (PlusCalProcess process : multiProcess.getProcesses()) { - constrainVariableDeclaration(registry, process.getName(), solver, generator, mapping); - constrainSelfVariable(process, process.getName().getUID(), solver, mapping); - for (PlusCalVariableDeclaration var : process.getVariables()) { - constrainVariableDeclaration(registry, var, solver, generator, mapping); - } - for (PlusCalStatement statements : process.getBody()) { - statements.accept( - new PlusCalStatementTypeConstraintVisitor(registry, solver, generator, mapping)); - } - } - return null; - } - }); - - solver.unify(ctx); - if (ctx.hasErrors()) { - return Collections.emptyMap(); - } - TypeSubstitution substitution = solver.getSubstitution(); - - Map resultingTypeMapping = new HashMap<>(); - - Set unresolvedVariables = new HashSet<>(); - Map additionalMappings = new HashMap<>(); - TypeVariableCollectionVisitor collector = new TypeVariableCollectionVisitor(unresolvedVariables); - TypeVariableSubstitutionVisitor subs = - new TypeVariableSubstitutionVisitor(new TypeSubstitution(new UnionFind<>(), additionalMappings)); - InterfaceType pGoInterfaceType = new InterfaceType(Collections.emptyList()); - for (Map.Entry m : mapping.entrySet()) { - UID uid = m.getKey(); - TypeVariable typeVariable = m.getValue(); - Type type; - if (substitution.containsKey(typeVariable)) { - type = substitution.get(typeVariable); - } else { - type = pGoInterfaceType; - additionalMappings.put(typeVariable, pGoInterfaceType); - } - type.accept(collector); - for (TypeVariable unresolvedVariable : unresolvedVariables) { - additionalMappings.put(unresolvedVariable, pGoInterfaceType); - } - unresolvedVariables.clear(); - resultingTypeMapping.put(uid, type.accept(subs)); - } - - TypeConversionVisitor goTypeConversionVisitor = new TypeConversionVisitor(); - for (UID varUID : registry.globalVariables()) { - registry.updateGlobalVariableType( - varUID, resultingTypeMapping.get(varUID).accept(goTypeConversionVisitor)); - } - - return resultingTypeMapping; - } -} diff --git a/src/pgo/trans/passes/validation/InconsistentInstantiationIssue.java b/src/pgo/trans/passes/validation/InconsistentInstantiationIssue.java deleted file mode 100644 index 6fd4628ed..000000000 --- a/src/pgo/trans/passes/validation/InconsistentInstantiationIssue.java +++ /dev/null @@ -1,65 +0,0 @@ -package pgo.trans.passes.validation; - -import pgo.errors.Issue; -import pgo.errors.IssueVisitor; -import pgo.formatters.IndentingWriter; -import pgo.formatters.IssueFormattingVisitor; -import pgo.model.mpcal.ModularPlusCalInstance; -import pgo.model.mpcal.ModularPlusCalMapping; -import pgo.model.pcal.PlusCalStatement; - -import java.io.IOException; -import java.io.StringWriter; - -public class InconsistentInstantiationIssue extends Issue { - private final ModularPlusCalInstance instance; - private final ModularPlusCalInstance conflict; - - public InconsistentInstantiationIssue(ModularPlusCalInstance statement, ModularPlusCalInstance conflict) { - this.instance = statement; - this.conflict = conflict; - } - - public ModularPlusCalInstance getInstance() { - return this.instance; - } - - public ModularPlusCalInstance getConflict() { - return this.conflict; - } - - public T accept(IssueVisitor v) throws E { - return v.visit(this); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - - if (obj == null) - return false; - - if (this.getClass() != obj.getClass()) - return false; - - InconsistentInstantiationIssue other = (InconsistentInstantiationIssue) obj; - - return this.getInstance().equals(other.getInstance()) && - this.getConflict().equals(other.getConflict()); - } - - @Override - public String toString() { - StringWriter w = new StringWriter(); - IndentingWriter out = new IndentingWriter(w); - - try { - this.accept(new IssueFormattingVisitor(out)); - } catch (IOException err) { - throw new RuntimeException("Error formatting issue", err); - } - - return w.toString(); - } -} \ No newline at end of file diff --git a/src/pgo/trans/passes/validation/InvalidArchetypeResourceUsageIssue.java b/src/pgo/trans/passes/validation/InvalidArchetypeResourceUsageIssue.java deleted file mode 100644 index 3da24902f..000000000 --- a/src/pgo/trans/passes/validation/InvalidArchetypeResourceUsageIssue.java +++ /dev/null @@ -1,61 +0,0 @@ -package pgo.trans.passes.validation; - -import pgo.errors.Issue; -import pgo.errors.IssueVisitor; -import pgo.formatters.IndentingWriter; -import pgo.formatters.IssueFormattingVisitor; -import pgo.model.pcal.PlusCalStatement; -import pgo.scope.UID; - -import java.io.IOException; -import java.io.StringWriter; -import java.util.Objects; - -public final class InvalidArchetypeResourceUsageIssue extends Issue { - private final PlusCalStatement statement; - private final boolean isFunction; - - public InvalidArchetypeResourceUsageIssue(PlusCalStatement statement, boolean isFunction) { - this.statement = statement; - this.isFunction = isFunction; - } - - public PlusCalStatement getStatement() { - return this.statement; - } - - public boolean isFunction() { - return isFunction; - } - - public T accept(IssueVisitor v) throws E { - return v.visit(this); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - InvalidArchetypeResourceUsageIssue that = (InvalidArchetypeResourceUsageIssue) o; - return isFunction == that.isFunction && Objects.equals(statement, that.statement); - } - - @Override - public int hashCode() { - return Objects.hash(statement, isFunction); - } - - @Override - public String toString() { - StringWriter w = new StringWriter(); - IndentingWriter out = new IndentingWriter(w); - - try { - this.accept(new IssueFormattingVisitor(out)); - } catch (IOException err) { - throw new RuntimeException("Error formatting issue", err); - } - - return w.toString(); - } -} \ No newline at end of file diff --git a/src/pgo/trans/passes/validation/LabelNotAllowedIssue.java b/src/pgo/trans/passes/validation/LabelNotAllowedIssue.java deleted file mode 100644 index 4f0c5eb02..000000000 --- a/src/pgo/trans/passes/validation/LabelNotAllowedIssue.java +++ /dev/null @@ -1,57 +0,0 @@ -package pgo.trans.passes.validation; - -import pgo.errors.Issue; -import pgo.errors.IssueVisitor; -import pgo.formatters.IndentingWriter; -import pgo.formatters.IssueFormattingVisitor; -import pgo.model.pcal.PlusCalStatement; - -import java.io.IOException; -import java.io.StringWriter; - -public class LabelNotAllowedIssue extends Issue { - - private final PlusCalStatement statement; - - public LabelNotAllowedIssue(PlusCalStatement statement) { - this.statement = statement; - } - - public PlusCalStatement getStatement() { - return this.statement; - } - - public T accept(IssueVisitor v) throws E { - return v.visit(this); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - - if (obj == null) - return false; - - if (this.getClass() != obj.getClass()) - return false; - - LabelNotAllowedIssue other = (LabelNotAllowedIssue) obj; - - return this.getStatement().equals(other.getStatement()); - } - - @Override - public String toString() { - StringWriter w = new StringWriter(); - IndentingWriter out = new IndentingWriter(w); - - try { - this.accept(new IssueFormattingVisitor(out)); - } catch (IOException err) { - throw new RuntimeException("Error formatting issue", err); - } - - return w.toString(); - } -} \ No newline at end of file diff --git a/src/pgo/trans/passes/validation/MissingLabelIssue.java b/src/pgo/trans/passes/validation/MissingLabelIssue.java deleted file mode 100644 index 113f6a4aa..000000000 --- a/src/pgo/trans/passes/validation/MissingLabelIssue.java +++ /dev/null @@ -1,57 +0,0 @@ -package pgo.trans.passes.validation; - -import pgo.errors.Issue; -import pgo.errors.IssueVisitor; -import pgo.formatters.IndentingWriter; -import pgo.formatters.IssueFormattingVisitor; -import pgo.model.pcal.PlusCalStatement; - -import java.io.IOException; -import java.io.StringWriter; - -public class MissingLabelIssue extends Issue { - - private final PlusCalStatement statement; - - public MissingLabelIssue(PlusCalStatement statement) { - this.statement = statement; - } - - public PlusCalStatement getStatement() { - return this.statement; - } - - public T accept(IssueVisitor v) throws E { - return v.visit(this); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - - if (obj == null) - return false; - - if (this.getClass() != obj.getClass()) - return false; - - MissingLabelIssue other = (MissingLabelIssue) obj; - - return this.getStatement().equals(other.getStatement()); - } - - @Override - public String toString() { - StringWriter w = new StringWriter(); - IndentingWriter out = new IndentingWriter(w); - - try { - this.accept(new IssueFormattingVisitor(out)); - } catch (IOException err) { - throw new RuntimeException("Error formatting issue", err); - } - - return w.toString(); - } -} diff --git a/src/pgo/trans/passes/validation/ModularPlusCalLabelingRulesVisitor.java b/src/pgo/trans/passes/validation/ModularPlusCalLabelingRulesVisitor.java deleted file mode 100644 index 3cc73d1e9..000000000 --- a/src/pgo/trans/passes/validation/ModularPlusCalLabelingRulesVisitor.java +++ /dev/null @@ -1,430 +0,0 @@ -package pgo.trans.passes.validation; - -import pgo.Unreachable; -import pgo.errors.IssueContext; -import pgo.model.mpcal.ModularPlusCalYield; -import pgo.model.pcal.*; -import pgo.model.tla.TLAExpression; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.stream.IntStream; - -/** - * Validates the labeling rules of a Modular PlusCal specification. The labeling rules - * used are exactly the same as those used by standard PlusCal and are described in - * its manual. - */ -public class ModularPlusCalLabelingRulesVisitor extends PlusCalStatementVisitor { - - /** - * Validates whether the next statement following a certain subtree in the AST requires to a label. - * This visitor assumes the root node of the AST is an If or Either expression (checks need to be - * performed by caller). - * - * The statement succeeding an 'if' or 'either' PlusCal statement needs to be labeled if there is: - * - a label - * - 'return' - * - 'goto' - * - 'call' - * - * anywhere within the 'if' or 'either' statement. - */ - private final class IfEitherNextStatementRequiresLabel extends PlusCalStatementVisitor { - public Boolean visit(PlusCalLabeledStatements plusCalLabeledStatements) { - return true; - } - - public Boolean visit(PlusCalWhile plusCalWhile) { - for (PlusCalStatement statement : plusCalWhile.getBody()) { - if (statement.accept(this)) { - return true; - } - } - - return false; - } - - public Boolean visit(PlusCalIf plusCalIf) { - for (PlusCalStatement statement : plusCalIf.getYes()) { - if (statement.accept(this)) { - return true; - } - } - - for (PlusCalStatement statement : plusCalIf.getNo()) { - if (statement.accept(this)) { - return true; - } - } - - return false; - } - - public Boolean visit(PlusCalEither plusCalEither){ - for (List cases : plusCalEither.getCases()) { - for (PlusCalStatement statement : cases) { - if (statement.accept(this)) { - return true; - } - } - } - - return false; - } - - public Boolean visit(PlusCalAssignment plusCalAssignment) { - return false; - } - - public Boolean visit(PlusCalReturn plusCalReturn) { - return true; - } - - public Boolean visit(PlusCalSkip plusCalSkip) { - return false; - } - - public Boolean visit(PlusCalCall plusCalCall) { - return true; - } - - public Boolean visit(PlusCalMacroCall macroCall) { - throw new Unreachable(); - } - - public Boolean visit(PlusCalWith plusCalWith) { - for (PlusCalStatement statement : plusCalWith.getBody()) { - if (statement.accept(this)) { - return true; - } - } - - return false; - } - - public Boolean visit(PlusCalPrint plusCalPrint) { - return false; - } - - public Boolean visit(PlusCalAssert plusCalAssert) { - return false; - } - - public Boolean visit(PlusCalAwait plusCalAwait) { - return false; - } - - public Boolean visit(PlusCalGoto plusCalGoto) { - return true; - } - - public Boolean visit(ModularPlusCalYield modularPlusCalYield) { - throw new Unreachable(); - } - } - - // Some label names are reserved by the PlusCal to TLA+ translator - private static final String[] RESERVED_LABELS = {"Done", "Error"}; - - private final IssueContext ctx; - private PlusCalStatement previousStatement; - private boolean labelsAllowed; - private Set assignedVariables; - - public ModularPlusCalLabelingRulesVisitor(IssueContext ctx) { - this.ctx = ctx; - this.previousStatement = null; - this.labelsAllowed = true; - this.assignedVariables = new HashSet<>(); - } - - public ModularPlusCalLabelingRulesVisitor(IssueContext ctx, boolean labelsAllowed) { - this.ctx = ctx; - this.previousStatement = null; - this.labelsAllowed = labelsAllowed; - this.assignedVariables = new HashSet<>(); - } - - public Void visit(PlusCalLabeledStatements plusCalLabeledStatements) { - this.previousStatement = plusCalLabeledStatements; - - if (!labelsAllowed) { - labelNotAllowed(plusCalLabeledStatements); - } else if (isReserved(plusCalLabeledStatements.getLabel())) { - reservedLabelName(plusCalLabeledStatements); - } - - // erase context of assigned variables when starting a new label - this.assignedVariables = new HashSet<>(); - - for (PlusCalStatement statement : plusCalLabeledStatements.getStatements()) { - statement.accept(this); - } - - return null; - } - - // NOTE: if a variable is assigned inside the body of a `while` loop, - // that assignment is "forgotten" once control flow exits the loop. That - // is because technically, the body of a `while` loop executes either once - // or not at all when its label is scheduled. - // - // Double assignments *within* the body of a `while` loop are still not - // allowed and enforced by this check; however, the `assignedVariables` set - // is reset to the empty set after visiting the `while` loop. - public Void visit(PlusCalWhile plusCalWhile) { - if (!firstOrLabeled(previousStatement)) { - missingLabel(plusCalWhile); - } - - this.previousStatement = plusCalWhile; - this.assignedVariables = new HashSet<>(); - for (PlusCalStatement statement : plusCalWhile.getBody()) { - statement.accept(this); - } - - this.assignedVariables = new HashSet<>(); - this.previousStatement = plusCalWhile; - return null; - } - - public Void visit(PlusCalIf plusCalIf) { - checkProcedureCall(plusCalIf); - checkReturnOrGoto(plusCalIf); - checkIfEither(plusCalIf); - - // save the actual statement preceding this 'if' statement so that - // both the 'yes' and 'no' branches of this condition have a consistent - // view of the previous statement. - PlusCalStatement oldPreviousStatement = previousStatement; - - // maintain a copy of the old set of assigned variables (variables - // assigned in different branches of the if condition should not - // be considered an error) - Set oldAssignedVariables = new HashSet<>(assignedVariables); - - for (PlusCalStatement statement : plusCalIf.getYes()) { - statement.accept(this); - } - - this.previousStatement = oldPreviousStatement; - Set assignedYes = new HashSet<>(this.assignedVariables); - - // restore variable assignment before visiting `else` set of - // statements - this.assignedVariables = oldAssignedVariables; - for (PlusCalStatement statement : plusCalIf.getNo()) { - statement.accept(this); - } - - // the set of variables assigned should be the union of the variables - // assigned in the `then` and `else` branches of the conditional. - this.assignedVariables.addAll(assignedYes); - this.previousStatement = plusCalIf; - return null; - } - - public Void visit(PlusCalEither plusCalEither) { - checkProcedureCall(plusCalEither); - checkReturnOrGoto(plusCalEither); - checkIfEither(plusCalEither); - - // save the actual statement preceding this 'if' statement so that - // both all cases of this either branch have a consistent view of - // the previous statement. - PlusCalStatement oldPreviousStatement = previousStatement; - - // keep a copy of the variables assigned before this `either` statement. - final Set oldAssignedVariables = new HashSet<>(assignedVariables); - List> assignmentCases = new ArrayList<>(); - - for (List cases : plusCalEither.getCases()) { - // restore the variables assigned before validating each of the cases - // of an `either` statement. Assigning to the same variable once - // in different cases of `either` is not an error. - this.assignedVariables = new HashSet<>(oldAssignedVariables); - - for (PlusCalStatement statement : cases) { - this.previousStatement = oldPreviousStatement; - statement.accept(this); - } - - assignmentCases.add(new HashSet<>(this.assignedVariables)); - } - - // the set of all assigned variables after an `either` statement should - // be the union of all variables assigned in all cases. - for (Set assignments : assignmentCases) { - this.assignedVariables.addAll(assignments); - } - - this.previousStatement = plusCalEither; - return null; - } - - public Void visit(PlusCalAssignment plusCalAssignment) { - checkProcedureCall(plusCalAssignment); - checkReturnOrGoto(plusCalAssignment); - checkIfEither(plusCalAssignment); - this.previousStatement = plusCalAssignment; - - for (PlusCalAssignmentPair pair : plusCalAssignment.getPairs()) { - if (assignedVariables.contains(pair.getLhs())) { - missingLabel(plusCalAssignment); - } else { - assignedVariables.add(pair.getLhs()); - } - } - - return null; - } - - public Void visit(PlusCalReturn plusCalReturn) { - // `return` statements can follow procedure calls -- no checks here - checkReturnOrGoto(plusCalReturn); - checkIfEither(plusCalReturn); - - this.previousStatement = plusCalReturn; - return null; - } - - public Void visit(PlusCalSkip plusCalSkip) { - checkProcedureCall(plusCalSkip); - checkReturnOrGoto(plusCalSkip); - checkIfEither(plusCalSkip); - - this.previousStatement = plusCalSkip; - - return null; - } - - public Void visit(PlusCalCall plusCalCall) { - checkProcedureCall(plusCalCall); - checkReturnOrGoto(plusCalCall); - checkIfEither(plusCalCall); - this.previousStatement = plusCalCall; - - return null; - } - - public Void visit(PlusCalMacroCall macroCall) { - checkProcedureCall(macroCall); - checkReturnOrGoto(macroCall); - checkIfEither(macroCall); - this.previousStatement = macroCall; - return null; - } - - public Void visit(PlusCalWith plusCalWith) { - checkProcedureCall(plusCalWith); - checkReturnOrGoto(plusCalWith); - checkIfEither(plusCalWith); - this.previousStatement = plusCalWith; - - // make sure all statements in the body of a 'with' expression - // do not have labels in them - boolean oldLabelsAllowed = labelsAllowed; - labelsAllowed = false; - for (PlusCalStatement statement : plusCalWith.getBody()) { - statement.accept(this); - } - - labelsAllowed = oldLabelsAllowed; - return null; - } - - public Void visit(PlusCalPrint plusCalPrint) { - checkProcedureCall(plusCalPrint); - checkReturnOrGoto(plusCalPrint); - checkIfEither(plusCalPrint); - this.previousStatement = plusCalPrint; - - return null; - } - - public Void visit(PlusCalAssert plusCalAssert) { - checkProcedureCall(plusCalAssert); - checkReturnOrGoto(plusCalAssert); - checkIfEither(plusCalAssert); - this.previousStatement = plusCalAssert; - - return null; - } - - public Void visit(PlusCalAwait plusCalAwait) { - checkProcedureCall(plusCalAwait); - checkReturnOrGoto(plusCalAwait); - checkIfEither(plusCalAwait); - this.previousStatement = plusCalAwait; - - return null; - } - - public Void visit(PlusCalGoto plusCalGoto) { - // `goto` statements can follow procedure calls -- no checks here - checkReturnOrGoto(plusCalGoto); - checkIfEither(plusCalGoto); - this.previousStatement = plusCalGoto; - - return null; - } - - public Void visit(ModularPlusCalYield modularPlusCalYield) { - throw new Unreachable(); - } - - private void missingLabel(PlusCalStatement statement) { - this.ctx.error(new MissingLabelIssue(statement)); - } - - private void labelNotAllowed(PlusCalStatement statement) { - this.ctx.error(new LabelNotAllowedIssue(statement)); - } - - private void reservedLabelName(PlusCalStatement statement) { - this.ctx.error(new ReservedLabelNameIssue(statement)); - } - - // checks whether the statement given is the first of an archetype/procedure/process, - // or if it is a labeled statement. The label checks in this visitor do not flag - // the case when the first statement is not labeled since that is already taken care - // of by ModularPlusCalValidationVisitor. - private boolean firstOrLabeled(PlusCalStatement statement) { - return (statement == null) || (statement instanceof PlusCalLabeledStatements); - } - - // PlusCal mandates that statements preceded by a procedure call need to be labeled, - // unless they are a `return` or `goto` statement. - private void checkProcedureCall(PlusCalStatement statement) { - if (previousStatement instanceof PlusCalCall) { - missingLabel(statement); - } - } - - // every statement followed by `return` or `goto` need to be labeled - private void checkReturnOrGoto(PlusCalStatement statement) { - if ((previousStatement instanceof PlusCalReturn) || (previousStatement instanceof PlusCalGoto)) { - missingLabel(statement); - } - } - - // a statement must be labeled if it is preceded by an `if` or `either` statement - // that includes a labeled statement, `goto`, `call` or `return` anywhere within it. - private void checkIfEither(PlusCalStatement statement) { - if ((previousStatement instanceof PlusCalIf) || (previousStatement instanceof PlusCalEither)) { - boolean needsLabel = previousStatement.accept(new IfEitherNextStatementRequiresLabel()); - - if (needsLabel) { - missingLabel(statement); - } - } - } - - private boolean isReserved(PlusCalLabel label) { - return IntStream.range(0, RESERVED_LABELS.length). - anyMatch(i -> RESERVED_LABELS[i].equals(label.getName())); - } -} diff --git a/src/pgo/trans/passes/validation/ModularPlusCalModificationValidationVisitor.java b/src/pgo/trans/passes/validation/ModularPlusCalModificationValidationVisitor.java deleted file mode 100644 index e28cb7c45..000000000 --- a/src/pgo/trans/passes/validation/ModularPlusCalModificationValidationVisitor.java +++ /dev/null @@ -1,125 +0,0 @@ -package pgo.trans.passes.validation; - -import pgo.Unreachable; -import pgo.errors.IssueContext; -import pgo.model.mpcal.ModularPlusCalYield; -import pgo.model.pcal.*; -import pgo.scope.UID; -import pgo.trans.intermediate.DefinitionRegistry; - -import java.util.List; -import java.util.Set; - -public class ModularPlusCalModificationValidationVisitor extends PlusCalStatementVisitor { - private final TLAExpressionLHSModificationValidationVisitor lhsVisitor; - - public ModularPlusCalModificationValidationVisitor(IssueContext ctx, DefinitionRegistry registry, - Set nonRefParams) { - this.lhsVisitor = new TLAExpressionLHSModificationValidationVisitor(ctx, registry, nonRefParams); - } - - @Override - public Void visit(PlusCalLabeledStatements plusCalLabeledStatements) throws RuntimeException { - for (PlusCalStatement statement : plusCalLabeledStatements.getStatements()) { - statement.accept(this); - } - return null; - } - - @Override - public Void visit(PlusCalWhile plusCalWhile) throws RuntimeException { - for (PlusCalStatement statement : plusCalWhile.getBody()) { - statement.accept(this); - } - return null; - } - - @Override - public Void visit(PlusCalIf plusCalIf) throws RuntimeException { - for (PlusCalStatement statement : plusCalIf.getYes()) { - statement.accept(this); - } - for (PlusCalStatement statement : plusCalIf.getNo()) { - statement.accept(this); - } - return null; - } - - @Override - public Void visit(PlusCalEither plusCalEither) throws RuntimeException { - for (List aCase : plusCalEither.getCases()) { - for (PlusCalStatement statement : aCase) { - statement.accept(this); - } - } - return null; - } - - @Override - public Void visit(PlusCalAssignment plusCalAssignment) throws RuntimeException { - for (PlusCalAssignmentPair pair : plusCalAssignment.getPairs()) { - pair.getLhs().accept(lhsVisitor); - } - return null; - } - - @Override - public Void visit(PlusCalReturn plusCalReturn) throws RuntimeException { - // nothing to do - return null; - } - - @Override - public Void visit(PlusCalSkip plusCalSkip) throws RuntimeException { - // nothing to do - return null; - } - - @Override - public Void visit(PlusCalCall plusCalCall) throws RuntimeException { - // TODO - return null; - } - - @Override - public Void visit(PlusCalMacroCall macroCall) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(PlusCalWith plusCalWith) throws RuntimeException { - for (PlusCalStatement statement : plusCalWith.getBody()) { - statement.accept(this); - } - return null; - } - - @Override - public Void visit(PlusCalPrint plusCalPrint) throws RuntimeException { - // nothing to do - return null; - } - - @Override - public Void visit(PlusCalAssert plusCalAssert) throws RuntimeException { - // nothing to do - return null; - } - - @Override - public Void visit(PlusCalAwait plusCalAwait) throws RuntimeException { - // nothing to do - return null; - } - - @Override - public Void visit(PlusCalGoto plusCalGoto) throws RuntimeException { - // nothing to do - return null; - } - - @Override - public Void visit(ModularPlusCalYield modularPlusCalYield) throws RuntimeException { - throw new Unreachable(); - } -} diff --git a/src/pgo/trans/passes/validation/ModularPlusCalStatementValidationVisitor.java b/src/pgo/trans/passes/validation/ModularPlusCalStatementValidationVisitor.java deleted file mode 100644 index 1f539d7ba..000000000 --- a/src/pgo/trans/passes/validation/ModularPlusCalStatementValidationVisitor.java +++ /dev/null @@ -1,128 +0,0 @@ -package pgo.trans.passes.validation; - -import pgo.Unreachable; -import pgo.errors.IssueContext; -import pgo.model.mpcal.ModularPlusCalYield; -import pgo.model.pcal.*; -import pgo.scope.UID; -import pgo.trans.intermediate.DefinitionRegistry; - -import java.util.*; - -public class ModularPlusCalStatementValidationVisitor extends PlusCalStatementVisitor { - private final IssueContext ctx; - private final DefinitionRegistry registry; - private final Map functionMapped; - - public ModularPlusCalStatementValidationVisitor(IssueContext ctx, DefinitionRegistry registry, - Map functionMapped) { - this.ctx = ctx; - this.registry = registry; - this.functionMapped = functionMapped; - } - - public Void visit(PlusCalLabeledStatements plusCalLabeledStatements) { - plusCalLabeledStatements.getStatements().forEach(statement -> - statement.accept(this) - ); - - return null; - } - - public Void visit(PlusCalWhile plusCalWhile) { - plusCalWhile.getCondition().accept(new ModularPlusCalTLAExpressionValidationVisitor( - ctx, registry, plusCalWhile, functionMapped)); - plusCalWhile.getBody().forEach(statement -> statement.accept(this)); - - return null; - } - - public Void visit(PlusCalIf plusCalIf) { - plusCalIf.getCondition().accept(new ModularPlusCalTLAExpressionValidationVisitor( - ctx, registry, plusCalIf, functionMapped)); - plusCalIf.getYes().forEach(statement -> statement.accept(this)); - plusCalIf.getNo().forEach(statement -> statement.accept(this)); - - return null; - } - - public Void visit(PlusCalEither plusCalEither) { - plusCalEither.getCases().forEach(aCase -> - aCase.forEach(statement -> statement.accept(this)) - ); - - return null; - } - - public Void visit(PlusCalAssignment plusCalAssignment) { - plusCalAssignment.getPairs().forEach(pair -> { - pair.getLhs().accept( - new ModularPlusCalTLAExpressionValidationVisitor(ctx, registry, plusCalAssignment, functionMapped)); - pair.getRhs().accept( - new ModularPlusCalTLAExpressionValidationVisitor(ctx, registry, plusCalAssignment, functionMapped)); - }); - - return null; - } - - public Void visit(PlusCalReturn plusCalReturn) { - return null; - } - - public Void visit(PlusCalSkip plusCalSkip) { - return null; - } - - public Void visit(PlusCalCall plusCalCall) { - plusCalCall.getArguments().forEach(arg -> - arg.accept( - new ModularPlusCalTLAExpressionValidationVisitor(ctx, registry, plusCalCall, functionMapped))); - - return null; - } - - public Void visit(PlusCalMacroCall macroCall) { - macroCall.getArguments().forEach(arg -> - arg.accept(new ModularPlusCalTLAExpressionValidationVisitor(ctx, registry, macroCall, functionMapped))); - - return null; - } - - public Void visit(PlusCalWith plusCalWith) { - plusCalWith.getVariables().forEach(varDecl -> - varDecl.getValue().accept( - new ModularPlusCalTLAExpressionValidationVisitor(ctx, registry, plusCalWith, functionMapped))); - plusCalWith.getBody().forEach(statement -> statement.accept(this)); - - return null; - } - - public Void visit(PlusCalPrint plusCalPrint) { - plusCalPrint.getValue().accept( - new ModularPlusCalTLAExpressionValidationVisitor(ctx, registry, plusCalPrint, functionMapped)); - - return null; - } - - public Void visit(PlusCalAssert plusCalAssert) { - plusCalAssert.getCondition().accept( - new ModularPlusCalTLAExpressionValidationVisitor(ctx, registry, plusCalAssert, functionMapped)); - - return null; - } - - public Void visit(PlusCalAwait plusCalAwait) { - plusCalAwait.getCondition().accept( - new ModularPlusCalTLAExpressionValidationVisitor(ctx, registry, plusCalAwait, functionMapped)); - - return null; - } - - public Void visit(PlusCalGoto plusCalGoto) { - return null; - } - - public Void visit(ModularPlusCalYield modularPlusCalYield) { - throw new Unreachable(); - } -} \ No newline at end of file diff --git a/src/pgo/trans/passes/validation/ModularPlusCalTLAExpressionValidationVisitor.java b/src/pgo/trans/passes/validation/ModularPlusCalTLAExpressionValidationVisitor.java deleted file mode 100644 index ec6ac27fc..000000000 --- a/src/pgo/trans/passes/validation/ModularPlusCalTLAExpressionValidationVisitor.java +++ /dev/null @@ -1,236 +0,0 @@ -package pgo.trans.passes.validation; - -import pgo.TODO; -import pgo.errors.IssueContext; -import pgo.model.pcal.PlusCalStatement; -import pgo.model.tla.*; -import pgo.scope.UID; -import pgo.trans.intermediate.DefinitionRegistry; - -import java.util.*; - -public class ModularPlusCalTLAExpressionValidationVisitor extends TLAExpressionVisitor { - private final IssueContext ctx; - private final DefinitionRegistry registry; - private final PlusCalStatement containingStatement; - private final Map functionMapped; - - public ModularPlusCalTLAExpressionValidationVisitor(IssueContext ctx, DefinitionRegistry registry, PlusCalStatement containingStatement, - Map functionMapped) { - this.ctx = ctx; - this.registry = registry; - this.containingStatement = containingStatement; - this.functionMapped = functionMapped; - } - - @Override - public Void visit(TLAFunctionCall tlaFunctionCall) throws RuntimeException { - tlaFunctionCall.getParams().forEach(param -> param.accept(this)); - - if (tlaFunctionCall.getFunction() instanceof TLAGeneralIdentifier) { - UID varUID = registry.followReference(tlaFunctionCall.getFunction().getUID()); - - if (functionMapped.containsKey(varUID) && !functionMapped.get(varUID)) { - ctx.error(new InvalidArchetypeResourceUsageIssue(containingStatement, false)); - } - } - - return null; - } - - @Override - public Void visit(TLABinOp tlaBinOp) throws RuntimeException { - tlaBinOp.getLHS().accept(this); - tlaBinOp.getRHS().accept(this); - - return null; - } - - @Override - public Void visit(TLABool tlaBool) throws RuntimeException { - return null; - } - - @Override - public Void visit(TLACase tlaCase) throws RuntimeException { - tlaCase.getArms().forEach(arm -> { - arm.getCondition().accept(this); - arm.getResult().accept(this); - }); - - return null; - } - - @Override - public Void visit(TLADot tlaDot) throws RuntimeException { - tlaDot.getExpression().accept(this); - - return null; - } - - @Override - public Void visit(TLAExistential tlaExistential) throws RuntimeException { - throw new TODO(); - } - - @Override - public Void visit(TLAFunction tlaFunction) throws RuntimeException { - tlaFunction.getBody().accept(this); - - return null; - } - - @Override - public Void visit(TLAFunctionSet tlaFunctionSet) throws RuntimeException { - throw new TODO(); - } - - @Override - public Void visit(TLAFunctionSubstitution tlaFunctionSubstitution) throws RuntimeException { - throw new TODO(); - } - - @Override - public Void visit(TLAIf tlaIf) throws RuntimeException { - tlaIf.getCond().accept(this); - tlaIf.getTval().accept(this); - tlaIf.getFval().accept(this); - - return null; - } - - @Override - public Void visit(TLALet tlaLet) throws RuntimeException { - throw new TODO(); - } - - @Override - public Void visit(TLAGeneralIdentifier tlaGeneralIdentifier) throws RuntimeException { - UID varUID = registry.followReference(tlaGeneralIdentifier.getUID()); - - if (functionMapped.containsKey(varUID) && functionMapped.get(varUID)) { - ctx.error(new InvalidArchetypeResourceUsageIssue(containingStatement, true)); - } - - return null; - } - - @Override - public Void visit(TLATuple tlaTuple) throws RuntimeException { - tlaTuple.getElements().forEach(e -> e.accept(this)); - - return null; - } - - @Override - public Void visit(TLAMaybeAction tlaMaybeAction) throws RuntimeException { - throw new TODO(); - } - - @Override - public Void visit(TLANumber tlaNumber) throws RuntimeException { - return null; - } - - @Override - public Void visit(TLAOperatorCall tlaOperatorCall) throws RuntimeException { - tlaOperatorCall.getArgs().forEach(arg -> arg.accept(this)); - - return null; - } - - @Override - public Void visit(TLAQuantifiedExistential tlaQuantifiedExistential) throws RuntimeException { - tlaQuantifiedExistential.getBody().accept(this); - - return null; - } - - @Override - public Void visit(TLAQuantifiedUniversal tlaQuantifiedUniversal) throws RuntimeException { - tlaQuantifiedUniversal.getBody().accept(this); - - return null; - } - - @Override - public Void visit(TLARecordConstructor tlaRecordConstructor) throws RuntimeException { - tlaRecordConstructor.getFields().forEach(field -> field.getValue().accept(this)); - - return null; - } - - @Override - public Void visit(TLARecordSet tlaRecordSet) throws RuntimeException { - throw new TODO(); - } - - @Override - public Void visit(TLARequiredAction tlaRequiredAction) throws RuntimeException { - throw new TODO(); - } - - @Override - public Void visit(TLASetConstructor tlaSetConstructor) throws RuntimeException { - tlaSetConstructor.getContents().forEach(e -> e.accept(this)); - - return null; - } - - @Override - public Void visit(TLASetComprehension tlaSetComprehension) throws RuntimeException { - tlaSetComprehension.getBody().accept(this); - - return null; - } - - @Override - public Void visit(TLASetRefinement tlaSetRefinement) throws RuntimeException { - tlaSetRefinement.getFrom().accept(this); - tlaSetRefinement.getWhen().accept(this); - - return null; - } - - @Override - public Void visit(TLAString tlaString) throws RuntimeException { - return null; - } - - @Override - public Void visit(TLAUnary tlaUnary) throws RuntimeException { - tlaUnary.getOperand().accept(this); - - return null; - } - - @Override - public Void visit(TLAUniversal tlaUniversal) throws RuntimeException { - throw new TODO(); - } - - @Override - public Void visit(PlusCalDefaultInitValue plusCalDefaultInitValue) throws RuntimeException { - return null; - } - - @Override - public Void visit(TLAFairness fairness) throws RuntimeException { - throw new TODO(); - } - - @Override - public Void visit(TLASpecialVariableVariable tlaSpecialVariableVariable) throws RuntimeException { - throw new TODO(); - } - - @Override - public Void visit(TLASpecialVariableValue tlaSpecialVariableValue) throws RuntimeException { - throw new TODO(); - } - - @Override - public Void visit(TLARef tlaRef) throws RuntimeException { - return null; - } -} \ No newline at end of file diff --git a/src/pgo/trans/passes/validation/ModularPlusCalValidationVisitor.java b/src/pgo/trans/passes/validation/ModularPlusCalValidationVisitor.java deleted file mode 100644 index f0b253249..000000000 --- a/src/pgo/trans/passes/validation/ModularPlusCalValidationVisitor.java +++ /dev/null @@ -1,168 +0,0 @@ -package pgo.trans.passes.validation; - -import java.util.*; - -import pgo.errors.IssueContext; -import pgo.model.mpcal.*; -import pgo.model.pcal.*; -import pgo.model.tla.TLAExpression; -import pgo.model.tla.TLAGeneralIdentifier; -import pgo.model.tla.TLARef; -import pgo.model.tla.TLAUnit; -import pgo.scope.UID; - -import java.util.function.Consumer; - -/** - * Validates that the Modular PlusCal specification is valid according to the restrictions - * imposed by the language (documented at https://github.com/UBC-NSS/pgo/wiki/Modular-PlusCal). - */ -public class ModularPlusCalValidationVisitor extends ModularPlusCalBlockVisitor { - private final IssueContext ctx; - - public ModularPlusCalValidationVisitor(IssueContext ctx) { - this.ctx = ctx; - } - - public Void visit(ModularPlusCalBlock modularPlusCalBlock) { - for (ModularPlusCalArchetype archetype : modularPlusCalBlock.getArchetypes()) { - archetype.accept(this); - } - - for (ModularPlusCalMappingMacro mappingMacro : modularPlusCalBlock.getMappingMacros()) { - mappingMacro.accept(this); - } - - for (PlusCalMacro macro : modularPlusCalBlock.getMacros()) { - macro.accept(this); - } - - for (PlusCalProcedure procedure : modularPlusCalBlock.getProcedures()) { - procedure.accept(this); - } - - if (modularPlusCalBlock.getProcesses() instanceof PlusCalSingleProcess) { - PlusCalSingleProcess singleProcess = (PlusCalSingleProcess) modularPlusCalBlock.getProcesses(); - singleProcess.accept(this); - } else if (modularPlusCalBlock.getProcesses() instanceof PlusCalMultiProcess) { - PlusCalMultiProcess multiProcess = (PlusCalMultiProcess) modularPlusCalBlock.getProcesses(); - multiProcess.accept(this); - } - - return null; - } - - /** - * Same labelling rules of vanilla PlusCal apply (see C-syntax manual, section 3.7) - */ - public Void visit(ModularPlusCalArchetype modularPlusCalArchetype) { - // guaranteed to exist at the parsing stage - PlusCalStatement firstStatement = modularPlusCalArchetype.getBody().get(0); - checkLabeled(firstStatement); - - ModularPlusCalLabelingRulesVisitor labels = new ModularPlusCalLabelingRulesVisitor(ctx); - modularPlusCalArchetype.getBody().forEach(statement -> statement.accept(labels)); - - return null; - } - - public Void visit(ModularPlusCalInstance modularPlusCalInstance) { - return null; - } - - public Void visit(ModularPlusCalMappingMacro modularPlusCalMappingMacro) { - // mapping macros should have no labels, `goto`, `call` or `while` statements. - PlusCalStatementRejectionVisitor visitor = new PlusCalStatementRejectionVisitor( - this.ctx, - Arrays.asList( - PlusCalStatementRejectionVisitor.Node.LABELS, - PlusCalStatementRejectionVisitor.Node.CALL, - PlusCalStatementRejectionVisitor.Node.GOTO, - PlusCalStatementRejectionVisitor.Node.WHILE - ) - ); - - Consumer> validateType = statements -> { - for (PlusCalStatement statement : statements) { - statement.accept(visitor); - } - }; - - validateType.accept(modularPlusCalMappingMacro.getReadBody()); - validateType.accept(modularPlusCalMappingMacro.getWriteBody()); - - return null; - } - - public Void visit(PlusCalMacro plusCalMacro) { - ModularPlusCalLabelingRulesVisitor visitor = - new ModularPlusCalLabelingRulesVisitor(this.ctx, false); - - // visit every statement of the macro, collecting an error in case a label - // is found within - for (PlusCalStatement statement : plusCalMacro.getBody()) { - statement.accept(visitor); - } - - // TODO: validate macros - return null; - } - - public Void visit(PlusCalProcedure plusCalProcedure) { - PlusCalStatement firstStatement = plusCalProcedure.getBody().get(0); - checkLabeled(firstStatement); - - ModularPlusCalLabelingRulesVisitor visitor = new ModularPlusCalLabelingRulesVisitor(this.ctx); - for (PlusCalStatement statement : plusCalProcedure.getBody()) { - statement.accept(visitor); - } - - // TODO: validate procedures - return null; - } - - public Void visit(PlusCalSingleProcess plusCalSingleProcess) { - PlusCalStatement firstStatement = plusCalSingleProcess.getBody().get(0); - checkLabeled(firstStatement); - - ModularPlusCalLabelingRulesVisitor visitor = new ModularPlusCalLabelingRulesVisitor(this.ctx); - for (PlusCalStatement statement : plusCalSingleProcess.getBody()) { - statement.accept(visitor); - } - - // TODO: validate single process - return null; - } - - public Void visit(PlusCalMultiProcess plusCalMultiProcess) { - for (PlusCalProcess process : plusCalMultiProcess.getProcesses()) { - PlusCalStatement firstStatement = process.getBody().get(0); - checkLabeled(firstStatement); - - ModularPlusCalLabelingRulesVisitor visitor = new ModularPlusCalLabelingRulesVisitor(this.ctx); - for (PlusCalStatement statement : process.getBody()) { - statement.accept(visitor); - } - - // TODO: validate PlusCal processes - } - - return null; - } - - public Void visit(TLAUnit tlaUnit) { - // TODO: validate TLA+ units - - return null; - } - - private Void checkLabeled(PlusCalStatement statement) { - boolean isLabeled = statement instanceof PlusCalLabeledStatements; - - if (!isLabeled) { - ctx.error(new MissingLabelIssue(statement)); - } - - return null; - } -} \ No newline at end of file diff --git a/src/pgo/trans/passes/validation/NonModularPlusCalNodeValidationVisitor.java b/src/pgo/trans/passes/validation/NonModularPlusCalNodeValidationVisitor.java deleted file mode 100644 index a380a0434..000000000 --- a/src/pgo/trans/passes/validation/NonModularPlusCalNodeValidationVisitor.java +++ /dev/null @@ -1,78 +0,0 @@ -package pgo.trans.passes.validation; - -import pgo.TODO; -import pgo.Unreachable; -import pgo.model.pcal.*; - -import java.util.List; - -public class NonModularPlusCalNodeValidationVisitor extends PlusCalNodeVisitor { - private final NonModularPlusCalStatementValidationVisitor statementVisitor; - private final NonModularPlusCalTLAExpressionValidationVisitor expressionVisitor; - - public NonModularPlusCalNodeValidationVisitor() { - this.statementVisitor = new NonModularPlusCalStatementValidationVisitor(); - this.expressionVisitor = new NonModularPlusCalTLAExpressionValidationVisitor(); - } - - private boolean validateStatements(List statements) { - return statements.stream().allMatch(s -> s.accept(statementVisitor)); - } - - @Override - public Boolean visit(PlusCalAlgorithm plusCalAlgorithm) throws RuntimeException { - throw new TODO(); - } - - @Override - public Boolean visit(PlusCalProcesses processes) throws RuntimeException { - if (processes instanceof PlusCalSingleProcess) { - return statementVisitor.validateStatements(((PlusCalSingleProcess) processes).getBody()); - } - if (processes instanceof PlusCalMultiProcess) { - return ((PlusCalMultiProcess) processes).getProcesses().stream().allMatch(p -> p.accept(this)); - } - throw new Unreachable(); - } - - @Override - public Boolean visit(PlusCalStatement statement) throws RuntimeException { - return statement.accept(statementVisitor); - } - - @Override - public Boolean visit(PlusCalLabel label) throws RuntimeException { - return true; - } - - @Override - public Boolean visit(PlusCalMacro macro) throws RuntimeException { - return validateStatements(macro.getBody()); - } - - @Override - public Boolean visit(PlusCalProcess plusCalProcess) throws RuntimeException { - return plusCalProcess.getName().accept(this) && - statementVisitor.validateDeclarations(plusCalProcess.getVariables()) && - statementVisitor.validateStatements(plusCalProcess.getBody()); - } - - @Override - public Boolean visit(PlusCalProcedure procedure) throws RuntimeException { - return statementVisitor.validateDeclarations(procedure.getParams()) && - statementVisitor.validateDeclarations(procedure.getVariables()) && - statementVisitor.validateStatements(procedure.getBody()); - } - - @Override - public Boolean visit(PlusCalVariableDeclaration variableDeclaration) throws RuntimeException { - return !variableDeclaration.isRef() && variableDeclaration.getValue().accept(expressionVisitor); - } - - @Override - public Boolean visit(PlusCalAssignmentPair plusCalAssignmentPair) throws RuntimeException { - return plusCalAssignmentPair.getLhs().accept(expressionVisitor) && - plusCalAssignmentPair.getRhs().accept(expressionVisitor); - } -} - diff --git a/src/pgo/trans/passes/validation/NonModularPlusCalStatementValidationVisitor.java b/src/pgo/trans/passes/validation/NonModularPlusCalStatementValidationVisitor.java deleted file mode 100644 index 753ad2679..000000000 --- a/src/pgo/trans/passes/validation/NonModularPlusCalStatementValidationVisitor.java +++ /dev/null @@ -1,102 +0,0 @@ -package pgo.trans.passes.validation; - -import pgo.model.mpcal.ModularPlusCalYield; -import pgo.model.pcal.*; - -import java.util.List; - -public class NonModularPlusCalStatementValidationVisitor extends PlusCalStatementVisitor { - private final NonModularPlusCalTLAExpressionValidationVisitor visitor; - - public NonModularPlusCalStatementValidationVisitor() { - this.visitor = new NonModularPlusCalTLAExpressionValidationVisitor(); - } - - boolean validateStatements(List statements) { - return statements.stream().allMatch(s -> s.accept(this)); - } - - boolean validateDeclarations(List declarations) { - return declarations.stream().allMatch(d -> !d.isRef() && d.getValue().accept(visitor)); - } - - @Override - public Boolean visit(PlusCalLabeledStatements plusCalLabeledStatements) throws RuntimeException { - return validateStatements(plusCalLabeledStatements.getStatements()); - } - - @Override - public Boolean visit(PlusCalWhile plusCalWhile) throws RuntimeException { - return plusCalWhile.getCondition().accept(visitor) && validateStatements(plusCalWhile.getBody()); - } - - @Override - public Boolean visit(PlusCalIf plusCalIf) throws RuntimeException { - return plusCalIf.getCondition().accept(visitor) && - validateStatements(plusCalIf.getYes()) && - validateStatements(plusCalIf.getNo()); - } - - @Override - public Boolean visit(PlusCalEither plusCalEither) throws RuntimeException { - return plusCalEither.getCases().stream().allMatch(this::validateStatements); - } - - @Override - public Boolean visit(PlusCalAssignment plusCalAssignment) throws RuntimeException { - return plusCalAssignment - .getPairs() - .stream() - .allMatch(p -> p.getLhs().accept(visitor) && p.getRhs().accept(visitor)); - } - - @Override - public Boolean visit(PlusCalReturn plusCalReturn) throws RuntimeException { - return true; - } - - @Override - public Boolean visit(PlusCalSkip plusCalSkip) throws RuntimeException { - return true; - } - - @Override - public Boolean visit(PlusCalCall plusCalCall) throws RuntimeException { - return plusCalCall.getArguments().stream().allMatch(a -> a.accept(visitor)); - } - - @Override - public Boolean visit(PlusCalMacroCall macroCall) throws RuntimeException { - return macroCall.getArguments().stream().allMatch(a -> a.accept(visitor)); - } - - @Override - public Boolean visit(PlusCalWith plusCalWith) throws RuntimeException { - return validateDeclarations(plusCalWith.getVariables()) && validateStatements(plusCalWith.getBody()); - } - - @Override - public Boolean visit(PlusCalPrint plusCalPrint) throws RuntimeException { - return plusCalPrint.getValue().accept(visitor); - } - - @Override - public Boolean visit(PlusCalAssert plusCalAssert) throws RuntimeException { - return plusCalAssert.getCondition().accept(visitor); - } - - @Override - public Boolean visit(PlusCalAwait plusCalAwait) throws RuntimeException { - return plusCalAwait.getCondition().accept(visitor); - } - - @Override - public Boolean visit(PlusCalGoto plusCalGoto) throws RuntimeException { - return true; - } - - @Override - public Boolean visit(ModularPlusCalYield modularPlusCalYield) throws RuntimeException { - return false; - } -} diff --git a/src/pgo/trans/passes/validation/NonModularPlusCalTLAExpressionValidationVisitor.java b/src/pgo/trans/passes/validation/NonModularPlusCalTLAExpressionValidationVisitor.java deleted file mode 100644 index 55bbf17a8..000000000 --- a/src/pgo/trans/passes/validation/NonModularPlusCalTLAExpressionValidationVisitor.java +++ /dev/null @@ -1,184 +0,0 @@ -package pgo.trans.passes.validation; - -import pgo.TODO; -import pgo.model.tla.*; - -import java.util.List; - -public class NonModularPlusCalTLAExpressionValidationVisitor extends TLAExpressionVisitor { - private boolean validateExpressions(List expressions) { - return expressions.stream().allMatch(e -> e.accept(this)); - } - - private boolean validateBounds(List bounds) { - return bounds.stream().allMatch(b -> b.getSet().accept(this)); - } - - @Override - public Boolean visit(TLAFunctionCall tlaFunctionCall) throws RuntimeException { - return tlaFunctionCall.getFunction().accept(this) && validateExpressions(tlaFunctionCall.getParams()); - } - - @Override - public Boolean visit(TLABinOp tlaBinOp) throws RuntimeException { - return tlaBinOp.getLHS().accept(this) && tlaBinOp.getRHS().accept(this); - } - - @Override - public Boolean visit(TLABool tlaBool) throws RuntimeException { - return true; - } - - @Override - public Boolean visit(TLACase tlaCase) throws RuntimeException { - return tlaCase.getArms() - .stream() - .allMatch(a -> a.getCondition().accept(this) && a.getResult().accept(this)) && - (tlaCase.getOther() == null || tlaCase.getOther().accept(this)); - } - - @Override - public Boolean visit(TLADot tlaDot) throws RuntimeException { - return tlaDot.getExpression().accept(this); - } - - @Override - public Boolean visit(TLAExistential tlaExistential) throws RuntimeException { - return tlaExistential.getBody().accept(this); - } - - @Override - public Boolean visit(TLAFunction tlaFunction) throws RuntimeException { - return validateBounds(tlaFunction.getArguments()) && tlaFunction.getBody().accept(this); - } - - @Override - public Boolean visit(TLAFunctionSet tlaFunctionSet) throws RuntimeException { - return tlaFunctionSet.getFrom().accept(this) && tlaFunctionSet.getTo().accept(this); - } - - @Override - public Boolean visit(TLAFunctionSubstitution tlaFunctionSubstitution) throws RuntimeException { - return tlaFunctionSubstitution.getSource().accept(this) && - tlaFunctionSubstitution.getSubstitutions() - .stream() - .allMatch( - p -> p.getValue().accept(this) && - p.getKeys().stream().allMatch(k -> validateExpressions(k.getIndices()))); - } - - @Override - public Boolean visit(TLAIf tlaIf) throws RuntimeException { - return tlaIf.getCond().accept(this) && tlaIf.getTval().accept(this) && tlaIf.getFval().accept(this); - } - - @Override - public Boolean visit(TLALet tlaLet) throws RuntimeException { - throw new TODO(); - } - - @Override - public Boolean visit(TLAGeneralIdentifier tlaGeneralIdentifier) throws RuntimeException { - return true; - } - - @Override - public Boolean visit(TLATuple tlaTuple) throws RuntimeException { - return validateExpressions(tlaTuple.getElements()); - } - - @Override - public Boolean visit(TLAMaybeAction tlaMaybeAction) throws RuntimeException { - return tlaMaybeAction.getVars().accept(this) && tlaMaybeAction.getBody().accept(this); - } - - @Override - public Boolean visit(TLANumber tlaNumber) throws RuntimeException { - return true; - } - - @Override - public Boolean visit(TLAOperatorCall tlaOperatorCall) throws RuntimeException { - return validateExpressions(tlaOperatorCall.getArgs()); - } - - @Override - public Boolean visit(TLAQuantifiedExistential tlaQuantifiedExistential) throws RuntimeException { - return validateBounds(tlaQuantifiedExistential.getIds()) && tlaQuantifiedExistential.getBody().accept(this); - } - - @Override - public Boolean visit(TLAQuantifiedUniversal tlaQuantifiedUniversal) throws RuntimeException { - return validateBounds(tlaQuantifiedUniversal.getIds()) && tlaQuantifiedUniversal.getBody().accept(this); - } - - @Override - public Boolean visit(TLARecordConstructor tlaRecordConstructor) throws RuntimeException { - return tlaRecordConstructor.getFields().stream().allMatch(f -> f.getValue().accept(this)); - } - - @Override - public Boolean visit(TLARecordSet tlaRecordSet) throws RuntimeException { - return tlaRecordSet.getFields().stream().allMatch(f -> f.getSet().accept(this)); - } - - @Override - public Boolean visit(TLARequiredAction tlaRequiredAction) throws RuntimeException { - return tlaRequiredAction.getVars().accept(this) && tlaRequiredAction.getBody().accept(this); - } - - @Override - public Boolean visit(TLASetConstructor tlaSetConstructor) throws RuntimeException { - return validateExpressions(tlaSetConstructor.getContents()); - } - - @Override - public Boolean visit(TLASetComprehension tlaSetComprehension) throws RuntimeException { - return validateBounds(tlaSetComprehension.getBounds()) && tlaSetComprehension.getBody().accept(this); - } - - @Override - public Boolean visit(TLASetRefinement tlaSetRefinement) throws RuntimeException { - return tlaSetRefinement.getFrom().accept(this) && tlaSetRefinement.getWhen().accept(this); - } - - @Override - public Boolean visit(TLAString tlaString) throws RuntimeException { - return true; - } - - @Override - public Boolean visit(TLAUnary tlaUnary) throws RuntimeException { - return tlaUnary.getOperand().accept(this); - } - - @Override - public Boolean visit(TLAUniversal tlaUniversal) throws RuntimeException { - return tlaUniversal.getBody().accept(this); - } - - @Override - public Boolean visit(PlusCalDefaultInitValue plusCalDefaultInitValue) throws RuntimeException { - return true; - } - - @Override - public Boolean visit(TLAFairness tlaFairness) throws RuntimeException { - return true; - } - - @Override - public Boolean visit(TLASpecialVariableVariable tlaSpecialVariableVariable) throws RuntimeException { - return false; - } - - @Override - public Boolean visit(TLASpecialVariableValue tlaSpecialVariableValue) throws RuntimeException { - return false; - } - - @Override - public Boolean visit(TLARef tlaRef) throws RuntimeException { - return false; - } -} diff --git a/src/pgo/trans/passes/validation/NonRefParamModification.java b/src/pgo/trans/passes/validation/NonRefParamModification.java deleted file mode 100644 index 82b981916..000000000 --- a/src/pgo/trans/passes/validation/NonRefParamModification.java +++ /dev/null @@ -1,22 +0,0 @@ -package pgo.trans.passes.validation; - -import pgo.errors.Issue; -import pgo.errors.IssueVisitor; -import pgo.scope.UID; - -public class NonRefParamModification extends Issue { - private final UID declarationUID; - - public NonRefParamModification(UID declarationUID) { - this.declarationUID = declarationUID; - } - - public UID getDeclarationUID() { - return declarationUID; - } - - @Override - public T accept(IssueVisitor v) throws E { - return v.visit(this); - } -} diff --git a/src/pgo/trans/passes/validation/PlusCalStatementRejectionVisitor.java b/src/pgo/trans/passes/validation/PlusCalStatementRejectionVisitor.java deleted file mode 100644 index 88792e926..000000000 --- a/src/pgo/trans/passes/validation/PlusCalStatementRejectionVisitor.java +++ /dev/null @@ -1,179 +0,0 @@ -package pgo.trans.passes.validation; - -import pgo.Unreachable; -import pgo.errors.IssueContext; -import pgo.model.mpcal.ModularPlusCalYield; -import pgo.model.pcal.*; - -import java.util.List; - -public class PlusCalStatementRejectionVisitor extends PlusCalStatementVisitor { - enum Node { - LABELS, WHILE, IF, EITHER, ASSIGNMENT, RETURN, SKIP, CALL, - MACRO_CALL, WITH, PRINT, ASSERT, AWAIT, GOTO, YIELD - } - - IssueContext ctx; - List rejections; - - public PlusCalStatementRejectionVisitor(IssueContext ctx, List rejections) { - this.ctx = ctx; - this.rejections = rejections; - } - - @Override - public Void visit(PlusCalLabeledStatements plusCalLabeledStatements) throws RuntimeException { - if (this.rejections.contains(Node.LABELS)) { - ctx.error(new StatementNotAllowedIssue(plusCalLabeledStatements)); - } - - for(PlusCalStatement stmt : plusCalLabeledStatements.getStatements()) { - stmt.accept(this); - } - - return null; - } - - @Override - public Void visit(PlusCalWhile plusCalWhile) throws RuntimeException { - if (this.rejections.contains(Node.WHILE)) { - ctx.error(new StatementNotAllowedIssue(plusCalWhile)); - } - - for(PlusCalStatement stmt : plusCalWhile.getBody()) { - stmt.accept(this); - } - return null; - } - - @Override - public Void visit(PlusCalIf plusCalIf) throws RuntimeException { - if (this.rejections.contains(Node.IF)) { - ctx.error(new StatementNotAllowedIssue(plusCalIf)); - } - - for(PlusCalStatement stmt : plusCalIf.getYes()) { - stmt.accept(this); - } - for(PlusCalStatement stmt : plusCalIf.getNo()) { - stmt.accept(this); - } - return null; - } - - @Override - public Void visit(PlusCalEither plusCalEither) throws RuntimeException { - if (this.rejections.contains(Node.EITHER)) { - ctx.error(new StatementNotAllowedIssue(plusCalEither)); - } - - for(List list : plusCalEither.getCases()) { - for(PlusCalStatement stmt : list) { - stmt.accept(this); - } - } - return null; - } - - @Override - public Void visit(PlusCalAssignment plusCalAssignment) throws RuntimeException { - if (this.rejections.contains(Node.ASSIGNMENT)) { - ctx.error(new StatementNotAllowedIssue(plusCalAssignment)); - } - - return null; - } - - @Override - public Void visit(PlusCalReturn plusCalReturn) throws RuntimeException { - if (this.rejections.contains(Node.RETURN)) { - ctx.error(new StatementNotAllowedIssue(plusCalReturn)); - } - - return null; - } - - @Override - public Void visit(PlusCalSkip plusCalSkip) throws RuntimeException { - if (this.rejections.contains(Node.SKIP)) { - ctx.error(new StatementNotAllowedIssue(plusCalSkip)); - } - - return null; - } - - @Override - public Void visit(PlusCalCall plusCalCall) throws RuntimeException { - if (this.rejections.contains(Node.CALL)) { - ctx.error(new StatementNotAllowedIssue(plusCalCall)); - } - - return null; - } - - @Override - public Void visit(PlusCalMacroCall macroCall) throws RuntimeException { - if (this.rejections.contains(Node.MACRO_CALL)) { - ctx.error(new StatementNotAllowedIssue(macroCall)); - } - - throw new Unreachable(); - } - - @Override - public Void visit(PlusCalWith plusCalWith) throws RuntimeException { - if (this.rejections.contains(Node.WITH)) { - ctx.error(new StatementNotAllowedIssue(plusCalWith)); - } - - for(PlusCalStatement stmt : plusCalWith.getBody()) { - stmt.accept(this); - } - return null; - } - - @Override - public Void visit(PlusCalPrint plusCalPrint) throws RuntimeException { - if (this.rejections.contains(Node.PRINT)) { - ctx.error(new StatementNotAllowedIssue(plusCalPrint)); - } - - return null; - } - - @Override - public Void visit(PlusCalAssert plusCalAssert) throws RuntimeException { - if (this.rejections.contains(Node.ASSERT)) { - ctx.error(new StatementNotAllowedIssue(plusCalAssert)); - } - - return null; - } - - @Override - public Void visit(PlusCalAwait plusCalAwait) throws RuntimeException { - if (this.rejections.contains(Node.AWAIT)) { - ctx.error(new StatementNotAllowedIssue(plusCalAwait)); - } - - return null; - } - - @Override - public Void visit(PlusCalGoto plusCalGoto) throws RuntimeException { - if (this.rejections.contains(Node.GOTO)) { - ctx.error(new StatementNotAllowedIssue(plusCalGoto)); - } - - return null; - } - - @Override - public Void visit(ModularPlusCalYield modularPlusCalYield) throws RuntimeException { - if (this.rejections.contains(Node.YIELD)) { - ctx.error(new StatementNotAllowedIssue(modularPlusCalYield)); - } - - return null; - } -} diff --git a/src/pgo/trans/passes/validation/ReservedLabelNameIssue.java b/src/pgo/trans/passes/validation/ReservedLabelNameIssue.java deleted file mode 100644 index bdc0c3df3..000000000 --- a/src/pgo/trans/passes/validation/ReservedLabelNameIssue.java +++ /dev/null @@ -1,57 +0,0 @@ -package pgo.trans.passes.validation; - -import pgo.errors.Issue; -import pgo.errors.IssueVisitor; -import pgo.formatters.IndentingWriter; -import pgo.formatters.IssueFormattingVisitor; -import pgo.model.pcal.PlusCalStatement; - -import java.io.IOException; -import java.io.StringWriter; - -public class ReservedLabelNameIssue extends Issue { - - private final PlusCalStatement statement; - - public ReservedLabelNameIssue(PlusCalStatement statement) { - this.statement = statement; - } - - public PlusCalStatement getStatement() { - return this.statement; - } - - public T accept(IssueVisitor v) throws E { - return v.visit(this); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - - if (obj == null) - return false; - - if (this.getClass() != obj.getClass()) - return false; - - ReservedLabelNameIssue other = (ReservedLabelNameIssue) obj; - - return this.getStatement().equals(other.getStatement()); - } - - @Override - public String toString() { - StringWriter w = new StringWriter(); - IndentingWriter out = new IndentingWriter(w); - - try { - this.accept(new IssueFormattingVisitor(out)); - } catch (IOException err) { - throw new RuntimeException("Error formatting issue", err); - } - - return w.toString(); - } -} \ No newline at end of file diff --git a/src/pgo/trans/passes/validation/StatementNotAllowedIssue.java b/src/pgo/trans/passes/validation/StatementNotAllowedIssue.java deleted file mode 100644 index 2eb8beacf..000000000 --- a/src/pgo/trans/passes/validation/StatementNotAllowedIssue.java +++ /dev/null @@ -1,57 +0,0 @@ -package pgo.trans.passes.validation; - -import pgo.errors.Issue; -import pgo.errors.IssueVisitor; -import pgo.formatters.IndentingWriter; -import pgo.formatters.IssueFormattingVisitor; -import pgo.model.pcal.PlusCalStatement; - -import java.io.IOException; -import java.io.StringWriter; - -public class StatementNotAllowedIssue extends Issue { - - private final PlusCalStatement statement; - - public StatementNotAllowedIssue(PlusCalStatement statement) { - this.statement = statement; - } - - public PlusCalStatement getStatement() { - return this.statement; - } - - public T accept(IssueVisitor v) throws E { - return v.visit(this); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - - if (obj == null) - return false; - - if (this.getClass() != obj.getClass()) - return false; - - StatementNotAllowedIssue other = (StatementNotAllowedIssue) obj; - - return this.getStatement().equals(other.getStatement()); - } - - @Override - public String toString() { - StringWriter w = new StringWriter(); - IndentingWriter out = new IndentingWriter(w); - - try { - this.accept(new IssueFormattingVisitor(out)); - } catch (IOException err) { - throw new RuntimeException("Error formatting issue", err); - } - - return w.toString(); - } -} \ No newline at end of file diff --git a/src/pgo/trans/passes/validation/TLAExpressionLHSModificationValidationVisitor.java b/src/pgo/trans/passes/validation/TLAExpressionLHSModificationValidationVisitor.java deleted file mode 100644 index 02cdb852b..000000000 --- a/src/pgo/trans/passes/validation/TLAExpressionLHSModificationValidationVisitor.java +++ /dev/null @@ -1,196 +0,0 @@ -package pgo.trans.passes.validation; - -import pgo.Unreachable; -import pgo.errors.IssueContext; -import pgo.model.tla.*; -import pgo.scope.UID; -import pgo.trans.intermediate.DefinitionRegistry; - -import java.util.Set; - -public class TLAExpressionLHSModificationValidationVisitor extends TLAExpressionVisitor { - private final IssueContext ctx; - private final DefinitionRegistry registry; - private final Set nonRefParams; - - public TLAExpressionLHSModificationValidationVisitor(IssueContext ctx, DefinitionRegistry registry, - Set nonRefParams) { - this.ctx = ctx; - this.registry = registry; - this.nonRefParams = nonRefParams; - } - - @Override - public Void visit(TLAFunctionCall tlaFunctionCall) throws RuntimeException { - // no need to check params because they are only read - tlaFunctionCall.getFunction().accept(this); - return null; - } - - @Override - public Void visit(TLABinOp tlaBinOp) throws RuntimeException { - tlaBinOp.getLHS().accept(this); - tlaBinOp.getRHS().accept(this); - return null; - } - - @Override - public Void visit(TLABool tlaBool) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLACase tlaCase) throws RuntimeException { - for (TLACaseArm arm : tlaCase.getArms()) { - // no need to check condition because they are only read - arm.getResult().accept(this); - } - tlaCase.getOther().accept(this); - return null; - } - - @Override - public Void visit(TLADot tlaDot) throws RuntimeException { - tlaDot.getExpression().accept(this); - return null; - } - - @Override - public Void visit(TLAExistential tlaExistential) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLAFairness tlaFairness) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLAFunction tlaFunction) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLAFunctionSet tlaFunctionSet) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLAFunctionSubstitution tlaFunctionSubstitution) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLAIf tlaIf) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLALet tlaLet) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLAGeneralIdentifier tlaGeneralIdentifier) throws RuntimeException { - UID varUID = registry.followReference(tlaGeneralIdentifier.getUID()); - if (nonRefParams.contains(varUID)) { - ctx.error(new NonRefParamModification(varUID)); - } - return null; - } - - @Override - public Void visit(TLATuple tlaTuple) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLAMaybeAction tlaMaybeAction) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLANumber tlaNumber) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLAOperatorCall tlaOperatorCall) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLAQuantifiedExistential tlaQuantifiedExistential) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLAQuantifiedUniversal tlaQuantifiedUniversal) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLARecordConstructor tlaRecordConstructor) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLARecordSet tlaRecordSet) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLARef tlaRef) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLARequiredAction tlaRequiredAction) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLASetConstructor tlaSetConstructor) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLASetComprehension tlaSetComprehension) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLASetRefinement tlaSetRefinement) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLASpecialVariableVariable tlaSpecialVariableVariable) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLASpecialVariableValue tlaSpecialVariableValue) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLAString tlaString) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLAUnary tlaUnary) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(TLAUniversal tlaUniversal) throws RuntimeException { - throw new Unreachable(); - } - - @Override - public Void visit(PlusCalDefaultInitValue plusCalDefaultInitValue) throws RuntimeException { - throw new Unreachable(); - } -} diff --git a/src/pgo/trans/passes/validation/ValidationPass.java b/src/pgo/trans/passes/validation/ValidationPass.java deleted file mode 100644 index 69be6934d..000000000 --- a/src/pgo/trans/passes/validation/ValidationPass.java +++ /dev/null @@ -1,101 +0,0 @@ -package pgo.trans.passes.validation; - -import pgo.errors.IssueContext; -import pgo.errors.TopLevelIssueContext; -import pgo.model.mpcal.*; -import pgo.model.pcal.PlusCalStatement; -import pgo.model.pcal.PlusCalVariableDeclaration; -import pgo.model.tla.TLAExpression; -import pgo.model.tla.TLAGeneralIdentifier; -import pgo.model.tla.TLARef; -import pgo.scope.UID; -import pgo.trans.intermediate.DefinitionRegistry; - -import java.util.*; - -public class ValidationPass { - private ValidationPass() {} - - public static void perform(IssueContext ctx, ModularPlusCalBlock mpcal) { - mpcal.accept(new ModularPlusCalValidationVisitor(ctx)); - } - - /** - * * Only local or `ref` variables can be assigned to - * * Parameters can only be used as functions if they were mapped as functions when - * instantiated (similarly, they cannot be used as variables if mapped as functions) - */ - public static void performPostScoping(TopLevelIssueContext ctx, DefinitionRegistry registry, - ModularPlusCalBlock modularPlusCalBlock) { - Map archetypesToInstance = new HashMap<>(); - for (ModularPlusCalInstance instance : modularPlusCalBlock.getInstances()) { - Map seenVars = new HashMap<>(); - List arguments = instance.getArguments(); - for (int i = 0; i < arguments.size(); i++) { - TLAExpression argument = arguments.get(i); - if (argument instanceof TLAGeneralIdentifier || argument instanceof TLARef) { - UID varUID = registry.followReference(argument.getUID()); - if (seenVars.containsKey(varUID)) { - ctx.error(new VariableMappedMultipleTimesIssue(varUID, instance)); - continue; - } - // 0-indexing - seenVars.put(varUID, i); - } - } - ModularPlusCalArchetype archetype = registry.findArchetype(instance.getTarget()); - boolean[] signature = new boolean[instance.getArguments().size()]; - for (ModularPlusCalMapping mapping : instance.getMappings()) { - ModularPlusCalMappingVariable variable = mapping.getVariable(); - UID varUID = registry.followReference(variable.getUID()); - if (seenVars.containsKey(varUID)) { - // 0-indexing - signature[seenVars.get(varUID)] = variable.isFunctionCall(); - } else if (variable instanceof ModularPlusCalMappingVariablePosition) { - signature[((ModularPlusCalMappingVariablePosition) variable).getPosition() - 1] = - variable.isFunctionCall(); - } - } - Optional optionalExistingSignature = registry.getSignature(archetype.getUID()); - if (!optionalExistingSignature.isPresent()) { - registry.putSignature(archetype.getUID(), signature); - archetypesToInstance.put(archetype.getUID(), instance); - continue; - } - boolean[] existingSignature = optionalExistingSignature.get(); - for (int i = 0; i < signature.length; i++) { - if (existingSignature[i] != signature[i]) { - ctx.error(new InconsistentInstantiationIssue( - instance, archetypesToInstance.get(archetype.getUID()))); - break; - } - } - } - for (ModularPlusCalArchetype archetype : modularPlusCalBlock.getArchetypes()) { - Set nonRefParams = new HashSet<>(); - for (PlusCalVariableDeclaration param : archetype.getParams()) { - if (!param.isRef()) { - nonRefParams.add(param.getUID()); - } - } - ModularPlusCalModificationValidationVisitor visitor = - new ModularPlusCalModificationValidationVisitor(ctx, registry, nonRefParams); - - // only validate usage if the archetype is actually instantiated - if (modularPlusCalBlock.getInstantiatedArchetypes().contains(archetype)) { - Map functionMapped = new HashMap<>(); - boolean[] signature = registry.getSignature(archetype.getUID()) - .orElseGet(() -> new boolean[archetype.getParams().size()]); - List params = archetype.getParams(); - for (int i = 0; i < params.size(); i++) { - PlusCalVariableDeclaration param = params.get(i); - functionMapped.put(param.getUID(), signature[i]); - } - for (PlusCalStatement statement : archetype.getBody()) { - statement.accept(visitor); - statement.accept(new ModularPlusCalStatementValidationVisitor(ctx, registry, functionMapped)); - } - } - } - } -} diff --git a/src/pgo/trans/passes/validation/VariableMappedMultipleTimesIssue.java b/src/pgo/trans/passes/validation/VariableMappedMultipleTimesIssue.java deleted file mode 100644 index cc8a19f40..000000000 --- a/src/pgo/trans/passes/validation/VariableMappedMultipleTimesIssue.java +++ /dev/null @@ -1,29 +0,0 @@ -package pgo.trans.passes.validation; - -import pgo.errors.Issue; -import pgo.errors.IssueVisitor; -import pgo.model.mpcal.ModularPlusCalInstance; -import pgo.scope.UID; - -public class VariableMappedMultipleTimesIssue extends Issue { - private final UID varUID; - private final ModularPlusCalInstance instance; - - public VariableMappedMultipleTimesIssue(UID varUID, ModularPlusCalInstance instance) { - this.varUID = varUID; - this.instance = instance; - } - - public UID getVarUID() { - return varUID; - } - - public ModularPlusCalInstance getInstance() { - return instance; - } - - @Override - public T accept(IssueVisitor v) throws E { - return v.visit(this); - } -} diff --git a/src/pgo/util/ConsList.java b/src/pgo/util/ConsList.java deleted file mode 100644 index e14213d58..000000000 --- a/src/pgo/util/ConsList.java +++ /dev/null @@ -1,53 +0,0 @@ -package pgo.util; - -import java.util.ArrayList; -import java.util.List; - -public final class ConsList { - - private static final class Node { - private final T value; - private final Node next; - - public Node(T value, Node next) { - this.value = value; - this.next = next; - } - - public T getValue() { return value; } - public Node getNext() { return next; } - } - - private final Node root; - - public ConsList() { - this.root = null; - } - - private ConsList(Node root) { - this.root = root; - } - - public T first() { return root.getValue(); } - public ConsList rest() { return new ConsList<>(root.getNext()); } - - public ConsList cons(T value) { - return new ConsList<>(new Node<>(value, root)); - } - - @Override - public String toString() { - return toList().toString(); - } - - public List toList() { - List result = new ArrayList<>(); - Node rootCopy = root; - while(rootCopy != null) { - result.add(rootCopy.getValue()); - rootCopy = rootCopy.getNext(); - } - return result; - } - -} diff --git a/src/pgo/util/Derived.java b/src/pgo/util/Derived.java deleted file mode 100644 index 28ae4c45f..000000000 --- a/src/pgo/util/Derived.java +++ /dev/null @@ -1,35 +0,0 @@ -package pgo.util; - -import java.util.ArrayList; -import java.util.List; - -/** - * - * Something that was derived from something else. - * - * This helps us track where things came from in PGo if an error occurs. - * - */ -public abstract class Derived implements Origin { - List origins; - - public Derived() { - this.origins = new ArrayList<>(); - } - - public Derived addOrigin(Origin origin) { - origins.add(origin); - return this; - } - - public List getOrigins(){ - return origins; - } - - public T accept(OriginVisitor v) throws E { - return v.visit(this); - } - - public abstract T accept(DerivedVisitor v) throws E; - -} diff --git a/src/pgo/util/DerivedVisitor.java b/src/pgo/util/DerivedVisitor.java deleted file mode 100644 index a34def53f..000000000 --- a/src/pgo/util/DerivedVisitor.java +++ /dev/null @@ -1,15 +0,0 @@ -package pgo.util; - -import pgo.model.type.constraint.MonomorphicConstraint; -import pgo.model.type.Type; -import pgo.model.type.constraint.PolymorphicConstraint; -import pgo.scope.UID; -import pgo.trans.intermediate.OperatorAccessor; - -public abstract class DerivedVisitor { - public abstract T visit(UID uid) throws E; - public abstract T visit(OperatorAccessor operatorAccessor) throws E; - public abstract T visit(Type type) throws E; - public abstract T visit(MonomorphicConstraint pGoTypeMonomorphicConstraint) throws E; - public abstract T visit(PolymorphicConstraint pGoTypePolymorphicConstraint) throws E; -} diff --git a/src/pgo/util/Description.scala b/src/pgo/util/Description.scala new file mode 100644 index 000000000..bdd3fb3eb --- /dev/null +++ b/src/pgo/util/Description.scala @@ -0,0 +1,147 @@ +package pgo.util + +import scala.collection.{AbstractIterator, View, mutable} + +private sealed abstract class DescriptionPart +private case object DescriptionLineBreakPart extends DescriptionPart +private case object DescriptionEnsureLineBreakPart extends DescriptionPart +private case object DescriptionIndentPart extends DescriptionPart +private case object DescriptionDedentPart extends DescriptionPart +private final case class DescriptionStringPart(str: String) extends DescriptionPart +private final case class DescriptionEmbedPart(embed: Any) extends DescriptionPart + +final class Description private (private val parts: View[DescriptionPart]) { + def indented: Description = + new Description(View(DescriptionIndentPart) ++ parts ++ View(DescriptionDedentPart)) + + def ensureLineBreakBefore: Description = + new Description(View(DescriptionEnsureLineBreakPart) ++ parts) + + def ensureLineBreakAfter: Description = + new Description(parts ++ View(DescriptionEnsureLineBreakPart)) + + def linesIterator: Iterator[String] = + new AbstractIterator[String] { + private val partsIterator = parts.iterator.flatMap { + case DescriptionEmbedPart(embed) => Description.stringToDescriptionParts(embed.toString) + case part => Iterator.single(part) + } + private var atStart = true // used to detect the "first line", for ensuring leading line breaks work properly + // note: semantically, the start of the description is at the beginning of a new line + private var hasNewLine = true // are we at the beginning of a new line? + private var indent = 0 // the indentation to apply after a new line, if the following line has any contents + private val lineBuilder = new StringBuilder() + private var nextLine: String = _ + + private def gatherNextLine(): Unit = { + nextLine = null + while((nextLine eq null) && partsIterator.hasNext) { + partsIterator.next() match { + case DescriptionLineBreakPart => + atStart = false + hasNewLine = true + nextLine = lineBuilder.result() + lineBuilder.clear() + case DescriptionEnsureLineBreakPart => + if(!hasNewLine || atStart) { + atStart = false + hasNewLine = true + nextLine = lineBuilder.result() + lineBuilder.clear() + } + case DescriptionIndentPart => + indent += 2 + case DescriptionDedentPart => + indent -= 2 + case DescriptionStringPart(str) => + atStart = false + if(hasNewLine) { + hasNewLine = false + (0 until indent).foreach(_ => lineBuilder += ' ') + } + lineBuilder.addAll(str) + case DescriptionEmbedPart(_) => ??? // should be unreachable + } + } + // lineBuilder.nonEmpty ==> make sure to output trailing strings without a new line following them + // hasNewLine ==> make sure to output trailing new lines + if((lineBuilder.nonEmpty || hasNewLine) && (nextLine eq null)) { + hasNewLine = false // if a trailing new line is output, make sure we stop there + nextLine = lineBuilder.result() + lineBuilder.clear() + } + } + + gatherNextLine() + + override def hasNext: Boolean = nextLine ne null + + override def next(): String = { + val line = nextLine + gatherNextLine() + line + } + } +} + +object Description { + private def stringToDescriptionParts(str: String): View[DescriptionPart] = { + var i = 0 + val partsBuffer = mutable.ListBuffer[DescriptionPart]() + val partBuilder = new StringBuilder + while(i < str.length) { + if(str.charAt(i) == '\n') { + partsBuffer += DescriptionStringPart(partBuilder.result()) + partsBuffer += DescriptionLineBreakPart + partBuilder.clear() + } else { + partBuilder += str.charAt(i) + } + i += 1 + } + if(partBuilder.nonEmpty) { + partsBuffer += DescriptionStringPart(partBuilder.result()) + } + partsBuffer.result().view + } + + implicit class IterableFlattenDescriptions(val descList: Iterable[Description]) extends AnyVal { + def flattenDescriptions: Description = + new Description(descList.view.flatMap(_.parts)) + } + + implicit class StringToDescription(val str: String) extends AnyVal { + def toDescription: Description = + new Description(stringToDescriptionParts(str)) + } + + implicit class DescriptionHelper(val ctx: StringContext) extends AnyVal { + private def mkDesc(parts: Seq[String], args: Seq[Any]): Description = { + val parts = Description.stringToDescriptionParts(StringContext.processEscapes(ctx.parts.head)) ++ + (args.view zip ctx.parts.view.tail).flatMap { + case (arg, part) => + (arg match { + case arg: Description => arg.parts + case str: String => Description.stringToDescriptionParts(str) + case any => View(DescriptionEmbedPart(any)) + }) ++ Description.stringToDescriptionParts(StringContext.processEscapes(part)) + } + new Description(parts) + } + + def d(args: Any*): Description = mkDesc(ctx.parts, args) + + def dd(args: Any*): Description = { + var foundPipe = false + val mappedParts = ctx.parts.map { part => + StringContext.processEscapes(part).flatMap { + case '\n' => foundPipe = false; "\n" + case _ if !foundPipe => "" + case '|' => foundPipe = true; "" + case ch => ch.toString + } + } + mkDesc(mappedParts, args) + } + } +} diff --git a/src/pgo/util/EmptyHeterogenousList.java b/src/pgo/util/EmptyHeterogenousList.java deleted file mode 100644 index 86f2428c9..000000000 --- a/src/pgo/util/EmptyHeterogenousList.java +++ /dev/null @@ -1,24 +0,0 @@ -package pgo.util; - -/** - * This class represents an empty {@link HeterogenousList}. This will always be the final tail of such a list. - * - *

    Interestingly, all heterogenous lists are subtypes of this list so it is actually possible to pass a - * longer list as where a shorter one was needed and have everything work.

    - */ -public class EmptyHeterogenousList { - /** - * @return whether this list is empty - */ - public boolean isEmpty(){ return true; } - - /** - * Produces a new list with {@param first} as the head element and the current list as the tail - * @param first the first element of the new list - * @param the type of {@param first} - * @return a new list with {@param first} as the first element and this list as the tail - */ - public HeterogenousList cons(First first) { - return new HeterogenousList<>(first, this); - } -} diff --git a/src/pgo/util/HeterogenousList.java b/src/pgo/util/HeterogenousList.java deleted file mode 100644 index 7f3c7dc33..000000000 --- a/src/pgo/util/HeterogenousList.java +++ /dev/null @@ -1,47 +0,0 @@ -package pgo.util; - -/** - * Represents a typesafe heterogenous list. - * - *

    This list is very limited compared to the typical {@link java.util.List}, but in exchange you can - * prepend elements of any type to it and retrieve them without having to risk a type-unsafe downcast.

    - * - *

    The lists's properties are achieved by creating a linked list where the type of the tail is irrelevant - * to each node of the list but is known to the typechecker, such that it can infer complete types for - * the two accessor methods.

    - * - *

    The most notable caveat is that it is either very hard or impossible to deal with arbitrarily-long lists - * of this kind. Luckily the main use for them is as the result of {@link pgo.parser.AbstractSequenceGrammar}, - * whose length is known at compile-time.

    - * @param the type of the head of this list - * @param the type of the tail of this list, recursively also a list. - */ -public final class HeterogenousList extends EmptyHeterogenousList { - - private final First first; - private final Rest rest; - - public HeterogenousList(First first, Rest rest) { - this.first = first; - this.rest = rest; - } - - /** - * @return the head, or first element of this list - */ - public First getFirst() { - return first; - } - - /** - * @return the tail of this list, which is also a list. - */ - public Rest getRest() { - return rest; - } - - @Override - public boolean isEmpty() { - return false; - } -} diff --git a/src/pgo/util/IdMap.scala b/src/pgo/util/IdMap.scala new file mode 100644 index 000000000..3a12c8122 --- /dev/null +++ b/src/pgo/util/IdMap.scala @@ -0,0 +1,55 @@ +package pgo.util + +import scala.collection.immutable.{Iterable, Map, MapOps} +import scala.collection.{MapFactory, MapFactoryDefaults, mutable} + +class IdMap[K, +V] private (underlying: Map[IdMap.Id[K],V]) extends Iterable[(K, V)] with MapOps[K, V, IdMap, IdMap[K, V]] with MapFactoryDefaults[K, V, IdMap, Iterable] { + import IdMap.Id + + override def removed(key: K): IdMap[K, V] = + new IdMap(underlying.removed(new Id(key))) + + override def updated[V1 >: V](key: K, value: V1): IdMap[K, V1] = + new IdMap(underlying.updated(new Id(key), value)) + + override def get(key: K): Option[V] = underlying.get(new Id(key)) + + override def iterator: Iterator[(K, V)] = underlying.iterator.map { + case (idKey, value) => (idKey.t, value) + } + + override def toString(): String = + s"IdMap(${iterator.mkString(",")})" + + override def mapFactory: MapFactory[IdMap] = IdMap +} + +object IdMap extends MapFactory[IdMap] { + private class Id[T](val t: T) { + override def equals(obj: Any): Boolean = + obj match { + case other: Id[_] => t.asInstanceOf[AnyRef] eq other.t.asInstanceOf[AnyRef] + case _ => false + } + + override def hashCode(): Int = System.identityHashCode(t) + } + + override def empty[K, V]: IdMap[K, V] = new IdMap(Map.empty[Id[K],V]) + + override def from[K, V](it: IterableOnce[(K, V)]): IdMap[K, V] = + new IdMap(Map.from(it.iterator.map { case key -> value => new Id(key) -> value })) + + override def newBuilder[K, V]: mutable.Builder[(K, V), IdMap[K, V]] = new mutable.Builder[(K, V), IdMap[K, V]] { + private val underlying = Map.newBuilder[Id[K], V] + + override def clear(): Unit = underlying.clear() + + override def result(): IdMap[K, V] = new IdMap(underlying.result()) + + override def addOne(elem: (K, V)): this.type = { + underlying.addOne((new Id(elem._1), elem._2)) + this + } + } +} diff --git a/src/pgo/util/IdSet.scala b/src/pgo/util/IdSet.scala new file mode 100644 index 000000000..ae1dad528 --- /dev/null +++ b/src/pgo/util/IdSet.scala @@ -0,0 +1,56 @@ +package pgo.util + +import scala.collection.immutable.{Iterable, Set, SetOps} +import scala.collection.{IterableFactory, IterableFactoryDefaults, mutable} + +class IdSet[V] private (underlying: Set[IdSet.Id[V]]) extends Iterable[V] with SetOps[V, IdSet, IdSet[V]] with IterableFactoryDefaults[V, IdSet] { + import IdSet.Id + + override def incl(elem: V): IdSet[V] = + new IdSet(underlying.incl(new Id(elem))) + + override def excl(elem: V): IdSet[V] = + new IdSet(underlying.excl(new Id(elem))) + + override def contains(elem: V): Boolean = + underlying.contains(new Id(elem)) + + override def iterator: Iterator[V] = + underlying.iterator.map(_.t) + + override def toString: String = + s"IdSet(${iterator.mkString(",")})" + + override def iterableFactory: IterableFactory[IdSet] = IdSet +} + +object IdSet extends IterableFactory[IdSet] { + private class Id[T](val t: T) { + override def equals(obj: Any): Boolean = + obj match { + case other: Id[_] => t.asInstanceOf[AnyRef] eq other.t.asInstanceOf[AnyRef] + case _ => false + } + + override def hashCode(): Int = System.identityHashCode(t) + } + + override def from[A](source: IterableOnce[A]): IdSet[A] = + new IdSet(Set.from(source.iterator.map(new Id(_)))) + + override def empty[A]: IdSet[A] = + new IdSet(Set.empty) + + override def newBuilder[A]: mutable.Builder[A, IdSet[A]] = new mutable.Builder[A, IdSet[A]] { + private val underlying = Set.newBuilder[Id[A]] + + override def clear(): Unit = underlying.clear() + + override def result(): IdSet[A] = new IdSet(underlying.result()) + + override def addOne(elem: A): this.type = { + underlying.addOne(new Id(elem)) + this + } + } +} diff --git a/src/pgo/util/MPCalPassUtils.scala b/src/pgo/util/MPCalPassUtils.scala new file mode 100644 index 000000000..e2e08f2d0 --- /dev/null +++ b/src/pgo/util/MPCalPassUtils.scala @@ -0,0 +1,163 @@ +package pgo.util + +import pgo.model.{Definition, DefinitionOne, DerivedSourceLocation, PGoError, RefersTo, Rewritable, SourceLocatable, SourceLocation, Visitable} +import pgo.model.mpcal._ +import pgo.model.pcal._ +import pgo.model.tla._ +import Description._ + +import scala.collection.mutable + +object MPCalPassUtils { + def forEachName(tlaModule: TLAModule, mpcalBlock: MPCalBlock)(fn: String => Unit): Unit = { + tlaModule.moduleDefinitions(captureLocal = true).foreach { defn => + defn.identifier match { + case Definition.ScopeIdentifierName(name) => fn(name.id) + case Definition.ScopeIdentifierSymbol(symbol) => symbol.symbol.representations.foreach(fn) + } + } + mpcalBlock.visit(Visitable.BottomUpFirstStrategy) { + case ident: TLAIdentifier => fn(ident.id) + case PCalLabeledStatements(label, _) => fn(label.name) + } + } + + def forEachBody(mpcalBlock: MPCalBlock)(fn: (List[PCalStatement], Map[String,DefinitionOne]) => Unit): Unit = + rewriteEachBody(mpcalBlock) { (body, lexicalScope) => + fn(body, lexicalScope) + body + } + + def rewriteEachBody(mpcalBlock: MPCalBlock)(fn: (List[PCalStatement], Map[String,DefinitionOne]) => List[PCalStatement]): MPCalBlock = + mpcalBlock.rewrite(Rewritable.TopDownFirstStrategy) { + case blk @MPCalMappingMacro(name, readBody, writeBody, freeVars) => + val lexicalScope = freeVars.view.map(v => v.id.id -> v).toMap + blk.withChildren(Iterator( + name, + fn(readBody, lexicalScope), + fn(writeBody, lexicalScope), + freeVars)) + case blk @PCalMacro(name, params, body, freeVars) => + blk.withChildren(Iterator( + name, params, + fn(body, (params.view.map(p => p.id.id -> p) ++ freeVars.view.map(v => v.id.id -> v)).toMap), + freeVars)) + case blk @PCalProcedure(name, params, variables, body) => + blk.withChildren(Iterator( + name, params, variables, + fn(body, (params.view.map(p => p.name.id -> p) ++ variables.view.map(v => v.name.id -> v)).toMap))) + case blk @MPCalProcedure(name, params, variables, body) => + blk.withChildren(Iterator( + name, params, variables, + fn(body, (params.view.map(p => p.name.id -> p) ++ variables.view.map(v => v.name.id -> v)).toMap))) + case blk @PCalProcess(selfDecl, fairness, variables, body) => + blk.withChildren(Iterator( + selfDecl, fairness, variables, + fn(body, variables.view.map(v => v.name.id -> v).toMap.updated("self", selfDecl)))) + case blk @MPCalArchetype(name, selfDecl, params, variables, body) => + blk.withChildren(Iterator( + name, selfDecl, params, variables, + fn(body, (params.view.map(p => p.name.id -> p) ++ variables.view.map(v => v.name.id -> v)).toMap.updated("self", selfDecl)))) + } + + final case class MacroExpandError(override val errors: List[PGoError.Error]) extends PGoError + + object MacroExpandError { + sealed abstract class Error(override val sourceLocation: SourceLocation, override val description: Description) extends PGoError.Error + + final case class ArgumentCountMismatchError(callNode: PCalMacroCall, definedAtNode: PCalMacro) extends Error( + callNode.sourceLocation, d"expected ${definedAtNode.params.size} arguments, as defined at ${ + definedAtNode.sourceLocation.longDescription + }\n but got ${callNode.arguments.size} instead") + + final case class UnboundFreeVariableError(freeVar: TLADefiningIdentifier, callNode: PCalMacroCall) extends Error( + freeVar.sourceLocation, d"macro call at ${ + callNode.sourceLocation.longDescription + }\n does not contextually bind free variable ${freeVar.id.id}") + + final case class MacroExpandAssignmentLhsError(lhs: PCalAssignmentLhsIdentifier, badExpr: TLAExpression) extends Error( + lhs.sourceLocation, d"during macro expansion, an expression that is not a plain identifier, coming from ${ + badExpr.sourceLocation.longDescription + }, would be expanded as a PlusCal assignment LHS") + } + + def expandMacroCall(pcalMacroCall: PCalMacroCall, enclosingScope: Map[String,DefinitionOne]): List[PCalStatement] = { + val m = pcalMacroCall.refersTo + val errors = mutable.ListBuffer[PGoError.Error]() + + if(pcalMacroCall.arguments.size != m.params.size) { + errors += MacroExpandError.ArgumentCountMismatchError(pcalMacroCall, m) + } + val paramsMap: Map[DefinitionOne,TLAExpression] = (m.params.iterator zip pcalMacroCall.arguments.iterator).toMap + + // make sure all free vars refer to something reasonable, and build a map of those references + val referenceMapping: Map[DefinitionOne,DefinitionOne] = m.freeVars.iterator.flatMap { fv => + enclosingScope.get(fv.id.id) match { + case Some(defn) => Iterator.single(fv -> defn) + case None => + errors += MacroExpandError.UnboundFreeVariableError(fv, pcalMacroCall) + Iterator.empty + } + }.toMap + + if(errors.nonEmpty) { + throw MacroExpandError(errors.result()) + } + + // substitute out references to macro args; shallow-copy everything in order to add the macro expansion to + // the source location. + // side-effect: all nodes are effectively deep-copied, except macro args that should not refer to the macro's free vars, + // so we can mutate refersTo below without worrying about sharing + val body: List[PCalStatement] = m.body.map(_.rewrite(Rewritable.BottomUpOnceStrategy) { + case ref: PCalAssignmentLhsIdentifier if paramsMap.contains(ref.refersTo) => + paramsMap(ref.refersTo) match { + case ident @TLAGeneralIdentifier(name, Nil) => + PCalAssignmentLhsIdentifier(name) + .setSourceLocation(ident.sourceLocation) + .setRefersTo(ident.refersTo) + case badExpr => + throw MacroExpandError(List(MacroExpandError.MacroExpandAssignmentLhsError(ref, badExpr))) + } + case ref: RefersTo[TLADefiningIdentifier] if paramsMap.contains(ref.refersTo) => + paramsMap(ref.refersTo): TLAExpression + case ref: SourceLocatable => + ref.shallowCopy().setSourceLocation( + DerivedSourceLocation(ref.sourceLocation, pcalMacroCall.sourceLocation, d"macro expansion")) + }) + + // remap all the references to free variables to point to what the free vars point to (relies on duplication, from above) + body.foreach(_.visit(Visitable.BottomUpFirstStrategy) { + case ref: RefersTo[DefinitionOne] if referenceMapping.contains(ref.refersTo) => + ref.setRefersTo(referenceMapping(ref.refersTo)) + }) + body + } + + def expandMacroCalls(stmts: List[PCalStatement], enclosingScope: Map[String,DefinitionOne]): List[PCalStatement] = + stmts.flatMap { + case stmt @PCalIf(condition, yes, no) => + List(stmt.withChildren(Iterator( + condition, + expandMacroCalls(yes, enclosingScope), + expandMacroCalls(no, enclosingScope)))) + case stmt @PCalEither(cases) => + List(stmt.withChildren(Iterator(cases.map(expandMacroCalls(_, enclosingScope))))) + case stmt @PCalLabeledStatements(label, statements) => + List(stmt.withChildren(Iterator( + label, + expandMacroCalls(statements, enclosingScope)))) + case macroCall: PCalMacroCall => + expandMacroCalls(expandMacroCall(macroCall, enclosingScope), enclosingScope) + case stmt @PCalWhile(condition, body) => + List(stmt.withChildren(Iterator( + condition, + expandMacroCalls(body, enclosingScope)))) + case stmt @PCalWith(variables, body) => + List(stmt.withChildren(Iterator( + variables, + expandMacroCalls( + body, + variables.foldLeft(enclosingScope)((nestedScope, v) => nestedScope.updated(v.name.id, v)))))) + case stmt => List(stmt) + } +} diff --git a/src/pgo/util/Mutator.java b/src/pgo/util/Mutator.java deleted file mode 100644 index a4274b269..000000000 --- a/src/pgo/util/Mutator.java +++ /dev/null @@ -1,33 +0,0 @@ -package pgo.util; - -/** - * - * This class is intended to work as a layer of indirection if/when it is needed. If is a mutable cell you - * can give references to, then write to/read from later. - * - * @param the type of the thing we are mutating - */ -public final class Mutator { - - private T value; - - public Mutator() { - this.value = null; - } - - public Mutator(T value) { - this.value = value; - } - - public boolean hasValue() { - return value != null; - } - - public void setValue(T value) { - this.value = value; - } - - public T getValue() { - return value; - } -} diff --git a/src/pgo/util/NameCleaner.scala b/src/pgo/util/NameCleaner.scala new file mode 100644 index 000000000..616a67d94 --- /dev/null +++ b/src/pgo/util/NameCleaner.scala @@ -0,0 +1,31 @@ +package pgo.util + +import scala.collection.mutable + +class NameCleaner { + private val namesSeen = mutable.HashSet[String]() + // optimisation: if the same hint is used multiple times, avoid recomputing all previously checked variations + // by restarting the search for a clean name at the last clean name's index + 1 + private val hintCounterAcc = mutable.HashMap[String,Int]() + + def addKnownName(name: String): this.type = { + namesSeen += name + this + } + + def cleanName(hint: String): String = { + if(namesSeen(hint)) { + var currSuffix = hintCounterAcc.getOrElse(hint, 0) + var currName = s"$hint$currSuffix" + while(namesSeen(currName)) { + currSuffix += 1 + currName = s"$hint$currSuffix" + } + namesSeen += currName + hintCounterAcc(hint) = currSuffix + 1 + currName + } else { + hint + } + } +} diff --git a/src/pgo/util/Origin.java b/src/pgo/util/Origin.java deleted file mode 100644 index b4c98e2b0..000000000 --- a/src/pgo/util/Origin.java +++ /dev/null @@ -1,13 +0,0 @@ -package pgo.util; - -/** - * - * Where something was Derived from. Should be implemented by anything relevant. - * - * The Visitor allows code to inspect what the origin actually was, ideally at a high - * level. - * - */ -public interface Origin { - T accept(OriginVisitor v) throws E; -} diff --git a/src/pgo/util/OriginVisitor.java b/src/pgo/util/OriginVisitor.java deleted file mode 100644 index 72dc06e2c..000000000 --- a/src/pgo/util/OriginVisitor.java +++ /dev/null @@ -1,6 +0,0 @@ -package pgo.util; - -public abstract class OriginVisitor{ - public abstract T visit(SourceLocatable sourceLocatable) throws E; - public abstract T visit(Derived derived) throws E; -} diff --git a/src/pgo/util/SourceLocatable.java b/src/pgo/util/SourceLocatable.java deleted file mode 100644 index 0ab68caa7..000000000 --- a/src/pgo/util/SourceLocatable.java +++ /dev/null @@ -1,21 +0,0 @@ -package pgo.util; - -/** - * - * A common abstract base, typically meant for AST nodes, that should be - * implemented by anything that needs to be traced back to its - * original location. - * - * Implements the Origin interface so that any node of this type may be referenced - * in a generic way. - * - */ -public abstract class SourceLocatable implements Origin { - - public abstract SourceLocation getLocation(); - - public T accept(OriginVisitor v) throws E { - return v.visit(this); - } - -} diff --git a/src/pgo/util/SourceLocation.java b/src/pgo/util/SourceLocation.java deleted file mode 100644 index 3abd03c4e..000000000 --- a/src/pgo/util/SourceLocation.java +++ /dev/null @@ -1,259 +0,0 @@ -package pgo.util; - -import pgo.Unreachable; -import pgo.formatters.IndentingWriter; - -import java.io.IOException; -import java.io.PrintWriter; -import java.io.RandomAccessFile; -import java.io.StringWriter; -import java.nio.MappedByteBuffer; -import java.nio.channels.FileChannel; -import java.nio.charset.StandardCharsets; -import java.nio.file.Path; -import java.util.Objects; - -public class SourceLocation implements Comparable { - private final Path file; - private final int startOffset; - private final int endOffset; - private final int startLine; - private final int endLine; - private final int startColumn; - private final int endColumn; - - public SourceLocation(Path file, int startOffset, int endOffset, int startLine, int endLine, int startColumn, - int endColumn) { - this.file = file; - this.startOffset = startOffset; - this.endOffset = endOffset; - this.startLine = startLine; - this.endLine = endLine; - this.startColumn = startColumn; - this.endColumn = endColumn; - } - - public String prettyString() { - StringWriter sw = new StringWriter(); - writePretty(new IndentingWriter(sw)); - return sw.getBuffer().toString(); - } - - public void writePretty(IndentingWriter out) { - try { - if(isUnknown()) { - out.write("at unknown source location"); - } else { - out.write("at "); - if(startLine != endLine) { - out.write(""+(startLine+1)+":"+(startColumn+1)+"-"+(endLine+1)+":"+endColumn); - } else { - if(startColumn != endColumn) { - out.write(""+(startLine+1)+":"+(startColumn+1)+"-"+endColumn); - } else { - out.write(""+(startLine+1)+":"+(startColumn+1)); - } - } - out.write(" in file "+file); - out.newLine(); - try { - FileChannel fileChannel = new RandomAccessFile(file.toFile(), "r").getChannel(); - MappedByteBuffer buffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, fileChannel.size()); - CharSequence charSeq = StandardCharsets.UTF_8.decode(buffer); - int lineStart = startOffset; - while(lineStart >= 0 && (lineStart >= charSeq.length() || charSeq.charAt(lineStart) != '\n')) { - lineStart--; - } - if(lineStart < charSeq.length() && (lineStart == -1 || charSeq.charAt(lineStart) == '\n')) { - lineStart++; - } - int lineEnd = endOffset; - while(lineEnd < charSeq.length() && charSeq.charAt(lineEnd) != '\n') { - lineEnd++; - } - if(startLine != endLine) { - for(int pos = lineStart; pos < startOffset; pos++) { - out.append(' '); - } - for(int pos = startOffset; pos <= endOffset && charSeq.charAt(pos) != '\n'; pos++) { - out.append('v'); - } - out.newLine(); - } - int lastLineBegin = lineStart; - for(int pos = lineStart; pos < lineEnd; pos++) { - if(charSeq.charAt(pos) == '\n') { - lastLineBegin = pos + 1; - } - } - out.append(charSeq, lineStart, lineEnd); - out.newLine(); - for(int pos = lastLineBegin; pos < startOffset; pos++) { - out.append(' '); - } - final int effectiveEndOffset; - if(startOffset == endOffset) { - effectiveEndOffset = endOffset + 1; - } else { - effectiveEndOffset = endOffset; - } - for(int pos = startOffset; pos < lineEnd && pos < effectiveEndOffset; pos++) { - out.append('^'); - } - if(startOffset == charSeq.length()) { - out.append("^ EOF"); - } - } catch (IOException e) { // if we can't read the file, replace the intended message with stacktrace - PrintWriter pw = new PrintWriter(out); - e.printStackTrace(pw); - } - } - } catch (IOException e) { - throw new Unreachable(); // string ops shouldn't throw IO exceptions - } - } - - public static SourceLocation unknown() { - return new SourceLocation(null, -1, -1, -1, -1, -1, -1); - } - - public boolean isUnknown() { - return file == null; - } - - public SourceLocation combine(SourceLocation other) { - if(isUnknown()) { - return other; - }else if(other.isUnknown()) { - return this; - } - // we assume this is programmer error, as one would usually only call this method when combining parsed - // tokens into an AST, not later when one might reasonably combine tokens from different files - if(!file.equals(other.getFile())) { - throw new RuntimeException("Tried to combine source locations from two different files: " + file + ", " + other.getFile()); - } - int mStartColumn, mEndColumn; - if(startLine == other.getStartLine()) { - mStartColumn = Integer.min(startColumn, other.getStartColumn()); - }else if(startLine < other.getStartLine()) { - mStartColumn = startColumn; - }else /* startLine > other.getStartLine() */ { - mStartColumn = other.getStartColumn(); - } - if(endLine == other.getEndLine()) { - mEndColumn = Integer.max(endColumn, other.getEndColumn()); - }else if(endLine > other.getEndLine()) { - mEndColumn = endColumn; - }else /* endLine < other.getEndLine() */ { - mEndColumn = other.getEndColumn(); - } - return new SourceLocation(file, - startOffset < other.startOffset ? startOffset : other.startOffset, - endOffset > other.endOffset ? endOffset : other.endOffset, - Integer.min(startLine, other.getStartLine()), - Integer.max(endLine, other.getEndLine()), - mStartColumn, - mEndColumn); - } - - public Path getFile() { - return file; - } - - public int getStartOffset() { - return startOffset; - } - - public int getEndOffset() { - return endOffset; - } - - public int getStartLine() { - return startLine; - } - - public int getEndLine() { - return endLine; - } - - public int getStartColumn() { - return startColumn; - } - - public int getEndColumn() { - return endColumn; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + endColumn; - result = prime * result + endLine; - result = prime * result + ((file == null) ? 0 : file.hashCode()); - result = prime * result + startOffset; - result = prime * result + endOffset; - result = prime * result + startColumn; - result = prime * result + startLine; - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - SourceLocation other = (SourceLocation) obj; - return endColumn == other.endColumn && endLine == other.endLine && startColumn == other.startColumn && - startOffset == other.startOffset && endOffset == other.endOffset && startLine == other.startLine && - Objects.equals(file, other.file); - } - - @Override - public String toString() { - if (isUnknown()) { - return "SourceLocation [UNKNOWN]"; - } else { - return "SourceLocation [file=" + file + ", startOffset=" + startOffset + ", endOffset=" + endOffset + - ", startLine=" + startLine + ", endLine=" + endLine + ", startColumn=" + startColumn + - ", endColumn=" + endColumn + "]"; - } - } - - @Override - public int compareTo(SourceLocation o) { - if (isUnknown() && o.isUnknown()) { - return 0; - } - if (isUnknown()) { - return -1; - } - if (o.isUnknown()) { - return 1; - } - int comparedFile = getFile().compareTo(o.getFile()); - if (comparedFile != 0) { - return comparedFile; - } - int comparedStartLine = Integer.compare(getStartLine(), o.getStartLine()); - if (comparedStartLine != 0) { - return comparedStartLine; - } - int comparedStartColumn = Integer.compare(getStartColumn(), o.getStartColumn()); - if (comparedStartColumn != 0) { - return comparedStartColumn; - } - int comparedStartOffset = Integer.compare(getStartOffset(), o.getStartOffset()); - if (comparedStartOffset != 0) { - return comparedStartOffset; - } - return Integer.compare(getEndOffset(), o.getEndOffset()); - } - -} diff --git a/src/pgo/util/UnionFind.java b/src/pgo/util/UnionFind.java deleted file mode 100644 index 0e1c6e77d..000000000 --- a/src/pgo/util/UnionFind.java +++ /dev/null @@ -1,66 +0,0 @@ -package pgo.util; - -import java.util.HashMap; -import java.util.Map; - -public class UnionFind { - private final Map predecessorMap; - private final Map rank; - - public UnionFind() { - this(new HashMap<>(), new HashMap<>()); - } - - private UnionFind(Map predecessorMap, Map rank) { - this.predecessorMap = predecessorMap; - this.rank = rank; - } - - private boolean ensurePresence(T element) { - if (!predecessorMap.containsKey(element)) { - predecessorMap.put(element, element); - rank.put(element, 0); - return false; - } - return true; - } - - public T find(T element) { - if (!ensurePresence(element)) { - return element; - } - while (true) { - T parent = predecessorMap.getOrDefault(element, element); - if (parent.equals(element)) { - return element; - } - predecessorMap.put(element, predecessorMap.get(parent)); - element = parent; - } - } - - public void union(T u, T v) { - T uRoot = find(u); - T vRoot = find(v); - if (uRoot.equals(vRoot)) { - return; - } - if (rank.get(uRoot) < rank.get(vRoot)) { - predecessorMap.put(uRoot, vRoot); - } else if (rank.get(uRoot) > rank.get(vRoot)) { - predecessorMap.put(vRoot, uRoot); - } else { - predecessorMap.put(vRoot, uRoot); - rank.put(uRoot, rank.get(uRoot) + 1); - } - } - - public int getRank(T element) { - ensurePresence(element); - return rank.get(find(element)); - } - - public UnionFind copy() { - return new UnionFind<>(new HashMap<>(predecessorMap), new HashMap<>(rank)); - } -} diff --git a/test/files/semantics/AssignmentRules.tla b/test/files/semantics/AssignmentRules.tla new file mode 100644 index 000000000..106a2033f --- /dev/null +++ b/test/files/semantics/AssignmentRules.tla @@ -0,0 +1,61 @@ +---- MODULE AssignmentRules ---- +EXTENDS Sequences, FiniteSets, Integers +(* +--mpcal AssignmentRules { + macro MyMacro(x) { + x := 3; + \*:: expectedError: MultipleAssignmentError + y := 4; + } + + procedure Proc2() + variables x, y; + { + l1: MyMacro(x); + l2: MyMacro(x); MyMacro( (*:: expectedError: MultipleAssignmentError *) x); + l3: MyMacro(x); (*:: expectedError: MultipleAssignmentError *) y := y + 1; + l4: MyMacro(x); (*:: expectedError: MultipleAssignmentError *) x := -1; + } + + procedure MyProcedure(x, y) + variables x, y; + { + p: either { y := 10 } or { skip }; + \*:: expectedError: MultipleAssignmentError + y := 11; (* missing label *) + p2: y := 20; + x := y || (*:: expectedError: MultipleAssignmentError *) y := x; (* swap x and y: invalid *) + } + + archetype MyArchetype(ref x) + variables x; + { + a1: x := 10; + \*:: expectedError: MultipleAssignmentError + x := 11; (* missing label *) + } + + process (MyProcess = 23) + variables n; + { + l1: n := 2; + l2: while (n < 10) { + n := 12; + if (n = 20) { + \*:: expectedError: MultipleAssignmentError + n := 100; (* missing label *) + } + }; + \*:: expectedError: MultipleAssignmentError + n := 32; (* label not missing *) + + l3: if (n = 32) { + n := 0; + }; + \*:: expectedError: MultipleAssignmentError + n := 12; (* missing label *) + } +} +*) +\* BEGIN TRANSLATION +==== \ No newline at end of file diff --git a/test/files/semantics/CallLabelingRules.tla b/test/files/semantics/CallLabelingRules.tla new file mode 100644 index 000000000..d4f903fcb --- /dev/null +++ b/test/files/semantics/CallLabelingRules.tla @@ -0,0 +1,36 @@ +---- MODULE CallLabelingRules ---- +EXTENDS Sequences, FiniteSets, Integers +(* +--mpcal CallLabelingRules { + procedure SomeProcedure() { + l99: skip; + } + + procedure MyProcedure() { + l2: print "procedure"; + call SomeProcedure(); + return; (* no label required *) + } + + archetype MyArchetype() { + l1: print "first label"; + call MyProcedure(); + \*:: expectedError: LabelRequiredError + call MyProcedure(); + } + + process (MyProcess = 32) + variables x; + { + l3: print "process"; + call MyProcedure(); + goto l3; (* no label required *) + l4: print "next label"; + call MyProcedure(); + \*:: expectedError: LabelRequiredError + x := 10; (* missing label *) + } +} +*) +\* BEGIN TRANSLATION +==== \ No newline at end of file diff --git a/test/files/semantics/IfEitherLabelingRules.tla b/test/files/semantics/IfEitherLabelingRules.tla new file mode 100644 index 000000000..42182f8de --- /dev/null +++ b/test/files/semantics/IfEitherLabelingRules.tla @@ -0,0 +1,47 @@ +---- MODULE IfEitherLabelingRules ---- +EXTENDS Sequences, FiniteSets, Integers +(* +--mpcal IfEitherLabelingRules { + + procedure MyProcedure() + variables v; + { + l2: print "procedure"; + either { v := 10 } or { return }; + \*:: expectedError: LabelRequiredError + goto l2; (* missing label *) + } + + archetype MyArchetype() { + l1: print "first label"; + if (TRUE) { + print "true"; + } else if (TRUE) { + call MyProcedure(); + }; + + \*:: expectedError: LabelRequiredError + print "needs label"; (* missing label *) + } + + process (MyProcess = 32) + variables x, y; + { + l3: print "process"; + either { x := 0 } or { goto l3 }; + l4: print "all good"; + + either { goto l4 } or { skip }; + \*:: expectedError: LabelRequiredError + x := 50; (* missing label *) + + l5: if (TRUE) { + l6: print "label"; + }; + \*:: expectedError: LabelRequiredError + y := 20; (* missing label *) + } +} +*) +\* BEGIN TRANSLATION +==== \ No newline at end of file diff --git a/test/files/semantics/LabelBeforeWhile.tla b/test/files/semantics/LabelBeforeWhile.tla new file mode 100644 index 000000000..72c42a34e --- /dev/null +++ b/test/files/semantics/LabelBeforeWhile.tla @@ -0,0 +1,31 @@ +|---- MODULE WhileLabels ---- +EXTENDS Sequences, FiniteSets, Integers +(* +--mpcal WhileLabels { + procedure CorrectProcedure() { + l2: print "procedure"; + l3: while (FALSE) { print(3 - 3) }; (* all good *) + } + + archetype IncorrectArchetype() { + l1: print "first label"; + \*:: expectedError: LabelRequiredError + while (TRUE) { print "hello" }; + } + + process (IncorrectProcess = 32) { + \*:: expectedError: LabelRequiredError + while (10 < 20) { print(2 * 2) }; + } + + process (NestedMissingWhileLabels = 33) { + \*:: expectedError: LabelRequiredError + while (10 < 20) { + \*:: expectedError: LabelRequiredError + while(20 < 30) { print(3 * 3) }; + }; + } +} +*) +\* BEGIN TRANSLATION +==== \ No newline at end of file diff --git a/test/files/semantics/LabelNotDefined.tla b/test/files/semantics/LabelNotDefined.tla new file mode 100644 index 000000000..38f7a8b41 --- /dev/null +++ b/test/files/semantics/LabelNotDefined.tla @@ -0,0 +1,20 @@ +---- MODULE LabelNotDefined ---- +EXTENDS Sequences, FiniteSets, Integers +(* +--mpcal LabelNotDefined { + procedure Proc() { + l1: + \*:: expectedError: LabelNotDefinedError + goto l2; + } + + process (P = 1) { + pl1: (*:: expectedError: LabelNotDefinedError *) goto pl2; + } + process (P = 2) { + pl2: (*:: expectedError: LabelNotDefinedError *) goto pl1; + } +} +*) +\* BEGIN TRANSLATION +==== \ No newline at end of file diff --git a/test/files/semantics/MPCalKindMatching.tla b/test/files/semantics/MPCalKindMatching.tla new file mode 100644 index 000000000..2da5b304e --- /dev/null +++ b/test/files/semantics/MPCalKindMatching.tla @@ -0,0 +1,23 @@ +---- MODULE MPCalKindMatching ---- +EXTENDS Sequences, FiniteSets, Integers +(* +--mpcal MPCalKindMatching { + procedure Proc(ref a[_]) { + l2: call Proc(a); + } + + archetype Arch(ref a[_]) { + l1: skip; + } + + variables myVar; + + process (A = 42) == instance Arch(myVar[_]); + + process (B = 43) == instance Arch(ref myVar); + + process (C = 44) == instance Arch(myVar); +} +*) +\* BEGIN TRANSLATION +==== \ No newline at end of file diff --git a/test/files/semantics/MacroRules.tla b/test/files/semantics/MacroRules.tla new file mode 100644 index 000000000..3c3f5bd41 --- /dev/null +++ b/test/files/semantics/MacroRules.tla @@ -0,0 +1,18 @@ +---- MODULE MacroRules ---- +EXTENDS Sequences, FiniteSets, Integers +(* +--mpcal MacroRules { + macro ValidMacro() { + print(1 + 1); + x := 10; + } + + macro InvalidMacro() { + either { skip } or { (*:: expectedError: LabelForbiddenError *) l1: print(10) }; (* invalid *) + \*:: expectedError: LabelForbiddenError + l2: print(20); (* invalid *) + } +} +*) +\* BEGIN TRANSLATION +==== \ No newline at end of file diff --git a/test/files/semantics/MappingMacroWithCallGoto.tla b/test/files/semantics/MappingMacroWithCallGoto.tla new file mode 100644 index 000000000..96a6088e2 --- /dev/null +++ b/test/files/semantics/MappingMacroWithCallGoto.tla @@ -0,0 +1,31 @@ +---- MODULE MappingMacroWithCallGoto ---- +EXTENDS Sequences, FiniteSets, Integers +(* +--mpcal MappingMacroWithCallGoto { + procedure YesProcedure() { + l1: skip; + } + procedure NoProcedure() { + l2: skip; + } + + mapping macro InvalidStatements { + read { + await Len($variable) = 0; + if (TRUE) { + call YesProcedure(); + }; + \*:: expectedError: LabelRequiredError + call NoProcedure(); + \*:: expectedError: LabelRequiredError + yield 0; + } + write { + either { yield $value } + or { (*:: expectedError: LabelForbiddenError *) l1: goto l1 }; + } + } +} +*) +\* BEGIN TRANSLATION +==== \ No newline at end of file diff --git a/test/files/semantics/MappingWithLabels.tla b/test/files/semantics/MappingWithLabels.tla new file mode 100644 index 000000000..4adbba3be --- /dev/null +++ b/test/files/semantics/MappingWithLabels.tla @@ -0,0 +1,20 @@ +---- MODULE MappingWithLabels ---- +EXTENDS Sequences, FiniteSets, Integers +(* +--mpcal MappingWithLabels { + mapping macro ContainsLabels { + read { + \*:: expectedError: LabelForbiddenError + r: yield $variable + } + write { + if ($variable > 10) { + \*:: expectedError: LabelForbiddenError + w: yield $value; + } + } + } +} +*) +\* BEGIN TRANSLATION +==== \ No newline at end of file diff --git a/test/files/semantics/NoFirstLabel.tla b/test/files/semantics/NoFirstLabel.tla new file mode 100644 index 000000000..0017fc021 --- /dev/null +++ b/test/files/semantics/NoFirstLabel.tla @@ -0,0 +1,25 @@ +---- MODULE NoFirstLabel ---- +EXTENDS Sequences, FiniteSets, Integers +(* +--mpcal NoFirstLabel { + procedure MPCalProc(a^) { + \*:: expectedError: LabelRequiredError + print(2 + 2); + } + archetype MyArchetype() { + (*:: expectedError: LabelRequiredError *) + print(1 + 1); + } + procedure PCalProc(a) { + \*:: expectedError: LabelRequiredError + print(3 + 3); + } + + process (Proc = 1) { + \*:: expectedError: LabelRequiredError + print(4 + 4); + } +} +*) +\* BEGIN TRANSLATION +==== \ No newline at end of file diff --git a/test/files/semantics/RecursiveMacroRules.tla b/test/files/semantics/RecursiveMacroRules.tla new file mode 100644 index 000000000..aab37fb73 --- /dev/null +++ b/test/files/semantics/RecursiveMacroRules.tla @@ -0,0 +1,27 @@ +---- MODULE RecursiveMacroRules ---- +EXTENDS Sequences, FiniteSets, Integers +(* +--mpcal RecursiveMacroRules { + macro RecursiveMacro(x) { + \*:: expectedError: RecursiveMacroError + RecursiveMacro(x) + } + + macro Indirect1(x) { + \*:: expectedError: RecursiveMacroError + Indirect2(x) + } + macro Indirect2(x) { + \*:: expectedError: RecursiveMacroError + Indirect1(x) + } + + procedure CallsMacro() { + label: + \*:: expectedError: RecursiveMacroError + Indirect1(5) + } +} +*) +\* BEGIN TRANSLATION +==== \ No newline at end of file diff --git a/test/files/semantics/ReservedLabels.tla b/test/files/semantics/ReservedLabels.tla new file mode 100644 index 000000000..b5b55686e --- /dev/null +++ b/test/files/semantics/ReservedLabels.tla @@ -0,0 +1,17 @@ +---- MODULE ReservedLabels ---- +EXTENDS Sequences, FiniteSets, Integers +(* +--mpcal ReservedLabels { + procedure MyProcedure(y) { + p: either { p1: y := 20 } or { (*:: expectedError: ReservedLabelError *) Error: skip }; (* reserved *) + } + + archetype MyArchetype(ref x) { + \*:: expectedError: ReservedLabelError + Done: x := 10; (* reserved *) + done: x := 30; (* no problem *) + } +} +*) +\* BEGIN TRANSLATION +==== \ No newline at end of file diff --git a/test/files/semantics/ReturnGotoLabelingRules.tla b/test/files/semantics/ReturnGotoLabelingRules.tla new file mode 100644 index 000000000..0c2b7492c --- /dev/null +++ b/test/files/semantics/ReturnGotoLabelingRules.tla @@ -0,0 +1,31 @@ +---- MODULE ReturnGotoLabelingRules ---- +EXTENDS Sequences, FiniteSets, Integers +(* +--mpcal ReturnGotoLabelingRules { + + procedure MyProcedure() { + l2: print "procedure"; + return; + \*:: expectedError: LabelRequiredError + goto l2; (* missing label *) + } + + archetype MyArchetype() { + l1: print "first label"; + goto l1; + \*:: expectedError: LabelRequiredError + print "needs label"; (* missing label *) + } + + process (MyProcess = 32) + variables x; + { + l3: print "process"; + goto l3; + \*:: expectedError: LabelRequiredError + x := 10; (* missing label *) + } +} +*) +\* BEGIN TRANSLATION +==== \ No newline at end of file diff --git a/test/files/semantics/WithRules.tla b/test/files/semantics/WithRules.tla new file mode 100644 index 000000000..f585157c3 --- /dev/null +++ b/test/files/semantics/WithRules.tla @@ -0,0 +1,25 @@ +---- MODULE WithRules ---- +EXTENDS Sequences, FiniteSets, Integers +(* +--mpcal WithRules { + macro MacroWith() { + print(1 + 1); + with (x = 10) { + print x; + \*:: expectedError: LabelForbiddenError + m1: x := 20; (* invalid *) + }; + \*:: expectedError: LabelForbiddenError + m2: print(20); (* invalid *) + } + + procedure ProcedureWith() { + l1: with (x = 10) { + \*:: expectedError: LabelForbiddenError + l2: print x; (* invalid *) + } + } +} +*) +\* BEGIN TRANSLATION +==== \ No newline at end of file diff --git a/test/pgo/ExampleCodegenRunTest.scala b/test/pgo/ExampleCodegenRunTest.scala deleted file mode 100644 index c9e66b1ca..000000000 --- a/test/pgo/ExampleCodegenRunTest.scala +++ /dev/null @@ -1,172 +0,0 @@ -package pgo - -import org.scalactic.source.Position -import org.scalatest.funsuite.AnyFunSuite -import pgo.IntegrationTestingUtils.{testCompileFile, testRunGoCode} - -import java.nio.file.{Path, Paths} -import scala.jdk.CollectionConverters._ - -class ExampleCodegenRunTest extends AnyFunSuite{ - def check(tag: String)(fileName: String, constants: Map[String,String], expectedOutput: String)(implicit pos: Position): Unit = - test(tag) { - testCompileFile(Paths.get("examples", fileName), constants.asJava, { compiledOutputPath => - testRunGoCode(compiledOutputPath, expectedOutput.linesIterator.toList.asJava) - }) - } - - check("Euclid N=5")( - fileName = "Euclid.tla", - constants = Map("N" -> "5"), - expectedOutput = "{24 1 have gcd 1}") - - check("counter procs=1 iters=1")( - fileName = "counter.tla", - constants = Map("procs" -> "1", "iters" -> "1"), - expectedOutput = "1") - - check("counter procs=1 itera=64")( - fileName = "counter.tla", - constants = Map("procs" -> "1", "iters" -> "64"), - expectedOutput = (1 to 64).mkString("\n")) - - check("counter procs=2 iters=1")( - fileName = "counter.tla", - constants = Map("procs" -> "2", "iters" -> "1"), - expectedOutput = - """1 - |2""".stripMargin) - - check("counter procs=64 iters=1")( - fileName = "counter.tla", - constants = Map("procs" -> "64", "iters" -> "1"), - expectedOutput = (1 to 64).mkString("\n")) - - check("counter procs=32 iters=32")( - fileName = "counter.tla", - constants = Map("procs" -> "32", "iters" -> "32"), - expectedOutput = (1 to 32*32).mkString("\n")) - - check("counter procs=64 iters=64")( - fileName = "counter.tla", - constants = Map("procs" -> "64", "iters" -> "64"), - expectedOutput = (1 to 64*64).mkString("\n")) - - check("Queens N=1")( - fileName = "Queens.tla", - constants = Map("N" -> "1"), - expectedOutput = "[[1]]") - - check("Queens N=2")( - fileName = "Queens.tla", - constants = Map("N" -> "2"), - expectedOutput = "[]") - - check("Queens N=3")( - fileName = "Queens.tla", - constants = Map("N" -> "3"), - expectedOutput = "[]") - - check("Queens N=4")( - fileName = "Queens.tla", - constants = Map("N" -> "4"), - expectedOutput = "[[2 4 1 3] [3 1 4 2]]") - - check("Queens N=5")( - fileName = "Queens.tla", - constants = Map("N" -> "5"), - expectedOutput = "[[1 3 5 2 4] [1 4 2 5 3] [2 4 1 3 5] [2 5 3 1 4] [3 1 4 2 5]" + - " [3 5 2 4 1] [4 1 3 5 2] [4 2 5 3 1] [5 2 4 1 3] [5 3 1 4 2]]") - - check("Queens N=9")( - fileName = "Queens.tla", - constants = Map("N" -> "9"), - expectedOutput = "[[1 3 6 8 2 4 9 7 5] [1 3 7 2 8 5 9 4 6] [1 3 8 6 9 2 5 7 4] [1 4 2 8 6 9 3 5 7] " + - "[1 4 6 3 9 2 8 5 7] [1 4 6 8 2 5 3 9 7] [1 4 7 3 8 2 5 9 6] [1 4 7 9 2 5 8 6 3] " + - "[1 4 8 3 9 7 5 2 6] [1 5 2 6 9 3 8 4 7] [1 5 7 2 6 3 9 4 8] [1 5 7 9 3 8 2 4 6] " + - "[1 5 7 9 4 2 8 6 3] [1 5 9 2 6 8 3 7 4] [1 5 9 6 4 2 8 3 7] [1 6 2 9 7 4 8 3 5] " + - "[1 6 4 2 7 9 3 5 8] [1 6 4 2 8 3 9 7 5] [1 6 8 3 7 4 2 9 5] [1 6 8 5 2 4 9 7 3] " + - "[1 6 9 5 2 8 3 7 4] [1 7 4 6 9 2 5 3 8] [1 7 4 8 3 5 9 2 6] [1 7 4 8 3 9 6 2 5] " + - "[1 7 5 8 2 9 3 6 4] [1 8 4 2 7 9 6 3 5] [1 8 5 3 6 9 2 4 7] [1 8 5 3 9 7 2 4 6] " + - "[2 4 1 7 9 6 3 5 8] [2 4 7 1 3 9 6 8 5] [2 4 8 3 9 6 1 5 7] [2 4 9 7 3 1 6 8 5] " + - "[2 4 9 7 5 3 1 6 8] [2 5 7 1 3 8 6 4 9] [2 5 7 4 1 3 9 6 8] [2 5 7 9 3 6 4 1 8] " + - "[2 5 7 9 4 8 1 3 6] [2 5 8 1 3 6 9 7 4] [2 5 8 1 9 6 3 7 4] [2 5 8 6 9 3 1 4 7] " + - "[2 5 8 6 9 3 1 7 4] [2 5 9 4 1 8 6 3 7] [2 6 1 3 7 9 4 8 5] [2 6 1 7 4 8 3 5 9] " + - "[2 6 1 7 5 3 9 4 8] [2 6 1 9 5 8 4 7 3] [2 6 3 1 8 4 9 7 5] [2 6 9 3 5 8 4 1 7] " + - "[2 7 5 1 9 4 6 8 3] [2 7 5 8 1 4 6 3 9] [2 7 9 6 3 1 4 8 5] [2 8 1 4 7 9 6 3 5] " + - "[2 8 5 3 9 6 4 1 7] [2 8 6 9 3 1 4 7 5] [2 9 5 3 8 4 7 1 6] [2 9 6 3 5 8 1 4 7] " + - "[2 9 6 3 7 4 1 8 5] [2 9 6 4 7 1 3 5 8] [3 1 4 7 9 2 5 8 6] [3 1 6 8 5 2 4 9 7] " + - "[3 1 7 2 8 6 4 9 5] [3 1 7 5 8 2 4 6 9] [3 1 8 4 9 7 5 2 6] [3 1 9 7 5 2 8 6 4] " + - "[3 5 2 8 1 4 7 9 6] [3 5 2 8 1 7 4 6 9] [3 5 7 1 4 2 8 6 9] [3 5 8 2 9 6 1 7 4] " + - "[3 5 8 2 9 7 1 4 6] [3 5 9 2 4 7 1 8 6] [3 5 9 4 1 7 2 6 8] [3 6 2 7 1 4 8 5 9] " + - "[3 6 2 9 5 1 8 4 7] [3 6 8 1 4 7 5 2 9] [3 6 8 1 5 9 2 4 7] [3 6 8 2 4 9 7 5 1] " + - "[3 6 8 5 1 9 7 2 4] [3 6 8 5 2 9 7 4 1] [3 6 9 1 8 4 2 7 5] [3 6 9 2 5 7 4 1 8] " + - "[3 6 9 2 8 1 4 7 5] [3 6 9 5 8 1 4 2 7] [3 6 9 7 1 4 2 5 8] [3 6 9 7 2 4 8 1 5] " + - "[3 6 9 7 4 1 8 2 5] [3 7 2 4 8 1 5 9 6] [3 7 2 8 5 9 1 6 4] [3 7 2 8 6 4 1 5 9] " + - "[3 7 4 2 9 5 1 8 6] [3 7 4 2 9 6 1 5 8] [3 7 4 8 5 9 1 6 2] [3 7 9 1 5 2 8 6 4] " + - "[3 7 9 4 2 5 8 6 1] [3 8 2 4 9 7 5 1 6] [3 8 4 7 9 2 5 1 6] [3 8 6 1 9 2 5 7 4] " + - "[3 8 6 4 9 1 5 7 2] [3 8 6 9 2 5 1 4 7] [3 9 2 5 8 1 7 4 6] [3 9 4 1 8 6 2 7 5] " + - "[3 9 4 2 8 6 1 7 5] [3 9 4 8 5 2 6 1 7] [3 9 6 2 5 7 1 4 8] [3 9 6 4 1 7 5 2 8] " + - "[3 9 6 8 2 4 1 7 5] [4 1 3 6 9 2 8 5 7] [4 1 5 2 9 7 3 8 6] [4 1 5 8 2 7 3 6 9] " + - "[4 1 5 9 2 6 8 3 7] [4 1 7 9 2 6 8 3 5] [4 1 9 6 3 7 2 8 5] [4 2 5 8 1 3 6 9 7] " + - "[4 2 7 3 1 8 5 9 6] [4 2 7 9 1 5 8 6 3] [4 2 7 9 1 8 5 3 6] [4 2 8 3 9 7 5 1 6] " + - "[4 2 9 3 6 8 1 5 7] [4 2 9 5 1 8 6 3 7] [4 6 1 5 2 8 3 7 9] [4 6 1 9 5 8 2 7 3] " + - "[4 6 1 9 7 3 8 2 5] [4 6 3 9 2 5 8 1 7] [4 6 3 9 2 8 5 7 1] [4 6 3 9 7 1 8 2 5] " + - "[4 6 8 2 5 1 9 7 3] [4 6 8 2 5 7 9 1 3] [4 6 8 2 7 1 3 5 9] [4 6 8 3 1 7 5 2 9] " + - "[4 6 9 3 1 8 2 5 7] [4 7 1 3 9 6 8 5 2] [4 7 1 6 9 2 8 5 3] [4 7 1 8 5 2 9 3 6] " + - "[4 7 3 6 9 1 8 5 2] [4 7 3 8 2 5 9 6 1] [4 7 3 8 6 1 9 2 5] [4 7 3 8 6 2 9 5 1] " + - "[4 7 5 2 9 1 3 8 6] [4 7 5 2 9 1 6 8 3] [4 7 5 2 9 6 8 3 1] [4 7 9 2 5 8 1 3 6] " + - "[4 7 9 2 6 1 3 5 8] [4 7 9 6 3 1 8 5 2] [4 8 1 5 7 2 6 3 9] [4 8 5 3 1 6 2 9 7] " + - "[4 8 5 3 1 7 2 6 9] [4 9 3 6 2 7 5 1 8] [4 9 5 3 1 6 8 2 7] [4 9 5 3 1 7 2 8 6] " + - "[4 9 5 8 1 3 6 2 7] [5 1 6 4 2 8 3 9 7] [5 1 8 4 2 7 9 6 3] [5 1 8 6 3 7 2 4 9] " + - "[5 2 4 1 7 9 3 6 8] [5 2 4 9 7 3 1 6 8] [5 2 6 1 3 7 9 4 8] [5 2 6 9 3 8 4 7 1] " + - "[5 2 6 9 7 4 1 3 8] [5 2 8 1 4 7 9 6 3] [5 2 8 1 7 9 3 6 4] [5 2 8 3 7 4 1 9 6] " + - "[5 2 8 3 7 9 1 6 4] [5 2 9 1 6 8 3 7 4] [5 2 9 6 3 7 4 1 8] [5 3 1 6 2 9 7 4 8] " + - "[5 3 1 6 8 2 4 7 9] [5 3 1 7 2 8 6 4 9] [5 3 6 9 2 8 1 4 7] [5 3 6 9 7 1 4 2 8] " + - "[5 3 6 9 7 2 4 8 1] [5 3 6 9 7 4 1 8 2] [5 3 8 4 2 9 6 1 7] [5 3 8 4 7 9 2 6 1] " + - "[5 3 8 6 2 9 1 4 7] [5 3 8 6 2 9 7 1 4] [5 3 9 4 2 8 6 1 7] [5 3 9 6 8 2 4 1 7] " + - "[5 7 1 4 2 8 6 9 3] [5 7 1 6 8 2 4 9 3] [5 7 2 4 8 1 3 9 6] [5 7 2 4 8 1 9 6 3] " + - "[5 7 2 6 3 1 8 4 9] [5 7 2 6 8 1 4 9 3] [5 7 4 1 3 6 9 2 8] [5 7 4 1 3 8 6 2 9] " + - "[5 7 4 1 3 9 6 8 2] [5 7 4 1 8 2 9 6 3] [5 7 9 3 8 2 4 6 1] [5 7 9 4 2 8 6 3 1] " + - "[5 7 9 4 8 1 3 6 2] [5 8 1 4 7 3 6 9 2] [5 8 1 9 4 2 7 3 6] [5 8 2 7 3 1 9 4 6] " + - "[5 8 2 7 3 6 9 1 4] [5 8 2 9 3 1 7 4 6] [5 8 2 9 6 3 1 4 7] [5 8 4 1 3 6 9 7 2] " + - "[5 8 4 1 7 2 6 3 9] [5 8 4 9 7 3 1 6 2] [5 8 6 1 3 7 9 4 2] [5 8 6 9 3 1 7 4 2] " + - "[5 9 2 4 7 3 8 6 1] [5 9 2 6 8 3 1 4 7] [5 9 4 6 8 2 7 1 3] [6 1 5 2 9 7 4 8 3] " + - "[6 1 5 7 9 3 8 2 4] [6 1 5 7 9 4 2 8 3] [6 1 7 4 8 3 5 9 2] [6 2 5 7 9 3 8 4 1] " + - "[6 2 5 7 9 4 8 1 3] [6 2 9 5 3 8 4 7 1] [6 3 1 4 7 9 2 5 8] [6 3 1 8 4 9 7 5 2] " + - "[6 3 1 8 5 2 9 7 4] [6 3 5 8 1 4 2 7 9] [6 3 5 8 1 9 4 2 7] [6 3 5 8 1 9 7 2 4] " + - "[6 3 7 2 4 8 1 5 9] [6 3 7 2 4 9 1 8 5] [6 3 7 2 8 5 1 4 9] [6 3 7 4 1 9 2 5 8] " + - "[6 3 9 2 5 8 1 7 4] [6 3 9 4 1 8 2 5 7] [6 3 9 7 1 4 2 5 8] [6 4 1 7 9 2 8 5 3] " + - "[6 4 2 7 9 3 5 8 1] [6 4 2 8 3 9 7 5 1] [6 4 2 8 5 3 1 9 7] [6 4 2 8 5 9 1 3 7] " + - "[6 4 7 1 3 9 2 8 5] [6 4 7 1 8 2 5 3 9] [6 4 7 1 8 5 2 9 3] [6 4 9 1 3 7 2 8 5] " + - "[6 4 9 1 5 2 8 3 7] [6 4 9 5 8 2 7 3 1] [6 8 1 5 9 2 4 7 3] [6 8 1 7 4 2 9 5 3] " + - "[6 8 2 7 1 3 5 9 4] [6 8 3 1 9 2 5 7 4] [6 8 3 1 9 5 2 4 7] [6 8 3 7 9 2 5 1 4] " + - "[6 8 5 2 9 7 4 1 3] [6 9 1 4 7 3 8 2 5] [6 9 3 1 8 4 2 7 5] [6 9 5 1 8 4 2 7 3] " + - "[6 9 5 2 8 3 7 4 1] [6 9 5 8 1 3 7 2 4] [6 9 7 4 1 8 2 5 3] [7 1 4 2 8 6 9 3 5] " + - "[7 1 4 6 9 3 5 8 2] [7 1 4 8 5 3 9 6 2] [7 1 6 2 5 8 4 9 3] [7 1 6 8 2 4 9 3 5] " + - "[7 1 6 9 2 4 8 3 5] [7 1 8 5 2 9 3 6 4] [7 2 4 1 8 5 9 6 3] [7 2 4 6 1 9 5 3 8] " + - "[7 2 4 9 1 8 5 3 6] [7 2 6 3 1 8 5 9 4] [7 2 8 6 1 3 5 9 4] [7 3 1 6 8 5 2 4 9] " + - "[7 3 1 9 5 8 2 4 6] [7 3 6 2 5 1 9 4 8] [7 3 6 8 1 4 9 5 2] [7 3 6 8 1 5 9 2 4] " + - "[7 3 8 2 4 6 9 5 1] [7 3 8 2 5 1 9 4 6] [7 3 8 6 2 9 5 1 4] [7 4 1 3 6 9 2 8 5] " + - "[7 4 1 3 8 6 2 9 5] [7 4 1 3 9 6 8 5 2] [7 4 1 5 2 9 6 8 3] [7 4 1 8 2 9 6 3 5] " + - "[7 4 1 8 5 3 6 9 2] [7 4 1 9 2 6 8 3 5] [7 4 2 5 8 1 3 6 9] [7 4 2 5 9 1 3 8 6] " + - "[7 4 2 8 6 1 3 5 9] [7 4 2 9 5 1 8 6 3] [7 4 2 9 6 3 5 8 1] [7 4 8 1 5 9 2 6 3] " + - "[7 4 8 3 9 6 2 5 1] [7 5 1 6 9 3 8 4 2] [7 5 1 8 6 3 9 2 4] [7 5 2 8 1 3 9 6 4] " + - "[7 5 2 8 1 4 9 3 6] [7 5 3 9 6 8 2 4 1] [7 5 8 2 9 3 6 4 1] [7 5 8 2 9 6 3 1 4] " + - "[7 9 1 3 5 8 2 4 6] [7 9 2 6 1 3 5 8 4] [7 9 3 5 2 8 6 4 1] [7 9 3 8 2 4 6 1 5] " + - "[7 9 4 2 5 8 6 1 3] [7 9 6 3 1 8 5 2 4] [8 1 4 6 3 9 7 5 2] [8 1 4 7 3 6 9 2 5] " + - "[8 1 4 7 5 2 9 6 3] [8 1 5 7 2 6 3 9 4] [8 2 4 1 7 9 6 3 5] [8 2 5 7 1 4 6 9 3] " + - "[8 2 9 6 3 1 4 7 5] [8 3 1 4 7 9 6 2 5] [8 3 5 2 9 6 4 7 1] [8 3 5 9 1 6 4 2 7] " + - "[8 4 1 7 5 2 6 9 3] [8 4 7 9 2 6 1 3 5] [8 4 9 1 5 2 6 3 7] [8 4 9 3 5 7 1 6 2] " + - "[8 4 9 3 6 2 7 5 1] [8 4 9 7 3 1 6 2 5] [8 5 1 6 9 2 4 7 3] [8 5 2 4 1 7 9 3 6] " + - "[8 5 2 4 1 7 9 6 3] [8 5 2 9 1 4 7 3 6] [8 5 2 9 7 4 1 3 6] [8 5 3 1 6 2 9 7 4] " + - "[8 5 3 1 7 4 6 9 2] [8 5 3 6 9 7 1 4 2] [8 5 3 9 7 2 4 6 1] [8 6 1 3 5 7 9 4 2] " + - "[8 6 1 3 7 9 4 2 5] [8 6 2 7 1 4 9 5 3] [8 6 3 9 7 1 4 2 5] [8 6 9 3 1 4 7 5 2] " + - "[9 2 5 7 1 3 8 6 4] [9 2 5 7 4 1 8 6 3] [9 2 6 8 3 1 4 7 5] [9 3 5 2 8 1 7 4 6] " + - "[9 3 6 2 7 1 4 8 5] [9 3 6 2 7 5 1 8 4] [9 3 6 4 1 8 5 7 2] [9 4 1 5 8 2 7 3 6] " + - "[9 4 2 5 8 6 1 3 7] [9 4 2 7 3 6 8 1 5] [9 4 6 8 2 7 1 3 5] [9 4 6 8 3 1 7 5 2] " + - "[9 4 8 1 3 6 2 7 5] [9 5 1 4 6 8 2 7 3] [9 5 1 8 4 2 7 3 6] [9 5 3 1 6 8 2 4 7] " + - "[9 5 3 1 7 2 8 6 4] [9 5 3 8 4 7 1 6 2] [9 5 8 4 1 7 2 6 3] [9 6 2 7 1 3 5 8 4] " + - "[9 6 3 1 8 5 2 4 7] [9 6 3 7 2 8 5 1 4] [9 6 4 2 8 5 7 1 3] [9 6 4 7 1 8 2 5 3] " + - "[9 6 8 2 4 1 7 5 3] [9 7 2 4 1 8 5 3 6] [9 7 3 8 2 5 1 6 4] [9 7 4 2 8 6 1 3 5]]") -} diff --git a/test/pgo/ExpressionCodeGenRunFailureTest.scala b/test/pgo/ExpressionCodeGenRunFailureTest.scala deleted file mode 100644 index 0a7174f6a..000000000 --- a/test/pgo/ExpressionCodeGenRunFailureTest.scala +++ /dev/null @@ -1,22 +0,0 @@ -package pgo - -import org.scalactic.source.Position -import org.scalatest.funsuite.AnyFunSuite -import pgo.model.tla.TLAExpression -import pgo.model.tla.TLABuilder._ - -import scala.jdk.CollectionConverters._ - -class ExpressionCodeGenRunFailureTest extends AnyFunSuite { - def check(tag: String)(expr: TLAExpression, vars: List[IntegrationTestingUtils.KeyValue], expected: String)(implicit pos: Position): Unit = - test(tag) { - IntegrationTestingUtils.testCompileExpression(expr, vars.asJava, { outputPath => - IntegrationTestingUtils.testRunGoCodeShouldPanic(outputPath, expected.linesIterator.toList.asJava) - }) - } - - check("unsatisfiable case expr")( - expr=caseexp(arms(arm(bool(false), str("Hello world"))), null), - vars=Nil, - "panic: No matching case!") -} \ No newline at end of file diff --git a/test/pgo/ExpressionCodeGenRunTest.scala b/test/pgo/ExpressionCodeGenRunTest.scala deleted file mode 100644 index 49e1adbd6..000000000 --- a/test/pgo/ExpressionCodeGenRunTest.scala +++ /dev/null @@ -1,291 +0,0 @@ -package pgo - -import org.scalactic.source.Position -import org.scalatest.funsuite.AnyFunSuite -import pgo.IntegrationTestingUtils.{KeyValue, testCompileExpression, testRunGoCode} -import pgo.model.tla.TLABuilder._ -import pgo.model.tla.TLAExpression - -import scala.jdk.CollectionConverters._ - -class ExpressionCodeGenRunTest extends AnyFunSuite { - def check(tag: String)(expr: TLAExpression, vars: List[(String,TLAExpression)] = Nil, expectedStr: String)(implicit pos: Position): Unit = - test(tag) { - // try to run the compiled Go code, check that it prints the right thing - testCompileExpression( - expr, - vars.map(p => new KeyValue(p._1, p._2)).asJava, - compiledOutputPath => - testRunGoCode(compiledOutputPath, expectedStr.linesIterator.toList.asJava)) - } - - check("case expression 3rd case")( - expr = caseexp( - arms( - arm(binop("=", idexp("a"), num(1)), str("a = 1")), - arm(binop("=", idexp("a"), num(2)), str("a = 2")), - arm(binop("=", idexp("a"), num(3)), str("a = 3")), - arm(binop("=", idexp("a"), num(4)), str("a = 4")), - arm(binop("=", idexp("a"), num(5)), str("a = 5"))), - str("a > 5 or a < 0")), - vars = List("a" -> num(3)), - expectedStr = "a = 3") - - check("case expression default case")( - expr = caseexp( - arms( - arm(binop("=", idexp("a"), num(1)), str("a = 1")), - arm(binop("=", idexp("a"), num(2)), str("a = 2")), - arm(binop("=", idexp("a"), num(3)), str("a = 3")), - arm(binop("=", idexp("a"), num(4)), str("a = 4")), - arm(binop("=", idexp("a"), num(5)), str("a = 5"))), - str("a > 5 or a < 0")), - vars = List("a" -> num(11)), - expectedStr = "a > 5 or a < 0") - - check("case expression 3rd case no default")( - expr = caseexp( - arms( - arm(binop("=", idexp("a"), num(1)), str("a = 1")), - arm(binop("=", idexp("a"), num(2)), str("a = 2")), - arm(binop("=", idexp("a"), num(3)), str("a = 3")), - arm(binop("=", idexp("a"), num(4)), str("a = 4")), - arm(binop("=", idexp("a"), num(5)), str("a = 5"))), - null), - vars = List("a" -> num(3)), - expectedStr = "a = 3") - - check("if expression then branch")( - expr = ifexp(bool(true), str("Then Branch"), str("Else Branch")), - expectedStr = "Then Branch") - - check("if expression else branch")( - expr = ifexp(bool(false), str("Then Branch"), str("Else Branch")), - expectedStr = "Else Branch") - - check("if expression complex then branch")( - expr = ifexp(binop(">", idexp("a"), idexp("b")), idexp("a"), idexp("b")), - vars = List("a" -> num(3), "b" -> num(1)), - expectedStr = "3") - - check("nested if expression else -> then branch")( - expr = ifexp(bool(false), str("Then Branch"), ifexp(bool(true), str("Else Branch -> Then Branch"), str("Else Branch -> Else Branch"))), - expectedStr = "Else Branch -> Then Branch") - - check("compound math * (+)")( - expr = binop("*", idexp("a"), binop("+", idexp("b"), idexp("c"))), - vars = List("a" -> num(2), "b" -> num(2), "c" -> num(3)), - expectedStr = "10") - - check("compound math * + *")( - expr = binop("*", idexp("a"), binop("+", idexp("b"), binop("*", idexp("c"), idexp("c")))), - vars = List("a" -> num(2), "b" -> num(2), "c" -> num(3)), - expectedStr = "22") - - check("set enumeration")( - expr = binop("..", num(0), binop("-", idexp("a"), num(1))), - vars = List("a" -> num(10)), - expectedStr = "[0 1 2 3 4 5 6 7 8 9]") - - check("set union no dupes")( - expr = binop("\\union", idexp("lhs"), idexp("rhs")), - vars = List( - "lhs" -> set(num(1), num(2)), - "rhs" -> set(num(3))), - expectedStr = "[1 2 3]") - - check("set union with dupes")( - expr = binop("\\union", idexp("lhs"), idexp("rhs")), - vars = List( - "lhs" -> set(num(1), num(2)), - "rhs" -> set(num(3), num(2))), - expectedStr = "[1 2 3]") - - check("set diff no intersect")( - expr = binop("\\", idexp("lhs"), idexp("rhs")), - vars = List( - "lhs" -> set(num(1), num(2)), - "rhs" -> set(num(3))), - expectedStr = "[1 2]") - - check("set diff intersect")( - expr = binop("\\", idexp("lhs"), idexp("rhs")), - vars = List( - "lhs" -> set(num(1), num(2)), - "rhs" -> set(num(2))), - expectedStr = "[1]") - - check("set member check yes")( - expr = binop("\\in", idexp("x"), idexp("s")), - vars = List("x" -> num(3), "s" -> set(num(1), num(2), num(3))), - expectedStr = "true") - - check("set member check no")( - expr = binop("\\in", idexp("x"), idexp("s")), - vars = List("x" -> num(30), "s" -> set(num(1), num(3), num(2))), - expectedStr = "false") - - check("set-of-sets pseudo-lexicographical sorting")( - idexp("value"), - vars = List("value" -> set(set(), set(num(1), num(2)), set(num(2)))), - expectedStr = "[[] [2] [1 2]]") - - check("set-of-tuples pseudo-lexicographical append")( - idexp("value"), - vars = List( - "workaround" -> opcall("Append", tuple(), num(2)), - "value" -> set(tuple(), tuple(num(1), num(2)), idexp("workaround"))), - expectedStr = "[[] [2] [1 2]]") - - check("set-of-sets union")( - expr = binop("\\union", idexp("lhs"), idexp("rhs")), - vars = List( - "lhs" -> set(set(num(5), num(3)), set(num(2)), set(num(1), num(10))), - "rhs" -> set(set(), set(num(2), num(2)))), - expectedStr = "[[] [2] [1 10] [3 5]]") - - check("set-of-tuples append diff")( - expr = binop("\\", idexp("lhs"), idexp("rhs")), - vars = List( - "workaround1" -> opcall("Append", tuple(), num(1)), - "workaround2" -> opcall("Append", tuple(), num(2)), - "lhs" -> set(tuple(), idexp("workaround1")), - "rhs" -> set(tuple(), idexp("workaround2"), tuple(num(1), num(2)))), - expectedStr = "[[1]]") - - check("set of records membership; internally ordered")( - expr = binop("\\in", - record(field(id("a"), num(1)), field(id("b"), num(2))), - set(idexp("r1"), idexp("r2"))), - vars = List( - "r1" -> record(field(id("a"), num(1)), field(id("b"), num(2))), - "r2" -> record(field(id("a"), num(2)), field(id("b"), num(1)))), - expectedStr = "true") - - check("set of records membership; internally disordered")( - expr = binop("\\in", - record(field(id("a"), num(1)), field(id("b"), num(2))), - set(idexp("r1"), idexp("r2"))), - vars = List( - "r1" -> record(field(id("a"), num(2)), field(id("b"), num(1))), - "r2" -> record(field(id("a"), num(1)), field(id("b"), num(2)))), - expectedStr = "true") - - check("set of records membership; with strings")( - expr = binop("\\in", - record(field(id("a"), num(1)), field(id("b"), str("hi"))), - set(idexp("r1"), idexp("r2"))), - vars = List( - "r1" -> record(field(id("a"), num(2)), field(id("b"), str("nope"))), - "r2" -> record(field(id("a"), num(1)), field(id("b"), str("hi")))), - expectedStr = "true") - - check("set of records membership; internally ordered; FALSE")( - expr = binop("\\in", - record(field(id("a"), num(1)), field(id("b"), num(2))), - set(idexp("r1"), idexp("r2"))), - vars = List( - "r1" -> record(field(id("a"), num(10)), field(id("b"), num(20))), - "r2" -> record(field(id("a"), num(20)), field(id("b"), num(10)))), - expectedStr = "false") - - check("set of records membership; empty set")( - expr = binop("\\in", - record(field(id("a"), num(1)), field(id("b"), num(2))), - set()), - expectedStr = "false") - - check("quantified universal 2 bounds true")( - expr = universal( - bounds( - qbIds(ids(id("x")), idexp("set1")), - qbIds(ids(id("y")), idexp("set2"))), - binop("=", - binop("%", binop("+", idexp("x"), idexp("y")), num(2)), - num(1))), - vars = List( - "set1" -> set(num(2), num(4), num(6)), - "set2" -> set(num(1), num(3), num(5))), - expectedStr = "true") - - check("quantified universal 2 bounds false")( - expr = universal( - bounds( - qbIds(ids(id("x")), idexp("set")), - qbIds(ids(id("y")), binop("..", num(1), num(3)))), - binop("=", - binop("%", binop("+", idexp("x"), idexp("y")), num(2)), - num(1))), - vars = List( - "set" -> set(num(2), num(4), num(6))), - expectedStr = "false") - - check("tuple concat")( - expr = binop("\\o", idexp("seq"), tuple(num(10))), - vars = List( - "seq" -> tuple(num(1), num(2))), - expectedStr = "[1 2 10]") - - check("tuple concat with empty")( - expr = binop("\\o", idexp("seq"), tuple(num(10))), - vars = List("seq" -> tuple()), - expectedStr = "[10]") - - check("tuple concat nested")( - expr = binop("\\o", binop("\\o", tuple(num(1), num(2)), tuple(num(3))), tuple(num(10), num(11))), - expectedStr = "[1 2 3 10 11]") - - check("tuple subseq last two")( - expr = opcall("SubSeq", idexp("seq"), num(4), num(5)), - vars = List( - "seq" -> tuple(num(1), num(2), num(3), num(4), num(5))), - expectedStr = "[4 5]") - - check("tuple subseq out of range")( - expr = opcall("SubSeq", idexp("seq"), num(6), num(5)), - vars = List( - "seq" -> tuple(num(1), num(2), num(3), num(4), num(5))), - expectedStr = "[]") - - check("tuple subseq last element")( - expr = opcall("SubSeq", idexp("seq"), num(5), num(5)), - vars = List( - "seq" -> tuple(num(1), num(2), num(3), num(4), num(5))), - expectedStr = "[5]") - - check("tuple subseq first element")( - expr = opcall("SubSeq", idexp("seq"), num(1), num(1)), - vars = List( - "seq" -> tuple(num(1), num(2), num(3), num(4), num(5))), - expectedStr = "[1]") - - check("literal function")( - expr = function( - bounds(qbIds(ids(id("x")), set(num(1), num(2), num(3)))), - idexp("x")), - expectedStr = "[{1 1} {2 2} {3 3}]") - - check("function call unary")( - expr = fncall(idexp("fn"), num(2)), - List("fn" -> function( - bounds(qbIds(ids(id("x")), set(num(1), num(2), num(3)))), - binop("+", idexp("x"), num(1)))), - expectedStr = "3") - - check("function call binary")( - expr = fncall(idexp("fn"), num(2), num(5)), - List("fn" -> function( - bounds( - qbIds(ids(id("x")), set(num(1), num(2), num(3))), - qbIds(ids(id("y")), set(num(4), num(5), num(6)))), - binop("+", idexp("x"), idexp("y")))), - expectedStr = "7") - - check("set cardinality 2")( - expr = opcall("Cardinality", set(num(1), num(2))), - expectedStr = "2") - - check("set cardinality empty")( - expr = opcall("Cardinality", set()), - expectedStr = "0") -} diff --git a/test/pgo/FileTestSuite.scala b/test/pgo/FileTestSuite.scala new file mode 100644 index 000000000..4e7a5d55e --- /dev/null +++ b/test/pgo/FileTestSuite.scala @@ -0,0 +1,97 @@ +package pgo + +import org.scalatest.funsuite.AnyFunSuite +import pgo.model.{PGoError, SourceLocationWithUnderlying} +import pgo.util.Description +import Description._ +import org.scalatest + +import java.util.regex.{MatchResult, Pattern} +import scala.collection.mutable + +trait FileTestSuite extends AnyFunSuite { + def testFiles: List[os.Path] + + def checkErrors(errors: List[PGoError.Error], testFile: os.Path): scalatest.Assertion = { + val fileContents = os.read(testFile) + final class ExpectedError(matchResult: MatchResult) { + val offset: Int = locally { + var offset: Int = matchResult.end() + while(Character.isWhitespace(fileContents.charAt(offset))) { + offset += 1 + } + offset + } + val name: String = matchResult.group(1) + } + + val parenError = Pattern.compile("\\(\\*::\\s+expectedError:\\s+(\\w+)\\s+\\*\\)") + val lineError = Pattern.compile("\\\\\\*::\\s+expectedError:\\s+(\\w+)\\s+") + val expectedErrors = locally { + val resultsBuilder = mutable.ListBuffer[ExpectedError]() + parenError.matcher(fileContents).results().forEachOrdered(res => resultsBuilder += new ExpectedError(res)) + lineError.matcher(fileContents).results().forEachOrdered(res => resultsBuilder += new ExpectedError(res)) + resultsBuilder.result() + } + val groupedErrors = errors.groupBy(_.sourceLocation.maybeOffset) + val groupedExpectedErrors = expectedErrors.groupBy(_.offset) + + val groupOffsets = (groupedErrors.keysIterator ++ groupedExpectedErrors.keysIterator).distinct.toArray.sortInPlace() + val missingErrors = mutable.ListBuffer[ExpectedError]() + val unexpectedErrors = mutable.ListBuffer[PGoError.Error]() + val matchingErrors = mutable.ListBuffer[PGoError.Error]() + groupOffsets.foreach { offset => + val expectedNames = groupedExpectedErrors.getOrElse(offset, Nil).view.map(_.name).toSet + val actualNames = groupedErrors.getOrElse(offset, Nil).view.map(_.productPrefix).toSet + groupedErrors.getOrElse(offset, Nil).foreach { err => + if(!expectedNames(err.productPrefix)) { + unexpectedErrors += err + } else { + matchingErrors += err + } + } + groupedExpectedErrors.getOrElse(offset, Nil).foreach { err => + if(!actualNames(err.name)) { + missingErrors += err + } + } + } + if(missingErrors.nonEmpty || unexpectedErrors.nonEmpty) { + fail { + d"Mismatch between expected errors and actual errors.${ + if(unexpectedErrors.nonEmpty) { + d"Unexpected errors present:${ + unexpectedErrors.view.map { err => + d"${err.productPrefix}: ${err.description} at ${err.sourceLocation.longDescription}" + .indented + .ensureLineBreakBefore + }.flattenDescriptions + }".ensureLineBreakBefore.indented + } else d"" + }${ + if(missingErrors.nonEmpty) { + d"Expected errors missing:${ + missingErrors.view.map { err => + d"${err.name} at ${err.offset}" + .indented + .ensureLineBreakBefore + }.flattenDescriptions + }".ensureLineBreakBefore.indented + } else d"" + }${ + if(matchingErrors.nonEmpty) { + d"Expected errors matched:${ + matchingErrors.view.map { err => + d"${err.productPrefix}: ${err.description} at ${err.sourceLocation.longDescription}" + .indented + .ensureLineBreakBefore + }.flattenDescriptions + }".ensureLineBreakBefore.indented + } else d"" + }".linesIterator.mkString("\n") + } + } else { + succeed + } + } +} diff --git a/test/pgo/GoGenFileTests.scala b/test/pgo/GoGenFileTests.scala new file mode 100644 index 000000000..7165258e7 --- /dev/null +++ b/test/pgo/GoGenFileTests.scala @@ -0,0 +1,19 @@ +package pgo + +class GoGenFileTests extends FileTestSuite { + override val testFiles: List[os.Path] = (os.list.stream(os.pwd / "test" / "files" / "gogen") ++ + os.list.stream(os.pwd / "test" / "files" / "semantics")) + .filter(_.last.endsWith(".tla")) + .toList + + testFiles.foreach { testFile => + test(s"gogen ${testFile.relativeTo(os.pwd)}") { + val outFile = os.temp() + val errors = PGo.run(Seq("gogen", "-s", testFile.toString(), "-o", outFile.toString())) + checkErrors(errors, testFile) + if(errors.isEmpty) { + // TODO: check Go compilation + } + } + } +} diff --git a/test/pgo/IntegrationTestingUtils.java b/test/pgo/IntegrationTestingUtils.java deleted file mode 100644 index 631b854bf..000000000 --- a/test/pgo/IntegrationTestingUtils.java +++ /dev/null @@ -1,374 +0,0 @@ -package pgo; - -import org.json.JSONObject; -import pgo.formatters.IndentingWriter; -import pgo.formatters.TLAExpressionFormattingVisitor; -import pgo.model.tla.TLAExpression; - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertThat; - -import java.io.*; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; -import java.util.stream.Collectors; - -public class IntegrationTestingUtils { - - static class MPCalRunDefinition { - private final String identifier; - private final List args; - private final InputStream expectedOutput; - private final File stdin; - - MPCalRunDefinition(String identifier, List args, InputStream expectedOutput, File stdin) { - this.identifier = identifier; - this.args = args; - this.expectedOutput = expectedOutput; - this.stdin = stdin; - } - - MPCalRunDefinition(String identifier, List args, InputStream expectedOutput) { - this(identifier, args, expectedOutput, null); - } - - String getIdentifier() { - return identifier; - } - - List getArgs() { - return args; - } - - Optional getStdin() { - return Optional.ofNullable(stdin); - } - - String getExpectedOutput() { - return new BufferedReader(new InputStreamReader(expectedOutput)) - .lines() - .collect(Collectors.joining("\n")); - } - } - - private IntegrationTestingUtils() {} - - static class KeyValue { - private final String key; - private final TLAExpression value; - - KeyValue(String key, TLAExpression value) { - super(); - this.key = key; - this.value = value; - } - - String getKey() { - return key; - } - - TLAExpression getValue() { - return value; - } - } - - public interface TestRunner { - void run(T t) throws IOException; - } - - public interface TestSetup { - Path setup(Path tempDirPath) throws IOException; - } - - private static void expungeFile(File file) { - if (file.isDirectory()) { - for (File f : file.listFiles()) { - expungeFile(f); - } - } - if (!file.delete()) { - System.err.println("WARNING: could not delete file "+file+"; check your temp folder"); - } - } - - // See testRunGoCode and testRunGoCodeShouldPanic below for runner examples - static void testCompileFile(Path filePath, Map constants, TestRunner runner) - throws IOException { - testCompile(ignored -> filePath, constants, runner); - } - - // See testRunGoCode and testRunGoCodeShouldPanic below for runner examples - static void testCompileExpression(TLAExpression result, List vars, TestRunner runner) - throws IOException { - testCompile(tempDirPath -> { - Path inputFilePath = tempDirPath.resolve("Test.tla"); - // generate test TLA+ file - try (BufferedWriter w = Files.newBufferedWriter(inputFilePath); - IndentingWriter out = new IndentingWriter(w)) { - out.write("---- MODULE Test ----"); - out.newLine(); - out.write("EXTENDS Sequences, FiniteSets, Integers"); - out.newLine(); - - out.write("(* --algorithm Test {"); - out.newLine(); - try (IndentingWriter.Indent i_ = out.indent()) { - if (!vars.isEmpty()) { - out.write("variables "); - try (IndentingWriter.Indent i2_ = out.indentToPosition()) { - for (KeyValue var : vars) { - out.write(var.getKey()); - out.write(" = "); - var.getValue().accept(new TLAExpressionFormattingVisitor(out)); - out.write(";"); - out.newLine(); - } - } - } - out.write("{"); - out.newLine(); - try (IndentingWriter.Indent i2_ = out.indent()) { - out.write("l: print "); - result.accept(new TLAExpressionFormattingVisitor(out)); - } - out.newLine(); - out.write("}"); - } - out.newLine(); - out.write("}"); - out.newLine(); - out.write("*)"); - - out.newLine(); - out.write("\\* BEGIN TRANSLATION"); - - out.newLine(); - out.write("===="); - } - return inputFilePath; - }, Collections.emptyMap(), runner); - } - - private static void testCompile(TestSetup setup, Map constants, TestRunner runner) - throws IOException { - Path tempDirPath = Files.createTempDirectory("pgotest"); - File tempDir = tempDirPath.toFile(); - Path generatedConfigPath = tempDirPath.resolve("config.json"); - - Path compiledOutputPath = tempDirPath.resolve("test.go"); - try { - Path inputFilePath = setup.setup(tempDirPath); - // generate config file - try (BufferedWriter w = Files.newBufferedWriter(generatedConfigPath)) { - JSONObject config = new JSONObject(); - - JSONObject build = new JSONObject(); - build.put("output_dir", tempDirPath.toString()); - build.put("dest_file", "test.go"); - config.put("build", build); - - JSONObject networking = new JSONObject(); - networking.put("enabled", false); - config.put("networking", networking); - - if (constants.size() > 0) { - JSONObject consts = new JSONObject(); - constants.forEach(consts::put); - config.put("constants", consts); - } - - config.write(w); - } - - // invoke the compiler - PGoMain.main(new String[] { - "-c", - generatedConfigPath.toString(), - inputFilePath.toString(), - }); - - // display the compiled code for inspection - Files.lines(compiledOutputPath).forEach(line -> System.out.println("source: " + line)); - - // try to run the compiled Go code, check that it prints the right thing - runner.run(compiledOutputPath); - } finally { - expungeFile(tempDir); - } - } - - static void testCompileMPCal(Path spec, String pack, Map constants, TestRunner runner) - throws IOException { - Path tempDirPath = Files.createTempDirectory("mpcaltest"); - File tempDir = tempDirPath.toFile(); - Path generatedConfigPath = tempDirPath.resolve("config.json"); - - try { - // generate config file - try (BufferedWriter w = Files.newBufferedWriter(generatedConfigPath)) { - JSONObject config = new JSONObject(); - - JSONObject build = new JSONObject(); - build.put("output_dir", tempDirPath.toString()); - build.put("dest_package", pack); - config.put("build", build); - - if (constants.size() > 0) { - JSONObject consts = new JSONObject(); - constants.forEach(consts::put); - config.put("constants", consts); - } - - config.write(w); - } - - // invoke the compiler - PGoMain.main(new String[] { - "-c", - generatedConfigPath.toString(), - spec.toString(), - }); - - runner.run(tempDirPath); - } finally { - expungeFile(tempDir); - } - } - - static void testRunGoCode(Path codePath, List expected) throws IOException { - // try to run the compiled Go code, check that it prints the right thing - ProcessBuilder pb = new ProcessBuilder("go", "run", codePath.toString()); - Process p = pb.start(); - // print stderr in case it says something interesting - try (InputStream err = p.getErrorStream(); - InputStreamReader r = new InputStreamReader(err); - BufferedReader bw = new BufferedReader(r)) { - bw.lines().forEach(line -> System.out.println("stderr: "+line)); - } - try (InputStream results = p.getInputStream(); - InputStreamReader r = new InputStreamReader(results); - BufferedReader bw = new BufferedReader(r)) { - List lines = bw.lines().collect(Collectors.toList()); - assertThat(lines, is(expected)); - } - } - - static void testRunGoCodeShouldPanic(Path codePath, List expected) throws IOException { - // try to run the compiled Go code, check that it panics - ProcessBuilder pb = new ProcessBuilder("go", "run", codePath.toString()); - Process p = pb.start(); - try (InputStream err = p.getErrorStream(); - InputStreamReader r = new InputStreamReader(err); - BufferedReader bw = new BufferedReader(r)) { - List lines = bw.lines().collect(Collectors.toList()); - assertThat(lines.subList(0, expected.size()), is(expected)); - } - } - - static MPCalRunDefinition mpcalRunDef(String id, List args, InputStream output) { - return new MPCalRunDefinition(id, args, output); - } - - static MPCalRunDefinition mpcalRunDef(String id, List args, File stdin, InputStream output) { - return new MPCalRunDefinition(id, args, output, stdin); - } - - private static List runAndPrint(ProcessBuilder pb, String prefix, boolean checkSuccess) { - try { - List lines = new ArrayList<>(); - Process build = pb.start(); - - try (InputStream err = build.getErrorStream(); - InputStreamReader r = new InputStreamReader(err); - BufferedReader br = new BufferedReader(r)) { - - br.lines().forEach(line -> System.out.println(prefix + ": " + line)); - } - - try (InputStream err = build.getInputStream(); - InputStreamReader r = new InputStreamReader(err); - BufferedReader br = new BufferedReader(r)) { - - br.lines().forEach(line -> { - System.out.println(prefix + ": " + line); - lines.add(line); - }); - } - - try { - int exitCode = build.waitFor(); - if (checkSuccess) { - if (exitCode != 0) { - assertFalse(prefix + " exited with (checked) non-zero exit code " + exitCode, true); - } - } - } catch (InterruptedException e) { - throw new RuntimeException("Interrupted: " + e.getMessage()); - } - - return lines; - } catch (IOException e) { - throw new RuntimeException("IOException: " + e.getMessage()); - } - } - - private static List runAndPrint(ProcessBuilder pb, String prefix) { - return runAndPrint(pb, prefix, true); - } - - static void testRunDistributedMPCal(Path codePath, List runDefinitions) throws InterruptedException { - // compile generate code - String binary = "mpcal_output"; - - // TODO: get rid of `go get` once we remove dependency on etcd - ProcessBuilder pb = new ProcessBuilder("go", "get", "-v"); - pb.environment().put("GOPATH", codePath.toString()); - pb.directory(codePath.resolve("src").resolve("pgo").resolve("distsys").toFile()); - runAndPrint(pb, "get"); - - pb = new ProcessBuilder("go", "build", "-v", "-o", binary); - pb.environment().put("GOPATH", codePath.toString()); - pb.directory(codePath.toFile()); - - runAndPrint(pb, "build"); - - // run the resulting code according to runDefinitions - Map> outputs = new ConcurrentHashMap<>(); - List runs = new ArrayList<>(); - runDefinitions.forEach(def -> - runs.add(new Thread(() -> { - List command = new ArrayList<>(); - command.add(codePath.resolve(binary).toString()); - command.addAll(def.getArgs()); - - System.out.println("Running: " + String.join(" ", command)); - ProcessBuilder builder = new ProcessBuilder(command); - builder.directory(codePath.toFile()); - - def.getStdin().ifPresent(builder::redirectInput); - outputs.put(def.getIdentifier(), runAndPrint(builder, def.getIdentifier())); - })) - ); - - for (Thread t : runs) { - t.start(); - } - - long tenSeconds = 10 * 1000; - for (Thread t : runs) { - t.join(tenSeconds); - } - - runDefinitions.forEach(def -> { - // compare lines instead of collections for easier debugging - // if the test fails - String actual = String.join("\n", outputs.get(def.getIdentifier())); - String expected = String.join("\n", def.getExpectedOutput()); - - assertThat(actual, is(expected)); - }); - } -} diff --git a/test/pgo/MPCalCodeGenRunTest.scala b/test/pgo/MPCalCodeGenRunTest.scala deleted file mode 100644 index 57fcb2327..000000000 --- a/test/pgo/MPCalCodeGenRunTest.scala +++ /dev/null @@ -1,287 +0,0 @@ -package pgo - -import org.scalactic.source.Position -import org.scalatest.funsuite.AnyFunSuite -import pgo.IntegrationTestingUtils.{mpcalRunDef, testCompileMPCal, testRunDistributedMPCal} - -import java.io.{ByteArrayInputStream, FileInputStream, IOException, InputStream} -import java.nio.file.attribute.BasicFileAttributes -import java.nio.file.{FileVisitResult, FileVisitor, Files, Path, Paths} -import java.util -import scala.jdk.CollectionConverters._ - -class MPCalCodeGenRunTest extends AnyFunSuite { - def check(tag: String)(specName: String, pack: String, - constants: Map[String,String], - processes: List[IntegrationTestingUtils.MPCalRunDefinition])(implicit pos: Position): Unit = - test(tag) { - val goDir = Paths.get("test", "mpcal", "go", specName) - - testCompileMPCal(Paths.get("test", "mpcal", "spec", s"$specName.tla"), pack, constants.asJava, { outputPath => - // copy files and directories under test/go/spec/{spec_name} to the compiled - // output temporary directory before we attempt to run it - Files.walkFileTree(goDir, new FileVisitor[Path] { - var currentOutputDir = outputPath - - override def preVisitDirectory(dir: Path, attrs: BasicFileAttributes): FileVisitResult = { - if(dir != goDir) { - Files.copy(dir, currentOutputDir.resolve(dir.getFileName)) - currentOutputDir = currentOutputDir.resolve(dir.getFileName) - } - FileVisitResult.CONTINUE - } - - override def visitFile(file: Path, attrs: BasicFileAttributes): FileVisitResult = { - Files.copy(file, currentOutputDir.resolve(file.getFileName)) - FileVisitResult.CONTINUE - } - - override def visitFileFailed(file: Path, exc: IOException): FileVisitResult = - throw new RuntimeException(s"failed to visit file: $file", exc) - - override def postVisitDirectory(dir: Path, exc: IOException): FileVisitResult = { - if(exc ne null) { - throw new RuntimeException(s"failed to visit directory: $dir", exc) - } else { - currentOutputDir = currentOutputDir.getParent - FileVisitResult.CONTINUE - } - } - }) - - // attempt to run - try { - testRunDistributedMPCal(outputPath, processes.asJava) - } catch { - case e: InterruptedException => - throw new RuntimeException("InterruptedException: " + e.getMessage, e) - } - }) - } - - def strInputStream(str: String): InputStream = - new ByteArrayInputStream(str.getBytes()) - - def fileInputStream(parts: String*): InputStream = - new FileInputStream( - Paths.get("test", Seq("mpcal", "go") ++ parts :_*).toFile) - - check("load_balancer_tuples")( - specName = "load_balancer_tuples", - pack = "load_balancer", - constants = Map( - "NUM_CLIENTS" -> "1", - "LoadBalancerId" -> "0", - "GET_PAGE" -> "200", - "NUM_SERVERS" -> "2"), - processes = List( - mpcalRunDef( - "AClient(3)", - util.Arrays.asList("AClient(3)", "127.0.0.1:5555"), - strInputStream { - """Connected! - |Received page: This is server 1! - |Received page: This is server 2! - |Received page: This is server 1! - |Received page: This is server 2!""".stripMargin - }), - mpcalRunDef( - "ALoadBalancer(0)", - util.Arrays.asList("ALoadBalancer(0)", "127.0.0.1:2222"), - strInputStream("")), - mpcalRunDef( - "AServer(1)", - util.Arrays.asList("AServer(1)", "127.0.0.1:3333", "page1.html"), - strInputStream("")), - mpcalRunDef( - "AServer(2)", - util.Arrays.asList("AServer(2)", "127.0.0.1:4444", "page2.html"), - strInputStream("")))) - - check("load_balancer_record_payloads")( - specName = "load_balancer_record_payloads", - pack = "load_balancer", - constants = Map( - "NUM_CLIENTS" -> "1", - "LoadBalancerId" -> "0", - "GET_PAGE" -> "200", - "NUM_SERVERS" -> "2"), - List( - mpcalRunDef( - "AClient(3)", - List("AClient(3)", "127.0.0.1:5555").asJava, - strInputStream { - """Connected! - |Received page: This is server 1! - |Received page: This is server 2! - |Received page: This is server 1! - |Received page: This is server 2!""".stripMargin - }), - mpcalRunDef( - "ALoadBalancer(0)", - util.Arrays.asList("ALoadBalancer(0)", "127.0.0.1:2222"), - strInputStream("")), - mpcalRunDef( - "AServer(1)", - List("AServer(1)", "127.0.0.1:3333", "page1.html").asJava, - strInputStream("")), - mpcalRunDef( - "AServer(2)", - List("AServer(2)", "127.0.0.1:4444", "page2.html").asJava, - strInputStream("")))) - - check("load_balancer_file_system")( - specName = "load_balancer_file_system", - pack = "load_balancer", - constants = Map( - "NUM_CLIENTS" -> "1", - "LoadBalancerId" -> "0", - "GET_PAGE" -> "200", - "NUM_SERVERS" -> "2"), - processes = List( - mpcalRunDef( - "AClient(3)", - List("AClient(3)", "127.0.0.1:5555").asJava, - strInputStream { - """Connected! - |Received page: This is server 1! - |Received page: This is server 1! - |Received page: This is server 2!""".stripMargin - }), - mpcalRunDef( - "ALoadBalancer(0)", - List("ALoadBalancer(0)", "127.0.0.1:2222").asJava, - strInputStream("")), - mpcalRunDef( - "AServer(1)", - List("AServer(1)", "127.0.0.1:3333", "pages").asJava, - strInputStream("")), - mpcalRunDef( - "AServer(2)", - List("AServer(2)", "127.0.0.1:4444", "pages").asJava, - strInputStream("")))) - - // Simple replicated_kv tests. No concurrency to update the same - // keys because we want to make the state of the database after - // execution deterministic - check("replicated_kv")( - specName = "replicated_kv", - pack = "replicated_kv", - constants = Map( - "DISCONNECT_MSG" -> "\"disconnect\"", - "GET_MSG" -> "\"get\"", - "PUT_MSG" -> "\"put\"", - "NULL_MSG" -> "\"clock_update\"", - "NUM_CLIENTS" -> "2", - "NUM_REPLICAS" -> "3", - "GET_RESPONSE" -> "\"get_response\"", - "PUT_RESPONSE" -> "\"put_response\""), - processes = List( - mpcalRunDef( - "Client(3)", - List( - "Client(3)", "Put a Client3-v1", "Put b Client3-v2", - "Get x", "Put c Client3-v3", "Get b" - ).asJava, - strInputStream { - """-- Put (a, Client3-v1): OK - |-- Put (b, Client3-v2): OK - |-- Get x: - |-- Put (c, Client3-v3): OK - |-- Get b: Client3-v2""".stripMargin - }), - mpcalRunDef( - "Client(4)", - List( - "Client(4)", "Put d Client4-v1", "Put d Client4-v2", - "Put e Client4-v3", "Get d", "Get e" - ).asJava, - strInputStream { - """-- Put (d, Client4-v1): OK - |-- Put (d, Client4-v2): OK - |-- Put (e, Client4-v3): OK - |-- Get d: Client4-v2 - |-- Get e: Client4-v3""".stripMargin - }), - mpcalRunDef( - "Replica(0)", - List("Replica(0)").asJava, - strInputStream { - "Replica snapshot:\n" + - "\ta -> Client3-v1\n" + - "\tb -> Client3-v2\n" + - "\tc -> Client3-v3\n" + - "\td -> Client4-v2\n" + - "\te -> Client4-v3" - }), - mpcalRunDef( - "Replica(1)", - List("Replica(1)").asJava, - strInputStream { - "Replica snapshot:\n" + - "\ta -> Client3-v1\n" + - "\tb -> Client3-v2\n" + - "\tc -> Client3-v3\n" + - "\td -> Client4-v2\n" + - "\te -> Client4-v3" - }), - mpcalRunDef( - "Replica(2)", - List("Replica(2)").asJava, - strInputStream { - "Replica snapshot:\n" + - "\ta -> Client3-v1\n" + - "\tb -> Client3-v2\n" + - "\tc -> Client3-v3\n" + - "\td -> Client4-v2\n" + - "\te -> Client4-v3" - }))) - - // Concurrent replicated key-value store: each client is given a list of - // operations, and they perform them concurrently (different Go routine for - // each operation). Since the client's output is non-deterministic, we only - // verify the output of the replica at the end of the process, guaranteeing - // that they are all consistent and equal. - check("concurrent_replicated_kv")( - specName = "concurrent_replicated_kv", - pack = "replicated_kv", - constants = Map( - "DISCONNECT_MSG" -> "\"disconnect\"", - "GET_MSG" -> "\"get\"", - "PUT_MSG" -> "\"put\"", - "NULL_MSG" -> "\"clock_update\"", - "NUM_CLIENTS" -> "3", - "NUM_REPLICAS" -> "2", - "GET_RESPONSE" -> "\"get_response\"", - "PUT_RESPONSE" -> "\"put_response\""), - processes = List( - mpcalRunDef( - "Replica(0)", - List("Replica(0)").asJava, - fileInputStream("concurrent_replicated_kv", "replicas_out.txt")), - mpcalRunDef( - "Replica(1)", - List("Replica(1)").asJava, - fileInputStream("concurrent_replicated_kv", "replicas_out.txt")), - mpcalRunDef( - "Client(2)", - List("Client(2)").asJava, - Paths.get( - "test", "mpcal", "go", "concurrent_replicated_kv", "client2_in.txt" - ).toFile(), - strInputStream("")), - mpcalRunDef( - "Client(3)", - List("Client(3)").asJava, - Paths.get( - "test", "mpcal", "go", "concurrent_replicated_kv", "client3_in.txt" - ).toFile(), - strInputStream("")), - mpcalRunDef( - "Client(4)", - List("Client(4)").asJava, - Paths.get( - "test", "mpcal", "go", "concurrent_replicated_kv", "client4_in.txt" - ).toFile(), - strInputStream("")))) -} diff --git a/test/pgo/PCalGenFileTests.scala b/test/pgo/PCalGenFileTests.scala new file mode 100644 index 000000000..e73d67376 --- /dev/null +++ b/test/pgo/PCalGenFileTests.scala @@ -0,0 +1,19 @@ +package pgo + +class PCalGenFileTests extends FileTestSuite { + override val testFiles: List[os.Path] = (os.list.stream(os.pwd / "test" / "files" / "pcalgen") ++ + os.list.stream(os.pwd / "test" / "files" / "semantics")) + .filter(_.last.endsWith(".tla")) + .toList + + testFiles.foreach { testFile => + test(s"pcalgen ${testFile.relativeTo(os.pwd)}") { + val tmpFile = os.temp(contents = testFile.toSource) + val errors = PGo.run(Seq("pcalgen", "-s", tmpFile.toString())) + checkErrors(errors, testFile) + if(errors.isEmpty) { + // TODO: check PCal compilation + } + } + } +} \ No newline at end of file diff --git a/test/pgo/PGoNetOptionsTest.scala b/test/pgo/PGoNetOptionsTest.scala deleted file mode 100644 index 3b21a8e8d..000000000 --- a/test/pgo/PGoNetOptionsTest.scala +++ /dev/null @@ -1,119 +0,0 @@ -package pgo - -import org.json.JSONObject -import org.scalatest.funsuite.AnyFunSuite - -import java.util - -class PGoNetOptionsTest extends AnyFunSuite { // parsed JSON object for the configuration file used in the tests - val configStr = - """{ - | "build": { - | "output_dir": "gen", - | "dest_file": "out.go" - | }, - | "networking": { - | "enabled": true, - | - | "state": { - | "strategy": "etcd", - | "peers": ["10.0.0.1:12345", "10.0.0.2:12345"], - | "endpoints": ["172.28.128.7:2379", "172.28.128.8:2379", "172.28.128.9:2379"], - | "timeout": 3 - | } - | } - |} - |""".stripMargin - - trait OFixture { - val config = new JSONObject(configStr) - - def getNetworking = config.getJSONObject(PGoNetOptions.NETWORKING_FIELD) - - def options = new PGoNetOptions(config) - } - - // networking mode is disabled if the configuration field is not present - test("testNoNetworking")(new OFixture { - config.remove("networking") - assert(!options.isEnabled) - }) - - // networking mode is disabled if explicitly configured so in the configuration file - test("testNetworkingDisabled")(new OFixture { - getNetworking.put("enabled", false) - assert(!options.isEnabled) - }) - - // configuration is invalid if an unknown state management strategy is used - test("testInvalidStateManagementStrategy")(new OFixture { - getNetworking.getJSONObject(PGoNetOptions.STATE_FIELD).put("strategy", "invalid") - assertThrows[PGoOptionException] { - options - } - }) - - // centralized-etcd state management is used if no strategy is declared - test("testDefaultStateStrategy")(new OFixture { - getNetworking.getJSONObject(PGoNetOptions.STATE_FIELD).remove("strategy") - assert(PGoNetOptions.StateOptions.STATE_SERVER == options.getStateOptions.strategy) - }) - - // having no endpoints in the centralized-etcd strategy is invalid - test("testNoEndpointsCentralizedEtcd")(new OFixture { - getNetworking.getJSONObject(PGoNetOptions.STATE_FIELD).put("strategy", "centralized-etcd") - getNetworking.getJSONObject(PGoNetOptions.STATE_FIELD).put("endpoints", new util.Vector[AnyRef]) - assertThrows[PGoOptionException] { - options - } - }) - - // having no endpoints in the centralized strategy is invalid - test("testNoEndpointsCentralized")(new OFixture { - getNetworking.getJSONObject(PGoNetOptions.STATE_FIELD).put("strategy", "centralized") - getNetworking.getJSONObject(PGoNetOptions.STATE_FIELD).put("endpoints", new util.Vector[AnyRef]) - assertThrows[PGoOptionException] { - options - } - }) - - // having more than one endpoint in the centralized strategy is invalid - test("testMoreThanOneEndpointCentralized")(new OFixture { - getNetworking.getJSONObject(PGoNetOptions.STATE_FIELD).put("strategy", "centralized") - getNetworking.getJSONObject(PGoNetOptions.STATE_FIELD).put("endpoints", new util.Vector[String](util.Arrays.asList("10.10.0.10", "10.10.0.11"))) - assertThrows[PGoOptionException] { - options - } - }) - - // the developer is able to specify the timeout for operations on global state - test("testTimeout")(new OFixture { - getNetworking.getJSONObject(PGoNetOptions.STATE_FIELD).put("timeout", 10) - assert(10 == options.getStateOptions.timeout) - }) - - test("testDefaultTimeout")(new OFixture { - getNetworking.getJSONObject(PGoNetOptions.STATE_FIELD).remove("timeout") - assert(3 == options.getStateOptions.timeout) - }) - - // when the configuration file misses a required field (e.g., "state" or "channels"), - // we throw a +PGoOptionException+, so that the user sees a proper error message - // instead of a stack trace. - test("testMissingRequiredFields")(new OFixture { - getNetworking.remove(PGoNetOptions.STATE_FIELD) - assertThrows[PGoOptionException] { - options - } - }) - - // it works and parses the information correctly when the configuration file - // is well-formed - test("testWellFormedConfiguration")(new OFixture { - val net = options - assert(net.isEnabled) - val expectedHosts = util.Arrays.asList("172.28.128.7:2379", "172.28.128.8:2379", "172.28.128.9:2379") - assert(PGoNetOptions.StateOptions.STATE_ETCD == net.getStateOptions.strategy) - assert(expectedHosts == net.getStateOptions.endpoints) - }) -} \ No newline at end of file diff --git a/test/pgo/PlusCalCodeGenPassTest.scala b/test/pgo/PlusCalCodeGenPassTest.scala deleted file mode 100644 index 8cd926a40..000000000 --- a/test/pgo/PlusCalCodeGenPassTest.scala +++ /dev/null @@ -1,1593 +0,0 @@ -package pgo - -import com.github.difflib.{DiffUtils, UnifiedDiffUtils} -import org.scalactic.source.Position -import org.scalatest.funsuite.AnyFunSuite -import pgo.errors.TopLevelIssueContext -import pgo.model.pcal.{PlusCalAlgorithm, PlusCalFairness} -import pgo.model.pcal.PlusCalBuilder.{`with`, _} -import pgo.model.tla.TLABuilder._ - -import java.util -import java.util.{Arrays, Collections} -import scala.jdk.CollectionConverters._ - -class PlusCalCodeGenPassTest extends AnyFunSuite { - def check(tag: String)(pair: (String, PlusCalAlgorithm))(implicit pos: Position): Unit = - test(tag) { - val (inputStr, expectedAlgorithm) = pair - withClue(s"with input:\n$inputStr\n") { - val (testFile, tlaModule, mpcalBlock) = TestingUtils.parseMPCalFromString(inputStr) - - val main = new PGoMain(Array[String]()) - val ctx = new TopLevelIssueContext() - - val actualAlgorithm = main.mpcalToPcal(testFile, ctx, mpcalBlock, tlaModule) - - withClue(s"with diff:\n${TestingUtils.stringDiff(expected = expectedAlgorithm.toString, actual = actualAlgorithm.toString).mkString("\n")}\n") { - assert(expectedAlgorithm == actualAlgorithm) - } - } - } - - check("algorithm1") { - """ - |----MODULE Algorithm1 ---- - |EXTENDS TLC, Sequences, FiniteSets, Integers - |(* - |--mpcal Algorithm1 { - | archetype A1(a) { - | l1: skip; - | } - | - | variable x = 10; - | fair process (P1 = 42) == instance A1(x); - |} - |*) - |\* BEGIN TRANSLATION - |==== - |""".stripMargin -> - // -- algorithm Algorithm1 { - // variable x = 10; - // fair process (P1 = 42) { - // l1: skip; - // } - // } - algorithm( - "Algorithm1", - Collections.singletonList(pcalVarDecl("x", false, false, num(10))), - Collections.emptyList, - Collections.emptyList, - Collections.emptyList, - process( - pcalVarDecl("P1", false, false, num(42)), - PlusCalFairness.WEAK_FAIR, - Collections.emptyList, - labeled(label("l1"), - skip))) - } - - check("algorithm2") { - """ - |----MODULE Algorithm2 ---- - |EXTENDS TLC, Sequences, FiniteSets, Integers - |(* - |--mpcal Algorithm2 { - | mapping macro Zero { - | read { - | yield 0 - | } - | write { - | yield $variable - | } - | } - | archetype A1(a, ref b) { - | l1: print << a, b >>; - | } - | - | variables x = 10, y = 20; - | fair process (P1 = 42) == instance A1(x, ref y) - | mapping x via Zero; - |} - |*) - |\* BEGIN TRANSLATION - |==== - |""".stripMargin -> - // --algorithm Algorithm2 { - // variables x = 10, y = 20, aRead, bRead; - // fair process (P1 = 42) - // { - // l1: aRead := 0; - // bRead := y; - // print << (aRead), (bRead) >>; - // } - // } - algorithm( - "Algorithm2", - util.Arrays.asList( - pcalVarDecl("x", false, false, num(10)), - pcalVarDecl("y", false, false, num(20)), - pcalVarDecl("aRead", false, false, PLUSCAL_DEFAULT_INIT_VALUE), - pcalVarDecl("bRead", false, false, PLUSCAL_DEFAULT_INIT_VALUE)), - Collections.emptyList, - Collections.emptyList, - Collections.emptyList, - process( - pcalVarDecl("P1", false, false, num(42)), - PlusCalFairness.WEAK_FAIR, - Collections.emptyList, - labeled(label("l1"), - assign(idexp("aRead"), num(0)), - assign(idexp("bRead"), idexp("y")), - printS(tuple(idexp("aRead"), idexp("bRead")))))) - } - - check("algorithm3") { - """ - |----MODULE Algorithm3 ---- - |EXTENDS TLC, Sequences, FiniteSets, Integers - |(* - |--mpcal Algorithm3 { - | mapping macro WeirdMacro { - | read { - | $variable := $variable - 1; - | with (v = 50) { - | either { yield v } or { yield 10 } - | } - | } - | write { - | yield $value + 1 - | } - | } - | archetype A1(ref a, b) - | variable local; { - | l1: if (a >= 42) { - | local := 42; - | }; - | l2: a := 10; - | l3: local := a + b; - | l4: print local; - | } - | variables x = 10, y = 20; - | fair process (P1 = 100) == instance A1(ref x, y) - | mapping x via WeirdMacro; - |} - |*) - |\* BEGIN TRANSLATION - |==== - |""".stripMargin -> - // --algorithm Algorithm3 { - // variables x = 10, y = 20, aRead, aWrite, bRead; - // process (P1 = 100) - // variables local; - // { - // l1: - // aWrite := (x)-(1); - // with (v0 = 50) { - // either { - // aRead := v0; - // } or { - // aRead := 10; - // }; - // }; - // if ((aRead)>=(42)) { - // local := 42; - // x := aWrite; - // } else { - // x := aWrite; - // } - // l2: - // aWrite := (10)+(1); - // x := aWrite; - // l3: - // aWrite := (x)-(1); - // with (v1 = 50) { - // either { - // aRead := v1; - // } or { - // aRead := 10; - // }; - // }; - // bRead := y; - // local := (aRead)+(bRead); - // x := aWrite; - // l4: - // print local; - // - // } - // } - algorithm( - "Algorithm3", - util.Arrays.asList( - pcalVarDecl("x", false, false, num(10)), - pcalVarDecl("y", false, false, num(20)), - pcalVarDecl("aRead", false, false, PLUSCAL_DEFAULT_INIT_VALUE), - pcalVarDecl("aWrite", false, false, PLUSCAL_DEFAULT_INIT_VALUE), - pcalVarDecl("bRead", false, false, PLUSCAL_DEFAULT_INIT_VALUE)), - Collections.emptyList, - Collections.emptyList, - Collections.emptyList, - process( - pcalVarDecl("P1", false, false, num(100)), - PlusCalFairness.WEAK_FAIR, - Collections.singletonList( - pcalVarDecl("local", false, false, PLUSCAL_DEFAULT_INIT_VALUE)), - labeled(label("l1"), - assign(idexp("aWrite"), binop("-", idexp("x"), num(1))), - `with`( - Collections.singletonList(pcalVarDecl("v0", false, false, num(50))), - either(util.Arrays.asList( - Collections.singletonList(assign(idexp("aRead"), idexp("v0"))), - Collections.singletonList(assign(idexp("aRead"), num(10)))))), - ifS( - binop(">=", idexp("aRead"), num(42)), - util.Arrays.asList( - assign(idexp("local"), num(42)), - assign(idexp("x"), idexp("aWrite"))), - Collections.singletonList(assign(idexp("x"), idexp("aWrite"))))), - labeled(label("l2"), - assign(idexp("aWrite"), binop("+", num(10), num(1))), - assign(idexp("x"), idexp("aWrite"))), labeled(label("l3"), - assign(idexp("aWrite"), binop("-", idexp("x"), num(1))), - `with`( - Collections.singletonList(pcalVarDecl("v1", false, false, num(50))), - either(util.Arrays.asList( - Collections.singletonList(assign(idexp("aRead"), idexp("v1"))), - Collections.singletonList(assign(idexp("aRead"), num(10)))))), - assign(idexp("bRead"), idexp("y")), - assign(idexp("local"), binop("+", idexp("aRead"), idexp("bRead"))), - assign(idexp("x"), idexp("aWrite"))), labeled(label("l4"), - printS(idexp("local"))))) - } - - check("algorithm4") { - """ - |----MODULE Algorithm4 ---- - |EXTENDS TLC, Sequences, FiniteSets, Integers - |(* - |--mpcal Algorithm4 { - | mapping macro WeirdMacro { - | read { - | $variable := $variable - 1; - | yield $variable; - | } - | write { - | $variable := $variable + 1; - | yield $variable + $value; - | } - | } - | archetype A1(ref a, b) - | variable local; { - | l1: if (a >= 42) { - | a := 42; - | }; - | l2: a := 10; - | local := a + a + b; - | l3: local := a + b; - | l4: print local; - | } - | variables x = 10, y = 20; - | fair process (P1 = 100) == instance A1(ref x, y) - | mapping x via WeirdMacro; - |} - |*) - |\* BEGIN TRANSLATION - |==== - |""".stripMargin -> - // --algorithm Algorithm4 { - // variables x = 10, y = 20, aRead, aWrite, aWrite0, aWrite1, aRead0, bRead; - // process (P1 = 100) - // variables local; - // { - // l1: - // aWrite := (x)-(1); - // aRead := aWrite; - // if ((aRead)>=(42)) { - // aWrite0 := (aWrite)+(1); - // aWrite1 := (aWrite0)+(42); - // aWrite2 := aWrite1; - // x := aWrite2; - // } else { - // aWrite2 := x; - // x := aWrite2; - // }; - // l2: - // aWrite := (x)+(1); - // aWrite0 := (aWrite)+(10); - // aWrite0 := (aWrite0)-(1); - // aRead := aWrite0; - // aWrite1 := (aWrite0)-(1); - // aRead0 := aWrite1; - // bRead := y; - // local := ((aRead)+(aRead0))+(bRead); - // x := aWrite1; - // l3: - // aWrite := (x)-(1); - // aRead := aWrite; - // bRead := y; - // local := (aRead)+(bRead); - // x := aWrite; - // l4: - // print local; - // } - // } - algorithm( - "Algorithm4", - util.Arrays.asList( - pcalVarDecl("x", false, false, num(10)), - pcalVarDecl("y", false, false, num(20)), - pcalVarDecl("aRead", false, false, PLUSCAL_DEFAULT_INIT_VALUE), - pcalVarDecl("aWrite", false, false, PLUSCAL_DEFAULT_INIT_VALUE), - pcalVarDecl("aWrite0", false, false, PLUSCAL_DEFAULT_INIT_VALUE), - pcalVarDecl("aWrite1", false, false, PLUSCAL_DEFAULT_INIT_VALUE), - pcalVarDecl("aWrite2", false, false, PLUSCAL_DEFAULT_INIT_VALUE), - pcalVarDecl("aRead0", false, false, PLUSCAL_DEFAULT_INIT_VALUE), - pcalVarDecl("bRead", false, false, PLUSCAL_DEFAULT_INIT_VALUE)), - Collections.emptyList, - Collections.emptyList, - Collections.emptyList, - process( - pcalVarDecl("P1", false, false, num(100)), - PlusCalFairness.WEAK_FAIR, - Collections.singletonList(pcalVarDecl("local", false, false, PLUSCAL_DEFAULT_INIT_VALUE)), - labeled(label("l1"), - assign(idexp("aWrite"), binop("-", idexp("x"), num(1))), - assign(idexp("aRead"), idexp("aWrite")), - ifS( - binop(">=", idexp("aRead"), num(42)), - util.Arrays.asList( - assign(idexp("aWrite0"), binop("+", idexp("aWrite"), num(1))), - assign(idexp("aWrite1"), binop("+", idexp("aWrite0"), num(42))), - assign(idexp("aWrite2"), idexp("aWrite1")), - assign(idexp("x"), idexp("aWrite2"))), - util.Arrays.asList( - assign(idexp("aWrite2"), idexp("x")), - assign(idexp("x"), idexp("aWrite2"))))), - labeled(label("l2"), - assign(idexp("aWrite"), binop("+", idexp("x"), num(1))), - assign(idexp("aWrite0"), binop("+", idexp("aWrite"), num(10))), - assign(idexp("aWrite1"), binop("-", idexp("aWrite0"), num(1))), - assign(idexp("aRead"), idexp("aWrite1")), - assign(idexp("aWrite2"), binop("-", idexp("aWrite1"), num(1))), - assign(idexp("aRead0"), idexp("aWrite2")), - assign(idexp("bRead"), idexp("y")), - assign(idexp("local"), binop("+", binop("+", idexp("aRead"), idexp("aRead0")), idexp("bRead"))), - assign(idexp("x"), idexp("aWrite2"))), labeled(label("l3"), - assign(idexp("aWrite"), binop("-", idexp("x"), num(1))), - assign(idexp("aRead"), idexp("aWrite")), assign(idexp("bRead"), idexp("y")), assign(idexp("local"), binop("+", idexp("aRead"), idexp("bRead"))), - assign(idexp("x"), idexp("aWrite"))), - labeled(label("l4"), - printS(idexp("local"))))) - } - - check("algorithm5") { - """ - |----MODULE Algorithm5 ---- - |EXTENDS TLC, Sequences, FiniteSets, Integers - |(* - |--mpcal Algorithm5 { - | mapping macro TCPConnection { - | read { - | with (msg = Head($variable)) { - | $variable := Tail($variable); - | yield msg; - | } - | } - | - | write { - | yield Append($variable, $value); - | } - | } - | - | archetype AddClient(ref netw) { - | l1: netw := 21; - | l2: netw := 21; - | print netw; - | } - | - | archetype AddServer(ref netw) - | variables a, b; - | { - | l1: a := netw; - | b := netw; - | netw := a + b; - | } - | - | variable network = <<>>; - | fair process (S = 42) == instance AddServer(ref network) - | mapping network via TCPConnection; - | fair process (C = 21) == instance AddClient(ref network) - | mapping network via TCPConnection; - |} - |*) - |\* BEGIN TRANSLATION - |==== - |""".stripMargin -> - // --algorithm Algorithm5 { - // variables network = <<>>, netwRead, netwWrite, netwRead0, netwWrite0, netwWrite1, - // netwWrite2, netwRead1, netwWrite3; - // fair process (S = 42) - // variables a, b; - // { - // l1: - // with (msg0 = Head(network)) { - // netwWrite := Tail(network); - // netwRead := msg0; - // } - // a := netwRead; - // with (msg1 = Head(netwWrite)) { - // netwWrite0 := Tail(netwWrite); - // netwRead0 := msg1; - // } - // b := netwRead0; - // netwWrite1 := Append(netwWrite0,(a)+(b)); - // network := netwWrite1; - // - // } - // fair process (C = 42) { - // l1: - // netwWrite2 := Append(network,21); - // network := netwWrite2; - // l2: - // netwWrite2 := Append(network,21); - // with (msg2 = Head(netwWrite2)) { - // netwWrite3 := Tail(netwWrite2); - // netwRead1 := msg2; - // } - // print netwRead1; - // network := netwWrite3; - // - // } - // } - algorithm( - "Algorithm5", - util.Arrays.asList( - pcalVarDecl("network", false, false, tuple()), - pcalVarDecl("netwRead", false, false, PLUSCAL_DEFAULT_INIT_VALUE), - pcalVarDecl("netwWrite", false, false, PLUSCAL_DEFAULT_INIT_VALUE), - pcalVarDecl("netwRead0", false, false, PLUSCAL_DEFAULT_INIT_VALUE), - pcalVarDecl("netwWrite0", false, false, PLUSCAL_DEFAULT_INIT_VALUE), - pcalVarDecl("netwWrite1", false, false, PLUSCAL_DEFAULT_INIT_VALUE), - pcalVarDecl("netwWrite2", false, false, PLUSCAL_DEFAULT_INIT_VALUE), - pcalVarDecl("netwRead1", false, false, PLUSCAL_DEFAULT_INIT_VALUE), - pcalVarDecl("netwWrite3", false, false, PLUSCAL_DEFAULT_INIT_VALUE)), - Collections.emptyList, - Collections.emptyList, - Collections.emptyList, - process( - pcalVarDecl("S", false, false, num(42)), - PlusCalFairness.WEAK_FAIR, - util.Arrays.asList( - pcalVarDecl("a", false, false, PLUSCAL_DEFAULT_INIT_VALUE), - pcalVarDecl("b", false, false, PLUSCAL_DEFAULT_INIT_VALUE)), - labeled(label("l1"), - `with`( - Collections.singletonList(pcalVarDecl("msg0", false, false, opcall("Head", idexp("network")))), - assign(idexp("netwWrite"), opcall("Tail", idexp("network"))), - assign(idexp("netwRead"), idexp("msg0"))), - assign(idexp("a"), idexp("netwRead")), - `with`( - Collections.singletonList(pcalVarDecl("msg1", false, false, opcall("Head", idexp("netwWrite")))), - assign(idexp("netwWrite0"), opcall("Tail", idexp("netwWrite"))), - assign(idexp("netwRead0"), idexp("msg1"))), - assign(idexp("b"), idexp("netwRead0")), - assign(idexp("netwWrite1"), opcall("Append", idexp("netwWrite0"), binop("+", idexp("a"), idexp("b")))), - assign(idexp("network"), idexp("netwWrite1")))), - process( - pcalVarDecl("C", false, false, num(21)), - PlusCalFairness.WEAK_FAIR, - Collections.emptyList, - labeled(label("l1"), - assign(idexp("netwWrite2"), opcall("Append", idexp("network"), num(21))), - assign(idexp("network"), idexp("netwWrite2"))), - labeled(label("l2"), - assign(idexp("netwWrite2"), opcall("Append", idexp("network"), num(21))), - `with`( - Collections.singletonList(pcalVarDecl("msg2", false, false, opcall("Head", idexp("netwWrite2")))), - assign(idexp("netwWrite3"), opcall("Tail", idexp("netwWrite2"))), - assign(idexp("netwRead1"), idexp("msg2"))), printS(idexp("netwRead1")), - assign(idexp("network"), idexp("netwWrite3"))))) - } - - check("algorithm6") { - """ - |----MODULE Algorithm6 ---- - |EXTENDS TLC, Sequences, FiniteSets, Integers - |(* - |--mpcal Algorithm6 { - | mapping macro FunctionMapping { - | read { - | yield $variable; - | } - | - | write { - | yield $value; - | } - | } - | - | archetype A(ref f) - | { - | l1: f[0] := 1; - | f[1] := 0; - | print <>; - | } - | - | variable func = [i \in {0, 1} |-> i]; - | fair process (P = 42) == instance A(ref func) - | mapping func[_] via FunctionMapping; - |} - |*) - |\* BEGIN TRANSLATION - |==== - |""".stripMargin -> - // --algorithm Algorithm6 { - // variables func = [i \in {0,1} |-> i], fWrite, fWrite0, fRead, fRead0; - // fair process (P = 42) { - // l1: - // fWrite := [func EXCEPT ![0] = 1]; - // fWrite0 := [fWrite EXCEPT ![1] = 0]; - // fRead := fWrite0[0]; - // fRead0 := fWrite0[1]; - // print <>; - // func := fWrite0; - // } - // } - algorithm( - "Algorithm6", - util.Arrays.asList( - pcalVarDecl("func", false, false, - function(bounds(qbIds(Collections.singletonList(id("i")), set(num(0), num(1)))), idexp("i"))), - pcalVarDecl("fWrite", false, false, PLUSCAL_DEFAULT_INIT_VALUE), - pcalVarDecl("fWrite0", false, false, PLUSCAL_DEFAULT_INIT_VALUE), - pcalVarDecl("fRead", false, false, PLUSCAL_DEFAULT_INIT_VALUE), - pcalVarDecl("fRead0", false, false, PLUSCAL_DEFAULT_INIT_VALUE)), - Collections.emptyList, - Collections.emptyList, - Collections.emptyList, - process( - pcalVarDecl("P", false, false, num(42)), - PlusCalFairness.WEAK_FAIR, - Collections.emptyList, - labeled(label("l1"), - assign(idexp("fWrite"), fnSubst(idexp("func"), fnSubstPair(Collections.singletonList(substKey(num(0))), num(1)))), - assign(idexp("fWrite0"), fnSubst(idexp("fWrite"), fnSubstPair(Collections.singletonList(substKey(num(1))), num(0)))), - assign(idexp("fRead"), fncall(idexp("fWrite0"), num(0))), - assign(idexp("fRead0"), fncall(idexp("fWrite0"), num(1))), - printS(tuple(idexp("fRead"), idexp("fRead0"))), - assign(idexp("func"), idexp("fWrite0"))))) - } - - check("algorithm7") { - """ - |----MODULE Algorithm7 ---- - |EXTENDS TLC, Sequences, FiniteSets, Integers - |(* - |--mpcal Algorithm7 { - | mapping macro TCPConnection { - | read { - | with (msg = Head($variable)) { - | $variable := Tail($variable); - | yield msg; - | } - | } - | - | write { - | yield Append($variable, $value); - | } - | } - | - | archetype AddClient(ref netw) { - | l1: netw[self] := 21; - | l2: netw[self] := 21; - | print netw[self]; - | } - | - | archetype AddServer(ref netw) - | variables a, b, dest; - | { - | l1: either { - | a := netw[0]; - | dest := 0; - | } or { - | a := netw[1]; - | dest := 1; - | }; - | b := netw[dest]; - | netw[dest] := a + b; - | } - | - | variable network = [i \in {0, 1} |-> <<>>]; - | fair process (S = 42) == instance AddServer(ref network) - | mapping network[_] via TCPConnection; - | fair process (C \in {0, 1}) == instance AddClient(ref network) - | mapping network[_] via TCPConnection; - |} - |*) - |\* BEGIN TRANSLATION - |==== - |""".stripMargin -> - // --algorithm Algorithm7 { - // variables network = [i \in {0,1}|-><<>>], netwRead, netwWrite, netwRead0, netwWrite0, - // netwRead1, netwWrite1, netwWrite2, netwWrite3, netwRead2, netwWrite4; - // fair process (S = 42) - // variables a, b, dest; - // { - // l1: - // either { - // with (msg0 = Head(network[0])) { - // netwWrite := [network EXCEPT ![0] = Tail(network[0])]; - // netwRead := msg0; - // } - // a := netwRead; - // dest := 0; - // netwWrite0 := netwWrite; - // } or { - // with (msg1 = Head(network[1])) { - // netwWrite := [network EXCEPT ![1] = Tail(network[1])]; - // netwRead := msg1; - // } - // a := netwRead; - // dest := 1; - // netwWrite0 := netwWrite; - // } - // with (msg2 = Head(netwWrite0[dest])) { - // netwWrite1 := [netwWrite0 EXCEPT ![dest] = Tail(netwWrite0[dest])]; - // netwRead0 := msg2; - // } - // b := netwRead0; - // netwWrite2 := [netwWrite1 EXCEPT ![dest] = Append(netwWrite1[dest], (a)+(b))]; - // network = netwWrite2; - // } - // fair process (C \in {0,1}) { - // l1: - // netwWrite3 := [network EXCEPT ![self] = Append(network[self], 21)]; - // network := netwWrite3; - // l2: - // netwWrite3 := [network EXCEPT ![self] = Append(network[self], 21)]; - // with (msg3 = Head(netwWrite3[self])) { - // netwWrite4 := [netwWrite3 EXCEPT ![self] = Tail(netwWrite3[self])]; - // netwRead1 := msg3; - // } - // print netwRead1; - // network := netWrite4; - // } - // } - algorithm( - "Algorithm7", - Arrays.asList( - pcalVarDecl( - "network", - false, - false, - function(bounds(qbIds(Collections.singletonList(id("i")), set(num(0), num(1)))), tuple())), - pcalVarDecl("netwRead", false, false, PLUSCAL_DEFAULT_INIT_VALUE), - pcalVarDecl("netwWrite", false, false, PLUSCAL_DEFAULT_INIT_VALUE), - pcalVarDecl("netwRead0", false, false, PLUSCAL_DEFAULT_INIT_VALUE), - pcalVarDecl("netwWrite0", false, false, PLUSCAL_DEFAULT_INIT_VALUE), - pcalVarDecl("netwRead1", false, false, PLUSCAL_DEFAULT_INIT_VALUE), - pcalVarDecl("netwWrite1", false, false, PLUSCAL_DEFAULT_INIT_VALUE), - pcalVarDecl("netwWrite2", false, false, PLUSCAL_DEFAULT_INIT_VALUE), - pcalVarDecl("netwWrite3", false, false, PLUSCAL_DEFAULT_INIT_VALUE), - pcalVarDecl("netwRead2", false, false, PLUSCAL_DEFAULT_INIT_VALUE), - pcalVarDecl("netwWrite4", false, false, PLUSCAL_DEFAULT_INIT_VALUE)), - Collections.emptyList(), - Collections.emptyList(), - Collections.emptyList(), - process( - pcalVarDecl("S", false, false, num(42)), - PlusCalFairness.WEAK_FAIR, - Arrays.asList( - pcalVarDecl("a", false, false, PLUSCAL_DEFAULT_INIT_VALUE), - pcalVarDecl("b", false, false, PLUSCAL_DEFAULT_INIT_VALUE), - pcalVarDecl("dest", false, false, PLUSCAL_DEFAULT_INIT_VALUE)), - labeled( - label("l1"), - either(Arrays.asList( - Arrays.asList( - `with`( - Collections.singletonList(pcalVarDecl("msg0", false, false, opcall("Head", fncall(idexp("network"), num(0))))), - assign(idexp("netwWrite"), fnSubst(idexp("network"), fnSubstPair(Collections.singletonList(substKey(num(0))), opcall("Tail", fncall(idexp("network"), num(0)))))), - assign(idexp("netwRead"), idexp("msg0"))), - assign(idexp("a"), idexp("netwRead")), - assign(idexp("dest"), num(0)), - assign(idexp("netwWrite0"), idexp("netwWrite"))), - Arrays.asList( - `with`( - Collections.singletonList(pcalVarDecl("msg1", false, false, opcall("Head", fncall(idexp("network"), num(1))))), - assign(idexp("netwWrite"), fnSubst(idexp("network"), fnSubstPair(Collections.singletonList(substKey(num(1))), opcall("Tail", fncall(idexp("network"), num(1)))))), - assign(idexp("netwRead0"), idexp("msg1"))), - assign(idexp("a"), idexp("netwRead0")), - assign(idexp("dest"), num(1)), - assign(idexp("netwWrite0"), idexp("netwWrite"))))), - `with`( - Collections.singletonList(pcalVarDecl("msg2", false, false, opcall("Head", fncall(idexp("netwWrite0"), idexp("dest"))))), - assign(idexp("netwWrite1"), fnSubst(idexp("netwWrite0"), fnSubstPair(Collections.singletonList(substKey(idexp("dest"))), opcall("Tail", fncall(idexp("netwWrite0"), idexp("dest")))))), - assign(idexp("netwRead1"), idexp("msg2"))), - assign(idexp("b"), idexp("netwRead1")), - assign(idexp("netwWrite2"), fnSubst(idexp("netwWrite1"), fnSubstPair(Collections.singletonList(substKey(idexp("dest"))), opcall("Append", fncall(idexp("netwWrite1"), idexp("dest")), binop("+", idexp("a"), idexp("b")))))), - assign(idexp("network"), idexp("netwWrite2")))), - process( - pcalVarDecl("C", false, true, set(num(0), num(1))), - PlusCalFairness.WEAK_FAIR, - Collections.emptyList(), - labeled( - label("l1"), - assign(idexp("netwWrite3"), fnSubst(idexp("network"), fnSubstPair(Collections.singletonList(substKey(idexp("self"))), opcall("Append", fncall(idexp("network"), idexp("self")), num(21))))), - assign(idexp("network"), idexp("netwWrite3"))), - labeled( - label("l2"), - assign(idexp("netwWrite3"), fnSubst(idexp("network"), fnSubstPair(Collections.singletonList(substKey(idexp("self"))), opcall("Append", fncall(idexp("network"), idexp("self")), num(21))))), - `with`( - Collections.singletonList(pcalVarDecl("msg3", false, false, opcall("Head", fncall(idexp("netwWrite3"), idexp("self"))))), - assign(idexp("netwWrite4"), fnSubst(idexp("netwWrite3"), fnSubstPair(Collections.singletonList(substKey(idexp("self"))), opcall("Tail", fncall(idexp("netwWrite3"), idexp("self")))))), - assign(idexp("netwRead2"), idexp("msg3"))), - printS(idexp("netwRead2")), - assign(idexp("network"), idexp("netwWrite4"))))) - } - - check("algorithm8") { - """ - |----MODULE Algorithm8 ---- - |EXTENDS TLC, Sequences, FiniteSets, Integers - |(* - |--mpcal Algorithm8 { - | mapping macro Identity { - | read { yield $variable; } - | write { yield $value; } - | } - | - | archetype Arch(ref mailboxes, ref other) { - | l: other := mailboxes[self]; - | } - | - | variables network = <<>>, - | processor = 0; - | - | fair process (SomeProcess = 3) == instance Arch(ref network, ref processor) - | mapping network[_] via Identity; - |} - |*) - |\* BEGIN TRANSLATION - |==== - |""".stripMargin -> - // --algorithm Algorithm8 { - // variables network = <<>>, processor = 0, mailboxesRead, otherWrite; - // fair process (SomeProcess = 3) { - // l: mailboxesRead := network[self]; - // otherWrite := mailboxesRead[self]; - // processor := otherWrite; - // } - algorithm( - "Algorithm8", - Arrays.asList( - pcalVarDecl("network", false, false, tuple()), - pcalVarDecl("processor", false, false, num(0)), - pcalVarDecl("mailboxesRead", false, false, PLUSCAL_DEFAULT_INIT_VALUE), - pcalVarDecl("otherWrite", false, false, PLUSCAL_DEFAULT_INIT_VALUE)), - Collections.emptyList(), - Collections.emptyList(), - Collections.emptyList(), - process( - pcalVarDecl("SomeProcess", false, false, num(3)), - PlusCalFairness.WEAK_FAIR, - Collections.emptyList(), - labeled( - label("l"), - assign(idexp("mailboxesRead"), fncall(idexp("network"), idexp("self"))), - assign(idexp("otherWrite"), idexp("mailboxesRead")), - assign(idexp("processor"), idexp("otherWrite"))))) - } - - check("algorithm9") { - """ - |----MODULE Algorithm9 ---- - |EXTENDS TLC, Sequences, FiniteSets, Integers - |(* - |--mpcal Algorithm9 { - | archetype A(ref a, b) { - | l1: if (b) { - | l2: a := 1; - | l3: a := 2; - | } else { - | a := 3; - | } - | } - | - | variables i = 0, flag = TRUE; - | - | process (P = 3) == instance A(ref i, flag); - |} - |*) - |\* BEGIN TRANSLATION - |==== - |""".stripMargin -> - // --algorithm Algorithm9 { - // variables i = 0, flag = TRUE, bRead, aWrite, aWrite0; - // process (P = 3) { - // l1: - // bRead := flag; - // if (bRead) { - // l2: - // aWrite := 1; - // i := aWrite; - // - // l3: - // aWrite := 2; - // i := aWrite; - // - // } else { - // aWrite := 3; - // aWrite0 := aWrite; - // i := aWrite0; - // } - // - // } - // } - algorithm( - "Algorithm9", - Arrays.asList( - pcalVarDecl("i", false, false, num(0)), - pcalVarDecl("flag", false, false, bool(true)), - pcalVarDecl("bRead", false, false, PLUSCAL_DEFAULT_INIT_VALUE), - pcalVarDecl("aWrite", false, false, PLUSCAL_DEFAULT_INIT_VALUE), - pcalVarDecl("aWrite0", false, false, PLUSCAL_DEFAULT_INIT_VALUE)), - Collections.emptyList(), - Collections.emptyList(), - Collections.emptyList(), - process( - pcalVarDecl("P", false, false, num(3)), - PlusCalFairness.UNFAIR, - Collections.emptyList(), - labeled( - label("l1"), - assign(idexp("bRead"), idexp("flag")), - ifS( - idexp("bRead"), - Arrays.asList( - labeled( - label("l2"), - assign(idexp("aWrite"), num(1)), - assign(idexp("i"), idexp("aWrite"))), - labeled( - label("l3"), - assign(idexp("aWrite"), num(2)), - assign(idexp("i"), idexp("aWrite")))), - Arrays.asList( - assign(idexp("aWrite"), num(3)), - assign(idexp("aWrite0"), idexp("aWrite")), - assign(idexp("i"), idexp("aWrite0"))))))) - } - - check("algorithm10") { - """ - |----MODULE Algorithm10 ---- - |EXTENDS TLC, Sequences, FiniteSets, Integers - |(* - |--mpcal WhileLoopWithFollowingStatement { - | archetype Valid(ref aBool) { - | l: - | while (aBool) { - | either { skip } - | or { - | l1: - | while (aBool) { - | skip; - | }; - | aBool := FALSE; - | } - | }; - | print "ok"; - | } - | - | variable b = TRUE; - | fair process (P = 10) == instance Valid(b); - |} - |*) - |\* BEGIN TRANSLATION - |==== - |""".stripMargin -> - // --algorithm WhileLoopWithFollowingStatement { - // variables b = TRUE, aBoolRead, aBoolRead0, aBoolWrite, aBoolWrite0, aBoolWrite1, aBoolWrite2; - // process (P = 10) { - // l: - // aBoolRead := b; - // if (aBoolRead) { - // either { - // aBoolWrite1 := b; - // aBoolWrite2 := aBoolWrite1; - // b := aBoolWrite2; - // goto l; - // } or { - // l1: - // aBoolRead0 := b; - // if (aBoolRead0) { - // aBoolWrite0 := b; - // b := aBoolWrite0; - // goto l1; - // } else { - // aBoolWrite := FALSE; - // aBoolWrite0 := aBoolWrite; - // b := aBoolWrite0; - // goto l; - // } - // - // } - // } else { - // print "ok"; - // aBoolWrite2 := b; - // b := aBoolWrite2; - // } - // - // } - // } - algorithm( - "WhileLoopWithFollowingStatement", - Arrays.asList( - pcalVarDecl("b", false, false, bool(true)), - pcalVarDecl("aBoolRead", false, false, PLUSCAL_DEFAULT_INIT_VALUE), - pcalVarDecl("aBoolWrite", false, false, PLUSCAL_DEFAULT_INIT_VALUE), - pcalVarDecl("aBoolWrite0", false, false, PLUSCAL_DEFAULT_INIT_VALUE), - pcalVarDecl("aBoolWrite1", false, false, PLUSCAL_DEFAULT_INIT_VALUE), - pcalVarDecl("aBoolWrite2", false, false, PLUSCAL_DEFAULT_INIT_VALUE)), - Collections.emptyList(), - Collections.emptyList(), - Collections.emptyList(), - process( - pcalVarDecl("P", false, false, num(10)), - PlusCalFairness.WEAK_FAIR, - Collections.emptyList(), - labeled( - label("l"), - assign(idexp("aBoolRead"), idexp("b")), - ifS( - idexp("aBoolRead"), - Collections.singletonList( - either(Arrays.asList( - Arrays.asList( - assign(idexp("aBoolWrite1"), idexp("b")), - assign(idexp("aBoolWrite2"), idexp("aBoolWrite1")), - assign(idexp("b"), idexp("aBoolWrite2")), - gotoS("l")), - Collections.singletonList( - labeled( - label("l1"), - assign(idexp("aBoolRead"), idexp("b")), - ifS( - idexp("aBoolRead"), - Arrays.asList( - assign(idexp("aBoolWrite0"), idexp("b")), - assign(idexp("b"), idexp("aBoolWrite0")), - gotoS("l1")), - Arrays.asList( - assign(idexp("aBoolWrite"), bool(false)), - assign(idexp("aBoolWrite0"), idexp("aBoolWrite")), - assign(idexp("b"), idexp("aBoolWrite0")), - gotoS("l")))))))), - Arrays.asList( - printS(str("ok")), - assign(idexp("aBoolWrite2"), idexp("b")), - assign(idexp("b"), idexp("aBoolWrite2"))))))) - } - - check("algorithm11") { - """ - |----MODULE Algorithm11 ---- - |EXTENDS TLC, Sequences, FiniteSets, Integers - |(* - |--mpcal Algorithm11 { - | procedure P(ref a1, a2) { - | l3: - | while (a1 < 10 /\ a2) { - | a1 := 1; - | } - | } - | - | mapping macro Adder { - | read { - | yield $variable; - | } - | write { - | yield $variable + $value; - | } - | } - | - | archetype A(ref a, b) { - | l1: - | a := 1; - | call P(ref a, b); - | l2: - | call P(ref a, b); - | } - | - | variables i = 0, flag = TRUE; - | - | fair process (Proc = 0) == instance A(ref i, flag) - | mapping i via Adder; - |} - |*) - |\* BEGIN TRANSLATION - |==== - |""".stripMargin -> - // --algorithm Algorithm11 { - // variables i = 0, flag = TRUE, aWrite; - // procedure P0 () - // variables local, a1Read, a2Read, a1Write, a1Write0; - // { - // l3: - // a1Read := i; - // a2Read := flag; - // if (a1Read < 10 /\ a2Read) { - // a1Write := i + 1; - // a1Write0 := a1Write; - // i := a1Write0; - // goto l2; - // } else { - // a1Write0 := i; - // i := a1Write0; - // } - // - // } - // fair process (Proc = 0) { - // l1: - // aWrite := i + 1; - // i := aWrite; - // call P0(); - // l2: - // call P0(); - // - // } - // } - algorithm( - "Algorithm11", - Arrays.asList( - pcalVarDecl("i", false, false, num(0)), - pcalVarDecl("flag", false, false, bool(true)), - pcalVarDecl("aWrite", false, false, PLUSCAL_DEFAULT_INIT_VALUE)), - Collections.emptyList(), - Collections.singletonList( - procedure( - "P0", - Collections.emptyList(), - Arrays.asList( - pcalVarDecl("a1Read", false, false, PLUSCAL_DEFAULT_INIT_VALUE), - pcalVarDecl("a2Read", false, false, PLUSCAL_DEFAULT_INIT_VALUE), - pcalVarDecl("a1Write", false, false, PLUSCAL_DEFAULT_INIT_VALUE), - pcalVarDecl("a1Write0", false, false, PLUSCAL_DEFAULT_INIT_VALUE)), - labeled( - label("l3"), - assign(idexp("a1Read"), idexp("i")), - assign(idexp("a2Read"), idexp("flag")), - ifS( - binop("/\\", binop("<", idexp("a1Read"), num(10)), idexp("a2Read")), - Arrays.asList( - assign(idexp("a1Write"), binop("+", idexp("i"), num(1))), - assign(idexp("a1Write0"), idexp("a1Write")), - assign(idexp("i"), idexp("a1Write0")), - gotoS("l3")), - Arrays.asList( - assign(idexp("a1Write0"), idexp("i")), - assign(idexp("i"), idexp("a1Write0"))))))), - Collections.emptyList(), - process( - pcalVarDecl("Proc", false, false, num(0)), - PlusCalFairness.WEAK_FAIR, - Collections.emptyList(), - labeled( - label("l1"), - assign(idexp("aWrite"), binop("+", idexp("i"), num(1))), - assign(idexp("i"), idexp("aWrite")), - call("P0")), - labeled( - label("l2"), - call("P0")))) - } - - check("algorithm12") { - """ - |----MODULE Algorithm12 ---- - |EXTENDS TLC, Sequences, FiniteSets, Integers - |(* - |--mpcal Algorithm12 { - | archetype A(a) - | variable local = 0; - | { - | l1: - | local := a + 1; - | print <>; - | } - | - | variables i = 0; - | - | fair process (Proc = 0) == instance A(i * 2 + 1); - |} - |*) - |\* BEGIN TRANSLATION - |==== - |""".stripMargin -> - // --algorithm Algorithm12 { - // variables i = 0, aRead, aRead0; - // fair process (Proc = 0) - // variables aLocal = i * 2 + 1, local = 0; - // { - // l1: - // aRead := aLocal; - // local := aRead + 1; - // aRead0 := aLocal; - // print <>; - // } - // } - algorithm( - "Algorithm12", - Arrays.asList( - pcalVarDecl("i", false, false, num(0)), - pcalVarDecl("aRead", false, false, PLUSCAL_DEFAULT_INIT_VALUE), - pcalVarDecl("aRead0", false, false, PLUSCAL_DEFAULT_INIT_VALUE)), - Collections.emptyList(), - Collections.emptyList(), - Collections.emptyList(), - process( - pcalVarDecl("Proc", false, false, num(0)), - PlusCalFairness.WEAK_FAIR, - Arrays.asList( - pcalVarDecl("aLocal", false, false, binop("+", binop("*", idexp("i"), num(2)), num(1))), - pcalVarDecl("local", false, false, num(0))), - labeled( - label("l1"), - assign(idexp("aRead"), idexp("aLocal")), - assign(idexp("local"), binop("+", idexp("aRead"), num(1))), - assign(idexp("aRead0"), idexp("aLocal")), - printS(tuple(idexp("aRead0"), idexp("local")))))) - } - - check("algorithm13") { - """ - |----MODULE Algorithm13 ---- - |EXTENDS TLC, Sequences, FiniteSets, Integers - |(* - |--mpcal Algorithm13 { - | archetype A(ref a) { - | l1: - | a := a + 1; - | print a; - | } - | - | variables i = 0; - | - | fair process (Proc = 0) == instance A(ref i); - |} - |*) - |\* BEGIN TRANSLATION - |==== - |""".stripMargin -> - // --algorithm Algorithm13 { - // variables i = 0, aRead, aWrite, aRead0; - // fair process (Proc = 0) { - // l1: - // aRead := i; - // aWrite := aRead + 1; - // aRead0 := aWrite; - // print aRead0; - // i := aWrite; - // } - // } - algorithm( - "Algorithm13", - Arrays.asList( - pcalVarDecl("i", false, false, num(0)), - pcalVarDecl("aRead", false, false, PLUSCAL_DEFAULT_INIT_VALUE), - pcalVarDecl("aWrite", false, false, PLUSCAL_DEFAULT_INIT_VALUE), - pcalVarDecl("aRead0", false, false, PLUSCAL_DEFAULT_INIT_VALUE)), - Collections.emptyList(), - Collections.emptyList(), - Collections.emptyList(), - process( - pcalVarDecl("Proc", false, false, num(0)), - PlusCalFairness.WEAK_FAIR, - Collections.emptyList(), - labeled( - label("l1"), - assign(idexp("aRead"), idexp("i")), - assign(idexp("aWrite"), binop("+", idexp("aRead"), num(1))), - assign(idexp("aRead0"), idexp("aWrite")), - printS(idexp("aRead0")), - assign(idexp("i"), idexp("aWrite"))))) - } - - check("algorithm14") { - """ - |----MODULE Algorithm14 ---- - |EXTENDS TLC, Sequences, FiniteSets, Integers - |(* - |--mpcal Algorithm14 { - | archetype A(a, b) - | variable local = 0; - | { - | l1: - | local := a + 1; - | if (b) { - | print <>; - | } else { - | print <>; - | l2: - | print a + 2; - | }; - | } - | - | variables i = 0, flag = TRUE; - | - | fair process (Proc = 0) == instance A(i * 2 + 1, flag); - |} - |*) - |\* BEGIN TRANSLATION - |==== - |""".stripMargin -> - // --algorithm Algorithm14 { - // variables i = 0, flag = TRUE, aRead, bRead, aRead0, aRead1; - // fair process (Proc = 0) - // variables aLocal = i * 2 + 1, local = 0; - // { - // l1: - // aRead := aLocal; - // local := aRead + 1; - // bRead := flag; - // if (bRead) { - // aRead0 := aLocal; - // print <>; - // } else { - // aRead1 := aLocal; - // print <>; - // l2: - // aRead := aLocal; - // print aRead + 2; - // }; - // } - // } - algorithm( - "Algorithm14", - Arrays.asList( - pcalVarDecl("i", false, false, num(0)), - pcalVarDecl("flag", false, false, bool(true)), - pcalVarDecl("aRead", false, false, PLUSCAL_DEFAULT_INIT_VALUE), - pcalVarDecl("bRead", false, false, PLUSCAL_DEFAULT_INIT_VALUE), - pcalVarDecl("aRead0", false, false, PLUSCAL_DEFAULT_INIT_VALUE), - pcalVarDecl("aRead1", false, false, PLUSCAL_DEFAULT_INIT_VALUE) - ), - Collections.emptyList(), - Collections.emptyList(), - Collections.emptyList(), - process( - pcalVarDecl("Proc", false, false, num(0)), - PlusCalFairness.WEAK_FAIR, - Arrays.asList( - pcalVarDecl("aLocal", false, false, binop("+", binop("*", idexp("i"), num(2)), num(1))), - pcalVarDecl("local", false, false, num(0))), - labeled( - label("l1"), - assign(idexp("aRead"), idexp("aLocal")), - assign(idexp("local"), binop("+", idexp("aRead"), num(1))), - assign(idexp("bRead"), idexp("flag")), - ifS( - idexp("bRead"), - Arrays.asList( - assign(idexp("aRead0"), idexp("aLocal")), - printS(tuple(idexp("aRead0"), idexp("local")))), - Arrays.asList( - assign(idexp("aRead1"), idexp("aLocal")), - printS(tuple(idexp("local"), binop("+", idexp("aRead1"), num(1)))), - labeled( - label("l2"), - assign(idexp("aRead"), idexp("aLocal")), - printS(binop("+", idexp("aRead"), num(2))))))))) - } - - check("algorithm15") { - """ - |----MODULE Algorithm15 ---- - |EXTENDS TLC, Sequences, FiniteSets, Integers - |(* - |--mpcal Algorithm15 { - | archetype A(ref a) - | variables local1 = 0, local2 = local1 + 1; - | { - | l1: - | a := a + 1; - | print <>; - | } - | - | variables i = 0; - | - | fair process (Proc = 0) == instance A(ref i); - |} - |*) - |\* BEGIN TRANSLATION - |==== - |""".stripMargin -> - // --algorithm Algorithm15 { - // variables i = 0, aRead, aWrite, aRead0; - // fair process (Proc = 0) - // variables local1 = 0, local2 = local1 + 1; - // { - // l1: - // aRead := i; - // aWrite := aRead + 1; - // aRead0 := aWrite; - // print <>; - // i := aWrite; - // } - // } - algorithm( - "Algorithm15", - Arrays.asList( - pcalVarDecl("i", false, false, num(0)), - pcalVarDecl("aRead", false, false, PLUSCAL_DEFAULT_INIT_VALUE), - pcalVarDecl("aWrite", false, false, PLUSCAL_DEFAULT_INIT_VALUE), - pcalVarDecl("aRead0", false, false, PLUSCAL_DEFAULT_INIT_VALUE)), - Collections.emptyList(), - Collections.emptyList(), - Collections.emptyList(), - process( - pcalVarDecl("Proc", false, false, num(0)), - PlusCalFairness.WEAK_FAIR, - Arrays.asList( - pcalVarDecl("local1", false, false, num(0)), - pcalVarDecl("local2", false, false, binop("+", idexp("local1"), num(1)))), - labeled( - label("l1"), - assign(idexp("aRead"), idexp("i")), - assign(idexp("aWrite"), binop("+", idexp("aRead"), num(1))), - assign(idexp("aRead0"), idexp("aWrite")), - printS(tuple(idexp("aRead0"), idexp("local1"), idexp("local2"))), - assign(idexp("i"), idexp("aWrite"))))) - } - - check("algorithm16") { - """ - |----MODULE Algorithm16 ---- - |EXTENDS TLC, Sequences, FiniteSets, Integers - |(* - |--mpcal Algorithm16 { - | archetype A(ref a) - | variables local1 = a, local2 = local1 + 1; - | { - | l1: - | a := a + 1; - | print <>; - | } - | - | variables i = 0; - | - | fair process (Proc = 0) == instance A(ref i); - |} - |*) - |\* BEGIN TRANSLATION - |==== - |""".stripMargin -> - // --algorithm Algorithm16 { - // variables i = 0, aRead, aWrite, aRead0; - // fair process (Proc = 0) - // variables local1, local2; - // { - // init: - // aRead := i; - // local1 := aRead; - // local2 := local1 + 1; - // l1: - // aRead := i; - // aWrite := aRead + 1; - // aRead0 := aWrite; - // print <>; - // i := aWrite; - // } - // } - algorithm( - "Algorithm16", - Arrays.asList( - pcalVarDecl("i", false, false, num(0)), - pcalVarDecl("aRead", false, false, PLUSCAL_DEFAULT_INIT_VALUE), - pcalVarDecl("aWrite", false, false, PLUSCAL_DEFAULT_INIT_VALUE), - pcalVarDecl("aRead0", false, false, PLUSCAL_DEFAULT_INIT_VALUE)), - Collections.emptyList(), - Collections.emptyList(), - Collections.emptyList(), - process( - pcalVarDecl("Proc", false, false, num(0)), - PlusCalFairness.WEAK_FAIR, - Arrays.asList( - pcalVarDecl("local1", false, false, PLUSCAL_DEFAULT_INIT_VALUE), - pcalVarDecl("local2", false, false, PLUSCAL_DEFAULT_INIT_VALUE) - ), - labeled( - label("init"), - assign(idexp("aRead"), idexp("i")), - assign(idexp("local1"), idexp("aRead")), - assign(idexp("local2"), binop("+", idexp("local1"), num(1))) - ), - labeled( - label("l1"), - assign(idexp("aRead"), idexp("i")), - assign(idexp("aWrite"), binop("+", idexp("aRead"), num(1))), - assign(idexp("aRead0"), idexp("aWrite")), - printS(tuple(idexp("aRead0"), idexp("local1"), idexp("local2"))), - assign(idexp("i"), idexp("aWrite")) - ))) - } - - check("algorithm17") { - """ - |----MODULE Algorithm17 ---- - |EXTENDS TLC, Sequences, FiniteSets, Integers - |(* - |--mpcal Algorithm17 { - | archetype A() - | { - | l1: - | if (TRUE) { - | skip; - | }; - | } - | - | fair process (Proc = 0) == instance A(); - |} - |*) - |\* BEGIN TRANSLATION - |==== - |""".stripMargin -> - // --algorithm Algorithm17 { - // fair process (Proc = 0) { - // l1: - // if (TRUE) { - // skip; - // }; - // } - // } - algorithm( - "Algorithm17", - Collections.emptyList(), - Collections.emptyList(), - Collections.emptyList(), - Collections.emptyList(), - process( - pcalVarDecl("Proc", false, false, num(0)), - PlusCalFairness.WEAK_FAIR, - Collections.emptyList(), - labeled( - label("l1"), - ifS( - bool(true), - Collections.singletonList(skip()), - Collections.emptyList())))) - } - - check("algorithm18") { - """ - |----MODULE Algorithm18 ---- - |EXTENDS TLC, Sequences, FiniteSets, Integers - |(* - |--mpcal Algorithm18 { - | mapping macro Macro { - | read { - | yield $variable; - | } - | write { - | yield $variable + $value; - | } - | } - | archetype A(ref a) - | { - | l1: - | a := 1; - | print a; - | } - | - | fair process (Proc = 0) == instance A(0) - | mapping @1 via Macro; - |} - |*) - |\* BEGIN TRANSLATION - |==== - |""".stripMargin -> - // --algorithm Algorithm18 { - // variables aWrite, aRead; - // fair process (Proc = 0) - // variables aLocal = 0; - // { - // l1: - // aWrite := aLocal + 1; - // aRead := aWrite; - // print aRead; - // aLocal := aWrite; - // } - // } - algorithm( - "Algorithm18", - Arrays.asList( - pcalVarDecl("aWrite", false, false, PLUSCAL_DEFAULT_INIT_VALUE), - pcalVarDecl("aRead", false, false, PLUSCAL_DEFAULT_INIT_VALUE) - ), - Collections.emptyList(), - Collections.emptyList(), - Collections.emptyList(), - process( - pcalVarDecl("Proc", false, false, num(0)), - PlusCalFairness.WEAK_FAIR, - Collections.singletonList( - pcalVarDecl("aLocal", false, false, num(0)) - ), - labeled( - label("l1"), - assign(idexp("aWrite"), binop("+", idexp("aLocal"), num(1))), - assign(idexp("aRead"), idexp("aWrite")), - printS(idexp("aRead")), - assign(idexp("aLocal"), idexp("aWrite"))))) - } - - check("algorithm19") { - """ - |----MODULE Algorithm19 ---- - |EXTENDS TLC, Sequences, FiniteSets, Integers - |(* - |--mpcal Algorithm19 { - | mapping macro Macro { - | read { - | yield $variable; - | } - | write { - | yield $variable + $value; - | } - | } - | archetype A(ref a) - | { - | l1: - | a[1] := 1; - | print a[1]; - | } - | - | fair process (Proc = 0) == instance A(<<0>>) - | mapping @1[_] via Macro; - |} - |*) - |\* BEGIN TRANSLATION - |==== - |""".stripMargin -> - // --algorithm Algorithm19 { - // variables aWrite, aRead; - // fair process (Proc = 0) - // variables aLocal = <<0>>; - // { - // l1: - // aWrite := [aLocal EXCEPT ![1] = aLocal[1] + 1]; - // aRead := aWrite[1]; - // print aRead; - // aLocal := aWrite; - // } - // } - algorithm( - "Algorithm19", - Arrays.asList( - pcalVarDecl("aWrite", false, false, PLUSCAL_DEFAULT_INIT_VALUE), - pcalVarDecl("aRead", false, false, PLUSCAL_DEFAULT_INIT_VALUE) - ), - Collections.emptyList(), - Collections.emptyList(), - Collections.emptyList(), - process( - pcalVarDecl("Proc", false, false, num(0)), - PlusCalFairness.WEAK_FAIR, - Collections.singletonList( - pcalVarDecl("aLocal", false, false, tuple(num(0))) - ), - labeled( - label("l1"), - assign( - idexp("aWrite"), - fnSubst( - idexp("aLocal"), - fnSubstPair( - Collections.singletonList(key(num(1))), - binop("+", fncall(idexp("aLocal"), num(1)), num(1))))), - assign(idexp("aRead"), fncall(idexp("aWrite"), num(1))), - printS(idexp("aRead")), - assign(idexp("aLocal"), idexp("aWrite"))))) - } - -} diff --git a/test/pgo/TestCodeGenRunTest.scala b/test/pgo/TestCodeGenRunTest.scala deleted file mode 100644 index 80e2b6448..000000000 --- a/test/pgo/TestCodeGenRunTest.scala +++ /dev/null @@ -1,115 +0,0 @@ -package pgo - -import org.scalactic.source.Position -import org.scalatest.funsuite.AnyFunSuite -import pgo.IntegrationTestingUtils.{testCompileFile, testRunGoCode} - -import java.nio.file.Paths -import scala.jdk.CollectionConverters._ - -class TestCodeGenRunTest extends AnyFunSuite { - def check(tag: String)(fileName: String, constants: Map[String,String] = Map.empty, expectedStr: String)(implicit pos: Position): Unit = - test(tag) { - testCompileFile( - Paths.get("test", "integration", fileName), - constants.asJava, compiledFilePath => - testRunGoCode(compiledFilePath, expectedStr.linesIterator.toList.asJava)) - } - - check("SimpleEither.tla")( - fileName = "SimpleEither.tla", - expectedStr = - """[1 30] - |[1 30] - |[1 30] - |""".stripMargin) - - check("EitherBothBranches.tla")( - fileName = "EitherBothBranches.tla", - expectedStr = - """[10 20] - |[10 20] - |""".stripMargin) - - check("EitherRepeatedExec.tla")( - fileName = "EitherRepeatedExec.tla", - expectedStr = "3") - - check("Procedures.tla")( - fileName = "Procedures.tla", - constants = Map("N" -> "20", "defaultInitValue" -> "0"), - expectedStr = - """1 - |2 - |fizz - |4 - |buzz - |fizz - |7 - |8 - |fizz - |buzz - |11 - |fizz - |13 - |14 - |fizzbuzz - |16 - |17 - |fizz - |19 - |buzz - |""".stripMargin) - - check("ProceduresPSyntax.tla")( - fileName = "ProceduresPSyntax.tla", - constants = Map("N" -> "20", "defaultInitValue" -> "0"), - expectedStr = - """1 - |2 - |fizz - |4 - |buzz - |fizz - |7 - |8 - |fizz - |buzz - |11 - |fizz - |13 - |14 - |fizzbuzz - |16 - |17 - |fizz - |19 - |buzz - |""".stripMargin) - - check("SingleProcess.tla")( - fileName = "SingleProcess.tla", - constants = Map("N" -> "20", "defaultInitValue" -> "0"), - expectedStr = - """1 - |2 - |fizz - |4 - |buzz - |fizz - |7 - |8 - |fizz - |buzz - |11 - |fizz - |13 - |14 - |fizzbuzz - |16 - |17 - |fizz - |19 - |buzz - |""".stripMargin) -} diff --git a/test/pgo/TestingUtils.scala b/test/pgo/TestingUtils.scala deleted file mode 100644 index 6d5a8d522..000000000 --- a/test/pgo/TestingUtils.scala +++ /dev/null @@ -1,48 +0,0 @@ -package pgo - -import com.github.difflib.{DiffUtils, UnifiedDiffUtils} -import pgo.model.mpcal.ModularPlusCalBlock -import pgo.model.tla.TLAModule -import pgo.parser.{ModularPlusCalParser, TLAParser} - -import java.nio.file.{Files, Path} -import scala.jdk.CollectionConverters._ - -object TestingUtils { - - def stringDiff(expected: String, actual: String): List[String] = { - val expectedLines = expected.linesIterator.toBuffer - val actualLines = actual.linesIterator.toBuffer - val patch = DiffUtils.diff(expectedLines.asJava, actualLines.asJava) - - UnifiedDiffUtils.generateUnifiedDiff("expected", "actual", expectedLines.asJava, patch, 3) - .asScala.toList - } - - def parseMPCalFromString(specStr: String): (Path,TLAModule,ModularPlusCalBlock) = { - val temp = Files.createTempFile("mpcal-reparse", "") - temp.toFile.deleteOnExit() - Files.writeString(temp, specStr) - val tlaModule = TLAParser.readModuleBeforeTranslation(temp, specStr) - (temp, tlaModule, ModularPlusCalParser.readBlock(temp, specStr, tlaModule)) - } - - def reparseMPCal(mpcal: ModularPlusCalBlock): (Path,ModularPlusCalBlock) = { - val mpcalStr = - s""" - |---- MODULE Before ---- - |EXTENDS Sequences, FiniteSets, Integers - |(* - |${mpcal.toString} - |*) - |${"\\"}* BEGIN TRANSLATION - |==== - |""".stripMargin - - val temp = Files.createTempFile("mpcal-reparse", "") - temp.toFile.deleteOnExit() - Files.writeString(temp, mpcalStr) - val tlaModule = TLAParser.readModuleBeforeTranslation(temp, mpcalStr) - (temp, ModularPlusCalParser.readBlock(temp, mpcalStr, tlaModule)) - } -} diff --git a/test/pgo/formatters/TLANodePrintEquivalenceTest.scala b/test/pgo/formatters/TLANodePrintEquivalenceTest.scala deleted file mode 100644 index fb325fb7c..000000000 --- a/test/pgo/formatters/TLANodePrintEquivalenceTest.scala +++ /dev/null @@ -1,37 +0,0 @@ -package pgo.formatters - -import org.scalactic.source.Position -import org.scalatest.funsuite.AnyFunSuite -import pgo.model.tla.TLABuilder._ -import pgo.model.tla.TLAModule -import pgo.parser.TLAParser - -import java.nio.file.{Path, Paths} -import java.util -import java.util.{Arrays, Collections} - -class TLANodePrintEquivalenceTest extends AnyFunSuite { - - def check(tag: String)(tlaModule: TLAModule)(implicit pos: Position): Unit = - test(tag) { - val str = tlaModule.toString - val testPath = Paths.get("TEST") - val actual = TLAParser.readModule(testPath, str) - assert(actual == tlaModule) - } - - check("extends but no operators") { - module("TEST", ids(id("Naturals"), id("TLC")), Collections.emptyList) - } - check("empty module") { - module("TEST", ids(), Collections.emptyList) - } - check("one operator") { - module( - "TEST", - ids(id("Sequences")), - util.Arrays.asList( - opdef(false, id("foo"), opdecls(opdecl(id("a")), opdecl(id("b"))), num(1)))) - } - -} diff --git a/test/pgo/model/type/TypeSolverTest.scala b/test/pgo/model/type/TypeSolverTest.scala deleted file mode 100644 index c65802475..000000000 --- a/test/pgo/model/type/TypeSolverTest.scala +++ /dev/null @@ -1,205 +0,0 @@ -package pgo.model.`type` - -import pgo.errors.TopLevelIssueContext -import pgo.scope.UID - -import java.util -import java.util.Collections -import org.scalatest.funsuite.AnyFunSuite -import pgo.model.`type`.constraint.MonomorphicConstraint - -class TypeSolverTest extends AnyFunSuite{ - trait TSFixture { - val solver = new TypeSolver() - val typeGenerator = new TypeGenerator("a") - val ctx = new TopLevelIssueContext() - val dummyUID = new UID() - } - - test("simpleTypeVariables")(new TSFixture { - val a = typeGenerator.getTypeVariable(Collections.emptyList) - val b = typeGenerator.getTypeVariable(Collections.emptyList) - solver.addConstraint(new MonomorphicConstraint(dummyUID, a, b)) - solver.unify(ctx) - assert(!ctx.hasErrors) - val substitution = solver.getSubstitution - assert(substitution.get(a) == substitution.get(b)) - }) - - test("simpleTuple")(new TSFixture { - val a = typeGenerator.getTypeVariable(Collections.emptyList) - val b = typeGenerator.getTypeVariable(Collections.emptyList) - val c = typeGenerator.getTypeVariable(Collections.emptyList) - solver.addConstraint(new MonomorphicConstraint(dummyUID, new TupleType(util.Arrays.asList(a, b), Collections.emptyList), c)) - solver.unify(ctx) - assert(!ctx.hasErrors) - val substitution = solver.getSubstitution - assert(new TupleType(util.Arrays.asList(a, b), Collections.emptyList) == substitution.get(c)) - }) - - test("boolSlice")(new TSFixture { - val a = typeGenerator.getTypeVariable(Collections.emptyList) - val b = typeGenerator.getTypeVariable(Collections.emptyList) - solver.addConstraint(new MonomorphicConstraint(dummyUID, a, new BoolType(Collections.emptyList))) - solver.addConstraint(new MonomorphicConstraint(dummyUID, b, new SliceType(a, Collections.emptyList))) - solver.unify(ctx) - assert(!ctx.hasErrors) - val substitution = solver.getSubstitution - assert(new BoolType(Collections.emptyList) == substitution.get(a)) - assert(new SliceType(new BoolType(Collections.emptyList), Collections.emptyList) == substitution.get(b)) - }) - - test("mapStringInterface")(new TSFixture { - val a = typeGenerator.getTypeVariable(Collections.emptyList) - val b = typeGenerator.getTypeVariable(Collections.emptyList) - solver.addConstraint(new MonomorphicConstraint(dummyUID, new MapType(new StringType(Collections.emptyList), new StringType(Collections.emptyList), Collections.emptyList), new MapType(a, b, Collections.emptyList))) - solver.unify(ctx) - assert(!ctx.hasErrors) - val substitution = solver.getSubstitution - assert(new StringType(Collections.emptyList) == substitution.get(a)) - assert(new StringType(Collections.emptyList) == substitution.get(b)) - }) - - test("chainedFunctions")(new TSFixture { - val a = typeGenerator.getTypeVariable(Collections.emptyList) - val b = typeGenerator.getTypeVariable(Collections.emptyList) - val c = typeGenerator.getTypeVariable(Collections.emptyList) - val d = typeGenerator.getTypeVariable(Collections.emptyList) - val e = typeGenerator.getTypeVariable(Collections.emptyList) - solver.addConstraint(new MonomorphicConstraint(dummyUID, new FunctionType(Collections.singletonList(a), b, Collections.emptyList), new FunctionType(Collections.singletonList(b), c, Collections.emptyList))) - solver.addConstraint(new MonomorphicConstraint(dummyUID, c, new FunctionType(Collections.singletonList(d), e, Collections.emptyList))) - solver.unify(ctx) - assert(!ctx.hasErrors) - val substitution = solver.getSubstitution - assert(new FunctionType(Collections.singletonList(d), e, Collections.emptyList) == substitution.get(a)) - assert(new FunctionType(Collections.singletonList(d), e, Collections.emptyList) == substitution.get(b)) - assert(new FunctionType(Collections.singletonList(d), e, Collections.emptyList) == substitution.get(c)) - }) - - test("notUnifiable")(new TSFixture { - val a = typeGenerator.getTypeVariable(Collections.emptyList) - solver.addConstraint(new MonomorphicConstraint(dummyUID, new BoolType(Collections.emptyList), new MapType(new BoolType(Collections.emptyList), a, Collections.emptyList))) - solver.unify(ctx) - assert(ctx.hasErrors) - }) - - test("infiniteType")(new TSFixture { - val a = typeGenerator.getTypeVariable(Collections.emptyList) - solver.addConstraint(new MonomorphicConstraint(dummyUID, a, new MapType(new IntType(Collections.emptyList), a, Collections.emptyList))) - solver.unify(ctx) - assert(ctx.hasErrors) - }) - - test("circularConstraints")(new TSFixture { - val a = typeGenerator.getTypeVariable(Collections.emptyList) - val b = typeGenerator.getTypeVariable(Collections.emptyList) - solver.addConstraint(new MonomorphicConstraint(dummyUID, a, b)) - solver.addConstraint(new MonomorphicConstraint(dummyUID, b, a)) - solver.unify(ctx) - assert(!ctx.hasErrors) - val substitution = solver.getSubstitution - assert(substitution.get(a) == substitution.get(b)) - }) - - test("circularSets")(new TSFixture { - val a = typeGenerator.getTypeVariable(Collections.emptyList) - val b = typeGenerator.getTypeVariable(Collections.emptyList) - solver.addConstraint(new MonomorphicConstraint(dummyUID, a, new SetType(b, Collections.emptyList))) - solver.addConstraint(new MonomorphicConstraint(dummyUID, b, new SetType(a, Collections.emptyList))) - solver.unify(ctx) - assert(ctx.hasErrors) - }) - - test("mismatchedSimpleContainerTypes")(new TSFixture { - val a = typeGenerator.getTypeVariable(Collections.emptyList) - val b = typeGenerator.getTypeVariable(Collections.emptyList) - solver.addConstraint(new MonomorphicConstraint(dummyUID, new SliceType(a, Collections.emptyList), new ChanType(b, Collections.emptyList))) - solver.unify(ctx) - assert(ctx.hasErrors) - }) - - test("mismatchedNestedTypes")(new TSFixture { - val a = typeGenerator.getTypeVariable(Collections.emptyList) - val b = typeGenerator.getTypeVariable(Collections.emptyList) - solver.addConstraint(new MonomorphicConstraint(dummyUID, new SetType(new SliceType(a, Collections.emptyList), Collections.emptyList), new SetType(new ChanType(b, Collections.emptyList), Collections.emptyList))) - solver.unify(ctx) - assert(ctx.hasErrors) - }) - - test("abstractRecord")(new TSFixture { - val a = typeGenerator.getTypeVariable(Collections.emptyList) - val abstractRecord = typeGenerator.getAbstractRecord(Collections.emptyList) - solver.addConstraint(new MonomorphicConstraint(dummyUID, a, abstractRecord)) - solver.addConstraint(new MonomorphicConstraint(dummyUID, abstractRecord, "src", new StringType(Collections.emptyList))) - solver.addConstraint(new MonomorphicConstraint(dummyUID, abstractRecord, "ttl", new IntType(Collections.emptyList))) - solver.addConstraint(new MonomorphicConstraint(dummyUID, abstractRecord, "data", new StringType(Collections.emptyList))) - solver.unify(ctx) - assert(!ctx.hasErrors) - val substitution = solver.getSubstitution - assert(substitution.get(a) == new RecordType(util.Arrays.asList(new RecordType.Field("data", new StringType(Collections.emptyList)), new RecordType.Field("src", new StringType(Collections.emptyList)), new RecordType.Field("ttl", new IntType(Collections.emptyList))), Collections.emptyList)) - }) - - test("indirectAbstractRecord")(new TSFixture { - val a = typeGenerator.getTypeVariable(Collections.emptyList) - val b = typeGenerator.getTypeVariable(Collections.emptyList) - val c = typeGenerator.getTypeVariable(Collections.emptyList) - val ar1 = typeGenerator.getAbstractRecord(Collections.emptyList) - val ar2 = typeGenerator.getAbstractRecord(Collections.emptyList) - val ar3 = typeGenerator.getAbstractRecord(Collections.emptyList) - solver.addConstraint(new MonomorphicConstraint(dummyUID, a, ar1)) - solver.addConstraint(new MonomorphicConstraint(dummyUID, ar1, "src", new StringType(Collections.emptyList))) - solver.addConstraint(new MonomorphicConstraint(dummyUID, b, ar2)) - solver.addConstraint(new MonomorphicConstraint(dummyUID, ar2, "ttl", new IntType(Collections.emptyList))) - solver.addConstraint(new MonomorphicConstraint(dummyUID, c, ar3)) - solver.addConstraint(new MonomorphicConstraint(dummyUID, ar3, "data", new StringType(Collections.emptyList))) - solver.addConstraint(new MonomorphicConstraint(dummyUID, a, b)) - solver.addConstraint(new MonomorphicConstraint(dummyUID, c, b)) - solver.unify(ctx) - assert(!ctx.hasErrors) - val substitution = solver.getSubstitution - assert(substitution.get(a) == substitution.get(b)) - assert(substitution.get(c) == substitution.get(b)) - assert(substitution.get(a) == new RecordType(util.Arrays.asList(new RecordType.Field("data", new StringType(Collections.emptyList)), new RecordType.Field("src", new StringType(Collections.emptyList)), new RecordType.Field("ttl", new IntType(Collections.emptyList))), Collections.emptyList)) - }) - - test("concreteAndAbstractRecord")(new TSFixture { - val a = typeGenerator.getTypeVariable(Collections.emptyList) - val b = typeGenerator.getTypeVariable(Collections.emptyList) - val c = typeGenerator.getTypeVariable(Collections.emptyList) - val d = typeGenerator.getTypeVariable(Collections.emptyList) - val ar1 = typeGenerator.getAbstractRecord(Collections.emptyList) - val ar2 = typeGenerator.getAbstractRecord(Collections.emptyList) - val ar3 = typeGenerator.getAbstractRecord(Collections.emptyList) - solver.addConstraint(new MonomorphicConstraint(dummyUID, a, ar1)) - solver.addConstraint(new MonomorphicConstraint(dummyUID, ar1, "src", new StringType(Collections.emptyList))) - solver.addConstraint(new MonomorphicConstraint(dummyUID, b, ar2)) - solver.addConstraint(new MonomorphicConstraint(dummyUID, ar2, "ttl", new IntType(Collections.emptyList))) - solver.addConstraint(new MonomorphicConstraint(dummyUID, c, ar3)) - solver.addConstraint(new MonomorphicConstraint(dummyUID, ar3, "data", new StringType(Collections.emptyList))) - solver.addConstraint(new MonomorphicConstraint(dummyUID, a, b)) - solver.addConstraint(new MonomorphicConstraint(dummyUID, c, b)) - solver.addConstraint(new MonomorphicConstraint(dummyUID, d, new RecordType(util.Arrays.asList(new RecordType.Field("src", new StringType(Collections.emptyList)), new RecordType.Field("ttl", new IntType(Collections.emptyList)), new RecordType.Field("data", new StringType(Collections.emptyList))), Collections.emptyList))) - solver.addConstraint(new MonomorphicConstraint(dummyUID, a, d)) - solver.unify(ctx) - assert(!ctx.hasErrors) - val substitution = solver.getSubstitution - assert(substitution.get(a) == substitution.get(b)) - assert(substitution.get(c) == substitution.get(b)) - assert(substitution.get(a) == substitution.get(d)) - assert(substitution.get(a) == new RecordType(util.Arrays.asList(new RecordType.Field("src", new StringType(Collections.emptyList)), new RecordType.Field("ttl", new IntType(Collections.emptyList)), new RecordType.Field("data", new StringType(Collections.emptyList))), Collections.emptyList)) - }) - - test("incompatibleConcreteAndAbstractRecord")(new TSFixture { - val a = typeGenerator.getTypeVariable(Collections.emptyList) - val b = typeGenerator.getTypeVariable(Collections.emptyList) - val abstractRecord = typeGenerator.getAbstractRecord(Collections.emptyList) - solver.addConstraint(new MonomorphicConstraint(dummyUID, a, abstractRecord)) - solver.addConstraint(new MonomorphicConstraint(dummyUID, abstractRecord, "src", new StringType(Collections.emptyList))) - solver.addConstraint(new MonomorphicConstraint(dummyUID, abstractRecord, "ttl", new IntType(Collections.emptyList))) - solver.addConstraint(new MonomorphicConstraint(dummyUID, abstractRecord, "data", new StringType(Collections.emptyList))) - solver.addConstraint(new MonomorphicConstraint(dummyUID, b, new RecordType(util.Arrays.asList(new RecordType.Field("src", new StringType(Collections.emptyList)), new RecordType.Field("data", new StringType(Collections.emptyList))), Collections.emptyList))) - solver.addConstraint(new MonomorphicConstraint(dummyUID, a, b)) - solver.unify(ctx) - assert(ctx.hasErrors) - }) -} \ No newline at end of file diff --git a/test/pgo/parser/ModularPlusCalParserTest.scala b/test/pgo/parser/ModularPlusCalParserTest.scala deleted file mode 100644 index 717018f6c..000000000 --- a/test/pgo/parser/ModularPlusCalParserTest.scala +++ /dev/null @@ -1,103 +0,0 @@ -package pgo.parser - -import org.scalatest.funsuite.AnyFunSuite -import pgo.TestingUtils -import pgo.model.mpcal.ModularPlusCalBlock -import pgo.model.mpcal.ModularPlusCalBuilder._ -import pgo.model.pcal.PlusCalBuilder._ -import pgo.model.pcal.{PlusCalFairness, PlusCalStatement} -import pgo.model.tla.TLABuilder._ - -import scala.jdk.CollectionConverters._ - -class ModularPlusCalParserTest extends AnyFunSuite { - def check(tag: String)(pair: (String,ModularPlusCalBlock)): Unit = - test(tag) { - val(specStr,expectedBlock) = pair - val (_, _, actualBlock) = TestingUtils.parseMPCalFromString(specStr) - assert(actualBlock == expectedBlock) - } - - check("single-process with procedure and macro") { - """---- MODULE Test ---- - |(* --mpcal Test { - | macro M(a) { - | print a; - | } - | procedure P(b) { - | print b; - | } - | variables global1 = 1, global2 = 2; - | { - | l1: print <>; - | } - |} - |*) - |\* BEGIN TRANSLATION - |====""".stripMargin -> mpcal( - "Test", - Nil.asJava, - List( - `macro`("M", - List("a").asJava, - printS(idexp("a")))).asJava, - List( - procedure("P", - List(pcalVarDecl("b", false, false, PLUSCAL_DEFAULT_INIT_VALUE)).asJava, - Nil.asJava, - printS(idexp("b")))).asJava, - Nil.asJava, - Nil.asJava, - List( - pcalVarDecl("global1", false, false, num(1)), - pcalVarDecl("global2", false, false, num(2))).asJava, - Nil.asJava, - List[PlusCalStatement]( - labeled(label("l1"), - printS(tuple(idexp("global1"), idexp("global2"))))).asJava) - } - - check("multi-process with procedure and macro") { - """---- MODULE Test ---- - |EXTENDS Integers - |(* --mpcal Test { - | macro M(a) { - | print a; - | } - | procedure P(b) { - | print b; - | } - | variables global1 = 1, global2 = 2; - | process (P \in 1..3) { - | l1: print <>; - | } - |} - |*) - |\* BEGIN TRANSLATION - |==== - |""".stripMargin -> mpcal( - "Test", - Nil.asJava, - List( - `macro`("M", - List("a").asJava, - printS(idexp("a")))).asJava, - List( - procedure("P", - List(pcalVarDecl("b", false, false, PLUSCAL_DEFAULT_INIT_VALUE)).asJava, - Nil.asJava, - printS(idexp("b")))).asJava, - Nil.asJava, - Nil.asJava, - List( - pcalVarDecl("global1", false, false, num(1)), - pcalVarDecl("global2", false, false, num(2))).asJava, - Nil.asJava, - process( - pcalVarDecl("P", false, true, binop("..", num(1), num(3))), - PlusCalFairness.UNFAIR, - Nil.asJava, - labeled(label("l1"), - printS(tuple(idexp("global1"), idexp("global2")))))) - } -} diff --git a/test/pgo/parser/ModularPlusCalUnitParserTest.scala b/test/pgo/parser/ModularPlusCalUnitParserTest.scala deleted file mode 100644 index 85777b676..000000000 --- a/test/pgo/parser/ModularPlusCalUnitParserTest.scala +++ /dev/null @@ -1,265 +0,0 @@ -package pgo.parser - -import org.scalactic.source.Position -import org.scalatest.funsuite.AnyFunSuite -import pgo.TestingUtils -import pgo.model.mpcal.{ModularPlusCalInstance, ModularPlusCalMappingMacro} -import pgo.model.pcal.{PlusCalBuilder, PlusCalFairness, PlusCalMacro, PlusCalProcedure, PlusCalProcess, PlusCalStatement} -import pgo.model.tla.TLABuilder._ -import pgo.model.pcal.PlusCalBuilder._ -import pgo.model.mpcal.ModularPlusCalBuilder._ -import pgo.model.tla.TLABuiltinModules - -import java.util.Collections -import scala.jdk.CollectionConverters._ - -class ModularPlusCalUnitParserTest extends AnyFunSuite with ModularPlusCalParser with ParsingUtils { - - implicit def theContext: PCalParserContext = { - val defns = TLABuiltinModules.Intrinsics.members ++ - TLABuiltinModules.Integers.members ++ TLABuiltinModules.Sequences.members ++ - List(id("global1"), id("global2"), id("global3")) - - implicit val ctx = defns.foldLeft(TLAParserContext())(_.withDefinition(_)) - PCalParserContext(archetypes = Map( - "Archetype" -> archetype("Archetype", Nil.asJava, Nil.asJava, Nil.asJava), - "Archetype3" -> archetype("Archetype3", - List( - PlusCalBuilder.pcalVarDecl("a", true, false, PLUSCAL_DEFAULT_INIT_VALUE), - PlusCalBuilder.pcalVarDecl("b", true, false, PLUSCAL_DEFAULT_INIT_VALUE), - PlusCalBuilder.pcalVarDecl("c", false, false, PLUSCAL_DEFAULT_INIT_VALUE)).asJava, - Nil.asJava, Nil.asJava))) - } - - def check[T](tag: String)(parser: Parser[T], input: String, expected: T)(implicit pos: Position): Unit = - test(tag) { - val path = ParserTestingUtils.ensureBackingFile(input) - withClue(input) { - val actual = checkResult { - phrase(parser)(buildReader(path, input)) - } - withClue("\n" + TestingUtils.stringDiff(expected.toString, actual.toString).mkString("\n")) { - assert(actual == expected) - } - } - } - - def checkMacro(tag: String)(pair: (String,PlusCalMacro))(implicit pos: Position): Unit = - check(tag)( - parser = mpcalWithRefs.pcalCSyntax.pcalMacro.cast, - input = pair._1, expected = pair._2) - - checkMacro("simple macro") { - """macro MyMacro(x) { - | x := x + 1; - |}""".stripMargin -> - `macro`("MyMacro", List("x").asJava, - assign(idexp("x"), binop("+", idexp("x"), num(1)))) - } - - - def checkProcedure(tag: String)(pair: (String,PlusCalProcedure))(implicit pos: Position): Unit = - check(tag)( - parser = mpcalWithRefs.pcalCSyntax.pcalProcedure.cast, - input = pair._1, expected = pair._2) - - checkProcedure("simple procedure") { - """procedure MyProcedure(x) { - | x := x + 1; - |}""".stripMargin -> - procedure("MyProcedure", List( - PlusCalBuilder.pcalVarDecl("x", false, false, PLUSCAL_DEFAULT_INIT_VALUE)).asJava, - Nil.asJava, - assign(idexp("x"), binop("+", idexp("x"), num(1)))) - } - - checkProcedure("procedure with ref arg") { - """procedure MyProcedure(ref x) { - | either { x := 10 } or { x := 20 }; - |}""".stripMargin -> - procedure("MyProcedure", List( - PlusCalBuilder.pcalVarDecl("x", true, false, PLUSCAL_DEFAULT_INIT_VALUE)).asJava, - Nil.asJava, - either(List( - List[PlusCalStatement](assign(idexp("x"), num(10))).asJava, - List[PlusCalStatement](assign(idexp("x"), num(20))).asJava, - ).asJava)) - } - - checkProcedure("call proc with ref") { - """procedure MyProcedure(ref x) { - | call MyProcedure(ref x); - |}""".stripMargin -> - procedure("MyProcedure", - List(PlusCalBuilder.pcalVarDecl("x", true, false, PLUSCAL_DEFAULT_INIT_VALUE)).asJava, - Nil.asJava, - call("MyProcedure", ref("x"))) - } - - def checkProcess(tag: String)(pair: (String,PlusCalProcess))(implicit pos: Position): Unit = - check(tag)(parser = mpcalWithRefs.pcalCSyntax.pcalProcess.cast, - input = pair._1, expected = pair._2) - - checkProcess("ref in call in process") { - """process (MyProcess = 12) - |variables x; - |{ - | call MyProcedure(ref x); - |}""".stripMargin -> - process( - PlusCalBuilder.pcalVarDecl("MyProcess", false, false, num(12)), - PlusCalFairness.UNFAIR, - List( - PlusCalBuilder.pcalVarDecl("x", false, false, PLUSCAL_DEFAULT_INIT_VALUE)).asJava, - call("MyProcedure", ref("x"))) - } - - // archetypes - - def checkInstance(tag: String)(pair: (String,ModularPlusCalInstance))(implicit pos: Position): Unit = - check(tag)(parser = mpcalInstance, input = pair._1, expected = pair._2) - - checkInstance("simple instance") { - """process (P \in 1..3) == instance Archetype();""".stripMargin -> - instance(PlusCalBuilder.pcalVarDecl("P", false, true, binop("..", num(1), num(3))), - PlusCalFairness.UNFAIR, "Archetype", Collections.emptyList(), Collections.emptyList()) - } - - checkInstance("weak fairness") { - """fair process (P \in 1..3) == instance Archetype();""".stripMargin -> - instance(PlusCalBuilder.pcalVarDecl("P", false, true, binop("..", num(1), num(3))), - PlusCalFairness.WEAK_FAIR, "Archetype", Collections.emptyList(), Collections.emptyList()) - } - - checkInstance("strong fairness") { - """fair+ process (P \in 1..3) == instance Archetype();""".stripMargin -> - instance(PlusCalBuilder.pcalVarDecl("P", false, true, binop("..", num(1), num(3))), - PlusCalFairness.STRONG_FAIR, "Archetype", Collections.emptyList(), Collections.emptyList()) - } - - checkInstance("full featured instance") { - """process (P = "P") == instance Archetype3(ref global1, ref global2, global3) - | mapping global1 via MappingMacro1 - | mapping global2[_] via MappingMacro2;""".stripMargin -> - instance(PlusCalBuilder.pcalVarDecl("P", false, false, str("P")), - PlusCalFairness.UNFAIR, - "Archetype3", - List( - ref("global1"), - ref("global2"), - idexp("global3")).asJava, - List( - mapping("global1", false, "MappingMacro1"), - mapping("global2", true, "MappingMacro2")).asJava) - } - - checkInstance("instance with indexed mappings") { - """process (P = "P") == instance Archetype3(ref global1, 42, global3) - | mapping @2 via MappingMacro1 - | mapping @3[_] via MappingMacro2;""".stripMargin -> - instance(PlusCalBuilder.pcalVarDecl("P", false, false, str("P")), - PlusCalFairness.UNFAIR, - "Archetype3", - List( - ref("global1"), - num(42), - idexp("global3")).asJava, - List( - mapping(2, false, "MappingMacro1"), - mapping(3, true, "MappingMacro2")).asJava) - } - - def checkMappingMacro(tag: String)(pair: (String, ModularPlusCalMappingMacro))(implicit pos: Position): Unit = - check(tag)(parser = mpcalMappingMacro, input = pair._1, expected = pair._2) - - checkMappingMacro("simple mapping macro") { - """mapping macro MappingMacro { - | read { - | yield $value; - | } - | write { - | yield $value; - | } - |}""".stripMargin -> - mappingMacro("MappingMacro", - Collections.singletonList(`yield`(DOLLAR_VALUE)), - Collections.singletonList(`yield`(DOLLAR_VALUE))) - } - - checkMappingMacro("mapping macro with either") { - """mapping macro UnreliableCounter { - | read { - | yield $value; - | } - | write { - | either { - | yield $variable + $value; - | } or { - | yield $variable; - | } - | } - |}""".stripMargin -> - mappingMacro("UnreliableCounter", - Collections.singletonList(`yield`(DOLLAR_VALUE)), - Collections.singletonList( - either( - List( - List[PlusCalStatement]( - `yield`(binop("+", DOLLAR_VARIABLE, DOLLAR_VALUE))).asJava, - List[PlusCalStatement]( - `yield`(DOLLAR_VARIABLE)).asJava).asJava))) - } - - checkMappingMacro("mapping macro with multiple statements") { - """mapping macro MappingMacro { - | read { - | await "someSpecialCondition"; - | yield $value; - | } - | write { - | yield $value; - | } - |}""".stripMargin -> - mappingMacro("MappingMacro", - List( - await(str("someSpecialCondition")), - `yield`(DOLLAR_VALUE)).asJava, - List[PlusCalStatement](`yield`(DOLLAR_VALUE)).asJava) - } - - checkMappingMacro("lossy network model") { - """mapping macro LossyNetwork { - | read { - | await Len($variable) > 0; - | with (msg = Head($variable)) { - | $variable := Tail($variable); - | yield msg; - | } - | } - | - | write { - | either { - | yield $variable; - | } or { - | await Len($variable) < global1; - | yield Append($variable, $value); - | } - | } - |}""".stripMargin -> - mappingMacro( - "LossyNetwork", - List( - await(binop(">", opcall("Len", DOLLAR_VARIABLE), num(0))), - `with`( - List( - PlusCalBuilder.pcalVarDecl("msg", false, false, opcall("Head", DOLLAR_VARIABLE))).asJava, - assign(DOLLAR_VARIABLE, opcall("Tail", DOLLAR_VARIABLE)), - `yield`(idexp("msg")))).asJava, - List[PlusCalStatement]( - either(List( - List[PlusCalStatement](`yield`(DOLLAR_VARIABLE)).asJava, - List[PlusCalStatement]( - await(binop("<", opcall("Len", DOLLAR_VARIABLE), idexp("global1"))), - `yield`(opcall("Append", DOLLAR_VARIABLE, DOLLAR_VALUE))).asJava).asJava)).asJava) - } -} diff --git a/test/pgo/parser/ParserTestingUtils.scala b/test/pgo/parser/ParserTestingUtils.scala deleted file mode 100644 index 693f5cb68..000000000 --- a/test/pgo/parser/ParserTestingUtils.scala +++ /dev/null @@ -1,12 +0,0 @@ -package pgo.parser - -import java.nio.file.{Files, Path} - -object ParserTestingUtils { - def ensureBackingFile(str: String): Path = { - val path = Files.createTempFile("backing-file", "") - path.toFile.deleteOnExit() - Files.writeString(path, str) - path - } -} diff --git a/test/pgo/parser/PlusCalParserSmokeTest.scala b/test/pgo/parser/PlusCalParserSmokeTest.scala deleted file mode 100644 index e372975cb..000000000 --- a/test/pgo/parser/PlusCalParserSmokeTest.scala +++ /dev/null @@ -1,39 +0,0 @@ -package pgo.parser - -import org.scalatest.funsuite.AnyFunSuite - -import java.io.RandomAccessFile -import java.nio.channels.FileChannel -import java.nio.charset.StandardCharsets -import java.nio.file.Paths -import scala.util.Using - -class PlusCalParserSmokeTest extends AnyFunSuite{ - val fileNames = List( - "Euclid", - "QueensPluscal", - "TwoPhaseCommit", - "AltBitProtocol", - "Sum", - "Await", - "FastMutex", - "pgo2pc", - ) - - fileNames.foreach { fileName => - test(fileName) { - val inputFilePath = Paths.get("test", "pluscal", s"$fileName.tla") - Using.Manager { use => - val file = use(new RandomAccessFile(inputFilePath.toFile, "r")) - val fileChannel = use(file.getChannel) - val buffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, fileChannel.size) - // assume UTF-8, though technically TLA+ is ASCII only according to the book - val charSeq = StandardCharsets.UTF_8.decode(buffer) - - // basic smoke test, ensure that we at least seem to parse all our example files correctly - val tlaModule = TLAParser.readModuleBeforeTranslation(inputFilePath, charSeq) - PlusCalParser.readAlgorithm(inputFilePath, StandardCharsets.UTF_8.decode(buffer), tlaModule) - } - } - } -} diff --git a/test/pgo/parser/TLAExpressionParseTest.scala b/test/pgo/parser/TLAExpressionParseTest.scala deleted file mode 100644 index 358c4704b..000000000 --- a/test/pgo/parser/TLAExpressionParseTest.scala +++ /dev/null @@ -1,382 +0,0 @@ -package pgo.parser - -import org.scalactic.source.Position -import org.scalatest.funsuite.AnyFunSuite - -import java.util -import java.util.Collections -import pgo.model.tla.{TLABool, TLABuiltinModules, TLAExpression, TLAFairness} -import pgo.util.SourceLocation -import pgo.model.tla.TLABuilder._ - -class TLAExpressionParseTest extends AnyFunSuite { - def check(tag: String)(pair: (String,TLAExpression))(implicit pos: Position): Unit = - test(tag) { - val (str, expected) = pair - withClue(str) { - val testFile = ParserTestingUtils.ensureBackingFile(str) - val expr = TLAParser.readExpression( - testFile, - str, - definitions = TLABuiltinModules.Integers.members ++ - TLABuiltinModules.Sequences.members ++ - TLABuiltinModules.Bags.members) // needed for (+) - assert(expr == expected) - } - } - // TODO: re-introduce in a way that makes sense given scoping - // {"a!b", idexp(prefix(idpart("a")), "b") }, - // {"a(1,2)!b", idexp(prefix(idpart("a", num(1), num(2))), "b")}, - // {"a(1,2)!b(3,4)", opcall(prefix(idpart("a", num(1), num(2))), id("b"), num(3), num(4)) }, - // {"a!b!c!d", idexp(prefix(idpart("a"), idpart("b"), idpart("c")), "d") }, - - // simple exprs - check("1") { - "1" -> num(1) - } - check("-1") { - "-1" -> unary("-_", num(1)) - } - check("(2)") { - "(2)" -> num(2) - } - check("TRUE") { - "TRUE" -> new TLABool(SourceLocation.unknown, true) - } - check("FALSE") { - "FALSE" -> new TLABool(SourceLocation.unknown, false) - } - check("some string") { - "\"some string\"" -> str("some string") - } - check("function") { - """[mgr \in "managers" |-> "start"]""" -> function( - bounds(qbIds(ids(id("mgr")), str("managers"))), - str("start")) - } - check("set refinement ambiguity") { - """{ a \in "B" : a \in a }""" -> setRefinement( - "a", - str("B"), - binop("\\in", idexp("a"), idexp("a"))) - } - check("record constructor") { - """[src |-> "clientId", dst |-> "serverId"]""" -> record( - field(id("src"), str("clientId")), - field(id("dst"), str("serverId"))) - } - check("empty tuple") { - "<< >>" -> tuple() - } - check("empty set") { - "{ }" -> set() - } - check("set containing empty tuple") { - "{ << >> }" -> set(tuple()) - } - check("tuple 3") { - "<<24, \"v_init\", \"have gcd\", \"v\">>" -> tuple( - num(24), str("v_init"), str("have gcd"), str("v")) - } - - // unary operators - check("prime operator") { - """"a"'""" -> unary(prefix(), "'", str("a")) - } - check("function call on primed expr") { - """"a"'["b"]""" -> fncall(unary("'", str("a")), str("b")) - } - check("function call plain") { - """"a"["b"]""" -> fncall(str("a"), str("b")) - } - check("prefixes: DOMAIN then lnot") { - """DOMAIN \lnot "a"""" -> unary("DOMAIN", unary("\\lnot", str("a"))) - } - check("prefixes: lnot then DOMAIN") { - """\lnot DOMAIN "a"""" -> unary("\\lnot", unary("DOMAIN", str("a"))) - } - - // infix operators - check("assignment of set of empty tuple") { - "\"todo\" = { << >> }" -> binop("=", str("todo"), set(tuple())) - } - check("number ..") { - """0..1""" -> binop("..", num(0), num(1)) - } - check("compound ..") { - """0.."procs"-1""" -> binop("..", num(0), binop("-", str("procs"), num(1))) - } - - check("prime with infix") { - """"x"' \notin "y"""" -> binop("\\notin", unary("'", str("x")), str("y")) - } - check("function call with infix") { - """"pc"["i"] \notin "x"""" -> binop( - "\\notin", - fncall(str("pc"), str("i")), - str("x")) - } - check("function call with bigger infix") { - """"pc"["i"] \notin {"Li5", "Li6", "ncs"}""" -> binop( - "\\notin", - fncall(str("pc"), str("i")), - set(str("Li5"), str("Li6"), str("ncs"))) - } - check("function call with assignment") { - """"pc"["self"] = "c1"""" -> binop("=", fncall(str("pc"), str("self")), str("c1")) - } - - // dotted - check("single dot expr") { - """"a".b""" -> dot(str("a"), "b") - } - check("chained dot expr") { - """"a".b.c""" -> dot(dot(str("a"), "b"), "c") - } - check("dot with function call") { - """"a"[1].b""" -> dot(fncall(str("a"), num(1)), "b") - } - check("dot with grouped function call") { - """("a"[1]).b""" -> dot(fncall(str("a"), num(1)), "b") - } - check("dot with prime") { - """"a"'.b""" -> dot(unary("'", str("a")), "b") - } - check("nested primed dots") { - """"a"'.b'.c""" -> dot(unary("'", dot(unary("'", str("a")), "b")), "c") - } - check("dot with infix") { - """"a" (+) "b".d""" -> binop("(+)", str("a"), dot(str("b"), "d")) - } - check("dot with grouped infix") { - """("a" \cup "b").c""" -> dot(binop("\\cup", str("a"), str("b")), "c") - } - check("dot with record construction") { - """[src |-> "clientId", dst |-> "serverId"].src""" -> dot( - record(field(id("src"), str("clientId")), field(id("dst"), str("serverId"))), - "src") - } - - // conjuncts - check("unary conjunct") { - """/\ 1""" -> num(1) - } - check("conjunct 2 aligned") { - """/\ 1 - |/\ 2""".stripMargin -> conjunct(num(1), num(2)) - } - check("conjunct 2 trailing dedent") { - """ /\ 1 - | /\ 2 - |/\ 3""".stripMargin -> conjunct(conjunct(num(1), num(2)), num(3)) - } - check("conjunct 3 aligned") { - """ /\ 1 - | /\ 2 - | /\ 3""".stripMargin -> conjunct(conjunct(num(1), num(2)), num(3)) - } - check("infix conjunct due to misalignment") { - """ /\ 1 - |/\ 2 - | /\ 3""".stripMargin -> conjunct(conjunct(num(1), num(2)), num(3)) - } - check("conjunct 2 with trailing new line") { - """/\ 1 - |/\ 2 - |""".stripMargin -> binop("/\\", num(1), num(2)) - } - check("indented conjunct 2 with trailing new line") { - """ /\ 1 - | /\ 2 - |""".stripMargin -> binop("/\\", num(1), num(2)) - } - check("conjunct 2 with nested conjunct 1") { - """ /\ 1 /\ 2 - | /\ 3 - |""".stripMargin -> binop("/\\", binop("/\\", num(1), num(2)), num(3)) - } - check("conjunct 2 with nested conjunct 1 + prefix op") { - """ /\ 1 /\ []2 - | /\ 3 - |""".stripMargin -> binop( - "/\\", - binop("/\\", num(1), unary("[]", num(2))), - num(3)) - } - check("triple nested conjunct 1") { - """ /\ 1 /\ []2 /\ 3 - |""".stripMargin -> binop( - "/\\", - binop("/\\", num(1), unary("[]", num(2))), - num(3)) - } - check("conjunct 2 with prefix op") { - """~ /\ 1 - | /\ 2""".stripMargin -> unary("~", binop("/\\", num(1), num(2))) - } - check("infix conjunct with prefix op") { - """[] 2 /\ 3""" -> binop("/\\", unary("[]", num(2)), num(3)) - } - check("conjunct 2 with nested WF_") { - """ /\ "Init" /\ 4 - | /\ WF_"vars"("P(self)")""".stripMargin -> binop( - "/\\", - binop("/\\", str("Init"), num(4)), - fairness(TLAFairness.Type.WEAK, str("vars"), str("P(self)"))) - } - check("conjunct 2 with nested disjunct") { - """/\ 1 \/ 2 - |/\ 3""".stripMargin -> binop("/\\", binop("\\/", num(1), num(2)), num(3)) - } - check("conjunct 2 with nested conjunct 1 + universal + WF_") { - """ /\ "Init" /\ 4 - | /\ \A self \in 0.."procs"-1 : WF_self("P"[self])""".stripMargin -> binop( - "/\\", - binop("/\\", str("Init"), num(4)), - universal( - bounds(qbIds( - ids(id("self")), - binop("..", num(0), binop("-", str("procs"), num(1))))), - fairness(TLAFairness.Type.WEAK, idexp("self"), fncall(str("P"), idexp("self"))))) - } - - // case exprs - check("case one branch") { - """CASE 0 -> 1""" -> caseexp(arms(arm(num(0), num(1))), null) - } - check("case one branch with other") { - """CASE 0 -> 1 - |[] OTHER -> "foo"""".stripMargin -> caseexp(arms(arm(num(0), num(1))), str("foo")) - } - check("case 2 branches with other") { - """CASE 0 -> 1 - |[] 2 -> 3 - |[] OTHER -> "foo"""".stripMargin -> caseexp( - arms( - arm(num(0), num(1)), - arm(num(2), num(3))), - str("foo")) - } - - // existentials and universals - check("universal over empty set") { - """\A i \in {} : i = 1""" -> universal( - Collections.singletonList(qbIds(Collections.singletonList(id("i")), set())), - binop("=", idexp("i"), num(1))) - } - check("existential over empty set") { - """\E i \in {} : i = 1""" -> existential( - Collections.singletonList(qbIds(Collections.singletonList(id("i")), set())), - binop("=", idexp("i"), num(1))) - } - check("forall over multiple bounds") { - """\A x \in "set",y \in (1)..(3) : (((x)+(y))%(2))=(1)""" -> universal( - bounds( - qbIds(ids(id("x")), str("set")), - qbIds(ids(id("y")), binop("..", num(1), num(3)))), - binop("=", binop("%", binop("+", idexp("x"), idexp("y")), num(2)), num(1))) - } - check("unqualified existential") { - """\E restaurant_stage, self : (restaurant_stage[self] = "commit")""" -> uqExistential( - util.Arrays.asList(id("restaurant_stage"), id("self")), - binop("=", fncall(idexp("restaurant_stage"), idexp("self")), str("commit"))) - } - - // bindings + WF_ - check("WF_ with arity 0 identifier in vars position") { - """\E foo, bar : - |WF_foo(bar)""".stripMargin -> uqExistential( - util.Arrays.asList(id("foo"), id("bar")), - fairness(TLAFairness.Type.WEAK, idexp("foo"), idexp("bar"))) - } - check("WF_ with parameterised operator in vars position") { - """LET foo(x) == x - | bar == 0 - |IN WF_foo(bar)(bar)""".stripMargin -> let( - util.Arrays.asList( - opdef(false, id("foo"), Collections.singletonList(opdecl(id("x"))), idexp("x")), - opdef(false, id("bar"), Collections.emptyList, num(0))), - fairness(TLAFairness.Type.WEAK, opcall("foo", idexp("bar")), idexp("bar"))) - } - check("operator call arity 2") { - """LET Append(x,y) == 0 - |IN Append("output", "msg"'[1])""".stripMargin -> let( - util.Arrays.asList( - opdef(false, id("Append"), util.Arrays.asList(opdecl(id("x")), opdecl(id("y"))), num(0))), - opcall("Append", str("output"), fncall(unary("'", str("msg")), num(1)))) - } - - // EXCEPT - check("EXCEPT one id") { - """["F" EXCEPT !.a = 2]""" -> except(str("F"), sub(keys(str("a")), num(2))) - } - check("EXCEPT one idx") { - """["F" EXCEPT ![1] = 2]""" -> except(str("F"), sub(keys(num(1)), num(2))) - } - check("EXCEPT one id with idx") { - """["F" EXCEPT !.a[1] = 2]""" -> except(str("F"), sub(keys(str("a"), num(1)), num(2))) - } - check("EXCEPT two: id with idx, and id") { - """["F" EXCEPT !.a[1] = 2, !.b = 3]""" -> except( - str("F"), - sub(keys(str("a"), num(1)), num(2)), - sub(keys(str("b")), num(3))) - } - check("EXCEPT one string idx") { - """["sum" EXCEPT !["self"] = "msg_"'["self"]]""" -> except( - str("sum"), - sub(keys(str("self")), fncall(unary("'", str("msg_")), str("self")))) - } - - // big - check("big compound expression") { - """\E pc, self, restaurant_stage, managers, rstMgrs, aborted : - | /\ pc[self] = "c1" - | /\ (restaurant_stage[self] = "commit") \/ - | (restaurant_stage[self] = "abort") - | /\ IF restaurant_stage[self] = "commit" - | THEN /\ restaurant_stage' = [restaurant_stage EXCEPT ![self] = "committed"] - | ELSE /\ restaurant_stage' = [restaurant_stage EXCEPT ![self] = "aborted"] - | /\ pc' = [pc EXCEPT ![self] = "Done"] - | /\ UNCHANGED << managers, rstMgrs, aborted >>""".stripMargin -> uqExistential( - util.Arrays.asList( - id("pc"), id("self"), id("restaurant_stage"), id("managers"), - id("rstMgrs"), id("aborted")), - binop( - "/\\", - binop( - "/\\", - binop( - "/\\", - binop( - "/\\", - binop("=", fncall(idexp("pc"), idexp("self")), str("c1")), - binop( - "\\/", - binop("=", fncall(idexp("restaurant_stage"), idexp("self")), str("commit")), - binop("=", fncall(idexp("restaurant_stage"), idexp("self")), str("abort")))), - ifexp( - binop("=", fncall(idexp("restaurant_stage"), idexp("self")), str("commit")), - binop( - "=", - unary("'", idexp("restaurant_stage")), - except(idexp("restaurant_stage"), sub(keys(idexp("self")), str("committed")))), - binop( - "=", - unary("'", idexp("restaurant_stage")), - except(idexp("restaurant_stage"), sub(keys(idexp("self")), str("aborted")))))), - binop("=", unary("'", idexp("pc")), except(idexp("pc"), sub(keys(idexp("self")), str("Done"))))), - unary("UNCHANGED", tuple(idexp("managers"), idexp("rstMgrs"), idexp("aborted"))))) - } - check("big nested universal") { - """\A i \in "Proc" : - | ("pc"[i] = "Li0") ~> (\E j \in "Proc" : "pc"[j] = "cs")""".stripMargin -> universal( - bounds(qbIds(ids(id("i")), str("Proc"))), - binop( - "~>", - binop("=", fncall(str("pc"), idexp("i")), str("Li0")), - existential( - bounds(qbIds(ids(id("j")), str("Proc"))), - binop("=", fncall(str("pc"), idexp("j")), str("cs"))))) - } -} \ No newline at end of file diff --git a/test/pgo/parser/TLAParserSmokeTest.scala b/test/pgo/parser/TLAParserSmokeTest.scala deleted file mode 100644 index 2032f788e..000000000 --- a/test/pgo/parser/TLAParserSmokeTest.scala +++ /dev/null @@ -1,46 +0,0 @@ -package pgo.parser - -import org.scalatest.funsuite.AnyFunSuite - -import java.io.RandomAccessFile -import java.nio.channels.FileChannel -import java.nio.charset.StandardCharsets -import java.nio.file.{Path, Paths} -import scala.util.Using - -trait TLAParserSmokeTestBase extends AnyFunSuite { - val fileNames = List( - "Euclid", - "QueensPluscal", - "TwoPhaseCommit", - "AltBitProtocol", - "Sum", - "Await", - "FastMutex", - "pgo2pc", - ) - def checkFor(path: java.nio.file.Path, charSequence: CharSequence): Unit - - fileNames.foreach { fileName => - test(fileName) { - val inputFilePath = Paths.get("test", "pluscal", fileName + ".tla") - Using.Manager { use => - val fileChannel = use(use(new RandomAccessFile(inputFilePath.toFile, "r")).getChannel) - val buffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, fileChannel.size) - val charSeq = StandardCharsets.UTF_8.decode(buffer) - - checkFor(inputFilePath, charSeq) - } - } - } -} - -class BeforeTranslationTLAParserSmokeTest extends TLAParserSmokeTestBase { - override def checkFor(path: Path, charSequence: CharSequence): Unit = - TLAParser.readModuleBeforeTranslation(path, charSequence) -} - -class WholeModuleTLAParserSmokeTest extends TLAParserSmokeTestBase { - override def checkFor(path: Path, charSequence: CharSequence): Unit = - TLAParser.readModule(path, charSequence) -} diff --git a/test/pgo/parser/TLAUnitParseTest.scala b/test/pgo/parser/TLAUnitParseTest.scala deleted file mode 100644 index 688949d44..000000000 --- a/test/pgo/parser/TLAUnitParseTest.scala +++ /dev/null @@ -1,229 +0,0 @@ -package pgo.parser - -import org.scalatest.funsuite.AnyFunSuite -import pgo.model.tla._ -import TLABuilder._ -import org.scalactic.source.Position -import pgo.TestingUtils - -import scala.jdk.CollectionConverters._ - -class TLAUnitParseTest extends AnyFunSuite with TLAParser with ParsingUtils { - def check(tag: String)(pair: (String, TLAUnit))(implicit pos: Position): Unit = - test(tag) { - val (input, expected) = pair - val backingFile = ParserTestingUtils.ensureBackingFile(input) - withClue(s"input:\n$input") { - val defns = TLABuiltinModules.Intrinsics.members ++ - TLABuiltinModules.Integers.members ++ TLABuiltinModules.Sequences.members - implicit val ctx = defns.foldLeft(TLAParserContext())(_.withDefinition(_)) - val actual = checkResult { - (wsChk ~> tlaUnit <~ wsChk) (buildReader(backingFile, input)) - } - withClue("\n" + TestingUtils.stringDiff(expected = expected.toString, actual = actual.toString).mkString("\n")) { - assert(expected == actual) - } - } - } - - check("queens IsSolution") { - """---- MODULE Test ---- - |EXTENDS Sequences, Integers - | - |Attacks(queens, i, j) == "stub" - |IsSolution(queens) == - | \A i \in 1 .. Len(queens)-1 : \A j \in i+1 .. Len(queens) : - | ~ Attacks(queens,i,j) - |==== - |""".stripMargin -> module( - "Test", - List(id("Sequences"), id("Integers")).asJava, - List[TLAUnit]( - opdef(false, id("Attacks"), List(opdecl(id("queens")), opdecl(id("i")), opdecl(id("j"))).asJava, - str("stub")), - opdef(false, id("IsSolution"), List(opdecl(id("queens"))).asJava, - universal(bounds(qbIds(ids(id("i")), binop("..", num(1), binop("-", opcall("Len", idexp("queens")), num(1))))), - universal(bounds(qbIds(ids(id("j")), binop("..", binop("+", idexp("i"), num(1)), opcall("Len", idexp("queens"))))), - unary("~", opcall("Attacks", idexp("queens"), idexp("i"), idexp("j"))))))).asJava) - } - - check("queens Solutions") { - """Solutions == LET N == 42 IsSolution(x) == FALSE IN { queens \in [1..N -> 1..N] : IsSolution(queens) }""" -> - opdef(false, id("Solutions"), opdecls(), - let( - List[TLAUnit]( - opdef(false, id("N"), opdecls(), num(42)), - opdef(false, id("IsSolution"), opdecls(opdecl(id("x"))), bool(false))).asJava, - setRefinement("queens", - functionSet(binop("..", num(1), idexp("N")), binop("..", num(1), idexp("N"))), - opcall("IsSolution", idexp("queens"))))) - } - - check("dashed prefix") { - """---- MODULE Test ---- - |CONSTANTS pc, Proc - | - |----------------------------------------------------------------------------- - |MutualExclusion == \A i, j \in Proc : - | (i # j) => ~ /\ pc[i] = "cs" - | /\ pc[j] = "cs" - |==== - |""".stripMargin -> module( - "Test", - Nil.asJava, - List[TLAUnit]( - constants(opdecl(id("pc")), opdecl(id("Proc"))), - opdef(false, id("MutualExclusion"), opdecls(), - universal(bounds(qbIds(ids(id("i"), id("j")), idexp("Proc"))), - binop("=>", binop("#", idexp("i"), idexp("j")), - unary("~", conjunct( - binop("=", - fncall(idexp("pc"), idexp("i")), - str("cs")), - binop("=", - fncall(idexp("pc"), idexp("j")), - str("cs")))))))).asJava) - } - - check("deadlockFreedom") { - """DeadlockFreedom == - | \E pc, Proc : - | \A i \in Proc : - | (pc[i] \notin {"Li5", "Li6", "ncs"}) ~> (\E j \in Proc : pc[j] = "cs") - |""".stripMargin -> - opdef(false, id("DeadlockFreedom"), opdecls(), - uqExistential(List(id("pc"), id("Proc")).asJava, - universal(bounds(qbIds(ids(id("i")), idexp("Proc"))), - binop("~>", - binop("\\notin", - fncall(idexp("pc"), idexp("i")), - set(str("Li5"), str("Li6"), str("ncs"))), - existential(bounds(qbIds(ids(id("j")), idexp("Proc"))), - binop("=", - fncall(idexp("pc"), idexp("j")), - str("cs"))))))) - } - - check("Termination") { - """Termination == \E pc : <>(pc = "Done")""".stripMargin -> - opdef(false, id("Termination"), opdecls(), - uqExistential(List(id("pc")).asJava, - unary("<>", binop("=", idexp("pc"), str("Done"))))) - } - - check("Spec") { - """Spec(self, Init, P(_), procs, vars) == - | /\ Init /\ []4 - | /\ \A self \in 0..procs-1 : WF_vars(P(self))""".stripMargin -> - opdef(false, id("Spec"), - opdecls( - opdecl(id("self")), - opdecl(id("Init")), - opdeclNamed(id("P"), 1), - opdecl(id("procs")), - opdecl(id("vars"))), - binop("/\\", - binop("/\\", - idexp("Init"), - unary("[]", - num(4))), - universal( - bounds( - qbIds( - ids(id("self")), - binop("..", - num(0), - binop("-", idexp("procs"), num(1))))), - fairness(TLAFairness.Type.WEAK, idexp("vars"), - opcall("P", idexp("self")))))) - } - - check("large conjunct") { - """c1(self) == \E pc, managers, rstMgrs, aborted, restaurant_stage : - | /\ pc[self] = "c1" - | /\ (restaurant_stage[self] = "commit") \/ - | (restaurant_stage[self] = "abort") - | /\ IF restaurant_stage[self] = "commit" - | THEN /\ restaurant_stage' = [restaurant_stage EXCEPT ![self] = "committed"] - | ELSE /\ restaurant_stage' = [restaurant_stage EXCEPT ![self] = "aborted"] - | /\ pc' = [pc EXCEPT ![self] = "Done"] - | /\ UNCHANGED << managers, rstMgrs, aborted >>""".stripMargin -> - opdef(false, id("c1"), opdecls(opdecl(id("self"))), - uqExistential(List(id("pc"), id("managers"), id("rstMgrs"), id("aborted"), id("restaurant_stage")).asJava, - binop("/\\", - binop("/\\", - binop("/\\", - binop("/\\", - binop("=", fncall(idexp("pc"), idexp("self")), str("c1")), - binop("\\/", - binop("=", - fncall(idexp("restaurant_stage"), idexp("self")), - str("commit")), - binop("=", - fncall(idexp("restaurant_stage"), idexp("self")), - str("abort")))), - ifexp( - binop("=", - fncall(idexp("restaurant_stage"), idexp("self")), - str("commit")), - binop("=", - unary("'", idexp("restaurant_stage")), - except( - idexp("restaurant_stage"), - sub(keys(idexp("self")), str("committed")))), - binop("=", - unary("'", idexp("restaurant_stage")), - except( - idexp("restaurant_stage"), - sub(keys(idexp("self")), str("aborted")))))), - binop("=", - unary("'", idexp("pc")), - except( - idexp("pc"), - sub(keys(idexp("self")), str("Done"))))), - unary("UNCHANGED", - tuple(idexp("managers"), idexp("rstMgrs"), idexp("aborted")))))) - } - - check("embedded comment") { - """----- MODULE Test ---- - |EXTENDS Sequences, Integers - |(* --algorithm Test { - | variables a = 2; \n" + - | b = 2; \n" + - | c = 3; \n" + - | { \n" + - | print (a)*((b)+(c))\n" + - | } \n" + - |} - |*) - | - |B == FALSE - |---- - |LOCAL C == TRUE - |====""".stripMargin -> module( - "Test", - List(id("Sequences"), id("Integers")).asJava, - List[TLAUnit]( - opdef(false, id("B"), Nil.asJava, bool(false)), - opdef(true, id("C"), Nil.asJava, bool(true))).asJava) - } - - check("DeadlockFree") { - """DeadlockFree == \E pc, Proc : \A i \in Proc : - | (pc[i] = "Li0") ~> (\E j \in Proc : pc[j] = "cs")""".stripMargin -> - opdef(false, id("DeadlockFree"), opdecls(), - uqExistential(List(id("pc"), id("Proc")).asJava, - universal( - bounds(qbIds(ids(id("i")), idexp("Proc"))), - binop("~>", - binop("=", - fncall(idexp("pc"), idexp("i")), - str("Li0")), - existential( - bounds(qbIds(ids(id("j")), idexp("Proc"))), - binop("=", - fncall(idexp("pc"), idexp("j")), - str("cs"))))))) - } -} diff --git a/test/pgo/trans/intermediate/ModularPlusCalMacroExpansionPassTest.scala b/test/pgo/trans/intermediate/ModularPlusCalMacroExpansionPassTest.scala deleted file mode 100644 index 91360dd95..000000000 --- a/test/pgo/trans/intermediate/ModularPlusCalMacroExpansionPassTest.scala +++ /dev/null @@ -1,58 +0,0 @@ -package pgo.trans.intermediate - -import org.scalactic.source.Position - -import java.util.Collections -import org.scalatest.funsuite.AnyFunSuite -import pgo.TestingUtils -import pgo.errors.TopLevelIssueContext -import pgo.model.mpcal.ModularPlusCalBlock -import pgo.model.pcal.PlusCalAlgorithm -import pgo.trans.passes.expansion.ModularPlusCalMacroExpansionPass -import pgo.model.pcal.PlusCalBuilder._ -import pgo.model.tla.TLABuilder._ - -import scala.jdk.CollectionConverters._ - - -class ModularPlusCalMacroExpansionPassTest extends AnyFunSuite { - def check(tag: String)(pair: (PlusCalAlgorithm,PlusCalAlgorithm))(implicit pos: Position): Unit = - test(tag) { - val (beforePCal, expectedPCal) = pair - val before = ModularPlusCalBlock.from(beforePCal) - val (_,reparsedBefore) = TestingUtils.reparseMPCal(before) - val expected = ModularPlusCalBlock.from(expectedPCal) - val ctx = new TopLevelIssueContext - val actual = ModularPlusCalMacroExpansionPass.perform(ctx, reparsedBefore) - assert(actual == expected) - } - - check("simple") { - algorithm( - "Test", - List(pcalVarDecl("a", false, false, str("a"))).asJava, - Collections.singletonList(`macro`( - "mymacro", Collections.singletonList("a"), - `with`(List(pcalVarDecl("b", false, false, str("b"))).asJava, - printS(idexp("a")), - printS(idexp("b"))))), - Collections.emptyList, - Collections.emptyList, - labeled( - label("foo"), - printS(idexp("a")), - macroCall("mymacro", binop("+", num(2), num(2)))) - ) -> algorithm( - "Test", - List(pcalVarDecl("a", false, false, str("a"))).asJava, - Collections.emptyList, - Collections.emptyList, - Collections.emptyList, - labeled( - label("foo"), - printS(idexp("a")), - `with`(List(pcalVarDecl("b", false, false, str("b"))).asJava, - printS(binop("+", num(2), num(2))), - printS(idexp("b"))))) - } -} \ No newline at end of file diff --git a/test/pgo/trans/passes/validation/PostScopingValidationTest.scala b/test/pgo/trans/passes/validation/PostScopingValidationTest.scala deleted file mode 100644 index 9937cd350..000000000 --- a/test/pgo/trans/passes/validation/PostScopingValidationTest.scala +++ /dev/null @@ -1,251 +0,0 @@ -package pgo.trans.passes.validation - -import org.scalactic.source.Position -import org.scalatest.funsuite.AnyFunSuite -import pgo.TestingUtils -import pgo.errors.{Issue, TopLevelIssueContext} -import pgo.model.mpcal.ModularPlusCalBuilder._ -import pgo.model.mpcal.ModularPlusCalUtils -import pgo.model.pcal.PlusCalBuilder._ -import pgo.model.pcal._ -import pgo.model.tla.TLABuilder._ -import pgo.trans.intermediate.{DefinitionRegistry, TLABuiltins} - -import java.util.Collections -import scala.jdk.CollectionConverters._ - -class PostScopingValidationTest extends AnyFunSuite { - def check(tag: String)(pair: (String,List[Issue]))(implicit pos: Position): Unit = - test(tag) { - val (specStr, expectedIssues) = pair - - val (_, _, spec) = TestingUtils.parseMPCalFromString(specStr) - - val ctx = new TopLevelIssueContext() - - val registry = new DefinitionRegistry - TLABuiltins.fillDefinitionRegistry(registry) - ModularPlusCalUtils.fillDefinitionRegistryFromModularPlusCalBlock(registry, spec) - - ValidationPass.perform(ctx, spec) - assert(!ctx.hasErrors) - - ValidationPass.performPostScoping(ctx, registry, spec) - assert(ctx.getIssues.asScala.toList == expectedIssues) - } - - check("inconsistent instantiations") { - """ - |---- MODULE InconsistentInstantiations ---- - |EXTENDS Sequences, FiniteSets, Integers - |(* - |--mpcal InconsistentInstantiations { - | mapping macro MyMapping { - | read { - | yield ""; - | } - | write { - | yield ""; - | } - | } - | mapping macro OtherMapping { - | read { - | yield ""; - | } - | write { - | yield ""; - | } - | } - | mapping macro SomeMapping { - | read { - | yield ""; - | } - | write { - | yield ""; - | } - | } - | archetype A1(ref a1) { - | l1: - | print 1; - | } - | archetype A2(ref a2) { - | l2: - | print 2; - | } - | variables network = <<>>; - | fair process (P1 = 1) == instance A1(ref network) - | mapping network[_] via MyMapping; - | fair process (Other = 42) == instance A2(ref network); - | fair process (P2 = 2) == instance A1(ref network) \* conflicts with P1 - | mapping network via OtherMapping; - | fair process (P3 = 3) == instance A1(network); \* conflicts with P1 - | fair process (Other2 = 24) == instance A2(network) \* conflicts with Other - | mapping network[_] via SomeMapping; - | } - | *) - |\* BEGIN TRANSLATION - |==== - |""".stripMargin -> List( - new InconsistentInstantiationIssue( - instance( - pcalVarDecl("P2", false, false, num(2)), - PlusCalFairness.WEAK_FAIR, - "A1", - Collections.singletonList(ref("network")), - Collections.singletonList( - mapping("network", false, "OtherMapping"))), - instance( - pcalVarDecl("P1", false, false, num(1)), - PlusCalFairness.WEAK_FAIR, - "A1", - Collections.singletonList(ref("network")), - Collections.singletonList(mapping("network", true, "MyMapping")))), - new InconsistentInstantiationIssue( - instance( - pcalVarDecl("P3", false, false, num(3)), - PlusCalFairness.WEAK_FAIR, - "A1", - Collections.singletonList(idexp("network")), - Collections.emptyList), - instance( - pcalVarDecl("P1", false, false, num(1)), - PlusCalFairness.WEAK_FAIR, - "A1", - Collections.singletonList(ref("network")), - Collections.singletonList(mapping("network", true, "MyMapping")))), - new InconsistentInstantiationIssue( - instance( - pcalVarDecl("Other2", false, false, num(24)), - PlusCalFairness.WEAK_FAIR, - "A2", - Collections.singletonList(idexp("network")), - Collections.singletonList(mapping("network", true, "SomeMapping"))), - instance( - pcalVarDecl("Other", false, false, num(42)), - PlusCalFairness.WEAK_FAIR, - "A2", - Collections.singletonList(ref("network")), - Collections.emptyList))) - } - - check("multiple mapping") { - """ - |---- MODULE MultipleMapping ---- - |EXTENDS Sequences, FiniteSets, Integers - |(* - |--mpcal MultipleMapping { - | mapping macro Macro { - | read { - | yield ""; - | } - | write { - | yield ""; - | } - | } - | archetype A(ref a) { - | l1: - | print 1; - | } - | variables global = <<>>; - | process (P = 1) == instance A(ref global) - | mapping global[_] via Macro; - | process (Q = 2) == instance A(ref global) - | mapping @1 via Macro; - |} - |*) - |\* BEGIN TRANSLATION - |""".stripMargin -> List( - new InconsistentInstantiationIssue( - instance( - pcalVarDecl("Q", false, false, num(2)), - PlusCalFairness.UNFAIR, - "A", - Collections.singletonList(ref("global")), - Collections.singletonList(mapping(1, false, "Macro"))), - instance(pcalVarDecl("P", false, false, num(1)), - PlusCalFairness.UNFAIR, - "A", - Collections.singletonList(ref("global")), - Collections.singletonList(mapping("global", true, "Macro"))))) - } - - check("invalid assignments") { - """ - |---- MODULE InvalidAssignments ---- - |EXTENDS Sequences, FiniteSets, Integers - |(* - |--mpcal InvalidAssignments { - | mapping macro SomeMacro { - | read { - | yield ""; - | } - | write { - | yield ""; - | } - | } - | - | mapping macro OtherMacro { - | read { - | yield ""; - | } - | write { - | yield ""; - | } - | } - | - | archetype MyArchetype(ref nonMapped, ref varMapped, ref fnMapped) - | variables someLocal; - | { - | l1: - | while (TRUE) { - | nonMapped := 10; \* valid - | someLocal := fnMapped[nonMapped]; \* valid - | }; - | - | l2: - | either { varMapped[10] := 0; } \* invalid - | or { varMapped := 10; }; \* valid - | - | l3: - | if (varMapped[10] = 10) { \* invalid - | someLocal := varMapped[10]; \* invalid - | } else { - | nonMapped[30] := 20; \* valid - | fnMapped := 12; \* invalid - | } - | } - | - | variables n = 0, v = 0, f = <<0>>; - | - | process (P1 = 42) == instance MyArchetype(ref n, ref v, ref f) - | mapping v via SomeMacro - | mapping f[_] via OtherMacro; - | } - |*) - |\* BEGIN TRANSLATION - |==== - |""".stripMargin -> List( - new InvalidArchetypeResourceUsageIssue( - assign(fncall(idexp("varMapped"), num(10)), num(0)), - false), - new InvalidArchetypeResourceUsageIssue( - ifS( - binop("=", fncall(idexp("varMapped"), num(10)), num(10)), - List[PlusCalStatement]( - assign(idexp("someLocal"), fncall(idexp("varMapped"), num(10)))).asJava, - List[PlusCalStatement]( - assign(fncall(idexp("nonMapped"), num(30)), num(20)), - assign(idexp("fnMapped"), num(12))).asJava), - false), - new InvalidArchetypeResourceUsageIssue( - assign(idexp("someLocal"), fncall(idexp("varMapped"), num(10))), - false), - new InvalidArchetypeResourceUsageIssue( - assign(fncall(idexp("nonMapped"), num(30)), num(20)), - false), - new InvalidArchetypeResourceUsageIssue( - assign(idexp("fnMapped"), num(12)), - true)) - } - -} diff --git a/test/pgo/trans/passes/validation/ValidationPassTest.scala b/test/pgo/trans/passes/validation/ValidationPassTest.scala deleted file mode 100644 index 7cfe54e69..000000000 --- a/test/pgo/trans/passes/validation/ValidationPassTest.scala +++ /dev/null @@ -1,490 +0,0 @@ -package pgo.trans.passes.validation - -import org.scalactic.source.Position -import org.scalatest.funsuite.AnyFunSuite -import pgo.TestingUtils -import pgo.errors.{Issue, TopLevelIssueContext} -import pgo.model.pcal.PlusCalBuilder._ -import pgo.model.tla.TLABuilder._ - -import java.util.Collections -import scala.jdk.CollectionConverters._ - -class ValidationPassTest extends AnyFunSuite { - def check(tag: String)(pair: (String,List[Issue]))(implicit pos: Position): Unit = - test(tag) { - val (specStr, expectedIssues) = pair - val ctx = new TopLevelIssueContext() - - val (_, _, spec) = TestingUtils.parseMPCalFromString(specStr) - - ValidationPass.perform(ctx, spec) - - assert(ctx.getIssues.asScala.toList == expectedIssues) - } - - check("no issues") { - """ - |---- MODULE NoIssues ---- - |EXTENDS Sequences, FiniteSets, Integers - |(* - |--mpcal NoIssues { - | procedure MyProcedure(y) { - | l2: print(3 - 3); - | if (TRUE) { - | y := 20; - | } else { - | y := 10; - | } - | } - | - | archetype MyArchetype(ref x) { - | l1: print(1 + 1); - | l2: either { x := 10 } or { x := 20 }; - | } - | - | process (MyProcess = 32) { - | l3: print(2 * 2); - | } - |} - |*) - |\* BEGIN TRANSLATION - |==== - |""".stripMargin -> Nil - } - - check("archetype no first label") { - """ - |---- MODULE ArchetypeNoFirstLabel ---- - |EXTENDS Sequences, FiniteSets, Integers - |(* - |--mpcal ArchetypeNoFirstLabel { - | archetype MyArchetype() { - | print(1 + 1); - | } - |} - |*) - |\* BEGIN TRANSLATION - |==== - |""".stripMargin -> List( - new MissingLabelIssue(printS(binop("+", num(1), num(1))))) - } - - check("procedure no first label") { - """ - |---- MODULE ProcedureNoFirstLabel ---- - |EXTENDS Sequences, FiniteSets, Integers - |(* - |--mpcal ProcedureNoFirstLabel { - | procedure MyProcess() { - | print(1 + 1); - | } - |} - |*) - |\* BEGIN TRANSLATION - |==== - |""".stripMargin -> List( - new MissingLabelIssue(printS(binop("+", num(1), num(1))))) - } - - check("process no first label") { - """ - |---- MODULE ArchetypeNoFirstLabel ---- - |EXTENDS Sequences, FiniteSets, Integers - |(* - |--mpcal ProcessNoFirstLabel { - | process (MyProcess = 32) { - | print(1 + 1); - | } - |} - |*) - |\* BEGIN TRANSLATION - |==== - |""".stripMargin -> List( - new MissingLabelIssue(printS(binop("+", num(1), num(1))))) - } - - check("more than one issue") { - """ - |---- MODULE MoreThanOneIssue ---- - |EXTENDS Sequences, FiniteSets, Integers - |(* - |--mpcal MoreThanOneIssue { - | - | procedure ValidProcedure() { - | l2: print(3 - 3); - | } - | - | procedure InvalidProcedure() { - | print("invalid procedure!"); - | } - | - | archetype ValidArchetype() { - | l1: print(1 + 1); - | } - | - | archetype InvalidArchetype() { - | print("invalid archetype!"); - | } - | - | process (ValidProcess = 32) { - | l3: print(2 * 2); - | } - | - | process (InvalidProcess = 64) { - | print("invalid process!"); - | } - |} - |*) - |\* BEGIN TRANSLATION - |==== - |""".stripMargin -> List( - new MissingLabelIssue(printS(str("invalid archetype!"))), - new MissingLabelIssue(printS(str("invalid procedure!"))), - new MissingLabelIssue(printS(str("invalid process!")))) - } - - check("while labels") { - """ - |---- MODULE WhileLabels ---- - |EXTENDS Sequences, FiniteSets, Integers - |(* - |--mpcal WhileLabels { - | procedure CorrectProcedure() { - | l2: print "procedure"; - | l3: while (FALSE) { print(3 - 3) }; (* all good *) - | } - | - | archetype IncorrectArchetype() { - | l1: print "first label"; - | while (TRUE) { print "hello" }; (* missing label here *) - | } - | - | process (IncorrectProcess = 32) { - | while (10 < 20) { print(2 * 2) }; (* missing label (first statement) *) - | } - |} - |*) - |\* BEGIN TRANSLATION - |==== - |""".stripMargin -> List( - new MissingLabelIssue( - whileS( - bool(true), - Collections.singletonList(printS(str("hello"))))), - new MissingLabelIssue( - whileS( - binop("<", num(10), num(20)), - Collections.singletonList(printS(binop("*", num(2), num(2))))))) - } - - check("call labeling rules") { - """ - |---- MODULE CallLabelingRules ---- - |EXTENDS Sequences, FiniteSets, Integers - |(* - |--mpcal CallLabelingRules { - | procedure MyProcedure() { - | l2: print "procedure"; - | call SomeProcedure(); - | return; (* no label required *) - | } - | - | archetype MyArchetype() { - | l1: print "first label"; - | call MyProcedure(); - | call MyProcedure(); (* missing label *) - | } - | - | process (MyProcess = 32) - | variables x; - | { - | l3: print "process"; - | call MyProcedure(); - | goto l3; (* no label required *) - | l4: print "next label"; - | call MyProcedure(); - | x := 10; (* missing label *) - | } - |} - |*) - |\* BEGIN TRANSLATION - |==== - |""".stripMargin -> List( - new MissingLabelIssue(call("MyProcedure")), - new MissingLabelIssue(assign(idexp("x"), num(10)))) - } - - check("return goto labeling rules") { - """ - |---- MODULE ReturnGotoLabelingRules ---- - |EXTENDS Sequences, FiniteSets, Integers - |(* - |--mpcal ReturnGotoLabelingRules { - | - | procedure MyProcedure() { - | l2: print "procedure"; - | return; - | goto l2; (* missing label *) - | } - | - | archetype MyArchetype() { - | l1: print "first label"; - | goto l1; - | print "needs label"; (* missing label *) - | } - | - | process (MyProcess = 32) - | variables x; - | { - | l3: print "process"; - | goto l3; - | x := 10; (* missing label *) - | } - |} - |*) - |\* BEGIN TRANSLATION - |==== - |""".stripMargin -> List( - new MissingLabelIssue(printS(str("needs label"))), - new MissingLabelIssue(gotoS("l2")), - new MissingLabelIssue(assign(idexp("x"), num(10)))) - } - - check("if either labeling rules") { - """ - |---- MODULE IfEitherLabelingRules ---- - |EXTENDS Sequences, FiniteSets, Integers - |(* - |--mpcal IfEitherLabelingRules { - | - | procedure MyProcedure() - | variables v; - | { - | l2: print "procedure"; - | either { v := 10 } or { return }; - | goto l2; (* missing label *) - | } - | - | archetype MyArchetype() { - | l1: print "first label"; - | if (TRUE) { - | print "true"; - | } else if (TRUE) { - | call MyProcedure(); - | }; - | - | print "needs label"; (* missing label *) - | } - | - | process (MyProcess = 32) - | variables x, y; - | { - | l3: print "process"; - | either { x := 0 } or { goto l3 }; - | l4: print "all good"; - | - | either { goto l4 } or { skip }; - | x := 50; (* missing label *) - | - | l5: if (TRUE) { - | l6: print "label"; - | }; - | y := 20; (* missing label *) - | } - |} - |*) - |\* BEGIN TRANSLATION - |==== - |""".stripMargin -> List( - new MissingLabelIssue(printS(str("needs label"))), - new MissingLabelIssue(gotoS("l2")), - new MissingLabelIssue(assign(idexp("x"), num(50))), - new MissingLabelIssue(assign(idexp("y"), num(20)))) - } - - check("macro rules") { - """ - |---- MODULE MacroRules ---- - |EXTENDS Sequences, FiniteSets, Integers - |(* - |--mpcal MacroRules { - | macro ValidMacro() { - | print(1 + 1); - | skip; \* x := 10; \* TODO: how to scope macros? - | } - | - | macro InvalidMacro() { - | either { skip } or { l1: print(10) }; (* invalid *) - | l2: print(20); (* invalid *) - | } - |} - |*) - |\* BEGIN TRANSLATION - |==== - |""".stripMargin -> List( - new LabelNotAllowedIssue(labeled(label("l1"), printS(num(10)))), - new LabelNotAllowedIssue(labeled(label("l2"), printS(num(20))))) - } - - check("with rules") { - """ - |---- MODULE WithRules ---- - |EXTENDS Sequences, FiniteSets, Integers - |(* - |--mpcal WithRules { - | macro MacroWith() { - | print(1 + 1); - | with (x = 10) { - | print x; - | m1: x := 20; (* invalid *) - | }; - | m2: print(20); (* invalid *) - | } - | - | procedure ProcedureWith() { - | l1: with (x = 10) { - | l2: print x; (* invalid *) - | } - | } - |} - |*) - |\* BEGIN TRANSLATION - |==== - |""".stripMargin -> List( - new LabelNotAllowedIssue(labeled(label("m1"), assign(idexp("x"), num(20)))), - new LabelNotAllowedIssue(labeled(label("m2"), printS(num(20)))), - new LabelNotAllowedIssue(labeled(label("l2"), printS(idexp("x"))))) - } - - check("assignment rules") { - """ - |---- MODULE AssignmentRules ---- - |EXTENDS Sequences, FiniteSets, Integers - |(* - |--mpcal AssignmentRules { - | - | procedure MyProcedure(x, y) - | variables x, y; - | { - | p: either { y := 10 } or { skip }; - | y := 11; (* missing label *) - | p2: y := 20; - | x := y || y := x; (* swap x and y: invalid *) - | } - | - | archetype MyArchetype(ref x) - | variables x; - | { - | a1: x := 10; - | x := 11; (* missing label *) - | } - | - | process (MyProcess = 23) - | variables n; - | { - | l1: n := 2; - | l2: while (n < 10) { - | n := 12; - | if (n = 20) { - | n := 100; (* missing label *) - | } - | }; - | n := 32; (* label not missing *) - | - | l3: if (n = 32) { - | n := 0; - | }; - | n := 12; (* missing label *) - | } - |} - |*) - |\* BEGIN TRANSLATION - |==== - |""".stripMargin -> List( - new MissingLabelIssue(assign(idexp("x"), num(11))), - new MissingLabelIssue(assign(idexp("y"), num(11))), - new MissingLabelIssue(assign(idexp("x"), idexp("y"), idexp("y"), idexp("x"))), - new MissingLabelIssue(assign(idexp("n"), num(100))), - new MissingLabelIssue(assign(idexp("n"), num(12)))) - } - - check("reserved labels") { - """ - |---- MODULE ReservedLabels ---- - |EXTENDS Sequences, FiniteSets, Integers - |(* - |--mpcal ReservedLabels { - | procedure MyProcedure(y) { - | p: either { p1: y := 20 } or { Error: skip }; (* reserved *) - | } - | - | archetype MyArchetype(ref x) { - | Done: x := 10; (* reserved *) - | done: x := 30; (* no problem *) - | } - |} - |*) - |\* BEGIN TRANSLATION - |==== - |""".stripMargin -> List( - new ReservedLabelNameIssue(labeled(label("Done"), assign(idexp("x"), num(10)))), - new ReservedLabelNameIssue(labeled(label("Error"), skip()))) - } - - check("mapping with labels") { - """ - |---- MODULE MappingWithLabels ---- - |EXTENDS Sequences, FiniteSets, Integers - |(* - |--mpcal MappingWithLabels { - | mapping macro ContainsLabels { - | read { - | r: yield $variable - | } - | write { - | if ($variable > 10) { - | w: yield $value; - | } - | } - | } - |} - |*) - |\* BEGIN TRANSLATION - |==== - |""".stripMargin -> List( - new StatementNotAllowedIssue(labeled(label("r"), `yield`(DOLLAR_VARIABLE))), - new StatementNotAllowedIssue(labeled(label("w"), `yield`(DOLLAR_VALUE)))) - } - - check("mapping macro with call goto") { - """ - |---- MODULE MappingMacroWithCallGoto ---- - |EXTENDS Sequences, FiniteSets, Integers - |(* - |--mpcal MappingMacroWithCallGoto { - | mapping macro InvalidStatements { - | read { - | await Len($variable) = 0; - | if (TRUE) { - | call YesProcedure(); - | }; - | call NoProcedure(); - | yield 0; - | } - | write { - | either { yield $value } - | or { goto l1 }; - | } - | } - |} - |*) - |\* BEGIN TRANSLATION - |==== - |""".stripMargin -> List( - new StatementNotAllowedIssue(call("YesProcedure")), - new StatementNotAllowedIssue(call("NoProcedure")), - new StatementNotAllowedIssue(gotoS("l1"))) - } - -} diff --git a/test/tla/tokens/AltBitProtocol.tokens b/test/tla/tokens/AltBitProtocol.tokens deleted file mode 100644 index bde2e7c89..000000000 --- a/test/tla/tokens/AltBitProtocol.tokens +++ /dev/null @@ -1,590 +0,0 @@ -[str |-> "---------------------", type |-> BUILTIN, col |-> 1, source |->[(1, 1)-(1, 22)], beginSub |-> [], endSub |-> []] -[str |-> "MODULE", type |-> BUILTIN, col |-> 23, source |->[(1, 23)-(1, 29)], beginSub |-> [], endSub |-> []] -[str |-> "AltBitProtocol", type |-> IDENT, col |-> 30, source |->[(1, 30)-(1, 44)], beginSub |-> [], endSub |-> []] -[str |-> "----------------------", type |-> BUILTIN, col |-> 46, source |->[(1, 46)-(1, 68)], beginSub |-> [], endSub |-> []] -null -[str |-> "EXTENDS", type |-> BUILTIN, col |-> 1, source |->[(2, 1)-(2, 8)], beginSub |-> [], endSub |-> []] -[str |-> "Naturals", type |-> IDENT, col |-> 9, source |->[(2, 9)-(2, 17)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 17, source |->[(2, 17)-(2, 18)], beginSub |-> [], endSub |-> []] -[str |-> "Sequences", type |-> IDENT, col |-> 19, source |->[(2, 19)-(2, 28)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 28, source |->[(2, 28)-(2, 29)], beginSub |-> [], endSub |-> []] -[str |-> "TLC", type |-> IDENT, col |-> 30, source |->[(2, 30)-(2, 33)], beginSub |-> [], endSub |-> []] -null -[str |-> "CONSTANT", type |-> BUILTIN, col |-> 1, source |->[(3, 1)-(3, 9)], beginSub |-> [], endSub |-> []] -[str |-> "Msg", type |-> IDENT, col |-> 10, source |->[(3, 10)-(3, 13)], beginSub |-> [], endSub |-> []] -null -null -null -null -null -null -null -[str |-> "Remove", type |-> IDENT, col |-> 1, source |->[(10, 1)-(10, 7)], beginSub |-> [], endSub |-> []] -[str |-> "(", type |-> BUILTIN, col |-> 7, source |->[(10, 7)-(10, 8)], beginSub |-> [], endSub |-> []] -[str |-> "i", type |-> IDENT, col |-> 8, source |->[(10, 8)-(10, 9)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 9, source |->[(10, 9)-(10, 10)], beginSub |-> [], endSub |-> []] -[str |-> "seq", type |-> IDENT, col |-> 11, source |->[(10, 11)-(10, 14)], beginSub |-> [], endSub |-> []] -[str |-> ")", type |-> BUILTIN, col |-> 14, source |->[(10, 14)-(10, 15)], beginSub |-> [], endSub |-> []] -[str |-> "==", type |-> BUILTIN, col |-> 16, source |->[(10, 16)-(10, 18)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 19, source |->[(10, 19)-(10, 20)], beginSub |-> [], endSub |-> []] -[str |-> "j", type |-> IDENT, col |-> 20, source |->[(10, 20)-(10, 21)], beginSub |-> [], endSub |-> []] -[str |-> "\in", type |-> BUILTIN, col |-> 22, source |->[(10, 22)-(10, 25)], beginSub |-> [], endSub |-> []] -[str |-> "1", type |-> NUMBER, col |-> 26, source |->[(10, 26)-(10, 27)], beginSub |-> [], endSub |-> []] -[str |-> "..", type |-> BUILTIN, col |-> 27, source |->[(10, 27)-(10, 29)], beginSub |-> [], endSub |-> []] -[str |-> "(", type |-> BUILTIN, col |-> 29, source |->[(10, 29)-(10, 30)], beginSub |-> [], endSub |-> []] -[str |-> "Len", type |-> IDENT, col |-> 30, source |->[(10, 30)-(10, 33)], beginSub |-> [], endSub |-> []] -[str |-> "(", type |-> BUILTIN, col |-> 33, source |->[(10, 33)-(10, 34)], beginSub |-> [], endSub |-> []] -[str |-> "seq", type |-> IDENT, col |-> 34, source |->[(10, 34)-(10, 37)], beginSub |-> [], endSub |-> []] -[str |-> ")", type |-> BUILTIN, col |-> 37, source |->[(10, 37)-(10, 38)], beginSub |-> [], endSub |-> []] -[str |-> "-", type |-> BUILTIN, col |-> 38, source |->[(10, 38)-(10, 39)], beginSub |-> [], endSub |-> []] -[str |-> "1", type |-> NUMBER, col |-> 39, source |->[(10, 39)-(10, 40)], beginSub |-> [], endSub |-> []] -[str |-> ")", type |-> BUILTIN, col |-> 40, source |->[(10, 40)-(10, 41)], beginSub |-> [], endSub |-> []] -[str |-> "|->", type |-> BUILTIN, col |-> 42, source |->[(10, 42)-(10, 45)], beginSub |-> [], endSub |-> []] -[str |-> "IF", type |-> BUILTIN, col |-> 46, source |->[(10, 46)-(10, 48)], beginSub |-> [], endSub |-> []] -[str |-> "j", type |-> IDENT, col |-> 49, source |->[(10, 49)-(10, 50)], beginSub |-> [], endSub |-> []] -[str |-> "<", type |-> BUILTIN, col |-> 51, source |->[(10, 51)-(10, 52)], beginSub |-> [], endSub |-> []] -[str |-> "i", type |-> IDENT, col |-> 53, source |->[(10, 53)-(10, 54)], beginSub |-> [], endSub |-> []] -[str |-> "THEN", type |-> BUILTIN, col |-> 55, source |->[(10, 55)-(10, 59)], beginSub |-> [], endSub |-> []] -[str |-> "seq", type |-> IDENT, col |-> 60, source |->[(10, 60)-(10, 63)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 63, source |->[(10, 63)-(10, 64)], beginSub |-> [], endSub |-> []] -[str |-> "j", type |-> IDENT, col |-> 64, source |->[(10, 64)-(10, 65)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 65, source |->[(10, 65)-(10, 66)], beginSub |-> [], endSub |-> []] -[str |-> "ELSE", type |-> BUILTIN, col |-> 67, source |->[(10, 67)-(10, 71)], beginSub |-> [], endSub |-> []] -[str |-> "seq", type |-> IDENT, col |-> 72, source |->[(10, 72)-(10, 75)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 75, source |->[(10, 75)-(10, 76)], beginSub |-> [], endSub |-> []] -[str |-> "j", type |-> IDENT, col |-> 76, source |->[(10, 76)-(10, 77)], beginSub |-> [], endSub |-> []] -[str |-> "+", type |-> BUILTIN, col |-> 77, source |->[(10, 77)-(10, 78)], beginSub |-> [], endSub |-> []] -[str |-> "1", type |-> NUMBER, col |-> 78, source |->[(10, 78)-(10, 79)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 79, source |->[(10, 79)-(10, 80)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 80, source |->[(10, 80)-(10, 81)], beginSub |-> [], endSub |-> []] -null -null -null -null -[str |-> "CONSTANT", type |-> BUILTIN, col |-> 1, source |->[(80, 1)-(80, 9)], beginSub |-> [], endSub |-> []] -[str |-> "defaultInitValue", type |-> IDENT, col |-> 10, source |->[(80, 10)-(80, 26)], beginSub |-> [], endSub |-> []] -null -[str |-> "VARIABLES", type |-> BUILTIN, col |-> 1, source |->[(81, 1)-(81, 10)], beginSub |-> [], endSub |-> []] -[str |-> "input", type |-> IDENT, col |-> 11, source |->[(81, 11)-(81, 16)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 16, source |->[(81, 16)-(81, 17)], beginSub |-> [], endSub |-> []] -[str |-> "output", type |-> IDENT, col |-> 18, source |->[(81, 18)-(81, 24)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 24, source |->[(81, 24)-(81, 25)], beginSub |-> [], endSub |-> []] -[str |-> "msgChan", type |-> IDENT, col |-> 26, source |->[(81, 26)-(81, 33)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 33, source |->[(81, 33)-(81, 34)], beginSub |-> [], endSub |-> []] -[str |-> "ackChan", type |-> IDENT, col |-> 35, source |->[(81, 35)-(81, 42)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 42, source |->[(81, 42)-(81, 43)], beginSub |-> [], endSub |-> []] -[str |-> "newChan", type |-> IDENT, col |-> 44, source |->[(81, 44)-(81, 51)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 51, source |->[(81, 51)-(81, 52)], beginSub |-> [], endSub |-> []] -[str |-> "next", type |-> IDENT, col |-> 53, source |->[(81, 53)-(81, 57)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 57, source |->[(81, 57)-(81, 58)], beginSub |-> [], endSub |-> []] -[str |-> "sbit", type |-> IDENT, col |-> 59, source |->[(81, 59)-(81, 63)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 63, source |->[(81, 63)-(81, 64)], beginSub |-> [], endSub |-> []] -[str |-> "ack", type |-> IDENT, col |-> 65, source |->[(81, 65)-(81, 68)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 68, source |->[(81, 68)-(81, 69)], beginSub |-> [], endSub |-> []] -[str |-> "rbit", type |-> IDENT, col |-> 70, source |->[(81, 70)-(81, 74)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 74, source |->[(81, 74)-(81, 75)], beginSub |-> [], endSub |-> []] -null -[str |-> "msg", type |-> IDENT, col |-> 11, source |->[(82, 11)-(82, 14)], beginSub |-> [], endSub |-> []] -null -null -[str |-> "vars", type |-> IDENT, col |-> 1, source |->[(84, 1)-(84, 5)], beginSub |-> [], endSub |-> []] -[str |-> "==", type |-> BUILTIN, col |-> 6, source |->[(84, 6)-(84, 8)], beginSub |-> [], endSub |-> []] -[str |-> "<<", type |-> BUILTIN, col |-> 9, source |->[(84, 9)-(84, 11)], beginSub |-> [], endSub |-> []] -[str |-> "input", type |-> IDENT, col |-> 12, source |->[(84, 12)-(84, 17)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 17, source |->[(84, 17)-(84, 18)], beginSub |-> [], endSub |-> []] -[str |-> "output", type |-> IDENT, col |-> 19, source |->[(84, 19)-(84, 25)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 25, source |->[(84, 25)-(84, 26)], beginSub |-> [], endSub |-> []] -[str |-> "msgChan", type |-> IDENT, col |-> 27, source |->[(84, 27)-(84, 34)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 34, source |->[(84, 34)-(84, 35)], beginSub |-> [], endSub |-> []] -[str |-> "ackChan", type |-> IDENT, col |-> 36, source |->[(84, 36)-(84, 43)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 43, source |->[(84, 43)-(84, 44)], beginSub |-> [], endSub |-> []] -[str |-> "newChan", type |-> IDENT, col |-> 45, source |->[(84, 45)-(84, 52)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 52, source |->[(84, 52)-(84, 53)], beginSub |-> [], endSub |-> []] -[str |-> "next", type |-> IDENT, col |-> 54, source |->[(84, 54)-(84, 58)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 58, source |->[(84, 58)-(84, 59)], beginSub |-> [], endSub |-> []] -[str |-> "sbit", type |-> IDENT, col |-> 60, source |->[(84, 60)-(84, 64)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 64, source |->[(84, 64)-(84, 65)], beginSub |-> [], endSub |-> []] -[str |-> "ack", type |-> IDENT, col |-> 66, source |->[(84, 66)-(84, 69)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 69, source |->[(84, 69)-(84, 70)], beginSub |-> [], endSub |-> []] -[str |-> "rbit", type |-> IDENT, col |-> 71, source |->[(84, 71)-(84, 75)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 75, source |->[(84, 75)-(84, 76)], beginSub |-> [], endSub |-> []] -null -[str |-> "msg", type |-> IDENT, col |-> 12, source |->[(85, 12)-(85, 15)], beginSub |-> [], endSub |-> []] -[str |-> ">>", type |-> BUILTIN, col |-> 16, source |->[(85, 16)-(85, 18)], beginSub |-> [], endSub |-> []] -null -null -[str |-> "ProcSet", type |-> IDENT, col |-> 1, source |->[(87, 1)-(87, 8)], beginSub |-> [], endSub |-> []] -[str |-> "==", type |-> BUILTIN, col |-> 9, source |->[(87, 9)-(87, 11)], beginSub |-> [], endSub |-> []] -[str |-> "{", type |-> BUILTIN, col |-> 12, source |->[(87, 12)-(87, 13)], beginSub |-> [], endSub |-> []] -[str |-> "S", type |-> STRING, col |-> 13, source |->[(87, 13)-(87, 14)], beginSub |-> [], endSub |-> []] -[str |-> "}", type |-> BUILTIN, col |-> 16, source |->[(87, 16)-(87, 17)], beginSub |-> [], endSub |-> []] -[str |-> "\cup", type |-> BUILTIN, col |-> 18, source |->[(87, 18)-(87, 22)], beginSub |-> [], endSub |-> []] -[str |-> "{", type |-> BUILTIN, col |-> 23, source |->[(87, 23)-(87, 24)], beginSub |-> [], endSub |-> []] -[str |-> "R", type |-> STRING, col |-> 24, source |->[(87, 24)-(87, 25)], beginSub |-> [], endSub |-> []] -[str |-> "}", type |-> BUILTIN, col |-> 27, source |->[(87, 27)-(87, 28)], beginSub |-> [], endSub |-> []] -[str |-> "\cup", type |-> BUILTIN, col |-> 29, source |->[(87, 29)-(87, 33)], beginSub |-> [], endSub |-> []] -[str |-> "{", type |-> BUILTIN, col |-> 34, source |->[(87, 34)-(87, 35)], beginSub |-> [], endSub |-> []] -[str |-> "L", type |-> STRING, col |-> 35, source |->[(87, 35)-(87, 36)], beginSub |-> [], endSub |-> []] -[str |-> "}", type |-> BUILTIN, col |-> 38, source |->[(87, 38)-(87, 39)], beginSub |-> [], endSub |-> []] -null -null -[str |-> "Init", type |-> IDENT, col |-> 1, source |->[(89, 1)-(89, 5)], beginSub |-> [], endSub |-> []] -[str |-> "==", type |-> BUILTIN, col |-> 6, source |->[(89, 6)-(89, 8)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 9, source |->[(90, 9)-(90, 11)], beginSub |-> [], endSub |-> []] -[str |-> "input", type |-> IDENT, col |-> 12, source |->[(90, 12)-(90, 17)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 18, source |->[(90, 18)-(90, 19)], beginSub |-> [], endSub |-> []] -[str |-> "<<", type |-> BUILTIN, col |-> 20, source |->[(90, 20)-(90, 22)], beginSub |-> [], endSub |-> []] -[str |-> ">>", type |-> BUILTIN, col |-> 22, source |->[(90, 22)-(90, 24)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 9, source |->[(91, 9)-(91, 11)], beginSub |-> [], endSub |-> []] -[str |-> "output", type |-> IDENT, col |-> 12, source |->[(91, 12)-(91, 18)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 19, source |->[(91, 19)-(91, 20)], beginSub |-> [], endSub |-> []] -[str |-> "<<", type |-> BUILTIN, col |-> 21, source |->[(91, 21)-(91, 23)], beginSub |-> [], endSub |-> []] -[str |-> ">>", type |-> BUILTIN, col |-> 23, source |->[(91, 23)-(91, 25)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 9, source |->[(92, 9)-(92, 11)], beginSub |-> [], endSub |-> []] -[str |-> "msgChan", type |-> IDENT, col |-> 12, source |->[(92, 12)-(92, 19)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 20, source |->[(92, 20)-(92, 21)], beginSub |-> [], endSub |-> []] -[str |-> "<<", type |-> BUILTIN, col |-> 22, source |->[(92, 22)-(92, 24)], beginSub |-> [], endSub |-> []] -[str |-> ">>", type |-> BUILTIN, col |-> 24, source |->[(92, 24)-(92, 26)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 9, source |->[(93, 9)-(93, 11)], beginSub |-> [], endSub |-> []] -[str |-> "ackChan", type |-> IDENT, col |-> 12, source |->[(93, 12)-(93, 19)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 20, source |->[(93, 20)-(93, 21)], beginSub |-> [], endSub |-> []] -[str |-> "<<", type |-> BUILTIN, col |-> 22, source |->[(93, 22)-(93, 24)], beginSub |-> [], endSub |-> []] -[str |-> ">>", type |-> BUILTIN, col |-> 24, source |->[(93, 24)-(93, 26)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 9, source |->[(94, 9)-(94, 11)], beginSub |-> [], endSub |-> []] -[str |-> "newChan", type |-> IDENT, col |-> 12, source |->[(94, 12)-(94, 19)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 20, source |->[(94, 20)-(94, 21)], beginSub |-> [], endSub |-> []] -[str |-> "<<", type |-> BUILTIN, col |-> 22, source |->[(94, 22)-(94, 24)], beginSub |-> [], endSub |-> []] -[str |-> ">>", type |-> BUILTIN, col |-> 24, source |->[(94, 24)-(94, 26)], beginSub |-> [], endSub |-> []] -null -null -[str |-> "/\", type |-> BUILTIN, col |-> 9, source |->[(96, 9)-(96, 11)], beginSub |-> [], endSub |-> []] -[str |-> "next", type |-> IDENT, col |-> 12, source |->[(96, 12)-(96, 16)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 17, source |->[(96, 17)-(96, 18)], beginSub |-> [], endSub |-> []] -[str |-> "1", type |-> NUMBER, col |-> 19, source |->[(96, 19)-(96, 20)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 9, source |->[(97, 9)-(97, 11)], beginSub |-> [], endSub |-> []] -[str |-> "sbit", type |-> IDENT, col |-> 12, source |->[(97, 12)-(97, 16)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 17, source |->[(97, 17)-(97, 18)], beginSub |-> [], endSub |-> []] -[str |-> "0", type |-> NUMBER, col |-> 19, source |->[(97, 19)-(97, 20)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 9, source |->[(98, 9)-(98, 11)], beginSub |-> [], endSub |-> []] -[str |-> "ack", type |-> IDENT, col |-> 12, source |->[(98, 12)-(98, 15)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 16, source |->[(98, 16)-(98, 17)], beginSub |-> [], endSub |-> []] -[str |-> "defaultInitValue", type |-> IDENT, col |-> 18, source |->[(98, 18)-(98, 34)], beginSub |-> [], endSub |-> []] -null -null -[str |-> "/\", type |-> BUILTIN, col |-> 9, source |->[(100, 9)-(100, 11)], beginSub |-> [], endSub |-> []] -[str |-> "rbit", type |-> IDENT, col |-> 12, source |->[(100, 12)-(100, 16)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 17, source |->[(100, 17)-(100, 18)], beginSub |-> [], endSub |-> []] -[str |-> "1", type |-> NUMBER, col |-> 19, source |->[(100, 19)-(100, 20)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 9, source |->[(101, 9)-(101, 11)], beginSub |-> [], endSub |-> []] -[str |-> "msg", type |-> IDENT, col |-> 12, source |->[(101, 12)-(101, 15)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 16, source |->[(101, 16)-(101, 17)], beginSub |-> [], endSub |-> []] -[str |-> "defaultInitValue", type |-> IDENT, col |-> 18, source |->[(101, 18)-(101, 34)], beginSub |-> [], endSub |-> []] -null -null -[str |-> "Sender", type |-> IDENT, col |-> 1, source |->[(103, 1)-(103, 7)], beginSub |-> [], endSub |-> []] -[str |-> "==", type |-> BUILTIN, col |-> 8, source |->[(103, 8)-(103, 10)], beginSub |-> [], endSub |-> []] -[str |-> "/\", type |-> BUILTIN, col |-> 11, source |->[(103, 11)-(103, 13)], beginSub |-> [], endSub |-> []] -[str |-> "\/", type |-> BUILTIN, col |-> 14, source |->[(103, 14)-(103, 16)], beginSub |-> [], endSub |-> []] -[str |-> "/\", type |-> BUILTIN, col |-> 17, source |->[(103, 17)-(103, 19)], beginSub |-> [], endSub |-> []] -[str |-> "\E", type |-> BUILTIN, col |-> 20, source |->[(103, 20)-(103, 22)], beginSub |-> [], endSub |-> []] -[str |-> "m", type |-> IDENT, col |-> 23, source |->[(103, 23)-(103, 24)], beginSub |-> [], endSub |-> []] -[str |-> "\in", type |-> BUILTIN, col |-> 25, source |->[(103, 25)-(103, 28)], beginSub |-> [], endSub |-> []] -[str |-> "Msg", type |-> IDENT, col |-> 29, source |->[(103, 29)-(103, 32)], beginSub |-> [], endSub |-> []] -[str |-> ":", type |-> BUILTIN, col |-> 32, source |->[(103, 32)-(103, 33)], beginSub |-> [], endSub |-> []] -null -[str |-> "input", type |-> IDENT, col |-> 22, source |->[(104, 22)-(104, 27)], beginSub |-> [], endSub |-> []] -[str |-> "'", type |-> BUILTIN, col |-> 27, source |->[(104, 27)-(104, 28)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 29, source |->[(104, 29)-(104, 30)], beginSub |-> [], endSub |-> []] -[str |-> "Append", type |-> IDENT, col |-> 31, source |->[(104, 31)-(104, 37)], beginSub |-> [], endSub |-> []] -[str |-> "(", type |-> BUILTIN, col |-> 37, source |->[(104, 37)-(104, 38)], beginSub |-> [], endSub |-> []] -[str |-> "input", type |-> IDENT, col |-> 38, source |->[(104, 38)-(104, 43)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 43, source |->[(104, 43)-(104, 44)], beginSub |-> [], endSub |-> []] -[str |-> "m", type |-> IDENT, col |-> 45, source |->[(104, 45)-(104, 46)], beginSub |-> [], endSub |-> []] -[str |-> ")", type |-> BUILTIN, col |-> 46, source |->[(104, 46)-(104, 47)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 17, source |->[(105, 17)-(105, 19)], beginSub |-> [], endSub |-> []] -[str |-> "UNCHANGED", type |-> BUILTIN, col |-> 20, source |->[(105, 20)-(105, 29)], beginSub |-> [], endSub |-> []] -[str |-> "<<", type |-> BUILTIN, col |-> 30, source |->[(105, 30)-(105, 32)], beginSub |-> [], endSub |-> []] -[str |-> "msgChan", type |-> IDENT, col |-> 32, source |->[(105, 32)-(105, 39)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 39, source |->[(105, 39)-(105, 40)], beginSub |-> [], endSub |-> []] -[str |-> "ackChan", type |-> IDENT, col |-> 41, source |->[(105, 41)-(105, 48)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 48, source |->[(105, 48)-(105, 49)], beginSub |-> [], endSub |-> []] -[str |-> "next", type |-> IDENT, col |-> 50, source |->[(105, 50)-(105, 54)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 54, source |->[(105, 54)-(105, 55)], beginSub |-> [], endSub |-> []] -[str |-> "sbit", type |-> IDENT, col |-> 56, source |->[(105, 56)-(105, 60)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 60, source |->[(105, 60)-(105, 61)], beginSub |-> [], endSub |-> []] -[str |-> "ack", type |-> IDENT, col |-> 62, source |->[(105, 62)-(105, 65)], beginSub |-> [], endSub |-> []] -[str |-> ">>", type |-> BUILTIN, col |-> 65, source |->[(105, 65)-(105, 67)], beginSub |-> [], endSub |-> []] -null -[str |-> "\/", type |-> BUILTIN, col |-> 14, source |->[(106, 14)-(106, 16)], beginSub |-> [], endSub |-> []] -[str |-> "/\", type |-> BUILTIN, col |-> 17, source |->[(106, 17)-(106, 19)], beginSub |-> [], endSub |-> []] -[str |-> "next", type |-> IDENT, col |-> 20, source |->[(106, 20)-(106, 24)], beginSub |-> [], endSub |-> []] -[str |-> "<", type |-> BUILTIN, col |-> 25, source |->[(106, 25)-(106, 26)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 26, source |->[(106, 26)-(106, 27)], beginSub |-> [], endSub |-> []] -[str |-> "Len", type |-> IDENT, col |-> 28, source |->[(106, 28)-(106, 31)], beginSub |-> [], endSub |-> []] -[str |-> "(", type |-> BUILTIN, col |-> 31, source |->[(106, 31)-(106, 32)], beginSub |-> [], endSub |-> []] -[str |-> "input", type |-> IDENT, col |-> 32, source |->[(106, 32)-(106, 37)], beginSub |-> [], endSub |-> []] -[str |-> ")", type |-> BUILTIN, col |-> 37, source |->[(106, 37)-(106, 38)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 17, source |->[(107, 17)-(107, 19)], beginSub |-> [], endSub |-> []] -[str |-> "msgChan", type |-> IDENT, col |-> 20, source |->[(107, 20)-(107, 27)], beginSub |-> [], endSub |-> []] -[str |-> "'", type |-> BUILTIN, col |-> 27, source |->[(107, 27)-(107, 28)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 29, source |->[(107, 29)-(107, 30)], beginSub |-> [], endSub |-> []] -[str |-> "Append", type |-> IDENT, col |-> 31, source |->[(107, 31)-(107, 37)], beginSub |-> [], endSub |-> []] -[str |-> "(", type |-> BUILTIN, col |-> 37, source |->[(107, 37)-(107, 38)], beginSub |-> [], endSub |-> []] -[str |-> "msgChan", type |-> IDENT, col |-> 38, source |->[(107, 38)-(107, 45)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 45, source |->[(107, 45)-(107, 46)], beginSub |-> [], endSub |-> []] -[str |-> "(", type |-> BUILTIN, col |-> 47, source |->[(107, 47)-(107, 48)], beginSub |-> [], endSub |-> []] -[str |-> "<<", type |-> BUILTIN, col |-> 48, source |->[(107, 48)-(107, 50)], beginSub |-> [], endSub |-> []] -[str |-> "input", type |-> IDENT, col |-> 50, source |->[(107, 50)-(107, 55)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 55, source |->[(107, 55)-(107, 56)], beginSub |-> [], endSub |-> []] -[str |-> "next", type |-> IDENT, col |-> 56, source |->[(107, 56)-(107, 60)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 60, source |->[(107, 60)-(107, 61)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 61, source |->[(107, 61)-(107, 62)], beginSub |-> [], endSub |-> []] -[str |-> "sbit", type |-> IDENT, col |-> 63, source |->[(107, 63)-(107, 67)], beginSub |-> [], endSub |-> []] -[str |-> ">>", type |-> BUILTIN, col |-> 67, source |->[(107, 67)-(107, 69)], beginSub |-> [], endSub |-> []] -[str |-> ")", type |-> BUILTIN, col |-> 69, source |->[(107, 69)-(107, 70)], beginSub |-> [], endSub |-> []] -[str |-> ")", type |-> BUILTIN, col |-> 70, source |->[(107, 70)-(107, 71)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 17, source |->[(108, 17)-(108, 19)], beginSub |-> [], endSub |-> []] -[str |-> "UNCHANGED", type |-> BUILTIN, col |-> 20, source |->[(108, 20)-(108, 29)], beginSub |-> [], endSub |-> []] -[str |-> "<<", type |-> BUILTIN, col |-> 30, source |->[(108, 30)-(108, 32)], beginSub |-> [], endSub |-> []] -[str |-> "input", type |-> IDENT, col |-> 32, source |->[(108, 32)-(108, 37)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 37, source |->[(108, 37)-(108, 38)], beginSub |-> [], endSub |-> []] -[str |-> "ackChan", type |-> IDENT, col |-> 39, source |->[(108, 39)-(108, 46)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 46, source |->[(108, 46)-(108, 47)], beginSub |-> [], endSub |-> []] -[str |-> "next", type |-> IDENT, col |-> 48, source |->[(108, 48)-(108, 52)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 52, source |->[(108, 52)-(108, 53)], beginSub |-> [], endSub |-> []] -[str |-> "sbit", type |-> IDENT, col |-> 54, source |->[(108, 54)-(108, 58)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 58, source |->[(108, 58)-(108, 59)], beginSub |-> [], endSub |-> []] -[str |-> "ack", type |-> IDENT, col |-> 60, source |->[(108, 60)-(108, 63)], beginSub |-> [], endSub |-> []] -[str |-> ">>", type |-> BUILTIN, col |-> 63, source |->[(108, 63)-(108, 65)], beginSub |-> [], endSub |-> []] -null -[str |-> "\/", type |-> BUILTIN, col |-> 14, source |->[(109, 14)-(109, 16)], beginSub |-> [], endSub |-> []] -[str |-> "/\", type |-> BUILTIN, col |-> 17, source |->[(109, 17)-(109, 19)], beginSub |-> [], endSub |-> []] -[str |-> "ackChan", type |-> IDENT, col |-> 20, source |->[(109, 20)-(109, 27)], beginSub |-> [], endSub |-> []] -[str |-> "#", type |-> BUILTIN, col |-> 28, source |->[(109, 28)-(109, 29)], beginSub |-> [], endSub |-> []] -[str |-> "<<", type |-> BUILTIN, col |-> 30, source |->[(109, 30)-(109, 32)], beginSub |-> [], endSub |-> []] -[str |-> ">>", type |-> BUILTIN, col |-> 32, source |->[(109, 32)-(109, 34)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 17, source |->[(110, 17)-(110, 19)], beginSub |-> [], endSub |-> []] -[str |-> "ack", type |-> IDENT, col |-> 20, source |->[(110, 20)-(110, 23)], beginSub |-> [], endSub |-> []] -[str |-> "'", type |-> BUILTIN, col |-> 23, source |->[(110, 23)-(110, 24)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 25, source |->[(110, 25)-(110, 26)], beginSub |-> [], endSub |-> []] -[str |-> "Head", type |-> IDENT, col |-> 27, source |->[(110, 27)-(110, 31)], beginSub |-> [], endSub |-> []] -[str |-> "(", type |-> BUILTIN, col |-> 31, source |->[(110, 31)-(110, 32)], beginSub |-> [], endSub |-> []] -[str |-> "ackChan", type |-> IDENT, col |-> 32, source |->[(110, 32)-(110, 39)], beginSub |-> [], endSub |-> []] -[str |-> ")", type |-> BUILTIN, col |-> 39, source |->[(110, 39)-(110, 40)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 17, source |->[(111, 17)-(111, 19)], beginSub |-> [], endSub |-> []] -[str |-> "ackChan", type |-> IDENT, col |-> 20, source |->[(111, 20)-(111, 27)], beginSub |-> [], endSub |-> []] -[str |-> "'", type |-> BUILTIN, col |-> 27, source |->[(111, 27)-(111, 28)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 29, source |->[(111, 29)-(111, 30)], beginSub |-> [], endSub |-> []] -[str |-> "Tail", type |-> IDENT, col |-> 31, source |->[(111, 31)-(111, 35)], beginSub |-> [], endSub |-> []] -[str |-> "(", type |-> BUILTIN, col |-> 35, source |->[(111, 35)-(111, 36)], beginSub |-> [], endSub |-> []] -[str |-> "ackChan", type |-> IDENT, col |-> 36, source |->[(111, 36)-(111, 43)], beginSub |-> [], endSub |-> []] -[str |-> ")", type |-> BUILTIN, col |-> 43, source |->[(111, 43)-(111, 44)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 17, source |->[(112, 17)-(112, 19)], beginSub |-> [], endSub |-> []] -[str |-> "IF", type |-> BUILTIN, col |-> 20, source |->[(112, 20)-(112, 22)], beginSub |-> [], endSub |-> []] -[str |-> "ack", type |-> IDENT, col |-> 23, source |->[(112, 23)-(112, 26)], beginSub |-> [], endSub |-> []] -[str |-> "'", type |-> BUILTIN, col |-> 26, source |->[(112, 26)-(112, 27)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 28, source |->[(112, 28)-(112, 29)], beginSub |-> [], endSub |-> []] -[str |-> "sbit", type |-> IDENT, col |-> 30, source |->[(112, 30)-(112, 34)], beginSub |-> [], endSub |-> []] -null -[str |-> "THEN", type |-> BUILTIN, col |-> 23, source |->[(113, 23)-(113, 27)], beginSub |-> [], endSub |-> []] -[str |-> "/\", type |-> BUILTIN, col |-> 28, source |->[(113, 28)-(113, 30)], beginSub |-> [], endSub |-> []] -[str |-> "next", type |-> IDENT, col |-> 31, source |->[(113, 31)-(113, 35)], beginSub |-> [], endSub |-> []] -[str |-> "'", type |-> BUILTIN, col |-> 35, source |->[(113, 35)-(113, 36)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 37, source |->[(113, 37)-(113, 38)], beginSub |-> [], endSub |-> []] -[str |-> "next", type |-> IDENT, col |-> 39, source |->[(113, 39)-(113, 43)], beginSub |-> [], endSub |-> []] -[str |-> "+", type |-> BUILTIN, col |-> 44, source |->[(113, 44)-(113, 45)], beginSub |-> [], endSub |-> []] -[str |-> "1", type |-> NUMBER, col |-> 46, source |->[(113, 46)-(113, 47)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 28, source |->[(114, 28)-(114, 30)], beginSub |-> [], endSub |-> []] -[str |-> "sbit", type |-> IDENT, col |-> 31, source |->[(114, 31)-(114, 35)], beginSub |-> [], endSub |-> []] -[str |-> "'", type |-> BUILTIN, col |-> 35, source |->[(114, 35)-(114, 36)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 37, source |->[(114, 37)-(114, 38)], beginSub |-> [], endSub |-> []] -[str |-> "(", type |-> BUILTIN, col |-> 39, source |->[(114, 39)-(114, 40)], beginSub |-> [], endSub |-> []] -[str |-> "sbit", type |-> IDENT, col |-> 40, source |->[(114, 40)-(114, 44)], beginSub |-> [], endSub |-> []] -[str |-> "+", type |-> BUILTIN, col |-> 45, source |->[(114, 45)-(114, 46)], beginSub |-> [], endSub |-> []] -[str |-> "1", type |-> NUMBER, col |-> 47, source |->[(114, 47)-(114, 48)], beginSub |-> [], endSub |-> []] -[str |-> ")", type |-> BUILTIN, col |-> 48, source |->[(114, 48)-(114, 49)], beginSub |-> [], endSub |-> []] -[str |-> "%", type |-> BUILTIN, col |-> 50, source |->[(114, 50)-(114, 51)], beginSub |-> [], endSub |-> []] -[str |-> "2", type |-> NUMBER, col |-> 52, source |->[(114, 52)-(114, 53)], beginSub |-> [], endSub |-> []] -null -[str |-> "ELSE", type |-> BUILTIN, col |-> 23, source |->[(115, 23)-(115, 27)], beginSub |-> [], endSub |-> []] -[str |-> "/\", type |-> BUILTIN, col |-> 28, source |->[(115, 28)-(115, 30)], beginSub |-> [], endSub |-> []] -[str |-> "TRUE", type |-> IDENT, col |-> 31, source |->[(115, 31)-(115, 35)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 28, source |->[(116, 28)-(116, 30)], beginSub |-> [], endSub |-> []] -[str |-> "UNCHANGED", type |-> BUILTIN, col |-> 31, source |->[(116, 31)-(116, 40)], beginSub |-> [], endSub |-> []] -[str |-> "<<", type |-> BUILTIN, col |-> 41, source |->[(116, 41)-(116, 43)], beginSub |-> [], endSub |-> []] -[str |-> "next", type |-> IDENT, col |-> 44, source |->[(116, 44)-(116, 48)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 48, source |->[(116, 48)-(116, 49)], beginSub |-> [], endSub |-> []] -[str |-> "sbit", type |-> IDENT, col |-> 50, source |->[(116, 50)-(116, 54)], beginSub |-> [], endSub |-> []] -[str |-> ">>", type |-> BUILTIN, col |-> 55, source |->[(116, 55)-(116, 57)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 17, source |->[(117, 17)-(117, 19)], beginSub |-> [], endSub |-> []] -[str |-> "UNCHANGED", type |-> BUILTIN, col |-> 20, source |->[(117, 20)-(117, 29)], beginSub |-> [], endSub |-> []] -[str |-> "<<", type |-> BUILTIN, col |-> 30, source |->[(117, 30)-(117, 32)], beginSub |-> [], endSub |-> []] -[str |-> "input", type |-> IDENT, col |-> 32, source |->[(117, 32)-(117, 37)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 37, source |->[(117, 37)-(117, 38)], beginSub |-> [], endSub |-> []] -[str |-> "msgChan", type |-> IDENT, col |-> 39, source |->[(117, 39)-(117, 46)], beginSub |-> [], endSub |-> []] -[str |-> ">>", type |-> BUILTIN, col |-> 46, source |->[(117, 46)-(117, 48)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 11, source |->[(118, 11)-(118, 13)], beginSub |-> [], endSub |-> []] -[str |-> "PrintT", type |-> IDENT, col |-> 14, source |->[(118, 14)-(118, 20)], beginSub |-> [], endSub |-> []] -[str |-> "(", type |-> BUILTIN, col |-> 20, source |->[(118, 20)-(118, 21)], beginSub |-> [], endSub |-> []] -[str |-> "<<", type |-> BUILTIN, col |-> 21, source |->[(118, 21)-(118, 23)], beginSub |-> [], endSub |-> []] -[str |-> "Sender", type |-> STRING, col |-> 23, source |->[(118, 23)-(118, 29)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 31, source |->[(118, 31)-(118, 32)], beginSub |-> [], endSub |-> []] -[str |-> "input", type |-> IDENT, col |-> 33, source |->[(118, 33)-(118, 38)], beginSub |-> [], endSub |-> []] -[str |-> "'", type |-> BUILTIN, col |-> 38, source |->[(118, 38)-(118, 39)], beginSub |-> [], endSub |-> []] -[str |-> ">>", type |-> BUILTIN, col |-> 39, source |->[(118, 39)-(118, 41)], beginSub |-> [], endSub |-> []] -[str |-> ")", type |-> BUILTIN, col |-> 41, source |->[(118, 41)-(118, 42)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 11, source |->[(119, 11)-(119, 13)], beginSub |-> [], endSub |-> []] -[str |-> "UNCHANGED", type |-> BUILTIN, col |-> 14, source |->[(119, 14)-(119, 23)], beginSub |-> [], endSub |-> []] -[str |-> "<<", type |-> BUILTIN, col |-> 24, source |->[(119, 24)-(119, 26)], beginSub |-> [], endSub |-> []] -[str |-> "output", type |-> IDENT, col |-> 27, source |->[(119, 27)-(119, 33)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 33, source |->[(119, 33)-(119, 34)], beginSub |-> [], endSub |-> []] -[str |-> "newChan", type |-> IDENT, col |-> 35, source |->[(119, 35)-(119, 42)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 42, source |->[(119, 42)-(119, 43)], beginSub |-> [], endSub |-> []] -[str |-> "rbit", type |-> IDENT, col |-> 44, source |->[(119, 44)-(119, 48)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 48, source |->[(119, 48)-(119, 49)], beginSub |-> [], endSub |-> []] -[str |-> "msg", type |-> IDENT, col |-> 50, source |->[(119, 50)-(119, 53)], beginSub |-> [], endSub |-> []] -[str |-> ">>", type |-> BUILTIN, col |-> 54, source |->[(119, 54)-(119, 56)], beginSub |-> [], endSub |-> []] -null -null -[str |-> "Receiver", type |-> IDENT, col |-> 1, source |->[(121, 1)-(121, 9)], beginSub |-> [], endSub |-> []] -[str |-> "==", type |-> BUILTIN, col |-> 10, source |->[(121, 10)-(121, 12)], beginSub |-> [], endSub |-> []] -[str |-> "/\", type |-> BUILTIN, col |-> 13, source |->[(121, 13)-(121, 15)], beginSub |-> [], endSub |-> []] -[str |-> "\/", type |-> BUILTIN, col |-> 16, source |->[(121, 16)-(121, 18)], beginSub |-> [], endSub |-> []] -[str |-> "/\", type |-> BUILTIN, col |-> 19, source |->[(121, 19)-(121, 21)], beginSub |-> [], endSub |-> []] -[str |-> "ackChan", type |-> IDENT, col |-> 22, source |->[(121, 22)-(121, 29)], beginSub |-> [], endSub |-> []] -[str |-> "'", type |-> BUILTIN, col |-> 29, source |->[(121, 29)-(121, 30)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 31, source |->[(121, 31)-(121, 32)], beginSub |-> [], endSub |-> []] -[str |-> "Append", type |-> IDENT, col |-> 33, source |->[(121, 33)-(121, 39)], beginSub |-> [], endSub |-> []] -[str |-> "(", type |-> BUILTIN, col |-> 39, source |->[(121, 39)-(121, 40)], beginSub |-> [], endSub |-> []] -[str |-> "ackChan", type |-> IDENT, col |-> 40, source |->[(121, 40)-(121, 47)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 47, source |->[(121, 47)-(121, 48)], beginSub |-> [], endSub |-> []] -[str |-> "rbit", type |-> IDENT, col |-> 49, source |->[(121, 49)-(121, 53)], beginSub |-> [], endSub |-> []] -[str |-> ")", type |-> BUILTIN, col |-> 53, source |->[(121, 53)-(121, 54)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 19, source |->[(122, 19)-(122, 21)], beginSub |-> [], endSub |-> []] -[str |-> "UNCHANGED", type |-> BUILTIN, col |-> 22, source |->[(122, 22)-(122, 31)], beginSub |-> [], endSub |-> []] -[str |-> "<<", type |-> BUILTIN, col |-> 32, source |->[(122, 32)-(122, 34)], beginSub |-> [], endSub |-> []] -[str |-> "output", type |-> IDENT, col |-> 34, source |->[(122, 34)-(122, 40)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 40, source |->[(122, 40)-(122, 41)], beginSub |-> [], endSub |-> []] -[str |-> "msgChan", type |-> IDENT, col |-> 42, source |->[(122, 42)-(122, 49)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 49, source |->[(122, 49)-(122, 50)], beginSub |-> [], endSub |-> []] -[str |-> "rbit", type |-> IDENT, col |-> 51, source |->[(122, 51)-(122, 55)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 55, source |->[(122, 55)-(122, 56)], beginSub |-> [], endSub |-> []] -[str |-> "msg", type |-> IDENT, col |-> 57, source |->[(122, 57)-(122, 60)], beginSub |-> [], endSub |-> []] -[str |-> ">>", type |-> BUILTIN, col |-> 60, source |->[(122, 60)-(122, 62)], beginSub |-> [], endSub |-> []] -null -[str |-> "\/", type |-> BUILTIN, col |-> 16, source |->[(123, 16)-(123, 18)], beginSub |-> [], endSub |-> []] -[str |-> "/\", type |-> BUILTIN, col |-> 19, source |->[(123, 19)-(123, 21)], beginSub |-> [], endSub |-> []] -[str |-> "msgChan", type |-> IDENT, col |-> 22, source |->[(123, 22)-(123, 29)], beginSub |-> [], endSub |-> []] -[str |-> "#", type |-> BUILTIN, col |-> 30, source |->[(123, 30)-(123, 31)], beginSub |-> [], endSub |-> []] -[str |-> "<<", type |-> BUILTIN, col |-> 32, source |->[(123, 32)-(123, 34)], beginSub |-> [], endSub |-> []] -[str |-> ">>", type |-> BUILTIN, col |-> 34, source |->[(123, 34)-(123, 36)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 19, source |->[(124, 19)-(124, 21)], beginSub |-> [], endSub |-> []] -[str |-> "msg", type |-> IDENT, col |-> 22, source |->[(124, 22)-(124, 25)], beginSub |-> [], endSub |-> []] -[str |-> "'", type |-> BUILTIN, col |-> 25, source |->[(124, 25)-(124, 26)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 27, source |->[(124, 27)-(124, 28)], beginSub |-> [], endSub |-> []] -[str |-> "Head", type |-> IDENT, col |-> 29, source |->[(124, 29)-(124, 33)], beginSub |-> [], endSub |-> []] -[str |-> "(", type |-> BUILTIN, col |-> 33, source |->[(124, 33)-(124, 34)], beginSub |-> [], endSub |-> []] -[str |-> "msgChan", type |-> IDENT, col |-> 34, source |->[(124, 34)-(124, 41)], beginSub |-> [], endSub |-> []] -[str |-> ")", type |-> BUILTIN, col |-> 41, source |->[(124, 41)-(124, 42)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 19, source |->[(125, 19)-(125, 21)], beginSub |-> [], endSub |-> []] -[str |-> "msgChan", type |-> IDENT, col |-> 22, source |->[(125, 22)-(125, 29)], beginSub |-> [], endSub |-> []] -[str |-> "'", type |-> BUILTIN, col |-> 29, source |->[(125, 29)-(125, 30)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 31, source |->[(125, 31)-(125, 32)], beginSub |-> [], endSub |-> []] -[str |-> "Tail", type |-> IDENT, col |-> 33, source |->[(125, 33)-(125, 37)], beginSub |-> [], endSub |-> []] -[str |-> "(", type |-> BUILTIN, col |-> 37, source |->[(125, 37)-(125, 38)], beginSub |-> [], endSub |-> []] -[str |-> "msgChan", type |-> IDENT, col |-> 38, source |->[(125, 38)-(125, 45)], beginSub |-> [], endSub |-> []] -[str |-> ")", type |-> BUILTIN, col |-> 45, source |->[(125, 45)-(125, 46)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 19, source |->[(126, 19)-(126, 21)], beginSub |-> [], endSub |-> []] -[str |-> "IF", type |-> BUILTIN, col |-> 22, source |->[(126, 22)-(126, 24)], beginSub |-> [], endSub |-> []] -[str |-> "msg", type |-> IDENT, col |-> 25, source |->[(126, 25)-(126, 28)], beginSub |-> [], endSub |-> []] -[str |-> "'", type |-> BUILTIN, col |-> 28, source |->[(126, 28)-(126, 29)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 29, source |->[(126, 29)-(126, 30)], beginSub |-> [], endSub |-> []] -[str |-> "2", type |-> NUMBER, col |-> 30, source |->[(126, 30)-(126, 31)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 31, source |->[(126, 31)-(126, 32)], beginSub |-> [], endSub |-> []] -[str |-> "#", type |-> BUILTIN, col |-> 33, source |->[(126, 33)-(126, 34)], beginSub |-> [], endSub |-> []] -[str |-> "rbit", type |-> IDENT, col |-> 35, source |->[(126, 35)-(126, 39)], beginSub |-> [], endSub |-> []] -null -[str |-> "THEN", type |-> BUILTIN, col |-> 25, source |->[(127, 25)-(127, 29)], beginSub |-> [], endSub |-> []] -[str |-> "/\", type |-> BUILTIN, col |-> 30, source |->[(127, 30)-(127, 32)], beginSub |-> [], endSub |-> []] -[str |-> "rbit", type |-> IDENT, col |-> 33, source |->[(127, 33)-(127, 37)], beginSub |-> [], endSub |-> []] -[str |-> "'", type |-> BUILTIN, col |-> 37, source |->[(127, 37)-(127, 38)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 39, source |->[(127, 39)-(127, 40)], beginSub |-> [], endSub |-> []] -[str |-> "(", type |-> BUILTIN, col |-> 41, source |->[(127, 41)-(127, 42)], beginSub |-> [], endSub |-> []] -[str |-> "rbit", type |-> IDENT, col |-> 42, source |->[(127, 42)-(127, 46)], beginSub |-> [], endSub |-> []] -[str |-> "+", type |-> BUILTIN, col |-> 47, source |->[(127, 47)-(127, 48)], beginSub |-> [], endSub |-> []] -[str |-> "1", type |-> NUMBER, col |-> 49, source |->[(127, 49)-(127, 50)], beginSub |-> [], endSub |-> []] -[str |-> ")", type |-> BUILTIN, col |-> 50, source |->[(127, 50)-(127, 51)], beginSub |-> [], endSub |-> []] -[str |-> "%", type |-> BUILTIN, col |-> 52, source |->[(127, 52)-(127, 53)], beginSub |-> [], endSub |-> []] -[str |-> "2", type |-> NUMBER, col |-> 54, source |->[(127, 54)-(127, 55)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 30, source |->[(128, 30)-(128, 32)], beginSub |-> [], endSub |-> []] -[str |-> "output", type |-> IDENT, col |-> 33, source |->[(128, 33)-(128, 39)], beginSub |-> [], endSub |-> []] -[str |-> "'", type |-> BUILTIN, col |-> 39, source |->[(128, 39)-(128, 40)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 41, source |->[(128, 41)-(128, 42)], beginSub |-> [], endSub |-> []] -[str |-> "Append", type |-> IDENT, col |-> 43, source |->[(128, 43)-(128, 49)], beginSub |-> [], endSub |-> []] -[str |-> "(", type |-> BUILTIN, col |-> 49, source |->[(128, 49)-(128, 50)], beginSub |-> [], endSub |-> []] -[str |-> "output", type |-> IDENT, col |-> 50, source |->[(128, 50)-(128, 56)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 56, source |->[(128, 56)-(128, 57)], beginSub |-> [], endSub |-> []] -[str |-> "msg", type |-> IDENT, col |-> 58, source |->[(128, 58)-(128, 61)], beginSub |-> [], endSub |-> []] -[str |-> "'", type |-> BUILTIN, col |-> 61, source |->[(128, 61)-(128, 62)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 62, source |->[(128, 62)-(128, 63)], beginSub |-> [], endSub |-> []] -[str |-> "1", type |-> NUMBER, col |-> 63, source |->[(128, 63)-(128, 64)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 64, source |->[(128, 64)-(128, 65)], beginSub |-> [], endSub |-> []] -[str |-> ")", type |-> BUILTIN, col |-> 65, source |->[(128, 65)-(128, 66)], beginSub |-> [], endSub |-> []] -null -[str |-> "ELSE", type |-> BUILTIN, col |-> 25, source |->[(129, 25)-(129, 29)], beginSub |-> [], endSub |-> []] -[str |-> "/\", type |-> BUILTIN, col |-> 30, source |->[(129, 30)-(129, 32)], beginSub |-> [], endSub |-> []] -[str |-> "TRUE", type |-> IDENT, col |-> 33, source |->[(129, 33)-(129, 37)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 30, source |->[(130, 30)-(130, 32)], beginSub |-> [], endSub |-> []] -[str |-> "UNCHANGED", type |-> BUILTIN, col |-> 33, source |->[(130, 33)-(130, 42)], beginSub |-> [], endSub |-> []] -[str |-> "<<", type |-> BUILTIN, col |-> 43, source |->[(130, 43)-(130, 45)], beginSub |-> [], endSub |-> []] -[str |-> "output", type |-> IDENT, col |-> 46, source |->[(130, 46)-(130, 52)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 52, source |->[(130, 52)-(130, 53)], beginSub |-> [], endSub |-> []] -[str |-> "rbit", type |-> IDENT, col |-> 54, source |->[(130, 54)-(130, 58)], beginSub |-> [], endSub |-> []] -[str |-> ">>", type |-> BUILTIN, col |-> 59, source |->[(130, 59)-(130, 61)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 19, source |->[(131, 19)-(131, 21)], beginSub |-> [], endSub |-> []] -[str |-> "UNCHANGED", type |-> BUILTIN, col |-> 22, source |->[(131, 22)-(131, 31)], beginSub |-> [], endSub |-> []] -[str |-> "ackChan", type |-> IDENT, col |-> 32, source |->[(131, 32)-(131, 39)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 13, source |->[(132, 13)-(132, 15)], beginSub |-> [], endSub |-> []] -[str |-> "UNCHANGED", type |-> BUILTIN, col |-> 16, source |->[(132, 16)-(132, 25)], beginSub |-> [], endSub |-> []] -[str |-> "<<", type |-> BUILTIN, col |-> 26, source |->[(132, 26)-(132, 28)], beginSub |-> [], endSub |-> []] -[str |-> "input", type |-> IDENT, col |-> 29, source |->[(132, 29)-(132, 34)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 34, source |->[(132, 34)-(132, 35)], beginSub |-> [], endSub |-> []] -[str |-> "newChan", type |-> IDENT, col |-> 36, source |->[(132, 36)-(132, 43)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 43, source |->[(132, 43)-(132, 44)], beginSub |-> [], endSub |-> []] -[str |-> "next", type |-> IDENT, col |-> 45, source |->[(132, 45)-(132, 49)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 49, source |->[(132, 49)-(132, 50)], beginSub |-> [], endSub |-> []] -[str |-> "sbit", type |-> IDENT, col |-> 51, source |->[(132, 51)-(132, 55)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 55, source |->[(132, 55)-(132, 56)], beginSub |-> [], endSub |-> []] -[str |-> "ack", type |-> IDENT, col |-> 57, source |->[(132, 57)-(132, 60)], beginSub |-> [], endSub |-> []] -[str |-> ">>", type |-> BUILTIN, col |-> 61, source |->[(132, 61)-(132, 63)], beginSub |-> [], endSub |-> []] -null -null -[str |-> "LoseMsg", type |-> IDENT, col |-> 1, source |->[(134, 1)-(134, 8)], beginSub |-> [], endSub |-> []] -[str |-> "==", type |-> BUILTIN, col |-> 9, source |->[(134, 9)-(134, 11)], beginSub |-> [], endSub |-> []] -[str |-> "/\", type |-> BUILTIN, col |-> 12, source |->[(134, 12)-(134, 14)], beginSub |-> [], endSub |-> []] -[str |-> "\/", type |-> BUILTIN, col |-> 15, source |->[(134, 15)-(134, 17)], beginSub |-> [], endSub |-> []] -[str |-> "/\", type |-> BUILTIN, col |-> 18, source |->[(134, 18)-(134, 20)], beginSub |-> [], endSub |-> []] -[str |-> "\E", type |-> BUILTIN, col |-> 21, source |->[(134, 21)-(134, 23)], beginSub |-> [], endSub |-> []] -[str |-> "i", type |-> IDENT, col |-> 24, source |->[(134, 24)-(134, 25)], beginSub |-> [], endSub |-> []] -[str |-> "\in", type |-> BUILTIN, col |-> 26, source |->[(134, 26)-(134, 29)], beginSub |-> [], endSub |-> []] -[str |-> "1", type |-> NUMBER, col |-> 30, source |->[(134, 30)-(134, 31)], beginSub |-> [], endSub |-> []] -[str |-> "..", type |-> BUILTIN, col |-> 31, source |->[(134, 31)-(134, 33)], beginSub |-> [], endSub |-> []] -[str |-> "Len", type |-> IDENT, col |-> 33, source |->[(134, 33)-(134, 36)], beginSub |-> [], endSub |-> []] -[str |-> "(", type |-> BUILTIN, col |-> 36, source |->[(134, 36)-(134, 37)], beginSub |-> [], endSub |-> []] -[str |-> "msgChan", type |-> IDENT, col |-> 37, source |->[(134, 37)-(134, 44)], beginSub |-> [], endSub |-> []] -[str |-> ")", type |-> BUILTIN, col |-> 44, source |->[(134, 44)-(134, 45)], beginSub |-> [], endSub |-> []] -[str |-> ":", type |-> BUILTIN, col |-> 45, source |->[(134, 45)-(134, 46)], beginSub |-> [], endSub |-> []] -null -[str |-> "msgChan", type |-> IDENT, col |-> 23, source |->[(135, 23)-(135, 30)], beginSub |-> [], endSub |-> []] -[str |-> "'", type |-> BUILTIN, col |-> 30, source |->[(135, 30)-(135, 31)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 32, source |->[(135, 32)-(135, 33)], beginSub |-> [], endSub |-> []] -[str |-> "Remove", type |-> IDENT, col |-> 34, source |->[(135, 34)-(135, 40)], beginSub |-> [], endSub |-> []] -[str |-> "(", type |-> BUILTIN, col |-> 40, source |->[(135, 40)-(135, 41)], beginSub |-> [], endSub |-> []] -[str |-> "i", type |-> IDENT, col |-> 41, source |->[(135, 41)-(135, 42)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 42, source |->[(135, 42)-(135, 43)], beginSub |-> [], endSub |-> []] -[str |-> "msgChan", type |-> IDENT, col |-> 44, source |->[(135, 44)-(135, 51)], beginSub |-> [], endSub |-> []] -[str |-> ")", type |-> BUILTIN, col |-> 51, source |->[(135, 51)-(135, 52)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 18, source |->[(136, 18)-(136, 20)], beginSub |-> [], endSub |-> []] -[str |-> "UNCHANGED", type |-> BUILTIN, col |-> 21, source |->[(136, 21)-(136, 30)], beginSub |-> [], endSub |-> []] -[str |-> "ackChan", type |-> IDENT, col |-> 31, source |->[(136, 31)-(136, 38)], beginSub |-> [], endSub |-> []] -null -[str |-> "\/", type |-> BUILTIN, col |-> 15, source |->[(137, 15)-(137, 17)], beginSub |-> [], endSub |-> []] -[str |-> "/\", type |-> BUILTIN, col |-> 18, source |->[(137, 18)-(137, 20)], beginSub |-> [], endSub |-> []] -[str |-> "\E", type |-> BUILTIN, col |-> 21, source |->[(137, 21)-(137, 23)], beginSub |-> [], endSub |-> []] -[str |-> "i", type |-> IDENT, col |-> 24, source |->[(137, 24)-(137, 25)], beginSub |-> [], endSub |-> []] -[str |-> "\in", type |-> BUILTIN, col |-> 26, source |->[(137, 26)-(137, 29)], beginSub |-> [], endSub |-> []] -[str |-> "1", type |-> NUMBER, col |-> 30, source |->[(137, 30)-(137, 31)], beginSub |-> [], endSub |-> []] -[str |-> "..", type |-> BUILTIN, col |-> 31, source |->[(137, 31)-(137, 33)], beginSub |-> [], endSub |-> []] -[str |-> "Len", type |-> IDENT, col |-> 33, source |->[(137, 33)-(137, 36)], beginSub |-> [], endSub |-> []] -[str |-> "(", type |-> BUILTIN, col |-> 36, source |->[(137, 36)-(137, 37)], beginSub |-> [], endSub |-> []] -[str |-> "ackChan", type |-> IDENT, col |-> 37, source |->[(137, 37)-(137, 44)], beginSub |-> [], endSub |-> []] -[str |-> ")", type |-> BUILTIN, col |-> 44, source |->[(137, 44)-(137, 45)], beginSub |-> [], endSub |-> []] -[str |-> ":", type |-> BUILTIN, col |-> 45, source |->[(137, 45)-(137, 46)], beginSub |-> [], endSub |-> []] -null -[str |-> "ackChan", type |-> IDENT, col |-> 23, source |->[(138, 23)-(138, 30)], beginSub |-> [], endSub |-> []] -[str |-> "'", type |-> BUILTIN, col |-> 30, source |->[(138, 30)-(138, 31)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 32, source |->[(138, 32)-(138, 33)], beginSub |-> [], endSub |-> []] -[str |-> "Remove", type |-> IDENT, col |-> 34, source |->[(138, 34)-(138, 40)], beginSub |-> [], endSub |-> []] -[str |-> "(", type |-> BUILTIN, col |-> 40, source |->[(138, 40)-(138, 41)], beginSub |-> [], endSub |-> []] -[str |-> "i", type |-> IDENT, col |-> 41, source |->[(138, 41)-(138, 42)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 42, source |->[(138, 42)-(138, 43)], beginSub |-> [], endSub |-> []] -[str |-> "ackChan", type |-> IDENT, col |-> 44, source |->[(138, 44)-(138, 51)], beginSub |-> [], endSub |-> []] -[str |-> ")", type |-> BUILTIN, col |-> 51, source |->[(138, 51)-(138, 52)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 18, source |->[(139, 18)-(139, 20)], beginSub |-> [], endSub |-> []] -[str |-> "UNCHANGED", type |-> BUILTIN, col |-> 21, source |->[(139, 21)-(139, 30)], beginSub |-> [], endSub |-> []] -[str |-> "msgChan", type |-> IDENT, col |-> 31, source |->[(139, 31)-(139, 38)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 12, source |->[(140, 12)-(140, 14)], beginSub |-> [], endSub |-> []] -[str |-> "UNCHANGED", type |-> BUILTIN, col |-> 15, source |->[(140, 15)-(140, 24)], beginSub |-> [], endSub |-> []] -[str |-> "<<", type |-> BUILTIN, col |-> 25, source |->[(140, 25)-(140, 27)], beginSub |-> [], endSub |-> []] -[str |-> "input", type |-> IDENT, col |-> 28, source |->[(140, 28)-(140, 33)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 33, source |->[(140, 33)-(140, 34)], beginSub |-> [], endSub |-> []] -[str |-> "output", type |-> IDENT, col |-> 35, source |->[(140, 35)-(140, 41)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 41, source |->[(140, 41)-(140, 42)], beginSub |-> [], endSub |-> []] -[str |-> "newChan", type |-> IDENT, col |-> 43, source |->[(140, 43)-(140, 50)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 50, source |->[(140, 50)-(140, 51)], beginSub |-> [], endSub |-> []] -[str |-> "next", type |-> IDENT, col |-> 52, source |->[(140, 52)-(140, 56)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 56, source |->[(140, 56)-(140, 57)], beginSub |-> [], endSub |-> []] -[str |-> "sbit", type |-> IDENT, col |-> 58, source |->[(140, 58)-(140, 62)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 62, source |->[(140, 62)-(140, 63)], beginSub |-> [], endSub |-> []] -[str |-> "ack", type |-> IDENT, col |-> 64, source |->[(140, 64)-(140, 67)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 67, source |->[(140, 67)-(140, 68)], beginSub |-> [], endSub |-> []] -[str |-> "rbit", type |-> IDENT, col |-> 69, source |->[(140, 69)-(140, 73)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 73, source |->[(140, 73)-(140, 74)], beginSub |-> [], endSub |-> []] -[str |-> "msg", type |-> IDENT, col |-> 75, source |->[(140, 75)-(140, 78)], beginSub |-> [], endSub |-> []] -[str |-> ">>", type |-> BUILTIN, col |-> 79, source |->[(140, 79)-(140, 81)], beginSub |-> [], endSub |-> []] -null -null -[str |-> "Next", type |-> IDENT, col |-> 1, source |->[(142, 1)-(142, 5)], beginSub |-> [], endSub |-> []] -[str |-> "==", type |-> BUILTIN, col |-> 6, source |->[(142, 6)-(142, 8)], beginSub |-> [], endSub |-> []] -[str |-> "Sender", type |-> IDENT, col |-> 9, source |->[(142, 9)-(142, 15)], beginSub |-> [], endSub |-> []] -[str |-> "\/", type |-> BUILTIN, col |-> 16, source |->[(142, 16)-(142, 18)], beginSub |-> [], endSub |-> []] -[str |-> "Receiver", type |-> IDENT, col |-> 19, source |->[(142, 19)-(142, 27)], beginSub |-> [], endSub |-> []] -[str |-> "\/", type |-> BUILTIN, col |-> 28, source |->[(142, 28)-(142, 30)], beginSub |-> [], endSub |-> []] -[str |-> "LoseMsg", type |-> IDENT, col |-> 31, source |->[(142, 31)-(142, 38)], beginSub |-> [], endSub |-> []] -null -null -[str |-> "Spec", type |-> IDENT, col |-> 1, source |->[(144, 1)-(144, 5)], beginSub |-> [], endSub |-> []] -[str |-> "==", type |-> BUILTIN, col |-> 6, source |->[(144, 6)-(144, 8)], beginSub |-> [], endSub |-> []] -[str |-> "Init", type |-> IDENT, col |-> 9, source |->[(144, 9)-(144, 13)], beginSub |-> [], endSub |-> []] -[str |-> "/\", type |-> BUILTIN, col |-> 14, source |->[(144, 14)-(144, 16)], beginSub |-> [], endSub |-> []] -[str |-> "[]", type |-> BUILTIN, col |-> 17, source |->[(144, 17)-(144, 19)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 19, source |->[(144, 19)-(144, 20)], beginSub |-> [], endSub |-> []] -[str |-> "Next", type |-> IDENT, col |-> 20, source |->[(144, 20)-(144, 24)], beginSub |-> [], endSub |-> []] -[str |-> "]_", type |-> BUILTIN, col |-> 24, source |->[(144, 24)-(144, 26)], beginSub |-> [], endSub |-> []] -[str |-> "vars", type |-> IDENT, col |-> 26, source |->[(144, 26)-(144, 30)], beginSub |-> [], endSub |-> []] -null -null -null -null -[str |-> "==================================================================", type |-> BUILTIN, col |-> 1, source |->[(148, 1)-(148, 67)], beginSub |-> [], endSub |-> []] -null \ No newline at end of file diff --git a/test/tla/tokens/Euclid.tokens b/test/tla/tokens/Euclid.tokens deleted file mode 100644 index 3e6d39251..000000000 --- a/test/tla/tokens/Euclid.tokens +++ /dev/null @@ -1,227 +0,0 @@ -[str |-> "------------------------", type |-> BUILTIN, col |-> 1, source |->[(1, 1)-(1, 25)], beginSub |-> [], endSub |-> []] -[str |-> "MODULE", type |-> BUILTIN, col |-> 26, source |->[(1, 26)-(1, 32)], beginSub |-> [], endSub |-> []] -[str |-> "Euclid", type |-> IDENT, col |-> 33, source |->[(1, 33)-(1, 39)], beginSub |-> [], endSub |-> []] -[str |-> "----------------------------", type |-> BUILTIN, col |-> 40, source |->[(1, 40)-(1, 68)], beginSub |-> [], endSub |-> []] -null -[str |-> "EXTENDS", type |-> BUILTIN, col |-> 1, source |->[(2, 1)-(2, 8)], beginSub |-> [], endSub |-> []] -[str |-> "Naturals", type |-> IDENT, col |-> 9, source |->[(2, 9)-(2, 17)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 17, source |->[(2, 17)-(2, 18)], beginSub |-> [], endSub |-> []] -[str |-> "TLC", type |-> IDENT, col |-> 19, source |->[(2, 19)-(2, 22)], beginSub |-> [], endSub |-> []] -null -[str |-> "CONSTANT", type |-> BUILTIN, col |-> 1, source |->[(3, 1)-(3, 9)], beginSub |-> [], endSub |-> []] -[str |-> "N", type |-> IDENT, col |-> 10, source |->[(3, 10)-(3, 11)], beginSub |-> [], endSub |-> []] -null -null -[str |-> " arg N int ", type |-> , col |-> 34, source |->[(6, 34)-(6, 45)], beginSub |-> [], endSub |-> []] -[str |-> " var u int ", type |-> , col |-> 12, source |->[(7, 12)-(7, 23)], beginSub |-> [], endSub |-> []] -[str |-> " var v int ", type |-> , col |-> 12, source |->[(8, 12)-(8, 23)], beginSub |-> [], endSub |-> []] -[str |-> " var v_init int ", type |-> , col |-> 12, source |->[(9, 12)-(9, 28)], beginSub |-> [], endSub |-> []] -null -null -[str |-> "VARIABLES", type |-> BUILTIN, col |-> 1, source |->[(26, 1)-(26, 10)], beginSub |-> [], endSub |-> []] -[str |-> "u", type |-> IDENT, col |-> 11, source |->[(26, 11)-(26, 12)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 12, source |->[(26, 12)-(26, 13)], beginSub |-> [], endSub |-> []] -[str |-> "v", type |-> IDENT, col |-> 14, source |->[(26, 14)-(26, 15)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 15, source |->[(26, 15)-(26, 16)], beginSub |-> [], endSub |-> []] -[str |-> "v_init", type |-> IDENT, col |-> 17, source |->[(26, 17)-(26, 23)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 23, source |->[(26, 23)-(26, 24)], beginSub |-> [], endSub |-> []] -[str |-> "pc", type |-> IDENT, col |-> 25, source |->[(26, 25)-(26, 27)], beginSub |-> [], endSub |-> []] -null -null -[str |-> "vars", type |-> IDENT, col |-> 1, source |->[(28, 1)-(28, 5)], beginSub |-> [], endSub |-> []] -[str |-> "==", type |-> BUILTIN, col |-> 6, source |->[(28, 6)-(28, 8)], beginSub |-> [], endSub |-> []] -[str |-> "<<", type |-> BUILTIN, col |-> 9, source |->[(28, 9)-(28, 11)], beginSub |-> [], endSub |-> []] -[str |-> "u", type |-> IDENT, col |-> 12, source |->[(28, 12)-(28, 13)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 13, source |->[(28, 13)-(28, 14)], beginSub |-> [], endSub |-> []] -[str |-> "v", type |-> IDENT, col |-> 15, source |->[(28, 15)-(28, 16)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 16, source |->[(28, 16)-(28, 17)], beginSub |-> [], endSub |-> []] -[str |-> "v_init", type |-> IDENT, col |-> 18, source |->[(28, 18)-(28, 24)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 24, source |->[(28, 24)-(28, 25)], beginSub |-> [], endSub |-> []] -[str |-> "pc", type |-> IDENT, col |-> 26, source |->[(28, 26)-(28, 28)], beginSub |-> [], endSub |-> []] -[str |-> ">>", type |-> BUILTIN, col |-> 29, source |->[(28, 29)-(28, 31)], beginSub |-> [], endSub |-> []] -null -null -[str |-> "Init", type |-> IDENT, col |-> 1, source |->[(30, 1)-(30, 5)], beginSub |-> [], endSub |-> []] -[str |-> "==", type |-> BUILTIN, col |-> 6, source |->[(30, 6)-(30, 8)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 9, source |->[(31, 9)-(31, 11)], beginSub |-> [], endSub |-> []] -[str |-> "u", type |-> IDENT, col |-> 12, source |->[(31, 12)-(31, 13)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 14, source |->[(31, 14)-(31, 15)], beginSub |-> [], endSub |-> []] -[str |-> "24", type |-> NUMBER, col |-> 16, source |->[(31, 16)-(31, 18)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 9, source |->[(32, 9)-(32, 11)], beginSub |-> [], endSub |-> []] -[str |-> "v", type |-> IDENT, col |-> 12, source |->[(32, 12)-(32, 13)], beginSub |-> [], endSub |-> []] -[str |-> "\in", type |-> BUILTIN, col |-> 14, source |->[(32, 14)-(32, 17)], beginSub |-> [], endSub |-> []] -[str |-> "1", type |-> NUMBER, col |-> 18, source |->[(32, 18)-(32, 19)], beginSub |-> [], endSub |-> []] -[str |-> "..", type |-> BUILTIN, col |-> 20, source |->[(32, 20)-(32, 22)], beginSub |-> [], endSub |-> []] -[str |-> "N", type |-> IDENT, col |-> 23, source |->[(32, 23)-(32, 24)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 9, source |->[(33, 9)-(33, 11)], beginSub |-> [], endSub |-> []] -[str |-> "v_init", type |-> IDENT, col |-> 12, source |->[(33, 12)-(33, 18)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 19, source |->[(33, 19)-(33, 20)], beginSub |-> [], endSub |-> []] -[str |-> "v", type |-> IDENT, col |-> 21, source |->[(33, 21)-(33, 22)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 9, source |->[(34, 9)-(34, 11)], beginSub |-> [], endSub |-> []] -[str |-> "pc", type |-> IDENT, col |-> 12, source |->[(34, 12)-(34, 14)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 15, source |->[(34, 15)-(34, 16)], beginSub |-> [], endSub |-> []] -[str |-> "Lbl_1", type |-> STRING, col |-> 17, source |->[(34, 17)-(34, 22)], beginSub |-> [], endSub |-> []] -null -null -[str |-> "Lbl_1", type |-> IDENT, col |-> 1, source |->[(36, 1)-(36, 6)], beginSub |-> [], endSub |-> []] -[str |-> "==", type |-> BUILTIN, col |-> 7, source |->[(36, 7)-(36, 9)], beginSub |-> [], endSub |-> []] -[str |-> "/\", type |-> BUILTIN, col |-> 10, source |->[(36, 10)-(36, 12)], beginSub |-> [], endSub |-> []] -[str |-> "pc", type |-> IDENT, col |-> 13, source |->[(36, 13)-(36, 15)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 16, source |->[(36, 16)-(36, 17)], beginSub |-> [], endSub |-> []] -[str |-> "Lbl_1", type |-> STRING, col |-> 18, source |->[(36, 18)-(36, 23)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 10, source |->[(37, 10)-(37, 12)], beginSub |-> [], endSub |-> []] -[str |-> "IF", type |-> BUILTIN, col |-> 13, source |->[(37, 13)-(37, 15)], beginSub |-> [], endSub |-> []] -[str |-> "u", type |-> IDENT, col |-> 16, source |->[(37, 16)-(37, 17)], beginSub |-> [], endSub |-> []] -[str |-> "#", type |-> BUILTIN, col |-> 18, source |->[(37, 18)-(37, 19)], beginSub |-> [], endSub |-> []] -[str |-> "0", type |-> NUMBER, col |-> 20, source |->[(37, 20)-(37, 21)], beginSub |-> [], endSub |-> []] -null -[str |-> "THEN", type |-> BUILTIN, col |-> 16, source |->[(38, 16)-(38, 20)], beginSub |-> [], endSub |-> []] -[str |-> "/\", type |-> BUILTIN, col |-> 21, source |->[(38, 21)-(38, 23)], beginSub |-> [], endSub |-> []] -[str |-> "IF", type |-> BUILTIN, col |-> 24, source |->[(38, 24)-(38, 26)], beginSub |-> [], endSub |-> []] -[str |-> "u", type |-> IDENT, col |-> 27, source |->[(38, 27)-(38, 28)], beginSub |-> [], endSub |-> []] -[str |-> "<", type |-> BUILTIN, col |-> 29, source |->[(38, 29)-(38, 30)], beginSub |-> [], endSub |-> []] -[str |-> "v", type |-> IDENT, col |-> 31, source |->[(38, 31)-(38, 32)], beginSub |-> [], endSub |-> []] -null -[str |-> "THEN", type |-> BUILTIN, col |-> 27, source |->[(39, 27)-(39, 31)], beginSub |-> [], endSub |-> []] -[str |-> "/\", type |-> BUILTIN, col |-> 32, source |->[(39, 32)-(39, 34)], beginSub |-> [], endSub |-> []] -[str |-> "/\", type |-> BUILTIN, col |-> 35, source |->[(39, 35)-(39, 37)], beginSub |-> [], endSub |-> []] -[str |-> "u", type |-> IDENT, col |-> 38, source |->[(39, 38)-(39, 39)], beginSub |-> [], endSub |-> []] -[str |-> "'", type |-> BUILTIN, col |-> 39, source |->[(39, 39)-(39, 40)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 41, source |->[(39, 41)-(39, 42)], beginSub |-> [], endSub |-> []] -[str |-> "v", type |-> IDENT, col |-> 43, source |->[(39, 43)-(39, 44)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 35, source |->[(40, 35)-(40, 37)], beginSub |-> [], endSub |-> []] -[str |-> "v", type |-> IDENT, col |-> 38, source |->[(40, 38)-(40, 39)], beginSub |-> [], endSub |-> []] -[str |-> "'", type |-> BUILTIN, col |-> 39, source |->[(40, 39)-(40, 40)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 41, source |->[(40, 41)-(40, 42)], beginSub |-> [], endSub |-> []] -[str |-> "u", type |-> IDENT, col |-> 43, source |->[(40, 43)-(40, 44)], beginSub |-> [], endSub |-> []] -null -[str |-> "ELSE", type |-> BUILTIN, col |-> 27, source |->[(41, 27)-(41, 31)], beginSub |-> [], endSub |-> []] -[str |-> "/\", type |-> BUILTIN, col |-> 32, source |->[(41, 32)-(41, 34)], beginSub |-> [], endSub |-> []] -[str |-> "TRUE", type |-> IDENT, col |-> 35, source |->[(41, 35)-(41, 39)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 32, source |->[(42, 32)-(42, 34)], beginSub |-> [], endSub |-> []] -[str |-> "UNCHANGED", type |-> BUILTIN, col |-> 35, source |->[(42, 35)-(42, 44)], beginSub |-> [], endSub |-> []] -[str |-> "<<", type |-> BUILTIN, col |-> 45, source |->[(42, 45)-(42, 47)], beginSub |-> [], endSub |-> []] -[str |-> "u", type |-> IDENT, col |-> 48, source |->[(42, 48)-(42, 49)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 49, source |->[(42, 49)-(42, 50)], beginSub |-> [], endSub |-> []] -[str |-> "v", type |-> IDENT, col |-> 51, source |->[(42, 51)-(42, 52)], beginSub |-> [], endSub |-> []] -[str |-> ">>", type |-> BUILTIN, col |-> 53, source |->[(42, 53)-(42, 55)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 21, source |->[(43, 21)-(43, 23)], beginSub |-> [], endSub |-> []] -[str |-> "pc", type |-> IDENT, col |-> 24, source |->[(43, 24)-(43, 26)], beginSub |-> [], endSub |-> []] -[str |-> "'", type |-> BUILTIN, col |-> 26, source |->[(43, 26)-(43, 27)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 28, source |->[(43, 28)-(43, 29)], beginSub |-> [], endSub |-> []] -[str |-> "Lbl_2", type |-> STRING, col |-> 30, source |->[(43, 30)-(43, 35)], beginSub |-> [], endSub |-> []] -null -[str |-> "ELSE", type |-> BUILTIN, col |-> 16, source |->[(44, 16)-(44, 20)], beginSub |-> [], endSub |-> []] -[str |-> "/\", type |-> BUILTIN, col |-> 21, source |->[(44, 21)-(44, 23)], beginSub |-> [], endSub |-> []] -[str |-> "PrintT", type |-> IDENT, col |-> 24, source |->[(44, 24)-(44, 30)], beginSub |-> [], endSub |-> []] -[str |-> "(", type |-> BUILTIN, col |-> 30, source |->[(44, 30)-(44, 31)], beginSub |-> [], endSub |-> []] -[str |-> "<<", type |-> BUILTIN, col |-> 31, source |->[(44, 31)-(44, 33)], beginSub |-> [], endSub |-> []] -[str |-> "24", type |-> NUMBER, col |-> 33, source |->[(44, 33)-(44, 35)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 35, source |->[(44, 35)-(44, 36)], beginSub |-> [], endSub |-> []] -[str |-> "v_init", type |-> IDENT, col |-> 37, source |->[(44, 37)-(44, 43)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 43, source |->[(44, 43)-(44, 44)], beginSub |-> [], endSub |-> []] -[str |-> "have gcd", type |-> STRING, col |-> 45, source |->[(44, 45)-(44, 53)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 55, source |->[(44, 55)-(44, 56)], beginSub |-> [], endSub |-> []] -[str |-> "v", type |-> IDENT, col |-> 57, source |->[(44, 57)-(44, 58)], beginSub |-> [], endSub |-> []] -[str |-> ">>", type |-> BUILTIN, col |-> 58, source |->[(44, 58)-(44, 60)], beginSub |-> [], endSub |-> []] -[str |-> ")", type |-> BUILTIN, col |-> 60, source |->[(44, 60)-(44, 61)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 21, source |->[(45, 21)-(45, 23)], beginSub |-> [], endSub |-> []] -[str |-> "pc", type |-> IDENT, col |-> 24, source |->[(45, 24)-(45, 26)], beginSub |-> [], endSub |-> []] -[str |-> "'", type |-> BUILTIN, col |-> 26, source |->[(45, 26)-(45, 27)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 28, source |->[(45, 28)-(45, 29)], beginSub |-> [], endSub |-> []] -[str |-> "Done", type |-> STRING, col |-> 30, source |->[(45, 30)-(45, 34)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 21, source |->[(46, 21)-(46, 23)], beginSub |-> [], endSub |-> []] -[str |-> "UNCHANGED", type |-> BUILTIN, col |-> 24, source |->[(46, 24)-(46, 33)], beginSub |-> [], endSub |-> []] -[str |-> "<<", type |-> BUILTIN, col |-> 34, source |->[(46, 34)-(46, 36)], beginSub |-> [], endSub |-> []] -[str |-> "u", type |-> IDENT, col |-> 37, source |->[(46, 37)-(46, 38)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 38, source |->[(46, 38)-(46, 39)], beginSub |-> [], endSub |-> []] -[str |-> "v", type |-> IDENT, col |-> 40, source |->[(46, 40)-(46, 41)], beginSub |-> [], endSub |-> []] -[str |-> ">>", type |-> BUILTIN, col |-> 42, source |->[(46, 42)-(46, 44)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 10, source |->[(47, 10)-(47, 12)], beginSub |-> [], endSub |-> []] -[str |-> "UNCHANGED", type |-> BUILTIN, col |-> 13, source |->[(47, 13)-(47, 22)], beginSub |-> [], endSub |-> []] -[str |-> "v_init", type |-> IDENT, col |-> 23, source |->[(47, 23)-(47, 29)], beginSub |-> [], endSub |-> []] -null -null -[str |-> "Lbl_2", type |-> IDENT, col |-> 1, source |->[(49, 1)-(49, 6)], beginSub |-> [], endSub |-> []] -[str |-> "==", type |-> BUILTIN, col |-> 7, source |->[(49, 7)-(49, 9)], beginSub |-> [], endSub |-> []] -[str |-> "/\", type |-> BUILTIN, col |-> 10, source |->[(49, 10)-(49, 12)], beginSub |-> [], endSub |-> []] -[str |-> "pc", type |-> IDENT, col |-> 13, source |->[(49, 13)-(49, 15)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 16, source |->[(49, 16)-(49, 17)], beginSub |-> [], endSub |-> []] -[str |-> "Lbl_2", type |-> STRING, col |-> 18, source |->[(49, 18)-(49, 23)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 10, source |->[(50, 10)-(50, 12)], beginSub |-> [], endSub |-> []] -[str |-> "u", type |-> IDENT, col |-> 13, source |->[(50, 13)-(50, 14)], beginSub |-> [], endSub |-> []] -[str |-> "'", type |-> BUILTIN, col |-> 14, source |->[(50, 14)-(50, 15)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 16, source |->[(50, 16)-(50, 17)], beginSub |-> [], endSub |-> []] -[str |-> "u", type |-> IDENT, col |-> 18, source |->[(50, 18)-(50, 19)], beginSub |-> [], endSub |-> []] -[str |-> "-", type |-> BUILTIN, col |-> 20, source |->[(50, 20)-(50, 21)], beginSub |-> [], endSub |-> []] -[str |-> "v", type |-> IDENT, col |-> 22, source |->[(50, 22)-(50, 23)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 10, source |->[(51, 10)-(51, 12)], beginSub |-> [], endSub |-> []] -[str |-> "pc", type |-> IDENT, col |-> 13, source |->[(51, 13)-(51, 15)], beginSub |-> [], endSub |-> []] -[str |-> "'", type |-> BUILTIN, col |-> 15, source |->[(51, 15)-(51, 16)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 17, source |->[(51, 17)-(51, 18)], beginSub |-> [], endSub |-> []] -[str |-> "Lbl_1", type |-> STRING, col |-> 19, source |->[(51, 19)-(51, 24)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 10, source |->[(52, 10)-(52, 12)], beginSub |-> [], endSub |-> []] -[str |-> "UNCHANGED", type |-> BUILTIN, col |-> 13, source |->[(52, 13)-(52, 22)], beginSub |-> [], endSub |-> []] -[str |-> "<<", type |-> BUILTIN, col |-> 23, source |->[(52, 23)-(52, 25)], beginSub |-> [], endSub |-> []] -[str |-> "v", type |-> IDENT, col |-> 26, source |->[(52, 26)-(52, 27)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 27, source |->[(52, 27)-(52, 28)], beginSub |-> [], endSub |-> []] -[str |-> "v_init", type |-> IDENT, col |-> 29, source |->[(52, 29)-(52, 35)], beginSub |-> [], endSub |-> []] -[str |-> ">>", type |-> BUILTIN, col |-> 36, source |->[(52, 36)-(52, 38)], beginSub |-> [], endSub |-> []] -null -null -[str |-> "Next", type |-> IDENT, col |-> 1, source |->[(54, 1)-(54, 5)], beginSub |-> [], endSub |-> []] -[str |-> "==", type |-> BUILTIN, col |-> 6, source |->[(54, 6)-(54, 8)], beginSub |-> [], endSub |-> []] -[str |-> "Lbl_1", type |-> IDENT, col |-> 9, source |->[(54, 9)-(54, 14)], beginSub |-> [], endSub |-> []] -[str |-> "\/", type |-> BUILTIN, col |-> 15, source |->[(54, 15)-(54, 17)], beginSub |-> [], endSub |-> []] -[str |-> "Lbl_2", type |-> IDENT, col |-> 18, source |->[(54, 18)-(54, 23)], beginSub |-> [], endSub |-> []] -null -[str |-> "\/", type |-> BUILTIN, col |-> 12, source |->[(55, 12)-(55, 14)], beginSub |-> [], endSub |-> []] -null -[str |-> "(", type |-> BUILTIN, col |-> 15, source |->[(56, 15)-(56, 16)], beginSub |-> [], endSub |-> []] -[str |-> "pc", type |-> IDENT, col |-> 16, source |->[(56, 16)-(56, 18)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 19, source |->[(56, 19)-(56, 20)], beginSub |-> [], endSub |-> []] -[str |-> "Done", type |-> STRING, col |-> 21, source |->[(56, 21)-(56, 25)], beginSub |-> [], endSub |-> []] -[str |-> "/\", type |-> BUILTIN, col |-> 28, source |->[(56, 28)-(56, 30)], beginSub |-> [], endSub |-> []] -[str |-> "UNCHANGED", type |-> BUILTIN, col |-> 31, source |->[(56, 31)-(56, 40)], beginSub |-> [], endSub |-> []] -[str |-> "vars", type |-> IDENT, col |-> 41, source |->[(56, 41)-(56, 45)], beginSub |-> [], endSub |-> []] -[str |-> ")", type |-> BUILTIN, col |-> 45, source |->[(56, 45)-(56, 46)], beginSub |-> [], endSub |-> []] -null -null -[str |-> "Spec", type |-> IDENT, col |-> 1, source |->[(58, 1)-(58, 5)], beginSub |-> [], endSub |-> []] -[str |-> "==", type |-> BUILTIN, col |-> 6, source |->[(58, 6)-(58, 8)], beginSub |-> [], endSub |-> []] -[str |-> "Init", type |-> IDENT, col |-> 9, source |->[(58, 9)-(58, 13)], beginSub |-> [], endSub |-> []] -[str |-> "/\", type |-> BUILTIN, col |-> 14, source |->[(58, 14)-(58, 16)], beginSub |-> [], endSub |-> []] -[str |-> "[]", type |-> BUILTIN, col |-> 17, source |->[(58, 17)-(58, 19)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 19, source |->[(58, 19)-(58, 20)], beginSub |-> [], endSub |-> []] -[str |-> "Next", type |-> IDENT, col |-> 20, source |->[(58, 20)-(58, 24)], beginSub |-> [], endSub |-> []] -[str |-> "]_", type |-> BUILTIN, col |-> 24, source |->[(58, 24)-(58, 26)], beginSub |-> [], endSub |-> []] -[str |-> "vars", type |-> IDENT, col |-> 26, source |->[(58, 26)-(58, 30)], beginSub |-> [], endSub |-> []] -null -null -[str |-> "Termination", type |-> IDENT, col |-> 1, source |->[(60, 1)-(60, 12)], beginSub |-> [], endSub |-> []] -[str |-> "==", type |-> BUILTIN, col |-> 13, source |->[(60, 13)-(60, 15)], beginSub |-> [], endSub |-> []] -[str |-> "<>", type |-> BUILTIN, col |-> 16, source |->[(60, 16)-(60, 18)], beginSub |-> [], endSub |-> []] -[str |-> "(", type |-> BUILTIN, col |-> 18, source |->[(60, 18)-(60, 19)], beginSub |-> [], endSub |-> []] -[str |-> "pc", type |-> IDENT, col |-> 19, source |->[(60, 19)-(60, 21)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 22, source |->[(60, 22)-(60, 23)], beginSub |-> [], endSub |-> []] -[str |-> "Done", type |-> STRING, col |-> 24, source |->[(60, 24)-(60, 28)], beginSub |-> [], endSub |-> []] -[str |-> ")", type |-> BUILTIN, col |-> 30, source |->[(60, 30)-(60, 31)], beginSub |-> [], endSub |-> []] -null -null -null -[str |-> "===================================================================", type |-> BUILTIN, col |-> 1, source |->[(63, 1)-(63, 68)], beginSub |-> [], endSub |-> []] -null \ No newline at end of file diff --git a/test/tla/tokens/TwoPhaseCommit.tokens b/test/tla/tokens/TwoPhaseCommit.tokens deleted file mode 100644 index afd3fb338..000000000 --- a/test/tla/tokens/TwoPhaseCommit.tokens +++ /dev/null @@ -1,1023 +0,0 @@ -[str |-> "---------------------", type |-> BUILTIN, col |-> 1, source |->[(1, 1)-(1, 22)], beginSub |-> [], endSub |-> []] -[str |-> "MODULE", type |-> BUILTIN, col |-> 23, source |->[(1, 23)-(1, 29)], beginSub |-> [], endSub |-> []] -[str |-> "TwoPhaseCommit", type |-> IDENT, col |-> 30, source |->[(1, 30)-(1, 44)], beginSub |-> [], endSub |-> []] -[str |-> "----------------------", type |-> BUILTIN, col |-> 45, source |->[(1, 45)-(1, 67)], beginSub |-> [], endSub |-> []] -null -[str |-> "EXTENDS", type |-> BUILTIN, col |-> 1, source |->[(2, 1)-(2, 8)], beginSub |-> [], endSub |-> []] -[str |-> "Naturals", type |-> IDENT, col |-> 9, source |->[(2, 9)-(2, 17)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 17, source |->[(2, 17)-(2, 18)], beginSub |-> [], endSub |-> []] -[str |-> "TLC", type |-> IDENT, col |-> 19, source |->[(2, 19)-(2, 22)], beginSub |-> [], endSub |-> []] -null -[str |-> " var managers Set[String] ", type |-> , col |-> 14, source |->[(6, 14)-(6, 40)], beginSub |-> [], endSub |-> []] -[str |-> " var restaurant_stage map[String]String ", type |-> , col |-> 14, source |->[(7, 14)-(7, 54)], beginSub |-> [], endSub |-> []] -[str |-> " func void SetAll() string Set[string] ", type |-> , col |-> 12, source |->[(11, 12)-(11, 51)], beginSub |-> [], endSub |-> []] -null -null -[str |-> "CONSTANT", type |-> BUILTIN, col |-> 1, source |->[(73, 1)-(73, 9)], beginSub |-> [], endSub |-> []] -[str |-> "defaultInitValue", type |-> IDENT, col |-> 10, source |->[(73, 10)-(73, 26)], beginSub |-> [], endSub |-> []] -null -[str |-> "VARIABLES", type |-> BUILTIN, col |-> 1, source |->[(74, 1)-(74, 10)], beginSub |-> [], endSub |-> []] -[str |-> "managers", type |-> IDENT, col |-> 11, source |->[(74, 11)-(74, 19)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 19, source |->[(74, 19)-(74, 20)], beginSub |-> [], endSub |-> []] -[str |-> "restaurant_stage", type |-> IDENT, col |-> 21, source |->[(74, 21)-(74, 37)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 37, source |->[(74, 37)-(74, 38)], beginSub |-> [], endSub |-> []] -[str |-> "pc", type |-> IDENT, col |-> 39, source |->[(74, 39)-(74, 41)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 41, source |->[(74, 41)-(74, 42)], beginSub |-> [], endSub |-> []] -[str |-> "rstMgrs", type |-> IDENT, col |-> 43, source |->[(74, 43)-(74, 50)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 50, source |->[(74, 50)-(74, 51)], beginSub |-> [], endSub |-> []] -[str |-> "aborted", type |-> IDENT, col |-> 52, source |->[(74, 52)-(74, 59)], beginSub |-> [], endSub |-> []] -null -null -[str |-> "vars", type |-> IDENT, col |-> 1, source |->[(76, 1)-(76, 5)], beginSub |-> [], endSub |-> []] -[str |-> "==", type |-> BUILTIN, col |-> 6, source |->[(76, 6)-(76, 8)], beginSub |-> [], endSub |-> []] -[str |-> "<<", type |-> BUILTIN, col |-> 9, source |->[(76, 9)-(76, 11)], beginSub |-> [], endSub |-> []] -[str |-> "managers", type |-> IDENT, col |-> 12, source |->[(76, 12)-(76, 20)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 20, source |->[(76, 20)-(76, 21)], beginSub |-> [], endSub |-> []] -[str |-> "restaurant_stage", type |-> IDENT, col |-> 22, source |->[(76, 22)-(76, 38)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 38, source |->[(76, 38)-(76, 39)], beginSub |-> [], endSub |-> []] -[str |-> "pc", type |-> IDENT, col |-> 40, source |->[(76, 40)-(76, 42)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 42, source |->[(76, 42)-(76, 43)], beginSub |-> [], endSub |-> []] -[str |-> "rstMgrs", type |-> IDENT, col |-> 44, source |->[(76, 44)-(76, 51)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 51, source |->[(76, 51)-(76, 52)], beginSub |-> [], endSub |-> []] -[str |-> "aborted", type |-> IDENT, col |-> 53, source |->[(76, 53)-(76, 60)], beginSub |-> [], endSub |-> []] -[str |-> ">>", type |-> BUILTIN, col |-> 61, source |->[(76, 61)-(76, 63)], beginSub |-> [], endSub |-> []] -null -null -[str |-> "ProcSet", type |-> IDENT, col |-> 1, source |->[(78, 1)-(78, 8)], beginSub |-> [], endSub |-> []] -[str |-> "==", type |-> BUILTIN, col |-> 9, source |->[(78, 9)-(78, 11)], beginSub |-> [], endSub |-> []] -[str |-> "(", type |-> BUILTIN, col |-> 12, source |->[(78, 12)-(78, 13)], beginSub |-> [], endSub |-> []] -[str |-> "managers", type |-> IDENT, col |-> 13, source |->[(78, 13)-(78, 21)], beginSub |-> [], endSub |-> []] -[str |-> ")", type |-> BUILTIN, col |-> 21, source |->[(78, 21)-(78, 22)], beginSub |-> [], endSub |-> []] -[str |-> "\cup", type |-> BUILTIN, col |-> 23, source |->[(78, 23)-(78, 27)], beginSub |-> [], endSub |-> []] -[str |-> "{", type |-> BUILTIN, col |-> 28, source |->[(78, 28)-(78, 29)], beginSub |-> [], endSub |-> []] -[str |-> "alice", type |-> STRING, col |-> 29, source |->[(78, 29)-(78, 34)], beginSub |-> [], endSub |-> []] -[str |-> "}", type |-> BUILTIN, col |-> 36, source |->[(78, 36)-(78, 37)], beginSub |-> [], endSub |-> []] -null -null -[str |-> "Init", type |-> IDENT, col |-> 1, source |->[(80, 1)-(80, 5)], beginSub |-> [], endSub |-> []] -[str |-> "==", type |-> BUILTIN, col |-> 6, source |->[(80, 6)-(80, 8)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 9, source |->[(81, 9)-(81, 11)], beginSub |-> [], endSub |-> []] -[str |-> "managers", type |-> IDENT, col |-> 12, source |->[(81, 12)-(81, 20)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 21, source |->[(81, 21)-(81, 22)], beginSub |-> [], endSub |-> []] -[str |-> "{", type |-> BUILTIN, col |-> 23, source |->[(81, 23)-(81, 24)], beginSub |-> [], endSub |-> []] -[str |-> "bob", type |-> STRING, col |-> 24, source |->[(81, 24)-(81, 27)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 29, source |->[(81, 29)-(81, 30)], beginSub |-> [], endSub |-> []] -[str |-> "chuck", type |-> STRING, col |-> 31, source |->[(81, 31)-(81, 36)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 38, source |->[(81, 38)-(81, 39)], beginSub |-> [], endSub |-> []] -[str |-> "dave", type |-> STRING, col |-> 40, source |->[(81, 40)-(81, 44)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 46, source |->[(81, 46)-(81, 47)], beginSub |-> [], endSub |-> []] -[str |-> "everett", type |-> STRING, col |-> 48, source |->[(81, 48)-(81, 55)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 57, source |->[(81, 57)-(81, 58)], beginSub |-> [], endSub |-> []] -[str |-> "fred", type |-> STRING, col |-> 59, source |->[(81, 59)-(81, 63)], beginSub |-> [], endSub |-> []] -[str |-> "}", type |-> BUILTIN, col |-> 65, source |->[(81, 65)-(81, 66)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 9, source |->[(82, 9)-(82, 11)], beginSub |-> [], endSub |-> []] -[str |-> "restaurant_stage", type |-> IDENT, col |-> 12, source |->[(82, 12)-(82, 28)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 29, source |->[(82, 29)-(82, 30)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 31, source |->[(82, 31)-(82, 32)], beginSub |-> [], endSub |-> []] -[str |-> "mgr", type |-> IDENT, col |-> 32, source |->[(82, 32)-(82, 35)], beginSub |-> [], endSub |-> []] -[str |-> "\in", type |-> BUILTIN, col |-> 36, source |->[(82, 36)-(82, 39)], beginSub |-> [], endSub |-> []] -[str |-> "managers", type |-> IDENT, col |-> 40, source |->[(82, 40)-(82, 48)], beginSub |-> [], endSub |-> []] -[str |-> "|->", type |-> BUILTIN, col |-> 49, source |->[(82, 49)-(82, 52)], beginSub |-> [], endSub |-> []] -[str |-> "start", type |-> STRING, col |-> 53, source |->[(82, 53)-(82, 58)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 60, source |->[(82, 60)-(82, 61)], beginSub |-> [], endSub |-> []] -null -null -[str |-> "/\", type |-> BUILTIN, col |-> 9, source |->[(84, 9)-(84, 11)], beginSub |-> [], endSub |-> []] -[str |-> "rstMgrs", type |-> IDENT, col |-> 12, source |->[(84, 12)-(84, 19)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 20, source |->[(84, 20)-(84, 21)], beginSub |-> [], endSub |-> []] -[str |-> "defaultInitValue", type |-> IDENT, col |-> 22, source |->[(84, 22)-(84, 38)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 9, source |->[(85, 9)-(85, 11)], beginSub |-> [], endSub |-> []] -[str |-> "aborted", type |-> IDENT, col |-> 12, source |->[(85, 12)-(85, 19)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 20, source |->[(85, 20)-(85, 21)], beginSub |-> [], endSub |-> []] -[str |-> "FALSE", type |-> IDENT, col |-> 22, source |->[(85, 22)-(85, 27)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 9, source |->[(86, 9)-(86, 11)], beginSub |-> [], endSub |-> []] -[str |-> "pc", type |-> IDENT, col |-> 12, source |->[(86, 12)-(86, 14)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 15, source |->[(86, 15)-(86, 16)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 17, source |->[(86, 17)-(86, 18)], beginSub |-> [], endSub |-> []] -[str |-> "self", type |-> IDENT, col |-> 18, source |->[(86, 18)-(86, 22)], beginSub |-> [], endSub |-> []] -[str |-> "\in", type |-> BUILTIN, col |-> 23, source |->[(86, 23)-(86, 26)], beginSub |-> [], endSub |-> []] -[str |-> "ProcSet", type |-> IDENT, col |-> 27, source |->[(86, 27)-(86, 34)], beginSub |-> [], endSub |-> []] -[str |-> "|->", type |-> BUILTIN, col |-> 35, source |->[(86, 35)-(86, 38)], beginSub |-> [], endSub |-> []] -[str |-> "CASE", type |-> BUILTIN, col |-> 39, source |->[(86, 39)-(86, 43)], beginSub |-> [], endSub |-> []] -[str |-> "self", type |-> IDENT, col |-> 44, source |->[(86, 44)-(86, 48)], beginSub |-> [], endSub |-> []] -[str |-> "\in", type |-> BUILTIN, col |-> 49, source |->[(86, 49)-(86, 52)], beginSub |-> [], endSub |-> []] -[str |-> "managers", type |-> IDENT, col |-> 53, source |->[(86, 53)-(86, 61)], beginSub |-> [], endSub |-> []] -[str |-> "->", type |-> BUILTIN, col |-> 62, source |->[(86, 62)-(86, 64)], beginSub |-> [], endSub |-> []] -[str |-> "c0", type |-> STRING, col |-> 65, source |->[(86, 65)-(86, 67)], beginSub |-> [], endSub |-> []] -null -[str |-> "[]", type |-> BUILTIN, col |-> 41, source |->[(87, 41)-(87, 43)], beginSub |-> [], endSub |-> []] -[str |-> "self", type |-> IDENT, col |-> 44, source |->[(87, 44)-(87, 48)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 49, source |->[(87, 49)-(87, 50)], beginSub |-> [], endSub |-> []] -[str |-> "alice", type |-> STRING, col |-> 51, source |->[(87, 51)-(87, 56)], beginSub |-> [], endSub |-> []] -[str |-> "->", type |-> BUILTIN, col |-> 59, source |->[(87, 59)-(87, 61)], beginSub |-> [], endSub |-> []] -[str |-> "n0", type |-> STRING, col |-> 62, source |->[(87, 62)-(87, 64)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 66, source |->[(87, 66)-(87, 67)], beginSub |-> [], endSub |-> []] -null -null -[str |-> "c0", type |-> IDENT, col |-> 1, source |->[(89, 1)-(89, 3)], beginSub |-> [], endSub |-> []] -[str |-> "(", type |-> BUILTIN, col |-> 3, source |->[(89, 3)-(89, 4)], beginSub |-> [], endSub |-> []] -[str |-> "self", type |-> IDENT, col |-> 4, source |->[(89, 4)-(89, 8)], beginSub |-> [], endSub |-> []] -[str |-> ")", type |-> BUILTIN, col |-> 8, source |->[(89, 8)-(89, 9)], beginSub |-> [], endSub |-> []] -[str |-> "==", type |-> BUILTIN, col |-> 10, source |->[(89, 10)-(89, 12)], beginSub |-> [], endSub |-> []] -[str |-> "/\", type |-> BUILTIN, col |-> 13, source |->[(89, 13)-(89, 15)], beginSub |-> [], endSub |-> []] -[str |-> "pc", type |-> IDENT, col |-> 16, source |->[(89, 16)-(89, 18)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 18, source |->[(89, 18)-(89, 19)], beginSub |-> [], endSub |-> []] -[str |-> "self", type |-> IDENT, col |-> 19, source |->[(89, 19)-(89, 23)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 23, source |->[(89, 23)-(89, 24)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 25, source |->[(89, 25)-(89, 26)], beginSub |-> [], endSub |-> []] -[str |-> "c0", type |-> STRING, col |-> 27, source |->[(89, 27)-(89, 29)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 13, source |->[(90, 13)-(90, 15)], beginSub |-> [], endSub |-> []] -[str |-> "restaurant_stage", type |-> IDENT, col |-> 16, source |->[(90, 16)-(90, 32)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 32, source |->[(90, 32)-(90, 33)], beginSub |-> [], endSub |-> []] -[str |-> "self", type |-> IDENT, col |-> 33, source |->[(90, 33)-(90, 37)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 37, source |->[(90, 37)-(90, 38)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 39, source |->[(90, 39)-(90, 40)], beginSub |-> [], endSub |-> []] -[str |-> "propose", type |-> STRING, col |-> 41, source |->[(90, 41)-(90, 48)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 13, source |->[(91, 13)-(91, 15)], beginSub |-> [], endSub |-> []] -[str |-> "\/", type |-> BUILTIN, col |-> 16, source |->[(91, 16)-(91, 18)], beginSub |-> [], endSub |-> []] -[str |-> "/\", type |-> BUILTIN, col |-> 19, source |->[(91, 19)-(91, 21)], beginSub |-> [], endSub |-> []] -[str |-> "restaurant_stage", type |-> IDENT, col |-> 22, source |->[(91, 22)-(91, 38)], beginSub |-> [], endSub |-> []] -[str |-> "'", type |-> BUILTIN, col |-> 38, source |->[(91, 38)-(91, 39)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 40, source |->[(91, 40)-(91, 41)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 42, source |->[(91, 42)-(91, 43)], beginSub |-> [], endSub |-> []] -[str |-> "restaurant_stage", type |-> IDENT, col |-> 43, source |->[(91, 43)-(91, 59)], beginSub |-> [], endSub |-> []] -[str |-> "EXCEPT", type |-> BUILTIN, col |-> 60, source |->[(91, 60)-(91, 66)], beginSub |-> [], endSub |-> []] -[str |-> "!", type |-> BUILTIN, col |-> 67, source |->[(91, 67)-(91, 68)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 68, source |->[(91, 68)-(91, 69)], beginSub |-> [], endSub |-> []] -[str |-> "self", type |-> IDENT, col |-> 69, source |->[(91, 69)-(91, 73)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 73, source |->[(91, 73)-(91, 74)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 75, source |->[(91, 75)-(91, 76)], beginSub |-> [], endSub |-> []] -[str |-> "accept", type |-> STRING, col |-> 77, source |->[(91, 77)-(91, 83)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 85, source |->[(91, 85)-(91, 86)], beginSub |-> [], endSub |-> []] -null -[str |-> "\/", type |-> BUILTIN, col |-> 16, source |->[(92, 16)-(92, 18)], beginSub |-> [], endSub |-> []] -[str |-> "/\", type |-> BUILTIN, col |-> 19, source |->[(92, 19)-(92, 21)], beginSub |-> [], endSub |-> []] -[str |-> "restaurant_stage", type |-> IDENT, col |-> 22, source |->[(92, 22)-(92, 38)], beginSub |-> [], endSub |-> []] -[str |-> "'", type |-> BUILTIN, col |-> 38, source |->[(92, 38)-(92, 39)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 40, source |->[(92, 40)-(92, 41)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 42, source |->[(92, 42)-(92, 43)], beginSub |-> [], endSub |-> []] -[str |-> "restaurant_stage", type |-> IDENT, col |-> 43, source |->[(92, 43)-(92, 59)], beginSub |-> [], endSub |-> []] -[str |-> "EXCEPT", type |-> BUILTIN, col |-> 60, source |->[(92, 60)-(92, 66)], beginSub |-> [], endSub |-> []] -[str |-> "!", type |-> BUILTIN, col |-> 67, source |->[(92, 67)-(92, 68)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 68, source |->[(92, 68)-(92, 69)], beginSub |-> [], endSub |-> []] -[str |-> "self", type |-> IDENT, col |-> 69, source |->[(92, 69)-(92, 73)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 73, source |->[(92, 73)-(92, 74)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 75, source |->[(92, 75)-(92, 76)], beginSub |-> [], endSub |-> []] -[str |-> "refuse", type |-> STRING, col |-> 77, source |->[(92, 77)-(92, 83)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 85, source |->[(92, 85)-(92, 86)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 13, source |->[(93, 13)-(93, 15)], beginSub |-> [], endSub |-> []] -[str |-> "pc", type |-> IDENT, col |-> 16, source |->[(93, 16)-(93, 18)], beginSub |-> [], endSub |-> []] -[str |-> "'", type |-> BUILTIN, col |-> 18, source |->[(93, 18)-(93, 19)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 20, source |->[(93, 20)-(93, 21)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 22, source |->[(93, 22)-(93, 23)], beginSub |-> [], endSub |-> []] -[str |-> "pc", type |-> IDENT, col |-> 23, source |->[(93, 23)-(93, 25)], beginSub |-> [], endSub |-> []] -[str |-> "EXCEPT", type |-> BUILTIN, col |-> 26, source |->[(93, 26)-(93, 32)], beginSub |-> [], endSub |-> []] -[str |-> "!", type |-> BUILTIN, col |-> 33, source |->[(93, 33)-(93, 34)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 34, source |->[(93, 34)-(93, 35)], beginSub |-> [], endSub |-> []] -[str |-> "self", type |-> IDENT, col |-> 35, source |->[(93, 35)-(93, 39)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 39, source |->[(93, 39)-(93, 40)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 41, source |->[(93, 41)-(93, 42)], beginSub |-> [], endSub |-> []] -[str |-> "c1", type |-> STRING, col |-> 43, source |->[(93, 43)-(93, 45)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 47, source |->[(93, 47)-(93, 48)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 13, source |->[(94, 13)-(94, 15)], beginSub |-> [], endSub |-> []] -[str |-> "UNCHANGED", type |-> BUILTIN, col |-> 16, source |->[(94, 16)-(94, 25)], beginSub |-> [], endSub |-> []] -[str |-> "<<", type |-> BUILTIN, col |-> 26, source |->[(94, 26)-(94, 28)], beginSub |-> [], endSub |-> []] -[str |-> "managers", type |-> IDENT, col |-> 29, source |->[(94, 29)-(94, 37)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 37, source |->[(94, 37)-(94, 38)], beginSub |-> [], endSub |-> []] -[str |-> "rstMgrs", type |-> IDENT, col |-> 39, source |->[(94, 39)-(94, 46)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 46, source |->[(94, 46)-(94, 47)], beginSub |-> [], endSub |-> []] -[str |-> "aborted", type |-> IDENT, col |-> 48, source |->[(94, 48)-(94, 55)], beginSub |-> [], endSub |-> []] -[str |-> ">>", type |-> BUILTIN, col |-> 56, source |->[(94, 56)-(94, 58)], beginSub |-> [], endSub |-> []] -null -null -[str |-> "c1", type |-> IDENT, col |-> 1, source |->[(96, 1)-(96, 3)], beginSub |-> [], endSub |-> []] -[str |-> "(", type |-> BUILTIN, col |-> 3, source |->[(96, 3)-(96, 4)], beginSub |-> [], endSub |-> []] -[str |-> "self", type |-> IDENT, col |-> 4, source |->[(96, 4)-(96, 8)], beginSub |-> [], endSub |-> []] -[str |-> ")", type |-> BUILTIN, col |-> 8, source |->[(96, 8)-(96, 9)], beginSub |-> [], endSub |-> []] -[str |-> "==", type |-> BUILTIN, col |-> 10, source |->[(96, 10)-(96, 12)], beginSub |-> [], endSub |-> []] -[str |-> "/\", type |-> BUILTIN, col |-> 13, source |->[(96, 13)-(96, 15)], beginSub |-> [], endSub |-> []] -[str |-> "pc", type |-> IDENT, col |-> 16, source |->[(96, 16)-(96, 18)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 18, source |->[(96, 18)-(96, 19)], beginSub |-> [], endSub |-> []] -[str |-> "self", type |-> IDENT, col |-> 19, source |->[(96, 19)-(96, 23)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 23, source |->[(96, 23)-(96, 24)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 25, source |->[(96, 25)-(96, 26)], beginSub |-> [], endSub |-> []] -[str |-> "c1", type |-> STRING, col |-> 27, source |->[(96, 27)-(96, 29)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 13, source |->[(97, 13)-(97, 15)], beginSub |-> [], endSub |-> []] -[str |-> "(", type |-> BUILTIN, col |-> 16, source |->[(97, 16)-(97, 17)], beginSub |-> [], endSub |-> []] -[str |-> "restaurant_stage", type |-> IDENT, col |-> 17, source |->[(97, 17)-(97, 33)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 33, source |->[(97, 33)-(97, 34)], beginSub |-> [], endSub |-> []] -[str |-> "self", type |-> IDENT, col |-> 34, source |->[(97, 34)-(97, 38)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 38, source |->[(97, 38)-(97, 39)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 40, source |->[(97, 40)-(97, 41)], beginSub |-> [], endSub |-> []] -[str |-> "commit", type |-> STRING, col |-> 42, source |->[(97, 42)-(97, 48)], beginSub |-> [], endSub |-> []] -[str |-> ")", type |-> BUILTIN, col |-> 50, source |->[(97, 50)-(97, 51)], beginSub |-> [], endSub |-> []] -[str |-> "\/", type |-> BUILTIN, col |-> 52, source |->[(97, 52)-(97, 54)], beginSub |-> [], endSub |-> []] -null -[str |-> "(", type |-> BUILTIN, col |-> 16, source |->[(98, 16)-(98, 17)], beginSub |-> [], endSub |-> []] -[str |-> "restaurant_stage", type |-> IDENT, col |-> 17, source |->[(98, 17)-(98, 33)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 33, source |->[(98, 33)-(98, 34)], beginSub |-> [], endSub |-> []] -[str |-> "self", type |-> IDENT, col |-> 34, source |->[(98, 34)-(98, 38)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 38, source |->[(98, 38)-(98, 39)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 40, source |->[(98, 40)-(98, 41)], beginSub |-> [], endSub |-> []] -[str |-> "abort", type |-> STRING, col |-> 42, source |->[(98, 42)-(98, 47)], beginSub |-> [], endSub |-> []] -[str |-> ")", type |-> BUILTIN, col |-> 49, source |->[(98, 49)-(98, 50)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 13, source |->[(99, 13)-(99, 15)], beginSub |-> [], endSub |-> []] -[str |-> "IF", type |-> BUILTIN, col |-> 16, source |->[(99, 16)-(99, 18)], beginSub |-> [], endSub |-> []] -[str |-> "restaurant_stage", type |-> IDENT, col |-> 19, source |->[(99, 19)-(99, 35)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 35, source |->[(99, 35)-(99, 36)], beginSub |-> [], endSub |-> []] -[str |-> "self", type |-> IDENT, col |-> 36, source |->[(99, 36)-(99, 40)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 40, source |->[(99, 40)-(99, 41)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 42, source |->[(99, 42)-(99, 43)], beginSub |-> [], endSub |-> []] -[str |-> "commit", type |-> STRING, col |-> 44, source |->[(99, 44)-(99, 50)], beginSub |-> [], endSub |-> []] -null -[str |-> "THEN", type |-> BUILTIN, col |-> 19, source |->[(100, 19)-(100, 23)], beginSub |-> [], endSub |-> []] -[str |-> "/\", type |-> BUILTIN, col |-> 24, source |->[(100, 24)-(100, 26)], beginSub |-> [], endSub |-> []] -[str |-> "restaurant_stage", type |-> IDENT, col |-> 27, source |->[(100, 27)-(100, 43)], beginSub |-> [], endSub |-> []] -[str |-> "'", type |-> BUILTIN, col |-> 43, source |->[(100, 43)-(100, 44)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 45, source |->[(100, 45)-(100, 46)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 47, source |->[(100, 47)-(100, 48)], beginSub |-> [], endSub |-> []] -[str |-> "restaurant_stage", type |-> IDENT, col |-> 48, source |->[(100, 48)-(100, 64)], beginSub |-> [], endSub |-> []] -[str |-> "EXCEPT", type |-> BUILTIN, col |-> 65, source |->[(100, 65)-(100, 71)], beginSub |-> [], endSub |-> []] -[str |-> "!", type |-> BUILTIN, col |-> 72, source |->[(100, 72)-(100, 73)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 73, source |->[(100, 73)-(100, 74)], beginSub |-> [], endSub |-> []] -[str |-> "self", type |-> IDENT, col |-> 74, source |->[(100, 74)-(100, 78)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 78, source |->[(100, 78)-(100, 79)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 80, source |->[(100, 80)-(100, 81)], beginSub |-> [], endSub |-> []] -[str |-> "committed", type |-> STRING, col |-> 82, source |->[(100, 82)-(100, 91)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 93, source |->[(100, 93)-(100, 94)], beginSub |-> [], endSub |-> []] -null -[str |-> "ELSE", type |-> BUILTIN, col |-> 19, source |->[(101, 19)-(101, 23)], beginSub |-> [], endSub |-> []] -[str |-> "/\", type |-> BUILTIN, col |-> 24, source |->[(101, 24)-(101, 26)], beginSub |-> [], endSub |-> []] -[str |-> "restaurant_stage", type |-> IDENT, col |-> 27, source |->[(101, 27)-(101, 43)], beginSub |-> [], endSub |-> []] -[str |-> "'", type |-> BUILTIN, col |-> 43, source |->[(101, 43)-(101, 44)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 45, source |->[(101, 45)-(101, 46)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 47, source |->[(101, 47)-(101, 48)], beginSub |-> [], endSub |-> []] -[str |-> "restaurant_stage", type |-> IDENT, col |-> 48, source |->[(101, 48)-(101, 64)], beginSub |-> [], endSub |-> []] -[str |-> "EXCEPT", type |-> BUILTIN, col |-> 65, source |->[(101, 65)-(101, 71)], beginSub |-> [], endSub |-> []] -[str |-> "!", type |-> BUILTIN, col |-> 72, source |->[(101, 72)-(101, 73)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 73, source |->[(101, 73)-(101, 74)], beginSub |-> [], endSub |-> []] -[str |-> "self", type |-> IDENT, col |-> 74, source |->[(101, 74)-(101, 78)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 78, source |->[(101, 78)-(101, 79)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 80, source |->[(101, 80)-(101, 81)], beginSub |-> [], endSub |-> []] -[str |-> "aborted", type |-> STRING, col |-> 82, source |->[(101, 82)-(101, 89)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 91, source |->[(101, 91)-(101, 92)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 13, source |->[(102, 13)-(102, 15)], beginSub |-> [], endSub |-> []] -[str |-> "pc", type |-> IDENT, col |-> 16, source |->[(102, 16)-(102, 18)], beginSub |-> [], endSub |-> []] -[str |-> "'", type |-> BUILTIN, col |-> 18, source |->[(102, 18)-(102, 19)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 20, source |->[(102, 20)-(102, 21)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 22, source |->[(102, 22)-(102, 23)], beginSub |-> [], endSub |-> []] -[str |-> "pc", type |-> IDENT, col |-> 23, source |->[(102, 23)-(102, 25)], beginSub |-> [], endSub |-> []] -[str |-> "EXCEPT", type |-> BUILTIN, col |-> 26, source |->[(102, 26)-(102, 32)], beginSub |-> [], endSub |-> []] -[str |-> "!", type |-> BUILTIN, col |-> 33, source |->[(102, 33)-(102, 34)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 34, source |->[(102, 34)-(102, 35)], beginSub |-> [], endSub |-> []] -[str |-> "self", type |-> IDENT, col |-> 35, source |->[(102, 35)-(102, 39)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 39, source |->[(102, 39)-(102, 40)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 41, source |->[(102, 41)-(102, 42)], beginSub |-> [], endSub |-> []] -[str |-> "Done", type |-> STRING, col |-> 43, source |->[(102, 43)-(102, 47)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 49, source |->[(102, 49)-(102, 50)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 13, source |->[(103, 13)-(103, 15)], beginSub |-> [], endSub |-> []] -[str |-> "UNCHANGED", type |-> BUILTIN, col |-> 16, source |->[(103, 16)-(103, 25)], beginSub |-> [], endSub |-> []] -[str |-> "<<", type |-> BUILTIN, col |-> 26, source |->[(103, 26)-(103, 28)], beginSub |-> [], endSub |-> []] -[str |-> "managers", type |-> IDENT, col |-> 29, source |->[(103, 29)-(103, 37)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 37, source |->[(103, 37)-(103, 38)], beginSub |-> [], endSub |-> []] -[str |-> "rstMgrs", type |-> IDENT, col |-> 39, source |->[(103, 39)-(103, 46)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 46, source |->[(103, 46)-(103, 47)], beginSub |-> [], endSub |-> []] -[str |-> "aborted", type |-> IDENT, col |-> 48, source |->[(103, 48)-(103, 55)], beginSub |-> [], endSub |-> []] -[str |-> ">>", type |-> BUILTIN, col |-> 56, source |->[(103, 56)-(103, 58)], beginSub |-> [], endSub |-> []] -null -null -[str |-> "Restaurant", type |-> IDENT, col |-> 1, source |->[(105, 1)-(105, 11)], beginSub |-> [], endSub |-> []] -[str |-> "(", type |-> BUILTIN, col |-> 11, source |->[(105, 11)-(105, 12)], beginSub |-> [], endSub |-> []] -[str |-> "self", type |-> IDENT, col |-> 12, source |->[(105, 12)-(105, 16)], beginSub |-> [], endSub |-> []] -[str |-> ")", type |-> BUILTIN, col |-> 16, source |->[(105, 16)-(105, 17)], beginSub |-> [], endSub |-> []] -[str |-> "==", type |-> BUILTIN, col |-> 18, source |->[(105, 18)-(105, 20)], beginSub |-> [], endSub |-> []] -[str |-> "c0", type |-> IDENT, col |-> 21, source |->[(105, 21)-(105, 23)], beginSub |-> [], endSub |-> []] -[str |-> "(", type |-> BUILTIN, col |-> 23, source |->[(105, 23)-(105, 24)], beginSub |-> [], endSub |-> []] -[str |-> "self", type |-> IDENT, col |-> 24, source |->[(105, 24)-(105, 28)], beginSub |-> [], endSub |-> []] -[str |-> ")", type |-> BUILTIN, col |-> 28, source |->[(105, 28)-(105, 29)], beginSub |-> [], endSub |-> []] -[str |-> "\/", type |-> BUILTIN, col |-> 30, source |->[(105, 30)-(105, 32)], beginSub |-> [], endSub |-> []] -[str |-> "c1", type |-> IDENT, col |-> 33, source |->[(105, 33)-(105, 35)], beginSub |-> [], endSub |-> []] -[str |-> "(", type |-> BUILTIN, col |-> 35, source |->[(105, 35)-(105, 36)], beginSub |-> [], endSub |-> []] -[str |-> "self", type |-> IDENT, col |-> 36, source |->[(105, 36)-(105, 40)], beginSub |-> [], endSub |-> []] -[str |-> ")", type |-> BUILTIN, col |-> 40, source |->[(105, 40)-(105, 41)], beginSub |-> [], endSub |-> []] -null -null -[str |-> "n0", type |-> IDENT, col |-> 1, source |->[(107, 1)-(107, 3)], beginSub |-> [], endSub |-> []] -[str |-> "==", type |-> BUILTIN, col |-> 4, source |->[(107, 4)-(107, 6)], beginSub |-> [], endSub |-> []] -[str |-> "/\", type |-> BUILTIN, col |-> 7, source |->[(107, 7)-(107, 9)], beginSub |-> [], endSub |-> []] -[str |-> "pc", type |-> IDENT, col |-> 10, source |->[(107, 10)-(107, 12)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 12, source |->[(107, 12)-(107, 13)], beginSub |-> [], endSub |-> []] -[str |-> "alice", type |-> STRING, col |-> 13, source |->[(107, 13)-(107, 18)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 20, source |->[(107, 20)-(107, 21)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 22, source |->[(107, 22)-(107, 23)], beginSub |-> [], endSub |-> []] -[str |-> "n0", type |-> STRING, col |-> 24, source |->[(107, 24)-(107, 26)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 7, source |->[(108, 7)-(108, 9)], beginSub |-> [], endSub |-> []] -[str |-> "rstMgrs", type |-> IDENT, col |-> 10, source |->[(108, 10)-(108, 17)], beginSub |-> [], endSub |-> []] -[str |-> "'", type |-> BUILTIN, col |-> 17, source |->[(108, 17)-(108, 18)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 19, source |->[(108, 19)-(108, 20)], beginSub |-> [], endSub |-> []] -[str |-> "managers", type |-> IDENT, col |-> 21, source |->[(108, 21)-(108, 29)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 7, source |->[(109, 7)-(109, 9)], beginSub |-> [], endSub |-> []] -[str |-> "pc", type |-> IDENT, col |-> 10, source |->[(109, 10)-(109, 12)], beginSub |-> [], endSub |-> []] -[str |-> "'", type |-> BUILTIN, col |-> 12, source |->[(109, 12)-(109, 13)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 14, source |->[(109, 14)-(109, 15)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 16, source |->[(109, 16)-(109, 17)], beginSub |-> [], endSub |-> []] -[str |-> "pc", type |-> IDENT, col |-> 17, source |->[(109, 17)-(109, 19)], beginSub |-> [], endSub |-> []] -[str |-> "EXCEPT", type |-> BUILTIN, col |-> 20, source |->[(109, 20)-(109, 26)], beginSub |-> [], endSub |-> []] -[str |-> "!", type |-> BUILTIN, col |-> 27, source |->[(109, 27)-(109, 28)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 28, source |->[(109, 28)-(109, 29)], beginSub |-> [], endSub |-> []] -[str |-> "alice", type |-> STRING, col |-> 29, source |->[(109, 29)-(109, 34)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 36, source |->[(109, 36)-(109, 37)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 38, source |->[(109, 38)-(109, 39)], beginSub |-> [], endSub |-> []] -[str |-> "n1", type |-> STRING, col |-> 40, source |->[(109, 40)-(109, 42)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 44, source |->[(109, 44)-(109, 45)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 7, source |->[(110, 7)-(110, 9)], beginSub |-> [], endSub |-> []] -[str |-> "UNCHANGED", type |-> BUILTIN, col |-> 10, source |->[(110, 10)-(110, 19)], beginSub |-> [], endSub |-> []] -[str |-> "<<", type |-> BUILTIN, col |-> 20, source |->[(110, 20)-(110, 22)], beginSub |-> [], endSub |-> []] -[str |-> "managers", type |-> IDENT, col |-> 23, source |->[(110, 23)-(110, 31)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 31, source |->[(110, 31)-(110, 32)], beginSub |-> [], endSub |-> []] -[str |-> "restaurant_stage", type |-> IDENT, col |-> 33, source |->[(110, 33)-(110, 49)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 49, source |->[(110, 49)-(110, 50)], beginSub |-> [], endSub |-> []] -[str |-> "aborted", type |-> IDENT, col |-> 51, source |->[(110, 51)-(110, 58)], beginSub |-> [], endSub |-> []] -[str |-> ">>", type |-> BUILTIN, col |-> 59, source |->[(110, 59)-(110, 61)], beginSub |-> [], endSub |-> []] -null -null -[str |-> "n1", type |-> IDENT, col |-> 1, source |->[(112, 1)-(112, 3)], beginSub |-> [], endSub |-> []] -[str |-> "==", type |-> BUILTIN, col |-> 4, source |->[(112, 4)-(112, 6)], beginSub |-> [], endSub |-> []] -[str |-> "/\", type |-> BUILTIN, col |-> 7, source |->[(112, 7)-(112, 9)], beginSub |-> [], endSub |-> []] -[str |-> "pc", type |-> IDENT, col |-> 10, source |->[(112, 10)-(112, 12)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 12, source |->[(112, 12)-(112, 13)], beginSub |-> [], endSub |-> []] -[str |-> "alice", type |-> STRING, col |-> 13, source |->[(112, 13)-(112, 18)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 20, source |->[(112, 20)-(112, 21)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 22, source |->[(112, 22)-(112, 23)], beginSub |-> [], endSub |-> []] -[str |-> "n1", type |-> STRING, col |-> 24, source |->[(112, 24)-(112, 26)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 7, source |->[(113, 7)-(113, 9)], beginSub |-> [], endSub |-> []] -[str |-> "IF", type |-> BUILTIN, col |-> 10, source |->[(113, 10)-(113, 12)], beginSub |-> [], endSub |-> []] -[str |-> "rstMgrs", type |-> IDENT, col |-> 13, source |->[(113, 13)-(113, 20)], beginSub |-> [], endSub |-> []] -[str |-> "#", type |-> BUILTIN, col |-> 21, source |->[(113, 21)-(113, 22)], beginSub |-> [], endSub |-> []] -[str |-> "{", type |-> BUILTIN, col |-> 23, source |->[(113, 23)-(113, 24)], beginSub |-> [], endSub |-> []] -[str |-> "}", type |-> BUILTIN, col |-> 24, source |->[(113, 24)-(113, 25)], beginSub |-> [], endSub |-> []] -null -[str |-> "THEN", type |-> BUILTIN, col |-> 13, source |->[(114, 13)-(114, 17)], beginSub |-> [], endSub |-> []] -[str |-> "/\", type |-> BUILTIN, col |-> 18, source |->[(114, 18)-(114, 20)], beginSub |-> [], endSub |-> []] -[str |-> "\E", type |-> BUILTIN, col |-> 21, source |->[(114, 21)-(114, 23)], beginSub |-> [], endSub |-> []] -[str |-> "km", type |-> IDENT, col |-> 24, source |->[(114, 24)-(114, 26)], beginSub |-> [], endSub |-> []] -[str |-> "\in", type |-> BUILTIN, col |-> 27, source |->[(114, 27)-(114, 30)], beginSub |-> [], endSub |-> []] -[str |-> "rstMgrs", type |-> IDENT, col |-> 31, source |->[(114, 31)-(114, 38)], beginSub |-> [], endSub |-> []] -[str |-> ":", type |-> BUILTIN, col |-> 38, source |->[(114, 38)-(114, 39)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 23, source |->[(115, 23)-(115, 25)], beginSub |-> [], endSub |-> []] -[str |-> "restaurant_stage", type |-> IDENT, col |-> 26, source |->[(115, 26)-(115, 42)], beginSub |-> [], endSub |-> []] -[str |-> "'", type |-> BUILTIN, col |-> 42, source |->[(115, 42)-(115, 43)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 44, source |->[(115, 44)-(115, 45)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 46, source |->[(115, 46)-(115, 47)], beginSub |-> [], endSub |-> []] -[str |-> "restaurant_stage", type |-> IDENT, col |-> 47, source |->[(115, 47)-(115, 63)], beginSub |-> [], endSub |-> []] -[str |-> "EXCEPT", type |-> BUILTIN, col |-> 64, source |->[(115, 64)-(115, 70)], beginSub |-> [], endSub |-> []] -[str |-> "!", type |-> BUILTIN, col |-> 71, source |->[(115, 71)-(115, 72)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 72, source |->[(115, 72)-(115, 73)], beginSub |-> [], endSub |-> []] -[str |-> "km", type |-> IDENT, col |-> 73, source |->[(115, 73)-(115, 75)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 75, source |->[(115, 75)-(115, 76)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 77, source |->[(115, 77)-(115, 78)], beginSub |-> [], endSub |-> []] -[str |-> "propose", type |-> STRING, col |-> 79, source |->[(115, 79)-(115, 86)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 88, source |->[(115, 88)-(115, 89)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 23, source |->[(116, 23)-(116, 25)], beginSub |-> [], endSub |-> []] -[str |-> "rstMgrs", type |-> IDENT, col |-> 26, source |->[(116, 26)-(116, 33)], beginSub |-> [], endSub |-> []] -[str |-> "'", type |-> BUILTIN, col |-> 33, source |->[(116, 33)-(116, 34)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 35, source |->[(116, 35)-(116, 36)], beginSub |-> [], endSub |-> []] -[str |-> "rstMgrs", type |-> IDENT, col |-> 37, source |->[(116, 37)-(116, 44)], beginSub |-> [], endSub |-> []] -[str |-> "\", type |-> BUILTIN, col |-> 45, source |->[(116, 45)-(116, 46)], beginSub |-> [], endSub |-> []] -[str |-> "{", type |-> BUILTIN, col |-> 47, source |->[(116, 47)-(116, 48)], beginSub |-> [], endSub |-> []] -[str |-> "km", type |-> IDENT, col |-> 48, source |->[(116, 48)-(116, 50)], beginSub |-> [], endSub |-> []] -[str |-> "}", type |-> BUILTIN, col |-> 50, source |->[(116, 50)-(116, 51)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 18, source |->[(117, 18)-(117, 20)], beginSub |-> [], endSub |-> []] -[str |-> "pc", type |-> IDENT, col |-> 21, source |->[(117, 21)-(117, 23)], beginSub |-> [], endSub |-> []] -[str |-> "'", type |-> BUILTIN, col |-> 23, source |->[(117, 23)-(117, 24)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 25, source |->[(117, 25)-(117, 26)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 27, source |->[(117, 27)-(117, 28)], beginSub |-> [], endSub |-> []] -[str |-> "pc", type |-> IDENT, col |-> 28, source |->[(117, 28)-(117, 30)], beginSub |-> [], endSub |-> []] -[str |-> "EXCEPT", type |-> BUILTIN, col |-> 31, source |->[(117, 31)-(117, 37)], beginSub |-> [], endSub |-> []] -[str |-> "!", type |-> BUILTIN, col |-> 38, source |->[(117, 38)-(117, 39)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 39, source |->[(117, 39)-(117, 40)], beginSub |-> [], endSub |-> []] -[str |-> "alice", type |-> STRING, col |-> 40, source |->[(117, 40)-(117, 45)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 47, source |->[(117, 47)-(117, 48)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 49, source |->[(117, 49)-(117, 50)], beginSub |-> [], endSub |-> []] -[str |-> "n1", type |-> STRING, col |-> 51, source |->[(117, 51)-(117, 53)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 55, source |->[(117, 55)-(117, 56)], beginSub |-> [], endSub |-> []] -null -[str |-> "ELSE", type |-> BUILTIN, col |-> 13, source |->[(118, 13)-(118, 17)], beginSub |-> [], endSub |-> []] -[str |-> "/\", type |-> BUILTIN, col |-> 18, source |->[(118, 18)-(118, 20)], beginSub |-> [], endSub |-> []] -[str |-> "rstMgrs", type |-> IDENT, col |-> 21, source |->[(118, 21)-(118, 28)], beginSub |-> [], endSub |-> []] -[str |-> "'", type |-> BUILTIN, col |-> 28, source |->[(118, 28)-(118, 29)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 30, source |->[(118, 30)-(118, 31)], beginSub |-> [], endSub |-> []] -[str |-> "managers", type |-> IDENT, col |-> 32, source |->[(118, 32)-(118, 40)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 18, source |->[(119, 18)-(119, 20)], beginSub |-> [], endSub |-> []] -[str |-> "pc", type |-> IDENT, col |-> 21, source |->[(119, 21)-(119, 23)], beginSub |-> [], endSub |-> []] -[str |-> "'", type |-> BUILTIN, col |-> 23, source |->[(119, 23)-(119, 24)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 25, source |->[(119, 25)-(119, 26)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 27, source |->[(119, 27)-(119, 28)], beginSub |-> [], endSub |-> []] -[str |-> "pc", type |-> IDENT, col |-> 28, source |->[(119, 28)-(119, 30)], beginSub |-> [], endSub |-> []] -[str |-> "EXCEPT", type |-> BUILTIN, col |-> 31, source |->[(119, 31)-(119, 37)], beginSub |-> [], endSub |-> []] -[str |-> "!", type |-> BUILTIN, col |-> 38, source |->[(119, 38)-(119, 39)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 39, source |->[(119, 39)-(119, 40)], beginSub |-> [], endSub |-> []] -[str |-> "alice", type |-> STRING, col |-> 40, source |->[(119, 40)-(119, 45)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 47, source |->[(119, 47)-(119, 48)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 49, source |->[(119, 49)-(119, 50)], beginSub |-> [], endSub |-> []] -[str |-> "n3", type |-> STRING, col |-> 51, source |->[(119, 51)-(119, 53)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 55, source |->[(119, 55)-(119, 56)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 18, source |->[(120, 18)-(120, 20)], beginSub |-> [], endSub |-> []] -[str |-> "UNCHANGED", type |-> BUILTIN, col |-> 21, source |->[(120, 21)-(120, 30)], beginSub |-> [], endSub |-> []] -[str |-> "restaurant_stage", type |-> IDENT, col |-> 31, source |->[(120, 31)-(120, 47)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 7, source |->[(121, 7)-(121, 9)], beginSub |-> [], endSub |-> []] -[str |-> "UNCHANGED", type |-> BUILTIN, col |-> 10, source |->[(121, 10)-(121, 19)], beginSub |-> [], endSub |-> []] -[str |-> "<<", type |-> BUILTIN, col |-> 20, source |->[(121, 20)-(121, 22)], beginSub |-> [], endSub |-> []] -[str |-> "managers", type |-> IDENT, col |-> 23, source |->[(121, 23)-(121, 31)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 31, source |->[(121, 31)-(121, 32)], beginSub |-> [], endSub |-> []] -[str |-> "aborted", type |-> IDENT, col |-> 33, source |->[(121, 33)-(121, 40)], beginSub |-> [], endSub |-> []] -[str |-> ">>", type |-> BUILTIN, col |-> 41, source |->[(121, 41)-(121, 43)], beginSub |-> [], endSub |-> []] -null -null -[str |-> "n3", type |-> IDENT, col |-> 1, source |->[(123, 1)-(123, 3)], beginSub |-> [], endSub |-> []] -[str |-> "==", type |-> BUILTIN, col |-> 4, source |->[(123, 4)-(123, 6)], beginSub |-> [], endSub |-> []] -[str |-> "/\", type |-> BUILTIN, col |-> 7, source |->[(123, 7)-(123, 9)], beginSub |-> [], endSub |-> []] -[str |-> "pc", type |-> IDENT, col |-> 10, source |->[(123, 10)-(123, 12)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 12, source |->[(123, 12)-(123, 13)], beginSub |-> [], endSub |-> []] -[str |-> "alice", type |-> STRING, col |-> 13, source |->[(123, 13)-(123, 18)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 20, source |->[(123, 20)-(123, 21)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 22, source |->[(123, 22)-(123, 23)], beginSub |-> [], endSub |-> []] -[str |-> "n3", type |-> STRING, col |-> 24, source |->[(123, 24)-(123, 26)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 7, source |->[(124, 7)-(124, 9)], beginSub |-> [], endSub |-> []] -[str |-> "IF", type |-> BUILTIN, col |-> 10, source |->[(124, 10)-(124, 12)], beginSub |-> [], endSub |-> []] -[str |-> "rstMgrs", type |-> IDENT, col |-> 13, source |->[(124, 13)-(124, 20)], beginSub |-> [], endSub |-> []] -[str |-> "#", type |-> BUILTIN, col |-> 21, source |->[(124, 21)-(124, 22)], beginSub |-> [], endSub |-> []] -[str |-> "{", type |-> BUILTIN, col |-> 23, source |->[(124, 23)-(124, 24)], beginSub |-> [], endSub |-> []] -[str |-> "}", type |-> BUILTIN, col |-> 24, source |->[(124, 24)-(124, 25)], beginSub |-> [], endSub |-> []] -null -[str |-> "THEN", type |-> BUILTIN, col |-> 13, source |->[(125, 13)-(125, 17)], beginSub |-> [], endSub |-> []] -[str |-> "/\", type |-> BUILTIN, col |-> 18, source |->[(125, 18)-(125, 20)], beginSub |-> [], endSub |-> []] -[str |-> "\E", type |-> BUILTIN, col |-> 21, source |->[(125, 21)-(125, 23)], beginSub |-> [], endSub |-> []] -[str |-> "r", type |-> IDENT, col |-> 24, source |->[(125, 24)-(125, 25)], beginSub |-> [], endSub |-> []] -[str |-> "\in", type |-> BUILTIN, col |-> 26, source |->[(125, 26)-(125, 29)], beginSub |-> [], endSub |-> []] -[str |-> "rstMgrs", type |-> IDENT, col |-> 30, source |->[(125, 30)-(125, 37)], beginSub |-> [], endSub |-> []] -[str |-> ":", type |-> BUILTIN, col |-> 37, source |->[(125, 37)-(125, 38)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 23, source |->[(126, 23)-(126, 25)], beginSub |-> [], endSub |-> []] -[str |-> "(", type |-> BUILTIN, col |-> 26, source |->[(126, 26)-(126, 27)], beginSub |-> [], endSub |-> []] -[str |-> "restaurant_stage", type |-> IDENT, col |-> 27, source |->[(126, 27)-(126, 43)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 43, source |->[(126, 43)-(126, 44)], beginSub |-> [], endSub |-> []] -[str |-> "r", type |-> IDENT, col |-> 44, source |->[(126, 44)-(126, 45)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 45, source |->[(126, 45)-(126, 46)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 47, source |->[(126, 47)-(126, 48)], beginSub |-> [], endSub |-> []] -[str |-> "accept", type |-> STRING, col |-> 49, source |->[(126, 49)-(126, 55)], beginSub |-> [], endSub |-> []] -[str |-> ")", type |-> BUILTIN, col |-> 57, source |->[(126, 57)-(126, 58)], beginSub |-> [], endSub |-> []] -[str |-> "\/", type |-> BUILTIN, col |-> 59, source |->[(126, 59)-(126, 61)], beginSub |-> [], endSub |-> []] -[str |-> "(", type |-> BUILTIN, col |-> 62, source |->[(126, 62)-(126, 63)], beginSub |-> [], endSub |-> []] -[str |-> "restaurant_stage", type |-> IDENT, col |-> 63, source |->[(126, 63)-(126, 79)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 79, source |->[(126, 79)-(126, 80)], beginSub |-> [], endSub |-> []] -[str |-> "r", type |-> IDENT, col |-> 80, source |->[(126, 80)-(126, 81)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 81, source |->[(126, 81)-(126, 82)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 83, source |->[(126, 83)-(126, 84)], beginSub |-> [], endSub |-> []] -[str |-> "refuse", type |-> STRING, col |-> 85, source |->[(126, 85)-(126, 91)], beginSub |-> [], endSub |-> []] -[str |-> ")", type |-> BUILTIN, col |-> 93, source |->[(126, 93)-(126, 94)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 23, source |->[(127, 23)-(127, 25)], beginSub |-> [], endSub |-> []] -[str |-> "IF", type |-> BUILTIN, col |-> 26, source |->[(127, 26)-(127, 28)], beginSub |-> [], endSub |-> []] -[str |-> "(", type |-> BUILTIN, col |-> 29, source |->[(127, 29)-(127, 30)], beginSub |-> [], endSub |-> []] -[str |-> "restaurant_stage", type |-> IDENT, col |-> 30, source |->[(127, 30)-(127, 46)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 46, source |->[(127, 46)-(127, 47)], beginSub |-> [], endSub |-> []] -[str |-> "r", type |-> IDENT, col |-> 47, source |->[(127, 47)-(127, 48)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 48, source |->[(127, 48)-(127, 49)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 50, source |->[(127, 50)-(127, 51)], beginSub |-> [], endSub |-> []] -[str |-> "refuse", type |-> STRING, col |-> 52, source |->[(127, 52)-(127, 58)], beginSub |-> [], endSub |-> []] -[str |-> ")", type |-> BUILTIN, col |-> 60, source |->[(127, 60)-(127, 61)], beginSub |-> [], endSub |-> []] -null -[str |-> "THEN", type |-> BUILTIN, col |-> 29, source |->[(128, 29)-(128, 33)], beginSub |-> [], endSub |-> []] -[str |-> "/\", type |-> BUILTIN, col |-> 34, source |->[(128, 34)-(128, 36)], beginSub |-> [], endSub |-> []] -[str |-> "aborted", type |-> IDENT, col |-> 37, source |->[(128, 37)-(128, 44)], beginSub |-> [], endSub |-> []] -[str |-> "'", type |-> BUILTIN, col |-> 44, source |->[(128, 44)-(128, 45)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 46, source |->[(128, 46)-(128, 47)], beginSub |-> [], endSub |-> []] -[str |-> "TRUE", type |-> IDENT, col |-> 48, source |->[(128, 48)-(128, 52)], beginSub |-> [], endSub |-> []] -null -[str |-> "ELSE", type |-> BUILTIN, col |-> 29, source |->[(129, 29)-(129, 33)], beginSub |-> [], endSub |-> []] -[str |-> "/\", type |-> BUILTIN, col |-> 34, source |->[(129, 34)-(129, 36)], beginSub |-> [], endSub |-> []] -[str |-> "TRUE", type |-> IDENT, col |-> 37, source |->[(129, 37)-(129, 41)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 34, source |->[(130, 34)-(130, 36)], beginSub |-> [], endSub |-> []] -[str |-> "UNCHANGED", type |-> BUILTIN, col |-> 37, source |->[(130, 37)-(130, 46)], beginSub |-> [], endSub |-> []] -[str |-> "aborted", type |-> IDENT, col |-> 47, source |->[(130, 47)-(130, 54)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 23, source |->[(131, 23)-(131, 25)], beginSub |-> [], endSub |-> []] -[str |-> "rstMgrs", type |-> IDENT, col |-> 26, source |->[(131, 26)-(131, 33)], beginSub |-> [], endSub |-> []] -[str |-> "'", type |-> BUILTIN, col |-> 33, source |->[(131, 33)-(131, 34)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 35, source |->[(131, 35)-(131, 36)], beginSub |-> [], endSub |-> []] -[str |-> "rstMgrs", type |-> IDENT, col |-> 37, source |->[(131, 37)-(131, 44)], beginSub |-> [], endSub |-> []] -[str |-> "\", type |-> BUILTIN, col |-> 45, source |->[(131, 45)-(131, 46)], beginSub |-> [], endSub |-> []] -[str |-> "{", type |-> BUILTIN, col |-> 47, source |->[(131, 47)-(131, 48)], beginSub |-> [], endSub |-> []] -[str |-> "r", type |-> IDENT, col |-> 48, source |->[(131, 48)-(131, 49)], beginSub |-> [], endSub |-> []] -[str |-> "}", type |-> BUILTIN, col |-> 49, source |->[(131, 49)-(131, 50)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 18, source |->[(132, 18)-(132, 20)], beginSub |-> [], endSub |-> []] -[str |-> "pc", type |-> IDENT, col |-> 21, source |->[(132, 21)-(132, 23)], beginSub |-> [], endSub |-> []] -[str |-> "'", type |-> BUILTIN, col |-> 23, source |->[(132, 23)-(132, 24)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 25, source |->[(132, 25)-(132, 26)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 27, source |->[(132, 27)-(132, 28)], beginSub |-> [], endSub |-> []] -[str |-> "pc", type |-> IDENT, col |-> 28, source |->[(132, 28)-(132, 30)], beginSub |-> [], endSub |-> []] -[str |-> "EXCEPT", type |-> BUILTIN, col |-> 31, source |->[(132, 31)-(132, 37)], beginSub |-> [], endSub |-> []] -[str |-> "!", type |-> BUILTIN, col |-> 38, source |->[(132, 38)-(132, 39)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 39, source |->[(132, 39)-(132, 40)], beginSub |-> [], endSub |-> []] -[str |-> "alice", type |-> STRING, col |-> 40, source |->[(132, 40)-(132, 45)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 47, source |->[(132, 47)-(132, 48)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 49, source |->[(132, 49)-(132, 50)], beginSub |-> [], endSub |-> []] -[str |-> "n3", type |-> STRING, col |-> 51, source |->[(132, 51)-(132, 53)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 55, source |->[(132, 55)-(132, 56)], beginSub |-> [], endSub |-> []] -null -[str |-> "ELSE", type |-> BUILTIN, col |-> 13, source |->[(133, 13)-(133, 17)], beginSub |-> [], endSub |-> []] -[str |-> "/\", type |-> BUILTIN, col |-> 18, source |->[(133, 18)-(133, 20)], beginSub |-> [], endSub |-> []] -[str |-> "rstMgrs", type |-> IDENT, col |-> 21, source |->[(133, 21)-(133, 28)], beginSub |-> [], endSub |-> []] -[str |-> "'", type |-> BUILTIN, col |-> 28, source |->[(133, 28)-(133, 29)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 30, source |->[(133, 30)-(133, 31)], beginSub |-> [], endSub |-> []] -[str |-> "managers", type |-> IDENT, col |-> 32, source |->[(133, 32)-(133, 40)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 18, source |->[(134, 18)-(134, 20)], beginSub |-> [], endSub |-> []] -[str |-> "IF", type |-> BUILTIN, col |-> 21, source |->[(134, 21)-(134, 23)], beginSub |-> [], endSub |-> []] -[str |-> "aborted", type |-> IDENT, col |-> 24, source |->[(134, 24)-(134, 31)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 32, source |->[(134, 32)-(134, 33)], beginSub |-> [], endSub |-> []] -[str |-> "TRUE", type |-> IDENT, col |-> 34, source |->[(134, 34)-(134, 38)], beginSub |-> [], endSub |-> []] -null -[str |-> "THEN", type |-> BUILTIN, col |-> 24, source |->[(135, 24)-(135, 28)], beginSub |-> [], endSub |-> []] -[str |-> "/\", type |-> BUILTIN, col |-> 29, source |->[(135, 29)-(135, 31)], beginSub |-> [], endSub |-> []] -[str |-> "pc", type |-> IDENT, col |-> 32, source |->[(135, 32)-(135, 34)], beginSub |-> [], endSub |-> []] -[str |-> "'", type |-> BUILTIN, col |-> 34, source |->[(135, 34)-(135, 35)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 36, source |->[(135, 36)-(135, 37)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 38, source |->[(135, 38)-(135, 39)], beginSub |-> [], endSub |-> []] -[str |-> "pc", type |-> IDENT, col |-> 39, source |->[(135, 39)-(135, 41)], beginSub |-> [], endSub |-> []] -[str |-> "EXCEPT", type |-> BUILTIN, col |-> 42, source |->[(135, 42)-(135, 48)], beginSub |-> [], endSub |-> []] -[str |-> "!", type |-> BUILTIN, col |-> 49, source |->[(135, 49)-(135, 50)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 50, source |->[(135, 50)-(135, 51)], beginSub |-> [], endSub |-> []] -[str |-> "alice", type |-> STRING, col |-> 51, source |->[(135, 51)-(135, 56)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 58, source |->[(135, 58)-(135, 59)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 60, source |->[(135, 60)-(135, 61)], beginSub |-> [], endSub |-> []] -[str |-> "n4", type |-> STRING, col |-> 62, source |->[(135, 62)-(135, 64)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 66, source |->[(135, 66)-(135, 67)], beginSub |-> [], endSub |-> []] -null -[str |-> "ELSE", type |-> BUILTIN, col |-> 24, source |->[(136, 24)-(136, 28)], beginSub |-> [], endSub |-> []] -[str |-> "/\", type |-> BUILTIN, col |-> 29, source |->[(136, 29)-(136, 31)], beginSub |-> [], endSub |-> []] -[str |-> "pc", type |-> IDENT, col |-> 32, source |->[(136, 32)-(136, 34)], beginSub |-> [], endSub |-> []] -[str |-> "'", type |-> BUILTIN, col |-> 34, source |->[(136, 34)-(136, 35)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 36, source |->[(136, 36)-(136, 37)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 38, source |->[(136, 38)-(136, 39)], beginSub |-> [], endSub |-> []] -[str |-> "pc", type |-> IDENT, col |-> 39, source |->[(136, 39)-(136, 41)], beginSub |-> [], endSub |-> []] -[str |-> "EXCEPT", type |-> BUILTIN, col |-> 42, source |->[(136, 42)-(136, 48)], beginSub |-> [], endSub |-> []] -[str |-> "!", type |-> BUILTIN, col |-> 49, source |->[(136, 49)-(136, 50)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 50, source |->[(136, 50)-(136, 51)], beginSub |-> [], endSub |-> []] -[str |-> "alice", type |-> STRING, col |-> 51, source |->[(136, 51)-(136, 56)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 58, source |->[(136, 58)-(136, 59)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 60, source |->[(136, 60)-(136, 61)], beginSub |-> [], endSub |-> []] -[str |-> "nck", type |-> STRING, col |-> 62, source |->[(136, 62)-(136, 65)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 67, source |->[(136, 67)-(136, 68)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 18, source |->[(137, 18)-(137, 20)], beginSub |-> [], endSub |-> []] -[str |-> "UNCHANGED", type |-> BUILTIN, col |-> 21, source |->[(137, 21)-(137, 30)], beginSub |-> [], endSub |-> []] -[str |-> "aborted", type |-> IDENT, col |-> 31, source |->[(137, 31)-(137, 38)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 7, source |->[(138, 7)-(138, 9)], beginSub |-> [], endSub |-> []] -[str |-> "UNCHANGED", type |-> BUILTIN, col |-> 10, source |->[(138, 10)-(138, 19)], beginSub |-> [], endSub |-> []] -[str |-> "<<", type |-> BUILTIN, col |-> 20, source |->[(138, 20)-(138, 22)], beginSub |-> [], endSub |-> []] -[str |-> "managers", type |-> IDENT, col |-> 23, source |->[(138, 23)-(138, 31)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 31, source |->[(138, 31)-(138, 32)], beginSub |-> [], endSub |-> []] -[str |-> "restaurant_stage", type |-> IDENT, col |-> 33, source |->[(138, 33)-(138, 49)], beginSub |-> [], endSub |-> []] -[str |-> ">>", type |-> BUILTIN, col |-> 50, source |->[(138, 50)-(138, 52)], beginSub |-> [], endSub |-> []] -null -null -[str |-> "n4", type |-> IDENT, col |-> 1, source |->[(140, 1)-(140, 3)], beginSub |-> [], endSub |-> []] -[str |-> "==", type |-> BUILTIN, col |-> 4, source |->[(140, 4)-(140, 6)], beginSub |-> [], endSub |-> []] -[str |-> "/\", type |-> BUILTIN, col |-> 7, source |->[(140, 7)-(140, 9)], beginSub |-> [], endSub |-> []] -[str |-> "pc", type |-> IDENT, col |-> 10, source |->[(140, 10)-(140, 12)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 12, source |->[(140, 12)-(140, 13)], beginSub |-> [], endSub |-> []] -[str |-> "alice", type |-> STRING, col |-> 13, source |->[(140, 13)-(140, 18)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 20, source |->[(140, 20)-(140, 21)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 22, source |->[(140, 22)-(140, 23)], beginSub |-> [], endSub |-> []] -[str |-> "n4", type |-> STRING, col |-> 24, source |->[(140, 24)-(140, 26)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 7, source |->[(141, 7)-(141, 9)], beginSub |-> [], endSub |-> []] -[str |-> "IF", type |-> BUILTIN, col |-> 10, source |->[(141, 10)-(141, 12)], beginSub |-> [], endSub |-> []] -[str |-> "rstMgrs", type |-> IDENT, col |-> 13, source |->[(141, 13)-(141, 20)], beginSub |-> [], endSub |-> []] -[str |-> "#", type |-> BUILTIN, col |-> 21, source |->[(141, 21)-(141, 22)], beginSub |-> [], endSub |-> []] -[str |-> "{", type |-> BUILTIN, col |-> 23, source |->[(141, 23)-(141, 24)], beginSub |-> [], endSub |-> []] -[str |-> "}", type |-> BUILTIN, col |-> 24, source |->[(141, 24)-(141, 25)], beginSub |-> [], endSub |-> []] -null -[str |-> "THEN", type |-> BUILTIN, col |-> 13, source |->[(142, 13)-(142, 17)], beginSub |-> [], endSub |-> []] -[str |-> "/\", type |-> BUILTIN, col |-> 18, source |->[(142, 18)-(142, 20)], beginSub |-> [], endSub |-> []] -[str |-> "\E", type |-> BUILTIN, col |-> 21, source |->[(142, 21)-(142, 23)], beginSub |-> [], endSub |-> []] -[str |-> "km", type |-> IDENT, col |-> 24, source |->[(142, 24)-(142, 26)], beginSub |-> [], endSub |-> []] -[str |-> "\in", type |-> BUILTIN, col |-> 27, source |->[(142, 27)-(142, 30)], beginSub |-> [], endSub |-> []] -[str |-> "rstMgrs", type |-> IDENT, col |-> 31, source |->[(142, 31)-(142, 38)], beginSub |-> [], endSub |-> []] -[str |-> ":", type |-> BUILTIN, col |-> 38, source |->[(142, 38)-(142, 39)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 23, source |->[(143, 23)-(143, 25)], beginSub |-> [], endSub |-> []] -[str |-> "restaurant_stage", type |-> IDENT, col |-> 26, source |->[(143, 26)-(143, 42)], beginSub |-> [], endSub |-> []] -[str |-> "'", type |-> BUILTIN, col |-> 42, source |->[(143, 42)-(143, 43)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 44, source |->[(143, 44)-(143, 45)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 46, source |->[(143, 46)-(143, 47)], beginSub |-> [], endSub |-> []] -[str |-> "restaurant_stage", type |-> IDENT, col |-> 47, source |->[(143, 47)-(143, 63)], beginSub |-> [], endSub |-> []] -[str |-> "EXCEPT", type |-> BUILTIN, col |-> 64, source |->[(143, 64)-(143, 70)], beginSub |-> [], endSub |-> []] -[str |-> "!", type |-> BUILTIN, col |-> 71, source |->[(143, 71)-(143, 72)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 72, source |->[(143, 72)-(143, 73)], beginSub |-> [], endSub |-> []] -[str |-> "km", type |-> IDENT, col |-> 73, source |->[(143, 73)-(143, 75)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 75, source |->[(143, 75)-(143, 76)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 77, source |->[(143, 77)-(143, 78)], beginSub |-> [], endSub |-> []] -[str |-> "abort", type |-> STRING, col |-> 79, source |->[(143, 79)-(143, 84)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 86, source |->[(143, 86)-(143, 87)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 23, source |->[(144, 23)-(144, 25)], beginSub |-> [], endSub |-> []] -[str |-> "rstMgrs", type |-> IDENT, col |-> 26, source |->[(144, 26)-(144, 33)], beginSub |-> [], endSub |-> []] -[str |-> "'", type |-> BUILTIN, col |-> 33, source |->[(144, 33)-(144, 34)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 35, source |->[(144, 35)-(144, 36)], beginSub |-> [], endSub |-> []] -[str |-> "rstMgrs", type |-> IDENT, col |-> 37, source |->[(144, 37)-(144, 44)], beginSub |-> [], endSub |-> []] -[str |-> "\", type |-> BUILTIN, col |-> 45, source |->[(144, 45)-(144, 46)], beginSub |-> [], endSub |-> []] -[str |-> "{", type |-> BUILTIN, col |-> 47, source |->[(144, 47)-(144, 48)], beginSub |-> [], endSub |-> []] -[str |-> "km", type |-> IDENT, col |-> 48, source |->[(144, 48)-(144, 50)], beginSub |-> [], endSub |-> []] -[str |-> "}", type |-> BUILTIN, col |-> 50, source |->[(144, 50)-(144, 51)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 18, source |->[(145, 18)-(145, 20)], beginSub |-> [], endSub |-> []] -[str |-> "pc", type |-> IDENT, col |-> 21, source |->[(145, 21)-(145, 23)], beginSub |-> [], endSub |-> []] -[str |-> "'", type |-> BUILTIN, col |-> 23, source |->[(145, 23)-(145, 24)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 25, source |->[(145, 25)-(145, 26)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 27, source |->[(145, 27)-(145, 28)], beginSub |-> [], endSub |-> []] -[str |-> "pc", type |-> IDENT, col |-> 28, source |->[(145, 28)-(145, 30)], beginSub |-> [], endSub |-> []] -[str |-> "EXCEPT", type |-> BUILTIN, col |-> 31, source |->[(145, 31)-(145, 37)], beginSub |-> [], endSub |-> []] -[str |-> "!", type |-> BUILTIN, col |-> 38, source |->[(145, 38)-(145, 39)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 39, source |->[(145, 39)-(145, 40)], beginSub |-> [], endSub |-> []] -[str |-> "alice", type |-> STRING, col |-> 40, source |->[(145, 40)-(145, 45)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 47, source |->[(145, 47)-(145, 48)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 49, source |->[(145, 49)-(145, 50)], beginSub |-> [], endSub |-> []] -[str |-> "n4", type |-> STRING, col |-> 51, source |->[(145, 51)-(145, 53)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 55, source |->[(145, 55)-(145, 56)], beginSub |-> [], endSub |-> []] -null -[str |-> "ELSE", type |-> BUILTIN, col |-> 13, source |->[(146, 13)-(146, 17)], beginSub |-> [], endSub |-> []] -[str |-> "/\", type |-> BUILTIN, col |-> 18, source |->[(146, 18)-(146, 20)], beginSub |-> [], endSub |-> []] -[str |-> "pc", type |-> IDENT, col |-> 21, source |->[(146, 21)-(146, 23)], beginSub |-> [], endSub |-> []] -[str |-> "'", type |-> BUILTIN, col |-> 23, source |->[(146, 23)-(146, 24)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 25, source |->[(146, 25)-(146, 26)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 27, source |->[(146, 27)-(146, 28)], beginSub |-> [], endSub |-> []] -[str |-> "pc", type |-> IDENT, col |-> 28, source |->[(146, 28)-(146, 30)], beginSub |-> [], endSub |-> []] -[str |-> "EXCEPT", type |-> BUILTIN, col |-> 31, source |->[(146, 31)-(146, 37)], beginSub |-> [], endSub |-> []] -[str |-> "!", type |-> BUILTIN, col |-> 38, source |->[(146, 38)-(146, 39)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 39, source |->[(146, 39)-(146, 40)], beginSub |-> [], endSub |-> []] -[str |-> "alice", type |-> STRING, col |-> 40, source |->[(146, 40)-(146, 45)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 47, source |->[(146, 47)-(146, 48)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 49, source |->[(146, 49)-(146, 50)], beginSub |-> [], endSub |-> []] -[str |-> "Done", type |-> STRING, col |-> 51, source |->[(146, 51)-(146, 55)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 57, source |->[(146, 57)-(146, 58)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 18, source |->[(147, 18)-(147, 20)], beginSub |-> [], endSub |-> []] -[str |-> "UNCHANGED", type |-> BUILTIN, col |-> 21, source |->[(147, 21)-(147, 30)], beginSub |-> [], endSub |-> []] -[str |-> "<<", type |-> BUILTIN, col |-> 31, source |->[(147, 31)-(147, 33)], beginSub |-> [], endSub |-> []] -[str |-> "restaurant_stage", type |-> IDENT, col |-> 34, source |->[(147, 34)-(147, 50)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 50, source |->[(147, 50)-(147, 51)], beginSub |-> [], endSub |-> []] -[str |-> "rstMgrs", type |-> IDENT, col |-> 52, source |->[(147, 52)-(147, 59)], beginSub |-> [], endSub |-> []] -[str |-> ">>", type |-> BUILTIN, col |-> 60, source |->[(147, 60)-(147, 62)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 7, source |->[(148, 7)-(148, 9)], beginSub |-> [], endSub |-> []] -[str |-> "UNCHANGED", type |-> BUILTIN, col |-> 10, source |->[(148, 10)-(148, 19)], beginSub |-> [], endSub |-> []] -[str |-> "<<", type |-> BUILTIN, col |-> 20, source |->[(148, 20)-(148, 22)], beginSub |-> [], endSub |-> []] -[str |-> "managers", type |-> IDENT, col |-> 23, source |->[(148, 23)-(148, 31)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 31, source |->[(148, 31)-(148, 32)], beginSub |-> [], endSub |-> []] -[str |-> "aborted", type |-> IDENT, col |-> 33, source |->[(148, 33)-(148, 40)], beginSub |-> [], endSub |-> []] -[str |-> ">>", type |-> BUILTIN, col |-> 41, source |->[(148, 41)-(148, 43)], beginSub |-> [], endSub |-> []] -null -null -[str |-> "nck", type |-> IDENT, col |-> 1, source |->[(150, 1)-(150, 4)], beginSub |-> [], endSub |-> []] -[str |-> "==", type |-> BUILTIN, col |-> 5, source |->[(150, 5)-(150, 7)], beginSub |-> [], endSub |-> []] -[str |-> "/\", type |-> BUILTIN, col |-> 8, source |->[(150, 8)-(150, 10)], beginSub |-> [], endSub |-> []] -[str |-> "pc", type |-> IDENT, col |-> 11, source |->[(150, 11)-(150, 13)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 13, source |->[(150, 13)-(150, 14)], beginSub |-> [], endSub |-> []] -[str |-> "alice", type |-> STRING, col |-> 14, source |->[(150, 14)-(150, 19)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 21, source |->[(150, 21)-(150, 22)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 23, source |->[(150, 23)-(150, 24)], beginSub |-> [], endSub |-> []] -[str |-> "nck", type |-> STRING, col |-> 25, source |->[(150, 25)-(150, 28)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 8, source |->[(151, 8)-(151, 10)], beginSub |-> [], endSub |-> []] -[str |-> "Assert", type |-> IDENT, col |-> 11, source |->[(151, 11)-(151, 17)], beginSub |-> [], endSub |-> []] -[str |-> "(", type |-> BUILTIN, col |-> 17, source |->[(151, 17)-(151, 18)], beginSub |-> [], endSub |-> []] -[str |-> "\A", type |-> BUILTIN, col |-> 18, source |->[(151, 18)-(151, 20)], beginSub |-> [], endSub |-> []] -[str |-> "rstMgr", type |-> IDENT, col |-> 21, source |->[(151, 21)-(151, 27)], beginSub |-> [], endSub |-> []] -[str |-> "\in", type |-> BUILTIN, col |-> 28, source |->[(151, 28)-(151, 31)], beginSub |-> [], endSub |-> []] -[str |-> "rstMgrs", type |-> IDENT, col |-> 32, source |->[(151, 32)-(151, 39)], beginSub |-> [], endSub |-> []] -[str |-> ":", type |-> BUILTIN, col |-> 40, source |->[(151, 40)-(151, 41)], beginSub |-> [], endSub |-> []] -[str |-> "(", type |-> BUILTIN, col |-> 42, source |->[(151, 42)-(151, 43)], beginSub |-> [], endSub |-> []] -[str |-> "restaurant_stage", type |-> IDENT, col |-> 43, source |->[(151, 43)-(151, 59)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 59, source |->[(151, 59)-(151, 60)], beginSub |-> [], endSub |-> []] -[str |-> "rstMgr", type |-> IDENT, col |-> 60, source |->[(151, 60)-(151, 66)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 66, source |->[(151, 66)-(151, 67)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 68, source |->[(151, 68)-(151, 69)], beginSub |-> [], endSub |-> []] -[str |-> "accept", type |-> STRING, col |-> 70, source |->[(151, 70)-(151, 76)], beginSub |-> [], endSub |-> []] -[str |-> ")", type |-> BUILTIN, col |-> 78, source |->[(151, 78)-(151, 79)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 79, source |->[(151, 79)-(151, 80)], beginSub |-> [], endSub |-> []] -null -[str |-> "Failure of assertion at line 60, column 11.", type |-> STRING, col |-> 18, source |->[(152, 18)-(152, 61)], beginSub |-> [], endSub |-> []] -[str |-> ")", type |-> BUILTIN, col |-> 63, source |->[(152, 63)-(152, 64)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 8, source |->[(153, 8)-(153, 10)], beginSub |-> [], endSub |-> []] -[str |-> "pc", type |-> IDENT, col |-> 11, source |->[(153, 11)-(153, 13)], beginSub |-> [], endSub |-> []] -[str |-> "'", type |-> BUILTIN, col |-> 13, source |->[(153, 13)-(153, 14)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 15, source |->[(153, 15)-(153, 16)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 17, source |->[(153, 17)-(153, 18)], beginSub |-> [], endSub |-> []] -[str |-> "pc", type |-> IDENT, col |-> 18, source |->[(153, 18)-(153, 20)], beginSub |-> [], endSub |-> []] -[str |-> "EXCEPT", type |-> BUILTIN, col |-> 21, source |->[(153, 21)-(153, 27)], beginSub |-> [], endSub |-> []] -[str |-> "!", type |-> BUILTIN, col |-> 28, source |->[(153, 28)-(153, 29)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 29, source |->[(153, 29)-(153, 30)], beginSub |-> [], endSub |-> []] -[str |-> "alice", type |-> STRING, col |-> 30, source |->[(153, 30)-(153, 35)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 37, source |->[(153, 37)-(153, 38)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 39, source |->[(153, 39)-(153, 40)], beginSub |-> [], endSub |-> []] -[str |-> "n5", type |-> STRING, col |-> 41, source |->[(153, 41)-(153, 43)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 45, source |->[(153, 45)-(153, 46)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 8, source |->[(154, 8)-(154, 10)], beginSub |-> [], endSub |-> []] -[str |-> "UNCHANGED", type |-> BUILTIN, col |-> 11, source |->[(154, 11)-(154, 20)], beginSub |-> [], endSub |-> []] -[str |-> "<<", type |-> BUILTIN, col |-> 21, source |->[(154, 21)-(154, 23)], beginSub |-> [], endSub |-> []] -[str |-> "managers", type |-> IDENT, col |-> 24, source |->[(154, 24)-(154, 32)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 32, source |->[(154, 32)-(154, 33)], beginSub |-> [], endSub |-> []] -[str |-> "restaurant_stage", type |-> IDENT, col |-> 34, source |->[(154, 34)-(154, 50)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 50, source |->[(154, 50)-(154, 51)], beginSub |-> [], endSub |-> []] -[str |-> "rstMgrs", type |-> IDENT, col |-> 52, source |->[(154, 52)-(154, 59)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 59, source |->[(154, 59)-(154, 60)], beginSub |-> [], endSub |-> []] -[str |-> "aborted", type |-> IDENT, col |-> 61, source |->[(154, 61)-(154, 68)], beginSub |-> [], endSub |-> []] -[str |-> ">>", type |-> BUILTIN, col |-> 69, source |->[(154, 69)-(154, 71)], beginSub |-> [], endSub |-> []] -null -null -[str |-> "n5", type |-> IDENT, col |-> 1, source |->[(156, 1)-(156, 3)], beginSub |-> [], endSub |-> []] -[str |-> "==", type |-> BUILTIN, col |-> 4, source |->[(156, 4)-(156, 6)], beginSub |-> [], endSub |-> []] -[str |-> "/\", type |-> BUILTIN, col |-> 7, source |->[(156, 7)-(156, 9)], beginSub |-> [], endSub |-> []] -[str |-> "pc", type |-> IDENT, col |-> 10, source |->[(156, 10)-(156, 12)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 12, source |->[(156, 12)-(156, 13)], beginSub |-> [], endSub |-> []] -[str |-> "alice", type |-> STRING, col |-> 13, source |->[(156, 13)-(156, 18)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 20, source |->[(156, 20)-(156, 21)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 22, source |->[(156, 22)-(156, 23)], beginSub |-> [], endSub |-> []] -[str |-> "n5", type |-> STRING, col |-> 24, source |->[(156, 24)-(156, 26)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 7, source |->[(157, 7)-(157, 9)], beginSub |-> [], endSub |-> []] -[str |-> "IF", type |-> BUILTIN, col |-> 10, source |->[(157, 10)-(157, 12)], beginSub |-> [], endSub |-> []] -[str |-> "rstMgrs", type |-> IDENT, col |-> 13, source |->[(157, 13)-(157, 20)], beginSub |-> [], endSub |-> []] -[str |-> "#", type |-> BUILTIN, col |-> 21, source |->[(157, 21)-(157, 22)], beginSub |-> [], endSub |-> []] -[str |-> "{", type |-> BUILTIN, col |-> 23, source |->[(157, 23)-(157, 24)], beginSub |-> [], endSub |-> []] -[str |-> "}", type |-> BUILTIN, col |-> 24, source |->[(157, 24)-(157, 25)], beginSub |-> [], endSub |-> []] -null -[str |-> "THEN", type |-> BUILTIN, col |-> 13, source |->[(158, 13)-(158, 17)], beginSub |-> [], endSub |-> []] -[str |-> "/\", type |-> BUILTIN, col |-> 18, source |->[(158, 18)-(158, 20)], beginSub |-> [], endSub |-> []] -[str |-> "\E", type |-> BUILTIN, col |-> 21, source |->[(158, 21)-(158, 23)], beginSub |-> [], endSub |-> []] -[str |-> "km", type |-> IDENT, col |-> 24, source |->[(158, 24)-(158, 26)], beginSub |-> [], endSub |-> []] -[str |-> "\in", type |-> BUILTIN, col |-> 27, source |->[(158, 27)-(158, 30)], beginSub |-> [], endSub |-> []] -[str |-> "rstMgrs", type |-> IDENT, col |-> 31, source |->[(158, 31)-(158, 38)], beginSub |-> [], endSub |-> []] -[str |-> ":", type |-> BUILTIN, col |-> 38, source |->[(158, 38)-(158, 39)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 23, source |->[(159, 23)-(159, 25)], beginSub |-> [], endSub |-> []] -[str |-> "restaurant_stage", type |-> IDENT, col |-> 26, source |->[(159, 26)-(159, 42)], beginSub |-> [], endSub |-> []] -[str |-> "'", type |-> BUILTIN, col |-> 42, source |->[(159, 42)-(159, 43)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 44, source |->[(159, 44)-(159, 45)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 46, source |->[(159, 46)-(159, 47)], beginSub |-> [], endSub |-> []] -[str |-> "restaurant_stage", type |-> IDENT, col |-> 47, source |->[(159, 47)-(159, 63)], beginSub |-> [], endSub |-> []] -[str |-> "EXCEPT", type |-> BUILTIN, col |-> 64, source |->[(159, 64)-(159, 70)], beginSub |-> [], endSub |-> []] -[str |-> "!", type |-> BUILTIN, col |-> 71, source |->[(159, 71)-(159, 72)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 72, source |->[(159, 72)-(159, 73)], beginSub |-> [], endSub |-> []] -[str |-> "km", type |-> IDENT, col |-> 73, source |->[(159, 73)-(159, 75)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 75, source |->[(159, 75)-(159, 76)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 77, source |->[(159, 77)-(159, 78)], beginSub |-> [], endSub |-> []] -[str |-> "commit", type |-> STRING, col |-> 79, source |->[(159, 79)-(159, 85)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 87, source |->[(159, 87)-(159, 88)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 23, source |->[(160, 23)-(160, 25)], beginSub |-> [], endSub |-> []] -[str |-> "rstMgrs", type |-> IDENT, col |-> 26, source |->[(160, 26)-(160, 33)], beginSub |-> [], endSub |-> []] -[str |-> "'", type |-> BUILTIN, col |-> 33, source |->[(160, 33)-(160, 34)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 35, source |->[(160, 35)-(160, 36)], beginSub |-> [], endSub |-> []] -[str |-> "rstMgrs", type |-> IDENT, col |-> 37, source |->[(160, 37)-(160, 44)], beginSub |-> [], endSub |-> []] -[str |-> "\", type |-> BUILTIN, col |-> 45, source |->[(160, 45)-(160, 46)], beginSub |-> [], endSub |-> []] -[str |-> "{", type |-> BUILTIN, col |-> 47, source |->[(160, 47)-(160, 48)], beginSub |-> [], endSub |-> []] -[str |-> "km", type |-> IDENT, col |-> 48, source |->[(160, 48)-(160, 50)], beginSub |-> [], endSub |-> []] -[str |-> "}", type |-> BUILTIN, col |-> 50, source |->[(160, 50)-(160, 51)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 18, source |->[(161, 18)-(161, 20)], beginSub |-> [], endSub |-> []] -[str |-> "pc", type |-> IDENT, col |-> 21, source |->[(161, 21)-(161, 23)], beginSub |-> [], endSub |-> []] -[str |-> "'", type |-> BUILTIN, col |-> 23, source |->[(161, 23)-(161, 24)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 25, source |->[(161, 25)-(161, 26)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 27, source |->[(161, 27)-(161, 28)], beginSub |-> [], endSub |-> []] -[str |-> "pc", type |-> IDENT, col |-> 28, source |->[(161, 28)-(161, 30)], beginSub |-> [], endSub |-> []] -[str |-> "EXCEPT", type |-> BUILTIN, col |-> 31, source |->[(161, 31)-(161, 37)], beginSub |-> [], endSub |-> []] -[str |-> "!", type |-> BUILTIN, col |-> 38, source |->[(161, 38)-(161, 39)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 39, source |->[(161, 39)-(161, 40)], beginSub |-> [], endSub |-> []] -[str |-> "alice", type |-> STRING, col |-> 40, source |->[(161, 40)-(161, 45)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 47, source |->[(161, 47)-(161, 48)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 49, source |->[(161, 49)-(161, 50)], beginSub |-> [], endSub |-> []] -[str |-> "n5", type |-> STRING, col |-> 51, source |->[(161, 51)-(161, 53)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 55, source |->[(161, 55)-(161, 56)], beginSub |-> [], endSub |-> []] -null -[str |-> "ELSE", type |-> BUILTIN, col |-> 13, source |->[(162, 13)-(162, 17)], beginSub |-> [], endSub |-> []] -[str |-> "/\", type |-> BUILTIN, col |-> 18, source |->[(162, 18)-(162, 20)], beginSub |-> [], endSub |-> []] -[str |-> "pc", type |-> IDENT, col |-> 21, source |->[(162, 21)-(162, 23)], beginSub |-> [], endSub |-> []] -[str |-> "'", type |-> BUILTIN, col |-> 23, source |->[(162, 23)-(162, 24)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 25, source |->[(162, 25)-(162, 26)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 27, source |->[(162, 27)-(162, 28)], beginSub |-> [], endSub |-> []] -[str |-> "pc", type |-> IDENT, col |-> 28, source |->[(162, 28)-(162, 30)], beginSub |-> [], endSub |-> []] -[str |-> "EXCEPT", type |-> BUILTIN, col |-> 31, source |->[(162, 31)-(162, 37)], beginSub |-> [], endSub |-> []] -[str |-> "!", type |-> BUILTIN, col |-> 38, source |->[(162, 38)-(162, 39)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 39, source |->[(162, 39)-(162, 40)], beginSub |-> [], endSub |-> []] -[str |-> "alice", type |-> STRING, col |-> 40, source |->[(162, 40)-(162, 45)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 47, source |->[(162, 47)-(162, 48)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 49, source |->[(162, 49)-(162, 50)], beginSub |-> [], endSub |-> []] -[str |-> "Done", type |-> STRING, col |-> 51, source |->[(162, 51)-(162, 55)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 57, source |->[(162, 57)-(162, 58)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 18, source |->[(163, 18)-(163, 20)], beginSub |-> [], endSub |-> []] -[str |-> "UNCHANGED", type |-> BUILTIN, col |-> 21, source |->[(163, 21)-(163, 30)], beginSub |-> [], endSub |-> []] -[str |-> "<<", type |-> BUILTIN, col |-> 31, source |->[(163, 31)-(163, 33)], beginSub |-> [], endSub |-> []] -[str |-> "restaurant_stage", type |-> IDENT, col |-> 34, source |->[(163, 34)-(163, 50)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 50, source |->[(163, 50)-(163, 51)], beginSub |-> [], endSub |-> []] -[str |-> "rstMgrs", type |-> IDENT, col |-> 52, source |->[(163, 52)-(163, 59)], beginSub |-> [], endSub |-> []] -[str |-> ">>", type |-> BUILTIN, col |-> 60, source |->[(163, 60)-(163, 62)], beginSub |-> [], endSub |-> []] -null -[str |-> "/\", type |-> BUILTIN, col |-> 7, source |->[(164, 7)-(164, 9)], beginSub |-> [], endSub |-> []] -[str |-> "UNCHANGED", type |-> BUILTIN, col |-> 10, source |->[(164, 10)-(164, 19)], beginSub |-> [], endSub |-> []] -[str |-> "<<", type |-> BUILTIN, col |-> 20, source |->[(164, 20)-(164, 22)], beginSub |-> [], endSub |-> []] -[str |-> "managers", type |-> IDENT, col |-> 23, source |->[(164, 23)-(164, 31)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 31, source |->[(164, 31)-(164, 32)], beginSub |-> [], endSub |-> []] -[str |-> "aborted", type |-> IDENT, col |-> 33, source |->[(164, 33)-(164, 40)], beginSub |-> [], endSub |-> []] -[str |-> ">>", type |-> BUILTIN, col |-> 41, source |->[(164, 41)-(164, 43)], beginSub |-> [], endSub |-> []] -null -null -[str |-> "Controller", type |-> IDENT, col |-> 1, source |->[(166, 1)-(166, 11)], beginSub |-> [], endSub |-> []] -[str |-> "==", type |-> BUILTIN, col |-> 12, source |->[(166, 12)-(166, 14)], beginSub |-> [], endSub |-> []] -[str |-> "n0", type |-> IDENT, col |-> 15, source |->[(166, 15)-(166, 17)], beginSub |-> [], endSub |-> []] -[str |-> "\/", type |-> BUILTIN, col |-> 18, source |->[(166, 18)-(166, 20)], beginSub |-> [], endSub |-> []] -[str |-> "n1", type |-> IDENT, col |-> 21, source |->[(166, 21)-(166, 23)], beginSub |-> [], endSub |-> []] -[str |-> "\/", type |-> BUILTIN, col |-> 24, source |->[(166, 24)-(166, 26)], beginSub |-> [], endSub |-> []] -[str |-> "n3", type |-> IDENT, col |-> 27, source |->[(166, 27)-(166, 29)], beginSub |-> [], endSub |-> []] -[str |-> "\/", type |-> BUILTIN, col |-> 30, source |->[(166, 30)-(166, 32)], beginSub |-> [], endSub |-> []] -[str |-> "n4", type |-> IDENT, col |-> 33, source |->[(166, 33)-(166, 35)], beginSub |-> [], endSub |-> []] -[str |-> "\/", type |-> BUILTIN, col |-> 36, source |->[(166, 36)-(166, 38)], beginSub |-> [], endSub |-> []] -[str |-> "nck", type |-> IDENT, col |-> 39, source |->[(166, 39)-(166, 42)], beginSub |-> [], endSub |-> []] -[str |-> "\/", type |-> BUILTIN, col |-> 43, source |->[(166, 43)-(166, 45)], beginSub |-> [], endSub |-> []] -[str |-> "n5", type |-> IDENT, col |-> 46, source |->[(166, 46)-(166, 48)], beginSub |-> [], endSub |-> []] -null -null -[str |-> "Next", type |-> IDENT, col |-> 1, source |->[(168, 1)-(168, 5)], beginSub |-> [], endSub |-> []] -[str |-> "==", type |-> BUILTIN, col |-> 6, source |->[(168, 6)-(168, 8)], beginSub |-> [], endSub |-> []] -[str |-> "Controller", type |-> IDENT, col |-> 9, source |->[(168, 9)-(168, 19)], beginSub |-> [], endSub |-> []] -null -[str |-> "\/", type |-> BUILTIN, col |-> 12, source |->[(169, 12)-(169, 14)], beginSub |-> [], endSub |-> []] -[str |-> "(", type |-> BUILTIN, col |-> 15, source |->[(169, 15)-(169, 16)], beginSub |-> [], endSub |-> []] -[str |-> "\E", type |-> BUILTIN, col |-> 16, source |->[(169, 16)-(169, 18)], beginSub |-> [], endSub |-> []] -[str |-> "self", type |-> IDENT, col |-> 19, source |->[(169, 19)-(169, 23)], beginSub |-> [], endSub |-> []] -[str |-> "\in", type |-> BUILTIN, col |-> 24, source |->[(169, 24)-(169, 27)], beginSub |-> [], endSub |-> []] -[str |-> "managers", type |-> IDENT, col |-> 28, source |->[(169, 28)-(169, 36)], beginSub |-> [], endSub |-> []] -[str |-> ":", type |-> BUILTIN, col |-> 36, source |->[(169, 36)-(169, 37)], beginSub |-> [], endSub |-> []] -[str |-> "Restaurant", type |-> IDENT, col |-> 38, source |->[(169, 38)-(169, 48)], beginSub |-> [], endSub |-> []] -[str |-> "(", type |-> BUILTIN, col |-> 48, source |->[(169, 48)-(169, 49)], beginSub |-> [], endSub |-> []] -[str |-> "self", type |-> IDENT, col |-> 49, source |->[(169, 49)-(169, 53)], beginSub |-> [], endSub |-> []] -[str |-> ")", type |-> BUILTIN, col |-> 53, source |->[(169, 53)-(169, 54)], beginSub |-> [], endSub |-> []] -[str |-> ")", type |-> BUILTIN, col |-> 54, source |->[(169, 54)-(169, 55)], beginSub |-> [], endSub |-> []] -null -[str |-> "\/", type |-> BUILTIN, col |-> 12, source |->[(170, 12)-(170, 14)], beginSub |-> [], endSub |-> []] -null -[str |-> "(", type |-> BUILTIN, col |-> 15, source |->[(171, 15)-(171, 16)], beginSub |-> [], endSub |-> []] -[str |-> "(", type |-> BUILTIN, col |-> 16, source |->[(171, 16)-(171, 17)], beginSub |-> [], endSub |-> []] -[str |-> "\A", type |-> BUILTIN, col |-> 17, source |->[(171, 17)-(171, 19)], beginSub |-> [], endSub |-> []] -[str |-> "self", type |-> IDENT, col |-> 20, source |->[(171, 20)-(171, 24)], beginSub |-> [], endSub |-> []] -[str |-> "\in", type |-> BUILTIN, col |-> 25, source |->[(171, 25)-(171, 28)], beginSub |-> [], endSub |-> []] -[str |-> "ProcSet", type |-> IDENT, col |-> 29, source |->[(171, 29)-(171, 36)], beginSub |-> [], endSub |-> []] -[str |-> ":", type |-> BUILTIN, col |-> 36, source |->[(171, 36)-(171, 37)], beginSub |-> [], endSub |-> []] -[str |-> "pc", type |-> IDENT, col |-> 38, source |->[(171, 38)-(171, 40)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 40, source |->[(171, 40)-(171, 41)], beginSub |-> [], endSub |-> []] -[str |-> "self", type |-> IDENT, col |-> 41, source |->[(171, 41)-(171, 45)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 45, source |->[(171, 45)-(171, 46)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 47, source |->[(171, 47)-(171, 48)], beginSub |-> [], endSub |-> []] -[str |-> "Done", type |-> STRING, col |-> 49, source |->[(171, 49)-(171, 53)], beginSub |-> [], endSub |-> []] -[str |-> ")", type |-> BUILTIN, col |-> 55, source |->[(171, 55)-(171, 56)], beginSub |-> [], endSub |-> []] -[str |-> "/\", type |-> BUILTIN, col |-> 57, source |->[(171, 57)-(171, 59)], beginSub |-> [], endSub |-> []] -[str |-> "UNCHANGED", type |-> BUILTIN, col |-> 60, source |->[(171, 60)-(171, 69)], beginSub |-> [], endSub |-> []] -[str |-> "vars", type |-> IDENT, col |-> 70, source |->[(171, 70)-(171, 74)], beginSub |-> [], endSub |-> []] -[str |-> ")", type |-> BUILTIN, col |-> 74, source |->[(171, 74)-(171, 75)], beginSub |-> [], endSub |-> []] -null -null -[str |-> "Spec", type |-> IDENT, col |-> 1, source |->[(173, 1)-(173, 5)], beginSub |-> [], endSub |-> []] -[str |-> "==", type |-> BUILTIN, col |-> 6, source |->[(173, 6)-(173, 8)], beginSub |-> [], endSub |-> []] -[str |-> "Init", type |-> IDENT, col |-> 9, source |->[(173, 9)-(173, 13)], beginSub |-> [], endSub |-> []] -[str |-> "/\", type |-> BUILTIN, col |-> 14, source |->[(173, 14)-(173, 16)], beginSub |-> [], endSub |-> []] -[str |-> "[]", type |-> BUILTIN, col |-> 17, source |->[(173, 17)-(173, 19)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 19, source |->[(173, 19)-(173, 20)], beginSub |-> [], endSub |-> []] -[str |-> "Next", type |-> IDENT, col |-> 20, source |->[(173, 20)-(173, 24)], beginSub |-> [], endSub |-> []] -[str |-> "]_", type |-> BUILTIN, col |-> 24, source |->[(173, 24)-(173, 26)], beginSub |-> [], endSub |-> []] -[str |-> "vars", type |-> IDENT, col |-> 26, source |->[(173, 26)-(173, 30)], beginSub |-> [], endSub |-> []] -null -null -[str |-> "Termination", type |-> IDENT, col |-> 1, source |->[(175, 1)-(175, 12)], beginSub |-> [], endSub |-> []] -[str |-> "==", type |-> BUILTIN, col |-> 13, source |->[(175, 13)-(175, 15)], beginSub |-> [], endSub |-> []] -[str |-> "<>", type |-> BUILTIN, col |-> 16, source |->[(175, 16)-(175, 18)], beginSub |-> [], endSub |-> []] -[str |-> "(", type |-> BUILTIN, col |-> 18, source |->[(175, 18)-(175, 19)], beginSub |-> [], endSub |-> []] -[str |-> "\A", type |-> BUILTIN, col |-> 19, source |->[(175, 19)-(175, 21)], beginSub |-> [], endSub |-> []] -[str |-> "self", type |-> IDENT, col |-> 22, source |->[(175, 22)-(175, 26)], beginSub |-> [], endSub |-> []] -[str |-> "\in", type |-> BUILTIN, col |-> 27, source |->[(175, 27)-(175, 30)], beginSub |-> [], endSub |-> []] -[str |-> "ProcSet", type |-> IDENT, col |-> 31, source |->[(175, 31)-(175, 38)], beginSub |-> [], endSub |-> []] -[str |-> ":", type |-> BUILTIN, col |-> 38, source |->[(175, 38)-(175, 39)], beginSub |-> [], endSub |-> []] -[str |-> "pc", type |-> IDENT, col |-> 40, source |->[(175, 40)-(175, 42)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 42, source |->[(175, 42)-(175, 43)], beginSub |-> [], endSub |-> []] -[str |-> "self", type |-> IDENT, col |-> 43, source |->[(175, 43)-(175, 47)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 47, source |->[(175, 47)-(175, 48)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 49, source |->[(175, 49)-(175, 50)], beginSub |-> [], endSub |-> []] -[str |-> "Done", type |-> STRING, col |-> 51, source |->[(175, 51)-(175, 55)], beginSub |-> [], endSub |-> []] -[str |-> ")", type |-> BUILTIN, col |-> 57, source |->[(175, 57)-(175, 58)], beginSub |-> [], endSub |-> []] -null -null -null -null -[str |-> "StateOK", type |-> IDENT, col |-> 1, source |->[(179, 1)-(179, 8)], beginSub |-> [], endSub |-> []] -[str |-> "==", type |-> BUILTIN, col |-> 9, source |->[(179, 9)-(179, 11)], beginSub |-> [], endSub |-> []] -[str |-> "/\", type |-> BUILTIN, col |-> 12, source |->[(179, 12)-(179, 14)], beginSub |-> [], endSub |-> []] -[str |-> "(", type |-> BUILTIN, col |-> 15, source |->[(179, 15)-(179, 16)], beginSub |-> [], endSub |-> []] -[str |-> "\A", type |-> BUILTIN, col |-> 16, source |->[(179, 16)-(179, 18)], beginSub |-> [], endSub |-> []] -[str |-> "i", type |-> IDENT, col |-> 19, source |->[(179, 19)-(179, 20)], beginSub |-> [], endSub |-> []] -[str |-> "\in", type |-> BUILTIN, col |-> 21, source |->[(179, 21)-(179, 24)], beginSub |-> [], endSub |-> []] -[str |-> "managers", type |-> IDENT, col |-> 25, source |->[(179, 25)-(179, 33)], beginSub |-> [], endSub |-> []] -[str |-> ":", type |-> BUILTIN, col |-> 33, source |->[(179, 33)-(179, 34)], beginSub |-> [], endSub |-> []] -[str |-> "restaurant_stage", type |-> IDENT, col |-> 35, source |->[(179, 35)-(179, 51)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 51, source |->[(179, 51)-(179, 52)], beginSub |-> [], endSub |-> []] -[str |-> "i", type |-> IDENT, col |-> 52, source |->[(179, 52)-(179, 53)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 53, source |->[(179, 53)-(179, 54)], beginSub |-> [], endSub |-> []] -[str |-> "\in", type |-> BUILTIN, col |-> 55, source |->[(179, 55)-(179, 58)], beginSub |-> [], endSub |-> []] -[str |-> "{", type |-> BUILTIN, col |-> 59, source |->[(179, 59)-(179, 60)], beginSub |-> [], endSub |-> []] -[str |-> "start", type |-> STRING, col |-> 60, source |->[(179, 60)-(179, 65)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 67, source |->[(179, 67)-(179, 68)], beginSub |-> [], endSub |-> []] -[str |-> "propose", type |-> STRING, col |-> 69, source |->[(179, 69)-(179, 76)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 78, source |->[(179, 78)-(179, 79)], beginSub |-> [], endSub |-> []] -[str |-> "accept", type |-> STRING, col |-> 80, source |->[(179, 80)-(179, 86)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 88, source |->[(179, 88)-(179, 89)], beginSub |-> [], endSub |-> []] -[str |-> "commit", type |-> STRING, col |-> 90, source |->[(179, 90)-(179, 96)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 98, source |->[(179, 98)-(179, 99)], beginSub |-> [], endSub |-> []] -[str |-> "abort", type |-> STRING, col |-> 100, source |->[(179, 100)-(179, 105)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 107, source |->[(179, 107)-(179, 108)], beginSub |-> [], endSub |-> []] -[str |-> "committed", type |-> STRING, col |-> 109, source |->[(179, 109)-(179, 118)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 120, source |->[(179, 120)-(179, 121)], beginSub |-> [], endSub |-> []] -[str |-> "aborted", type |-> STRING, col |-> 122, source |->[(179, 122)-(179, 129)], beginSub |-> [], endSub |-> []] -[str |-> ",", type |-> BUILTIN, col |-> 131, source |->[(179, 131)-(179, 132)], beginSub |-> [], endSub |-> []] -[str |-> "refuse", type |-> STRING, col |-> 133, source |->[(179, 133)-(179, 139)], beginSub |-> [], endSub |-> []] -[str |-> "}", type |-> BUILTIN, col |-> 141, source |->[(179, 141)-(179, 142)], beginSub |-> [], endSub |-> []] -[str |-> ")", type |-> BUILTIN, col |-> 142, source |->[(179, 142)-(179, 143)], beginSub |-> [], endSub |-> []] -null -null -[str |-> "Committed", type |-> IDENT, col |-> 1, source |->[(181, 1)-(181, 10)], beginSub |-> [], endSub |-> []] -[str |-> "==", type |-> BUILTIN, col |-> 11, source |->[(181, 11)-(181, 13)], beginSub |-> [], endSub |-> []] -[str |-> "/\", type |-> BUILTIN, col |-> 14, source |->[(181, 14)-(181, 16)], beginSub |-> [], endSub |-> []] -[str |-> "\/", type |-> BUILTIN, col |-> 17, source |->[(181, 17)-(181, 19)], beginSub |-> [], endSub |-> []] -[str |-> "<>", type |-> BUILTIN, col |-> 20, source |->[(181, 20)-(181, 22)], beginSub |-> [], endSub |-> []] -[str |-> "(", type |-> BUILTIN, col |-> 22, source |->[(181, 22)-(181, 23)], beginSub |-> [], endSub |-> []] -[str |-> "\A", type |-> BUILTIN, col |-> 23, source |->[(181, 23)-(181, 25)], beginSub |-> [], endSub |-> []] -[str |-> "i", type |-> IDENT, col |-> 26, source |->[(181, 26)-(181, 27)], beginSub |-> [], endSub |-> []] -[str |-> "\in", type |-> BUILTIN, col |-> 28, source |->[(181, 28)-(181, 31)], beginSub |-> [], endSub |-> []] -[str |-> "managers", type |-> IDENT, col |-> 32, source |->[(181, 32)-(181, 40)], beginSub |-> [], endSub |-> []] -[str |-> ":", type |-> BUILTIN, col |-> 40, source |->[(181, 40)-(181, 41)], beginSub |-> [], endSub |-> []] -[str |-> "restaurant_stage", type |-> IDENT, col |-> 42, source |->[(181, 42)-(181, 58)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 58, source |->[(181, 58)-(181, 59)], beginSub |-> [], endSub |-> []] -[str |-> "i", type |-> IDENT, col |-> 59, source |->[(181, 59)-(181, 60)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 60, source |->[(181, 60)-(181, 61)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 62, source |->[(181, 62)-(181, 63)], beginSub |-> [], endSub |-> []] -[str |-> "committed", type |-> STRING, col |-> 64, source |->[(181, 64)-(181, 73)], beginSub |-> [], endSub |-> []] -[str |-> ")", type |-> BUILTIN, col |-> 75, source |->[(181, 75)-(181, 76)], beginSub |-> [], endSub |-> []] -null -[str |-> "\/", type |-> BUILTIN, col |-> 17, source |->[(182, 17)-(182, 19)], beginSub |-> [], endSub |-> []] -[str |-> "<>", type |-> BUILTIN, col |-> 20, source |->[(182, 20)-(182, 22)], beginSub |-> [], endSub |-> []] -[str |-> "(", type |-> BUILTIN, col |-> 22, source |->[(182, 22)-(182, 23)], beginSub |-> [], endSub |-> []] -[str |-> "\A", type |-> BUILTIN, col |-> 23, source |->[(182, 23)-(182, 25)], beginSub |-> [], endSub |-> []] -[str |-> "i", type |-> IDENT, col |-> 26, source |->[(182, 26)-(182, 27)], beginSub |-> [], endSub |-> []] -[str |-> "\in", type |-> BUILTIN, col |-> 28, source |->[(182, 28)-(182, 31)], beginSub |-> [], endSub |-> []] -[str |-> "managers", type |-> IDENT, col |-> 32, source |->[(182, 32)-(182, 40)], beginSub |-> [], endSub |-> []] -[str |-> ":", type |-> BUILTIN, col |-> 40, source |->[(182, 40)-(182, 41)], beginSub |-> [], endSub |-> []] -[str |-> "restaurant_stage", type |-> IDENT, col |-> 42, source |->[(182, 42)-(182, 58)], beginSub |-> [], endSub |-> []] -[str |-> "[", type |-> BUILTIN, col |-> 58, source |->[(182, 58)-(182, 59)], beginSub |-> [], endSub |-> []] -[str |-> "i", type |-> IDENT, col |-> 59, source |->[(182, 59)-(182, 60)], beginSub |-> [], endSub |-> []] -[str |-> "]", type |-> BUILTIN, col |-> 60, source |->[(182, 60)-(182, 61)], beginSub |-> [], endSub |-> []] -[str |-> "=", type |-> BUILTIN, col |-> 62, source |->[(182, 62)-(182, 63)], beginSub |-> [], endSub |-> []] -[str |-> "aborted", type |-> STRING, col |-> 64, source |->[(182, 64)-(182, 71)], beginSub |-> [], endSub |-> []] -[str |-> ")", type |-> BUILTIN, col |-> 73, source |->[(182, 73)-(182, 74)], beginSub |-> [], endSub |-> []] -null -null -[str |-> "==================================================================", type |-> BUILTIN, col |-> 1, source |->[(184, 1)-(184, 67)], beginSub |-> [], endSub |-> []] -null From 36c7124e38ae6bd104282ce766bd0e4812a3f36c Mon Sep 17 00:00:00 2001 From: fhackett Date: Wed, 21 Apr 2021 13:49:59 -0700 Subject: [PATCH 02/27] more manageable renaming; kind-matching semantic check; build.sbt --- build.sbt | 14 ++-- src/pgo/model/Definitions.scala | 2 +- src/pgo/model/RefersTo.scala | 74 +---------------- src/pgo/model/Rewritable.scala | 74 ++++++++++++++++- src/pgo/model/mpcal/AST.scala | 95 ++-------------------- src/pgo/model/pcal/AST.scala | 86 ++------------------ src/pgo/model/tla/AST.scala | 68 ++-------------- src/pgo/parser/MPCalParser.scala | 4 +- src/pgo/trans/MPCalSemanticCheckPass.scala | 26 ++++++ test/files/semantics/MPCalKindMatching.tla | 18 +++- 10 files changed, 143 insertions(+), 318 deletions(-) diff --git a/build.sbt b/build.sbt index f70b17180..d476391ea 100644 --- a/build.sbt +++ b/build.sbt @@ -1,5 +1,5 @@ name := "pgo" -scalaVersion := "2.13.4" +scalaVersion := "2.13.5" javacOptions ++= Seq("-source", "1.8") Compile / javaSource := baseDirectory.value / "src" @@ -7,15 +7,13 @@ Test / javaSource := baseDirectory.value / "test" Compile / scalaSource := baseDirectory.value / "src" Test / scalaSource := baseDirectory.value / "test" -unmanagedJars in Compile ++= Seq( - file("lib/json.jar"), - file("lib/plume.jar")) +libraryDependencies += "org.scala-lang" % "scala-reflect" % scalaVersion.value -libraryDependencies += "org.scala-lang.modules" %% "scala-parser-combinators" % "1.2.0-M1" +libraryDependencies += "org.rogach" %% "scallop" % "4.0.2" +libraryDependencies += "io.spray" %% "spray-json" % "1.3.6" -libraryDependencies += "com.novocode" % "junit-interface" % "0.11" % Test +libraryDependencies += "org.scala-lang.modules" %% "scala-parser-combinators" % "1.2.0-M1" +libraryDependencies += "com.lihaoyi" %% "os-lib" % "0.7.3" libraryDependencies += "org.scalatest" %% "scalatest" % "3.2.2" % Test -libraryDependencies += "org.scalatestplus" %% "junit-4-13" % "3.2.2.0" % Test - libraryDependencies += "io.github.java-diff-utils" % "java-diff-utils" % "4.9" % Test \ No newline at end of file diff --git a/src/pgo/model/Definitions.scala b/src/pgo/model/Definitions.scala index 3ef5cf4c5..ac4361d84 100644 --- a/src/pgo/model/Definitions.scala +++ b/src/pgo/model/Definitions.scala @@ -24,7 +24,7 @@ object Definition { } } -trait DefinitionOne extends Definition { +trait DefinitionOne extends Definition with RefersTo.HasReferences { override def singleDefinitions: View[DefinitionOne] = View(this) def arity: Int diff --git a/src/pgo/model/RefersTo.scala b/src/pgo/model/RefersTo.scala index 04b1fc8dd..e6c23eafe 100644 --- a/src/pgo/model/RefersTo.scala +++ b/src/pgo/model/RefersTo.scala @@ -1,11 +1,8 @@ package pgo.model -import pgo.model.Rewritable.BottomUpOnceStrategy -import pgo.util.IdMap - import scala.reflect.ClassTag -trait RefersTo[T] extends Rewritable { _: Rewritable => +trait RefersTo[T <: RefersTo.HasReferences] extends Rewritable { private var refersTo_ : Option[T] = None def refersTo: T = refersTo_.get def setRefersTo(refersTo: T): this.type = { @@ -29,72 +26,5 @@ object RefersTo { case _ => None } - def eqFixpoint[T](init: T)(fn: T => T): T = { - import Rewritable._ - var tmp = init - var nextTmp = fn(tmp) - while(!(tmp forceEq nextTmp)) { - tmp = nextTmp - nextTmp = fn(tmp) - } - tmp - } - - final class Renamer[RefType <: AnyRef](implicit tag: ClassTag[RefType]) { - private var renamings = IdMap.empty[RefType,RefType] - - def addRenaming(from: RefType, to: RefType): this.type = { - renamings = renamings.updated(from, to) - this - } - - def addRenamings(renamings: IterableOnce[(RefType,RefType)]): this.type = { - renamings.iterator.foreach { - case (from, to) => addRenaming(from, to) - } - this - } - - private object RenamedTo { - def unapply(node: Rewritable): Option[(Rewritable with RefersTo[RefType], RefType)] = { - node match { - case node: Rewritable with RefersTo[RefType] if tag.runtimeClass.isInstance(node.refersTo) => - // catch transitive renamings - def rec(ref: RefType): Option[RefType] = - renamings.get(ref) - .filter(_ ne ref) // avoid renaming loops - .flatMap(rec) - .orElse(Some(ref)) - - rec(node.refersTo).map((node, _)) - case _ => None - } - } - } - - def apply[N <: Rewritable](node: N): N = { - if(renamings.nonEmpty) { - node.rewrite(strategy = BottomUpOnceStrategy) { - case RenamedTo(ref, to) => ref.shallowCopy().setRefersTo(to) - } - } else node - } - - def captureRenaming[T <: RefType with Rewritable](ref: T, fn: T=>T): T = { - val mappedRef = fn(apply(ref)) - if(mappedRef ne ref) { - addRenaming(ref, mappedRef) - } - mappedRef - } - - def captureRenamingAny[T <: RefType with Rewritable](ref: T, fn: Any=>Any): T = - captureRenaming(ref, (t: T) => fn(t).asInstanceOf[T]) - - def mapConserveRenaming[T <: RefType with Rewritable](refs: List[T], fn: T=>T): List[T] = - refs.mapConserve(captureRenaming(_, fn)) - - def mapConserveRenamingAny[T <: RefType with Rewritable](refs: List[T], fn: Any=>Any): List[T] = - mapConserveRenaming(refs, (t: T) => fn(t).asInstanceOf[T]) - } + trait HasReferences } diff --git a/src/pgo/model/Rewritable.scala b/src/pgo/model/Rewritable.scala index 2140636f7..1163fd796 100644 --- a/src/pgo/model/Rewritable.scala +++ b/src/pgo/model/Rewritable.scala @@ -1,18 +1,86 @@ package pgo.model +import pgo.util.IdMap + import java.lang.reflect.Constructor +import scala.annotation.tailrec trait Rewritable { import Rewritable._ def productIterator: Iterator[Any] - //def namedParts: Iterator[Any] = Iterator.empty + /** + * Creates an iterator over all "named things" contained within this Rewritable. + * Assumption: an instance of RefersTo.HasReferences that is directly accessible from this case class's fields + * (i.e not contained within some other nested Rewritable) is part of this AST node, and may be referenced + * by other subtrees. + */ + def namedParts: Iterator[RefersTo.HasReferences] = { + def gatherOtherwise(subject: Any): Iterator[RefersTo.HasReferences] = + subject match { + case _: Rewritable => Iterator.empty + case map: Map[_, _] => map.valuesIterator.flatMap(gather) + case iterable: Iterable[_] => iterable.iterator.flatMap(gather) + case product: Product => product.productIterator.flatMap(gather) + case _ => Iterator.empty + } + + def gather(subject: Any): Iterator[RefersTo.HasReferences] = + subject match { + case subject: RefersTo.HasReferences => Iterator(subject) ++ gatherOtherwise(subject) + case otherwise => gatherOtherwise(otherwise) + } + + gather(this) + } def decorateLike(succ: this.type): this.type = succ - def mapChildren(fn: Any => Any): this.type = - withChildren(productIterator.map(fn)) + def mapChildren(fn: Any => Any): this.type = { + @tailrec + def applyRenamings(self: Rewritable, rewrittenSelf: Rewritable, existingRenamings: IdMap[RefersTo.HasReferences,RefersTo.HasReferences]): Rewritable = { + val newRenamings = (self.namedParts zip rewrittenSelf.namedParts).filter(p => (p._1 ne p._2) && !existingRenamings.contains(p._1)).to(IdMap) + def applyAllRenamings: Rewritable = { + val allRenamings = existingRenamings ++ newRenamings + Visitable.BottomUpFirstStrategy.execute(rewrittenSelf, { + case ref: RefersTo[RefersTo.HasReferences] @unchecked if allRenamings.contains(ref.refersTo) => + def findTarget(target: RefersTo.HasReferences): RefersTo.HasReferences = + allRenamings.get(target) match { + case Some(target) => target + case None => target + } + + ref.setRefersTo(findTarget(ref.refersTo)) + }) + + rewrittenSelf + } + + if(newRenamings.isEmpty) { + applyAllRenamings + } else { + val withDups = rewrittenSelf.withChildren(rewrittenSelf.productIterator.map { elem => + Rewritable.BottomUpOnceStrategy.execute(elem, { + case ref: RefersTo[_] if newRenamings.contains(ref.refersTo) => ref.shallowCopy() + case other => other + }) + }) + if(withDups ne rewrittenSelf) { + applyRenamings(self, withDups, existingRenamings ++ newRenamings) + } else { + applyAllRenamings + } + } + } + + val result = withChildren(productIterator.map(fn)) + if(this ne result) { + applyRenamings(this, result, IdMap.empty).asInstanceOf[this.type] + } else { + this + } + } final def withChildren(children: Iterator[Any]): this.type = { val childrenSeq = children.toSeq diff --git a/src/pgo/model/mpcal/AST.scala b/src/pgo/model/mpcal/AST.scala index ad167aca1..42b9991c7 100644 --- a/src/pgo/model/mpcal/AST.scala +++ b/src/pgo/model/mpcal/AST.scala @@ -1,10 +1,8 @@ package pgo.model.mpcal -import pgo.model.RefersTo.Renamer import pgo.model.{Definition, DefinitionOne, RefersTo, Rewritable, SourceLocatable, Visitable} import pgo.model.tla._ import pgo.model.pcal._ -import pgo.util.IdMap sealed abstract class MPCalNode extends Rewritable with Visitable with SourceLocatable { override def decorateLike(succ: this.type): this.type = @@ -26,103 +24,26 @@ sealed abstract class MPCalParam extends MPCalNode with DefinitionOne { def name: TLAIdentifier override def arity: Int = 0 override def identifier: Definition.ScopeIdentifier = Definition.ScopeIdentifierName(name) + + def mappingCount: Int } -final case class MPCalRefParam(override val name: TLAIdentifier, mappingCount: Int) extends MPCalParam -final case class MPCalValParam(override val name: TLAIdentifier, mappingCount: Int) extends MPCalParam +final case class MPCalRefParam(override val name: TLAIdentifier, override val mappingCount: Int) extends MPCalParam +final case class MPCalValParam(override val name: TLAIdentifier, override val mappingCount: Int) extends MPCalParam final case class MPCalBlock(name: TLAIdentifier, units: List[TLAUnit], macros: List[PCalMacro], mpcalProcedures: List[MPCalProcedure], mappingMacros: List[MPCalMappingMacro], archetypes: List[MPCalArchetype], variables: List[PCalVariableDeclaration], instances: List[MPCalInstance], pcalProcedures: List[PCalProcedure], - processes: Either[List[PCalStatement],List[PCalProcess]]) extends MPCalNode { - override def mapChildren(fn: Any => Any): this.type = { - val renamer = new Renamer[Rewritable]() - val mappedName = fn(name) - val mappedUnits = renamer.mapConserveRenamingAny(units, fn) - // like in PCal AST, macros and procedures are mutually referential, so if one changes, we need to recompute references - var mappedMacros = macros.mapConserve(renamer.captureRenamingAny(_, fn)) - var mappedPCalProcedures = pcalProcedures.mapConserve(renamer.captureRenamingAny(_, fn)) - var mappedMPCalProcedures = mpcalProcedures.mapConserve(renamer.captureRenamingAny(_, fn)) - if((mappedMacros ne macros) || (mappedPCalProcedures ne pcalProcedures) || (mappedMPCalProcedures ne mpcalProcedures)) { - def duplicator[N <: Rewritable](n: N): N = - n.rewrite() { - case call @PCalCall(_, _) => call.shallowCopy() - case macroCall @PCalMacroCall(_, _) => macroCall.shallowCopy() - case mpcalCall @MPCalCall(_, _) => mpcalCall.shallowCopy() - } - mappedMacros = mappedMacros.mapConserve(renamer.captureRenaming(_, duplicator[PCalMacro])) - mappedPCalProcedures = mappedPCalProcedures.mapConserve(renamer.captureRenaming(_, duplicator[PCalProcedure])) - mappedMPCalProcedures = mappedMPCalProcedures.mapConserve(renamer.captureRenaming(_, duplicator[MPCalProcedure])) - val macroMap = (macros.view zip mappedMacros).to(IdMap) - val pcalProcMap = (pcalProcedures.view zip mappedPCalProcedures).to(IdMap) - val mpcalProcMap = (mpcalProcedures.view zip mappedMPCalProcedures).to(IdMap) - def referenceFixer[N <: Visitable](n: N): Unit = - n.visit() { - case call @PCalCall(_, _) => call.setRefersTo(pcalProcMap(call.refersTo)) - case macroCall @PCalMacroCall(_, _) => macroCall.setRefersTo(macroMap(macroCall.refersTo)) - case mpcalCall @MPCalCall(_, _) => mpcalCall.setRefersTo(mpcalProcMap(mpcalCall.refersTo)) - } - mappedMacros.foreach(referenceFixer(_)) - mappedPCalProcedures.foreach(referenceFixer(_)) - mappedMPCalProcedures.foreach(referenceFixer(_)) - } - val mappedMappingMacros = mappingMacros.mapConserve(renamer.captureRenamingAny(_, fn)) - val mappedArchetypes = archetypes.mapConserve(archetype => fn(renamer(archetype)).asInstanceOf[MPCalArchetype]) - val mappedVariables = renamer.mapConserveRenamingAny(variables, fn) - val mappedInstances = instances.mapConserve(instance => fn(renamer(instance)).asInstanceOf[MPCalInstance]) - val mappedProcesses: Either[List[PCalStatement],List[PCalProcess]] = processes match { - case Left(body) => - val mappedBody = body.mapConserve(stmt => fn(renamer(stmt)).asInstanceOf[PCalStatement]) - if(mappedBody ne body) { - Left(mappedBody) - } else processes - case Right(processes) => - val mappedProcesses = processes.mapConserve(process => fn(renamer(process)).asInstanceOf[PCalProcess]) - if(mappedProcesses ne processes) { - Right(mappedProcesses) - } else this.processes - } - withChildren(Iterator(mappedName, mappedUnits, mappedMacros, mappedMPCalProcedures, mappedMappingMacros, mappedArchetypes, - mappedVariables, mappedInstances, mappedPCalProcedures, mappedProcesses)) - } -} + processes: Either[List[PCalStatement],List[PCalProcess]]) extends MPCalNode final case class MPCalProcedure(name: TLAIdentifier, params: List[MPCalParam], variables: List[PCalPVariableDeclaration], - body: List[PCalStatement]) extends MPCalNode { - override def mapChildren(fn: Any => Any): this.type = { - val renamer = new Renamer[DefinitionOne with Rewritable]() - val mappedName = fn(name) - val mappedParams = renamer.mapConserveRenamingAny(params, fn) - val mappedVariables = renamer.mapConserveRenamingAny(variables, fn) - val mappedBody = body.mapConserve(stmt => fn(renamer(stmt)).asInstanceOf[PCalStatement]) - withChildren(Iterator(mappedName, mappedParams, mappedVariables, mappedBody)) - } -} + body: List[PCalStatement]) extends MPCalNode with RefersTo.HasReferences final case class MPCalMappingMacro(name: TLAIdentifier, readBody: List[PCalStatement], writeBody: List[PCalStatement], - freeVars: List[TLADefiningIdentifier]) extends MPCalNode { - override def mapChildren(fn: Any => Any): this.type = { - val renamer = new Renamer[TLADefiningIdentifier]() - val mappedName = fn(name) - val mappedFreeVars = renamer.mapConserveRenamingAny(freeVars, fn) - val mappedReadBody = readBody.mapConserve(stmt => fn(renamer(stmt)).asInstanceOf[PCalStatement]) - val mappedWriteBody = writeBody.mapConserve(stmt => fn(renamer(stmt)).asInstanceOf[PCalStatement]) - withChildren(Iterator(mappedName, mappedReadBody, mappedWriteBody, mappedFreeVars)) - } -} + freeVars: List[TLADefiningIdentifier]) extends MPCalNode with RefersTo.HasReferences final case class MPCalArchetype(name: TLAIdentifier, selfDecl: TLADefiningIdentifier, params: List[MPCalParam], - variables: List[PCalVariableDeclaration], body: List[PCalStatement]) extends MPCalNode { - override def mapChildren(fn: Any => Any): this.type = { - val renamer = new Renamer[DefinitionOne with Rewritable]() - val mappedName = fn(name) - val mappedSelf = renamer.captureRenamingAny(selfDecl, fn) - val mappedParams = renamer.mapConserveRenamingAny(params, fn) - val mappedVariables = renamer.mapConserveRenamingAny(variables, fn) - val mappedBody = body.mapConserve(stmt => fn(renamer(stmt)).asInstanceOf[PCalStatement]) - withChildren(Iterator(mappedName, mappedSelf, mappedParams, mappedVariables, mappedBody)) - } -} + variables: List[PCalVariableDeclaration], body: List[PCalStatement]) extends MPCalNode with RefersTo.HasReferences final case class MPCalInstance(selfDecl: PCalVariableDeclarationBound, fairness: PCalFairness, archetypeName: TLAIdentifier, arguments: List[Either[MPCalParam,TLAExpression]], diff --git a/src/pgo/model/pcal/AST.scala b/src/pgo/model/pcal/AST.scala index ba5436816..a9bb63505 100644 --- a/src/pgo/model/pcal/AST.scala +++ b/src/pgo/model/pcal/AST.scala @@ -1,9 +1,7 @@ package pgo.model.pcal -import pgo.model.RefersTo.Renamer import pgo.model.{Definition, DefinitionOne, RefersTo, Rewritable, SourceLocatable, Visitable} import pgo.model.tla._ -import pgo.util.IdMap sealed abstract class PCalNode extends Rewritable with Visitable with SourceLocatable { @@ -22,48 +20,7 @@ final case class PCalDefaultInitValue() extends PCalNode final case class PCalAlgorithm(fairness: PCalFairness, name: TLAIdentifier, variables: List[PCalVariableDeclaration], units: List[TLAUnit], macros: List[PCalMacro], procedures: List[PCalProcedure], - processes: Either[List[PCalStatement],List[PCalProcess]]) extends PCalNode { - override def mapChildren(fn: Any => Any): this.type = { - val renamer = new Renamer[Rewritable]() - val mappedName = fn(name) - val mappedVariables = renamer.mapConserveRenamingAny(variables, fn) - val mappedUnits = renamer.mapConserveRenamingAny(units, fn) - var mappedMacros = macros.mapConserve(renamer.captureRenamingAny(_, fn)) - var mappedProcedures = procedures.mapConserve(renamer.captureRenamingAny(_, fn)) - // macros and procedures are mutually referential, so we have to apply any renamings using a special strategy - if((mappedMacros ne macros) || (mappedProcedures ne procedures)) { - def duplicator[N <: Rewritable](n: N): N = - n.rewrite() { - case call @PCalCall(_, _) => call.shallowCopy() - case macroCall @PCalMacroCall(_, _) => macroCall.shallowCopy() - } - mappedMacros = mappedMacros.mapConserve(renamer.captureRenaming(_, duplicator[PCalMacro])) - mappedProcedures = mappedProcedures.mapConserve(renamer.captureRenaming(_, duplicator[PCalProcedure])) - val macroMap = (macros.view zip mappedMacros).to(IdMap) - val procMap = (procedures.view zip mappedProcedures).to(IdMap) - def referenceFixer[N <: Visitable](n: N): Unit = - n.visit() { - case call @PCalCall(_, _) => call.setRefersTo(procMap(call.refersTo)) - case macroCall @PCalMacroCall(_, _) => macroCall.setRefersTo(macroMap(macroCall.refersTo)) - } - mappedMacros.foreach(referenceFixer(_)) - mappedProcedures.foreach(referenceFixer(_)) - } - val mappedProcesses = processes match { - case Left(body) => - val mappedBody = body.mapConserve(stmt => fn(renamer(stmt)).asInstanceOf[PCalStatement]) - if(mappedBody ne body) { - Left(mappedBody) - } else processes - case Right(processes) => - val mappedProcesses = processes.mapConserve(process => fn(renamer(process)).asInstanceOf[PCalProcess]) - if(mappedProcesses ne processes) { - Right(mappedProcesses) - } else processes - } - withChildren(Iterator(fairness, mappedName, mappedVariables, mappedUnits, mappedMacros, mappedProcedures, mappedProcesses)) - } -} + processes: Either[List[PCalStatement],List[PCalProcess]]) extends PCalNode final case class PCalPVariableDeclaration(name: TLAIdentifier, value: Option[TLAExpression]) extends PCalNode with DefinitionOne { override def arity: Int = 0 @@ -83,39 +40,13 @@ final case class PCalVariableDeclarationValue(name: TLAIdentifier, value: TLAExp final case class PCalVariableDeclarationSet(name: TLAIdentifier, set: TLAExpression) extends PCalVariableDeclarationBound final case class PCalMacro(name: TLAIdentifier, params: List[TLADefiningIdentifier], body: List[PCalStatement], - freeVars: List[TLADefiningIdentifier]) extends PCalNode { - override def mapChildren(fn: Any => Any): this.type = { - val renamer = new Renamer[TLADefiningIdentifier]() - val mappedName = fn(name) - val mappedFreeVars = renamer.mapConserveRenamingAny(freeVars, fn) - val mappedParams = renamer.mapConserveRenamingAny(params, fn) - val mappedBody = body.mapConserve(stmt => fn(renamer(stmt)).asInstanceOf[PCalStatement]) - withChildren(Iterator(mappedName, mappedParams, mappedBody, mappedFreeVars)) - } -} + freeVars: List[TLADefiningIdentifier]) extends PCalNode with RefersTo.HasReferences final case class PCalProcedure(name: TLAIdentifier, params: List[PCalPVariableDeclaration], - variables: List[PCalPVariableDeclaration], body: List[PCalStatement]) extends PCalNode { - override def mapChildren(fn: Any => Any): this.type = { - val renamer = new Renamer[DefinitionOne with Rewritable]() - val mappedName = fn(name).asInstanceOf[TLAIdentifier] - val mappedParams = renamer.mapConserveRenamingAny(params, fn) - val mappedVariables = renamer.mapConserveRenamingAny(variables, fn) - val mappedBody = body.mapConserve(stmt => fn(renamer(stmt)).asInstanceOf[PCalStatement]) - withChildren(Iterator(mappedName, mappedParams, mappedVariables, mappedBody)) - } -} + variables: List[PCalPVariableDeclaration], body: List[PCalStatement]) extends PCalNode with RefersTo.HasReferences final case class PCalProcess(selfDecl: PCalVariableDeclarationBound, fairness: PCalFairness, - variables: List[PCalVariableDeclaration], body: List[PCalStatement]) extends PCalNode { - override def mapChildren(fn: Any => Any): this.type = { - val renamer = new Renamer[PCalVariableDeclaration]() - val mappedSelfDecl = renamer.captureRenamingAny(selfDecl, fn) - val mappedVariables = renamer.mapConserveRenamingAny(variables, fn) - val mappedBody = body.mapConserve(stmt => fn(renamer(stmt)).asInstanceOf[PCalStatement]) - withChildren(Iterator(mappedSelfDecl, fairness, mappedVariables, mappedBody)) - } -} + variables: List[PCalVariableDeclaration], body: List[PCalStatement]) extends PCalNode sealed abstract class PCalStatement extends PCalNode @@ -165,11 +96,4 @@ final case class PCalSkip() extends PCalStatement final case class PCalWhile(condition: TLAExpression, body: List[PCalStatement]) extends PCalStatement -final case class PCalWith(variables: List[PCalVariableDeclarationBound], body: List[PCalStatement]) extends PCalStatement { - override def mapChildren(fn: Any => Any): this.type = { - val renamer = new Renamer[PCalVariableDeclarationBound]() - val mappedVariables = renamer.mapConserveRenamingAny(variables, fn) - val mappedBody = body.mapConserve(bodyStmt => fn(renamer(bodyStmt)).asInstanceOf[PCalStatement]) - withChildren(Iterator(mappedVariables, mappedBody)) - } -} +final case class PCalWith(variables: List[PCalVariableDeclarationBound], body: List[PCalStatement]) extends PCalStatement diff --git a/src/pgo/model/tla/AST.scala b/src/pgo/model/tla/AST.scala index b1a503172..54ffb35f7 100644 --- a/src/pgo/model/tla/AST.scala +++ b/src/pgo/model/tla/AST.scala @@ -1,6 +1,5 @@ package pgo.model.tla -import pgo.model.RefersTo.Renamer import pgo.model.{Definition, DefinitionComposite, DefinitionOne, RefersTo, Rewritable, SourceLocatable, Visitable} import scala.collection.View @@ -228,7 +227,7 @@ object TLAOpDecl { } } -sealed abstract class TLAUnit extends TLANode { +sealed abstract class TLAUnit extends TLANode with RefersTo.HasReferences { def definitions: View[Definition] } @@ -259,13 +258,9 @@ final case class TLAModule(name: TLAIdentifier, exts: List[TLAModuleRef], units: units.view.flatMap(_.definitions).flatMap(_.singleDefinitions).filter(captureLocal || _.isLocal) override def mapChildren(fn: Any => Any): this.type = { - val renamer = new Renamer[TLAUnit]() - val mappedName = fn(name) - val mappedExts = exts.mapConserve(ext => fn(ext).asInstanceOf[TLAModuleRef]) - assert(mappedExts eq exts, s"internal error: can't automatically rewrite module contents after replacing EXTENDS clause(s)") - - val mappedUnits = renamer.mapConserveRenamingAny(units, fn) - withChildren(Iterator(mappedName, mappedExts, mappedUnits)) + val mapped = super.mapChildren(fn) + assert(mapped.exts eq exts, s"internal error: can't automatically rewrite module contents after replacing EXTENDS clause(s)") + mapped } } @@ -325,8 +320,6 @@ sealed abstract class TLAExpression extends TLANode final case class TLAExtensionExpression(contents: Any) extends TLAExpression -//final case class TLABool(value: Boolean) extends TLAExpression - final case class TLAString(value: String) extends TLAExpression final case class TLANumber(value: TLANumber.Value, syntax: TLANumber.Syntax = TLANumber.DecimalSyntax) extends TLAExpression @@ -341,7 +334,6 @@ object TLANumber { case object BinarySyntax extends Syntax case object OctalSyntax extends Syntax case object HexadecimalSyntax extends Syntax - } final case class TLAGeneralIdentifier(name: TLAIdentifier, prefix: List[TLAGeneralIdentifierPart]) extends TLAExpression with RefersTo[DefinitionOne] @@ -356,14 +348,7 @@ final case class TLABinOp(operation: TLASymbol, prefix: List[TLAGeneralIdentifie final case class TLAIf(cond: TLAExpression, tval: TLAExpression, fval: TLAExpression) extends TLAExpression -final case class TLALet(defs: List[TLAUnit], body: TLAExpression) extends TLAExpression { - override def mapChildren(fn: Any => Any): this.type = { - val renamer = new RefersTo.Renamer[TLAUnit]() - val mappedDefs = renamer.mapConserveRenamingAny(defs, fn) - val mappedBody = fn(renamer(body)) - withChildren(Iterator(mappedDefs, mappedBody)) - } -} +final case class TLALet(defs: List[TLAUnit], body: TLAExpression) extends TLAExpression final case class TLACase(arms: List[TLACaseArm], other: Option[TLAExpression]) extends TLAExpression @@ -381,14 +366,7 @@ object TLAFairness { case object WeakFairness extends Kind } -final case class TLAFunction(args: List[TLAQuantifierBound], body: TLAExpression) extends TLAExpression { - override def mapChildren(fn: Any => Any): this.type = { - val renamer = new RefersTo.Renamer[TLAQuantifierBound]() - val mappedArgs = renamer.mapConserveRenamingAny(args, fn) - val mappedBody = fn(renamer(body)) - withChildren(Iterator(mappedArgs, mappedBody)) - } -} +final case class TLAFunction(args: List[TLAQuantifierBound], body: TLAExpression) extends TLAExpression final case class TLAFunctionCall(function: TLAExpression, params: List[TLAExpression]) extends TLAExpression @@ -401,16 +379,8 @@ final case class TLAFunctionSubstitutionPair(keys: List[TLAFunctionSubstitutionK final case class TLAFunctionSubstitutionKey(indices: List[TLAExpression]) extends TLANode trait TLAQuantified { - self: Rewritable => def bounds: List[TLAQuantifierBound] def body: TLAExpression - - override def mapChildren(fn: Any => Any): this.type = { - val renamer = new RefersTo.Renamer[TLAQuantifierBound]() - val mappedBounds = renamer.mapConserveRenamingAny(bounds, fn) - val mappedBody = fn(renamer(body)) - withChildren(Iterator(mappedBounds, mappedBody)) - } } final case class TLAQuantifiedExistential(bounds: List[TLAQuantifierBound], body: TLAExpression) extends TLAExpression with TLAQuantified @@ -418,16 +388,8 @@ final case class TLAQuantifiedExistential(bounds: List[TLAQuantifierBound], body final case class TLAQuantifiedUniversal(bounds: List[TLAQuantifierBound], body: TLAExpression) extends TLAExpression with TLAQuantified trait TLAUnquantified { - self: Rewritable => def ids: List[TLADefiningIdentifier] def body: TLAExpression - - override def mapChildren(fn: Any => Any): this.type = { - val renamer = new RefersTo.Renamer[TLADefiningIdentifier]() - val mappedIds = renamer.mapConserveRenamingAny(ids, fn) - val mappedBody = fn(renamer.apply(body)) - withChildren(Iterator(mappedIds, mappedBody)) - } } final case class TLAExistential(ids: List[TLADefiningIdentifier], body: TLAExpression) extends TLAExpression with TLAUnquantified @@ -436,23 +398,9 @@ final case class TLAUniversal(ids: List[TLADefiningIdentifier], body: TLAExpress final case class TLASetConstructor(contents: List[TLAExpression]) extends TLAExpression -final case class TLASetRefinement(binding: TLAQuantifierBound, when: TLAExpression) extends TLAExpression { - override def mapChildren(fn: Any => Any): this.type = { - val renamer = new RefersTo.Renamer[TLAQuantifierBound]() - val mappedBinding = renamer.captureRenamingAny(binding, fn) - val mappedWhen = fn(renamer(when)) - withChildren(Iterator(mappedBinding, mappedWhen)) - } -} +final case class TLASetRefinement(binding: TLAQuantifierBound, when: TLAExpression) extends TLAExpression -final case class TLASetComprehension(body: TLAExpression, bounds: List[TLAQuantifierBound]) extends TLAExpression { - override def mapChildren(fn: Any => Any): this.type = { - val renamer = new RefersTo.Renamer[TLAQuantifierBound]() - val mappedBounds = renamer.mapConserveRenamingAny(bounds, fn) - val mappedBody = fn(renamer(body)) - withChildren(Iterator(mappedBody, mappedBounds)) - } -} +final case class TLASetComprehension(body: TLAExpression, bounds: List[TLAQuantifierBound]) extends TLAExpression final case class TLATuple(elements: List[TLAExpression]) extends TLAExpression diff --git a/src/pgo/parser/MPCalParser.scala b/src/pgo/parser/MPCalParser.scala index 915ec14c9..2adda9e81 100644 --- a/src/pgo/parser/MPCalParser.scala +++ b/src/pgo/parser/MPCalParser.scala @@ -191,8 +191,8 @@ trait MPCalParser extends PCalParser { } ref } - } - }.map(TLAExtensionExpression) | super.pcalCallParam + }.map(TLAExtensionExpression) + } | super.pcalCallParam } } diff --git a/src/pgo/trans/MPCalSemanticCheckPass.scala b/src/pgo/trans/MPCalSemanticCheckPass.scala index 66f650099..e5632cac7 100644 --- a/src/pgo/trans/MPCalSemanticCheckPass.scala +++ b/src/pgo/trans/MPCalSemanticCheckPass.scala @@ -307,6 +307,32 @@ object MPCalSemanticCheckPass { val paramsMap = params.view.map(p => p -> p).to(IdMap) body.foreach { stmt => stmt.visit(Visitable.BottomUpFirstStrategy) { + case PCalAssignmentPair(lhs, _) => + @tailrec + def findMappingCount(lhs: PCalAssignmentLhs, acc: Int = 0): Int = + lhs match { + case PCalAssignmentLhsIdentifier(_) => acc + case PCalAssignmentLhsProjection(lhs, _) => findMappingCount(lhs, acc + 1) + } + + @tailrec + def findDefn(lhs: PCalAssignmentLhs): Option[MPCalParam] = + lhs match { + case lhs @PCalAssignmentLhsIdentifier(_) => + lhs.refersTo match { + case p: MPCalParam => Some(p) + case _ => None + } + case PCalAssignmentLhsProjection(lhs, _) => findDefn(lhs) + } + + findDefn(lhs).foreach { defn => + val mappingCount = findMappingCount(lhs) + val mappingCountP = defn.mappingCount + if(mappingCountP > mappingCount) { + errors += SemanticError.MPCalKindMismatchError(usage = lhs, defn = defn) + } + } case ref @MPCalValExpr(_, mappingCount) => paramsMap(ref.refersTo) match { case defn @ MPCalRefParam(_, mappingCountP) => diff --git a/test/files/semantics/MPCalKindMatching.tla b/test/files/semantics/MPCalKindMatching.tla index 2da5b304e..951a6f636 100644 --- a/test/files/semantics/MPCalKindMatching.tla +++ b/test/files/semantics/MPCalKindMatching.tla @@ -3,7 +3,15 @@ EXTENDS Sequences, FiniteSets, Integers (* --mpcal MPCalKindMatching { procedure Proc(ref a[_]) { - l2: call Proc(a); + l2: call Proc((*:: expectedError: MPCalKindMismatchError *) a); + l4: call Proc2(ref a[_]); + l5: a[2] := 3; + l3: (*:: expectedError: MPCalKindMismatchError *) a := 3; + l6: a[5][6] := 3; + } + + procedure Proc2(ref b[_][_]) { + l3: skip; } archetype Arch(ref a[_]) { @@ -12,11 +20,13 @@ EXTENDS Sequences, FiniteSets, Integers variables myVar; - process (A = 42) == instance Arch(myVar[_]); + process (A = 42) == instance Arch((*:: expectedError: MPCalKindMismatchError *) myVar[_]); + + process (B = 43) == instance Arch((*:: expectedError: MPCalKindMismatchError *) ref myVar); - process (B = 43) == instance Arch(ref myVar); + process (C = 44) == instance Arch((*:: expectedError: MPCalKindMismatchError *) myVar); - process (C = 44) == instance Arch(myVar); + process (D = 45) == instance Arch((*:: expectedError: MPCalKindMismatchError *) ref myVar[_][_]); } *) \* BEGIN TRANSLATION From b525a3bcd04888f8e1fdd1c539f9736bb5fe0515 Mon Sep 17 00:00:00 2001 From: fhackett Date: Fri, 23 Apr 2021 01:56:59 -0700 Subject: [PATCH 03/27] fix minor glitches; begin testing on real MPCal specs, normalize seems to work --- src/pgo/model/SourceLocation.scala | 3 + src/pgo/parser/MPCalParser.scala | 6 +- src/pgo/parser/TLAMeta.scala | 2 +- src/pgo/trans/MPCalNormalizePass.scala | 225 +- src/pgo/trans/MPCalPCalCodegenPass.scala | 1 - src/pgo/trans/MPCalSemanticCheckPass.scala | 45 +- src/pgo/util/MPCalPassUtils.scala | 34 +- test/files/pcalgen/dqueue.tla | 284 ++ test/files/pcalgen/load_balancer.tla | 578 +++ test/files/pcalgen/replicated_kv.tla | 3216 +++++++++++++++++ .../files/semantics/IfEitherLabelingRules.tla | 5 + 11 files changed, 4313 insertions(+), 86 deletions(-) create mode 100644 test/files/pcalgen/dqueue.tla create mode 100644 test/files/pcalgen/load_balancer.tla create mode 100644 test/files/pcalgen/replicated_kv.tla diff --git a/src/pgo/model/SourceLocation.scala b/src/pgo/model/SourceLocation.scala index e568f3487..20044372c 100644 --- a/src/pgo/model/SourceLocation.scala +++ b/src/pgo/model/SourceLocation.scala @@ -13,6 +13,9 @@ sealed abstract class SourceLocation { def maybeOffset: Int = -1 + def derivedVia(description: Description, viaPos: SourceLocation = SourceLocationInternal): SourceLocation = + DerivedSourceLocation(this, viaPos, description) + def ++(other: SourceLocation): SourceLocation = { (this, other) match { case (SourceLocationUnknown, SourceLocationUnknown) => SourceLocationUnknown diff --git a/src/pgo/parser/MPCalParser.scala b/src/pgo/parser/MPCalParser.scala index 2adda9e81..f753dd3ae 100644 --- a/src/pgo/parser/MPCalParser.scala +++ b/src/pgo/parser/MPCalParser.scala @@ -59,10 +59,10 @@ trait MPCalParser extends PCalParser { withSourceLocation { querySourceLocation("@" ~> mpcalMappingPosition) ~ (ws ~> mpcalRefSuffix) ^^ { case (positionLoc, position) ~ mappingCount => - if(position > maxPosition) { + if(position > maxPosition || position <= 0) { throw MappingIndexOutOfBounds(positionLoc, position, maxPosition) } - MPCalMappingTarget(position, mappingCount) + MPCalMappingTarget(position-1, mappingCount) } } } ~ (ws ~> "via" ~> ws ~> tlaIdentifierExpr) ^^ { @@ -119,7 +119,7 @@ trait MPCalParser extends PCalParser { mpcalSpecialVariable | super.tlaExpressionNoOperators override def pcalLhsId(implicit ctx: PCalParserContext): Parser[PCalAssignmentLhs] = - (mpcalSpecialVariable ^^ PCalAssignmentLhsExtension) | super.pcalLhsId + withSourceLocation(mpcalSpecialVariable ^^ PCalAssignmentLhsExtension) | super.pcalLhsId override val pcalCSyntax: PCalCSyntax = new PCalCSyntax { override def pcalUnlabeledStmt(implicit ctx: PCalParserContext): Parser[PCalStatement] = diff --git a/src/pgo/parser/TLAMeta.scala b/src/pgo/parser/TLAMeta.scala index 273149a9d..2d9617cb2 100644 --- a/src/pgo/parser/TLAMeta.scala +++ b/src/pgo/parser/TLAMeta.scala @@ -117,7 +117,7 @@ object TLAMeta { raw"""\succeq""" -> (5, 5, false), raw"""\supset""" -> (5, 5, false), raw"""\supseteq""" -> (5, 5, false), - raw"""${ "\\" }union""" -> (8, 8, false), + raw"""${ "\\" }union""" -> (8, 8, true), raw"""${ "\\" }uplus""" -> (9, 13, true), raw"""\wr""" -> (9, 14, false), raw"""^""" -> (14, 14, false), diff --git a/src/pgo/trans/MPCalNormalizePass.scala b/src/pgo/trans/MPCalNormalizePass.scala index d12415da3..5062bd433 100644 --- a/src/pgo/trans/MPCalNormalizePass.scala +++ b/src/pgo/trans/MPCalNormalizePass.scala @@ -1,75 +1,202 @@ package pgo.trans -import pgo.model.{PGoError, Rewritable} +import pgo.model.{DerivedSourceLocation, PGoError, Rewritable, SourceLocationInternal, Visitable} import pgo.model.mpcal._ import pgo.model.pcal._ import pgo.model.tla._ -import pgo.util.{MPCalPassUtils, NameCleaner} +import pgo.util.{Description, IdMap, MPCalPassUtils, NameCleaner} +import Description._ import scala.annotation.tailrec object MPCalNormalizePass { @throws[PGoError] def apply(tlaModule: TLAModule, mpcalBlock: MPCalBlock): MPCalBlock = { - // remove while loops - var block: MPCalBlock = mpcalBlock.rewrite(Rewritable.BottomUpOnceStrategy) { + var block: MPCalBlock = mpcalBlock + + // expand all PCal macros (not including archetypes + mapping macros) + block = MPCalPassUtils.rewriteEachBody(block) { (body, lexicalScope) => + MPCalPassUtils.expandMacroCalls(body, lexicalScope) + } + // remove the now-expanded macros + block = block.decorateLike(block.copy(macros = Nil)) + + // normalise label nesting, so all labels appear at the top level. + // retain control flow by injecting synthetic gotos at label boundaries that use fall-through + // do this as early as possible (minus PCal macros), as it helps other passes skip nested label-related edge cases: + // it is very useful to have the guarantee that some syntactically nested compound statement must be entirely + // within the same critical section (and, in some cases, to know that syntactically all sub-statements will not involve labels) + block = locally { + val containsLabels = MPCalPassUtils.gatherContainsLabels(block) + + MPCalPassUtils.rewriteEachBody(block) { (body, _) => + val labelCleaner = new NameCleaner + body.foreach { stmt => + stmt.visit(Visitable.BottomUpFirstStrategy) { + case PCalLabeledStatements(label, _) => + labelCleaner.addKnownName(label.name) + } + } + + def findLabelAfter(restStmts: List[PCalStatement], labelAfter: Option[PCalLabel]): Option[PCalLabel] = + restStmts match { + case Nil => labelAfter + case PCalLabeledStatements(label, _) :: _ => Some(label) + case _ => None + } + + @tailrec + def transBlocks(blocks: List[PCalLabeledStatements], labelAfter: Option[PCalLabel], blocksOut: Iterator[PCalLabeledStatements]): Iterator[PCalLabeledStatements] = + blocks match { + case Nil => blocksOut + case (labeledStmts @PCalLabeledStatements(whileLabel, (whileStmt @PCalWhile(whileCondition, whileBody)) :: afterWhileStmts)) :: restBlocks => + val (whileBodyTrans, whileBodyBlocks) = impl(whileBody, Some(whileLabel), Iterator.empty, Iterator.empty) + val (afterWhileTrans, afterWhileBlocks) = impl(afterWhileStmts, findLabelAfter(restBlocks, labelAfter), Iterator.empty, Iterator.empty) + val whileTrans = whileStmt.withChildren(Iterator(whileCondition, whileBodyTrans)) + val labeledStmtsTrans = labeledStmts.withChildren(Iterator(whileLabel, whileTrans :: afterWhileTrans)) + transBlocks(restBlocks, labelAfter, blocksOut ++ Iterator.single(labeledStmtsTrans) ++ whileBodyBlocks ++ afterWhileBlocks) + case (labeledStmts @PCalLabeledStatements(label, stmts)) :: restBlocks => + val (stmtsTrans, stmtsBlocks) = impl(stmts, findLabelAfter(restBlocks, labelAfter), Iterator.empty, Iterator.empty) + val labeledTrans = labeledStmts.withChildren(Iterator(label, stmtsTrans)) + transBlocks(restBlocks, labelAfter, blocksOut ++ Iterator.single(labeledTrans) ++ stmtsBlocks) + } + + def transStmt(stmt: PCalStatement, labelAfter: Option[PCalLabel]): (PCalStatement, Iterator[PCalLabeledStatements]) = + stmt match { + case stmt @PCalEither(cases) => + val casesTrans = cases.map(impl(_, labelAfter, Iterator.empty, Iterator.empty)) + (stmt.withChildren(Iterator(casesTrans.map(_._1))), casesTrans.iterator.flatMap(_._2)) + case stmt @PCalIf(condition, yes, no) => + val (yesTrans, yesBlocks) = impl(yes, labelAfter, Iterator.empty, Iterator.empty) + val (noTrans, noBlocks) = impl(no, labelAfter, Iterator.empty, Iterator.empty) + (stmt.withChildren(Iterator(condition, yesTrans, noTrans)), yesBlocks ++ noBlocks) + case PCalLabeledStatements(label, statements) => ??? // should be inaccessible; handled via other cases + case stmt @PCalWhile(condition, body) => + val (bodyTrans, bodyBlocks) = impl(body, labelAfter, Iterator.empty, Iterator.empty) + (stmt.withChildren(Iterator(condition, bodyTrans)), bodyBlocks) + case stmt @PCalWith(variables, body) => + val (bodyTrans, bodyBlocks) = impl(body, labelAfter, Iterator.empty, Iterator.empty) + assert(bodyBlocks.isEmpty) + (stmt.withChildren(Iterator(variables, bodyTrans)), Iterator.empty) + case stmt => (stmt, Iterator.empty) + } + + @tailrec + def impl(stmts: List[PCalStatement], labelAfter: Option[PCalLabel], stmtsOut: Iterator[PCalStatement], blocksOut: Iterator[PCalLabeledStatements]): (List[PCalStatement],Iterator[PCalLabeledStatements]) = { + object ContainsJump { + def unapply(stmts: List[PCalStatement]): Option[(List[PCalStatement],List[PCalStatement])] = + stmts match { + case (goto: PCalGoto) :: restBlocks => Some((List(goto), restBlocks)) + case (ifStmt: PCalIf) :: restBlocks if containsLabels(ifStmt) => Some((List(ifStmt), restBlocks)) + case (either: PCalEither) :: restBlocks if containsLabels(either) => Some((List(either), restBlocks)) + + case (call: PCalCall) :: (ret: PCalReturn) :: restBlocks => Some((List(call, ret), restBlocks)) + case (call: PCalCall) :: (goto: PCalGoto) :: restBlocks => Some((List(call, goto), restBlocks)) + case (call: PCalCall) :: restBlocks => Some((List(call), restBlocks)) + + case (mpCall @PCalExtensionStatement(_: MPCalCall)) :: (ret: PCalReturn) :: restBlocks => Some((List(mpCall, ret), restBlocks)) + case (mpCall @PCalExtensionStatement(_: MPCalCall)) :: (goto: PCalGoto) :: restBlocks => Some((List(mpCall, goto), restBlocks)) + case (mpCall @PCalExtensionStatement(_: MPCalCall)) :: restBlocks => Some((List(mpCall), restBlocks)) + + case _ => None + } + } + + stmts match { + case Nil => + val synthJump = labelAfter.map(label => PCalGoto(label.name).setSourceLocation(DerivedSourceLocation(label.sourceLocation, SourceLocationInternal, d"tail-call transformation"))) + ((stmtsOut ++ synthJump.iterator).toList, blocksOut) + case allBlocks @PCalLabeledStatements(_, _) :: _ => + assert(allBlocks.forall(_.isInstanceOf[PCalLabeledStatements])) + (stmtsOut.toList, transBlocks(allBlocks.asInstanceOf[List[PCalLabeledStatements]], labelAfter, blocksOut)) + case ContainsJump(jumpStmts, restStmts) => + assert(restStmts.forall(_.isInstanceOf[PCalLabeledStatements])) + val jumpTrans = jumpStmts.map(transStmt(_, findLabelAfter(restStmts, labelAfter))) + ((stmtsOut ++ jumpTrans.iterator.map(_._1)).toList, + transBlocks(restStmts.asInstanceOf[List[PCalLabeledStatements]], labelAfter, blocksOut ++ jumpTrans.iterator.flatMap(_._2))) + case stmt :: restStmts => + val (stmtTrans, stmtBlocks) = transStmt(stmt, findLabelAfter(restStmts, labelAfter)) + impl(restStmts, labelAfter, stmtsOut ++ Iterator.single(stmtTrans), blocksOut ++ stmtBlocks) + } + } + + body match { + case PCalLabeledStatements(_, _) :: _ => + assert(body.forall(_.isInstanceOf[PCalLabeledStatements])) + transBlocks(body.asInstanceOf[List[PCalLabeledStatements]], None, Iterator.empty).toList + case _ => + assert(body.forall(!containsLabels(_))) + body + } + + } + } + + // desugar while loops into ifs and gotos + // note: the statements after the while go inside the _else branch_, as evidenced by a label not being needed + // after a label-containing while statement (if it were equivalent to an if with statements after it, a label would be needed) + block = block.rewrite(Rewritable.BottomUpOnceStrategy) { case labeledStmts @PCalLabeledStatements(label, (whileStmt @PCalWhile(condition, body)) :: restStmts) => PCalLabeledStatements( label, - PCalIf( + List(PCalIf( condition, - body :+ PCalGoto(label.name).setSourceLocation(whileStmt.sourceLocation), - Nil).setSourceLocation(whileStmt.sourceLocation) :: restStmts) - .setSourceLocation(labeledStmts.sourceLocation) - } - - block = MPCalPassUtils.rewriteEachBody(block) { (body, lexicalScope) => - MPCalPassUtils.expandMacroCalls(body, lexicalScope) + body :+ PCalGoto(label.name).setSourceLocation(whileStmt.sourceLocation.derivedVia(d"while statement desugaring")), + restStmts).setSourceLocation(whileStmt.sourceLocation.derivedVia(d"while statement desugaring"))) + ).setSourceLocation(labeledStmts.sourceLocation) } + // needed below: gather all names, to generate synthetic ones for multiple assignment temp vars val nameCleaner = new NameCleaner MPCalPassUtils.forEachName(tlaModule, block)(nameCleaner.addKnownName) + block.visit(Visitable.BottomUpFirstStrategy) { + case ident: TLAIdentifier => nameCleaner.addKnownName(ident.id) + } - // remove multiple assignment - block = MPCalPassUtils.rewriteEachBody(block) { (body, _) => - def impl(body: List[PCalStatement]): List[PCalStatement] = - body.flatMap { - case PCalAssignment(pairs) if pairs.size > 1 => - @tailrec - def lhsIdentifier(lhs: PCalAssignmentLhs): TLAIdentifier = + // desugar multiple assignment into single assignment, using a with statement to ensure correct order of operations + block = block.rewrite(Rewritable.BottomUpOnceStrategy) { + case assignment @PCalAssignment(pairs) if pairs.size > 1 => + @tailrec + def lhsIdentifier(lhs: PCalAssignmentLhs): PCalAssignmentLhsIdentifier = + lhs match { + case ident @PCalAssignmentLhsIdentifier(_) => ident + case PCalAssignmentLhsProjection(lhs, _) => lhsIdentifier(lhs) + } + val bindings = pairs.map { + case pair @PCalAssignmentPair(lhs, rhs) => + val lhsIdent = lhsIdentifier(lhs) + val lhsName = nameCleaner.cleanName(lhsIdent.identifier.id) + val decl = PCalVariableDeclarationValue( + TLAIdentifier(lhsName) + .setSourceLocation(lhsIdent.sourceLocation.derivedVia(d"multiple-assignment desugaring")), + rhs) + .setSourceLocation(pair.sourceLocation.derivedVia(d"multiple-assignment desugaring")) + (lhsIdent.refersTo, decl) + } + val refMap = bindings.to(IdMap) + PCalWith(bindings.map(_._2), pairs.map { + case pair @PCalAssignmentPair(lhs, rhs) => + def applyRenamings[T <: Rewritable](rewritable: T): T = + rewritable.rewrite(Rewritable.BottomUpOnceStrategy) { + case ident: TLAGeneralIdentifier if refMap.contains(ident.refersTo) => + val defn = refMap(ident.refersTo) + val loc = ident.sourceLocation.derivedVia(d"multiple-assignment desugaring") + TLAGeneralIdentifier(defn.name.shallowCopy().setSourceLocation(loc), Nil) + .setSourceLocation(loc) + .setRefersTo(defn) + } + + def applyRenamingsToLhs(lhs: PCalAssignmentLhs): PCalAssignmentLhs = lhs match { - case PCalAssignmentLhsIdentifier(identifier) => identifier - case PCalAssignmentLhsProjection(lhs, _) => lhsIdentifier(lhs) - case PCalAssignmentLhsExtension(contents) => ??? + case ident @PCalAssignmentLhsIdentifier(_) => ident + case proj @PCalAssignmentLhsProjection(lhs, projections) => + proj.withChildren(Iterator(applyRenamingsToLhs(lhs), projections.mapConserve(applyRenamings))) } - val bindings = pairs.map { - case pair @PCalAssignmentPair(lhs, rhs) => - val lhsIdent = lhsIdentifier(lhs) - val lhsName = nameCleaner.cleanName(lhsIdent.id) - PCalVariableDeclarationValue(lhsIdent.withChildren(Iterator(lhsName)), rhs) - .setSourceLocation(pair.sourceLocation) - } - pairs.map { - case pair @PCalAssignmentPair(lhs, rhs) => - PCalAssignment(List(???)) - } - case stmt @PCalEither(cases) => - List(stmt.withChildren(Iterator(cases.mapConserve(impl)))) - case stmt @PCalIf(condition, yes, no) => - List(stmt.withChildren(Iterator( - condition, impl(yes), impl(no)))) - case stmt @PCalLabeledStatements(label, statements) => - List(stmt.withChildren(Iterator( - label, impl(statements)))) - case stmt @PCalWhile(condition, body) => - List(stmt.withChildren(Iterator( - condition, impl(body)))) - case stmt @PCalWith(variables, body) => - List(stmt.withChildren(Iterator( - variables, impl(body)))) - } - impl(body) + PCalAssignment(List(PCalAssignmentPair(applyRenamingsToLhs(lhs), applyRenamings(rhs)))) + .setSourceLocation(pair.sourceLocation.derivedVia(d"multiple-assignment desugaring")) + }) + .setSourceLocation(assignment.sourceLocation.derivedVia(d"multiple-assignment desugaring")) } block diff --git a/src/pgo/trans/MPCalPCalCodegenPass.scala b/src/pgo/trans/MPCalPCalCodegenPass.scala index dc8cbc6b0..8feb9dce6 100644 --- a/src/pgo/trans/MPCalPCalCodegenPass.scala +++ b/src/pgo/trans/MPCalPCalCodegenPass.scala @@ -5,7 +5,6 @@ import pgo.model.mpcal.MPCalBlock import pgo.model.pcal.PCalAlgorithm object MPCalPCalCodegenPass { - @throws[PGoError] def apply(mpcalBlock: MPCalBlock): PCalAlgorithm = ??? } diff --git a/src/pgo/trans/MPCalSemanticCheckPass.scala b/src/pgo/trans/MPCalSemanticCheckPass.scala index e5632cac7..4aa743630 100644 --- a/src/pgo/trans/MPCalSemanticCheckPass.scala +++ b/src/pgo/trans/MPCalSemanticCheckPass.scala @@ -111,35 +111,7 @@ object MPCalSemanticCheckPass { hasRecursiveMacro } - val containsLabels: IdSet[PCalStatement] = locally { - var containsLabels = IdSet.empty[PCalStatement] - def gatherContainsLabels(stmt: PCalStatement): Boolean = { - // note: the seemingly over-engineered map+reduce ensures all sub-statements are reached, - // vs. a more concise but short-circuiting .exists(...) - val result: Boolean = stmt match { - case PCalEither(cases) => cases.view.flatMap(_.view.map(gatherContainsLabels)).foldLeft(false)(_ || _) - case PCalIf(_, yes, no) => - yes.view.map(gatherContainsLabels).foldLeft(false)(_ || _) || - no.view.map(gatherContainsLabels).foldLeft(false)(_ || _) - case PCalLabeledStatements(_, statements) => - statements.foreach(gatherContainsLabels) - true - case PCalWhile(_, body) => body.view.map(gatherContainsLabels).foldLeft(false)(_ || _) - case PCalWith(_, body) => body.view.map(gatherContainsLabels).foldLeft(false)(_ || _) - case _ => false - } - if(result) { - containsLabels += stmt - } - result - } - - mpcalBlock.visit(Visitable.TopDownFirstStrategy) { - case stmt: PCalStatement => gatherContainsLabels(stmt) - } - - containsLabels - } + val containsLabels: IdSet[PCalStatement] = MPCalPassUtils.gatherContainsLabels(mpcalBlock) val tailStatements: IdMap[PCalStatement,Vector[PCalStatement]] = locally { var tailStatements = IdMap.empty[PCalStatement,Vector[PCalStatement]] @@ -175,6 +147,7 @@ object MPCalSemanticCheckPass { def checkWhileLabelPlacement(visitable: Visitable): Unit = visitable.visit(Visitable.TopDownFirstStrategy) { + case PCalMacro(_, _, _, _) => // skip macro bodies, we check these at expansion site case PCalLabeledStatements(_, PCalWhile(_, whileBody) :: restBody) => whileBody.foreach(checkWhileLabelPlacement) restBody.foreach(checkWhileLabelPlacement) @@ -183,7 +156,16 @@ object MPCalSemanticCheckPass { body.foreach(checkWhileLabelPlacement) } - checkWhileLabelPlacement(mpcalBlock) + // check that all while statements are directly inside labels (accounting for macro expansion, if that's sound) + checkWhileLabelPlacement { + if(!hasRecursiveMacro) { + MPCalPassUtils.rewriteEachBody(mpcalBlock) { (body, lexicalScope) => + MPCalPassUtils.expandMacroCalls(body, lexicalScope) + } + } else { + mpcalBlock + } + } // check whether statements that must be followed by a label are followed by a label locally { @@ -203,6 +185,7 @@ object MPCalSemanticCheckPass { val labelNeedingStatementComesBefore = tailStatements(beforeStmt).exists { case ifStmt: PCalIf => containsLabels(ifStmt) + case eitherStmt: PCalEither => containsLabels(eitherStmt) case _: PCalReturn => true case _: PCalGoto => true case _: PCalCall => !supportsTailCall(notLabel) @@ -250,6 +233,7 @@ object MPCalSemanticCheckPass { lhs match { case PCalAssignmentLhsIdentifier(identifier) => identifier case PCalAssignmentLhsProjection(lhs, _) => getId(lhs) + case PCalAssignmentLhsExtension(TLAExtensionExpression(MPCalDollarVariable())) => TLAIdentifier("$variable") // hack to model special var } val lhsId = getId(lhs) @@ -382,6 +366,7 @@ object MPCalSemanticCheckPass { } (archetype.params.view zip arguments.view).foreach { case (MPCalRefParam(_, mappingCountP), Left(MPCalRefParam(_, mappingCount))) if mappingCount == mappingCountP => // ok + case (MPCalRefParam(_, 0), Right(_)) => // ok (see TODO above..?) case (MPCalValParam(_, 0), Right(_)) => // ok case (MPCalValParam(_, mappingCountP), Left(MPCalValParam(_, mappingCount))) if mappingCount == mappingCountP => // ok case (param, Left(arg)) => diff --git a/src/pgo/util/MPCalPassUtils.scala b/src/pgo/util/MPCalPassUtils.scala index e2e08f2d0..3bf770937 100644 --- a/src/pgo/util/MPCalPassUtils.scala +++ b/src/pgo/util/MPCalPassUtils.scala @@ -118,7 +118,7 @@ object MPCalPassUtils { case badExpr => throw MacroExpandError(List(MacroExpandError.MacroExpandAssignmentLhsError(ref, badExpr))) } - case ref: RefersTo[TLADefiningIdentifier] if paramsMap.contains(ref.refersTo) => + case ref: RefersTo[TLADefiningIdentifier @unchecked] if paramsMap.contains(ref.refersTo) => paramsMap(ref.refersTo): TLAExpression case ref: SourceLocatable => ref.shallowCopy().setSourceLocation( @@ -127,7 +127,7 @@ object MPCalPassUtils { // remap all the references to free variables to point to what the free vars point to (relies on duplication, from above) body.foreach(_.visit(Visitable.BottomUpFirstStrategy) { - case ref: RefersTo[DefinitionOne] if referenceMapping.contains(ref.refersTo) => + case ref: RefersTo[DefinitionOne @unchecked] if referenceMapping.contains(ref.refersTo) => ref.setRefersTo(referenceMapping(ref.refersTo)) }) body @@ -160,4 +160,34 @@ object MPCalPassUtils { variables.foldLeft(enclosingScope)((nestedScope, v) => nestedScope.updated(v.name.id, v)))))) case stmt => List(stmt) } + + def gatherContainsLabels(mpcalBlock: MPCalBlock): IdSet[PCalStatement] = { + var containsLabels = IdSet.empty[PCalStatement] + def gatherContainsLabels(stmt: PCalStatement): Boolean = { + // note: the seemingly over-engineered map+reduce ensures all sub-statements are reached, + // vs. a more concise but short-circuiting .exists(...) + val result: Boolean = stmt match { + case PCalEither(cases) => cases.view.flatMap(_.view.map(gatherContainsLabels)).foldLeft(false)(_ || _) + case PCalIf(_, yes, no) => + yes.view.map(gatherContainsLabels).foldLeft(false)(_ || _) || + no.view.map(gatherContainsLabels).foldLeft(false)(_ || _) + case PCalLabeledStatements(_, statements) => + statements.foreach(gatherContainsLabels) + true + case PCalWhile(_, body) => body.view.map(gatherContainsLabels).foldLeft(false)(_ || _) + case PCalWith(_, body) => body.view.map(gatherContainsLabels).foldLeft(false)(_ || _) + case _ => false + } + if(result) { + containsLabels += stmt + } + result + } + + mpcalBlock.visit(Visitable.TopDownFirstStrategy) { + case stmt: PCalStatement => gatherContainsLabels(stmt) + } + + containsLabels + } } diff --git a/test/files/pcalgen/dqueue.tla b/test/files/pcalgen/dqueue.tla new file mode 100644 index 000000000..125df98a8 --- /dev/null +++ b/test/files/pcalgen/dqueue.tla @@ -0,0 +1,284 @@ +----------------------------- MODULE dqueue ----------------------------- +(***************************************************************************) +(* Distributed queue using Modular PlusCal. *) +(***************************************************************************) + +EXTENDS Naturals, Sequences, TLC + +CONSTANTS BUFFER_SIZE, NUM_CONSUMERS, PRODUCER + + +(*************************************************************************** +--mpcal dqueue { + define { + (* total nodes in the system: number of consumers + the producer *) + NUM_NODES == NUM_CONSUMERS + 1 + } + + mapping macro TCPChannel { + read { + await Len($variable) > 0; + with (msg = Head($variable)) { + $variable := Tail($variable); + yield msg; + }; + } + + write { + await Len($variable) < BUFFER_SIZE; + yield Append($variable, $value); + } + } + + mapping macro CyclicReads { + read { + $variable := ($variable + 1) % BUFFER_SIZE; + yield $variable; + + } + + write { yield $variable } + } + + (* consumer: Processes one element read from the network at a time, infinitely *) + archetype AConsumer(ref net, ref proc) { + c: while (TRUE) { + (* request more data to the producer by sending your own identifier + over the network *) + c1: net[PRODUCER] := self; + + (* processes the piece of data the producer sends back over the network + by writing to a "processor" abstract interface *) + c2: proc := net[self]; + } + } + + archetype AProducer(ref net, s) + variable requester; { + p: while (TRUE) { + (* wait for a consumer to request data *) + p1: requester := net[self]; + + (* send some data to the requester coming from a "stream" abstract interface *) + p2: net[requester] := s; + } + } + + variables network = [id \in 0..NUM_NODES-1 |-> <<>>], + processor = 0, + stream = 0; + + fair process (Consumer \in 1..NUM_CONSUMERS) == instance AConsumer(ref network, ref processor) + mapping network[_] via TCPChannel; + fair process (Producer \in {PRODUCER}) == instance AProducer(ref network, stream) + mapping network[_] via TCPChannel + mapping stream via CyclicReads; +} + +\* BEGIN PLUSCAL TRANSLATION +--algorithm dqueue { + variables network = [id \in (0) .. ((NUM_NODES) - (1)) |-> <<>>], processor = 0, stream = 0, netWrite, netRead, procWrite, netWrite0, procWrite0, netRead0, netWrite1, sRead, sWrite, netWrite2, sWrite0; + define { + NUM_NODES == (NUM_CONSUMERS) + (1) + } + fair process (Consumer \in (1) .. (NUM_CONSUMERS)) + { + c: + if (TRUE) { + c1: + await (Len(network[PRODUCER])) < (BUFFER_SIZE); + netWrite := [network EXCEPT ![PRODUCER] = Append(network[PRODUCER], self)]; + network := netWrite; + + c2: + await (Len(network[self])) > (0); + with (msg0 = Head(network[self])) { + netWrite := [network EXCEPT ![self] = Tail(network[self])]; + netRead := msg0; + }; + procWrite := netRead; + network := netWrite; + processor := procWrite; + goto c; + + } else { + netWrite0 := network; + procWrite0 := processor; + network := netWrite0; + processor := procWrite0; + }; + + } + fair process (Producer \in {PRODUCER}) + variables requester; + { + p: + if (TRUE) { + p1: + await (Len(network[self])) > (0); + with (msg1 = Head(network[self])) { + netWrite1 := [network EXCEPT ![self] = Tail(network[self])]; + netRead0 := msg1; + }; + requester := netRead0; + network := netWrite1; + + p2: + sWrite := ((stream) + (1)) % (BUFFER_SIZE); + sRead := sWrite; + await (Len(network[requester])) < (BUFFER_SIZE); + netWrite1 := [network EXCEPT ![requester] = Append(network[requester], sRead)]; + network := netWrite1; + stream := sWrite; + goto p; + + } else { + netWrite2 := network; + sWrite0 := stream; + network := netWrite2; + stream := sWrite0; + }; + + } +} +\* END PLUSCAL TRANSLATION + + + + +***************************************************************************) +\* BEGIN TRANSLATION PCal-e64ab9284c1a4c5172f564abb6f099c4 +CONSTANT defaultInitValue +VARIABLES network, processor, stream, netWrite, netRead, procWrite, netWrite0, + procWrite0, netRead0, netWrite1, sRead, sWrite, netWrite2, sWrite0, + pc + +(* define statement *) +NUM_NODES == (NUM_CONSUMERS) + (1) + +VARIABLE requester + +vars == << network, processor, stream, netWrite, netRead, procWrite, + netWrite0, procWrite0, netRead0, netWrite1, sRead, sWrite, + netWrite2, sWrite0, pc, requester >> + +ProcSet == ((1) .. (NUM_CONSUMERS)) \cup ({PRODUCER}) + +Init == (* Global variables *) + /\ network = [id \in (0) .. ((NUM_NODES) - (1)) |-> <<>>] + /\ processor = 0 + /\ stream = 0 + /\ netWrite = defaultInitValue + /\ netRead = defaultInitValue + /\ procWrite = defaultInitValue + /\ netWrite0 = defaultInitValue + /\ procWrite0 = defaultInitValue + /\ netRead0 = defaultInitValue + /\ netWrite1 = defaultInitValue + /\ sRead = defaultInitValue + /\ sWrite = defaultInitValue + /\ netWrite2 = defaultInitValue + /\ sWrite0 = defaultInitValue + (* Process Producer *) + /\ requester = [self \in {PRODUCER} |-> defaultInitValue] + /\ pc = [self \in ProcSet |-> CASE self \in (1) .. (NUM_CONSUMERS) -> "c" + [] self \in {PRODUCER} -> "p"] + +c(self) == /\ pc[self] = "c" + /\ IF TRUE + THEN /\ pc' = [pc EXCEPT ![self] = "c1"] + /\ UNCHANGED << network, processor, netWrite0, + procWrite0 >> + ELSE /\ netWrite0' = network + /\ procWrite0' = processor + /\ network' = netWrite0' + /\ processor' = procWrite0' + /\ pc' = [pc EXCEPT ![self] = "Done"] + /\ UNCHANGED << stream, netWrite, netRead, procWrite, netRead0, + netWrite1, sRead, sWrite, netWrite2, sWrite0, + requester >> + +c1(self) == /\ pc[self] = "c1" + /\ (Len(network[PRODUCER])) < (BUFFER_SIZE) + /\ netWrite' = [network EXCEPT ![PRODUCER] = Append(network[PRODUCER], self)] + /\ network' = netWrite' + /\ pc' = [pc EXCEPT ![self] = "c2"] + /\ UNCHANGED << processor, stream, netRead, procWrite, netWrite0, + procWrite0, netRead0, netWrite1, sRead, sWrite, + netWrite2, sWrite0, requester >> + +c2(self) == /\ pc[self] = "c2" + /\ (Len(network[self])) > (0) + /\ LET msg0 == Head(network[self]) IN + /\ netWrite' = [network EXCEPT ![self] = Tail(network[self])] + /\ netRead' = msg0 + /\ procWrite' = netRead' + /\ network' = netWrite' + /\ processor' = procWrite' + /\ pc' = [pc EXCEPT ![self] = "c"] + /\ UNCHANGED << stream, netWrite0, procWrite0, netRead0, netWrite1, + sRead, sWrite, netWrite2, sWrite0, requester >> + +Consumer(self) == c(self) \/ c1(self) \/ c2(self) + +p(self) == /\ pc[self] = "p" + /\ IF TRUE + THEN /\ pc' = [pc EXCEPT ![self] = "p1"] + /\ UNCHANGED << network, stream, netWrite2, sWrite0 >> + ELSE /\ netWrite2' = network + /\ sWrite0' = stream + /\ network' = netWrite2' + /\ stream' = sWrite0' + /\ pc' = [pc EXCEPT ![self] = "Done"] + /\ UNCHANGED << processor, netWrite, netRead, procWrite, netWrite0, + procWrite0, netRead0, netWrite1, sRead, sWrite, + requester >> + +p1(self) == /\ pc[self] = "p1" + /\ (Len(network[self])) > (0) + /\ LET msg1 == Head(network[self]) IN + /\ netWrite1' = [network EXCEPT ![self] = Tail(network[self])] + /\ netRead0' = msg1 + /\ requester' = [requester EXCEPT ![self] = netRead0'] + /\ network' = netWrite1' + /\ pc' = [pc EXCEPT ![self] = "p2"] + /\ UNCHANGED << processor, stream, netWrite, netRead, procWrite, + netWrite0, procWrite0, sRead, sWrite, netWrite2, + sWrite0 >> + +p2(self) == /\ pc[self] = "p2" + /\ sWrite' = ((stream) + (1)) % (BUFFER_SIZE) + /\ sRead' = sWrite' + /\ (Len(network[requester[self]])) < (BUFFER_SIZE) + /\ netWrite1' = [network EXCEPT ![requester[self]] = Append(network[requester[self]], sRead')] + /\ network' = netWrite1' + /\ stream' = sWrite' + /\ pc' = [pc EXCEPT ![self] = "p"] + /\ UNCHANGED << processor, netWrite, netRead, procWrite, netWrite0, + procWrite0, netRead0, netWrite2, sWrite0, + requester >> + +Producer(self) == p(self) \/ p1(self) \/ p2(self) + +(* Allow infinite stuttering to prevent deadlock on termination. *) +Terminating == /\ \A self \in ProcSet: pc[self] = "Done" + /\ UNCHANGED vars + +Next == (\E self \in (1) .. (NUM_CONSUMERS): Consumer(self)) + \/ (\E self \in {PRODUCER}: Producer(self)) + \/ Terminating + +Spec == /\ Init /\ [][Next]_vars + /\ \A self \in (1) .. (NUM_CONSUMERS) : WF_vars(Consumer(self)) + /\ \A self \in {PRODUCER} : WF_vars(Producer(self)) + +Termination == <>(\A self \in ProcSet: pc[self] = "Done") + +\* END TRANSLATION TLA-3b32e33f9317d9065792b6369f21a56b +============================================================================= +\* Modification History +\* Last modified Fri Dec 18 02:02:58 PST 2020 by finn +\* Last modified Mon Apr 01 02:11:17 PDT 2019 by minh +\* Last modified Tue Jan 22 18:38:13 PST 2019 by rmc +\* Last modified Wed Oct 12 02:41:48 PDT 2011 by lamport +\* Created Mon Oct 10 06:26:47 PDT 2011 by lamport diff --git a/test/files/pcalgen/load_balancer.tla b/test/files/pcalgen/load_balancer.tla new file mode 100644 index 000000000..a43888fb7 --- /dev/null +++ b/test/files/pcalgen/load_balancer.tla @@ -0,0 +1,578 @@ +----------------------------- MODULE load_balancer ----------------------------- +(***************************************************************************) +(* Specifies a simple load balancer. *) +(***************************************************************************) + +\* Extends some built-in TLA+ modules +EXTENDS Naturals, Sequences, TLC + +\* The `TCPChannel` mapping macro used in this specification is parameterized +\* by a `BUFFER_SIZE` constant. This value controls the number of messages being +\* held in a buffer by each process. Processes trying to send a message to another +\* process with a full buffer wil "block" (not be scheduled by TLC). +CONSTANT BUFFER_SIZE + +\* Define a constant identifier for the load balancer. +CONSTANT LoadBalancerId + +\* The number of servers and clients in the model checking setup. +CONSTANTS NUM_SERVERS, NUM_CLIENTS + +\* TLC should assume that both numbers are greater than zero (i.e., we always +\* have at least one server and one client). Note, however, that increasing +\* these numbers makes the number of states to be checked by TLC to grow +\* exponentially. +ASSUME NUM_SERVERS > 0 /\ NUM_CLIENTS > 0 + +\* GET_PAGE is a label attached to messages sent from the clients to +\* the load balancer. +CONSTANTS GET_PAGE + +\* Represents a file that can be returned by the server +CONSTANT WEB_PAGE + +(*************************************************************************** +--mpcal LoadBalancer { + define { + \* total nodes in the system: + \* number of clients + number of servers + the load balancer + NUM_NODES == NUM_CLIENTS + NUM_SERVERS + 1 + } + + \* The TCPChannel mapping macro models a communication channel + \* between two processes using TCP-like semantics. In particular: + \* + \* - reading from the channel "blocks" unless there is a message + \* ready to be read. + \* - message delivery is reliable and ordered (i.e., FIFO). + mapping macro TCPChannel { + read { + await Len($variable) > 0; + with (msg = Head($variable)) { + $variable := Tail($variable); + yield msg; + }; + } + + write { + await Len($variable) < BUFFER_SIZE; + yield Append($variable, $value); + } + } + + \* Mapping macros keep implementation-specific behavior that we don't + \* want to model check outside of our archetype definitions. + \* In the case of this load balancer, how a server retrieves a web page + \* is orthogonal to the correctness of the properties we are interested + \* to check with this specification. + \* + \* This mapping macro abstracts the process of reading a web page by + \* always returning the `WEB_PAGE` constant when the variable is read. + \* + \* Since "writing" to this mapping is meaningless, the attempting to write + \* to a variable mapped with WebPage will result in a model checking + \* error (see `assert(FALSE)` in the write definition). + mapping macro WebPages { + read { + yield WEB_PAGE; + } + + write { + assert(FALSE); + yield $value; + } + } + + \* ALoadBalancer is the archetype that defines the behavior of + \* the load balancer process. The `mailboxes` parameter represents + \* connections to all nodes in the system. + archetype ALoadBalancer(ref mailboxes) + + \* Local variables of this archetype: + variables + \* Holds messages received by the load balancer (sent + \* by clients) + msg, + + \* identifier attached to every message sent to servers by + \* the load balancer. + next = 0; + { + main: + while (TRUE) { + + \* waits for a message to be received. Upon receipt, the `assert` + \* call ensures that the message is of type `GET_PAGE`, the only + \* type of message supported in this simple specification. + \* + \* Every message received by the load balancer is expected to + \* be a record of the following type. + \* + \* [message_type : Int, client_id : Int, path: Interface{}] + \* + \* Note that tuples are 1-indexed. + rcvMsg: + msg := mailboxes[LoadBalancerId]; + assert(msg.message_type = GET_PAGE); + + \* the load balancer needs to forward the client request to the + \* server, who will process the request and send a web page back to + \* the client. + \* + \* The message sent to the server is a tuple in the format: + \* + \* [message_id : Int, client_id : Int, path: Interface{}] + \* + \* We send the client ID here so that the server can directly + \* reply to a client, bypassing the load balancer. This is usually + \* not what happens in practice, but the model is simple + \* enough for our (illustrative) purposes. + sendServer: + next := (next % NUM_SERVERS) + 1; + mailboxes[next] := [message_id |-> next, client_id |-> msg.client_id, path |-> msg.path]; + } + } + + \* AServer is the archetype that defines the behavior of the servers + \* in our system. The two parameters it recieves are: + \* + \* - mailboxes: contains connections to every node in the system + \* - file_system: abstraction of a real file system. In practice, + \* this is implementation specific and irrelevant for + \* the properties we want to check in this specification + archetype AServer(ref mailboxes, file_system) + + \* Local variables + variable + \* temporary buffer to hold incoming messages + msg; + { + serverLoop: + while (TRUE) { + + \* waits for an incoming message. Note that the only process + \* that sends messages to the server is the load balancer process + \* (defined according to the ALoadBalancer archetype) and the + \* message has the type [message_id : Int, client_id : Int] + rcvReq: + msg := mailboxes[self]; + + sendPage: + \* sends a web page (read from `file_system`) back to the requester + \* i.e., the client. + mailboxes[msg.client_id] := file_system[msg.path]; + } + } + + \* Client processes are given integer identifiers starting from NUM_SERVERS+1. + \* Keep in mind that this "range" notation in PlusCal defines a set, and is + \* _inclusive_ (i.e., NUM_SERVERS+NUM_CLIENTS+1 is part of the set). + \* + \* The parameters received by a client are: + \* + \* - mailboxes: contains connections to every node in the system + \* - instream: a stream of inputs to the client + \* - outstream: an output stream, where the client sends the messages it receives + \* from servers. + archetype AClient(ref mailboxes, instream, ref outstream) + + \* Local variables + variable + \* Temporary buffers to hold messages + req, resp; + { + clientLoop: + while (TRUE) { + + \* First, the client makes a request to the load balancer. + \* The format of the message is a tuple: + \* + \* [message_type : Int, client_id : Int, path : Interface{}]. + \* + \* If you check the ALoadBalancer definition, this is the message format + \* expected there. + \* + \* Remember that `self` is an implicitly defined, immutable variable that + \* contains the process identifier of the "running" process. + clientRequest: + req := [message_type |-> GET_PAGE, client_id |-> self, path |-> instream]; + mailboxes[LoadBalancerId] := req; + + \* Clients then wait for the response to the previously sent request. + \* Since there is only one type of web page in this simple specification + \* (defined by the WEB_PAGE constant), we assert here that the message + \* received indeed is equal our expected web page. + clientReceive: + resp := mailboxes[self]; + outstream := resp; + } + } + + \* GLOBAL VARIABLES *\ + + variables + \* our network is modeled as a function from node identifier + \* to a sequence of incoming messages + network = [id \in 0..(NUM_NODES-1) |-> <<>>], + + \* set as input and output "streams" + in = 0, out = 0, + + fs = [f \in {in} |-> WEB_PAGE]; + + \* PROCESS INSTANTIATION *\ + + \* The system has a single load balancer entity, instantiated from the ALoadBalancer + \* archetype. The model of our network is going to be the one defined by the TCPChannel + \* mapping macro in all instantiations. + fair process (LoadBalancer = LoadBalancerId) == instance ALoadBalancer(ref network) + mapping network[_] via TCPChannel; + + \* Instantiate `NUM_SERVERS` server processes according to the AServer archetype. + \* We map the page stream according to the WebPages mapping macro since this is + \* an implementation detail that needs to be specified during implementation at + \* a later stage. + fair process (Servers \in 1..NUM_SERVERS) == instance AServer(ref network, fs) + mapping network[_] via TCPChannel + mapping fs[_] via WebPages; + + fair process (Client \in (NUM_SERVERS+1)..(NUM_SERVERS+NUM_CLIENTS)) == instance AClient(ref network, in, ref out) + mapping network[_] via TCPChannel; +} + +\* BEGIN PLUSCAL TRANSLATION +--algorithm LoadBalancer { + variables network = [id \in (0) .. ((NUM_NODES) - (1)) |-> <<>>], in = 0, out = 0, fs = [f \in {in} |-> WEB_PAGE], mailboxesRead, mailboxesWrite, mailboxesWrite0, mailboxesRead0, mailboxesWrite1, file_systemRead, mailboxesWrite2, instreamRead, mailboxesWrite3, mailboxesRead1, outstreamWrite, mailboxesWrite4, outstreamWrite0; + define { + NUM_NODES == ((NUM_CLIENTS) + (NUM_SERVERS)) + (1) + } + fair process (LoadBalancer = LoadBalancerId) + variables msg, next = 0; + { + main: + if (TRUE) { + rcvMsg: + await (Len(network[LoadBalancerId])) > (0); + with (msg0 = Head(network[LoadBalancerId])) { + mailboxesWrite := [network EXCEPT ![LoadBalancerId] = Tail(network[LoadBalancerId])]; + mailboxesRead := msg0; + }; + msg := mailboxesRead; + assert ((msg).message_type) = (GET_PAGE); + network := mailboxesWrite; + + sendServer: + next := ((next) % (NUM_SERVERS)) + (1); + await (Len(network[next])) < (BUFFER_SIZE); + mailboxesWrite := [network EXCEPT ![next] = Append(network[next], [message_id |-> next, client_id |-> (msg).client_id, path |-> (msg).path])]; + network := mailboxesWrite; + goto main; + + } else { + mailboxesWrite0 := network; + network := mailboxesWrite0; + }; + + } + fair process (Servers \in (1) .. (NUM_SERVERS)) + variables msg; + { + serverLoop: + if (TRUE) { + rcvReq: + await (Len(network[self])) > (0); + with (msg1 = Head(network[self])) { + mailboxesWrite1 := [network EXCEPT ![self] = Tail(network[self])]; + mailboxesRead0 := msg1; + }; + msg := mailboxesRead0; + network := mailboxesWrite1; + + sendPage: + file_systemRead := WEB_PAGE; + await (Len(network[(msg).client_id])) < (BUFFER_SIZE); + mailboxesWrite1 := [network EXCEPT ![(msg).client_id] = Append(network[(msg).client_id], file_systemRead)]; + network := mailboxesWrite1; + goto serverLoop; + + } else { + mailboxesWrite2 := network; + network := mailboxesWrite2; + }; + + } + fair process (Client \in ((NUM_SERVERS) + (1)) .. ((NUM_SERVERS) + (NUM_CLIENTS))) + variables req, resp; + { + clientLoop: + if (TRUE) { + clientRequest: + instreamRead := in; + req := [message_type |-> GET_PAGE, client_id |-> self, path |-> instreamRead]; + await (Len(network[LoadBalancerId])) < (BUFFER_SIZE); + mailboxesWrite3 := [network EXCEPT ![LoadBalancerId] = Append(network[LoadBalancerId], req)]; + network := mailboxesWrite3; + + clientReceive: + await (Len(network[self])) > (0); + with (msg2 = Head(network[self])) { + mailboxesWrite3 := [network EXCEPT ![self] = Tail(network[self])]; + mailboxesRead1 := msg2; + }; + resp := mailboxesRead1; + outstreamWrite := resp; + network := mailboxesWrite3; + out := outstreamWrite; + goto clientLoop; + + } else { + mailboxesWrite4 := network; + outstreamWrite0 := out; + network := mailboxesWrite4; + out := outstreamWrite0; + }; + + } +} +\* END PLUSCAL TRANSLATION + + + +***************************************************************************) +\* BEGIN TRANSLATION PCal-4500c0fe7eed005c96be5ba74dff2461 +\* Process variable msg of process LoadBalancer at line 250 col 15 changed to msg_ +CONSTANT defaultInitValue +VARIABLES network, in, out, fs, mailboxesRead, mailboxesWrite, + mailboxesWrite0, mailboxesRead0, mailboxesWrite1, file_systemRead, + mailboxesWrite2, instreamRead, mailboxesWrite3, mailboxesRead1, + outstreamWrite, mailboxesWrite4, outstreamWrite0, pc + +(* define statement *) +NUM_NODES == ((NUM_CLIENTS) + (NUM_SERVERS)) + (1) + +VARIABLES msg_, next, msg, req, resp + +vars == << network, in, out, fs, mailboxesRead, mailboxesWrite, + mailboxesWrite0, mailboxesRead0, mailboxesWrite1, file_systemRead, + mailboxesWrite2, instreamRead, mailboxesWrite3, mailboxesRead1, + outstreamWrite, mailboxesWrite4, outstreamWrite0, pc, msg_, next, + msg, req, resp >> + +ProcSet == {LoadBalancerId} \cup ((1) .. (NUM_SERVERS)) \cup (((NUM_SERVERS) + (1)) .. ((NUM_SERVERS) + (NUM_CLIENTS))) + +Init == (* Global variables *) + /\ network = [id \in (0) .. ((NUM_NODES) - (1)) |-> <<>>] + /\ in = 0 + /\ out = 0 + /\ fs = [f \in {in} |-> WEB_PAGE] + /\ mailboxesRead = defaultInitValue + /\ mailboxesWrite = defaultInitValue + /\ mailboxesWrite0 = defaultInitValue + /\ mailboxesRead0 = defaultInitValue + /\ mailboxesWrite1 = defaultInitValue + /\ file_systemRead = defaultInitValue + /\ mailboxesWrite2 = defaultInitValue + /\ instreamRead = defaultInitValue + /\ mailboxesWrite3 = defaultInitValue + /\ mailboxesRead1 = defaultInitValue + /\ outstreamWrite = defaultInitValue + /\ mailboxesWrite4 = defaultInitValue + /\ outstreamWrite0 = defaultInitValue + (* Process LoadBalancer *) + /\ msg_ = defaultInitValue + /\ next = 0 + (* Process Servers *) + /\ msg = [self \in (1) .. (NUM_SERVERS) |-> defaultInitValue] + (* Process Client *) + /\ req = [self \in ((NUM_SERVERS) + (1)) .. ((NUM_SERVERS) + (NUM_CLIENTS)) |-> defaultInitValue] + /\ resp = [self \in ((NUM_SERVERS) + (1)) .. ((NUM_SERVERS) + (NUM_CLIENTS)) |-> defaultInitValue] + /\ pc = [self \in ProcSet |-> CASE self = LoadBalancerId -> "main" + [] self \in (1) .. (NUM_SERVERS) -> "serverLoop" + [] self \in ((NUM_SERVERS) + (1)) .. ((NUM_SERVERS) + (NUM_CLIENTS)) -> "clientLoop"] + +main == /\ pc[LoadBalancerId] = "main" + /\ IF TRUE + THEN /\ pc' = [pc EXCEPT ![LoadBalancerId] = "rcvMsg"] + /\ UNCHANGED << network, mailboxesWrite0 >> + ELSE /\ mailboxesWrite0' = network + /\ network' = mailboxesWrite0' + /\ pc' = [pc EXCEPT ![LoadBalancerId] = "Done"] + /\ UNCHANGED << in, out, fs, mailboxesRead, mailboxesWrite, + mailboxesRead0, mailboxesWrite1, file_systemRead, + mailboxesWrite2, instreamRead, mailboxesWrite3, + mailboxesRead1, outstreamWrite, mailboxesWrite4, + outstreamWrite0, msg_, next, msg, req, resp >> + +rcvMsg == /\ pc[LoadBalancerId] = "rcvMsg" + /\ (Len(network[LoadBalancerId])) > (0) + /\ LET msg0 == Head(network[LoadBalancerId]) IN + /\ mailboxesWrite' = [network EXCEPT ![LoadBalancerId] = Tail(network[LoadBalancerId])] + /\ mailboxesRead' = msg0 + /\ msg_' = mailboxesRead' + /\ Assert(((msg_').message_type) = (GET_PAGE), + "Failure of assertion at line 261, column 21.") + /\ network' = mailboxesWrite' + /\ pc' = [pc EXCEPT ![LoadBalancerId] = "sendServer"] + /\ UNCHANGED << in, out, fs, mailboxesWrite0, mailboxesRead0, + mailboxesWrite1, file_systemRead, mailboxesWrite2, + instreamRead, mailboxesWrite3, mailboxesRead1, + outstreamWrite, mailboxesWrite4, outstreamWrite0, + next, msg, req, resp >> + +sendServer == /\ pc[LoadBalancerId] = "sendServer" + /\ next' = ((next) % (NUM_SERVERS)) + (1) + /\ (Len(network[next'])) < (BUFFER_SIZE) + /\ mailboxesWrite' = [network EXCEPT ![next'] = Append(network[next'], [message_id |-> next', client_id |-> (msg_).client_id, path |-> (msg_).path])] + /\ network' = mailboxesWrite' + /\ pc' = [pc EXCEPT ![LoadBalancerId] = "main"] + /\ UNCHANGED << in, out, fs, mailboxesRead, mailboxesWrite0, + mailboxesRead0, mailboxesWrite1, file_systemRead, + mailboxesWrite2, instreamRead, mailboxesWrite3, + mailboxesRead1, outstreamWrite, mailboxesWrite4, + outstreamWrite0, msg_, msg, req, resp >> + +LoadBalancer == main \/ rcvMsg \/ sendServer + +serverLoop(self) == /\ pc[self] = "serverLoop" + /\ IF TRUE + THEN /\ pc' = [pc EXCEPT ![self] = "rcvReq"] + /\ UNCHANGED << network, mailboxesWrite2 >> + ELSE /\ mailboxesWrite2' = network + /\ network' = mailboxesWrite2' + /\ pc' = [pc EXCEPT ![self] = "Done"] + /\ UNCHANGED << in, out, fs, mailboxesRead, mailboxesWrite, + mailboxesWrite0, mailboxesRead0, + mailboxesWrite1, file_systemRead, + instreamRead, mailboxesWrite3, + mailboxesRead1, outstreamWrite, + mailboxesWrite4, outstreamWrite0, msg_, + next, msg, req, resp >> + +rcvReq(self) == /\ pc[self] = "rcvReq" + /\ (Len(network[self])) > (0) + /\ LET msg1 == Head(network[self]) IN + /\ mailboxesWrite1' = [network EXCEPT ![self] = Tail(network[self])] + /\ mailboxesRead0' = msg1 + /\ msg' = [msg EXCEPT ![self] = mailboxesRead0'] + /\ network' = mailboxesWrite1' + /\ pc' = [pc EXCEPT ![self] = "sendPage"] + /\ UNCHANGED << in, out, fs, mailboxesRead, mailboxesWrite, + mailboxesWrite0, file_systemRead, + mailboxesWrite2, instreamRead, mailboxesWrite3, + mailboxesRead1, outstreamWrite, + mailboxesWrite4, outstreamWrite0, msg_, next, + req, resp >> + +sendPage(self) == /\ pc[self] = "sendPage" + /\ file_systemRead' = WEB_PAGE + /\ (Len(network[(msg[self]).client_id])) < (BUFFER_SIZE) + /\ mailboxesWrite1' = [network EXCEPT ![(msg[self]).client_id] = Append(network[(msg[self]).client_id], file_systemRead')] + /\ network' = mailboxesWrite1' + /\ pc' = [pc EXCEPT ![self] = "serverLoop"] + /\ UNCHANGED << in, out, fs, mailboxesRead, mailboxesWrite, + mailboxesWrite0, mailboxesRead0, + mailboxesWrite2, instreamRead, + mailboxesWrite3, mailboxesRead1, + outstreamWrite, mailboxesWrite4, + outstreamWrite0, msg_, next, msg, req, resp >> + +Servers(self) == serverLoop(self) \/ rcvReq(self) \/ sendPage(self) + +clientLoop(self) == /\ pc[self] = "clientLoop" + /\ IF TRUE + THEN /\ pc' = [pc EXCEPT ![self] = "clientRequest"] + /\ UNCHANGED << network, out, mailboxesWrite4, + outstreamWrite0 >> + ELSE /\ mailboxesWrite4' = network + /\ outstreamWrite0' = out + /\ network' = mailboxesWrite4' + /\ out' = outstreamWrite0' + /\ pc' = [pc EXCEPT ![self] = "Done"] + /\ UNCHANGED << in, fs, mailboxesRead, mailboxesWrite, + mailboxesWrite0, mailboxesRead0, + mailboxesWrite1, file_systemRead, + mailboxesWrite2, instreamRead, + mailboxesWrite3, mailboxesRead1, + outstreamWrite, msg_, next, msg, req, resp >> + +clientRequest(self) == /\ pc[self] = "clientRequest" + /\ instreamRead' = in + /\ req' = [req EXCEPT ![self] = [message_type |-> GET_PAGE, client_id |-> self, path |-> instreamRead']] + /\ (Len(network[LoadBalancerId])) < (BUFFER_SIZE) + /\ mailboxesWrite3' = [network EXCEPT ![LoadBalancerId] = Append(network[LoadBalancerId], req'[self])] + /\ network' = mailboxesWrite3' + /\ pc' = [pc EXCEPT ![self] = "clientReceive"] + /\ UNCHANGED << in, out, fs, mailboxesRead, + mailboxesWrite, mailboxesWrite0, + mailboxesRead0, mailboxesWrite1, + file_systemRead, mailboxesWrite2, + mailboxesRead1, outstreamWrite, + mailboxesWrite4, outstreamWrite0, msg_, + next, msg, resp >> + +clientReceive(self) == /\ pc[self] = "clientReceive" + /\ (Len(network[self])) > (0) + /\ LET msg2 == Head(network[self]) IN + /\ mailboxesWrite3' = [network EXCEPT ![self] = Tail(network[self])] + /\ mailboxesRead1' = msg2 + /\ resp' = [resp EXCEPT ![self] = mailboxesRead1'] + /\ outstreamWrite' = resp'[self] + /\ network' = mailboxesWrite3' + /\ out' = outstreamWrite' + /\ pc' = [pc EXCEPT ![self] = "clientLoop"] + /\ UNCHANGED << in, fs, mailboxesRead, mailboxesWrite, + mailboxesWrite0, mailboxesRead0, + mailboxesWrite1, file_systemRead, + mailboxesWrite2, instreamRead, + mailboxesWrite4, outstreamWrite0, msg_, + next, msg, req >> + +Client(self) == clientLoop(self) \/ clientRequest(self) + \/ clientReceive(self) + +(* Allow infinite stuttering to prevent deadlock on termination. *) +Terminating == /\ \A self \in ProcSet: pc[self] = "Done" + /\ UNCHANGED vars + +Next == LoadBalancer + \/ (\E self \in (1) .. (NUM_SERVERS): Servers(self)) + \/ (\E self \in ((NUM_SERVERS) + (1)) .. ((NUM_SERVERS) + (NUM_CLIENTS)): Client(self)) + \/ Terminating + +Spec == /\ Init /\ [][Next]_vars + /\ WF_vars(LoadBalancer) + /\ \A self \in (1) .. (NUM_SERVERS) : WF_vars(Servers(self)) + /\ \A self \in ((NUM_SERVERS) + (1)) .. ((NUM_SERVERS) + (NUM_CLIENTS)) : WF_vars(Client(self)) + +Termination == <>(\A self \in ProcSet: pc[self] = "Done") + +\* END TRANSLATION TLA-91fe3e564ee1f74fb78055868c4540bc + + +(* INVARIANTS *) + + +\* This is an _invariant_ of our specification: in other words, +\* we expect the BuffersOk predicate to always be true in every step of execution +BufferOk(node) == Len(network[node]) >= 0 /\ Len(network[node]) <= BUFFER_SIZE +BuffersOk == \A node \in DOMAIN network : BufferOk(node) + + +(* PROPERTIES *) + +\* This is a property we would like to check about our specification. +\* Properties are defined using _temporal logic_. In this specific example, +\* we want to make sure that every client that requests a web page (i.e., are +\* in the 'clientRequest' label) eventually receive a response (i.e., are +\* in the 'clientReceive' label). In order to specify this property, we have to +\* write the formula as if the client enters 'clientReceive' label, it will +\* eventually successfully receive a response and then go back to issuing +\* another request in the 'clientRequest' label. +ReceivesPage(client) == pc[client] = "clientReceive" ~> pc[client] = "clientRequest" +ClientsOk == \A client \in (NUM_SERVERS+1)..(NUM_SERVERS+NUM_CLIENTS) : ReceivesPage(client) + +============================================================================= +\* Modification History +\* Last modified Mon Dec 21 03:17:07 PST 2020 by finn +\* Last modified Sun Mar 31 21:53:44 PDT 2019 by minh +\* Last modified Wed Feb 27 14:42:14 PST 2019 by rmc diff --git a/test/files/pcalgen/replicated_kv.tla b/test/files/pcalgen/replicated_kv.tla new file mode 100644 index 000000000..d8301990d --- /dev/null +++ b/test/files/pcalgen/replicated_kv.tla @@ -0,0 +1,3216 @@ +----------------------------- MODULE replicated_kv ----------------------------- +(***************************************************************************************) +(* Specifies a simple replicated Key-Value store in MPCal. *) +(* *) +(* Specifies a replicated state machines (RSM) approach as described in: *) +(* *) +(* Implementing fault-tolerant services using the state machine approach: a tutorial. *) +(* http://dl.acm.org/citation.cfm?id=98167 *) +(***************************************************************************************) + +\* Use some built-in TLA+ modules +EXTENDS Integers, Sequences, FiniteSets, TLC + +\* Constant Definitions +\* -------------------- + +\* Defines the size of the network buffer in a FIFOChannel (the mapping macro). +\* +\* TLC will explore states with up to `BUFFER_SIZE` messages being held on the buffer. +\* If the communication buffer is full, a process that attempts to send a message will not +\* run until a message on the other end of the channel is received. +CONSTANT BUFFER_SIZE + +\* Defines the number of key-value store replicas and clients in the system. The specification +\* is orthogonal to these numbers. Note, however, that increasing the number of replicas and/or +\* clients exponentially increases the state space that TLC needs to explore in order to model +\* check your specification. +CONSTANTS NUM_REPLICAS, NUM_CLIENTS + +\* When a client sends a message to a replica, the client needs to be able to identify +\* what type of message it just received. These constants below are such labels. Make sure +\* to give them distinct concrete values when model checking. +CONSTANTS DISCONNECT_MSG, GET_MSG, PUT_MSG, NULL_MSG + +\* labels that identify a payload corresponds to the response of a previously issues Get +\* or Put request. +CONSTANTS GET_RESPONSE, PUT_RESPONSE + +\* an arbitrary `NULL` value. We model the underlying key-value store as a function from +\* a certain key-space (function domain) to this `NULL` element. When a client issues a `PUT` +\* request, the database is updated and the key being set no longer maps to `NULL`. +CONSTANT NULL + +\* Defines which keys are used by clients when performing Get and Put operations +\* Since we are interested to test properties like message stability detection +\* and the semantics of the database, we keep these constant throughout model checking. +CONSTANT GET_KEY, PUT_KEY + +\* Whenever clients issue PUT requests, they set keys to the value declared in this constant. +CONSTANT PUT_VALUE + +\* Defines the set of keys a client may set. In this specification, we restrict +\* it to them to GET_KEY and PUT_KEY +KeySpace == { GET_KEY, PUT_KEY } + +\* These constants allow PlusCal processes to derive their client identifiers from +\* their PlusCal identifiers. +GET_ORDER == 0 +PUT_ORDER == 1 +DISCONNECT_ORDER == 2 +NULL_ORDER == 3 + +\* We have clients that perform each of the operations supported by our Replicated KV-store: +\* Get, Put, Disconnect, and ClockUpdate (or 'null' request). PlusCal requires that every process +\* has a unique identifier. The set definitions below just ensure that our clients have +\* consecutive identifiers. +GetSet == (NUM_REPLICAS)..(NUM_REPLICAS+NUM_CLIENTS-1) +PutSet == (NUM_REPLICAS+NUM_CLIENTS)..(NUM_REPLICAS + 2*NUM_CLIENTS - 1) +DisconnectSet == (NUM_REPLICAS+2*NUM_CLIENTS)..(NUM_REPLICAS+3*NUM_CLIENTS-1) +NullSet == (NUM_REPLICAS+3*NUM_CLIENTS)..(NUM_REPLICAS+4*NUM_CLIENTS-1) + +(*************************************************************************** +--mpcal ReplicatedKV { + define { + \* Define NUM_NODES to be the total number of nodes in the system, i.e., the number of + \* clients plus the number of replicas + NUM_NODES == NUM_REPLICAS + NUM_CLIENTS + + \* Each replica and each client in the system need an identifier. By default, replicas + \* are identified from 1 to NUM_REPLICAS, and the clients are identified from NUM_REPLICAS+1 + \* to NUM_NODES. It is important that identifiers are unique, consecutive and non-overlapping, + \* due to the way we are modeling our network in this specification. + ReplicaSet == 0..(NUM_REPLICAS-1) + ClientSet == NUM_REPLICAS..(NUM_NODES-1) + } + + \* Broadcasts a certain `msg` to `nodes` with identifiers ranging from + \* `domainStart` to `domainEnd`. + \* + \* Only returns once every message has been sent (i.e., it may "block" if + \* the buffer of one of the receivers is full). + macro Broadcast(nodes, i, until, msg, clock) { + while (i <= until /\ clock # -1) { + nodes[i] := msg; + i := i + 1; + } + } + + \* Models a FIFO channel. Messages are always delivered. Every process + \* can have up to `BUFFER_SIZE` messages in its buffer before being + \* processed. + mapping macro FIFOChannel { + read { + await Len($variable) > 0; + with (msg = Head($variable)) { + $variable := Tail($variable); + yield msg; + }; + } + + write { + await Len($variable) < BUFFER_SIZE; + yield Append($variable, $value); + } + } + + \* The following mapping macros make sure that archetypes that + \* perform client functions read the correct client identifier with + \* respect to their PlusCal process identifier (`self`). + + mapping macro GetClientId { + read { yield self - (NUM_CLIENTS * GET_ORDER); } + write { assert(FALSE); yield $value; } + } + + mapping macro PutClientId { + read { yield self - (NUM_CLIENTS * PUT_ORDER); } + write { assert(FALSE); yield $value; } + } + + mapping macro DisconnectClientId { + read { yield self - (NUM_CLIENTS * DISCONNECT_ORDER); } + write { assert(FALSE); yield $value; } + } + + mapping macro NullClientId { + read { yield self - (NUM_CLIENTS * NULL_ORDER); } + write { assert(FALSE); yield $value; } + } + + \* Mapping via identity is sometimes necessary in order to inform + \* the compiler that a certain resource is to be function mapped, but + \* no meaningful manipulation on reads and writes is necessary. + mapping macro Identity { + read { yield $variable; } + write { yield $value; } + } + + \* This archetype defines the behavior of the replica servers in the system. + \* Its parameters are: + \* + \* - clients: connections to all clients in the system; it needs to wait + \* for client requests in order to perform operations. + \* - replicas: connections to replicas. Since replicas do not talk to each + \* other, this parameter is only used in order to listen to + \* incoming messages. + \* - kv: the underlying "database". When 'put' requests become stable, this + \* database is updated to include the value being set by the client. + archetype AReplica(ref clients, replicas, ref kv) + + \* Local state in a replica: + variables + \* Each replica knows which clients are live (i.e., haven't disconnected) + \* Initially, all clients are live. + liveClients = ClientSet, + + \* Replicas remember which requests are pending (i.e., have not been + \* replied yet). This variable maps client identifiers to a sequence + \* of pending requests + pendingRequests = [c \in liveClients |-> <<>>], + + \* Temporary variables: holds messages that are stable + stableMessages = <<>>, + + \* incremented during in loops + i, + + \* temporary variable: holds the first pending message from + \* a client. The first pending message has the lowest logical + \* clock in the sequence (logical clocks are monotonically increasing) + firstPending, + + \* temporary variables used while finding the set of stable + \* messages. + timestamp, + nextClient, + lowestPending, + chooseMessage, + + \* the replica needs to know the logical clocks of the last + \* message received by each client in order to determine + \* request stability. + currentClocks = [c \in liveClients |-> 0]; + + \* determines the lowest logical clock value seen from all + \* clients. Any pending messages with timestamp lower than this + \* can be considered stable. + minClock, + + \* controls while loop execution. See the 'findStableRequestsLoop' + \* step for more information + continue, + + \* temporary variable: live clients that have pending + \* messages (stable or not) + pendingClients, + + \* Used when iterating over sets of clients + clientsIter, + + \* used to hold messages sent/received by the replica + msg, + + \* put requests were successful + ok, + + \* holds keys/values to be read from/written to the database + key, + val; { + + \* Main replica loop. In each iteration of the loop, the replica: + \* + \* 1. Waits for incoming messages from clients; + \* 2. Finds stable messages; + \* 3. Replies to all stable messages. + replicaLoop: + while (TRUE) { + + stableMessages := <<>>; + continue := TRUE; + + \* Waits for an incoming message from any client. This statement will + \* "block" the replica until a message is read into 'msg'. + \* See definition of client archetypes for the format of the messages. + receiveClientRequest: + msg := replicas[self]; + + \* if the message received is a disconnection from a client, + \* remove the client from the set of live clients + clientDisconnected: + if (msg.op = DISCONNECT_MSG) { + liveClients := liveClients \ {msg.client}; + }; + + \* if the message is a Get request: + replicaGetRequest: + if (msg.op = GET_MSG) { + \* safety assertion: a client requesting for a key must be live + assert(msg.client \in liveClients); + + \* update our records of the current logical clock of the + \* requesting client. + currentClocks[msg.client] := msg.timestamp; + + \* make this a pending message (to be dealt with later, during + \* stability check) + pendingRequests[msg.client] := Append(pendingRequests[msg.client], msg); + }; + + \* if the message is a Put request: similar to Get request. + replicaPutRequest: + if (msg.op = PUT_MSG) { + currentClocks[msg.client] := msg.timestamp; + pendingRequests[msg.client] := Append(pendingRequests[msg.client], msg); + }; + + \* if the message is a clock update from a client, inspect the logical clock + \* to check if it's lower than that of any other message seen before. + replicaNullRequest: + if (msg.op = NULL_MSG) { + currentClocks[msg.client] := msg.timestamp; + }; + + \* Message stability + \* ----------------- + \* + \* The replica needs to detect when messages become stable, and then respond to + \* those messages. Finding out which messages are stable and totally ordering them + \* is crucial for the correctness of the algorithm. If message stability does not work + \* correctly in the replicas, the database may get inconsistent across replicas + \* (if operations are applied in a different order), or clients may get "stuck" + \* (if stable messages are not replied). + + + \* This is the main loop that finds which of the pending requests (if any) are stable + findStableRequestsLoop: + while (continue) { + + \* only consider clients that have messages pending + pendingClients := {c \in liveClients : Len(pendingRequests[c]) > 0}; + + \* if two messages have the same logical clock, total ordering is enforced + \* based on the client identifier: requests from smaller client identifiers + \* are applied first + nextClient := NUM_NODES + 1; + + clientsIter := liveClients; + i := 0; + minClock := 0; + + \* in order to find the set of stable messages, we need to determine + \* the lowest logical clock among our set of live clients. Then, every + \* pending message with a timestamp greater than 'minClock' can be + \* considered stable. + findMinClock: + while (i < Cardinality(clientsIter)) { + with (client \in clientsIter) { + if (minClock = 0 \/ currentClocks[client] < minClock) { + minClock := currentClocks[client]; + }; + + clientsIter := clientsIter \ {client}; + } + }; + + \* this variable holds the timestamp of the request with the lowest clock + \* value that is pending and stable + lowestPending := minClock + 1; + + i := 0; + + \* find the next stable message to be processed + findMinClient: + while (i < Cardinality(pendingClients)) { + with (client \in pendingClients) { + + \* for each client with pending requests: + \* - inspect the first pending message (by definition, the message with + \* lowest clock from that client) + \* - extract the timestamp from the message + \* - record the client and timestamp in case this is the "oldest" message + + firstPending := Head(pendingRequests[client]); + assert(firstPending.op = GET_MSG \/ firstPending.op = PUT_MSG); + timestamp := firstPending.timestamp; + + \* a message is only stable if its timestamp is lower than + \* minClock + if (timestamp < minClock) { + + \* this is the next stable message if it has the lowest + \* timestamp seen so far; if the timestamp is the same as + \* the lowest seen so far, do a client-id comparison + chooseMessage := (timestamp < lowestPending) \/ ((timestamp = lowestPending) /\ (client < nextClient)); + if (chooseMessage) { + nextClient := client; + lowestPending := timestamp; + } + }; + + pendingClients := pendingClients \ {client}; + } + }; + + \* add the next stable message to the 'stableMessages' sequence. + \* if 'lowestPending' is >= 'minClock', it means no more stable messages + \* are pending, and we can leave this loop. + addStableMessage: + if (lowestPending < minClock) { + msg := Head(pendingRequests[nextClient]); + pendingRequests[nextClient] := Tail(pendingRequests[nextClient]); + + stableMessages := Append(stableMessages, msg); + } else { + continue := FALSE; + } + }; + + i := 1; + + \* iterate over our sequence of 'stableMessages' built in the previous + \* step, responding to each of them in order. + respondPendingRequestsLoop: + while (i <= Len(stableMessages)) { + msg := stableMessages[i]; + i := i + 1; + + respondStableGet: + if (msg.op = GET_MSG) { + key := msg.key; + val := kv[key]; + + \* send the value read from the database back to the client + clients[msg.reply_to] := [type |-> GET_RESPONSE, result |-> val]; + }; + + respondStablePut: + if (msg.op = PUT_MSG) { + key := msg.key; + val := msg.value; + + \* update our database and send an OK back to the client + kv[key] := val; + + clients[msg.reply_to] := [type |-> PUT_RESPONSE, result |-> ok]; + }; + } + } + } + + \* Client Definitions + \* ------------------ + \* + \* The following archetypes define the client functions as specified in A1. + \* Note that these operations are the "logical" versions of the API: for example, + \* a Put archetype here sends a "Put" message to all replicas. + \* + \* In all of the definitions below, note that 'clocks' represent the client's + \* logical clock. However, upon disconnection, the clock is set to '-1', and + \* clients know to terminate when that happens. + + + \* Specifies a Get request from a client. Arguments: + \* + \* - clientId: client identifier, used by the replica to identify which client is + \* performing the operation + \* - replicas: connections to replica servers + \* - clients: connections to clients. Used only to listen for incoming messages + \* from replicas (i.e., to send the value of the key being read). + \* - key: the key being read. This *must* belong to the KeySpace set. + \* - clock: The initial logical clock + \* + \* A Get message sent to the replica is a record in the following format: + \* + \* [op: GET_MSG, key: key, client: client_id, timestamp: lamport_clock] + archetype Get(clientId, ref replicas, clients, key, ref clock, spin, ref outside) + variable continue = TRUE, getReq, getResp; + { + \* Loop until disconnected + getLoop: + while (continue) { + getRequest: + \* if disconnected, return + if (clock[clientId] = -1) { + continue := FALSE + } else { + \* increment the logical clock, and construct a valid + \* Get message. + clock[clientId] := clock[clientId] + 1; + getReq := [op |-> GET_MSG, key |-> key, client |-> clientId, timestamp |-> clock[clientId], reply_to |-> self]; + + \* Choose some replica from the set of replicas to send this + \* request to + with (dst \in ReplicaSet) { + replicas[dst] := getReq; + }; + + getReply: + if (clock[clientId] = -1) { + \* Client disconnected -- terminate + continue := FALSE; + } else { + \* Waits for the response from the replica + getResp := clients[self]; + assert(getResp.type = GET_RESPONSE); + outside := getResp.result; + } + }; + + getCheckSpin: + if (~spin) { + continue := FALSE; + } + } + } + + \* Specifies a Put request from a client. Arguments: + \* + \* - clientId: client identifier, used by the replica to identify which client is + \* performing the operation + \* - replicas: connection to the replicas. + \* - clients: connection to the clients. Used to read incoming messages (response + \* from the Put request + \* - key: the key being set. + \* - value: the value being written to the key + \* - clock: Lamport clocks + \* + \* A Put message sent to the replica is a record in the following format: + \* + \* [op: PUT_MSG, key: key, value: value, client: client_id, timestamp: lamport_clock] + archetype Put(clientId, ref replicas, clients, key, value, ref clock, spin, ref outside) + variables continue = TRUE, i, j, putReq, putResp; + { + \* Loops indefinitely until disconnected + putLoop: + while (continue) { + putRequest: + \* if disconnected, return + if (clock[clientId] = -1) { + continue := FALSE; + } else { + \* increment the logical clock, construct the payload to be sent + \* to the replica, and set 'locked' to TRUE + clock[clientId] := clock[clientId] + 1; + putReq := [op |-> PUT_MSG, key |-> key, value |-> value, client |-> clientId, timestamp |-> clock[clientId], reply_to |-> self]; + i := 0; + j := 0; + + \* Put requests must be broadcast to all replicas + putBroadcast: + Broadcast(replicas, j, NUM_REPLICAS-1, putReq, clock[clientId]); + + \* wait for a response from all replicas, and allow other + \* calls to the replica to happen after that. + putResponse: + while (i < Cardinality(ReplicaSet)) { + if (clock[clientId] = -1) { + continue := FALSE; + goto putLoop; + } else { + putResp := clients[self]; + assert(putResp.type = PUT_RESPONSE); + + i := i + 1; + } + }; + + putComplete: + outside := PUT_RESPONSE; + }; + + putCheckSpin: + if (~spin) { + continue := FALSE; + } + } + } + + \* Specifies a Disconnect message from the client. + \* + \* A Disconnect message sent to the replica is a record in the following format: + \* + \* [op: DISCONNECT_MSG, client: client_id] + archetype Disconnect(clientId, ref replicas, ref clock) + variables msg, j; + { + sendDisconnectRequest: + msg := [op |-> DISCONNECT_MSG, client |-> clientId]; + + \* setting the logical clock internally to -1 indicates that this client + \* has disconnected. Other operations terminate accordingly. + clock[clientId] := -1; + j := 0; + + \* Disconnection messages need to be broadcast to all replicas. + \* "Clock" is set to zero because the replica is disconnected but we + \* *do* want to broadcast that message + disconnectBroadcast: + Broadcast(replicas, j, NUM_REPLICAS-1, msg, 0); + } + + \* Specifies a ClockUpdate ('null') message from the client. + \* If the client has disconnected, no more clock updates are sent. + \* + \* A ClockUpdate message sent to the replica is a record in the following format: + \* + \* [op: NULL_MSG, client: client_id, timestamp: logical_clock] + archetype ClockUpdate(clientId, ref replicas, ref clock, spin) + variables continue = TRUE, j, msg; + { + clockUpdateLoop: + while (continue) { + \* if we have disconnected, return + if (clock[clientId] = -1) { + continue := FALSE; + } else { + \* tick the lock and construct the message accordingly + clock[clientId] := clock[clientId] + 1; + msg := [op |-> NULL_MSG, client |-> clientId, timestamp |-> clock[clientId]]; + j := 0; + + nullBroadcast: + \* clock update messages must be broadcast to all replicas. + Broadcast(replicas, j, NUM_REPLICAS-1, msg, clock[clientId]); + }; + + nullCheckSpin: + if (~spin) { + continue := FALSE; + } + } + } + + \* Global Variables + \* ---------------- + + variables + \* queue of incoming messages for each of the replicas + replicasNetwork = [id \in ReplicaSet |-> <<>>], + + \* all clients performing operations in this model + allClients = GetSet \cup PutSet \cup DisconnectSet \cup NullSet, + + \* queue of incoming messages for each of the clients + clientMailboxes = [id \in allClients |-> <<>>], + + \* client identifier: to be appropriately mapped + cid = 0, + + \* communication channel with the caller; astracted + \* in this specification + out = 0, + + \* all clocks set to 0 initially + clocks = [c \in ClientSet |-> 0]; + + + \* Process Instantiations + \* ---------------------- + \* + \* This is where the archetypes defined above are instantiated into actual PlusCal + \* processes. We instantiate NUM_REPLICAS replica servers and NUM_CLIENTS client + \* processes for each possible client operation. TLC will be responsible for + \* exploring the different orderings in which these clients and replicas + \* may interact. + + + \* Instantiate replica servers. The network model used is the one defined in + \* the FIFOChannel mapping macro. + fair process (Replica \in ReplicaSet) == instance AReplica(ref clientMailboxes, replicasNetwork, [k \in KeySpace |-> NULL]) + mapping @1[_] via FIFOChannel + mapping @2[_] via FIFOChannel + mapping @3[_] via Identity; + + \* Instantiate clients: + + fair process (GetClient \in GetSet) == instance Get(cid, ref replicasNetwork, clientMailboxes, GET_KEY, ref clocks, TRUE, ref out) + mapping cid via GetClientId + mapping replicasNetwork[_] via FIFOChannel + mapping clientMailboxes[_] via FIFOChannel + mapping clocks[_] via Identity; + + fair process (PutClient \in PutSet) == instance Put(cid, ref replicasNetwork, clientMailboxes, PUT_KEY, PUT_VALUE, ref clocks, TRUE, ref out) + mapping cid via PutClientId + mapping replicasNetwork[_] via FIFOChannel + mapping clientMailboxes[_] via FIFOChannel + mapping clocks[_] via Identity; + + fair process (DisconnectClient \in DisconnectSet) == instance Disconnect(cid, ref replicasNetwork, ref clocks) + mapping cid via DisconnectClientId + mapping replicasNetwork[_] via FIFOChannel + mapping clocks[_] via Identity; + + fair process (ClockUpdateClient \in NullSet) == instance ClockUpdate(cid, ref replicasNetwork, ref clocks, TRUE) + mapping cid via NullClientId + mapping replicasNetwork[_] via FIFOChannel + mapping clocks[_] via Identity; +} + +\* BEGIN PLUSCAL TRANSLATION +--algorithm ReplicatedKV { + variables replicasNetwork = [id \in ReplicaSet |-> <<>>], allClients = (((GetSet) \cup (PutSet)) \cup (DisconnectSet)) \cup (NullSet), clientMailboxes = [id \in allClients |-> <<>>], cid = 0, out = 0, clocks = [c \in ClientSet |-> 0], replicasRead, replicasWrite, kvRead, clientsWrite, clientsWrite0, kvWrite, kvWrite0, clientsWrite1, clientsWrite2, kvWrite1, replicasWrite0, clientsWrite3, kvWrite2, clientIdRead, clockRead, clientIdRead0, clockRead0, clientIdRead1, clockWrite, keyRead, clientIdRead2, clientIdRead3, clockRead1, replicasWrite1, clientsRead, clientsWrite4, outsideWrite, clientsWrite5, outsideWrite0, clockWrite0, replicasWrite2, clientsWrite6, outsideWrite1, spinRead, clockWrite1, replicasWrite3, clientsWrite7, outsideWrite2, clientIdRead4, clockRead2, clientIdRead5, clockRead3, clientIdRead6, clockWrite2, keyRead0, valueRead, clientIdRead7, clientIdRead8, clockRead4, replicasWrite4, replicasWrite5, clientsRead0, clientsWrite8, clientsWrite9, clientsWrite10, outsideWrite3, clockWrite3, replicasWrite6, clientsWrite11, outsideWrite4, spinRead0, clockWrite4, replicasWrite7, clientsWrite12, outsideWrite5, clientIdRead9, clientIdRead10, clockWrite5, replicasWrite8, replicasWrite9, clientIdRead11, clockRead5, clientIdRead12, clockRead6, clientIdRead13, clockWrite6, clientIdRead14, clientIdRead15, clockRead7, replicasWrite10, replicasWrite11, clockWrite7, replicasWrite12, spinRead1, clockWrite8, replicasWrite13; + define { + NUM_NODES == (NUM_REPLICAS) + (NUM_CLIENTS) + ReplicaSet == (0) .. ((NUM_REPLICAS) - (1)) + ClientSet == (NUM_REPLICAS) .. ((NUM_NODES) - (1)) + } + fair process (Replica \in ReplicaSet) + variables kvLocal = [k \in KeySpace |-> NULL], liveClients = ClientSet, pendingRequests = [c \in liveClients |-> <<>>], stableMessages = <<>>, i, firstPending, timestamp, nextClient, lowestPending, chooseMessage, currentClocks = [c \in liveClients |-> 0], minClock, continue, pendingClients, clientsIter, msg, ok, key, val; + { + replicaLoop: + if (TRUE) { + stableMessages := <<>>; + continue := TRUE; + receiveClientRequest: + await (Len(replicasNetwork[self])) > (0); + with (msg0 = Head(replicasNetwork[self])) { + replicasWrite := [replicasNetwork EXCEPT ![self] = Tail(replicasNetwork[self])]; + replicasRead := msg0; + }; + msg := replicasRead; + replicasNetwork := replicasWrite; + + clientDisconnected: + if (((msg).op) = (DISCONNECT_MSG)) { + liveClients := (liveClients) \ ({(msg).client}); + }; + + replicaGetRequest: + if (((msg).op) = (GET_MSG)) { + assert ((msg).client) \in (liveClients); + currentClocks[msg.client] := (msg).timestamp; + pendingRequests[msg.client] := Append(pendingRequests[(msg).client], msg); + }; + + replicaPutRequest: + if (((msg).op) = (PUT_MSG)) { + currentClocks[msg.client] := (msg).timestamp; + pendingRequests[msg.client] := Append(pendingRequests[(msg).client], msg); + }; + + replicaNullRequest: + if (((msg).op) = (NULL_MSG)) { + currentClocks[msg.client] := (msg).timestamp; + }; + + findStableRequestsLoop: + if (continue) { + pendingClients := {c \in liveClients : (Len(pendingRequests[c])) > (0)}; + nextClient := (NUM_NODES) + (1); + clientsIter := liveClients; + i := 0; + minClock := 0; + findMinClock: + if ((i) < (Cardinality(clientsIter))) { + with (client \in clientsIter) { + if (((minClock) = (0)) \/ ((currentClocks[client]) < (minClock))) { + minClock := currentClocks[client]; + }; + clientsIter := (clientsIter) \ ({client}); + }; + goto findMinClock; + } else { + lowestPending := (minClock) + (1); + i := 0; + }; + + findMinClient: + if ((i) < (Cardinality(pendingClients))) { + with (client \in pendingClients) { + firstPending := Head(pendingRequests[client]); + assert (((firstPending).op) = (GET_MSG)) \/ (((firstPending).op) = (PUT_MSG)); + timestamp := (firstPending).timestamp; + if ((timestamp) < (minClock)) { + chooseMessage := ((timestamp) < (lowestPending)) \/ (((timestamp) = (lowestPending)) /\ ((client) < (nextClient))); + if (chooseMessage) { + nextClient := client; + lowestPending := timestamp; + }; + }; + pendingClients := (pendingClients) \ ({client}); + }; + goto findMinClient; + }; + + addStableMessage: + if ((lowestPending) < (minClock)) { + msg := Head(pendingRequests[nextClient]); + pendingRequests[nextClient] := Tail(pendingRequests[nextClient]); + stableMessages := Append(stableMessages, msg); + goto findStableRequestsLoop; + } else { + continue := FALSE; + goto findStableRequestsLoop; + }; + + } else { + i := 1; + }; + + respondPendingRequestsLoop: + if ((i) <= (Len(stableMessages))) { + msg := stableMessages[i]; + i := (i) + (1); + respondStableGet: + if (((msg).op) = (GET_MSG)) { + key := (msg).key; + kvRead := kvLocal[key]; + val := kvRead; + await (Len(clientMailboxes[(msg).reply_to])) < (BUFFER_SIZE); + clientsWrite := [clientMailboxes EXCEPT ![(msg).reply_to] = Append(clientMailboxes[(msg).reply_to], [type |-> GET_RESPONSE, result |-> val])]; + clientsWrite0 := clientsWrite; + clientMailboxes := clientsWrite0; + } else { + clientsWrite0 := clientMailboxes; + clientMailboxes := clientsWrite0; + }; + + respondStablePut: + if (((msg).op) = (PUT_MSG)) { + key := (msg).key; + val := (msg).value; + kvWrite := [kvLocal EXCEPT ![key] = val]; + await (Len(clientMailboxes[(msg).reply_to])) < (BUFFER_SIZE); + clientsWrite := [clientMailboxes EXCEPT ![(msg).reply_to] = Append(clientMailboxes[(msg).reply_to], [type |-> PUT_RESPONSE, result |-> ok])]; + kvWrite0 := kvWrite; + clientsWrite1 := clientsWrite; + clientMailboxes := clientsWrite1; + kvLocal := kvWrite0; + goto respondPendingRequestsLoop; + } else { + kvWrite0 := kvLocal; + clientsWrite1 := clientMailboxes; + clientMailboxes := clientsWrite1; + kvLocal := kvWrite0; + goto respondPendingRequestsLoop; + }; + + } else { + clientsWrite2 := clientMailboxes; + kvWrite1 := kvLocal; + clientMailboxes := clientsWrite2; + kvLocal := kvWrite1; + goto replicaLoop; + }; + + } else { + replicasWrite0 := replicasNetwork; + clientsWrite3 := clientMailboxes; + kvWrite2 := kvLocal; + clientMailboxes := clientsWrite3; + replicasNetwork := replicasWrite0; + kvLocal := kvWrite2; + }; + + } + fair process (GetClient \in GetSet) + variables spinLocal = TRUE, continue = TRUE, getReq, getResp; + { + getLoop: + if (continue) { + getRequest: + clientIdRead := (self) - ((NUM_CLIENTS) * (GET_ORDER)); + clockRead := clocks[clientIdRead]; + if ((clockRead) = (-(1))) { + continue := FALSE; + clockWrite0 := clocks; + replicasWrite2 := replicasNetwork; + clientsWrite6 := clientMailboxes; + outsideWrite1 := out; + replicasNetwork := replicasWrite2; + clientMailboxes := clientsWrite6; + clocks := clockWrite0; + out := outsideWrite1; + } else { + clientIdRead0 := (self) - ((NUM_CLIENTS) * (GET_ORDER)); + clockRead0 := clocks[clientIdRead0]; + clientIdRead1 := (self) - ((NUM_CLIENTS) * (GET_ORDER)); + clockWrite := [clocks EXCEPT ![clientIdRead1] = (clockRead0) + (1)]; + keyRead := GET_KEY; + clientIdRead2 := (self) - ((NUM_CLIENTS) * (GET_ORDER)); + clientIdRead3 := (self) - ((NUM_CLIENTS) * (GET_ORDER)); + clockRead1 := clockWrite[clientIdRead3]; + getReq := [op |-> GET_MSG, key |-> keyRead, client |-> clientIdRead2, timestamp |-> clockRead1, reply_to |-> self]; + with (dst \in ReplicaSet) { + await (Len(replicasNetwork[dst])) < (BUFFER_SIZE); + replicasWrite1 := [replicasNetwork EXCEPT ![dst] = Append(replicasNetwork[dst], getReq)]; + }; + replicasNetwork := replicasWrite1; + clocks := clockWrite; + getReply: + clientIdRead := (self) - ((NUM_CLIENTS) * (GET_ORDER)); + clockRead := clocks[clientIdRead]; + if ((clockRead) = (-(1))) { + continue := FALSE; + clientsWrite5 := clientMailboxes; + outsideWrite0 := out; + clientMailboxes := clientsWrite5; + out := outsideWrite0; + } else { + await (Len(clientMailboxes[self])) > (0); + with (msg1 = Head(clientMailboxes[self])) { + clientsWrite4 := [clientMailboxes EXCEPT ![self] = Tail(clientMailboxes[self])]; + clientsRead := msg1; + }; + getResp := clientsRead; + assert ((getResp).type) = (GET_RESPONSE); + outsideWrite := (getResp).result; + clientsWrite5 := clientsWrite4; + outsideWrite0 := outsideWrite; + clientMailboxes := clientsWrite5; + out := outsideWrite0; + }; + + }; + + getCheckSpin: + spinRead := spinLocal; + if (~(spinRead)) { + continue := FALSE; + goto getLoop; + } else { + goto getLoop; + }; + + } else { + clockWrite1 := clocks; + replicasWrite3 := replicasNetwork; + clientsWrite7 := clientMailboxes; + outsideWrite2 := out; + replicasNetwork := replicasWrite3; + clientMailboxes := clientsWrite7; + clocks := clockWrite1; + out := outsideWrite2; + }; + + } + fair process (PutClient \in PutSet) + variables spinLocal0 = TRUE, continue = TRUE, i, j, putReq, putResp; + { + putLoop: + if (continue) { + putRequest: + clientIdRead4 := (self) - ((NUM_CLIENTS) * (PUT_ORDER)); + clockRead2 := clocks[clientIdRead4]; + if ((clockRead2) = (-(1))) { + continue := FALSE; + clockWrite3 := clocks; + replicasWrite6 := replicasNetwork; + clientsWrite11 := clientMailboxes; + outsideWrite4 := out; + replicasNetwork := replicasWrite6; + clientMailboxes := clientsWrite11; + clocks := clockWrite3; + out := outsideWrite4; + } else { + clientIdRead5 := (self) - ((NUM_CLIENTS) * (PUT_ORDER)); + clockRead3 := clocks[clientIdRead5]; + clientIdRead6 := (self) - ((NUM_CLIENTS) * (PUT_ORDER)); + clockWrite2 := [clocks EXCEPT ![clientIdRead6] = (clockRead3) + (1)]; + keyRead0 := PUT_KEY; + valueRead := PUT_VALUE; + clientIdRead7 := (self) - ((NUM_CLIENTS) * (PUT_ORDER)); + clientIdRead8 := (self) - ((NUM_CLIENTS) * (PUT_ORDER)); + clockRead4 := clockWrite2[clientIdRead8]; + putReq := [op |-> PUT_MSG, key |-> keyRead0, value |-> valueRead, client |-> clientIdRead7, timestamp |-> clockRead4, reply_to |-> self]; + i := 0; + j := 0; + clocks := clockWrite2; + putBroadcast: + clientIdRead4 := (self) - ((NUM_CLIENTS) * (PUT_ORDER)); + clockRead2 := clocks[clientIdRead4]; + if (((j) <= ((NUM_REPLICAS) - (1))) /\ ((clockRead2) # (-(1)))) { + await (Len(replicasNetwork[j])) < (BUFFER_SIZE); + replicasWrite4 := [replicasNetwork EXCEPT ![j] = Append(replicasNetwork[j], putReq)]; + j := (j) + (1); + replicasWrite5 := replicasWrite4; + replicasNetwork := replicasWrite5; + goto putBroadcast; + } else { + replicasWrite5 := replicasNetwork; + replicasNetwork := replicasWrite5; + }; + + putResponse: + if ((i) < (Cardinality(ReplicaSet))) { + clientIdRead4 := (self) - ((NUM_CLIENTS) * (PUT_ORDER)); + clockRead2 := clocks[clientIdRead4]; + if ((clockRead2) = (-(1))) { + continue := FALSE; + clientsWrite9 := clientMailboxes; + clientsWrite10 := clientsWrite9; + clientMailboxes := clientsWrite10; + goto putLoop; + } else { + await (Len(clientMailboxes[self])) > (0); + with (msg2 = Head(clientMailboxes[self])) { + clientsWrite8 := [clientMailboxes EXCEPT ![self] = Tail(clientMailboxes[self])]; + clientsRead0 := msg2; + }; + putResp := clientsRead0; + assert ((putResp).type) = (PUT_RESPONSE); + i := (i) + (1); + clientsWrite9 := clientsWrite8; + clientsWrite10 := clientsWrite9; + clientMailboxes := clientsWrite10; + goto putResponse; + }; + } else { + clientsWrite10 := clientMailboxes; + clientMailboxes := clientsWrite10; + }; + + putComplete: + outsideWrite3 := PUT_RESPONSE; + out := outsideWrite3; + + }; + + putCheckSpin: + spinRead0 := spinLocal0; + if (~(spinRead0)) { + continue := FALSE; + goto putLoop; + } else { + goto putLoop; + }; + + } else { + clockWrite4 := clocks; + replicasWrite7 := replicasNetwork; + clientsWrite12 := clientMailboxes; + outsideWrite5 := out; + replicasNetwork := replicasWrite7; + clientMailboxes := clientsWrite12; + clocks := clockWrite4; + out := outsideWrite5; + }; + + } + fair process (DisconnectClient \in DisconnectSet) + variables msg, j; + { + sendDisconnectRequest: + clientIdRead9 := (self) - ((NUM_CLIENTS) * (DISCONNECT_ORDER)); + msg := [op |-> DISCONNECT_MSG, client |-> clientIdRead9]; + clientIdRead10 := (self) - ((NUM_CLIENTS) * (DISCONNECT_ORDER)); + clockWrite5 := [clocks EXCEPT ![clientIdRead10] = -(1)]; + j := 0; + clocks := clockWrite5; + disconnectBroadcast: + if (((j) <= ((NUM_REPLICAS) - (1))) /\ ((0) # (-(1)))) { + await (Len(replicasNetwork[j])) < (BUFFER_SIZE); + replicasWrite8 := [replicasNetwork EXCEPT ![j] = Append(replicasNetwork[j], msg)]; + j := (j) + (1); + replicasWrite9 := replicasWrite8; + replicasNetwork := replicasWrite9; + goto disconnectBroadcast; + } else { + replicasWrite9 := replicasNetwork; + replicasNetwork := replicasWrite9; + }; + + } + fair process (ClockUpdateClient \in NullSet) + variables spinLocal1 = TRUE, continue = TRUE, j, msg; + { + clockUpdateLoop: + if (continue) { + clientIdRead11 := (self) - ((NUM_CLIENTS) * (NULL_ORDER)); + clockRead5 := clocks[clientIdRead11]; + if ((clockRead5) = (-(1))) { + continue := FALSE; + clockWrite7 := clocks; + replicasWrite12 := replicasNetwork; + replicasNetwork := replicasWrite12; + clocks := clockWrite7; + } else { + clientIdRead12 := (self) - ((NUM_CLIENTS) * (NULL_ORDER)); + clockRead6 := clocks[clientIdRead12]; + clientIdRead13 := (self) - ((NUM_CLIENTS) * (NULL_ORDER)); + clockWrite6 := [clocks EXCEPT ![clientIdRead13] = (clockRead6) + (1)]; + clientIdRead14 := (self) - ((NUM_CLIENTS) * (NULL_ORDER)); + clientIdRead15 := (self) - ((NUM_CLIENTS) * (NULL_ORDER)); + clockRead7 := clockWrite6[clientIdRead15]; + msg := [op |-> NULL_MSG, client |-> clientIdRead14, timestamp |-> clockRead7]; + j := 0; + clocks := clockWrite6; + nullBroadcast: + clientIdRead11 := (self) - ((NUM_CLIENTS) * (NULL_ORDER)); + clockRead5 := clocks[clientIdRead11]; + if (((j) <= ((NUM_REPLICAS) - (1))) /\ ((clockRead5) # (-(1)))) { + await (Len(replicasNetwork[j])) < (BUFFER_SIZE); + replicasWrite10 := [replicasNetwork EXCEPT ![j] = Append(replicasNetwork[j], msg)]; + j := (j) + (1); + replicasWrite11 := replicasWrite10; + replicasNetwork := replicasWrite11; + goto nullBroadcast; + } else { + replicasWrite11 := replicasNetwork; + replicasNetwork := replicasWrite11; + }; + + }; + nullCheckSpin: + spinRead1 := spinLocal1; + if (~(spinRead1)) { + continue := FALSE; + goto clockUpdateLoop; + } else { + goto clockUpdateLoop; + }; + + } else { + clockWrite8 := clocks; + replicasWrite13 := replicasNetwork; + replicasNetwork := replicasWrite13; + clocks := clockWrite8; + }; + + } +} +\* END PLUSCAL TRANSLATION + + +***************************************************************************) +\* BEGIN TRANSLATION - the hash of the PCal code: PCal-edda648b9b148ad88bcb79bb7a4a821b +\* Process variable i of process Replica at line 659 col 148 changed to i_ +\* Process variable continue of process Replica at line 659 col 271 changed to continue_ +\* Process variable msg of process Replica at line 659 col 310 changed to msg_ +\* Process variable continue of process GetClient at line 808 col 33 changed to continue_G +\* Process variable continue of process PutClient at line 889 col 34 changed to continue_P +\* Process variable j of process PutClient at line 889 col 54 changed to j_ +\* Process variable msg of process DisconnectClient at line 992 col 15 changed to msg_D +\* Process variable j of process DisconnectClient at line 992 col 20 changed to j_D +CONSTANT defaultInitValue +VARIABLES replicasNetwork, allClients, clientMailboxes, cid, out, clocks, + replicasRead, replicasWrite, kvRead, clientsWrite, clientsWrite0, + kvWrite, kvWrite0, clientsWrite1, clientsWrite2, kvWrite1, + replicasWrite0, clientsWrite3, kvWrite2, clientIdRead, clockRead, + clientIdRead0, clockRead0, clientIdRead1, clockWrite, keyRead, + clientIdRead2, clientIdRead3, clockRead1, replicasWrite1, + clientsRead, clientsWrite4, outsideWrite, clientsWrite5, + outsideWrite0, clockWrite0, replicasWrite2, clientsWrite6, + outsideWrite1, spinRead, clockWrite1, replicasWrite3, clientsWrite7, + outsideWrite2, clientIdRead4, clockRead2, clientIdRead5, clockRead3, + clientIdRead6, clockWrite2, keyRead0, valueRead, clientIdRead7, + clientIdRead8, clockRead4, replicasWrite4, replicasWrite5, + clientsRead0, clientsWrite8, clientsWrite9, clientsWrite10, + outsideWrite3, clockWrite3, replicasWrite6, clientsWrite11, + outsideWrite4, spinRead0, clockWrite4, replicasWrite7, + clientsWrite12, outsideWrite5, clientIdRead9, clientIdRead10, + clockWrite5, replicasWrite8, replicasWrite9, clientIdRead11, + clockRead5, clientIdRead12, clockRead6, clientIdRead13, clockWrite6, + clientIdRead14, clientIdRead15, clockRead7, replicasWrite10, + replicasWrite11, clockWrite7, replicasWrite12, spinRead1, + clockWrite8, replicasWrite13, pc + +(* define statement *) +NUM_NODES == (NUM_REPLICAS) + (NUM_CLIENTS) +ReplicaSet == (0) .. ((NUM_REPLICAS) - (1)) +ClientSet == (NUM_REPLICAS) .. ((NUM_NODES) - (1)) + +VARIABLES kvLocal, liveClients, pendingRequests, stableMessages, i_, + firstPending, timestamp, nextClient, lowestPending, chooseMessage, + currentClocks, minClock, continue_, pendingClients, clientsIter, + msg_, ok, key, val, spinLocal, continue_G, getReq, getResp, + spinLocal0, continue_P, i, j_, putReq, putResp, msg_D, j_D, + spinLocal1, continue, j, msg + +vars == << replicasNetwork, allClients, clientMailboxes, cid, out, clocks, + replicasRead, replicasWrite, kvRead, clientsWrite, clientsWrite0, + kvWrite, kvWrite0, clientsWrite1, clientsWrite2, kvWrite1, + replicasWrite0, clientsWrite3, kvWrite2, clientIdRead, clockRead, + clientIdRead0, clockRead0, clientIdRead1, clockWrite, keyRead, + clientIdRead2, clientIdRead3, clockRead1, replicasWrite1, + clientsRead, clientsWrite4, outsideWrite, clientsWrite5, + outsideWrite0, clockWrite0, replicasWrite2, clientsWrite6, + outsideWrite1, spinRead, clockWrite1, replicasWrite3, + clientsWrite7, outsideWrite2, clientIdRead4, clockRead2, + clientIdRead5, clockRead3, clientIdRead6, clockWrite2, keyRead0, + valueRead, clientIdRead7, clientIdRead8, clockRead4, + replicasWrite4, replicasWrite5, clientsRead0, clientsWrite8, + clientsWrite9, clientsWrite10, outsideWrite3, clockWrite3, + replicasWrite6, clientsWrite11, outsideWrite4, spinRead0, + clockWrite4, replicasWrite7, clientsWrite12, outsideWrite5, + clientIdRead9, clientIdRead10, clockWrite5, replicasWrite8, + replicasWrite9, clientIdRead11, clockRead5, clientIdRead12, + clockRead6, clientIdRead13, clockWrite6, clientIdRead14, + clientIdRead15, clockRead7, replicasWrite10, replicasWrite11, + clockWrite7, replicasWrite12, spinRead1, clockWrite8, + replicasWrite13, pc, kvLocal, liveClients, pendingRequests, + stableMessages, i_, firstPending, timestamp, nextClient, + lowestPending, chooseMessage, currentClocks, minClock, continue_, + pendingClients, clientsIter, msg_, ok, key, val, spinLocal, + continue_G, getReq, getResp, spinLocal0, continue_P, i, j_, putReq, + putResp, msg_D, j_D, spinLocal1, continue, j, msg >> + +ProcSet == (ReplicaSet) \cup (GetSet) \cup (PutSet) \cup (DisconnectSet) \cup (NullSet) + +Init == (* Global variables *) + /\ replicasNetwork = [id \in ReplicaSet |-> <<>>] + /\ allClients = ((((GetSet) \cup (PutSet)) \cup (DisconnectSet)) \cup (NullSet)) + /\ clientMailboxes = [id \in allClients |-> <<>>] + /\ cid = 0 + /\ out = 0 + /\ clocks = [c \in ClientSet |-> 0] + /\ replicasRead = defaultInitValue + /\ replicasWrite = defaultInitValue + /\ kvRead = defaultInitValue + /\ clientsWrite = defaultInitValue + /\ clientsWrite0 = defaultInitValue + /\ kvWrite = defaultInitValue + /\ kvWrite0 = defaultInitValue + /\ clientsWrite1 = defaultInitValue + /\ clientsWrite2 = defaultInitValue + /\ kvWrite1 = defaultInitValue + /\ replicasWrite0 = defaultInitValue + /\ clientsWrite3 = defaultInitValue + /\ kvWrite2 = defaultInitValue + /\ clientIdRead = defaultInitValue + /\ clockRead = defaultInitValue + /\ clientIdRead0 = defaultInitValue + /\ clockRead0 = defaultInitValue + /\ clientIdRead1 = defaultInitValue + /\ clockWrite = defaultInitValue + /\ keyRead = defaultInitValue + /\ clientIdRead2 = defaultInitValue + /\ clientIdRead3 = defaultInitValue + /\ clockRead1 = defaultInitValue + /\ replicasWrite1 = defaultInitValue + /\ clientsRead = defaultInitValue + /\ clientsWrite4 = defaultInitValue + /\ outsideWrite = defaultInitValue + /\ clientsWrite5 = defaultInitValue + /\ outsideWrite0 = defaultInitValue + /\ clockWrite0 = defaultInitValue + /\ replicasWrite2 = defaultInitValue + /\ clientsWrite6 = defaultInitValue + /\ outsideWrite1 = defaultInitValue + /\ spinRead = defaultInitValue + /\ clockWrite1 = defaultInitValue + /\ replicasWrite3 = defaultInitValue + /\ clientsWrite7 = defaultInitValue + /\ outsideWrite2 = defaultInitValue + /\ clientIdRead4 = defaultInitValue + /\ clockRead2 = defaultInitValue + /\ clientIdRead5 = defaultInitValue + /\ clockRead3 = defaultInitValue + /\ clientIdRead6 = defaultInitValue + /\ clockWrite2 = defaultInitValue + /\ keyRead0 = defaultInitValue + /\ valueRead = defaultInitValue + /\ clientIdRead7 = defaultInitValue + /\ clientIdRead8 = defaultInitValue + /\ clockRead4 = defaultInitValue + /\ replicasWrite4 = defaultInitValue + /\ replicasWrite5 = defaultInitValue + /\ clientsRead0 = defaultInitValue + /\ clientsWrite8 = defaultInitValue + /\ clientsWrite9 = defaultInitValue + /\ clientsWrite10 = defaultInitValue + /\ outsideWrite3 = defaultInitValue + /\ clockWrite3 = defaultInitValue + /\ replicasWrite6 = defaultInitValue + /\ clientsWrite11 = defaultInitValue + /\ outsideWrite4 = defaultInitValue + /\ spinRead0 = defaultInitValue + /\ clockWrite4 = defaultInitValue + /\ replicasWrite7 = defaultInitValue + /\ clientsWrite12 = defaultInitValue + /\ outsideWrite5 = defaultInitValue + /\ clientIdRead9 = defaultInitValue + /\ clientIdRead10 = defaultInitValue + /\ clockWrite5 = defaultInitValue + /\ replicasWrite8 = defaultInitValue + /\ replicasWrite9 = defaultInitValue + /\ clientIdRead11 = defaultInitValue + /\ clockRead5 = defaultInitValue + /\ clientIdRead12 = defaultInitValue + /\ clockRead6 = defaultInitValue + /\ clientIdRead13 = defaultInitValue + /\ clockWrite6 = defaultInitValue + /\ clientIdRead14 = defaultInitValue + /\ clientIdRead15 = defaultInitValue + /\ clockRead7 = defaultInitValue + /\ replicasWrite10 = defaultInitValue + /\ replicasWrite11 = defaultInitValue + /\ clockWrite7 = defaultInitValue + /\ replicasWrite12 = defaultInitValue + /\ spinRead1 = defaultInitValue + /\ clockWrite8 = defaultInitValue + /\ replicasWrite13 = defaultInitValue + (* Process Replica *) + /\ kvLocal = [self \in ReplicaSet |-> [k \in KeySpace |-> NULL]] + /\ liveClients = [self \in ReplicaSet |-> ClientSet] + /\ pendingRequests = [self \in ReplicaSet |-> [c \in liveClients[self] |-> <<>>]] + /\ stableMessages = [self \in ReplicaSet |-> <<>>] + /\ i_ = [self \in ReplicaSet |-> defaultInitValue] + /\ firstPending = [self \in ReplicaSet |-> defaultInitValue] + /\ timestamp = [self \in ReplicaSet |-> defaultInitValue] + /\ nextClient = [self \in ReplicaSet |-> defaultInitValue] + /\ lowestPending = [self \in ReplicaSet |-> defaultInitValue] + /\ chooseMessage = [self \in ReplicaSet |-> defaultInitValue] + /\ currentClocks = [self \in ReplicaSet |-> [c \in liveClients[self] |-> 0]] + /\ minClock = [self \in ReplicaSet |-> defaultInitValue] + /\ continue_ = [self \in ReplicaSet |-> defaultInitValue] + /\ pendingClients = [self \in ReplicaSet |-> defaultInitValue] + /\ clientsIter = [self \in ReplicaSet |-> defaultInitValue] + /\ msg_ = [self \in ReplicaSet |-> defaultInitValue] + /\ ok = [self \in ReplicaSet |-> defaultInitValue] + /\ key = [self \in ReplicaSet |-> defaultInitValue] + /\ val = [self \in ReplicaSet |-> defaultInitValue] + (* Process GetClient *) + /\ spinLocal = [self \in GetSet |-> TRUE] + /\ continue_G = [self \in GetSet |-> TRUE] + /\ getReq = [self \in GetSet |-> defaultInitValue] + /\ getResp = [self \in GetSet |-> defaultInitValue] + (* Process PutClient *) + /\ spinLocal0 = [self \in PutSet |-> TRUE] + /\ continue_P = [self \in PutSet |-> TRUE] + /\ i = [self \in PutSet |-> defaultInitValue] + /\ j_ = [self \in PutSet |-> defaultInitValue] + /\ putReq = [self \in PutSet |-> defaultInitValue] + /\ putResp = [self \in PutSet |-> defaultInitValue] + (* Process DisconnectClient *) + /\ msg_D = [self \in DisconnectSet |-> defaultInitValue] + /\ j_D = [self \in DisconnectSet |-> defaultInitValue] + (* Process ClockUpdateClient *) + /\ spinLocal1 = [self \in NullSet |-> TRUE] + /\ continue = [self \in NullSet |-> TRUE] + /\ j = [self \in NullSet |-> defaultInitValue] + /\ msg = [self \in NullSet |-> defaultInitValue] + /\ pc = [self \in ProcSet |-> CASE self \in ReplicaSet -> "replicaLoop" + [] self \in GetSet -> "getLoop" + [] self \in PutSet -> "putLoop" + [] self \in DisconnectSet -> "sendDisconnectRequest" + [] self \in NullSet -> "clockUpdateLoop"] + +replicaLoop(self) == /\ pc[self] = "replicaLoop" + /\ IF TRUE + THEN /\ stableMessages' = [stableMessages EXCEPT ![self] = <<>>] + /\ continue_' = [continue_ EXCEPT ![self] = TRUE] + /\ pc' = [pc EXCEPT ![self] = "receiveClientRequest"] + /\ UNCHANGED << replicasNetwork, + clientMailboxes, + replicasWrite0, clientsWrite3, + kvWrite2, kvLocal >> + ELSE /\ replicasWrite0' = replicasNetwork + /\ clientsWrite3' = clientMailboxes + /\ kvWrite2' = kvLocal[self] + /\ clientMailboxes' = clientsWrite3' + /\ replicasNetwork' = replicasWrite0' + /\ kvLocal' = [kvLocal EXCEPT ![self] = kvWrite2'] + /\ pc' = [pc EXCEPT ![self] = "Done"] + /\ UNCHANGED << stableMessages, continue_ >> + /\ UNCHANGED << allClients, cid, out, clocks, + replicasRead, replicasWrite, kvRead, + clientsWrite, clientsWrite0, kvWrite, + kvWrite0, clientsWrite1, clientsWrite2, + kvWrite1, clientIdRead, clockRead, + clientIdRead0, clockRead0, clientIdRead1, + clockWrite, keyRead, clientIdRead2, + clientIdRead3, clockRead1, replicasWrite1, + clientsRead, clientsWrite4, outsideWrite, + clientsWrite5, outsideWrite0, clockWrite0, + replicasWrite2, clientsWrite6, + outsideWrite1, spinRead, clockWrite1, + replicasWrite3, clientsWrite7, + outsideWrite2, clientIdRead4, clockRead2, + clientIdRead5, clockRead3, clientIdRead6, + clockWrite2, keyRead0, valueRead, + clientIdRead7, clientIdRead8, clockRead4, + replicasWrite4, replicasWrite5, + clientsRead0, clientsWrite8, + clientsWrite9, clientsWrite10, + outsideWrite3, clockWrite3, + replicasWrite6, clientsWrite11, + outsideWrite4, spinRead0, clockWrite4, + replicasWrite7, clientsWrite12, + outsideWrite5, clientIdRead9, + clientIdRead10, clockWrite5, + replicasWrite8, replicasWrite9, + clientIdRead11, clockRead5, + clientIdRead12, clockRead6, + clientIdRead13, clockWrite6, + clientIdRead14, clientIdRead15, + clockRead7, replicasWrite10, + replicasWrite11, clockWrite7, + replicasWrite12, spinRead1, clockWrite8, + replicasWrite13, liveClients, + pendingRequests, i_, firstPending, + timestamp, nextClient, lowestPending, + chooseMessage, currentClocks, minClock, + pendingClients, clientsIter, msg_, ok, + key, val, spinLocal, continue_G, getReq, + getResp, spinLocal0, continue_P, i, j_, + putReq, putResp, msg_D, j_D, spinLocal1, + continue, j, msg >> + +receiveClientRequest(self) == /\ pc[self] = "receiveClientRequest" + /\ (Len(replicasNetwork[self])) > (0) + /\ LET msg0 == Head(replicasNetwork[self]) IN + /\ replicasWrite' = [replicasNetwork EXCEPT ![self] = Tail(replicasNetwork[self])] + /\ replicasRead' = msg0 + /\ msg_' = [msg_ EXCEPT ![self] = replicasRead'] + /\ replicasNetwork' = replicasWrite' + /\ pc' = [pc EXCEPT ![self] = "clientDisconnected"] + /\ UNCHANGED << allClients, clientMailboxes, cid, + out, clocks, kvRead, + clientsWrite, clientsWrite0, + kvWrite, kvWrite0, clientsWrite1, + clientsWrite2, kvWrite1, + replicasWrite0, clientsWrite3, + kvWrite2, clientIdRead, + clockRead, clientIdRead0, + clockRead0, clientIdRead1, + clockWrite, keyRead, + clientIdRead2, clientIdRead3, + clockRead1, replicasWrite1, + clientsRead, clientsWrite4, + outsideWrite, clientsWrite5, + outsideWrite0, clockWrite0, + replicasWrite2, clientsWrite6, + outsideWrite1, spinRead, + clockWrite1, replicasWrite3, + clientsWrite7, outsideWrite2, + clientIdRead4, clockRead2, + clientIdRead5, clockRead3, + clientIdRead6, clockWrite2, + keyRead0, valueRead, + clientIdRead7, clientIdRead8, + clockRead4, replicasWrite4, + replicasWrite5, clientsRead0, + clientsWrite8, clientsWrite9, + clientsWrite10, outsideWrite3, + clockWrite3, replicasWrite6, + clientsWrite11, outsideWrite4, + spinRead0, clockWrite4, + replicasWrite7, clientsWrite12, + outsideWrite5, clientIdRead9, + clientIdRead10, clockWrite5, + replicasWrite8, replicasWrite9, + clientIdRead11, clockRead5, + clientIdRead12, clockRead6, + clientIdRead13, clockWrite6, + clientIdRead14, clientIdRead15, + clockRead7, replicasWrite10, + replicasWrite11, clockWrite7, + replicasWrite12, spinRead1, + clockWrite8, replicasWrite13, + kvLocal, liveClients, + pendingRequests, stableMessages, + i_, firstPending, timestamp, + nextClient, lowestPending, + chooseMessage, currentClocks, + minClock, continue_, + pendingClients, clientsIter, ok, + key, val, spinLocal, continue_G, + getReq, getResp, spinLocal0, + continue_P, i, j_, putReq, + putResp, msg_D, j_D, spinLocal1, + continue, j, msg >> + +clientDisconnected(self) == /\ pc[self] = "clientDisconnected" + /\ IF ((msg_[self]).op) = (DISCONNECT_MSG) + THEN /\ liveClients' = [liveClients EXCEPT ![self] = (liveClients[self]) \ ({(msg_[self]).client})] + ELSE /\ TRUE + /\ UNCHANGED liveClients + /\ pc' = [pc EXCEPT ![self] = "replicaGetRequest"] + /\ UNCHANGED << replicasNetwork, allClients, + clientMailboxes, cid, out, clocks, + replicasRead, replicasWrite, + kvRead, clientsWrite, + clientsWrite0, kvWrite, kvWrite0, + clientsWrite1, clientsWrite2, + kvWrite1, replicasWrite0, + clientsWrite3, kvWrite2, + clientIdRead, clockRead, + clientIdRead0, clockRead0, + clientIdRead1, clockWrite, keyRead, + clientIdRead2, clientIdRead3, + clockRead1, replicasWrite1, + clientsRead, clientsWrite4, + outsideWrite, clientsWrite5, + outsideWrite0, clockWrite0, + replicasWrite2, clientsWrite6, + outsideWrite1, spinRead, + clockWrite1, replicasWrite3, + clientsWrite7, outsideWrite2, + clientIdRead4, clockRead2, + clientIdRead5, clockRead3, + clientIdRead6, clockWrite2, + keyRead0, valueRead, clientIdRead7, + clientIdRead8, clockRead4, + replicasWrite4, replicasWrite5, + clientsRead0, clientsWrite8, + clientsWrite9, clientsWrite10, + outsideWrite3, clockWrite3, + replicasWrite6, clientsWrite11, + outsideWrite4, spinRead0, + clockWrite4, replicasWrite7, + clientsWrite12, outsideWrite5, + clientIdRead9, clientIdRead10, + clockWrite5, replicasWrite8, + replicasWrite9, clientIdRead11, + clockRead5, clientIdRead12, + clockRead6, clientIdRead13, + clockWrite6, clientIdRead14, + clientIdRead15, clockRead7, + replicasWrite10, replicasWrite11, + clockWrite7, replicasWrite12, + spinRead1, clockWrite8, + replicasWrite13, kvLocal, + pendingRequests, stableMessages, + i_, firstPending, timestamp, + nextClient, lowestPending, + chooseMessage, currentClocks, + minClock, continue_, + pendingClients, clientsIter, msg_, + ok, key, val, spinLocal, + continue_G, getReq, getResp, + spinLocal0, continue_P, i, j_, + putReq, putResp, msg_D, j_D, + spinLocal1, continue, j, msg >> + +replicaGetRequest(self) == /\ pc[self] = "replicaGetRequest" + /\ IF ((msg_[self]).op) = (GET_MSG) + THEN /\ Assert(((msg_[self]).client) \in (liveClients[self]), + "Failure of assertion at line 681, column 25.") + /\ currentClocks' = [currentClocks EXCEPT ![self][msg_[self].client] = (msg_[self]).timestamp] + /\ pendingRequests' = [pendingRequests EXCEPT ![self][msg_[self].client] = Append(pendingRequests[self][(msg_[self]).client], msg_[self])] + ELSE /\ TRUE + /\ UNCHANGED << pendingRequests, + currentClocks >> + /\ pc' = [pc EXCEPT ![self] = "replicaPutRequest"] + /\ UNCHANGED << replicasNetwork, allClients, + clientMailboxes, cid, out, clocks, + replicasRead, replicasWrite, kvRead, + clientsWrite, clientsWrite0, + kvWrite, kvWrite0, clientsWrite1, + clientsWrite2, kvWrite1, + replicasWrite0, clientsWrite3, + kvWrite2, clientIdRead, clockRead, + clientIdRead0, clockRead0, + clientIdRead1, clockWrite, keyRead, + clientIdRead2, clientIdRead3, + clockRead1, replicasWrite1, + clientsRead, clientsWrite4, + outsideWrite, clientsWrite5, + outsideWrite0, clockWrite0, + replicasWrite2, clientsWrite6, + outsideWrite1, spinRead, + clockWrite1, replicasWrite3, + clientsWrite7, outsideWrite2, + clientIdRead4, clockRead2, + clientIdRead5, clockRead3, + clientIdRead6, clockWrite2, + keyRead0, valueRead, clientIdRead7, + clientIdRead8, clockRead4, + replicasWrite4, replicasWrite5, + clientsRead0, clientsWrite8, + clientsWrite9, clientsWrite10, + outsideWrite3, clockWrite3, + replicasWrite6, clientsWrite11, + outsideWrite4, spinRead0, + clockWrite4, replicasWrite7, + clientsWrite12, outsideWrite5, + clientIdRead9, clientIdRead10, + clockWrite5, replicasWrite8, + replicasWrite9, clientIdRead11, + clockRead5, clientIdRead12, + clockRead6, clientIdRead13, + clockWrite6, clientIdRead14, + clientIdRead15, clockRead7, + replicasWrite10, replicasWrite11, + clockWrite7, replicasWrite12, + spinRead1, clockWrite8, + replicasWrite13, kvLocal, + liveClients, stableMessages, i_, + firstPending, timestamp, nextClient, + lowestPending, chooseMessage, + minClock, continue_, pendingClients, + clientsIter, msg_, ok, key, val, + spinLocal, continue_G, getReq, + getResp, spinLocal0, continue_P, i, + j_, putReq, putResp, msg_D, j_D, + spinLocal1, continue, j, msg >> + +replicaPutRequest(self) == /\ pc[self] = "replicaPutRequest" + /\ IF ((msg_[self]).op) = (PUT_MSG) + THEN /\ currentClocks' = [currentClocks EXCEPT ![self][msg_[self].client] = (msg_[self]).timestamp] + /\ pendingRequests' = [pendingRequests EXCEPT ![self][msg_[self].client] = Append(pendingRequests[self][(msg_[self]).client], msg_[self])] + ELSE /\ TRUE + /\ UNCHANGED << pendingRequests, + currentClocks >> + /\ pc' = [pc EXCEPT ![self] = "replicaNullRequest"] + /\ UNCHANGED << replicasNetwork, allClients, + clientMailboxes, cid, out, clocks, + replicasRead, replicasWrite, kvRead, + clientsWrite, clientsWrite0, + kvWrite, kvWrite0, clientsWrite1, + clientsWrite2, kvWrite1, + replicasWrite0, clientsWrite3, + kvWrite2, clientIdRead, clockRead, + clientIdRead0, clockRead0, + clientIdRead1, clockWrite, keyRead, + clientIdRead2, clientIdRead3, + clockRead1, replicasWrite1, + clientsRead, clientsWrite4, + outsideWrite, clientsWrite5, + outsideWrite0, clockWrite0, + replicasWrite2, clientsWrite6, + outsideWrite1, spinRead, + clockWrite1, replicasWrite3, + clientsWrite7, outsideWrite2, + clientIdRead4, clockRead2, + clientIdRead5, clockRead3, + clientIdRead6, clockWrite2, + keyRead0, valueRead, clientIdRead7, + clientIdRead8, clockRead4, + replicasWrite4, replicasWrite5, + clientsRead0, clientsWrite8, + clientsWrite9, clientsWrite10, + outsideWrite3, clockWrite3, + replicasWrite6, clientsWrite11, + outsideWrite4, spinRead0, + clockWrite4, replicasWrite7, + clientsWrite12, outsideWrite5, + clientIdRead9, clientIdRead10, + clockWrite5, replicasWrite8, + replicasWrite9, clientIdRead11, + clockRead5, clientIdRead12, + clockRead6, clientIdRead13, + clockWrite6, clientIdRead14, + clientIdRead15, clockRead7, + replicasWrite10, replicasWrite11, + clockWrite7, replicasWrite12, + spinRead1, clockWrite8, + replicasWrite13, kvLocal, + liveClients, stableMessages, i_, + firstPending, timestamp, nextClient, + lowestPending, chooseMessage, + minClock, continue_, pendingClients, + clientsIter, msg_, ok, key, val, + spinLocal, continue_G, getReq, + getResp, spinLocal0, continue_P, i, + j_, putReq, putResp, msg_D, j_D, + spinLocal1, continue, j, msg >> + +replicaNullRequest(self) == /\ pc[self] = "replicaNullRequest" + /\ IF ((msg_[self]).op) = (NULL_MSG) + THEN /\ currentClocks' = [currentClocks EXCEPT ![self][msg_[self].client] = (msg_[self]).timestamp] + ELSE /\ TRUE + /\ UNCHANGED currentClocks + /\ pc' = [pc EXCEPT ![self] = "findStableRequestsLoop"] + /\ UNCHANGED << replicasNetwork, allClients, + clientMailboxes, cid, out, clocks, + replicasRead, replicasWrite, + kvRead, clientsWrite, + clientsWrite0, kvWrite, kvWrite0, + clientsWrite1, clientsWrite2, + kvWrite1, replicasWrite0, + clientsWrite3, kvWrite2, + clientIdRead, clockRead, + clientIdRead0, clockRead0, + clientIdRead1, clockWrite, keyRead, + clientIdRead2, clientIdRead3, + clockRead1, replicasWrite1, + clientsRead, clientsWrite4, + outsideWrite, clientsWrite5, + outsideWrite0, clockWrite0, + replicasWrite2, clientsWrite6, + outsideWrite1, spinRead, + clockWrite1, replicasWrite3, + clientsWrite7, outsideWrite2, + clientIdRead4, clockRead2, + clientIdRead5, clockRead3, + clientIdRead6, clockWrite2, + keyRead0, valueRead, clientIdRead7, + clientIdRead8, clockRead4, + replicasWrite4, replicasWrite5, + clientsRead0, clientsWrite8, + clientsWrite9, clientsWrite10, + outsideWrite3, clockWrite3, + replicasWrite6, clientsWrite11, + outsideWrite4, spinRead0, + clockWrite4, replicasWrite7, + clientsWrite12, outsideWrite5, + clientIdRead9, clientIdRead10, + clockWrite5, replicasWrite8, + replicasWrite9, clientIdRead11, + clockRead5, clientIdRead12, + clockRead6, clientIdRead13, + clockWrite6, clientIdRead14, + clientIdRead15, clockRead7, + replicasWrite10, replicasWrite11, + clockWrite7, replicasWrite12, + spinRead1, clockWrite8, + replicasWrite13, kvLocal, + liveClients, pendingRequests, + stableMessages, i_, firstPending, + timestamp, nextClient, + lowestPending, chooseMessage, + minClock, continue_, + pendingClients, clientsIter, msg_, + ok, key, val, spinLocal, + continue_G, getReq, getResp, + spinLocal0, continue_P, i, j_, + putReq, putResp, msg_D, j_D, + spinLocal1, continue, j, msg >> + +findStableRequestsLoop(self) == /\ pc[self] = "findStableRequestsLoop" + /\ IF continue_[self] + THEN /\ pendingClients' = [pendingClients EXCEPT ![self] = {c \in liveClients[self] : (Len(pendingRequests[self][c])) > (0)}] + /\ nextClient' = [nextClient EXCEPT ![self] = (NUM_NODES) + (1)] + /\ clientsIter' = [clientsIter EXCEPT ![self] = liveClients[self]] + /\ i_' = [i_ EXCEPT ![self] = 0] + /\ minClock' = [minClock EXCEPT ![self] = 0] + /\ pc' = [pc EXCEPT ![self] = "findMinClock"] + ELSE /\ i_' = [i_ EXCEPT ![self] = 1] + /\ pc' = [pc EXCEPT ![self] = "respondPendingRequestsLoop"] + /\ UNCHANGED << nextClient, + minClock, + pendingClients, + clientsIter >> + /\ UNCHANGED << replicasNetwork, allClients, + clientMailboxes, cid, out, + clocks, replicasRead, + replicasWrite, kvRead, + clientsWrite, clientsWrite0, + kvWrite, kvWrite0, + clientsWrite1, clientsWrite2, + kvWrite1, replicasWrite0, + clientsWrite3, kvWrite2, + clientIdRead, clockRead, + clientIdRead0, clockRead0, + clientIdRead1, clockWrite, + keyRead, clientIdRead2, + clientIdRead3, clockRead1, + replicasWrite1, clientsRead, + clientsWrite4, outsideWrite, + clientsWrite5, outsideWrite0, + clockWrite0, replicasWrite2, + clientsWrite6, outsideWrite1, + spinRead, clockWrite1, + replicasWrite3, clientsWrite7, + outsideWrite2, clientIdRead4, + clockRead2, clientIdRead5, + clockRead3, clientIdRead6, + clockWrite2, keyRead0, + valueRead, clientIdRead7, + clientIdRead8, clockRead4, + replicasWrite4, replicasWrite5, + clientsRead0, clientsWrite8, + clientsWrite9, clientsWrite10, + outsideWrite3, clockWrite3, + replicasWrite6, clientsWrite11, + outsideWrite4, spinRead0, + clockWrite4, replicasWrite7, + clientsWrite12, outsideWrite5, + clientIdRead9, clientIdRead10, + clockWrite5, replicasWrite8, + replicasWrite9, clientIdRead11, + clockRead5, clientIdRead12, + clockRead6, clientIdRead13, + clockWrite6, clientIdRead14, + clientIdRead15, clockRead7, + replicasWrite10, + replicasWrite11, clockWrite7, + replicasWrite12, spinRead1, + clockWrite8, replicasWrite13, + kvLocal, liveClients, + pendingRequests, + stableMessages, firstPending, + timestamp, lowestPending, + chooseMessage, currentClocks, + continue_, msg_, ok, key, val, + spinLocal, continue_G, getReq, + getResp, spinLocal0, + continue_P, i, j_, putReq, + putResp, msg_D, j_D, + spinLocal1, continue, j, msg >> + +findMinClock(self) == /\ pc[self] = "findMinClock" + /\ IF (i_[self]) < (Cardinality(clientsIter[self])) + THEN /\ \E client \in clientsIter[self]: + /\ IF ((minClock[self]) = (0)) \/ ((currentClocks[self][client]) < (minClock[self])) + THEN /\ minClock' = [minClock EXCEPT ![self] = currentClocks[self][client]] + ELSE /\ TRUE + /\ UNCHANGED minClock + /\ clientsIter' = [clientsIter EXCEPT ![self] = (clientsIter[self]) \ ({client})] + /\ pc' = [pc EXCEPT ![self] = "findMinClock"] + /\ UNCHANGED << i_, lowestPending >> + ELSE /\ lowestPending' = [lowestPending EXCEPT ![self] = (minClock[self]) + (1)] + /\ i_' = [i_ EXCEPT ![self] = 0] + /\ pc' = [pc EXCEPT ![self] = "findMinClient"] + /\ UNCHANGED << minClock, clientsIter >> + /\ UNCHANGED << replicasNetwork, allClients, + clientMailboxes, cid, out, clocks, + replicasRead, replicasWrite, kvRead, + clientsWrite, clientsWrite0, kvWrite, + kvWrite0, clientsWrite1, clientsWrite2, + kvWrite1, replicasWrite0, clientsWrite3, + kvWrite2, clientIdRead, clockRead, + clientIdRead0, clockRead0, clientIdRead1, + clockWrite, keyRead, clientIdRead2, + clientIdRead3, clockRead1, + replicasWrite1, clientsRead, + clientsWrite4, outsideWrite, + clientsWrite5, outsideWrite0, + clockWrite0, replicasWrite2, + clientsWrite6, outsideWrite1, spinRead, + clockWrite1, replicasWrite3, + clientsWrite7, outsideWrite2, + clientIdRead4, clockRead2, clientIdRead5, + clockRead3, clientIdRead6, clockWrite2, + keyRead0, valueRead, clientIdRead7, + clientIdRead8, clockRead4, + replicasWrite4, replicasWrite5, + clientsRead0, clientsWrite8, + clientsWrite9, clientsWrite10, + outsideWrite3, clockWrite3, + replicasWrite6, clientsWrite11, + outsideWrite4, spinRead0, clockWrite4, + replicasWrite7, clientsWrite12, + outsideWrite5, clientIdRead9, + clientIdRead10, clockWrite5, + replicasWrite8, replicasWrite9, + clientIdRead11, clockRead5, + clientIdRead12, clockRead6, + clientIdRead13, clockWrite6, + clientIdRead14, clientIdRead15, + clockRead7, replicasWrite10, + replicasWrite11, clockWrite7, + replicasWrite12, spinRead1, clockWrite8, + replicasWrite13, kvLocal, liveClients, + pendingRequests, stableMessages, + firstPending, timestamp, nextClient, + chooseMessage, currentClocks, continue_, + pendingClients, msg_, ok, key, val, + spinLocal, continue_G, getReq, getResp, + spinLocal0, continue_P, i, j_, putReq, + putResp, msg_D, j_D, spinLocal1, + continue, j, msg >> + +findMinClient(self) == /\ pc[self] = "findMinClient" + /\ IF (i_[self]) < (Cardinality(pendingClients[self])) + THEN /\ \E client \in pendingClients[self]: + /\ firstPending' = [firstPending EXCEPT ![self] = Head(pendingRequests[self][client])] + /\ Assert((((firstPending'[self]).op) = (GET_MSG)) \/ (((firstPending'[self]).op) = (PUT_MSG)), + "Failure of assertion at line 722, column 37.") + /\ timestamp' = [timestamp EXCEPT ![self] = (firstPending'[self]).timestamp] + /\ IF (timestamp'[self]) < (minClock[self]) + THEN /\ chooseMessage' = [chooseMessage EXCEPT ![self] = ((timestamp'[self]) < (lowestPending[self])) \/ (((timestamp'[self]) = (lowestPending[self])) /\ ((client) < (nextClient[self])))] + /\ IF chooseMessage'[self] + THEN /\ nextClient' = [nextClient EXCEPT ![self] = client] + /\ lowestPending' = [lowestPending EXCEPT ![self] = timestamp'[self]] + ELSE /\ TRUE + /\ UNCHANGED << nextClient, + lowestPending >> + ELSE /\ TRUE + /\ UNCHANGED << nextClient, + lowestPending, + chooseMessage >> + /\ pendingClients' = [pendingClients EXCEPT ![self] = (pendingClients[self]) \ ({client})] + /\ pc' = [pc EXCEPT ![self] = "findMinClient"] + ELSE /\ pc' = [pc EXCEPT ![self] = "addStableMessage"] + /\ UNCHANGED << firstPending, timestamp, + nextClient, lowestPending, + chooseMessage, + pendingClients >> + /\ UNCHANGED << replicasNetwork, allClients, + clientMailboxes, cid, out, clocks, + replicasRead, replicasWrite, kvRead, + clientsWrite, clientsWrite0, kvWrite, + kvWrite0, clientsWrite1, clientsWrite2, + kvWrite1, replicasWrite0, clientsWrite3, + kvWrite2, clientIdRead, clockRead, + clientIdRead0, clockRead0, + clientIdRead1, clockWrite, keyRead, + clientIdRead2, clientIdRead3, + clockRead1, replicasWrite1, clientsRead, + clientsWrite4, outsideWrite, + clientsWrite5, outsideWrite0, + clockWrite0, replicasWrite2, + clientsWrite6, outsideWrite1, spinRead, + clockWrite1, replicasWrite3, + clientsWrite7, outsideWrite2, + clientIdRead4, clockRead2, + clientIdRead5, clockRead3, + clientIdRead6, clockWrite2, keyRead0, + valueRead, clientIdRead7, clientIdRead8, + clockRead4, replicasWrite4, + replicasWrite5, clientsRead0, + clientsWrite8, clientsWrite9, + clientsWrite10, outsideWrite3, + clockWrite3, replicasWrite6, + clientsWrite11, outsideWrite4, + spinRead0, clockWrite4, replicasWrite7, + clientsWrite12, outsideWrite5, + clientIdRead9, clientIdRead10, + clockWrite5, replicasWrite8, + replicasWrite9, clientIdRead11, + clockRead5, clientIdRead12, clockRead6, + clientIdRead13, clockWrite6, + clientIdRead14, clientIdRead15, + clockRead7, replicasWrite10, + replicasWrite11, clockWrite7, + replicasWrite12, spinRead1, clockWrite8, + replicasWrite13, kvLocal, liveClients, + pendingRequests, stableMessages, i_, + currentClocks, minClock, continue_, + clientsIter, msg_, ok, key, val, + spinLocal, continue_G, getReq, getResp, + spinLocal0, continue_P, i, j_, putReq, + putResp, msg_D, j_D, spinLocal1, + continue, j, msg >> + +addStableMessage(self) == /\ pc[self] = "addStableMessage" + /\ IF (lowestPending[self]) < (minClock[self]) + THEN /\ msg_' = [msg_ EXCEPT ![self] = Head(pendingRequests[self][nextClient[self]])] + /\ pendingRequests' = [pendingRequests EXCEPT ![self][nextClient[self]] = Tail(pendingRequests[self][nextClient[self]])] + /\ stableMessages' = [stableMessages EXCEPT ![self] = Append(stableMessages[self], msg_'[self])] + /\ pc' = [pc EXCEPT ![self] = "findStableRequestsLoop"] + /\ UNCHANGED continue_ + ELSE /\ continue_' = [continue_ EXCEPT ![self] = FALSE] + /\ pc' = [pc EXCEPT ![self] = "findStableRequestsLoop"] + /\ UNCHANGED << pendingRequests, + stableMessages, msg_ >> + /\ UNCHANGED << replicasNetwork, allClients, + clientMailboxes, cid, out, clocks, + replicasRead, replicasWrite, kvRead, + clientsWrite, clientsWrite0, kvWrite, + kvWrite0, clientsWrite1, + clientsWrite2, kvWrite1, + replicasWrite0, clientsWrite3, + kvWrite2, clientIdRead, clockRead, + clientIdRead0, clockRead0, + clientIdRead1, clockWrite, keyRead, + clientIdRead2, clientIdRead3, + clockRead1, replicasWrite1, + clientsRead, clientsWrite4, + outsideWrite, clientsWrite5, + outsideWrite0, clockWrite0, + replicasWrite2, clientsWrite6, + outsideWrite1, spinRead, clockWrite1, + replicasWrite3, clientsWrite7, + outsideWrite2, clientIdRead4, + clockRead2, clientIdRead5, + clockRead3, clientIdRead6, + clockWrite2, keyRead0, valueRead, + clientIdRead7, clientIdRead8, + clockRead4, replicasWrite4, + replicasWrite5, clientsRead0, + clientsWrite8, clientsWrite9, + clientsWrite10, outsideWrite3, + clockWrite3, replicasWrite6, + clientsWrite11, outsideWrite4, + spinRead0, clockWrite4, + replicasWrite7, clientsWrite12, + outsideWrite5, clientIdRead9, + clientIdRead10, clockWrite5, + replicasWrite8, replicasWrite9, + clientIdRead11, clockRead5, + clientIdRead12, clockRead6, + clientIdRead13, clockWrite6, + clientIdRead14, clientIdRead15, + clockRead7, replicasWrite10, + replicasWrite11, clockWrite7, + replicasWrite12, spinRead1, + clockWrite8, replicasWrite13, + kvLocal, liveClients, i_, + firstPending, timestamp, nextClient, + lowestPending, chooseMessage, + currentClocks, minClock, + pendingClients, clientsIter, ok, key, + val, spinLocal, continue_G, getReq, + getResp, spinLocal0, continue_P, i, + j_, putReq, putResp, msg_D, j_D, + spinLocal1, continue, j, msg >> + +respondPendingRequestsLoop(self) == /\ pc[self] = "respondPendingRequestsLoop" + /\ IF (i_[self]) <= (Len(stableMessages[self])) + THEN /\ msg_' = [msg_ EXCEPT ![self] = stableMessages[self][i_[self]]] + /\ i_' = [i_ EXCEPT ![self] = (i_[self]) + (1)] + /\ pc' = [pc EXCEPT ![self] = "respondStableGet"] + /\ UNCHANGED << clientMailboxes, + clientsWrite2, + kvWrite1, + kvLocal >> + ELSE /\ clientsWrite2' = clientMailboxes + /\ kvWrite1' = kvLocal[self] + /\ clientMailboxes' = clientsWrite2' + /\ kvLocal' = [kvLocal EXCEPT ![self] = kvWrite1'] + /\ pc' = [pc EXCEPT ![self] = "replicaLoop"] + /\ UNCHANGED << i_, msg_ >> + /\ UNCHANGED << replicasNetwork, + allClients, cid, out, + clocks, replicasRead, + replicasWrite, kvRead, + clientsWrite, + clientsWrite0, kvWrite, + kvWrite0, clientsWrite1, + replicasWrite0, + clientsWrite3, kvWrite2, + clientIdRead, clockRead, + clientIdRead0, clockRead0, + clientIdRead1, clockWrite, + keyRead, clientIdRead2, + clientIdRead3, clockRead1, + replicasWrite1, + clientsRead, clientsWrite4, + outsideWrite, + clientsWrite5, + outsideWrite0, clockWrite0, + replicasWrite2, + clientsWrite6, + outsideWrite1, spinRead, + clockWrite1, + replicasWrite3, + clientsWrite7, + outsideWrite2, + clientIdRead4, clockRead2, + clientIdRead5, clockRead3, + clientIdRead6, clockWrite2, + keyRead0, valueRead, + clientIdRead7, + clientIdRead8, clockRead4, + replicasWrite4, + replicasWrite5, + clientsRead0, + clientsWrite8, + clientsWrite9, + clientsWrite10, + outsideWrite3, clockWrite3, + replicasWrite6, + clientsWrite11, + outsideWrite4, spinRead0, + clockWrite4, + replicasWrite7, + clientsWrite12, + outsideWrite5, + clientIdRead9, + clientIdRead10, + clockWrite5, + replicasWrite8, + replicasWrite9, + clientIdRead11, clockRead5, + clientIdRead12, clockRead6, + clientIdRead13, + clockWrite6, + clientIdRead14, + clientIdRead15, clockRead7, + replicasWrite10, + replicasWrite11, + clockWrite7, + replicasWrite12, spinRead1, + clockWrite8, + replicasWrite13, + liveClients, + pendingRequests, + stableMessages, + firstPending, timestamp, + nextClient, lowestPending, + chooseMessage, + currentClocks, minClock, + continue_, pendingClients, + clientsIter, ok, key, val, + spinLocal, continue_G, + getReq, getResp, + spinLocal0, continue_P, i, + j_, putReq, putResp, msg_D, + j_D, spinLocal1, continue, + j, msg >> + +respondStableGet(self) == /\ pc[self] = "respondStableGet" + /\ IF ((msg_[self]).op) = (GET_MSG) + THEN /\ key' = [key EXCEPT ![self] = (msg_[self]).key] + /\ kvRead' = kvLocal[self][key'[self]] + /\ val' = [val EXCEPT ![self] = kvRead'] + /\ (Len(clientMailboxes[(msg_[self]).reply_to])) < (BUFFER_SIZE) + /\ clientsWrite' = [clientMailboxes EXCEPT ![(msg_[self]).reply_to] = Append(clientMailboxes[(msg_[self]).reply_to], [type |-> GET_RESPONSE, result |-> val'[self]])] + /\ clientsWrite0' = clientsWrite' + /\ clientMailboxes' = clientsWrite0' + ELSE /\ clientsWrite0' = clientMailboxes + /\ clientMailboxes' = clientsWrite0' + /\ UNCHANGED << kvRead, clientsWrite, key, + val >> + /\ pc' = [pc EXCEPT ![self] = "respondStablePut"] + /\ UNCHANGED << replicasNetwork, allClients, cid, + out, clocks, replicasRead, + replicasWrite, kvWrite, kvWrite0, + clientsWrite1, clientsWrite2, + kvWrite1, replicasWrite0, + clientsWrite3, kvWrite2, + clientIdRead, clockRead, + clientIdRead0, clockRead0, + clientIdRead1, clockWrite, keyRead, + clientIdRead2, clientIdRead3, + clockRead1, replicasWrite1, + clientsRead, clientsWrite4, + outsideWrite, clientsWrite5, + outsideWrite0, clockWrite0, + replicasWrite2, clientsWrite6, + outsideWrite1, spinRead, clockWrite1, + replicasWrite3, clientsWrite7, + outsideWrite2, clientIdRead4, + clockRead2, clientIdRead5, + clockRead3, clientIdRead6, + clockWrite2, keyRead0, valueRead, + clientIdRead7, clientIdRead8, + clockRead4, replicasWrite4, + replicasWrite5, clientsRead0, + clientsWrite8, clientsWrite9, + clientsWrite10, outsideWrite3, + clockWrite3, replicasWrite6, + clientsWrite11, outsideWrite4, + spinRead0, clockWrite4, + replicasWrite7, clientsWrite12, + outsideWrite5, clientIdRead9, + clientIdRead10, clockWrite5, + replicasWrite8, replicasWrite9, + clientIdRead11, clockRead5, + clientIdRead12, clockRead6, + clientIdRead13, clockWrite6, + clientIdRead14, clientIdRead15, + clockRead7, replicasWrite10, + replicasWrite11, clockWrite7, + replicasWrite12, spinRead1, + clockWrite8, replicasWrite13, + kvLocal, liveClients, + pendingRequests, stableMessages, i_, + firstPending, timestamp, nextClient, + lowestPending, chooseMessage, + currentClocks, minClock, continue_, + pendingClients, clientsIter, msg_, + ok, spinLocal, continue_G, getReq, + getResp, spinLocal0, continue_P, i, + j_, putReq, putResp, msg_D, j_D, + spinLocal1, continue, j, msg >> + +respondStablePut(self) == /\ pc[self] = "respondStablePut" + /\ IF ((msg_[self]).op) = (PUT_MSG) + THEN /\ key' = [key EXCEPT ![self] = (msg_[self]).key] + /\ val' = [val EXCEPT ![self] = (msg_[self]).value] + /\ kvWrite' = [kvLocal[self] EXCEPT ![key'[self]] = val'[self]] + /\ (Len(clientMailboxes[(msg_[self]).reply_to])) < (BUFFER_SIZE) + /\ clientsWrite' = [clientMailboxes EXCEPT ![(msg_[self]).reply_to] = Append(clientMailboxes[(msg_[self]).reply_to], [type |-> PUT_RESPONSE, result |-> ok[self]])] + /\ kvWrite0' = kvWrite' + /\ clientsWrite1' = clientsWrite' + /\ clientMailboxes' = clientsWrite1' + /\ kvLocal' = [kvLocal EXCEPT ![self] = kvWrite0'] + /\ pc' = [pc EXCEPT ![self] = "respondPendingRequestsLoop"] + ELSE /\ kvWrite0' = kvLocal[self] + /\ clientsWrite1' = clientMailboxes + /\ clientMailboxes' = clientsWrite1' + /\ kvLocal' = [kvLocal EXCEPT ![self] = kvWrite0'] + /\ pc' = [pc EXCEPT ![self] = "respondPendingRequestsLoop"] + /\ UNCHANGED << clientsWrite, kvWrite, + key, val >> + /\ UNCHANGED << replicasNetwork, allClients, cid, + out, clocks, replicasRead, + replicasWrite, kvRead, clientsWrite0, + clientsWrite2, kvWrite1, + replicasWrite0, clientsWrite3, + kvWrite2, clientIdRead, clockRead, + clientIdRead0, clockRead0, + clientIdRead1, clockWrite, keyRead, + clientIdRead2, clientIdRead3, + clockRead1, replicasWrite1, + clientsRead, clientsWrite4, + outsideWrite, clientsWrite5, + outsideWrite0, clockWrite0, + replicasWrite2, clientsWrite6, + outsideWrite1, spinRead, clockWrite1, + replicasWrite3, clientsWrite7, + outsideWrite2, clientIdRead4, + clockRead2, clientIdRead5, + clockRead3, clientIdRead6, + clockWrite2, keyRead0, valueRead, + clientIdRead7, clientIdRead8, + clockRead4, replicasWrite4, + replicasWrite5, clientsRead0, + clientsWrite8, clientsWrite9, + clientsWrite10, outsideWrite3, + clockWrite3, replicasWrite6, + clientsWrite11, outsideWrite4, + spinRead0, clockWrite4, + replicasWrite7, clientsWrite12, + outsideWrite5, clientIdRead9, + clientIdRead10, clockWrite5, + replicasWrite8, replicasWrite9, + clientIdRead11, clockRead5, + clientIdRead12, clockRead6, + clientIdRead13, clockWrite6, + clientIdRead14, clientIdRead15, + clockRead7, replicasWrite10, + replicasWrite11, clockWrite7, + replicasWrite12, spinRead1, + clockWrite8, replicasWrite13, + liveClients, pendingRequests, + stableMessages, i_, firstPending, + timestamp, nextClient, lowestPending, + chooseMessage, currentClocks, + minClock, continue_, pendingClients, + clientsIter, msg_, ok, spinLocal, + continue_G, getReq, getResp, + spinLocal0, continue_P, i, j_, + putReq, putResp, msg_D, j_D, + spinLocal1, continue, j, msg >> + +Replica(self) == replicaLoop(self) \/ receiveClientRequest(self) + \/ clientDisconnected(self) \/ replicaGetRequest(self) + \/ replicaPutRequest(self) \/ replicaNullRequest(self) + \/ findStableRequestsLoop(self) \/ findMinClock(self) + \/ findMinClient(self) \/ addStableMessage(self) + \/ respondPendingRequestsLoop(self) + \/ respondStableGet(self) \/ respondStablePut(self) + +getLoop(self) == /\ pc[self] = "getLoop" + /\ IF continue_G[self] + THEN /\ pc' = [pc EXCEPT ![self] = "getRequest"] + /\ UNCHANGED << replicasNetwork, clientMailboxes, + out, clocks, clockWrite1, + replicasWrite3, clientsWrite7, + outsideWrite2 >> + ELSE /\ clockWrite1' = clocks + /\ replicasWrite3' = replicasNetwork + /\ clientsWrite7' = clientMailboxes + /\ outsideWrite2' = out + /\ replicasNetwork' = replicasWrite3' + /\ clientMailboxes' = clientsWrite7' + /\ clocks' = clockWrite1' + /\ out' = outsideWrite2' + /\ pc' = [pc EXCEPT ![self] = "Done"] + /\ UNCHANGED << allClients, cid, replicasRead, replicasWrite, + kvRead, clientsWrite, clientsWrite0, kvWrite, + kvWrite0, clientsWrite1, clientsWrite2, + kvWrite1, replicasWrite0, clientsWrite3, + kvWrite2, clientIdRead, clockRead, + clientIdRead0, clockRead0, clientIdRead1, + clockWrite, keyRead, clientIdRead2, + clientIdRead3, clockRead1, replicasWrite1, + clientsRead, clientsWrite4, outsideWrite, + clientsWrite5, outsideWrite0, clockWrite0, + replicasWrite2, clientsWrite6, outsideWrite1, + spinRead, clientIdRead4, clockRead2, + clientIdRead5, clockRead3, clientIdRead6, + clockWrite2, keyRead0, valueRead, + clientIdRead7, clientIdRead8, clockRead4, + replicasWrite4, replicasWrite5, clientsRead0, + clientsWrite8, clientsWrite9, clientsWrite10, + outsideWrite3, clockWrite3, replicasWrite6, + clientsWrite11, outsideWrite4, spinRead0, + clockWrite4, replicasWrite7, clientsWrite12, + outsideWrite5, clientIdRead9, clientIdRead10, + clockWrite5, replicasWrite8, replicasWrite9, + clientIdRead11, clockRead5, clientIdRead12, + clockRead6, clientIdRead13, clockWrite6, + clientIdRead14, clientIdRead15, clockRead7, + replicasWrite10, replicasWrite11, clockWrite7, + replicasWrite12, spinRead1, clockWrite8, + replicasWrite13, kvLocal, liveClients, + pendingRequests, stableMessages, i_, + firstPending, timestamp, nextClient, + lowestPending, chooseMessage, currentClocks, + minClock, continue_, pendingClients, + clientsIter, msg_, ok, key, val, spinLocal, + continue_G, getReq, getResp, spinLocal0, + continue_P, i, j_, putReq, putResp, msg_D, + j_D, spinLocal1, continue, j, msg >> + +getRequest(self) == /\ pc[self] = "getRequest" + /\ clientIdRead' = (self) - ((NUM_CLIENTS) * (GET_ORDER)) + /\ clockRead' = clocks[clientIdRead'] + /\ IF (clockRead') = (-(1)) + THEN /\ continue_G' = [continue_G EXCEPT ![self] = FALSE] + /\ clockWrite0' = clocks + /\ replicasWrite2' = replicasNetwork + /\ clientsWrite6' = clientMailboxes + /\ outsideWrite1' = out + /\ replicasNetwork' = replicasWrite2' + /\ clientMailboxes' = clientsWrite6' + /\ clocks' = clockWrite0' + /\ out' = outsideWrite1' + /\ pc' = [pc EXCEPT ![self] = "getCheckSpin"] + /\ UNCHANGED << clientIdRead0, clockRead0, + clientIdRead1, clockWrite, + keyRead, clientIdRead2, + clientIdRead3, clockRead1, + replicasWrite1, getReq >> + ELSE /\ clientIdRead0' = (self) - ((NUM_CLIENTS) * (GET_ORDER)) + /\ clockRead0' = clocks[clientIdRead0'] + /\ clientIdRead1' = (self) - ((NUM_CLIENTS) * (GET_ORDER)) + /\ clockWrite' = [clocks EXCEPT ![clientIdRead1'] = (clockRead0') + (1)] + /\ keyRead' = GET_KEY + /\ clientIdRead2' = (self) - ((NUM_CLIENTS) * (GET_ORDER)) + /\ clientIdRead3' = (self) - ((NUM_CLIENTS) * (GET_ORDER)) + /\ clockRead1' = clockWrite'[clientIdRead3'] + /\ getReq' = [getReq EXCEPT ![self] = [op |-> GET_MSG, key |-> keyRead', client |-> clientIdRead2', timestamp |-> clockRead1', reply_to |-> self]] + /\ \E dst \in ReplicaSet: + /\ (Len(replicasNetwork[dst])) < (BUFFER_SIZE) + /\ replicasWrite1' = [replicasNetwork EXCEPT ![dst] = Append(replicasNetwork[dst], getReq'[self])] + /\ replicasNetwork' = replicasWrite1' + /\ clocks' = clockWrite' + /\ pc' = [pc EXCEPT ![self] = "getReply"] + /\ UNCHANGED << clientMailboxes, out, + clockWrite0, replicasWrite2, + clientsWrite6, outsideWrite1, + continue_G >> + /\ UNCHANGED << allClients, cid, replicasRead, + replicasWrite, kvRead, clientsWrite, + clientsWrite0, kvWrite, kvWrite0, + clientsWrite1, clientsWrite2, kvWrite1, + replicasWrite0, clientsWrite3, kvWrite2, + clientsRead, clientsWrite4, outsideWrite, + clientsWrite5, outsideWrite0, spinRead, + clockWrite1, replicasWrite3, clientsWrite7, + outsideWrite2, clientIdRead4, clockRead2, + clientIdRead5, clockRead3, clientIdRead6, + clockWrite2, keyRead0, valueRead, + clientIdRead7, clientIdRead8, clockRead4, + replicasWrite4, replicasWrite5, + clientsRead0, clientsWrite8, clientsWrite9, + clientsWrite10, outsideWrite3, clockWrite3, + replicasWrite6, clientsWrite11, + outsideWrite4, spinRead0, clockWrite4, + replicasWrite7, clientsWrite12, + outsideWrite5, clientIdRead9, + clientIdRead10, clockWrite5, + replicasWrite8, replicasWrite9, + clientIdRead11, clockRead5, clientIdRead12, + clockRead6, clientIdRead13, clockWrite6, + clientIdRead14, clientIdRead15, clockRead7, + replicasWrite10, replicasWrite11, + clockWrite7, replicasWrite12, spinRead1, + clockWrite8, replicasWrite13, kvLocal, + liveClients, pendingRequests, + stableMessages, i_, firstPending, + timestamp, nextClient, lowestPending, + chooseMessage, currentClocks, minClock, + continue_, pendingClients, clientsIter, + msg_, ok, key, val, spinLocal, getResp, + spinLocal0, continue_P, i, j_, putReq, + putResp, msg_D, j_D, spinLocal1, continue, + j, msg >> + +getReply(self) == /\ pc[self] = "getReply" + /\ clientIdRead' = (self) - ((NUM_CLIENTS) * (GET_ORDER)) + /\ clockRead' = clocks[clientIdRead'] + /\ IF (clockRead') = (-(1)) + THEN /\ continue_G' = [continue_G EXCEPT ![self] = FALSE] + /\ clientsWrite5' = clientMailboxes + /\ outsideWrite0' = out + /\ clientMailboxes' = clientsWrite5' + /\ out' = outsideWrite0' + /\ UNCHANGED << clientsRead, clientsWrite4, + outsideWrite, getResp >> + ELSE /\ (Len(clientMailboxes[self])) > (0) + /\ LET msg1 == Head(clientMailboxes[self]) IN + /\ clientsWrite4' = [clientMailboxes EXCEPT ![self] = Tail(clientMailboxes[self])] + /\ clientsRead' = msg1 + /\ getResp' = [getResp EXCEPT ![self] = clientsRead'] + /\ Assert(((getResp'[self]).type) = (GET_RESPONSE), + "Failure of assertion at line 857, column 33.") + /\ outsideWrite' = (getResp'[self]).result + /\ clientsWrite5' = clientsWrite4' + /\ outsideWrite0' = outsideWrite' + /\ clientMailboxes' = clientsWrite5' + /\ out' = outsideWrite0' + /\ UNCHANGED continue_G + /\ pc' = [pc EXCEPT ![self] = "getCheckSpin"] + /\ UNCHANGED << replicasNetwork, allClients, cid, clocks, + replicasRead, replicasWrite, kvRead, + clientsWrite, clientsWrite0, kvWrite, + kvWrite0, clientsWrite1, clientsWrite2, + kvWrite1, replicasWrite0, clientsWrite3, + kvWrite2, clientIdRead0, clockRead0, + clientIdRead1, clockWrite, keyRead, + clientIdRead2, clientIdRead3, clockRead1, + replicasWrite1, clockWrite0, replicasWrite2, + clientsWrite6, outsideWrite1, spinRead, + clockWrite1, replicasWrite3, clientsWrite7, + outsideWrite2, clientIdRead4, clockRead2, + clientIdRead5, clockRead3, clientIdRead6, + clockWrite2, keyRead0, valueRead, + clientIdRead7, clientIdRead8, clockRead4, + replicasWrite4, replicasWrite5, clientsRead0, + clientsWrite8, clientsWrite9, clientsWrite10, + outsideWrite3, clockWrite3, replicasWrite6, + clientsWrite11, outsideWrite4, spinRead0, + clockWrite4, replicasWrite7, clientsWrite12, + outsideWrite5, clientIdRead9, clientIdRead10, + clockWrite5, replicasWrite8, replicasWrite9, + clientIdRead11, clockRead5, clientIdRead12, + clockRead6, clientIdRead13, clockWrite6, + clientIdRead14, clientIdRead15, clockRead7, + replicasWrite10, replicasWrite11, + clockWrite7, replicasWrite12, spinRead1, + clockWrite8, replicasWrite13, kvLocal, + liveClients, pendingRequests, stableMessages, + i_, firstPending, timestamp, nextClient, + lowestPending, chooseMessage, currentClocks, + minClock, continue_, pendingClients, + clientsIter, msg_, ok, key, val, spinLocal, + getReq, spinLocal0, continue_P, i, j_, + putReq, putResp, msg_D, j_D, spinLocal1, + continue, j, msg >> + +getCheckSpin(self) == /\ pc[self] = "getCheckSpin" + /\ spinRead' = spinLocal[self] + /\ IF ~(spinRead') + THEN /\ continue_G' = [continue_G EXCEPT ![self] = FALSE] + /\ pc' = [pc EXCEPT ![self] = "getLoop"] + ELSE /\ pc' = [pc EXCEPT ![self] = "getLoop"] + /\ UNCHANGED continue_G + /\ UNCHANGED << replicasNetwork, allClients, + clientMailboxes, cid, out, clocks, + replicasRead, replicasWrite, kvRead, + clientsWrite, clientsWrite0, kvWrite, + kvWrite0, clientsWrite1, clientsWrite2, + kvWrite1, replicasWrite0, clientsWrite3, + kvWrite2, clientIdRead, clockRead, + clientIdRead0, clockRead0, clientIdRead1, + clockWrite, keyRead, clientIdRead2, + clientIdRead3, clockRead1, + replicasWrite1, clientsRead, + clientsWrite4, outsideWrite, + clientsWrite5, outsideWrite0, + clockWrite0, replicasWrite2, + clientsWrite6, outsideWrite1, + clockWrite1, replicasWrite3, + clientsWrite7, outsideWrite2, + clientIdRead4, clockRead2, clientIdRead5, + clockRead3, clientIdRead6, clockWrite2, + keyRead0, valueRead, clientIdRead7, + clientIdRead8, clockRead4, + replicasWrite4, replicasWrite5, + clientsRead0, clientsWrite8, + clientsWrite9, clientsWrite10, + outsideWrite3, clockWrite3, + replicasWrite6, clientsWrite11, + outsideWrite4, spinRead0, clockWrite4, + replicasWrite7, clientsWrite12, + outsideWrite5, clientIdRead9, + clientIdRead10, clockWrite5, + replicasWrite8, replicasWrite9, + clientIdRead11, clockRead5, + clientIdRead12, clockRead6, + clientIdRead13, clockWrite6, + clientIdRead14, clientIdRead15, + clockRead7, replicasWrite10, + replicasWrite11, clockWrite7, + replicasWrite12, spinRead1, clockWrite8, + replicasWrite13, kvLocal, liveClients, + pendingRequests, stableMessages, i_, + firstPending, timestamp, nextClient, + lowestPending, chooseMessage, + currentClocks, minClock, continue_, + pendingClients, clientsIter, msg_, ok, + key, val, spinLocal, getReq, getResp, + spinLocal0, continue_P, i, j_, putReq, + putResp, msg_D, j_D, spinLocal1, + continue, j, msg >> + +GetClient(self) == getLoop(self) \/ getRequest(self) \/ getReply(self) + \/ getCheckSpin(self) + +putLoop(self) == /\ pc[self] = "putLoop" + /\ IF continue_P[self] + THEN /\ pc' = [pc EXCEPT ![self] = "putRequest"] + /\ UNCHANGED << replicasNetwork, clientMailboxes, + out, clocks, clockWrite4, + replicasWrite7, clientsWrite12, + outsideWrite5 >> + ELSE /\ clockWrite4' = clocks + /\ replicasWrite7' = replicasNetwork + /\ clientsWrite12' = clientMailboxes + /\ outsideWrite5' = out + /\ replicasNetwork' = replicasWrite7' + /\ clientMailboxes' = clientsWrite12' + /\ clocks' = clockWrite4' + /\ out' = outsideWrite5' + /\ pc' = [pc EXCEPT ![self] = "Done"] + /\ UNCHANGED << allClients, cid, replicasRead, replicasWrite, + kvRead, clientsWrite, clientsWrite0, kvWrite, + kvWrite0, clientsWrite1, clientsWrite2, + kvWrite1, replicasWrite0, clientsWrite3, + kvWrite2, clientIdRead, clockRead, + clientIdRead0, clockRead0, clientIdRead1, + clockWrite, keyRead, clientIdRead2, + clientIdRead3, clockRead1, replicasWrite1, + clientsRead, clientsWrite4, outsideWrite, + clientsWrite5, outsideWrite0, clockWrite0, + replicasWrite2, clientsWrite6, outsideWrite1, + spinRead, clockWrite1, replicasWrite3, + clientsWrite7, outsideWrite2, clientIdRead4, + clockRead2, clientIdRead5, clockRead3, + clientIdRead6, clockWrite2, keyRead0, + valueRead, clientIdRead7, clientIdRead8, + clockRead4, replicasWrite4, replicasWrite5, + clientsRead0, clientsWrite8, clientsWrite9, + clientsWrite10, outsideWrite3, clockWrite3, + replicasWrite6, clientsWrite11, outsideWrite4, + spinRead0, clientIdRead9, clientIdRead10, + clockWrite5, replicasWrite8, replicasWrite9, + clientIdRead11, clockRead5, clientIdRead12, + clockRead6, clientIdRead13, clockWrite6, + clientIdRead14, clientIdRead15, clockRead7, + replicasWrite10, replicasWrite11, clockWrite7, + replicasWrite12, spinRead1, clockWrite8, + replicasWrite13, kvLocal, liveClients, + pendingRequests, stableMessages, i_, + firstPending, timestamp, nextClient, + lowestPending, chooseMessage, currentClocks, + minClock, continue_, pendingClients, + clientsIter, msg_, ok, key, val, spinLocal, + continue_G, getReq, getResp, spinLocal0, + continue_P, i, j_, putReq, putResp, msg_D, + j_D, spinLocal1, continue, j, msg >> + +putRequest(self) == /\ pc[self] = "putRequest" + /\ clientIdRead4' = (self) - ((NUM_CLIENTS) * (PUT_ORDER)) + /\ clockRead2' = clocks[clientIdRead4'] + /\ IF (clockRead2') = (-(1)) + THEN /\ continue_P' = [continue_P EXCEPT ![self] = FALSE] + /\ clockWrite3' = clocks + /\ replicasWrite6' = replicasNetwork + /\ clientsWrite11' = clientMailboxes + /\ outsideWrite4' = out + /\ replicasNetwork' = replicasWrite6' + /\ clientMailboxes' = clientsWrite11' + /\ clocks' = clockWrite3' + /\ out' = outsideWrite4' + /\ pc' = [pc EXCEPT ![self] = "putCheckSpin"] + /\ UNCHANGED << clientIdRead5, clockRead3, + clientIdRead6, clockWrite2, + keyRead0, valueRead, + clientIdRead7, clientIdRead8, + clockRead4, i, j_, putReq >> + ELSE /\ clientIdRead5' = (self) - ((NUM_CLIENTS) * (PUT_ORDER)) + /\ clockRead3' = clocks[clientIdRead5'] + /\ clientIdRead6' = (self) - ((NUM_CLIENTS) * (PUT_ORDER)) + /\ clockWrite2' = [clocks EXCEPT ![clientIdRead6'] = (clockRead3') + (1)] + /\ keyRead0' = PUT_KEY + /\ valueRead' = PUT_VALUE + /\ clientIdRead7' = (self) - ((NUM_CLIENTS) * (PUT_ORDER)) + /\ clientIdRead8' = (self) - ((NUM_CLIENTS) * (PUT_ORDER)) + /\ clockRead4' = clockWrite2'[clientIdRead8'] + /\ putReq' = [putReq EXCEPT ![self] = [op |-> PUT_MSG, key |-> keyRead0', value |-> valueRead', client |-> clientIdRead7', timestamp |-> clockRead4', reply_to |-> self]] + /\ i' = [i EXCEPT ![self] = 0] + /\ j_' = [j_ EXCEPT ![self] = 0] + /\ clocks' = clockWrite2' + /\ pc' = [pc EXCEPT ![self] = "putBroadcast"] + /\ UNCHANGED << replicasNetwork, + clientMailboxes, out, + clockWrite3, replicasWrite6, + clientsWrite11, outsideWrite4, + continue_P >> + /\ UNCHANGED << allClients, cid, replicasRead, + replicasWrite, kvRead, clientsWrite, + clientsWrite0, kvWrite, kvWrite0, + clientsWrite1, clientsWrite2, kvWrite1, + replicasWrite0, clientsWrite3, kvWrite2, + clientIdRead, clockRead, clientIdRead0, + clockRead0, clientIdRead1, clockWrite, + keyRead, clientIdRead2, clientIdRead3, + clockRead1, replicasWrite1, clientsRead, + clientsWrite4, outsideWrite, clientsWrite5, + outsideWrite0, clockWrite0, replicasWrite2, + clientsWrite6, outsideWrite1, spinRead, + clockWrite1, replicasWrite3, clientsWrite7, + outsideWrite2, replicasWrite4, + replicasWrite5, clientsRead0, + clientsWrite8, clientsWrite9, + clientsWrite10, outsideWrite3, spinRead0, + clockWrite4, replicasWrite7, + clientsWrite12, outsideWrite5, + clientIdRead9, clientIdRead10, clockWrite5, + replicasWrite8, replicasWrite9, + clientIdRead11, clockRead5, clientIdRead12, + clockRead6, clientIdRead13, clockWrite6, + clientIdRead14, clientIdRead15, clockRead7, + replicasWrite10, replicasWrite11, + clockWrite7, replicasWrite12, spinRead1, + clockWrite8, replicasWrite13, kvLocal, + liveClients, pendingRequests, + stableMessages, i_, firstPending, + timestamp, nextClient, lowestPending, + chooseMessage, currentClocks, minClock, + continue_, pendingClients, clientsIter, + msg_, ok, key, val, spinLocal, continue_G, + getReq, getResp, spinLocal0, putResp, + msg_D, j_D, spinLocal1, continue, j, msg >> + +putBroadcast(self) == /\ pc[self] = "putBroadcast" + /\ clientIdRead4' = (self) - ((NUM_CLIENTS) * (PUT_ORDER)) + /\ clockRead2' = clocks[clientIdRead4'] + /\ IF ((j_[self]) <= ((NUM_REPLICAS) - (1))) /\ ((clockRead2') # (-(1))) + THEN /\ (Len(replicasNetwork[j_[self]])) < (BUFFER_SIZE) + /\ replicasWrite4' = [replicasNetwork EXCEPT ![j_[self]] = Append(replicasNetwork[j_[self]], putReq[self])] + /\ j_' = [j_ EXCEPT ![self] = (j_[self]) + (1)] + /\ replicasWrite5' = replicasWrite4' + /\ replicasNetwork' = replicasWrite5' + /\ pc' = [pc EXCEPT ![self] = "putBroadcast"] + ELSE /\ replicasWrite5' = replicasNetwork + /\ replicasNetwork' = replicasWrite5' + /\ pc' = [pc EXCEPT ![self] = "putResponse"] + /\ UNCHANGED << replicasWrite4, j_ >> + /\ UNCHANGED << allClients, clientMailboxes, cid, out, + clocks, replicasRead, replicasWrite, + kvRead, clientsWrite, clientsWrite0, + kvWrite, kvWrite0, clientsWrite1, + clientsWrite2, kvWrite1, replicasWrite0, + clientsWrite3, kvWrite2, clientIdRead, + clockRead, clientIdRead0, clockRead0, + clientIdRead1, clockWrite, keyRead, + clientIdRead2, clientIdRead3, clockRead1, + replicasWrite1, clientsRead, + clientsWrite4, outsideWrite, + clientsWrite5, outsideWrite0, + clockWrite0, replicasWrite2, + clientsWrite6, outsideWrite1, spinRead, + clockWrite1, replicasWrite3, + clientsWrite7, outsideWrite2, + clientIdRead5, clockRead3, clientIdRead6, + clockWrite2, keyRead0, valueRead, + clientIdRead7, clientIdRead8, clockRead4, + clientsRead0, clientsWrite8, + clientsWrite9, clientsWrite10, + outsideWrite3, clockWrite3, + replicasWrite6, clientsWrite11, + outsideWrite4, spinRead0, clockWrite4, + replicasWrite7, clientsWrite12, + outsideWrite5, clientIdRead9, + clientIdRead10, clockWrite5, + replicasWrite8, replicasWrite9, + clientIdRead11, clockRead5, + clientIdRead12, clockRead6, + clientIdRead13, clockWrite6, + clientIdRead14, clientIdRead15, + clockRead7, replicasWrite10, + replicasWrite11, clockWrite7, + replicasWrite12, spinRead1, clockWrite8, + replicasWrite13, kvLocal, liveClients, + pendingRequests, stableMessages, i_, + firstPending, timestamp, nextClient, + lowestPending, chooseMessage, + currentClocks, minClock, continue_, + pendingClients, clientsIter, msg_, ok, + key, val, spinLocal, continue_G, getReq, + getResp, spinLocal0, continue_P, i, + putReq, putResp, msg_D, j_D, spinLocal1, + continue, j, msg >> + +putResponse(self) == /\ pc[self] = "putResponse" + /\ IF (i[self]) < (Cardinality(ReplicaSet)) + THEN /\ clientIdRead4' = (self) - ((NUM_CLIENTS) * (PUT_ORDER)) + /\ clockRead2' = clocks[clientIdRead4'] + /\ IF (clockRead2') = (-(1)) + THEN /\ continue_P' = [continue_P EXCEPT ![self] = FALSE] + /\ clientsWrite9' = clientMailboxes + /\ clientsWrite10' = clientsWrite9' + /\ clientMailboxes' = clientsWrite10' + /\ pc' = [pc EXCEPT ![self] = "putLoop"] + /\ UNCHANGED << clientsRead0, + clientsWrite8, i, + putResp >> + ELSE /\ (Len(clientMailboxes[self])) > (0) + /\ LET msg2 == Head(clientMailboxes[self]) IN + /\ clientsWrite8' = [clientMailboxes EXCEPT ![self] = Tail(clientMailboxes[self])] + /\ clientsRead0' = msg2 + /\ putResp' = [putResp EXCEPT ![self] = clientsRead0'] + /\ Assert(((putResp'[self]).type) = (PUT_RESPONSE), + "Failure of assertion at line 952, column 37.") + /\ i' = [i EXCEPT ![self] = (i[self]) + (1)] + /\ clientsWrite9' = clientsWrite8' + /\ clientsWrite10' = clientsWrite9' + /\ clientMailboxes' = clientsWrite10' + /\ pc' = [pc EXCEPT ![self] = "putResponse"] + /\ UNCHANGED continue_P + ELSE /\ clientsWrite10' = clientMailboxes + /\ clientMailboxes' = clientsWrite10' + /\ pc' = [pc EXCEPT ![self] = "putComplete"] + /\ UNCHANGED << clientIdRead4, clockRead2, + clientsRead0, clientsWrite8, + clientsWrite9, continue_P, i, + putResp >> + /\ UNCHANGED << replicasNetwork, allClients, cid, out, + clocks, replicasRead, replicasWrite, + kvRead, clientsWrite, clientsWrite0, + kvWrite, kvWrite0, clientsWrite1, + clientsWrite2, kvWrite1, replicasWrite0, + clientsWrite3, kvWrite2, clientIdRead, + clockRead, clientIdRead0, clockRead0, + clientIdRead1, clockWrite, keyRead, + clientIdRead2, clientIdRead3, clockRead1, + replicasWrite1, clientsRead, + clientsWrite4, outsideWrite, + clientsWrite5, outsideWrite0, clockWrite0, + replicasWrite2, clientsWrite6, + outsideWrite1, spinRead, clockWrite1, + replicasWrite3, clientsWrite7, + outsideWrite2, clientIdRead5, clockRead3, + clientIdRead6, clockWrite2, keyRead0, + valueRead, clientIdRead7, clientIdRead8, + clockRead4, replicasWrite4, + replicasWrite5, outsideWrite3, + clockWrite3, replicasWrite6, + clientsWrite11, outsideWrite4, spinRead0, + clockWrite4, replicasWrite7, + clientsWrite12, outsideWrite5, + clientIdRead9, clientIdRead10, + clockWrite5, replicasWrite8, + replicasWrite9, clientIdRead11, + clockRead5, clientIdRead12, clockRead6, + clientIdRead13, clockWrite6, + clientIdRead14, clientIdRead15, + clockRead7, replicasWrite10, + replicasWrite11, clockWrite7, + replicasWrite12, spinRead1, clockWrite8, + replicasWrite13, kvLocal, liveClients, + pendingRequests, stableMessages, i_, + firstPending, timestamp, nextClient, + lowestPending, chooseMessage, + currentClocks, minClock, continue_, + pendingClients, clientsIter, msg_, ok, + key, val, spinLocal, continue_G, getReq, + getResp, spinLocal0, j_, putReq, msg_D, + j_D, spinLocal1, continue, j, msg >> + +putComplete(self) == /\ pc[self] = "putComplete" + /\ outsideWrite3' = PUT_RESPONSE + /\ out' = outsideWrite3' + /\ pc' = [pc EXCEPT ![self] = "putCheckSpin"] + /\ UNCHANGED << replicasNetwork, allClients, + clientMailboxes, cid, clocks, + replicasRead, replicasWrite, kvRead, + clientsWrite, clientsWrite0, kvWrite, + kvWrite0, clientsWrite1, clientsWrite2, + kvWrite1, replicasWrite0, clientsWrite3, + kvWrite2, clientIdRead, clockRead, + clientIdRead0, clockRead0, clientIdRead1, + clockWrite, keyRead, clientIdRead2, + clientIdRead3, clockRead1, replicasWrite1, + clientsRead, clientsWrite4, outsideWrite, + clientsWrite5, outsideWrite0, clockWrite0, + replicasWrite2, clientsWrite6, + outsideWrite1, spinRead, clockWrite1, + replicasWrite3, clientsWrite7, + outsideWrite2, clientIdRead4, clockRead2, + clientIdRead5, clockRead3, clientIdRead6, + clockWrite2, keyRead0, valueRead, + clientIdRead7, clientIdRead8, clockRead4, + replicasWrite4, replicasWrite5, + clientsRead0, clientsWrite8, + clientsWrite9, clientsWrite10, + clockWrite3, replicasWrite6, + clientsWrite11, outsideWrite4, spinRead0, + clockWrite4, replicasWrite7, + clientsWrite12, outsideWrite5, + clientIdRead9, clientIdRead10, + clockWrite5, replicasWrite8, + replicasWrite9, clientIdRead11, + clockRead5, clientIdRead12, clockRead6, + clientIdRead13, clockWrite6, + clientIdRead14, clientIdRead15, + clockRead7, replicasWrite10, + replicasWrite11, clockWrite7, + replicasWrite12, spinRead1, clockWrite8, + replicasWrite13, kvLocal, liveClients, + pendingRequests, stableMessages, i_, + firstPending, timestamp, nextClient, + lowestPending, chooseMessage, + currentClocks, minClock, continue_, + pendingClients, clientsIter, msg_, ok, + key, val, spinLocal, continue_G, getReq, + getResp, spinLocal0, continue_P, i, j_, + putReq, putResp, msg_D, j_D, spinLocal1, + continue, j, msg >> + +putCheckSpin(self) == /\ pc[self] = "putCheckSpin" + /\ spinRead0' = spinLocal0[self] + /\ IF ~(spinRead0') + THEN /\ continue_P' = [continue_P EXCEPT ![self] = FALSE] + /\ pc' = [pc EXCEPT ![self] = "putLoop"] + ELSE /\ pc' = [pc EXCEPT ![self] = "putLoop"] + /\ UNCHANGED continue_P + /\ UNCHANGED << replicasNetwork, allClients, + clientMailboxes, cid, out, clocks, + replicasRead, replicasWrite, kvRead, + clientsWrite, clientsWrite0, kvWrite, + kvWrite0, clientsWrite1, clientsWrite2, + kvWrite1, replicasWrite0, clientsWrite3, + kvWrite2, clientIdRead, clockRead, + clientIdRead0, clockRead0, clientIdRead1, + clockWrite, keyRead, clientIdRead2, + clientIdRead3, clockRead1, + replicasWrite1, clientsRead, + clientsWrite4, outsideWrite, + clientsWrite5, outsideWrite0, + clockWrite0, replicasWrite2, + clientsWrite6, outsideWrite1, spinRead, + clockWrite1, replicasWrite3, + clientsWrite7, outsideWrite2, + clientIdRead4, clockRead2, clientIdRead5, + clockRead3, clientIdRead6, clockWrite2, + keyRead0, valueRead, clientIdRead7, + clientIdRead8, clockRead4, + replicasWrite4, replicasWrite5, + clientsRead0, clientsWrite8, + clientsWrite9, clientsWrite10, + outsideWrite3, clockWrite3, + replicasWrite6, clientsWrite11, + outsideWrite4, clockWrite4, + replicasWrite7, clientsWrite12, + outsideWrite5, clientIdRead9, + clientIdRead10, clockWrite5, + replicasWrite8, replicasWrite9, + clientIdRead11, clockRead5, + clientIdRead12, clockRead6, + clientIdRead13, clockWrite6, + clientIdRead14, clientIdRead15, + clockRead7, replicasWrite10, + replicasWrite11, clockWrite7, + replicasWrite12, spinRead1, clockWrite8, + replicasWrite13, kvLocal, liveClients, + pendingRequests, stableMessages, i_, + firstPending, timestamp, nextClient, + lowestPending, chooseMessage, + currentClocks, minClock, continue_, + pendingClients, clientsIter, msg_, ok, + key, val, spinLocal, continue_G, getReq, + getResp, spinLocal0, i, j_, putReq, + putResp, msg_D, j_D, spinLocal1, + continue, j, msg >> + +PutClient(self) == putLoop(self) \/ putRequest(self) \/ putBroadcast(self) + \/ putResponse(self) \/ putComplete(self) + \/ putCheckSpin(self) + +sendDisconnectRequest(self) == /\ pc[self] = "sendDisconnectRequest" + /\ clientIdRead9' = (self) - ((NUM_CLIENTS) * (DISCONNECT_ORDER)) + /\ msg_D' = [msg_D EXCEPT ![self] = [op |-> DISCONNECT_MSG, client |-> clientIdRead9']] + /\ clientIdRead10' = (self) - ((NUM_CLIENTS) * (DISCONNECT_ORDER)) + /\ clockWrite5' = [clocks EXCEPT ![clientIdRead10'] = -(1)] + /\ j_D' = [j_D EXCEPT ![self] = 0] + /\ clocks' = clockWrite5' + /\ pc' = [pc EXCEPT ![self] = "disconnectBroadcast"] + /\ UNCHANGED << replicasNetwork, allClients, + clientMailboxes, cid, out, + replicasRead, replicasWrite, + kvRead, clientsWrite, + clientsWrite0, kvWrite, + kvWrite0, clientsWrite1, + clientsWrite2, kvWrite1, + replicasWrite0, clientsWrite3, + kvWrite2, clientIdRead, + clockRead, clientIdRead0, + clockRead0, clientIdRead1, + clockWrite, keyRead, + clientIdRead2, clientIdRead3, + clockRead1, replicasWrite1, + clientsRead, clientsWrite4, + outsideWrite, clientsWrite5, + outsideWrite0, clockWrite0, + replicasWrite2, clientsWrite6, + outsideWrite1, spinRead, + clockWrite1, replicasWrite3, + clientsWrite7, outsideWrite2, + clientIdRead4, clockRead2, + clientIdRead5, clockRead3, + clientIdRead6, clockWrite2, + keyRead0, valueRead, + clientIdRead7, clientIdRead8, + clockRead4, replicasWrite4, + replicasWrite5, clientsRead0, + clientsWrite8, clientsWrite9, + clientsWrite10, outsideWrite3, + clockWrite3, replicasWrite6, + clientsWrite11, outsideWrite4, + spinRead0, clockWrite4, + replicasWrite7, clientsWrite12, + outsideWrite5, replicasWrite8, + replicasWrite9, clientIdRead11, + clockRead5, clientIdRead12, + clockRead6, clientIdRead13, + clockWrite6, clientIdRead14, + clientIdRead15, clockRead7, + replicasWrite10, + replicasWrite11, clockWrite7, + replicasWrite12, spinRead1, + clockWrite8, replicasWrite13, + kvLocal, liveClients, + pendingRequests, stableMessages, + i_, firstPending, timestamp, + nextClient, lowestPending, + chooseMessage, currentClocks, + minClock, continue_, + pendingClients, clientsIter, + msg_, ok, key, val, spinLocal, + continue_G, getReq, getResp, + spinLocal0, continue_P, i, j_, + putReq, putResp, spinLocal1, + continue, j, msg >> + +disconnectBroadcast(self) == /\ pc[self] = "disconnectBroadcast" + /\ IF ((j_D[self]) <= ((NUM_REPLICAS) - (1))) /\ ((0) # (-(1))) + THEN /\ (Len(replicasNetwork[j_D[self]])) < (BUFFER_SIZE) + /\ replicasWrite8' = [replicasNetwork EXCEPT ![j_D[self]] = Append(replicasNetwork[j_D[self]], msg_D[self])] + /\ j_D' = [j_D EXCEPT ![self] = (j_D[self]) + (1)] + /\ replicasWrite9' = replicasWrite8' + /\ replicasNetwork' = replicasWrite9' + /\ pc' = [pc EXCEPT ![self] = "disconnectBroadcast"] + ELSE /\ replicasWrite9' = replicasNetwork + /\ replicasNetwork' = replicasWrite9' + /\ pc' = [pc EXCEPT ![self] = "Done"] + /\ UNCHANGED << replicasWrite8, j_D >> + /\ UNCHANGED << allClients, clientMailboxes, cid, + out, clocks, replicasRead, + replicasWrite, kvRead, + clientsWrite, clientsWrite0, + kvWrite, kvWrite0, clientsWrite1, + clientsWrite2, kvWrite1, + replicasWrite0, clientsWrite3, + kvWrite2, clientIdRead, clockRead, + clientIdRead0, clockRead0, + clientIdRead1, clockWrite, + keyRead, clientIdRead2, + clientIdRead3, clockRead1, + replicasWrite1, clientsRead, + clientsWrite4, outsideWrite, + clientsWrite5, outsideWrite0, + clockWrite0, replicasWrite2, + clientsWrite6, outsideWrite1, + spinRead, clockWrite1, + replicasWrite3, clientsWrite7, + outsideWrite2, clientIdRead4, + clockRead2, clientIdRead5, + clockRead3, clientIdRead6, + clockWrite2, keyRead0, valueRead, + clientIdRead7, clientIdRead8, + clockRead4, replicasWrite4, + replicasWrite5, clientsRead0, + clientsWrite8, clientsWrite9, + clientsWrite10, outsideWrite3, + clockWrite3, replicasWrite6, + clientsWrite11, outsideWrite4, + spinRead0, clockWrite4, + replicasWrite7, clientsWrite12, + outsideWrite5, clientIdRead9, + clientIdRead10, clockWrite5, + clientIdRead11, clockRead5, + clientIdRead12, clockRead6, + clientIdRead13, clockWrite6, + clientIdRead14, clientIdRead15, + clockRead7, replicasWrite10, + replicasWrite11, clockWrite7, + replicasWrite12, spinRead1, + clockWrite8, replicasWrite13, + kvLocal, liveClients, + pendingRequests, stableMessages, + i_, firstPending, timestamp, + nextClient, lowestPending, + chooseMessage, currentClocks, + minClock, continue_, + pendingClients, clientsIter, msg_, + ok, key, val, spinLocal, + continue_G, getReq, getResp, + spinLocal0, continue_P, i, j_, + putReq, putResp, msg_D, + spinLocal1, continue, j, msg >> + +DisconnectClient(self) == sendDisconnectRequest(self) + \/ disconnectBroadcast(self) + +clockUpdateLoop(self) == /\ pc[self] = "clockUpdateLoop" + /\ IF continue[self] + THEN /\ clientIdRead11' = (self) - ((NUM_CLIENTS) * (NULL_ORDER)) + /\ clockRead5' = clocks[clientIdRead11'] + /\ IF (clockRead5') = (-(1)) + THEN /\ continue' = [continue EXCEPT ![self] = FALSE] + /\ clockWrite7' = clocks + /\ replicasWrite12' = replicasNetwork + /\ replicasNetwork' = replicasWrite12' + /\ clocks' = clockWrite7' + /\ pc' = [pc EXCEPT ![self] = "nullCheckSpin"] + /\ UNCHANGED << clientIdRead12, + clockRead6, + clientIdRead13, + clockWrite6, + clientIdRead14, + clientIdRead15, + clockRead7, j, + msg >> + ELSE /\ clientIdRead12' = (self) - ((NUM_CLIENTS) * (NULL_ORDER)) + /\ clockRead6' = clocks[clientIdRead12'] + /\ clientIdRead13' = (self) - ((NUM_CLIENTS) * (NULL_ORDER)) + /\ clockWrite6' = [clocks EXCEPT ![clientIdRead13'] = (clockRead6') + (1)] + /\ clientIdRead14' = (self) - ((NUM_CLIENTS) * (NULL_ORDER)) + /\ clientIdRead15' = (self) - ((NUM_CLIENTS) * (NULL_ORDER)) + /\ clockRead7' = clockWrite6'[clientIdRead15'] + /\ msg' = [msg EXCEPT ![self] = [op |-> NULL_MSG, client |-> clientIdRead14', timestamp |-> clockRead7']] + /\ j' = [j EXCEPT ![self] = 0] + /\ clocks' = clockWrite6' + /\ pc' = [pc EXCEPT ![self] = "nullBroadcast"] + /\ UNCHANGED << replicasNetwork, + clockWrite7, + replicasWrite12, + continue >> + /\ UNCHANGED << clockWrite8, + replicasWrite13 >> + ELSE /\ clockWrite8' = clocks + /\ replicasWrite13' = replicasNetwork + /\ replicasNetwork' = replicasWrite13' + /\ clocks' = clockWrite8' + /\ pc' = [pc EXCEPT ![self] = "Done"] + /\ UNCHANGED << clientIdRead11, clockRead5, + clientIdRead12, clockRead6, + clientIdRead13, + clockWrite6, + clientIdRead14, + clientIdRead15, clockRead7, + clockWrite7, + replicasWrite12, continue, + j, msg >> + /\ UNCHANGED << allClients, clientMailboxes, cid, out, + replicasRead, replicasWrite, kvRead, + clientsWrite, clientsWrite0, kvWrite, + kvWrite0, clientsWrite1, + clientsWrite2, kvWrite1, + replicasWrite0, clientsWrite3, + kvWrite2, clientIdRead, clockRead, + clientIdRead0, clockRead0, + clientIdRead1, clockWrite, keyRead, + clientIdRead2, clientIdRead3, + clockRead1, replicasWrite1, + clientsRead, clientsWrite4, + outsideWrite, clientsWrite5, + outsideWrite0, clockWrite0, + replicasWrite2, clientsWrite6, + outsideWrite1, spinRead, clockWrite1, + replicasWrite3, clientsWrite7, + outsideWrite2, clientIdRead4, + clockRead2, clientIdRead5, clockRead3, + clientIdRead6, clockWrite2, keyRead0, + valueRead, clientIdRead7, + clientIdRead8, clockRead4, + replicasWrite4, replicasWrite5, + clientsRead0, clientsWrite8, + clientsWrite9, clientsWrite10, + outsideWrite3, clockWrite3, + replicasWrite6, clientsWrite11, + outsideWrite4, spinRead0, clockWrite4, + replicasWrite7, clientsWrite12, + outsideWrite5, clientIdRead9, + clientIdRead10, clockWrite5, + replicasWrite8, replicasWrite9, + replicasWrite10, replicasWrite11, + spinRead1, kvLocal, liveClients, + pendingRequests, stableMessages, i_, + firstPending, timestamp, nextClient, + lowestPending, chooseMessage, + currentClocks, minClock, continue_, + pendingClients, clientsIter, msg_, ok, + key, val, spinLocal, continue_G, + getReq, getResp, spinLocal0, + continue_P, i, j_, putReq, putResp, + msg_D, j_D, spinLocal1 >> + +nullCheckSpin(self) == /\ pc[self] = "nullCheckSpin" + /\ spinRead1' = spinLocal1[self] + /\ IF ~(spinRead1') + THEN /\ continue' = [continue EXCEPT ![self] = FALSE] + /\ pc' = [pc EXCEPT ![self] = "clockUpdateLoop"] + ELSE /\ pc' = [pc EXCEPT ![self] = "clockUpdateLoop"] + /\ UNCHANGED continue + /\ UNCHANGED << replicasNetwork, allClients, + clientMailboxes, cid, out, clocks, + replicasRead, replicasWrite, kvRead, + clientsWrite, clientsWrite0, kvWrite, + kvWrite0, clientsWrite1, clientsWrite2, + kvWrite1, replicasWrite0, clientsWrite3, + kvWrite2, clientIdRead, clockRead, + clientIdRead0, clockRead0, + clientIdRead1, clockWrite, keyRead, + clientIdRead2, clientIdRead3, + clockRead1, replicasWrite1, clientsRead, + clientsWrite4, outsideWrite, + clientsWrite5, outsideWrite0, + clockWrite0, replicasWrite2, + clientsWrite6, outsideWrite1, spinRead, + clockWrite1, replicasWrite3, + clientsWrite7, outsideWrite2, + clientIdRead4, clockRead2, + clientIdRead5, clockRead3, + clientIdRead6, clockWrite2, keyRead0, + valueRead, clientIdRead7, clientIdRead8, + clockRead4, replicasWrite4, + replicasWrite5, clientsRead0, + clientsWrite8, clientsWrite9, + clientsWrite10, outsideWrite3, + clockWrite3, replicasWrite6, + clientsWrite11, outsideWrite4, + spinRead0, clockWrite4, replicasWrite7, + clientsWrite12, outsideWrite5, + clientIdRead9, clientIdRead10, + clockWrite5, replicasWrite8, + replicasWrite9, clientIdRead11, + clockRead5, clientIdRead12, clockRead6, + clientIdRead13, clockWrite6, + clientIdRead14, clientIdRead15, + clockRead7, replicasWrite10, + replicasWrite11, clockWrite7, + replicasWrite12, clockWrite8, + replicasWrite13, kvLocal, liveClients, + pendingRequests, stableMessages, i_, + firstPending, timestamp, nextClient, + lowestPending, chooseMessage, + currentClocks, minClock, continue_, + pendingClients, clientsIter, msg_, ok, + key, val, spinLocal, continue_G, getReq, + getResp, spinLocal0, continue_P, i, j_, + putReq, putResp, msg_D, j_D, spinLocal1, + j, msg >> + +nullBroadcast(self) == /\ pc[self] = "nullBroadcast" + /\ clientIdRead11' = (self) - ((NUM_CLIENTS) * (NULL_ORDER)) + /\ clockRead5' = clocks[clientIdRead11'] + /\ IF ((j[self]) <= ((NUM_REPLICAS) - (1))) /\ ((clockRead5') # (-(1))) + THEN /\ (Len(replicasNetwork[j[self]])) < (BUFFER_SIZE) + /\ replicasWrite10' = [replicasNetwork EXCEPT ![j[self]] = Append(replicasNetwork[j[self]], msg[self])] + /\ j' = [j EXCEPT ![self] = (j[self]) + (1)] + /\ replicasWrite11' = replicasWrite10' + /\ replicasNetwork' = replicasWrite11' + /\ pc' = [pc EXCEPT ![self] = "nullBroadcast"] + ELSE /\ replicasWrite11' = replicasNetwork + /\ replicasNetwork' = replicasWrite11' + /\ pc' = [pc EXCEPT ![self] = "nullCheckSpin"] + /\ UNCHANGED << replicasWrite10, j >> + /\ UNCHANGED << allClients, clientMailboxes, cid, out, + clocks, replicasRead, replicasWrite, + kvRead, clientsWrite, clientsWrite0, + kvWrite, kvWrite0, clientsWrite1, + clientsWrite2, kvWrite1, replicasWrite0, + clientsWrite3, kvWrite2, clientIdRead, + clockRead, clientIdRead0, clockRead0, + clientIdRead1, clockWrite, keyRead, + clientIdRead2, clientIdRead3, + clockRead1, replicasWrite1, clientsRead, + clientsWrite4, outsideWrite, + clientsWrite5, outsideWrite0, + clockWrite0, replicasWrite2, + clientsWrite6, outsideWrite1, spinRead, + clockWrite1, replicasWrite3, + clientsWrite7, outsideWrite2, + clientIdRead4, clockRead2, + clientIdRead5, clockRead3, + clientIdRead6, clockWrite2, keyRead0, + valueRead, clientIdRead7, clientIdRead8, + clockRead4, replicasWrite4, + replicasWrite5, clientsRead0, + clientsWrite8, clientsWrite9, + clientsWrite10, outsideWrite3, + clockWrite3, replicasWrite6, + clientsWrite11, outsideWrite4, + spinRead0, clockWrite4, replicasWrite7, + clientsWrite12, outsideWrite5, + clientIdRead9, clientIdRead10, + clockWrite5, replicasWrite8, + replicasWrite9, clientIdRead12, + clockRead6, clientIdRead13, clockWrite6, + clientIdRead14, clientIdRead15, + clockRead7, clockWrite7, + replicasWrite12, spinRead1, clockWrite8, + replicasWrite13, kvLocal, liveClients, + pendingRequests, stableMessages, i_, + firstPending, timestamp, nextClient, + lowestPending, chooseMessage, + currentClocks, minClock, continue_, + pendingClients, clientsIter, msg_, ok, + key, val, spinLocal, continue_G, getReq, + getResp, spinLocal0, continue_P, i, j_, + putReq, putResp, msg_D, j_D, spinLocal1, + continue, msg >> + +ClockUpdateClient(self) == clockUpdateLoop(self) \/ nullCheckSpin(self) + \/ nullBroadcast(self) + +(* Allow infinite stuttering to prevent deadlock on termination. *) +Terminating == /\ \A self \in ProcSet: pc[self] = "Done" + /\ UNCHANGED vars + +Next == (\E self \in ReplicaSet: Replica(self)) + \/ (\E self \in GetSet: GetClient(self)) + \/ (\E self \in PutSet: PutClient(self)) + \/ (\E self \in DisconnectSet: DisconnectClient(self)) + \/ (\E self \in NullSet: ClockUpdateClient(self)) + \/ Terminating + +Spec == /\ Init /\ [][Next]_vars + /\ \A self \in ReplicaSet : WF_vars(Replica(self)) + /\ \A self \in GetSet : WF_vars(GetClient(self)) + /\ \A self \in PutSet : WF_vars(PutClient(self)) + /\ \A self \in DisconnectSet : WF_vars(DisconnectClient(self)) + /\ \A self \in NullSet : WF_vars(ClockUpdateClient(self)) + +Termination == <>(\A self \in ProcSet: pc[self] = "Done") + +\* END TRANSLATION - the hash of the generated TLA code (remove to silence divergence warnings): TLA-bac0bd5a9581fcaaf62a0704717e8973 + +\* This predicate is true when all client processes are finished. +AllClientsDisconnected == \A client \in allClients : pc[client] = "Done" + + +\* Invariants +\* ********** + +\* These ensure that, in all states explored by TLC, the buffers (from client to replica and vice versa) +\* are within bounds. Using the FIFOChannel mapping macro is sufficient for this invariant to +\* hold. +BufferOk(net, node) == Len(net[node]) >= 0 /\ Len(net[node]) <= BUFFER_SIZE +ClientBuffersOk == \A node \in DOMAIN clientMailboxes : BufferOk(clientMailboxes, node) +ReplicaBuffersOk == \A node \in DOMAIN replicasNetwork : BufferOk(replicasNetwork, node) +AllBuffersOk == ClientBuffersOk /\ ReplicaBuffersOk + +\* This invariant tests that message stability detection in the replica is safe: +\* every message considered stable must have a timestamp lower than the current logical +\* clock of any live client. +MessageStability == \A replica \in ReplicaSet : + LET stable == stableMessages[replica] + alive == { c \in ClientSet : clocks[c] > 0 } + IN + Len(stable) > 0 => + \A m_id \in DOMAIN stable : + \A client \in alive : stable[m_id].timestamp < clocks[client] + + +\* Put semantics: once a client has been notified that a Put request was succesful +\* every replica must have the updated value. +PersistentPut == \A client \in PutSet : + pc[client] = "putComplete" => \A replica \in ReplicaSet : kvLocal[replica][PUT_KEY] = PUT_VALUE + + +\* Properties +\* ********** + +\* Logical clocks are monotonically increasing. This property checks that in every state, +\* pending messages in the replicas have increasing timestamps (or the process disconnected) +ClockIncreased == clocks' /= clocks => + \E c \in ClientSet : clocks'[c] = clocks[c]+1 \/ clocks'[c] = -1 + +MonotonicallyIncreasingClocks == [][ClockIncreased]_<> + + +\* Safety of disconnection: once a client has disconnected (and sent a message to all replicas +\* informing of that event), then the logical clock of that client should remain +\* unchanced -- i.e., no more messages from that client should be seen in the system. +DisconnectionSafe == \A client \in ClientSet : <>[](clocks[client] = -1) + +============================================================================= +\* Modification History +\* Last modified Mon Dec 21 03:02:11 PST 2020 by finn +\* Last modified Thu Apr 11 09:46:33 PDT 2019 by rmc +\* Last modified Wed Feb 27 12:42:52 PST 2019 by minh diff --git a/test/files/semantics/IfEitherLabelingRules.tla b/test/files/semantics/IfEitherLabelingRules.tla index 42182f8de..bd3e29b5e 100644 --- a/test/files/semantics/IfEitherLabelingRules.tla +++ b/test/files/semantics/IfEitherLabelingRules.tla @@ -40,6 +40,11 @@ EXTENDS Sequences, FiniteSets, Integers }; \*:: expectedError: LabelRequiredError y := 20; (* missing label *) + + l6: while(TRUE) { + l7: skip; + }; + skip; \* ok, no label needed (this says something about the correct desugaring for while) } } *) From 15f837f4b4ae726ee4d69de4ea00f0f198e6950f Mon Sep 17 00:00:00 2001 From: fhackett Date: Tue, 4 May 2021 05:26:21 -0700 Subject: [PATCH 04/27] WIP: read/write PCal tests, some progress on PCal codegen --- src/pgo/model/PGoError.scala | 6 +- src/pgo/model/SourceLocation.scala | 3 +- src/pgo/model/mpcal/AST.scala | 17 +- src/pgo/model/pcal/AST.scala | 2 +- src/pgo/model/tla/AST.scala | 24 +- src/pgo/model/tla/BuiltinModules.scala | 1 + src/pgo/parser/MPCalParser.scala | 75 ++-- src/pgo/parser/PCalParser.scala | 24 +- src/pgo/parser/ParsingErrors.scala | 3 + src/pgo/parser/TLAParser.scala | 38 +- src/pgo/parser/TLAParserContext.scala | 6 +- src/pgo/trans/MPCalNormalizePass.scala | 5 +- src/pgo/trans/MPCalPCalCodegenPass.scala | 223 +++++++++++- src/pgo/trans/MPCalSemanticCheckPass.scala | 10 +- src/pgo/trans/PCalRenderPass.scala | 404 ++++++++++++++++++++- src/pgo/util/Description.scala | 9 + test/pgo/PCalReadWriteTests.scala | 43 +++ 17 files changed, 812 insertions(+), 81 deletions(-) create mode 100644 test/pgo/PCalReadWriteTests.scala diff --git a/src/pgo/model/PGoError.scala b/src/pgo/model/PGoError.scala index a53080724..395abc2dd 100644 --- a/src/pgo/model/PGoError.scala +++ b/src/pgo/model/PGoError.scala @@ -2,9 +2,13 @@ package pgo.model import pgo.util.Description +import Description._ + abstract class PGoError extends RuntimeException { override def getMessage: String = - errors.view.map(err => err.description.ensureLineBreakBefore) + errors.view.map { err => + d"${err.description} at ${err.sourceLocation.longDescription}".ensureLineBreakBefore + } .flattenDescriptions .linesIterator .mkString("\n") diff --git a/src/pgo/model/SourceLocation.scala b/src/pgo/model/SourceLocation.scala index 20044372c..bf6477dfc 100644 --- a/src/pgo/model/SourceLocation.scala +++ b/src/pgo/model/SourceLocation.scala @@ -137,7 +137,8 @@ final case class SourceLocationWithUnderlying(underlying: SourceLocation.Underly d"$header\n${lines.view.map(_.toDescription.ensureLineBreakBefore).flattenDescriptions}\n$footer" } } else { - val footer = (View.fill(startColumn)(d" ") ++ View.fill(endColumn - startColumn)(d"^") ++ (if(atEOF) View(d" EOF") else View.empty)).flattenDescriptions + val effectiveEndColumn = if(startColumn == endColumn) startColumn + 1 else endColumn + val footer = (View.fill(startColumn)(d" ") ++ View.fill(effectiveEndColumn - startColumn)(d"^") ++ (if(atEOF) View(d" EOF") else View.empty)).flattenDescriptions d"$firstLine\n$footer" } }" diff --git a/src/pgo/model/mpcal/AST.scala b/src/pgo/model/mpcal/AST.scala index 42b9991c7..18db2f676 100644 --- a/src/pgo/model/mpcal/AST.scala +++ b/src/pgo/model/mpcal/AST.scala @@ -9,8 +9,13 @@ sealed abstract class MPCalNode extends Rewritable with Visitable with SourceLoc super.decorateLike(succ.setSourceLocation(sourceLocation)) } -final case class MPCalRefExpr(name: TLAIdentifier, mappingCount: Int) extends MPCalNode with RefersTo[MPCalParam] -final case class MPCalValExpr(name: TLAIdentifier, mappingCount: Int) extends MPCalNode with RefersTo[MPCalParam] +sealed abstract class MPCalParamExpr extends MPCalNode with RefersTo[DefinitionOne] { + def name: TLAIdentifier + def mappingCount: Int +} + +final case class MPCalRefExpr(override val name: TLAIdentifier, override val mappingCount: Int) extends MPCalParamExpr +final case class MPCalValExpr(override val name: TLAIdentifier, override val mappingCount: Int) extends MPCalParamExpr final case class MPCalDollarValue() extends MPCalNode @@ -18,14 +23,14 @@ final case class MPCalDollarVariable() extends MPCalNode final case class MPCalYield(expr: TLAExpression) extends MPCalNode -final case class MPCalCall(target: TLAIdentifier, arguments: List[TLAExpression]) extends MPCalNode with RefersTo[MPCalProcedure] +final case class MPCalCall(target: TLAIdentifier, arguments: List[Either[MPCalParamExpr,TLAExpression]]) extends MPCalNode with RefersTo[MPCalProcedure] sealed abstract class MPCalParam extends MPCalNode with DefinitionOne { def name: TLAIdentifier + def mappingCount: Int + override def arity: Int = 0 override def identifier: Definition.ScopeIdentifier = Definition.ScopeIdentifierName(name) - - def mappingCount: Int } final case class MPCalRefParam(override val name: TLAIdentifier, override val mappingCount: Int) extends MPCalParam final case class MPCalValParam(override val name: TLAIdentifier, override val mappingCount: Int) extends MPCalParam @@ -46,7 +51,7 @@ final case class MPCalArchetype(name: TLAIdentifier, selfDecl: TLADefiningIdenti variables: List[PCalVariableDeclaration], body: List[PCalStatement]) extends MPCalNode with RefersTo.HasReferences final case class MPCalInstance(selfDecl: PCalVariableDeclarationBound, fairness: PCalFairness, - archetypeName: TLAIdentifier, arguments: List[Either[MPCalParam,TLAExpression]], + archetypeName: TLAIdentifier, arguments: List[Either[MPCalParamExpr,TLAExpression]], mappings: List[MPCalMapping]) extends MPCalNode with RefersTo[MPCalArchetype] final case class MPCalMapping(target: MPCalMappingTarget, mappingMacroIdentifier: TLAIdentifier) extends MPCalNode with RefersTo[MPCalMappingMacro] diff --git a/src/pgo/model/pcal/AST.scala b/src/pgo/model/pcal/AST.scala index a9bb63505..57f429cf9 100644 --- a/src/pgo/model/pcal/AST.scala +++ b/src/pgo/model/pcal/AST.scala @@ -71,7 +71,7 @@ final case class PCalEither(cases: List[List[PCalStatement]]) extends PCalStatem require(cases.nonEmpty, s"either must have at least one case") } -// target is a string, because it would be much to hard to integrate gotos (which can reference any local label) into RefersTo +// target is a string, because it would be much too hard to integrate gotos (which can reference any local label) into RefersTo final case class PCalGoto(target: String) extends PCalStatement final case class PCalIf(condition: TLAExpression, yes: List[PCalStatement], no: List[PCalStatement]) extends PCalStatement diff --git a/src/pgo/model/tla/AST.scala b/src/pgo/model/tla/AST.scala index 54ffb35f7..d4569504c 100644 --- a/src/pgo/model/tla/AST.scala +++ b/src/pgo/model/tla/AST.scala @@ -59,6 +59,16 @@ object TLASymbol { precedenceLow } + /** + * A canonical string to represent this symbol at definition site + */ + def stringReprDefn: String = representations.head + + /** + * A canonical string to represent this symbol when referenced in an expression + */ + def stringReprUsage: String = representations.head + def precedenceLow: Int = TLAMeta.prefixOperators.get(representations.head).map(_._1) .orElse(TLAMeta.infixOperators.get(representations.head).map(_._1)) @@ -81,7 +91,9 @@ object TLASymbol { case object PrefixUnionSymbol extends Symbol("UNION") case object TLEventuallySymbol extends Symbol("<>") case object TLAlwaysSymbol extends Symbol("[]") - case object NegationSymbol extends Symbol("-_") + case object NegationSymbol extends Symbol("-_") { + override def stringReprUsage: String = "-" + } // infix case object DoubleExclamationSymbol extends Symbol("!!") @@ -340,12 +352,8 @@ final case class TLAGeneralIdentifier(name: TLAIdentifier, prefix: List[TLAGener final case class TLADot(lhs: TLAExpression, identifier: TLAIdentifier) extends TLAExpression -final case class TLAUnary(operation: TLASymbol, prefix: List[TLAGeneralIdentifierPart], operand: TLAExpression) extends TLAExpression with RefersTo[DefinitionOne] - final case class TLAOperatorCall(name: Definition.ScopeIdentifier, prefix: List[TLAGeneralIdentifierPart], arguments: List[TLAExpression]) extends TLAExpression with RefersTo[DefinitionOne] -final case class TLABinOp(operation: TLASymbol, prefix: List[TLAGeneralIdentifierPart], lhs: TLAExpression, rhs: TLAExpression) extends TLAExpression with RefersTo[DefinitionOne] - final case class TLAIf(cond: TLAExpression, tval: TLAExpression, fval: TLAExpression) extends TLAExpression final case class TLALet(defs: List[TLAUnit], body: TLAExpression) extends TLAExpression @@ -374,10 +382,14 @@ final case class TLAFunctionSet(from: TLAExpression, to: TLAExpression) extends final case class TLAFunctionSubstitution(source: TLAExpression, substitutions: List[TLAFunctionSubstitutionPair]) extends TLAExpression -final case class TLAFunctionSubstitutionPair(keys: List[TLAFunctionSubstitutionKey], value: TLAExpression) extends TLANode +final case class TLAFunctionSubstitutionPair(anchor: TLAFunctionSubstitutionPairAnchor, keys: List[TLAFunctionSubstitutionKey], value: TLAExpression) extends TLANode final case class TLAFunctionSubstitutionKey(indices: List[TLAExpression]) extends TLANode +final case class TLAFunctionSubstitutionPairAnchor() extends TLANode with RefersTo.HasReferences + +final case class TLAFunctionSubstitutionAt() extends TLAExpression with RefersTo[TLAFunctionSubstitutionPairAnchor] + trait TLAQuantified { def bounds: List[TLAQuantifierBound] def body: TLAExpression diff --git a/src/pgo/model/tla/BuiltinModules.scala b/src/pgo/model/tla/BuiltinModules.scala index b4154b1f0..cc4c83686 100644 --- a/src/pgo/model/tla/BuiltinModules.scala +++ b/src/pgo/model/tla/BuiltinModules.scala @@ -59,6 +59,7 @@ object BuiltinModules { symOp(TLASymbol.EqualsSymbol) symOp(TLASymbol.NotEqualsSymbol) symOp(TLASymbol.InSymbol) + symOp(TLASymbol.NotInSymbol) symOp(TLASymbol.IntersectSymbol) symOp(TLASymbol.UnionSymbol) symOp(TLASymbol.SubsetOrEqualSymbol) diff --git a/src/pgo/parser/MPCalParser.scala b/src/pgo/parser/MPCalParser.scala index f753dd3ae..5fed9ebaf 100644 --- a/src/pgo/parser/MPCalParser.scala +++ b/src/pgo/parser/MPCalParser.scala @@ -82,7 +82,9 @@ trait MPCalParser extends PCalParser { ((("fair" ~> ws ~> "+" ^^^ PCalFairness.StrongFair) | ("fair" ^^^ PCalFairness.WeakFair) | success(PCalFairness.Unfair)) ~ (ws ~> "process" ~> ws ~> "(" ~> pcalVarDeclBound <~ ws <~ ")") ~ (ws ~> "==" ~> ws ~> "instance" ~> ws ~> tlaIdentifierExpr) ~ - (ws ~> "(" ~> ws ~> repsep(mpcalParam ^^ (Left(_)) | tlaExpression ^^ (Right(_)), ws ~> "," ~> ws) <~ ws <~ ")")).flatMap { + (ws ~> "(" ~> ws ~> repsep(mpcalParamExpr ^^ { case TLAExtensionExpression(pExp: MPCalParamExpr) => Left(pExp) } | + tlaExpression ^^ (Right(_)), ws ~> "," ~> ws) <~ ws <~ ")") + ).flatMap { case fairness ~ nameDecl ~ target ~ arguments => val namePosMapping = arguments.view.zipWithIndex.collect { case (Left(param), idx) => param.name.id -> idx @@ -160,40 +162,36 @@ trait MPCalParser extends PCalParser { } } + def mpcalParamExpr(implicit ctx: PCalParserContext): Parser[TLAExpression] = + withSourceLocation { + querySourceLocation { + ("ref" ~> ws ~> tlaIdentifierExpr ~ (ws ~> mpcalRefSuffix) ^^ { + case id ~ mappingCount => (id, MPCalRefExpr(id, mappingCount)) + } | + tlaIdentifierExpr ~ (ws ~> mpcalRefSuffix) ^^ { + case id ~ mappingCount => (id, MPCalValExpr(id, mappingCount)) + }) + } + .map { + case (loc, (id, ref)) => + ref.setSourceLocation(loc) + ctx.ctx.lookupDefinition(List(Definition.ScopeIdentifierName(id))) match { + case None => + if(ctx.ctx.lateBindingStack.nonEmpty) { + ctx.ctx.lateBindingStack.head.getOrElseUpdate(id, mutable.ArrayBuffer()) += ref.setRefersTo + } else { + throw DefinitionLookupError(Nil, Definition.ScopeIdentifierName(id)) + } + case Some(defn) => + ref.setRefersTo(defn) + } + ref + }.map(TLAExtensionExpression) + } | super.pcalCallParam + def mpcalWithRefs(implicit ctx: MPCalParserContext): MPCalParser = new MPCalParser { - override def pcalCallParam(implicit ctx: PCalParserContext): Parser[TLAExpression] = { - withSourceLocation { - withSourceLocation { - ("ref" ~> ws ~> tlaIdentifierExpr ~ (ws ~> mpcalRefSuffix) ^^ { - case id ~ mappingCount => (id, MPCalRefExpr(id, mappingCount)) - } | - tlaIdentifierExpr ~ (ws ~> mpcalRefSuffix) ^^ { - case id ~ mappingCount => (id, MPCalValExpr(id, mappingCount)) - }) - .map { - case (id, ref) => - ctx.ctx.lookupDefinition(List(Definition.ScopeIdentifierName(id))) match { - case None => - if(ctx.ctx.lateBindingStack.nonEmpty) { - ctx.ctx.lateBindingStack.head.getOrElseUpdate(id, mutable.ArrayBuffer()) += { - case param: MPCalParam => ref.setRefersTo(param) - case _ => throw KindMismatchError(ref.sourceLocation, d"expected procedure or archetype param reference") - } - } else { - throw DefinitionLookupError(Nil, Definition.ScopeIdentifierName(id)) - } - case Some(defn) => - defn match { - case param: MPCalParam => ref.setRefersTo(param) - case _ => throw KindMismatchError(ref.sourceLocation, d"expected procedure or archetype param reference") - } - } - ref - } - }.map(TLAExtensionExpression) - } | super.pcalCallParam - } + override def pcalCallParam(implicit ctx: PCalParserContext): Parser[TLAExpression] = mpcalParamExpr } def mpcalBlock(implicit ctx: MPCalParserContext): Parser[MPCalBlock] = @@ -248,7 +246,11 @@ trait MPCalParser extends PCalParser { // like this, even if it's fake, all the parts have a refersTo, and the auto-renaming at least "thinks" it's working correctly result = result.rewrite() { case call @PCalCall(target, args) if mpcalProcedureMap.contains(target) => - PCalExtensionStatement(MPCalCall(target, args) + val transformedArgs = args.map { + case TLAExtensionExpression(pExp: MPCalParamExpr) => Left(pExp) + case expr => Right(expr) + } + PCalExtensionStatement(MPCalCall(target, transformedArgs) .setSourceLocation(call.sourceLocation) .setRefersTo(mpcalProcedureMap(target))).setSourceLocation(call.sourceLocation) } @@ -277,6 +279,11 @@ object MPCalParser extends MPCalParser with ParsingUtils { result.visit(Visitable.BottomUpFirstStrategy) { case loc: SourceLocatable => assert(loc.sourceLocation.isInstanceOf[SourceLocationWithUnderlying], s"internal error: did not have source location: $loc") } + // ensure no dandling ref or [_] are left in random expressions + result.visit(Visitable.BottomUpFirstStrategy) { + case TLAExtensionExpression(pExp: MPCalParamExpr) => + assert(false, s"ref or [_] found in wrong expression context: these syntaxes may only be used directly as arguments to an MPCal procedure call: ${pExp.sourceLocation}") + } result } } diff --git a/src/pgo/parser/PCalParser.scala b/src/pgo/parser/PCalParser.scala index 54ba6ca31..1e141f26e 100644 --- a/src/pgo/parser/PCalParser.scala +++ b/src/pgo/parser/PCalParser.scala @@ -270,7 +270,7 @@ trait PCalParser extends TLAParser { trait PCalCSyntax extends GenericSyntax { override def pcalIf(implicit ctx: PCalParserContext): Parser[PCalIf] = withSourceLocation { - "if" ~> ws ~> "(" ~> tlaExpression ~ (ws ~> ")" ~> ws ~> pcalStmts) ~ + "if" ~>! ws ~> "(" ~> tlaExpression ~ (ws ~> ")" ~> ws ~> pcalStmts) ~ opt(opt(ws ~> ";") ~> ws ~> "else" ~> ws ~> pcalStmts).map(_.getOrElse(Nil)) ^^ { case cond ~ yes ~ no => PCalIf(cond, yes, no) } @@ -278,25 +278,25 @@ trait PCalParser extends TLAParser { override def pcalWhile(implicit ctx: PCalParserContext): Parser[PCalWhile] = withSourceLocation { - "while" ~> ws ~> "(" ~> ws ~> tlaExpression ~ (ws ~> ")" ~> ws ~> pcalStmts) ^^ { + "while" ~>! ws ~> "(" ~> ws ~> tlaExpression ~ (ws ~> ")" ~> ws ~> pcalStmts) ^^ { case cond ~ body => PCalWhile(cond, body) } } override def pcalEither(implicit ctx: PCalParserContext): Parser[PCalEither] = withSourceLocation { - "either" ~> ws ~> pcalStmts ~ (ws ~> rep1sep("or" ~> ws ~> pcalStmts, ws)) ^^ { + "either" ~>! ws ~> pcalStmts ~ (ws ~> rep1sep("or" ~> ws ~> pcalStmts, ws)) ^^ { case part1 ~ parts => PCalEither(part1 :: parts) } } override def pcalWith(implicit ctx: PCalParserContext): Parser[PCalWith] = withSourceLocation { - "with" ~> ws ~> "(" ~> { + "with" ~>! ws ~> "(" ~> { def rec(rest: Boolean)(implicit ctx: PCalParserContext): Parser[(List[PCalVariableDeclarationBound],List[PCalStatement])] = { val origCtx = ctx (if(rest) { - ws ~> (";" | ",") + ws ~> (";" | ",") ~> ws } else { ws }) ~> pcalVarDeclBound.flatMap { decl => @@ -344,17 +344,17 @@ trait PCalParser extends TLAParser { override def pcalIf(implicit ctx: PCalParserContext): Parser[PCalIf] = { lazy val elsePart: Parser[List[PCalStatement]] = { val elsif = withSourceLocation { - "elsif" ~> ws ~> tlaExpression ~ (ws ~> "then" ~> ws ~> rep1sep(pcalStmt, ws)) ~ (ws ~> elsePart) ^^ { + "elsif" ~>! ws ~> tlaExpression ~ (ws ~> "then" ~> ws ~> rep1sep(pcalStmt, ws)) ~ (ws ~> elsePart) ^^ { case cond ~ yes ~ no => PCalIf(cond, yes, no) } } ^^ (List(_)) - val els = "else" ~> ws ~> rep1sep(pcalStmt, ws) + val els = "else" ~>! ws ~> rep1sep(pcalStmt, ws) elsif | els | success(Nil) } withSourceLocation { - "if" ~> ws ~> tlaExpression ~ (ws ~> "then" ~> ws ~> rep1sep(pcalStmt, ws) <~ ws) ~ elsePart <~ ws <~ "end" <~ ws <~ "if" ^^ { + "if" ~>! ws ~> tlaExpression ~ (ws ~> "then" ~> ws ~> rep1sep(pcalStmt, ws) <~ ws) ~ elsePart <~ ws <~ "end" <~ ws <~ "if" ^^ { case cond ~ yes ~ no => PCalIf(cond, yes, no) } } @@ -362,19 +362,19 @@ trait PCalParser extends TLAParser { override def pcalWhile(implicit ctx: PCalParserContext): Parser[PCalWhile] = withSourceLocation { - "while" ~> ws ~> tlaExpression ~ (ws ~> "do" ~> ws ~> rep1sep(pcalStmt, ws) <~ ws <~ "end" <~ ws <~ "while") ^^ { + "while" ~>! ws ~> tlaExpression ~ (ws ~> "do" ~> ws ~> rep1sep(pcalStmt, ws) <~ ws <~ "end" <~ ws <~ "while") ^^ { case cond ~ body => PCalWhile(cond, body) } } override def pcalEither(implicit ctx: PCalParserContext): Parser[PCalEither] = withSourceLocation { - "either" ~> ws ~> rep1sep(rep1sep(pcalStmt, ws), ws ~> "or" ~> ws) <~ ws <~ "end" <~ ws <~ "either" ^^ PCalEither + "either" ~>! ws ~> rep1sep(rep1sep(pcalStmt, ws), ws ~> "or" ~> ws) <~ ws <~ "end" <~ ws <~ "either" ^^ PCalEither } override def pcalWith(implicit ctx: PCalParserContext): Parser[PCalWith] = withSourceLocation { - "with" ~> { + "with" ~>! { def rec(rest: Boolean)(implicit ctx: PCalParserContext): Parser[(List[PCalVariableDeclarationBound], List[PCalStatement])] = { val origCtx = ctx (if (rest) { @@ -410,7 +410,7 @@ trait PCalParser extends TLAParser { override def pcalStmts(implicit ctx: PCalParserContext): Parser[List[PCalStatement]] = rep1sep(pcalStmt, ws) override def pcalBody(pSuffix: String)(implicit ctx: PCalParserContext): Parser[List[PCalStatement]] = - "begin" ~> ws ~> pcalStmts <~ ws <~ "end" <~ ws <~ pSuffix + "begin" ~>! ws ~> pcalStmts <~ ws <~ "end" <~ ws <~ pSuffix override def pcalProcessSelf(implicit ctx: PCalParserContext): Parser[PCalVariableDeclarationBound] = pcalVarDeclBound diff --git a/src/pgo/parser/ParsingErrors.scala b/src/pgo/parser/ParsingErrors.scala index 9226bee77..2e2d1fe0f 100644 --- a/src/pgo/parser/ParsingErrors.scala +++ b/src/pgo/parser/ParsingErrors.scala @@ -46,5 +46,8 @@ final case class ArchetypeArityMismatchError(loc: SourceLocation, archetype: MPC final case class KindMismatchError(loc: SourceLocation, explanation: Description) extends ParsingError( loc, d"kind mismatch: $explanation") +final case class FunctionSubstitutionAtError(loc: SourceLocation) extends ParsingError( + loc, d"function substitution anchor (the @ expression) found outside EXCEPT expression") + final case class ParseFailureError(err: String, loc: SourceLocation) extends ParsingError( loc, d"parsing failed: $err") diff --git a/src/pgo/parser/TLAParser.scala b/src/pgo/parser/TLAParser.scala index ed79f2957..a8011dfd2 100644 --- a/src/pgo/parser/TLAParser.scala +++ b/src/pgo/parser/TLAParser.scala @@ -232,7 +232,8 @@ trait TLAParser extends RegexParsers { val (symLoc, _) ~ rhs = part val combinedLoc = locationAcc ++ rhs.sourceLocation val sym = TLASymbol(TLASymbol.forString(which)).setSourceLocation(symLoc) - val binop = TLABinOp(sym, Nil, lhs, rhs).setSourceLocation(combinedLoc) + val binop = TLAOperatorCall(Definition.ScopeIdentifierSymbol(sym), Nil, List(lhs, rhs)) + .setSourceLocation(combinedLoc) // should always succeed, /\ and \/ are built-in binop.setRefersTo(ctx.lookupDefinition(List(Definition.ScopeIdentifierSymbol(sym))).get) (combinedLoc, binop) @@ -322,8 +323,22 @@ trait TLAParser extends RegexParsers { } } + def tlaFunctionSubstitutionAtExpr(implicit ctx: TLAParserContext): Parser[TLAFunctionSubstitutionAt] = + querySourceLocation("@") ^^ { + case (loc, _) => + ctx.functionSubstitutionPairAnchor match { + case None => + throw FunctionSubstitutionAtError(loc) + case Some(anchor) => + TLAFunctionSubstitutionAt() + .setSourceLocation(loc) + .setRefersTo(anchor) + } + } + def tlaFunctionSubstitutionExpr(implicit ctx: TLAParserContext): Parser[TLAFunctionSubstitution] = withSourceLocation { + val origCtx = ctx "[" ~> wsChk ~> tlaExpression ~ (wsChk ~> "EXCEPT" ~>! wsChk ~> tlaComma1Sep { withSourceLocation { "!" ~>! rep1 { @@ -336,8 +351,12 @@ trait TLAParser extends RegexParsers { withSourceLocation { "[" ~> wsChk ~> tlaComma1Sep(tlaExpression) <~ wsChk <~ "]" ^^ TLAFunctionSubstitutionKey }) - } ~ (wsChk ~> "=" ~> wsChk ~> tlaExpression) ^^ { - case path ~ value => TLAFunctionSubstitutionPair(path, value) + }.flatMap { path => + val anchor = TLAFunctionSubstitutionPairAnchor() // definition for the @ expression + implicit val ctx = origCtx.withFunctionSubstitutionPairAnchor(anchor) + (wsChk ~> "=" ~> wsChk ~> tlaExpression) ^^ { value => + TLAFunctionSubstitutionPair(anchor, path, value) + } } } } <~ wsChk <~ "]") ^^ { @@ -521,7 +540,8 @@ trait TLAParser extends RegexParsers { val (lowPrec, highPrec) = (opSym.symbol.precedenceLow, opSym.symbol.precedenceHigh) wsChk ~> querySourceLocation(tlaExpressionMinPrecedence(highPrec + 1)) ^^ { case (loc2, innerExpr) => - val result = TLAUnary(opSym, pfx, innerExpr).setSourceLocation(loc ++ loc2) + val result = TLAOperatorCall(Definition.ScopeIdentifierSymbol(opSym), pfx, List(innerExpr)) + .setSourceLocation(loc ++ loc2) ctx.lookupDefinition(pfx.map(id => Definition.ScopeIdentifierName(id.id)) :+ Definition.ScopeIdentifierSymbol(opSym)) match { case None => throw DefinitionLookupError(pfx, Definition.ScopeIdentifierSymbol(opSym)) case Some(defn) => result.setRefersTo(defn) @@ -544,7 +564,8 @@ trait TLAParser extends RegexParsers { }.flatMap { case (loc, (pfx, opSym)) => val combinedLoc = lhsLoc ++ loc - val result = TLAUnary(opSym, pfx, lhs).setSourceLocation(combinedLoc) + val result = TLAOperatorCall(Definition.ScopeIdentifierSymbol(opSym), pfx, List(lhs)) + .setSourceLocation(combinedLoc) ctx.lookupDefinition(pfx.map(id => Definition.ScopeIdentifierName(id.id)) :+ Definition.ScopeIdentifierSymbol(opSym)) match { case None => throw DefinitionLookupError(pfx, Definition.ScopeIdentifierSymbol(opSym)) case Some(defn) => result.setRefersTo(defn) @@ -587,7 +608,8 @@ trait TLAParser extends RegexParsers { querySourceLocation(wsChk ~> tlaExpressionMinPrecedence(highPrec + 1)).flatMap { case (rhsLoc, rhs) => val combinedLoc = lhsLoc ++ loc ++ rhsLoc - val result = TLABinOp(opSym, pfx, lhs, rhs).setSourceLocation(combinedLoc) + val result = TLAOperatorCall(Definition.ScopeIdentifierSymbol(opSym), pfx, List(lhs, rhs)) + .setSourceLocation(combinedLoc) ctx.lookupDefinition(pfx.map(id => Definition.ScopeIdentifierName(id.id)) :+ Definition.ScopeIdentifierSymbol(opSym)) match { case None => throw DefinitionLookupError(pfx, Definition.ScopeIdentifierSymbol(opSym)) case Some(defn) => result.setRefersTo(defn) @@ -599,7 +621,8 @@ trait TLAParser extends RegexParsers { }.flatMap { case (loc, pfx ~ opSym ~ rhs) => val combinedLoc = lhsLoc ++ loc - val nextLhs = TLABinOp(opSym, pfx, lhs, rhs).setSourceLocation(combinedLoc) + val nextLhs = TLAOperatorCall(Definition.ScopeIdentifierSymbol(opSym), pfx, List(lhs, rhs)) + .setSourceLocation(combinedLoc) ctx.lookupDefinition(pfx.map(id => Definition.ScopeIdentifierName(id.id)) :+ Definition.ScopeIdentifierSymbol(opSym)) match { case None => throw DefinitionLookupError(pfx, Definition.ScopeIdentifierSymbol(opSym)) case Some(defn) => nextLhs.setRefersTo(defn) @@ -620,6 +643,7 @@ trait TLAParser extends RegexParsers { tlaNumberExpr | tlaStringExpr | ("(" ~>! wsChk ~> tlaExpression <~ wsChk <~ ")") | + tlaFunctionSubstitutionAtExpr | tlaTupleExpr | tlaRequiredActionExpr | tlaOperatorCallOrGeneralIdentifier | diff --git a/src/pgo/parser/TLAParserContext.scala b/src/pgo/parser/TLAParserContext.scala index 2032d6e57..68714eca4 100644 --- a/src/pgo/parser/TLAParserContext.scala +++ b/src/pgo/parser/TLAParserContext.scala @@ -8,7 +8,8 @@ import scala.collection.mutable final case class TLAParserContext(minColumn: Int = -1, lateBindingStack: List[mutable.Map[TLAIdentifier,mutable.Buffer[DefinitionOne=>Unit]]] = Nil, - currentScope: Map[Definition.ScopeIdentifier,DefinitionOne] = Map.empty) { + currentScope: Map[Definition.ScopeIdentifier,DefinitionOne] = Map.empty, + functionSubstitutionPairAnchor: Option[TLAFunctionSubstitutionPairAnchor] = None) { def withMinColumn(minColumn: Int): TLAParserContext = copy(minColumn=minColumn) @@ -19,6 +20,9 @@ final case class TLAParserContext(minColumn: Int = -1, case defn: DefinitionComposite => defn.singleDefinitions.foldLeft(this)(_.withDefinition(_)) } + def withFunctionSubstitutionPairAnchor(anchor: TLAFunctionSubstitutionPairAnchor): TLAParserContext = + copy(functionSubstitutionPairAnchor = Some(anchor)) + def withLateBinding: TLAParserContext = copy(lateBindingStack=mutable.Map.empty[TLAIdentifier,mutable.Buffer[DefinitionOne=>Unit]] :: lateBindingStack) diff --git a/src/pgo/trans/MPCalNormalizePass.scala b/src/pgo/trans/MPCalNormalizePass.scala index 5062bd433..9216ccf48 100644 --- a/src/pgo/trans/MPCalNormalizePass.scala +++ b/src/pgo/trans/MPCalNormalizePass.scala @@ -19,7 +19,10 @@ object MPCalNormalizePass { MPCalPassUtils.expandMacroCalls(body, lexicalScope) } // remove the now-expanded macros - block = block.decorateLike(block.copy(macros = Nil)) + locally { + val stableBlock = block // hax because decorateLike incorrectly uses this.type + block = stableBlock.decorateLike(stableBlock.copy(macros = Nil).asInstanceOf[stableBlock.type]) + } // normalise label nesting, so all labels appear at the top level. // retain control flow by injecting synthetic gotos at label boundaries that use fall-through diff --git a/src/pgo/trans/MPCalPCalCodegenPass.scala b/src/pgo/trans/MPCalPCalCodegenPass.scala index 8feb9dce6..262fdf6a1 100644 --- a/src/pgo/trans/MPCalPCalCodegenPass.scala +++ b/src/pgo/trans/MPCalPCalCodegenPass.scala @@ -1,10 +1,225 @@ package pgo.trans -import pgo.model.PGoError -import pgo.model.mpcal.MPCalBlock -import pgo.model.pcal.PCalAlgorithm +import pgo.model.{Definition, DefinitionOne, PGoError, RefersTo, Rewritable, SourceLocation} +import pgo.model.mpcal._ +import pgo.model.pcal._ +import pgo.model.tla._ +import pgo.util.{IdMap, IdSet} + +import scala.annotation.tailrec +import scala.collection.{immutable, mutable} object MPCalPCalCodegenPass { @throws[PGoError] - def apply(mpcalBlock: MPCalBlock): PCalAlgorithm = ??? + def apply(mpcalBlock: MPCalBlock): PCalAlgorithm = { + var block: MPCalBlock = mpcalBlock + + block = locally { + val generatedPCalProcedures = mutable.ListBuffer[PCalProcedure]() + val generatedPCalProcesses = mutable.ListBuffer[PCalProcess]() + // mpcal procedure expansion signature: + // - identity of the mpcal procedure being expanded + // - for a ref param, the identity of the param referenced (or, the expression, if that's the case), and the identity of the mapping to be applied + // - for a non-ref [_] param, the identity of the mapping to be applied (but not the identity of what is referenced, as it is taken by-value) + val mpcalProcedureCache = mutable.HashMap[List[TLAExpression],PCalProcedure]() + + def impl(stmts: List[PCalStatement], inProcedures: IdSet[MPCalProcedure]): List[PCalStatement] = { + stmts.flatMap { + case PCalAssignment(List(PCalAssignmentPair(lhs, rhs))) => + ??? + case PCalAssignment(moreThanOnePair) => ??? // should be unreachable + case PCalExtensionStatement(MPCalCall(target, arguments)) => + ??? + } + } + + // TODO: single-process MPCal + val rewritten = block.rewrite(Rewritable.TopDownFirstStrategy) { + case instance @MPCalInstance(selfDecl, fairness, archetypeName, arguments, mappings) => + val archetype = instance.refersTo + + val substitutionsBuilder = immutable.Map.newBuilder[RefersTo.HasReferences,DefinitionOne] + val variables = archetype.variables.iterator.map { v => + val clone = v.shallowCopy() + substitutionsBuilder += v -> clone + clone + }.to(mutable.ListBuffer) + (arguments.iterator zip archetype.params).foreach { + case Left(arg @MPCalRefExpr(_, _)) -> param => + substitutionsBuilder += param -> arg.refersTo + case Left(arg @MPCalValExpr(_, _)) -> param => + variables += PCalVariableDeclarationValue(param.name, TLAGeneralIdentifier(arg.name, Nil)) + substitutionsBuilder += param -> variables.last + case Right(expr) -> param => + variables += PCalVariableDeclarationValue(param.name, expr) + substitutionsBuilder += param -> variables.last + } + val substitutions = substitutionsBuilder.result() + + val mappingsMap = mappings.iterator.map { + case mapping @MPCalMapping(MPCalMappingTarget(index, mappingCount), _) => + val param = archetype.params(index) + (param: DefinitionOne) -> (mappingCount, mapping.refersTo) + }.toMap + + def updateStmt(stmt: PCalStatement): PCalStatement = { + // TODO: how to "interpolate" the mapping macro stmts into a read/write + // - in any case, rename any local bindings in the read body + // - for write, force the write into whatever nested position. there will only be one per nested stmt, so no need to worry about side-effects + // - for read, more care is needed: the value that was read should be bound via "with" where it logically appears, and + // further read macros should be expanded inside the with body. if a yield is in non-tail position, interaction between multiple applications + // of the same mapping (multiple reads of the same value per-expression) will be unsound, as statements logically "after" the read may appear + // in positions that do not respect logical control flow. Note also that reads are treated syntactically, with the same syntactic read being + // expanded exactly once outside the containing expression, in all cases. + // Function-mapped reads that depend on quantified variables, or LET-bound variables, will not be treated soundly. + import scala.util.control.TailCalls._ + + var stmtSink: TailRec[PCalStatement] => PCalStatement = _.result + + object MappedRead { + @tailrec + private def unapplyImpl(rewritable: Rewritable, mappingCount: Int): Option[(Int,TLAGeneralIdentifier)] = + rewritable match { + case TLAFunctionCall(fn, _) => + unapplyImpl(fn, mappingCount + 1) + case ident: TLAGeneralIdentifier => Some((mappingCount, ident)) + case _ => None + } + + def unapply(rewritable: Rewritable): Option[(Int,TLAGeneralIdentifier)] = + unapplyImpl(rewritable, mappingCount = 0) + } + + def updateReads[T <: Rewritable](t: T): T = { + var result: T = t + result = t.rewrite(Rewritable.TopDownFirstStrategy) { + case expr@ MappedRead(mappingCount, ident) => + mappingsMap.get(ident.refersTo) match { + case Some((expectedMappingCount, mapping)) if expectedMappingCount == mappingCount => + val mappedBind = PCalVariableDeclarationValue(???, expr.asInstanceOf[TLAExpression]) + + stmtSink = { innerStmt => + stmtSink(innerStmt.flatMap { innerStmt => + done(PCalWith(List(mappedBind), + mapping.readBody.mapConserve { stmt => + stmt.rewrite(Rewritable.TopDownFirstStrategy) { + case PCalExtensionStatement(MPCalYield(expr)) => + val yieldedBind = PCalVariableDeclarationValue(???, expr) + PCalWith(List(yieldedBind), List(innerStmt)) + } + } + )) + }) + } + + ??? //TLAGeneralIdentifier(???, Nil).setRefersTo(yieldedBind) + case _ => expr + } + } + + result = t.rewrite(Rewritable.BottomUpOnceStrategy) { + case ident: TLAGeneralIdentifier if substitutions.contains(ident.refersTo) => + val replacement = substitutions(ident.refersTo) + ident.shallowCopy().copy(name = replacement.identifier.asInstanceOf[Definition.ScopeIdentifierName].name).setRefersTo(replacement) + } + result + } + + stmtSink(done { + stmt match { + case stmt: PCalAssignment => + @tailrec + def getRef(lhs: PCalAssignmentLhs): Option[DefinitionOne] = + lhs match { + case ident: PCalAssignmentLhsIdentifier => Some(ident.refersTo) + case PCalAssignmentLhsProjection(lhs, _) => getRef(lhs) + case PCalAssignmentLhsExtension(_) => None + } + + /*@tailrec + def findReceiver(lhs: PCalAssignmentLhs, mappingCount: Int): (PCalAssignmentLhs, ) = { + assert(mappingCount >= 0) + if (mappingCount == 0) lhs else { + lhs match { + case PCalAssignmentLhsIdentifier(identifier) => ??? + case PCalAssignmentLhsProjection(lhs, projections) => + findReceiver(lhs, mappingCount - 1) + case PCalAssignmentLhsExtension(contents) => ??? + } + } + }*/ + + val withReads@PCalAssignment(List(PCalAssignmentPair(lhs, rhs))) = updateReads(stmt) + getRef(lhs).flatMap { ref => + mappingsMap.get(ref).map { + case (mappingCount, MPCalMappingMacro(name, readBody, writeBody, freeVars)) => + //val receiver = findReceiver(lhs, mappingCount) + + ??? + } + }.getOrElse(withReads) + case stmt@PCalEither(cases) => + stmt.withChildren(Iterator( + cases.mapConserve(_.mapConserve(updateStmt)) + )) + case stmt@PCalIf(condition, yes, no) => + stmt.withChildren(Iterator( + updateReads(condition), + yes.mapConserve(updateStmt), + no.mapConserve(updateStmt), + )) + case stmt@PCalLabeledStatements(label, statements) => + stmt.withChildren(Iterator(label, statements.mapConserve(updateStmt))) + case PCalMacroCall(_, _) => ??? + case PCalWhile(_, _) => ??? + case stmt@PCalWith(variables, body) => + stmt.withChildren(Iterator( + variables.mapConserve(updateReads), + body.mapConserve(updateStmt), + )) + case PCalExtensionStatement(MPCalCall(target, arguments)) => + ??? // TODO: correctly handle refs, that is, ensure that the mpcal procedure is instantiated correctly, + // and that substitutions are also applied correctly + // (substitutions will remove refs/function mappings, by design, but also breaking procedure signatures) + case stmt => + updateReads(stmt) + } + }) + } + + generatedPCalProcesses += PCalProcess(selfDecl, fairness, variables.result(), ???) + .setSourceLocation(instance.sourceLocation) + + instance // return the instance unchanged; we got what we came for + case PCalProcess(selfDecl, fairness, variables, body) => + ??? + case PCalProcedure(name, params, variables, body) => + ??? + } + + rewritten.copy( + pcalProcedures = generatedPCalProcedures.result(), + mpcalProcedures = Nil, + instances = Nil, + processes = rewritten.processes match { + case left @Left(_) => + assert(generatedPCalProcesses.isEmpty) + left + case Right(existingProcs) => + Right(existingProcs ::: generatedPCalProcesses.result()) + }) + } + // expand archetypes + mapping macros (using list buffer accumulator for add'l stmts) + mpcal procedures + // ensure single assignment to each var + + PCalAlgorithm( + name = block.name, + fairness = PCalFairness.Unfair, + units = block.units, + macros = Nil, + variables = block.variables, + procedures = block.pcalProcedures, + processes = block.processes, + ).setSourceLocation(block.sourceLocation) + } } diff --git a/src/pgo/trans/MPCalSemanticCheckPass.scala b/src/pgo/trans/MPCalSemanticCheckPass.scala index 4aa743630..6aa99a06b 100644 --- a/src/pgo/trans/MPCalSemanticCheckPass.scala +++ b/src/pgo/trans/MPCalSemanticCheckPass.scala @@ -288,7 +288,7 @@ object MPCalSemanticCheckPass { // enforce kind-matching for MPCal params (ref vs. non-ref, number of mappings) locally { def checkMPCalParamRefs(body: List[PCalStatement], params: List[MPCalParam]): Unit = { - val paramsMap = params.view.map(p => p -> p).to(IdMap) + val paramsMap = params.view.map(p => (p: DefinitionOne) -> p).to(IdMap) body.foreach { stmt => stmt.visit(Visitable.BottomUpFirstStrategy) { case PCalAssignmentPair(lhs, _) => @@ -352,11 +352,11 @@ object MPCalSemanticCheckPass { case MPCalMapping(target @MPCalMappingTarget(position, mappingCount), id) => arguments(position) match { case Left(param) => param match { - case MPCalRefParam(_, mappingCountP) => + case MPCalRefExpr(_, mappingCountP) => if(mappingCount < mappingCountP) { errors += SemanticError.MPCalKindMismatchError(usage = target, defn = param) } - case MPCalValParam(_, mappingCountP) => + case MPCalValExpr(_, mappingCountP) => if(mappingCount < mappingCountP) { errors += SemanticError.MPCalKindMismatchError(usage = target, defn = param) } @@ -365,10 +365,10 @@ object MPCalSemanticCheckPass { } } (archetype.params.view zip arguments.view).foreach { - case (MPCalRefParam(_, mappingCountP), Left(MPCalRefParam(_, mappingCount))) if mappingCount == mappingCountP => // ok + case (MPCalRefParam(_, mappingCountP), Left(MPCalRefExpr(_, mappingCount))) if mappingCount == mappingCountP => // ok case (MPCalRefParam(_, 0), Right(_)) => // ok (see TODO above..?) case (MPCalValParam(_, 0), Right(_)) => // ok - case (MPCalValParam(_, mappingCountP), Left(MPCalValParam(_, mappingCount))) if mappingCount == mappingCountP => // ok + case (MPCalValParam(_, mappingCountP), Left(MPCalValExpr(_, mappingCount))) if mappingCount == mappingCountP => // ok case (param, Left(arg)) => errors += SemanticError.MPCalKindMismatchError(usage = arg, defn = param) case (param, Right(arg)) => diff --git a/src/pgo/trans/PCalRenderPass.scala b/src/pgo/trans/PCalRenderPass.scala index 61fd5d4c3..33d84ee60 100644 --- a/src/pgo/trans/PCalRenderPass.scala +++ b/src/pgo/trans/PCalRenderPass.scala @@ -1,8 +1,408 @@ package pgo.trans -import pgo.model.pcal.PCalAlgorithm +import pgo.model.tla._ +import pgo.model.pcal._ +import pgo.model.mpcal._ import pgo.util.Description +import Description._ +import pgo.model.Definition + +import scala.collection.View object PCalRenderPass { - def apply(pcalAlgorithm: PCalAlgorithm): Description = ??? + def describeQuantifierBound(qb: TLAQuantifierBound): Description = + qb.tpe match { + case TLAQuantifierBound.IdsType => + d"${qb.ids.map(_.id.id.toDescription).separateBy(d", ")} \\in ${describeExpr(qb.set)}" + case TLAQuantifierBound.TupleType => + d"<<${qb.ids.map(_.id.id.toDescription).separateBy(d", ")}>> \\in ${describeExpr(qb.set)}" + } + + def describePrefix(prefix: List[TLAGeneralIdentifierPart]): Description = + prefix.view.map { + case TLAGeneralIdentifierPart(id, parameters) => + d"${id.id}(${ + parameters.view.map(describeExpr).separateBy(d", ") + })!" + }.flattenDescriptions + + def describeExpr(expr: TLAExpression): Description = + expr match { + case TLAExtensionExpression(MPCalDollarVariable()) => d"$$variable" + case TLAExtensionExpression(MPCalDollarValue()) => d"$$value" + case TLAString(value) => + d""""${ + value.flatMap { + case '"' => "\\\"" + case '\\' => "\\\\" + case '\t' => "\\t" + case '\n' => "\\n" + case '\f' => "\\f" + case '\r' => "\\r" + case ch => ch.toString + } + }"""" + case TLANumber(value, _ /* force decimal representation, should be correct in most cases */) => + value match { + case TLANumber.IntValue(value) => + value.toString().toDescription + case TLANumber.DecimalValue(value) => + value.toString().toDescription + } + case TLAGeneralIdentifier(name, prefix) => + d"${describePrefix(prefix)}${name.id}" + case TLADot(lhs, identifier) => + d"(${describeExpr(lhs)}).${identifier.id}" + case TLAOperatorCall(name, prefix, arguments) => + name match { + case Definition.ScopeIdentifierName(name) => + d"${describePrefix(prefix)}${name.id}(${ + arguments.view.map(describeExpr).separateBy(d", ") + })" + case Definition.ScopeIdentifierSymbol(symbol) => + if(symbol.symbol.isPrefix) { + val List(operand) = arguments + d"${describePrefix(prefix)}${symbol.symbol.stringReprUsage} (${describeExpr(operand)})" + } else if(symbol.symbol.isPostfix) { + val List(operand) = arguments + d"(${describeExpr(operand)}) ${describePrefix(prefix)}${symbol.symbol.stringReprUsage}" + } else { + assert(symbol.symbol.isInfix) + val List(lhs, rhs) = arguments + d"(${describeExpr(lhs)}) ${describePrefix(prefix)}${symbol.symbol.stringReprUsage} (${describeExpr(rhs)})" + } + } + case TLAIf(cond, tval, fval) => + d"IF ${describeExpr(cond)} THEN ${describeExpr(tval)} ELSE ${describeExpr(fval)}" + case TLALet(defs, body) => + d"LET ${ + defs.view.map(describeUnit(_).ensureLineBreakAfter) + .flattenDescriptions.indented + } IN ${describeExpr(body)}" + case TLACase(TLACaseArm(cond1, result1) :: armsRest, other) => + d"CASE ${describeExpr(cond1)} -> ${describeExpr(result1)}${ + armsRest.view.map { + case TLACaseArm(cond, result) => + d"\n[] ${describeExpr(cond)} -> ${describeExpr(result)}" + }.flattenDescriptions.indented + }${ + other.map { other => + d"\n[] OTHER -> ${describeExpr(other)}".indented + }.getOrElse(d"") + }" + case TLAMaybeAction(body, vars) => + d"[${describeExpr(body)}]_${describeExpr(vars)}" + case TLARequiredAction(body, vars) => + d"<<${describeExpr(body)}>>_${describeExpr(vars)}" + case TLAFairness(kind, vars, expression) => + kind match { + case TLAFairness.StrongFairness => + d"WF_${describeExpr(expression)}(${describeExpr(vars)})" + case TLAFairness.WeakFairness => + d"SF_${describeExpr(expression)}(${describeExpr(vars)})" + } + case TLAFunction(args, body) => + d"[${args.view.map(describeQuantifierBound).separateBy(d", ")} |-> ${describeExpr(body)}]" + case TLAFunctionCall(function, params) => + d"(${describeExpr(function)})[${ + params.view.map(describeExpr).separateBy(d", ") + }]" + case TLAFunctionSet(from, to) => + d"[${describeExpr(from)} -> ${describeExpr(to)}]" + case TLAFunctionSubstitution(source, substitutions) => + d"[${describeExpr(source)} EXCEPT ${ + substitutions.view.map { + case TLAFunctionSubstitutionPair(anchor, keys, value) => + d"!${ + keys.view.map { + case TLAFunctionSubstitutionKey(indices) => + d"[${indices.view.map(describeExpr).separateBy(d", ")}]" + }.flattenDescriptions + } = ${describeExpr(value)}" + }.separateBy(d" ") + }]" + case TLAFunctionSubstitutionAt() => d"@" + case TLAQuantifiedExistential(bounds, body) => + d"\\E ${bounds.view.map(describeQuantifierBound).separateBy(d", ")} : ${describeExpr(body)}" + case TLAQuantifiedUniversal(bounds, body) => + d"\\A ${bounds.view.map(describeQuantifierBound).separateBy(d", ")} : ${describeExpr(body)}" + case TLAExistential(ids, body) => + d"\\EE ${ids.view.map(_.id.id.toDescription).separateBy(d", ")} : ${describeExpr(body)}" + case TLAUniversal(ids, body) => + d"\\AA ${ids.view.map(_.id.id.toDescription).separateBy(d", ")} : ${describeExpr(body)}" + case TLASetConstructor(contents) => + d"{${contents.view.map(describeExpr).separateBy(d", ")}}" + case TLASetRefinement(binding, when) => + d"{${describeQuantifierBound(binding)} : ${describeExpr(when)}}" + case TLASetComprehension(body, bounds) => + d"{${describeExpr(body)} : ${bounds.view.map(describeQuantifierBound).separateBy(d", ")}}" + case TLATuple(elements) => + d"<<${elements.view.map(describeExpr).separateBy(d", ")}>>" + case TLARecordConstructor(fields) => + d"[${ + fields.view.map { + case TLARecordConstructorField(name, value) => + d"${name.id} |-> ${describeExpr(value)}" + }.separateBy(d", ") + }]" + case TLARecordSet(fields) => + d"[${ + fields.view.map { + case TLARecordSetField(name, set) => + d"${name.id} : ${describeExpr(set)}" + }.separateBy(d", ") + }]" + } + + def describeOpDecl(opDecl: TLAOpDecl): Description = + opDecl.variant match { + case TLAOpDecl.NamedVariant(ident, 0) => + ident.id.toDescription + case TLAOpDecl.NamedVariant(ident, arity) => + d"${ident.id}(${View.fill(arity)(d"_").separateBy(d", ")})" + case TLAOpDecl.SymbolVariant(sym) => + if(sym.symbol.isPrefix) { + d"${sym.symbol.stringReprDefn} _" + } else if(sym.symbol.isPostfix) { + d"_ ${sym.symbol.stringReprDefn}" + } else { + assert(sym.symbol.isInfix) + d"_ ${sym.symbol.stringReprDefn} _" + } + } + + def describeUnit(unit: TLAUnit, ignoreLocal: Boolean = false): Description = + unit match { + case TLAAssumption(assumption) => + d"ASSUME ${describeExpr(assumption)}" + case TLAConstantDeclaration(constants) => + d"CONSTANTS ${constants.view.map(describeOpDecl).separateBy(d", ")}" + case TLAInstance(moduleName, remappings, isLocal) => + d"${if(isLocal && !ignoreLocal) d"LOCAL " else d""}INSTANCE ${moduleName.id}${ + if(remappings.nonEmpty) { + d" WITH ${ + remappings.view.map { + case TLAInstanceRemapping(from, to) => + from match { + case Definition.ScopeIdentifierName(name) => + d"${name.id} <- ${describeExpr(to)}" + case Definition.ScopeIdentifierSymbol(symbol) => + d"${symbol.symbol.stringReprDefn} <- ${describeExpr(to)}" + } + }.separateBy(d", ") + }" + } else d"" + }" + case TLAModule(name, exts, units) => + d"---- MODULE ${name.id} ----${ + if(exts.nonEmpty) { + d"\nEXTENDS ${exts.view.map(_.identifier.name.id.toDescription).separateBy(d", ")}" + } else d"" + }${ + units.view.map(describeUnit(_).ensureLineBreakBefore).flattenDescriptions + }\n====" + case TLAModuleDefinition(name, args, instance, isLocal) => + d"${if(isLocal && !ignoreLocal) d"LOCAL " else d""}${name.id}(${ + args.view.map(describeOpDecl).separateBy(d", ") + }) == ${describeUnit(instance)}" + case TLAOperatorDefinition(name, args, body, isLocal) => + d"${if(isLocal && !ignoreLocal) d"LOCAL " else d""}${ + name match { + case Definition.ScopeIdentifierName(name) => + d"${name.id}(${args.view.map(describeOpDecl).separateBy(d", ")}) == ${describeExpr(body)}" + case Definition.ScopeIdentifierSymbol(symbol) => + if(symbol.symbol.isPrefix) { + val List(TLAOpDecl(TLAOpDecl.NamedVariant(id, 0))) = args + d"${symbol.symbol.stringReprDefn} ${id.id} == ${describeExpr(body)}" + } else if(symbol.symbol.isPostfix) { + val List(TLAOpDecl(TLAOpDecl.NamedVariant(id, 0))) = args + d"${id.id} ${symbol.symbol.stringReprDefn} == ${describeExpr(body)}" + } else { + assert(symbol.symbol.isInfix) + val List(TLAOpDecl(TLAOpDecl.NamedVariant(idLhs, 0)), TLAOpDecl(TLAOpDecl.NamedVariant(idRhs, 0))) = args + d"${idLhs.id} ${symbol.symbol.stringReprDefn} ${idRhs.id} == ${describeExpr(body)}" + } + } + }" + case TLATheorem(theorem) => + d"THEOREM ${describeExpr(theorem)}" + case TLAVariableDeclaration(variables) => + d"VARIABLES ${variables.view.map(_.id.id.toDescription).separateBy(d", ")}" + } + + def describeStatement(stmt: PCalStatement): Description = + stmt match { + case PCalExtensionStatement(MPCalCall(target, arguments)) => + d"call $target(${ + arguments.view.map { + case Left(pExp: MPCalParamExpr) => + pExp match { + case MPCalRefExpr(name, mappingCount) => d"ref ${name.id}${View.fill(mappingCount)(d"[_]").flattenDescriptions}" + case MPCalValExpr(name, mappingCount) => d"${name.id}${View.fill(mappingCount)(d"[_]").flattenDescriptions}" + } + case Right(expr) => describeExpr(expr) + }.separateBy(d", ") + })" + case PCalAssert(condition) => + d"assert ${describeExpr(condition)}" + case PCalAssignment(pairs) => + def describeLhs(lhs: PCalAssignmentLhs): Description = + lhs match { + case PCalAssignmentLhsIdentifier(identifier) => + identifier.id.toDescription + case PCalAssignmentLhsProjection(lhs, projections) => + d"${describeLhs(lhs)}[${projections.view.map(describeExpr).separateBy(d", ")}]" + case PCalAssignmentLhsExtension(MPCalDollarVariable()) => + d"$$variable" + } + + pairs.view.map { + case PCalAssignmentPair(lhs, rhs) => + d"${describeLhs(lhs)} := ${describeExpr(rhs)}" + }.separateBy(d" || ") + case PCalAwait(condition) => + d"await ${describeExpr(condition)}" + case PCalCall(target, arguments) => + d"call ${target.id}(${arguments.view.map(describeExpr).separateBy(d", ")})" + case PCalEither(cases) => + d"either ${ + cases.view.map { block => + d"{\n${describeStatements(block).indented}\n}" + }.separateBy(d" or ") + }" + case PCalGoto(target) => + d"goto $target" + case PCalIf(condition, yes, no) => + d"if(${describeExpr(condition)}) {\n${ + describeStatements(yes).indented + }\n}${ + if(no.nonEmpty) { + d" else {\n${describeStatements(no).indented}\n}" + } else d"" + }" + case PCalLabeledStatements(label, statements) => + d"${label.name}${ + label.modifier match { + case PCalLabel.PlusModifier => d"-" + case PCalLabel.MinusModifier => d"+" + case PCalLabel.NoModifier => d"" + } + }:\n${describeStatements(statements, tailSemicolon = false).indented}" + case PCalMacroCall(target, arguments) => + d"${target.id}(${arguments.view.map(describeExpr).separateBy(d", ")})" + case PCalPrint(value) => + d"print ${describeExpr(value)}" + case PCalReturn() => d"return" + case PCalSkip() => d"skip" + case PCalWhile(condition, body) => + d"while(${describeExpr(condition)}) {\n${ + describeStatements(body).indented + }\n}" + case PCalWith(variables, body) => + d"with (${variables.view.map(describeVarDecl).separateBy(d", ")}) {\n${ + describeStatements(body).indented + }\n}" + } + + def describeStatements(stmts: List[PCalStatement], tailSemicolon: Boolean = true): Description = + if(tailSemicolon) { + stmts.view.map(stmt => d"${describeStatement(stmt)};".ensureLineBreakBefore) + .flattenDescriptions + } else { + stmts.view.map(stmt => d"${describeStatement(stmt)}".ensureLineBreakBefore) + .separateBy(d";") + } + + def describeVarDecl(varDecl: PCalVariableDeclaration): Description = + varDecl match { + case PCalVariableDeclarationEmpty(name) => name.id.toDescription + case PCalVariableDeclarationValue(name, value) => d"${name.id} = ${describeExpr(value)}" + case PCalVariableDeclarationSet(name, set) => d"${name.id} \\in ${describeExpr(set)}" + } + + def apply(pcalAlgorithm: PCalAlgorithm): Description = { + val PCalAlgorithm(fairness, name, variables, units, macros, procedures, processes) = pcalAlgorithm + + val header = fairness match { + case PCalFairness.Unfair => d"--algorithm" + case PCalFairness.WeakFair => d"--fair algorithm" + case PCalFairness.StrongFair => ??? + } + + d"$header ${name.id} {${ + if(variables.nonEmpty) { + d"\nvariables${ + variables.view.map { decl => + d" ${describeVarDecl(decl)};" + }.flattenDescriptions + }".indented + } else d"" + }${ + if(units.nonEmpty) { + d"\ndefine{${ + units.view.map { unit => + d"\n${describeUnit(unit)}".indented + }.flattenDescriptions + }\n}".indented + } else d"" + }${ + macros.view.map { + case PCalMacro(name, params, body, _) => + d"\n\nmacro ${name.id}(${ + params.view.map(_.id.id.toDescription).separateBy(d", ") + }) {${ + describeStatements(body).indented + }\n}" + }.flattenDescriptions + }${ + procedures.view.map { + case PCalProcedure(name, params, variables, body) => + d"\n\nprocedure ${name.id}(${ + params.view.map { + case PCalPVariableDeclaration(name, value) => + d"${name.id}${value.map(v => d" = ${describeExpr(v)}").getOrElse(d"")}" + }.separateBy(d", ") + })${ + if(variables.nonEmpty) { + d"variables${ + variables.view.map { + case PCalPVariableDeclaration(name, value) => + d" ${name.id}${value.map(v => d" = ${describeExpr(v)};")}" + }.flattenDescriptions + }" + } else d"" + }\n{${ + describeStatements(body).indented + }\n}" + }.flattenDescriptions + }${ + processes match { + case Left(statements) => + d"\n{${ + describeStatements(statements).indented + }\n}" + case Right(processes) => + processes.view.map { + case PCalProcess(selfDecl, fairness, variables, body) => + d"\n\n${ + fairness match { + case PCalFairness.Unfair => d"" + case PCalFairness.WeakFair => d"fair " + case PCalFairness.StrongFair => d"fair+ " + } + } process (${describeVarDecl(selfDecl)})${ + if(variables.nonEmpty) { + d"\nvariables${ + variables.view.map { decl => + d" ${describeVarDecl(decl)};" + }.flattenDescriptions + }".indented + } else d"" + }\n{\n${ + describeStatements(body).indented + }\n}" + }.flattenDescriptions + } + }\n}" + } } diff --git a/src/pgo/util/Description.scala b/src/pgo/util/Description.scala index bdd3fb3eb..12c68333c 100644 --- a/src/pgo/util/Description.scala +++ b/src/pgo/util/Description.scala @@ -108,6 +108,15 @@ object Description { implicit class IterableFlattenDescriptions(val descList: Iterable[Description]) extends AnyVal { def flattenDescriptions: Description = new Description(descList.view.flatMap(_.parts)) + + def separateBy(desc: Description): Description = + new Description(View.fromIteratorProvider { () => + var first = true + descList.iterator.flatMap(elem => if(first) { + first = false + elem.parts.iterator + } else desc.parts.iterator ++ elem.parts.iterator) + }) } implicit class StringToDescription(val str: String) extends AnyVal { diff --git a/test/pgo/PCalReadWriteTests.scala b/test/pgo/PCalReadWriteTests.scala new file mode 100644 index 000000000..e20a759c3 --- /dev/null +++ b/test/pgo/PCalReadWriteTests.scala @@ -0,0 +1,43 @@ +package pgo + +import org.scalactic.source.Position +import org.scalatest.funsuite.AnyFunSuite +import pgo.util.Description +import pgo.model.SourceLocation +import pgo.parser.{PCalParser, TLAParser} +import Description._ +import pgo.trans.PCalRenderPass + +class PCalReadWriteTests extends AnyFunSuite { + def check(path: os.Path)(implicit pos: Position): Unit = { + test(path.relativeTo(os.pwd).toString()) { + val underlying = new SourceLocation.UnderlyingFile(path) + val fileContents = os.read(path) + withClue(s"original file:\n$fileContents") { + val tlaModule = TLAParser.readModuleBeforeTranslation( + underlying = underlying, seq = fileContents) + val pcalAlgorithm = PCalParser.readAlgorithm( + underlying = underlying, contents = fileContents, tlaModule = tlaModule) + + val renderedContentsLines = d"(*\n${PCalRenderPass(pcalAlgorithm)}\n*)" + .linesIterator.toBuffer + val renderedContents = renderedContentsLines.mkString("\n") + + withClue(d"rendered file:\n$renderedContents") { + val reparsedAlgorithm = PCalParser.readAlgorithm( + new SourceLocation.UnderlyingString(renderedContents), renderedContents, tlaModule) + + assert(pcalAlgorithm == reparsedAlgorithm) + } + } + } + } + + check(os.pwd / "examples" / "Queens.tla") + check(os.pwd / "examples" / "Euclid.tla") + check(os.pwd / "examples" / "pgo2pc.tla") + check(os.pwd / "examples" / "2pc.tla") + check(os.pwd / "examples" / "round_robin.tla") + check(os.pwd / "examples" / "counter.tla") + check(os.pwd / "examples" / "DijkstraMutex.tla") +} From 4532a9fdb0ced28571e5ffda56768db0d1848ade Mon Sep 17 00:00:00 2001 From: fhackett Date: Wed, 5 May 2021 23:25:36 -0700 Subject: [PATCH 05/27] WIP: fixed some pcal codegen bugs; tests still broken --- src/pgo/PGo.scala | 4 +- src/pgo/model/Rewritable.scala | 4 +- src/pgo/model/mpcal/AST.scala | 2 +- src/pgo/model/pcal/AST.scala | 6 +- src/pgo/model/tla/AST.scala | 2 +- src/pgo/parser/MPCalParser.scala | 9 +- src/pgo/trans/MPCalNormalizePass.scala | 24 +- src/pgo/trans/MPCalPCalCodegenPass.scala | 324 ++++++++++++--------- src/pgo/trans/MPCalSemanticCheckPass.scala | 2 +- src/pgo/trans/PCalRenderPass.scala | 8 +- src/pgo/util/NameCleaner.scala | 1 + test/files/pcalgen/dqueue.tla | 8 +- test/pgo/PCalGenFileTests.scala | 18 +- test/pgo/model/RewritableTests.scala | 29 ++ 14 files changed, 272 insertions(+), 169 deletions(-) create mode 100644 test/pgo/model/RewritableTests.scala diff --git a/src/pgo/PGo.scala b/src/pgo/PGo.scala index 201b9b376..71a4b432d 100644 --- a/src/pgo/PGo.scala +++ b/src/pgo/PGo.scala @@ -104,7 +104,7 @@ object PGo { var pcalBeginFound = false var pcalEndFound = false - os.write(tempOutput, os.read.lines.stream(config.PCalGenCmd.specFile()).zipWithIndex.flatMap { + os.write.over(tempOutput, (os.read.lines.stream(config.PCalGenCmd.specFile()).zipWithIndex.flatMap { case (PCalBeginTranslation(), lineIdx) if !pcalBeginFound => assert(!pcalEndFound, s"at line ${lineIdx+1}, found PLUSCAL END TRANSLATION comment before PLUSCAL BEGIN TRANSLATION") pcalBeginFound = true @@ -119,7 +119,7 @@ object PGo { case (line, _) => Iterator(line) } ++ Generator.selfClosing { (if(!pcalBeginFound) renderedPCalIterator else Iterator.empty, () => ()) - }) + }).map(line => s"$line\n")) } // move the rendered output over the spec file, replacing it os.move(from = tempOutput, to = config.PCalGenCmd.specFile(), replaceExisting = true, atomicMove = true) diff --git a/src/pgo/model/Rewritable.scala b/src/pgo/model/Rewritable.scala index 1163fd796..22eb871d7 100644 --- a/src/pgo/model/Rewritable.scala +++ b/src/pgo/model/Rewritable.scala @@ -5,7 +5,7 @@ import pgo.util.IdMap import java.lang.reflect.Constructor import scala.annotation.tailrec -trait Rewritable { +trait Rewritable extends Visitable { import Rewritable._ def productIterator: Iterator[Any] @@ -19,7 +19,7 @@ trait Rewritable { def namedParts: Iterator[RefersTo.HasReferences] = { def gatherOtherwise(subject: Any): Iterator[RefersTo.HasReferences] = subject match { - case _: Rewritable => Iterator.empty + case subject: Rewritable if subject ne this => Iterator.empty case map: Map[_, _] => map.valuesIterator.flatMap(gather) case iterable: Iterable[_] => iterable.iterator.flatMap(gather) case product: Product => product.productIterator.flatMap(gather) diff --git a/src/pgo/model/mpcal/AST.scala b/src/pgo/model/mpcal/AST.scala index 18db2f676..34c54303b 100644 --- a/src/pgo/model/mpcal/AST.scala +++ b/src/pgo/model/mpcal/AST.scala @@ -4,7 +4,7 @@ import pgo.model.{Definition, DefinitionOne, RefersTo, Rewritable, SourceLocatab import pgo.model.tla._ import pgo.model.pcal._ -sealed abstract class MPCalNode extends Rewritable with Visitable with SourceLocatable { +sealed abstract class MPCalNode extends Rewritable with SourceLocatable { override def decorateLike(succ: this.type): this.type = super.decorateLike(succ.setSourceLocation(sourceLocation)) } diff --git a/src/pgo/model/pcal/AST.scala b/src/pgo/model/pcal/AST.scala index 57f429cf9..6f6c62880 100644 --- a/src/pgo/model/pcal/AST.scala +++ b/src/pgo/model/pcal/AST.scala @@ -4,7 +4,7 @@ import pgo.model.{Definition, DefinitionOne, RefersTo, Rewritable, SourceLocatab import pgo.model.tla._ -sealed abstract class PCalNode extends Rewritable with Visitable with SourceLocatable { +sealed abstract class PCalNode extends Rewritable with SourceLocatable { override def decorateLike(succ: this.type): this.type = super.decorateLike(succ.setSourceLocation(sourceLocation)) } @@ -61,7 +61,9 @@ final case class PCalAssignmentPair(lhs: PCalAssignmentLhs, rhs: TLAExpression) sealed abstract class PCalAssignmentLhs extends PCalNode final case class PCalAssignmentLhsIdentifier(identifier: TLAIdentifier) extends PCalAssignmentLhs with RefersTo[DefinitionOne] final case class PCalAssignmentLhsProjection(lhs: PCalAssignmentLhs, projections: List[TLAExpression]) extends PCalAssignmentLhs -final case class PCalAssignmentLhsExtension(contents: Any) extends PCalAssignmentLhs +final case class PCalAssignmentLhsExtension(contents: Any) extends PCalAssignmentLhs { + assert(!contents.isInstanceOf[TLAGeneralIdentifier]) +} final case class PCalAwait(condition: TLAExpression) extends PCalStatement diff --git a/src/pgo/model/tla/AST.scala b/src/pgo/model/tla/AST.scala index d4569504c..d3d19569b 100644 --- a/src/pgo/model/tla/AST.scala +++ b/src/pgo/model/tla/AST.scala @@ -5,7 +5,7 @@ import pgo.model.{Definition, DefinitionComposite, DefinitionOne, RefersTo, Rewr import scala.collection.View -sealed abstract class TLANode extends Rewritable with Visitable with SourceLocatable { +sealed abstract class TLANode extends Rewritable with SourceLocatable { override def decorateLike(succ: this.type): this.type = super.decorateLike(succ.setSourceLocation(sourceLocation)) } diff --git a/src/pgo/parser/MPCalParser.scala b/src/pgo/parser/MPCalParser.scala index 5fed9ebaf..633b53d5d 100644 --- a/src/pgo/parser/MPCalParser.scala +++ b/src/pgo/parser/MPCalParser.scala @@ -82,8 +82,10 @@ trait MPCalParser extends PCalParser { ((("fair" ~> ws ~> "+" ^^^ PCalFairness.StrongFair) | ("fair" ^^^ PCalFairness.WeakFair) | success(PCalFairness.Unfair)) ~ (ws ~> "process" ~> ws ~> "(" ~> pcalVarDeclBound <~ ws <~ ")") ~ (ws ~> "==" ~> ws ~> "instance" ~> ws ~> tlaIdentifierExpr) ~ - (ws ~> "(" ~> ws ~> repsep(mpcalParamExpr ^^ { case TLAExtensionExpression(pExp: MPCalParamExpr) => Left(pExp) } | - tlaExpression ^^ (Right(_)), ws ~> "," ~> ws) <~ ws <~ ")") + (ws ~> "(" ~> ws ~> repsep(mpcalParamExpr ^^ { + case TLAExtensionExpression(pExp: MPCalParamExpr) => Left(pExp) + case expr: TLAExpression => Right(expr) + }, ws ~> "," ~> ws) <~ ws <~ ")") ).flatMap { case fairness ~ nameDecl ~ target ~ arguments => val namePosMapping = arguments.view.zipWithIndex.collect { @@ -121,7 +123,8 @@ trait MPCalParser extends PCalParser { mpcalSpecialVariable | super.tlaExpressionNoOperators override def pcalLhsId(implicit ctx: PCalParserContext): Parser[PCalAssignmentLhs] = - withSourceLocation(mpcalSpecialVariable ^^ PCalAssignmentLhsExtension) | super.pcalLhsId + withSourceLocation(withSourceLocation("$variable" ^^ (_ => MPCalDollarVariable())) ^^ PCalAssignmentLhsExtension) | + super.pcalLhsId override val pcalCSyntax: PCalCSyntax = new PCalCSyntax { override def pcalUnlabeledStmt(implicit ctx: PCalParserContext): Parser[PCalStatement] = diff --git a/src/pgo/trans/MPCalNormalizePass.scala b/src/pgo/trans/MPCalNormalizePass.scala index 9216ccf48..1b3b4aae6 100644 --- a/src/pgo/trans/MPCalNormalizePass.scala +++ b/src/pgo/trans/MPCalNormalizePass.scala @@ -55,8 +55,8 @@ object MPCalNormalizePass { case (labeledStmts @PCalLabeledStatements(whileLabel, (whileStmt @PCalWhile(whileCondition, whileBody)) :: afterWhileStmts)) :: restBlocks => val (whileBodyTrans, whileBodyBlocks) = impl(whileBody, Some(whileLabel), Iterator.empty, Iterator.empty) val (afterWhileTrans, afterWhileBlocks) = impl(afterWhileStmts, findLabelAfter(restBlocks, labelAfter), Iterator.empty, Iterator.empty) - val whileTrans = whileStmt.withChildren(Iterator(whileCondition, whileBodyTrans)) - val labeledStmtsTrans = labeledStmts.withChildren(Iterator(whileLabel, whileTrans :: afterWhileTrans)) + val whileTrans = PCalIf(whileCondition, whileBodyTrans, afterWhileTrans).setSourceLocation(whileStmt.sourceLocation) + val labeledStmtsTrans = labeledStmts.withChildren(Iterator(whileLabel, whileTrans :: Nil)) transBlocks(restBlocks, labelAfter, blocksOut ++ Iterator.single(labeledStmtsTrans) ++ whileBodyBlocks ++ afterWhileBlocks) case (labeledStmts @PCalLabeledStatements(label, stmts)) :: restBlocks => val (stmtsTrans, stmtsBlocks) = impl(stmts, findLabelAfter(restBlocks, labelAfter), Iterator.empty, Iterator.empty) @@ -84,7 +84,6 @@ object MPCalNormalizePass { case stmt => (stmt, Iterator.empty) } - @tailrec def impl(stmts: List[PCalStatement], labelAfter: Option[PCalLabel], stmtsOut: Iterator[PCalStatement], blocksOut: Iterator[PCalLabeledStatements]): (List[PCalStatement],Iterator[PCalLabeledStatements]) = { object ContainsJump { def unapply(stmts: List[PCalStatement]): Option[(List[PCalStatement],List[PCalStatement])] = @@ -109,9 +108,10 @@ object MPCalNormalizePass { case Nil => val synthJump = labelAfter.map(label => PCalGoto(label.name).setSourceLocation(DerivedSourceLocation(label.sourceLocation, SourceLocationInternal, d"tail-call transformation"))) ((stmtsOut ++ synthJump.iterator).toList, blocksOut) - case allBlocks @PCalLabeledStatements(_, _) :: _ => + case allBlocks @PCalLabeledStatements(nextLabel, _) :: _ => assert(allBlocks.forall(_.isInstanceOf[PCalLabeledStatements])) - (stmtsOut.toList, transBlocks(allBlocks.asInstanceOf[List[PCalLabeledStatements]], labelAfter, blocksOut)) + val (resultStmts, _) = impl(Nil, Some(nextLabel), stmtsOut, Iterator.empty) + (resultStmts, transBlocks(allBlocks.asInstanceOf[List[PCalLabeledStatements]], labelAfter, blocksOut)) case ContainsJump(jumpStmts, restStmts) => assert(restStmts.forall(_.isInstanceOf[PCalLabeledStatements])) val jumpTrans = jumpStmts.map(transStmt(_, findLabelAfter(restStmts, labelAfter))) @@ -135,19 +135,27 @@ object MPCalNormalizePass { } } - // desugar while loops into ifs and gotos + /*// desugar while loops into ifs and gotos // note: the statements after the while go inside the _else branch_, as evidenced by a label not being needed // after a label-containing while statement (if it were equivalent to an if with statements after it, a label would be needed) block = block.rewrite(Rewritable.BottomUpOnceStrategy) { case labeledStmts @PCalLabeledStatements(label, (whileStmt @PCalWhile(condition, body)) :: restStmts) => + def pushDownGoto(goto: PCalStatement, stmts: List[PCalStatement]): List[PCalStatement] = + stmts match { + case Nil => goto :: Nil + case (labeled@PCalLabeledStatements(label, stmts)) :: Nil => + labeled.withChildren(Iterator(label, pushDownGoto(goto, stmts))) :: Nil + case hd :: tl => hd :: pushDownGoto(goto, tl) + } + PCalLabeledStatements( label, List(PCalIf( condition, - body :+ PCalGoto(label.name).setSourceLocation(whileStmt.sourceLocation.derivedVia(d"while statement desugaring")), + pushDownGoto(PCalGoto(label.name).setSourceLocation(whileStmt.sourceLocation.derivedVia(d"while statement desugaring")), body), restStmts).setSourceLocation(whileStmt.sourceLocation.derivedVia(d"while statement desugaring"))) ).setSourceLocation(labeledStmts.sourceLocation) - } + }*/ // needed below: gather all names, to generate synthetic ones for multiple assignment temp vars val nameCleaner = new NameCleaner diff --git a/src/pgo/trans/MPCalPCalCodegenPass.scala b/src/pgo/trans/MPCalPCalCodegenPass.scala index 262fdf6a1..def3810d5 100644 --- a/src/pgo/trans/MPCalPCalCodegenPass.scala +++ b/src/pgo/trans/MPCalPCalCodegenPass.scala @@ -1,10 +1,10 @@ package pgo.trans -import pgo.model.{Definition, DefinitionOne, PGoError, RefersTo, Rewritable, SourceLocation} +import pgo.model.{Definition, DefinitionOne, PGoError, RefersTo, Rewritable, SourceLocation, Visitable} import pgo.model.mpcal._ import pgo.model.pcal._ import pgo.model.tla._ -import pgo.util.{IdMap, IdSet} +import pgo.util.{IdMap, IdSet, NameCleaner} import scala.annotation.tailrec import scala.collection.{immutable, mutable} @@ -14,6 +14,20 @@ object MPCalPCalCodegenPass { def apply(mpcalBlock: MPCalBlock): PCalAlgorithm = { var block: MPCalBlock = mpcalBlock + val nameCleaner = new NameCleaner + block.visit(Visitable.BottomUpFirstStrategy) { + case TLAIdentifier(id) => nameCleaner.addKnownName(id) + } + + // Expand mpcal procedures and mapping macros + // - in any case, rename any local bindings in the read body + // - for write, force the write into whatever nested position. there will only be one per nested stmt, so no need to worry about side-effects + // - for read, more care is needed: the value that was read should be bound via "with" where it logically appears, and + // further read macros should be expanded inside the with body. if a yield is in non-tail position, interaction between multiple applications + // of the same mapping (multiple reads of the same value per-expression) will be unsound, as statements logically "after" the read may appear + // in positions that do not respect logical control flow. Note also that reads are treated syntactically, with the same syntactic read being + // expanded exactly once outside the containing expression, in all cases. + // Function-mapped reads that depend on quantified variables, or LET-bound variables, will not be treated soundly. block = locally { val generatedPCalProcedures = mutable.ListBuffer[PCalProcedure]() val generatedPCalProcesses = mutable.ListBuffer[PCalProcess]() @@ -23,14 +37,161 @@ object MPCalPCalCodegenPass { // - for a non-ref [_] param, the identity of the mapping to be applied (but not the identity of what is referenced, as it is taken by-value) val mpcalProcedureCache = mutable.HashMap[List[TLAExpression],PCalProcedure]() - def impl(stmts: List[PCalStatement], inProcedures: IdSet[MPCalProcedure]): List[PCalStatement] = { - stmts.flatMap { - case PCalAssignment(List(PCalAssignmentPair(lhs, rhs))) => - ??? - case PCalAssignment(moreThanOnePair) => ??? // should be unreachable + object MappedRead { + @tailrec + private def unapplyImpl(expr: TLAExpression, mappingCount: Int): Option[(Int,TLAGeneralIdentifier)] = + expr match { + case TLAFunctionCall(fn, _) => + unapplyImpl(fn, mappingCount + 1) + case ident: TLAGeneralIdentifier => Some((mappingCount, ident)) + case _ => None + } + + def unapply(expr: TLAExpression): Option[(Int,TLAGeneralIdentifier)] = + unapplyImpl(expr, mappingCount = 0) + } + + def updateStmt(stmt: PCalStatement)(implicit mappingsMap: IdMap[DefinitionOne,(Int,MPCalMappingMacro)], substitutions: IdMap[RefersTo.HasReferences,DefinitionOne]): PCalStatement = { + var stmtSink: PCalStatement => PCalStatement = identity + + def updateReads[E <: Rewritable](expr: E, skipMappings: Boolean = false): E = + expr.rewrite(Rewritable.TopDownFirstStrategy) { + case expr@MappedRead(mappingCount, ident) if !skipMappings && mappingsMap.get(ident.refersTo).exists(_._1 == mappingCount) => + val (_, mapping) = mappingsMap(ident.refersTo) + val mappedBind = PCalVariableDeclarationValue(TLAIdentifier(nameCleaner.cleanName("value")), updateReads(expr, skipMappings = true)) + val placeholder = PCalVariableDeclarationValue(TLAIdentifier("THIS_IS_A_BUG"), TLAString("THIS IS A BUG")) + + stmtSink = { innerStmt => + stmtSink { + PCalWith(List(mappedBind), + mapping.readBody.mapConserve(_.rewrite(Rewritable.BottomUpOnceStrategy) { + case PCalAssignmentLhsExtension(MPCalDollarVariable()) => + val sub = substitutions(ident.refersTo) + PCalAssignmentLhsIdentifier(sub.identifier.asInstanceOf[Definition.ScopeIdentifierName].name) + .setRefersTo(sub) + case TLAExtensionExpression(MPCalDollarVariable()) => + val sub = substitutions(ident.refersTo) + TLAGeneralIdentifier(sub.identifier.asInstanceOf[Definition.ScopeIdentifierName].name, Nil) + .setRefersTo(sub) + case PCalExtensionStatement(MPCalYield(valExpr)) => + val yieldedBind = PCalVariableDeclarationValue(TLAIdentifier(nameCleaner.cleanName("yielded")), valExpr) + PCalWith(List(yieldedBind), List( + innerStmt.rewrite(Rewritable.BottomUpOnceStrategy) { + case ident: TLAGeneralIdentifier if ident.refersTo eq placeholder => + TLAGeneralIdentifier(yieldedBind.name, Nil).setRefersTo(yieldedBind) + } + )) + }) + ) + } + } + TLAGeneralIdentifier(placeholder.name, Nil).setRefersTo(placeholder) + case ident@TLAGeneralIdentifier(_, prefix) if substitutions.contains(ident.refersTo) => + val mappedPrefix = prefix.mapConserve(updateReads(_)) + val subDefn = substitutions(ident.refersTo) + val name = subDefn.identifier.asInstanceOf[Definition.ScopeIdentifierName].name + TLAGeneralIdentifier(name, mappedPrefix).setRefersTo(subDefn) + } + + val unwrappedStmt = stmt match { + case stmt: PCalAssignment => + @tailrec + def findRef(lhs: PCalAssignmentLhs): Option[PCalAssignmentLhsIdentifier] = + lhs match { + case ident: PCalAssignmentLhsIdentifier => Some(ident) + case PCalAssignmentLhsProjection(lhs, _) => findRef(lhs) + } + + def replaceRef(lhs: PCalAssignmentLhs): PCalAssignmentLhs = + lhs match { + case ident: PCalAssignmentLhsIdentifier if substitutions.contains(ident.refersTo) => + ident.shallowCopy().setRefersTo(substitutions(ident.refersTo)) + case ident: PCalAssignmentLhsIdentifier => ident + case proj@PCalAssignmentLhsProjection(lhs, projections) => + proj.withChildren(Iterator(replaceRef(lhs), projections)) + } + + def splitLhs(lhs: PCalAssignmentLhs, mappingCount: Int): (PCalAssignmentLhs, PCalAssignmentLhs=>PCalAssignmentLhs) = { + assert(mappingCount >= 0) + @tailrec + def findDepth(lhs: PCalAssignmentLhs, acc: Int = 0): Int = + lhs match { + case PCalAssignmentLhsIdentifier(_) => acc + case PCalAssignmentLhsProjection(lhs, _) => findDepth(lhs, acc + 1) + } + + val depth = findDepth(lhs) + @tailrec + def findMappedLhs(lhs: PCalAssignmentLhs, layersToDiscard: Int): PCalAssignmentLhs = { + assert(layersToDiscard >= 0) + if(layersToDiscard == 0) { + replaceRef(lhs) + } else { + val PCalAssignmentLhsProjection(innerLhs, _) = lhs + findMappedLhs(innerLhs, layersToDiscard - 1) + } + } + // FIXME: the wrapper for when depth > mappingCount + (findMappedLhs(lhs, depth - mappingCount), identity) + } + + def convertLhs(lhs: PCalAssignmentLhs): TLAExpression = + lhs match { + case lhs@PCalAssignmentLhsIdentifier(identifier) => + TLAGeneralIdentifier(identifier, Nil) + .setRefersTo(lhs.refersTo) + case PCalAssignmentLhsProjection(lhs, projections) => + TLAFunctionCall(convertLhs(lhs), projections) + } + + val withReads@PCalAssignment(List(PCalAssignmentPair(lhs, rhs))) = updateReads(stmt) + findRef(lhs).flatMap { + case ident if mappingsMap.contains(ident.refersTo) => + val (mappingCount, mapping) = mappingsMap(ident.refersTo) + val (mappedLhs, lhsReplacer) = splitLhs(lhs, mappingCount) + val convertedLhs = convertLhs(mappedLhs) + val valueBind = PCalVariableDeclarationValue(TLAIdentifier(nameCleaner.cleanName("value")), rhs) + Some { + PCalWith(List(valueBind), mapping.writeBody.mapConserve(_.rewrite(Rewritable.BottomUpOnceStrategy) { + case PCalAssignmentLhsExtension(MPCalDollarVariable()) => + mappedLhs + case TLAExtensionExpression(MPCalDollarValue()) => + TLAGeneralIdentifier(valueBind.name, Nil).setRefersTo(valueBind) + case TLAExtensionExpression(MPCalDollarVariable()) => + convertedLhs + case PCalExtensionStatement(MPCalYield(yieldedExpr)) => + // FIXME: account for "extra" lhs parts + PCalAssignment(List(PCalAssignmentPair(mappedLhs, yieldedExpr))) + })) + } + case _ => None + }.getOrElse(withReads) + case stmt@PCalEither(cases) => + stmt.withChildren(Iterator( + cases.mapConserve(_.mapConserve(updateStmt)) + )) + case stmt@PCalIf(condition, yes, no) => + stmt.withChildren(Iterator( + updateReads(condition), + yes.mapConserve(updateStmt), + no.mapConserve(updateStmt), + )) + case stmt@PCalLabeledStatements(label, statements) => + stmt.withChildren(Iterator(label, statements.mapConserve(updateStmt))) + case PCalMacroCall(_, _) => ??? + case PCalWhile(_, _) => ??? + case stmt@PCalWith(variables, body) => + stmt.withChildren(Iterator( + variables.mapConserve(updateReads(_)), + body.mapConserve(updateStmt), + )) case PCalExtensionStatement(MPCalCall(target, arguments)) => - ??? + ??? // TODO: correctly handle refs, that is, ensure that the mpcal procedure is instantiated correctly, + // and that substitutions are also applied correctly + // (substitutions will remove refs/function mappings, by design, but also breaking procedure signatures) + case stmt => updateReads(stmt) } + stmtSink(unwrappedStmt) } // TODO: single-process MPCal @@ -38,7 +199,7 @@ object MPCalPCalCodegenPass { case instance @MPCalInstance(selfDecl, fairness, archetypeName, arguments, mappings) => val archetype = instance.refersTo - val substitutionsBuilder = immutable.Map.newBuilder[RefersTo.HasReferences,DefinitionOne] + val substitutionsBuilder = mutable.Buffer.empty[(RefersTo.HasReferences,DefinitionOne)] val variables = archetype.variables.iterator.map { v => val clone = v.shallowCopy() substitutionsBuilder += v -> clone @@ -54,147 +215,26 @@ object MPCalPCalCodegenPass { variables += PCalVariableDeclarationValue(param.name, expr) substitutionsBuilder += param -> variables.last } - val substitutions = substitutionsBuilder.result() + val substitutions = IdMap.from(substitutionsBuilder) val mappingsMap = mappings.iterator.map { case mapping @MPCalMapping(MPCalMappingTarget(index, mappingCount), _) => val param = archetype.params(index) (param: DefinitionOne) -> (mappingCount, mapping.refersTo) - }.toMap - - def updateStmt(stmt: PCalStatement): PCalStatement = { - // TODO: how to "interpolate" the mapping macro stmts into a read/write - // - in any case, rename any local bindings in the read body - // - for write, force the write into whatever nested position. there will only be one per nested stmt, so no need to worry about side-effects - // - for read, more care is needed: the value that was read should be bound via "with" where it logically appears, and - // further read macros should be expanded inside the with body. if a yield is in non-tail position, interaction between multiple applications - // of the same mapping (multiple reads of the same value per-expression) will be unsound, as statements logically "after" the read may appear - // in positions that do not respect logical control flow. Note also that reads are treated syntactically, with the same syntactic read being - // expanded exactly once outside the containing expression, in all cases. - // Function-mapped reads that depend on quantified variables, or LET-bound variables, will not be treated soundly. - import scala.util.control.TailCalls._ - - var stmtSink: TailRec[PCalStatement] => PCalStatement = _.result - - object MappedRead { - @tailrec - private def unapplyImpl(rewritable: Rewritable, mappingCount: Int): Option[(Int,TLAGeneralIdentifier)] = - rewritable match { - case TLAFunctionCall(fn, _) => - unapplyImpl(fn, mappingCount + 1) - case ident: TLAGeneralIdentifier => Some((mappingCount, ident)) - case _ => None - } - - def unapply(rewritable: Rewritable): Option[(Int,TLAGeneralIdentifier)] = - unapplyImpl(rewritable, mappingCount = 0) - } - - def updateReads[T <: Rewritable](t: T): T = { - var result: T = t - result = t.rewrite(Rewritable.TopDownFirstStrategy) { - case expr@ MappedRead(mappingCount, ident) => - mappingsMap.get(ident.refersTo) match { - case Some((expectedMappingCount, mapping)) if expectedMappingCount == mappingCount => - val mappedBind = PCalVariableDeclarationValue(???, expr.asInstanceOf[TLAExpression]) - - stmtSink = { innerStmt => - stmtSink(innerStmt.flatMap { innerStmt => - done(PCalWith(List(mappedBind), - mapping.readBody.mapConserve { stmt => - stmt.rewrite(Rewritable.TopDownFirstStrategy) { - case PCalExtensionStatement(MPCalYield(expr)) => - val yieldedBind = PCalVariableDeclarationValue(???, expr) - PCalWith(List(yieldedBind), List(innerStmt)) - } - } - )) - }) - } - - ??? //TLAGeneralIdentifier(???, Nil).setRefersTo(yieldedBind) - case _ => expr - } - } - - result = t.rewrite(Rewritable.BottomUpOnceStrategy) { - case ident: TLAGeneralIdentifier if substitutions.contains(ident.refersTo) => - val replacement = substitutions(ident.refersTo) - ident.shallowCopy().copy(name = replacement.identifier.asInstanceOf[Definition.ScopeIdentifierName].name).setRefersTo(replacement) - } - result - } - - stmtSink(done { - stmt match { - case stmt: PCalAssignment => - @tailrec - def getRef(lhs: PCalAssignmentLhs): Option[DefinitionOne] = - lhs match { - case ident: PCalAssignmentLhsIdentifier => Some(ident.refersTo) - case PCalAssignmentLhsProjection(lhs, _) => getRef(lhs) - case PCalAssignmentLhsExtension(_) => None - } - - /*@tailrec - def findReceiver(lhs: PCalAssignmentLhs, mappingCount: Int): (PCalAssignmentLhs, ) = { - assert(mappingCount >= 0) - if (mappingCount == 0) lhs else { - lhs match { - case PCalAssignmentLhsIdentifier(identifier) => ??? - case PCalAssignmentLhsProjection(lhs, projections) => - findReceiver(lhs, mappingCount - 1) - case PCalAssignmentLhsExtension(contents) => ??? - } - } - }*/ - - val withReads@PCalAssignment(List(PCalAssignmentPair(lhs, rhs))) = updateReads(stmt) - getRef(lhs).flatMap { ref => - mappingsMap.get(ref).map { - case (mappingCount, MPCalMappingMacro(name, readBody, writeBody, freeVars)) => - //val receiver = findReceiver(lhs, mappingCount) - - ??? - } - }.getOrElse(withReads) - case stmt@PCalEither(cases) => - stmt.withChildren(Iterator( - cases.mapConserve(_.mapConserve(updateStmt)) - )) - case stmt@PCalIf(condition, yes, no) => - stmt.withChildren(Iterator( - updateReads(condition), - yes.mapConserve(updateStmt), - no.mapConserve(updateStmt), - )) - case stmt@PCalLabeledStatements(label, statements) => - stmt.withChildren(Iterator(label, statements.mapConserve(updateStmt))) - case PCalMacroCall(_, _) => ??? - case PCalWhile(_, _) => ??? - case stmt@PCalWith(variables, body) => - stmt.withChildren(Iterator( - variables.mapConserve(updateReads), - body.mapConserve(updateStmt), - )) - case PCalExtensionStatement(MPCalCall(target, arguments)) => - ??? // TODO: correctly handle refs, that is, ensure that the mpcal procedure is instantiated correctly, - // and that substitutions are also applied correctly - // (substitutions will remove refs/function mappings, by design, but also breaking procedure signatures) - case stmt => - updateReads(stmt) - } - }) - } + }.to(IdMap) - generatedPCalProcesses += PCalProcess(selfDecl, fairness, variables.result(), ???) - .setSourceLocation(instance.sourceLocation) + generatedPCalProcesses += PCalProcess( + selfDecl, fairness, variables.result(), + archetype.body.mapConserve(updateStmt(_)(substitutions = substitutions, mappingsMap = mappingsMap)) + ).setSourceLocation(instance.sourceLocation) instance // return the instance unchanged; we got what we came for - case PCalProcess(selfDecl, fairness, variables, body) => - ??? - case PCalProcedure(name, params, variables, body) => - ??? + case proc@PCalProcess(selfDecl, fairness, variables, body) => + proc.withChildren(Iterator(selfDecl, fairness, variables, + body.mapConserve(updateStmt(_)(substitutions = IdMap.empty, mappingsMap = IdMap.empty)))) + case proc@PCalProcedure(name, params, variables, body) => + proc.withChildren(Iterator(name, params, variables, + body.mapConserve(updateStmt(_)(substitutions = IdMap.empty, mappingsMap = IdMap.empty)))) } rewritten.copy( diff --git a/src/pgo/trans/MPCalSemanticCheckPass.scala b/src/pgo/trans/MPCalSemanticCheckPass.scala index 6aa99a06b..aa89b12b3 100644 --- a/src/pgo/trans/MPCalSemanticCheckPass.scala +++ b/src/pgo/trans/MPCalSemanticCheckPass.scala @@ -233,7 +233,7 @@ object MPCalSemanticCheckPass { lhs match { case PCalAssignmentLhsIdentifier(identifier) => identifier case PCalAssignmentLhsProjection(lhs, _) => getId(lhs) - case PCalAssignmentLhsExtension(TLAExtensionExpression(MPCalDollarVariable())) => TLAIdentifier("$variable") // hack to model special var + case PCalAssignmentLhsExtension(MPCalDollarVariable()) => TLAIdentifier("$variable") // hack to model special var } val lhsId = getId(lhs) diff --git a/src/pgo/trans/PCalRenderPass.scala b/src/pgo/trans/PCalRenderPass.scala index 33d84ee60..ec582b06f 100644 --- a/src/pgo/trans/PCalRenderPass.scala +++ b/src/pgo/trans/PCalRenderPass.scala @@ -208,6 +208,8 @@ object PCalRenderPass { case TLAOperatorDefinition(name, args, body, isLocal) => d"${if(isLocal && !ignoreLocal) d"LOCAL " else d""}${ name match { + case Definition.ScopeIdentifierName(name) if args.isEmpty => + d"${name.id} == ${describeExpr(body)}" case Definition.ScopeIdentifierName(name) => d"${name.id}(${args.view.map(describeOpDecl).separateBy(d", ")}) == ${describeExpr(body)}" case Definition.ScopeIdentifierSymbol(symbol) => @@ -254,6 +256,8 @@ object PCalRenderPass { d"${describeLhs(lhs)}[${projections.view.map(describeExpr).separateBy(d", ")}]" case PCalAssignmentLhsExtension(MPCalDollarVariable()) => d"$$variable" + case PCalAssignmentLhsExtension(contents) => + d"?? ${contents.toString} ??" } pairs.view.map { @@ -390,7 +394,7 @@ object PCalRenderPass { case PCalFairness.WeakFair => d"fair " case PCalFairness.StrongFair => d"fair+ " } - } process (${describeVarDecl(selfDecl)})${ + }process (${describeVarDecl(selfDecl)})${ if(variables.nonEmpty) { d"\nvariables${ variables.view.map { decl => @@ -401,7 +405,7 @@ object PCalRenderPass { }\n{\n${ describeStatements(body).indented }\n}" - }.flattenDescriptions + }.flattenDescriptions.indented } }\n}" } diff --git a/src/pgo/util/NameCleaner.scala b/src/pgo/util/NameCleaner.scala index 616a67d94..488dd8a6a 100644 --- a/src/pgo/util/NameCleaner.scala +++ b/src/pgo/util/NameCleaner.scala @@ -25,6 +25,7 @@ class NameCleaner { hintCounterAcc(hint) = currSuffix + 1 currName } else { + namesSeen += hint hint } } diff --git a/test/files/pcalgen/dqueue.tla b/test/files/pcalgen/dqueue.tla index 125df98a8..398c7d38f 100644 --- a/test/files/pcalgen/dqueue.tla +++ b/test/files/pcalgen/dqueue.tla @@ -41,7 +41,7 @@ CONSTANTS BUFFER_SIZE, NUM_CONSUMERS, PRODUCER } (* consumer: Processes one element read from the network at a time, infinitely *) - archetype AConsumer(ref net, ref proc) { + archetype AConsumer(ref net[_], ref proc) { c: while (TRUE) { (* request more data to the producer by sending your own identifier over the network *) @@ -53,7 +53,7 @@ CONSTANTS BUFFER_SIZE, NUM_CONSUMERS, PRODUCER } } - archetype AProducer(ref net, s) + archetype AProducer(ref net[_], ref s) variable requester; { p: while (TRUE) { (* wait for a consumer to request data *) @@ -68,9 +68,9 @@ CONSTANTS BUFFER_SIZE, NUM_CONSUMERS, PRODUCER processor = 0, stream = 0; - fair process (Consumer \in 1..NUM_CONSUMERS) == instance AConsumer(ref network, ref processor) + fair process (Consumer \in 1..NUM_CONSUMERS) == instance AConsumer(ref network[_], ref processor) mapping network[_] via TCPChannel; - fair process (Producer \in {PRODUCER}) == instance AProducer(ref network, stream) + fair process (Producer \in {PRODUCER}) == instance AProducer(ref network[_], ref stream) mapping network[_] via TCPChannel mapping stream via CyclicReads; } diff --git a/test/pgo/PCalGenFileTests.scala b/test/pgo/PCalGenFileTests.scala index e73d67376..3b1e9968e 100644 --- a/test/pgo/PCalGenFileTests.scala +++ b/test/pgo/PCalGenFileTests.scala @@ -1,5 +1,9 @@ package pgo +import com.github.difflib.{DiffUtils, UnifiedDiffUtils} + +import scala.jdk.CollectionConverters._ + class PCalGenFileTests extends FileTestSuite { override val testFiles: List[os.Path] = (os.list.stream(os.pwd / "test" / "files" / "pcalgen") ++ os.list.stream(os.pwd / "test" / "files" / "semantics")) @@ -12,7 +16,19 @@ class PCalGenFileTests extends FileTestSuite { val errors = PGo.run(Seq("pcalgen", "-s", tmpFile.toString())) checkErrors(errors, testFile) if(errors.isEmpty) { - // TODO: check PCal compilation + val expectedFile = testFile / os.up / s"${testFile.last}.expectpcal" + val expectedLines = if(os.exists(expectedFile)) os.read.lines(expectedFile) else IndexedSeq.empty + val actualLines = os.read.lines(tmpFile) + + val patch = DiffUtils.diff(expectedLines.asJava, actualLines.asJava) + val diff = UnifiedDiffUtils.generateUnifiedDiff("expected", "actual", expectedLines.asJava, patch, 5) + + withClue(diff.asScala.mkString("\n")) { + if(expectedLines != actualLines) { + os.write.over(testFile / os.up / s"${testFile.last}.outpcal", data = tmpFile.toSource) + fail(s"expected PCal codegen did not match actual") + } + } } } } diff --git a/test/pgo/model/RewritableTests.scala b/test/pgo/model/RewritableTests.scala new file mode 100644 index 000000000..f2d50aec1 --- /dev/null +++ b/test/pgo/model/RewritableTests.scala @@ -0,0 +1,29 @@ +package pgo.model + +import org.scalatest.funsuite.AnyFunSuite + +// can't be fields of an object; it messes with constructor signature +sealed abstract class Node extends Rewritable +final case class Split(left: Node, right: Node) extends Node +final case class Def(i: Int) extends Node with RefersTo.HasReferences +final case class Ref() extends Node with RefersTo[Def] + +class RewritableTests extends AnyFunSuite { + private val d1 = Def(1) + private val d2 = Def(2) + private val ast1 = Split(d1, Ref().setRefersTo(d1)) + + test("namedParts returns immediate sub-nodes") { + assert(ast1.namedParts.toList == List(d1)) + } + + test("rewrite preserves cross-references") { + val ast2 = ast1.rewrite(Rewritable.BottomUpOnceStrategy) { + case `d1` => d2 + } + + assert(ast2.left eq d2) + assert(ast2.right.asInstanceOf[Ref].refersTo eq d2) + } + +} From 6f72bdd927ec158239ff6d232ca73353b8d9b9aa Mon Sep 17 00:00:00 2001 From: fhackett Date: Thu, 6 May 2021 23:22:23 -0700 Subject: [PATCH 06/27] WIP: implement desugaring to single-variable assignment in pcalgen --- src/pgo/model/pcal/AST.scala | 4 +- src/pgo/trans/MPCalNormalizePass.scala | 41 +++---- src/pgo/trans/MPCalPCalCodegenPass.scala | 139 ++++++++++++++++------- src/pgo/trans/PCalRenderPass.scala | 2 +- src/pgo/util/Unreachable.scala | 7 ++ 5 files changed, 119 insertions(+), 74 deletions(-) create mode 100644 src/pgo/util/Unreachable.scala diff --git a/src/pgo/model/pcal/AST.scala b/src/pgo/model/pcal/AST.scala index 6f6c62880..50a362b72 100644 --- a/src/pgo/model/pcal/AST.scala +++ b/src/pgo/model/pcal/AST.scala @@ -61,9 +61,7 @@ final case class PCalAssignmentPair(lhs: PCalAssignmentLhs, rhs: TLAExpression) sealed abstract class PCalAssignmentLhs extends PCalNode final case class PCalAssignmentLhsIdentifier(identifier: TLAIdentifier) extends PCalAssignmentLhs with RefersTo[DefinitionOne] final case class PCalAssignmentLhsProjection(lhs: PCalAssignmentLhs, projections: List[TLAExpression]) extends PCalAssignmentLhs -final case class PCalAssignmentLhsExtension(contents: Any) extends PCalAssignmentLhs { - assert(!contents.isInstanceOf[TLAGeneralIdentifier]) -} +final case class PCalAssignmentLhsExtension(contents: Any) extends PCalAssignmentLhs final case class PCalAwait(condition: TLAExpression) extends PCalStatement diff --git a/src/pgo/trans/MPCalNormalizePass.scala b/src/pgo/trans/MPCalNormalizePass.scala index 1b3b4aae6..5d91bfc0c 100644 --- a/src/pgo/trans/MPCalNormalizePass.scala +++ b/src/pgo/trans/MPCalNormalizePass.scala @@ -6,6 +6,7 @@ import pgo.model.pcal._ import pgo.model.tla._ import pgo.util.{Description, IdMap, MPCalPassUtils, NameCleaner} import Description._ +import pgo.util.Unreachable.!!! import scala.annotation.tailrec @@ -73,10 +74,8 @@ object MPCalNormalizePass { val (yesTrans, yesBlocks) = impl(yes, labelAfter, Iterator.empty, Iterator.empty) val (noTrans, noBlocks) = impl(no, labelAfter, Iterator.empty, Iterator.empty) (stmt.withChildren(Iterator(condition, yesTrans, noTrans)), yesBlocks ++ noBlocks) - case PCalLabeledStatements(label, statements) => ??? // should be inaccessible; handled via other cases - case stmt @PCalWhile(condition, body) => - val (bodyTrans, bodyBlocks) = impl(body, labelAfter, Iterator.empty, Iterator.empty) - (stmt.withChildren(Iterator(condition, bodyTrans)), bodyBlocks) + case PCalLabeledStatements(_, _) => !!! // should be inaccessible; handled via other cases + case PCalWhile(_, _) => !!! // see above case stmt @PCalWith(variables, body) => val (bodyTrans, bodyBlocks) = impl(body, labelAfter, Iterator.empty, Iterator.empty) assert(bodyBlocks.isEmpty) @@ -119,7 +118,17 @@ object MPCalNormalizePass { transBlocks(restStmts.asInstanceOf[List[PCalLabeledStatements]], labelAfter, blocksOut ++ jumpTrans.iterator.flatMap(_._2))) case stmt :: restStmts => val (stmtTrans, stmtBlocks) = transStmt(stmt, findLabelAfter(restStmts, labelAfter)) - impl(restStmts, labelAfter, stmtsOut ++ Iterator.single(stmtTrans), blocksOut ++ stmtBlocks) + // if: + // 1. restStmts is empty + // 2. stmt had sub-statements (proxy: the translation was one of the compound expressions we don't desugar), and we had a labelAfter + // then stmt will have our final gotos embedded into it, so we should _not_ add our own + // otherwise, we should keep looking for places to add synthetic gotos + val effectiveLabelAfter = + stmtTrans match { + case PCalEither(_) | PCalIf(_, _, _) | PCalWith(_, _) if restStmts.isEmpty => None + case _ => labelAfter + } + impl(restStmts, effectiveLabelAfter, stmtsOut ++ Iterator.single(stmtTrans), blocksOut ++ stmtBlocks) } } @@ -135,28 +144,6 @@ object MPCalNormalizePass { } } - /*// desugar while loops into ifs and gotos - // note: the statements after the while go inside the _else branch_, as evidenced by a label not being needed - // after a label-containing while statement (if it were equivalent to an if with statements after it, a label would be needed) - block = block.rewrite(Rewritable.BottomUpOnceStrategy) { - case labeledStmts @PCalLabeledStatements(label, (whileStmt @PCalWhile(condition, body)) :: restStmts) => - def pushDownGoto(goto: PCalStatement, stmts: List[PCalStatement]): List[PCalStatement] = - stmts match { - case Nil => goto :: Nil - case (labeled@PCalLabeledStatements(label, stmts)) :: Nil => - labeled.withChildren(Iterator(label, pushDownGoto(goto, stmts))) :: Nil - case hd :: tl => hd :: pushDownGoto(goto, tl) - } - - PCalLabeledStatements( - label, - List(PCalIf( - condition, - pushDownGoto(PCalGoto(label.name).setSourceLocation(whileStmt.sourceLocation.derivedVia(d"while statement desugaring")), body), - restStmts).setSourceLocation(whileStmt.sourceLocation.derivedVia(d"while statement desugaring"))) - ).setSourceLocation(labeledStmts.sourceLocation) - }*/ - // needed below: gather all names, to generate synthetic ones for multiple assignment temp vars val nameCleaner = new NameCleaner MPCalPassUtils.forEachName(tlaModule, block)(nameCleaner.addKnownName) diff --git a/src/pgo/trans/MPCalPCalCodegenPass.scala b/src/pgo/trans/MPCalPCalCodegenPass.scala index def3810d5..99f091401 100644 --- a/src/pgo/trans/MPCalPCalCodegenPass.scala +++ b/src/pgo/trans/MPCalPCalCodegenPass.scala @@ -1,13 +1,14 @@ package pgo.trans -import pgo.model.{Definition, DefinitionOne, PGoError, RefersTo, Rewritable, SourceLocation, Visitable} +import pgo.model.{Definition, DefinitionOne, PGoError, RefersTo, Rewritable, Visitable} import pgo.model.mpcal._ import pgo.model.pcal._ import pgo.model.tla._ -import pgo.util.{IdMap, IdSet, NameCleaner} +import pgo.util.Unreachable.!!! +import pgo.util.{IdMap, NameCleaner} import scala.annotation.tailrec -import scala.collection.{immutable, mutable} +import scala.collection.mutable object MPCalPCalCodegenPass { @throws[PGoError] @@ -51,38 +52,39 @@ object MPCalPCalCodegenPass { unapplyImpl(expr, mappingCount = 0) } - def updateStmt(stmt: PCalStatement)(implicit mappingsMap: IdMap[DefinitionOne,(Int,MPCalMappingMacro)], substitutions: IdMap[RefersTo.HasReferences,DefinitionOne]): PCalStatement = { - var stmtSink: PCalStatement => PCalStatement = identity + def updateStmt(stmt: PCalStatement)(implicit mappingsMap: IdMap[DefinitionOne,(Int,MPCalMappingMacro)], substitutions: IdMap[RefersTo.HasReferences,DefinitionOne]): List[PCalStatement] = { + var stmtSink: List[PCalStatement] => List[PCalStatement] = identity def updateReads[E <: Rewritable](expr: E, skipMappings: Boolean = false): E = expr.rewrite(Rewritable.TopDownFirstStrategy) { case expr@MappedRead(mappingCount, ident) if !skipMappings && mappingsMap.get(ident.refersTo).exists(_._1 == mappingCount) => val (_, mapping) = mappingsMap(ident.refersTo) - val mappedBind = PCalVariableDeclarationValue(TLAIdentifier(nameCleaner.cleanName("value")), updateReads(expr, skipMappings = true)) + val translatedExpr = updateReads(expr, skipMappings = true) + def translateLhs(expr: TLAExpression): PCalAssignmentLhs = + expr match { + case expr@TLAGeneralIdentifier(name, Nil) => PCalAssignmentLhsIdentifier(name).setRefersTo(expr.refersTo) + case TLAFunctionCall(fn, arguments) => PCalAssignmentLhsProjection(translateLhs(fn), arguments) + } + + val translatedLhs = translateLhs(translatedExpr) + val placeholder = PCalVariableDeclarationValue(TLAIdentifier("THIS_IS_A_BUG"), TLAString("THIS IS A BUG")) - stmtSink = { innerStmt => - stmtSink { - PCalWith(List(mappedBind), - mapping.readBody.mapConserve(_.rewrite(Rewritable.BottomUpOnceStrategy) { - case PCalAssignmentLhsExtension(MPCalDollarVariable()) => - val sub = substitutions(ident.refersTo) - PCalAssignmentLhsIdentifier(sub.identifier.asInstanceOf[Definition.ScopeIdentifierName].name) - .setRefersTo(sub) - case TLAExtensionExpression(MPCalDollarVariable()) => - val sub = substitutions(ident.refersTo) - TLAGeneralIdentifier(sub.identifier.asInstanceOf[Definition.ScopeIdentifierName].name, Nil) - .setRefersTo(sub) - case PCalExtensionStatement(MPCalYield(valExpr)) => - val yieldedBind = PCalVariableDeclarationValue(TLAIdentifier(nameCleaner.cleanName("yielded")), valExpr) - PCalWith(List(yieldedBind), List( - innerStmt.rewrite(Rewritable.BottomUpOnceStrategy) { - case ident: TLAGeneralIdentifier if ident.refersTo eq placeholder => - TLAGeneralIdentifier(yieldedBind.name, Nil).setRefersTo(yieldedBind) - } - )) - }) - ) + val oldStmtSink = stmtSink + stmtSink = { innerStmts => + oldStmtSink { + mapping.readBody.mapConserve(_.rewrite(Rewritable.BottomUpOnceStrategy) { + case PCalAssignmentLhsExtension(MPCalDollarVariable()) => translatedLhs + case TLAExtensionExpression(MPCalDollarVariable()) => translatedExpr + case PCalExtensionStatement(MPCalYield(valExpr)) => + val yieldedBind = PCalVariableDeclarationValue(TLAIdentifier(nameCleaner.cleanName("yielded")), valExpr) + PCalWith(List(yieldedBind), + innerStmts.mapConserve(_.rewrite(Rewritable.BottomUpOnceStrategy) { + case ident: TLAGeneralIdentifier if ident.refersTo eq placeholder => + TLAGeneralIdentifier(yieldedBind.name, Nil).setRefersTo(yieldedBind) + }) + ) + }) } } TLAGeneralIdentifier(placeholder.name, Nil).setRefersTo(placeholder) @@ -105,7 +107,9 @@ object MPCalPCalCodegenPass { def replaceRef(lhs: PCalAssignmentLhs): PCalAssignmentLhs = lhs match { case ident: PCalAssignmentLhsIdentifier if substitutions.contains(ident.refersTo) => - ident.shallowCopy().setRefersTo(substitutions(ident.refersTo)) + val sub = substitutions(ident.refersTo) + PCalAssignmentLhsIdentifier(sub.identifier.asInstanceOf[Definition.ScopeIdentifierName].name) + .setRefersTo(sub) case ident: PCalAssignmentLhsIdentifier => ident case proj@PCalAssignmentLhsProjection(lhs, projections) => proj.withChildren(Iterator(replaceRef(lhs), projections)) @@ -168,22 +172,22 @@ object MPCalPCalCodegenPass { }.getOrElse(withReads) case stmt@PCalEither(cases) => stmt.withChildren(Iterator( - cases.mapConserve(_.mapConserve(updateStmt)) + cases.map(_.flatMap(updateStmt)) )) case stmt@PCalIf(condition, yes, no) => stmt.withChildren(Iterator( updateReads(condition), - yes.mapConserve(updateStmt), - no.mapConserve(updateStmt), + yes.flatMap(updateStmt), + no.flatMap(updateStmt), )) case stmt@PCalLabeledStatements(label, statements) => - stmt.withChildren(Iterator(label, statements.mapConserve(updateStmt))) - case PCalMacroCall(_, _) => ??? - case PCalWhile(_, _) => ??? + stmt.withChildren(Iterator(label, statements.flatMap(updateStmt))) + case PCalMacroCall(_, _) => !!! + case PCalWhile(_, _) => !!! case stmt@PCalWith(variables, body) => stmt.withChildren(Iterator( variables.mapConserve(updateReads(_)), - body.mapConserve(updateStmt), + body.flatMap(updateStmt), )) case PCalExtensionStatement(MPCalCall(target, arguments)) => ??? // TODO: correctly handle refs, that is, ensure that the mpcal procedure is instantiated correctly, @@ -191,7 +195,7 @@ object MPCalPCalCodegenPass { // (substitutions will remove refs/function mappings, by design, but also breaking procedure signatures) case stmt => updateReads(stmt) } - stmtSink(unwrappedStmt) + stmtSink(List(unwrappedStmt)) } // TODO: single-process MPCal @@ -209,7 +213,7 @@ object MPCalPCalCodegenPass { case Left(arg @MPCalRefExpr(_, _)) -> param => substitutionsBuilder += param -> arg.refersTo case Left(arg @MPCalValExpr(_, _)) -> param => - variables += PCalVariableDeclarationValue(param.name, TLAGeneralIdentifier(arg.name, Nil)) + variables += PCalVariableDeclarationValue(param.name, TLAGeneralIdentifier(arg.name, Nil).setRefersTo(arg.refersTo)) substitutionsBuilder += param -> variables.last case Right(expr) -> param => variables += PCalVariableDeclarationValue(param.name, expr) @@ -225,20 +229,21 @@ object MPCalPCalCodegenPass { generatedPCalProcesses += PCalProcess( selfDecl, fairness, variables.result(), - archetype.body.mapConserve(updateStmt(_)(substitutions = substitutions, mappingsMap = mappingsMap)) + archetype.body.flatMap(updateStmt(_)(substitutions = substitutions, mappingsMap = mappingsMap)) ).setSourceLocation(instance.sourceLocation) instance // return the instance unchanged; we got what we came for case proc@PCalProcess(selfDecl, fairness, variables, body) => proc.withChildren(Iterator(selfDecl, fairness, variables, - body.mapConserve(updateStmt(_)(substitutions = IdMap.empty, mappingsMap = IdMap.empty)))) + body.flatMap(updateStmt(_)(substitutions = IdMap.empty, mappingsMap = IdMap.empty)))) case proc@PCalProcedure(name, params, variables, body) => proc.withChildren(Iterator(name, params, variables, - body.mapConserve(updateStmt(_)(substitutions = IdMap.empty, mappingsMap = IdMap.empty)))) + body.flatMap(updateStmt(_)(substitutions = IdMap.empty, mappingsMap = IdMap.empty)))) } rewritten.copy( pcalProcedures = generatedPCalProcedures.result(), + mappingMacros = Nil, mpcalProcedures = Nil, instances = Nil, processes = rewritten.processes match { @@ -249,8 +254,56 @@ object MPCalPCalCodegenPass { Right(existingProcs ::: generatedPCalProcesses.result()) }) } - // expand archetypes + mapping macros (using list buffer accumulator for add'l stmts) + mpcal procedures - // ensure single assignment to each var + + // desugar all non-trivial (e.g just to a name) assignments, using the TLA+ EXCEPT expression where appropriate + // rationale: this makes it a lot easier to repair any "multiple write within same label" issues induced by MPCal expansion + // as plain assignments match with statement semantics, vs. just needing to do the same transformation in-line + // with repairs anyway, which is more complicated + block = block.rewrite(Rewritable.BottomUpOnceStrategy) { + case PCalAssignment(List(PCalAssignmentPair(lhs, rhs))) => + @tailrec + def findIdent(lhs: PCalAssignmentLhs): PCalAssignmentLhsIdentifier = + lhs match { + case lhs: PCalAssignmentLhsIdentifier => lhs + case PCalAssignmentLhsProjection(lhs, _) => findIdent(lhs) + } + + @tailrec + def findSubstitutionKeys(lhs: PCalAssignmentLhs, keysAcc: mutable.ListBuffer[TLAFunctionSubstitutionKey]): List[TLAFunctionSubstitutionKey] = + lhs match { + case PCalAssignmentLhsIdentifier(_) => keysAcc.result() + case PCalAssignmentLhsProjection(lhs, projections) => + keysAcc += TLAFunctionSubstitutionKey(projections) + findSubstitutionKeys(lhs, keysAcc) + } + + val ident = findIdent(lhs) + val substitutionKeys = findSubstitutionKeys(lhs, mutable.ListBuffer.empty) + val wrappedRhs = + if(substitutionKeys.isEmpty) { + rhs + } else { + TLAFunctionSubstitution( + source = TLAGeneralIdentifier(ident.identifier, Nil).setRefersTo(ident.refersTo), + substitutions = List(TLAFunctionSubstitutionPair( + anchor = TLAFunctionSubstitutionPairAnchor(), + keys = substitutionKeys, + value = rhs)) + ) + } + + PCalAssignment(List(PCalAssignmentPair(ident, wrappedRhs))) + } + + // TODO: deduplicate repeat assignments within the same label, by lifting non-final assignments to with statements + /*block = locally { + + + block.rewrite(Rewritable.TopDownFirstStrategy) { + case PCalLabeledStatements(label, body) => + ??? + } + }*/ PCalAlgorithm( name = block.name, diff --git a/src/pgo/trans/PCalRenderPass.scala b/src/pgo/trans/PCalRenderPass.scala index ec582b06f..e1d457363 100644 --- a/src/pgo/trans/PCalRenderPass.scala +++ b/src/pgo/trans/PCalRenderPass.scala @@ -330,7 +330,7 @@ object PCalRenderPass { val header = fairness match { case PCalFairness.Unfair => d"--algorithm" case PCalFairness.WeakFair => d"--fair algorithm" - case PCalFairness.StrongFair => ??? + case PCalFairness.StrongFair => d"--fair+ algorithm" // TODO: is this correct? we can't parse this } d"$header ${name.id} {${ diff --git a/src/pgo/util/Unreachable.scala b/src/pgo/util/Unreachable.scala new file mode 100644 index 000000000..82fcc79ad --- /dev/null +++ b/src/pgo/util/Unreachable.scala @@ -0,0 +1,7 @@ +package pgo.util + +case class Unreachable() extends RuntimeException("this code should never be reached") + +object Unreachable { + def !!! : Nothing = throw Unreachable() +} From aefedc80568c837b119165001f36afced67d2353 Mon Sep 17 00:00:00 2001 From: fhackett Date: Fri, 7 May 2021 05:12:52 -0700 Subject: [PATCH 07/27] WIP: pcalgen mode implementation almost-complete; missing MPCal procedure support + some rare mapping cases --- src/pgo/PGo.scala | 26 +- src/pgo/trans/MPCalNormalizePass.scala | 19 +- src/pgo/trans/MPCalPCalCodegenPass.scala | 150 +- src/pgo/trans/PlusCalCodeGenPassS.txt | 760 ---- test/files/pcalgen/dqueue.tla.expectpcal | 279 ++ .../pcalgen/load_balancer.tla.expectpcal | 573 +++ .../pcalgen/replicated_kv.tla.expectpcal | 3170 +++++++++++++++++ 7 files changed, 4189 insertions(+), 788 deletions(-) delete mode 100644 src/pgo/trans/PlusCalCodeGenPassS.txt create mode 100644 test/files/pcalgen/dqueue.tla.expectpcal create mode 100644 test/files/pcalgen/load_balancer.tla.expectpcal create mode 100644 test/files/pcalgen/replicated_kv.tla.expectpcal diff --git a/src/pgo/PGo.scala b/src/pgo/PGo.scala index 71a4b432d..9c4c0b2d1 100644 --- a/src/pgo/PGo.scala +++ b/src/pgo/PGo.scala @@ -2,13 +2,13 @@ package pgo import geny.Generator import org.rogach.scallop -import org.rogach.scallop.{ScallopConf, Subcommand} +import org.rogach.scallop.{ScallopConf, ScallopOption, Subcommand, ValueConverter} +import os.Path import pgo.model.{PGoError, SourceLocation} import pgo.model.mpcal.MPCalBlock import pgo.model.tla.TLAModule import pgo.parser.{MPCalParser, TLAParser} import pgo.trans.{MPCalGoCodegenPass, MPCalNormalizePass, MPCalPCalCodegenPass, MPCalSemanticCheckPass, PCalRenderPass} - import pgo.util.Description._ import java.io.RandomAccessFile @@ -17,12 +17,12 @@ import java.nio.charset.StandardCharsets import scala.util.Using object PGo { - implicit val pathConverter = scallop.singleArgConverter(os.Path(_, os.pwd)) + implicit val pathConverter: ValueConverter[Path] = scallop.singleArgConverter(os.Path(_, os.pwd)) class Config(arguments: Seq[String]) extends ScallopConf(arguments) { banner("PGo compiler") trait Cmd { self: ScallopConf => - val specFile = opt[os.Path](required = true) + val specFile: ScallopOption[Path] = opt[os.Path](required = true) addValidation { if(os.exists(specFile())) { Right(()) @@ -32,8 +32,8 @@ object PGo { } } object GoGenCmd extends Subcommand("gogen") with Cmd { - val outFile = opt[os.Path](required = true) - val packageName = opt[String](required = false) + val outFile: ScallopOption[Path] = opt[os.Path](required = true) + val packageName: ScallopOption[String] = opt[String](required = false) } addSubcommand(GoGenCmd) object PCalGenCmd extends Subcommand("pcalgen") with Cmd { @@ -94,8 +94,8 @@ object PGo { val tempOutput = os.temp.apply(dir = os.pwd) locally { - val PCalBeginTranslation = raw"""\\*\s+BEGIN\s+PLUSCAL\s+TRANSLATION""".r - val PCalEndTranslation = raw"""\\*\s+END\s+PLUSCAL\s+TRANSLATION""".r + val PCalBeginTranslation = raw"""\s*\\\*\s+BEGIN\s+PLUSCAL\s+TRANSLATION""".r + val PCalEndTranslation = raw"""\s*\\\*\s+END\s+PLUSCAL\s+TRANSLATION""".r val renderedPCalIterator = Iterator("", "", "\\* BEGIN PLUSCAL TRANSLATION") ++ renderedPCal.linesIterator ++ @@ -104,7 +104,7 @@ object PGo { var pcalBeginFound = false var pcalEndFound = false - os.write.over(tempOutput, (os.read.lines.stream(config.PCalGenCmd.specFile()).zipWithIndex.flatMap { + os.write.over(tempOutput, os.read.lines.stream(config.PCalGenCmd.specFile()).zipWithIndex.flatMap { case (PCalBeginTranslation(), lineIdx) if !pcalBeginFound => assert(!pcalEndFound, s"at line ${lineIdx+1}, found PLUSCAL END TRANSLATION comment before PLUSCAL BEGIN TRANSLATION") pcalBeginFound = true @@ -117,9 +117,11 @@ object PGo { // skip all lines between begin and end of translation Generator() case (line, _) => Iterator(line) - } ++ Generator.selfClosing { - (if(!pcalBeginFound) renderedPCalIterator else Iterator.empty, () => ()) - }).map(line => s"$line\n")) + }.map(line => s"$line\n")) + + assert(pcalBeginFound && pcalEndFound, + s"""one or both of "\\* PLUSCAL BEGIN TRANSLATION" and "\\* PLUSCAL END TRANSLATION" not found; + |add these tags so that PGo knows where to put its generated PlusCal""".stripMargin) } // move the rendered output over the spec file, replacing it os.move(from = tempOutput, to = config.PCalGenCmd.specFile(), replaceExisting = true, atomicMove = true) diff --git a/src/pgo/trans/MPCalNormalizePass.scala b/src/pgo/trans/MPCalNormalizePass.scala index 5d91bfc0c..475406a10 100644 --- a/src/pgo/trans/MPCalNormalizePass.scala +++ b/src/pgo/trans/MPCalNormalizePass.scala @@ -119,16 +119,17 @@ object MPCalNormalizePass { case stmt :: restStmts => val (stmtTrans, stmtBlocks) = transStmt(stmt, findLabelAfter(restStmts, labelAfter)) // if: - // 1. restStmts is empty + // 1. restStmts is empty, or labeled // 2. stmt had sub-statements (proxy: the translation was one of the compound expressions we don't desugar), and we had a labelAfter - // then stmt will have our final gotos embedded into it, so we should _not_ add our own - // otherwise, we should keep looking for places to add synthetic gotos - val effectiveLabelAfter = - stmtTrans match { - case PCalEither(_) | PCalIf(_, _, _) | PCalWith(_, _) if restStmts.isEmpty => None - case _ => labelAfter - } - impl(restStmts, effectiveLabelAfter, stmtsOut ++ Iterator.single(stmtTrans), blocksOut ++ stmtBlocks) + // then stmt will have our final gotos embedded into it, so we should _not_ add our own (which is what will happen if we just recurse on restStmts) + // otherwise, we recurse normally, and will keep looking for places to add synthetic gotos + stmtTrans match { + case PCalEither(_) | PCalIf(_, _, _) | PCalWith(_, _) if restStmts.isEmpty || restStmts.head.isInstanceOf[PCalLabeledStatements] => + assert(restStmts.forall(_.isInstanceOf[PCalLabeledStatements])) + ((stmtsOut ++ Iterator.single(stmtTrans)).toList, transBlocks(restStmts.asInstanceOf[List[PCalLabeledStatements]], labelAfter, blocksOut)) + case _ => + impl(restStmts, labelAfter, stmtsOut ++ Iterator.single(stmtTrans), blocksOut ++ stmtBlocks) + } } } diff --git a/src/pgo/trans/MPCalPCalCodegenPass.scala b/src/pgo/trans/MPCalPCalCodegenPass.scala index 99f091401..a63cb2139 100644 --- a/src/pgo/trans/MPCalPCalCodegenPass.scala +++ b/src/pgo/trans/MPCalPCalCodegenPass.scala @@ -32,7 +32,7 @@ object MPCalPCalCodegenPass { block = locally { val generatedPCalProcedures = mutable.ListBuffer[PCalProcedure]() val generatedPCalProcesses = mutable.ListBuffer[PCalProcess]() - // mpcal procedure expansion signature: + // TODO mpcal procedure expansion signature: // - identity of the mpcal procedure being expanded // - for a ref param, the identity of the param referenced (or, the expression, if that's the case), and the identity of the mapping to be applied // - for a non-ref [_] param, the identity of the mapping to be applied (but not the identity of what is referenced, as it is taken by-value) @@ -77,7 +77,7 @@ object MPCalPCalCodegenPass { case PCalAssignmentLhsExtension(MPCalDollarVariable()) => translatedLhs case TLAExtensionExpression(MPCalDollarVariable()) => translatedExpr case PCalExtensionStatement(MPCalYield(valExpr)) => - val yieldedBind = PCalVariableDeclarationValue(TLAIdentifier(nameCleaner.cleanName("yielded")), valExpr) + val yieldedBind = PCalVariableDeclarationValue(TLAIdentifier(nameCleaner.cleanName(s"yielded_${ident.name.id}")), valExpr) PCalWith(List(yieldedBind), innerStmts.mapConserve(_.rewrite(Rewritable.BottomUpOnceStrategy) { case ident: TLAGeneralIdentifier if ident.refersTo eq placeholder => @@ -295,15 +295,151 @@ object MPCalPCalCodegenPass { PCalAssignment(List(PCalAssignmentPair(ident, wrappedRhs))) } - // TODO: deduplicate repeat assignments within the same label, by lifting non-final assignments to with statements - /*block = locally { + // deduplicate repeat assignments within the same label, by lifting non-final assignments to with statements + // rough strategy: + // 1. count assignments to each variable within a given block (group of labeled statements), over-approximating branches + // 2. have a memoized (maybe efficient) way to query the assignment counters over a given list of stmts + // 3. while folding statements after any branching statement into each branch (causing AST duplication, yes)... + // 3a. for any assignment to a variable whose count in the remaining statements (aka. the rest of that control flow path) + // is >= 1, lift that statement into a with-binding. record which assigned variables are "lifted" like this + // 3b. for any assignment to a variable whose count in the remaining statements is 0 (aka. is the last one, or the only) + // ensure that records of any with-bindings are removed. this variable is "normally assigned" again. + // 4. when the end of a path is reached, generate synthetic assignments from any remaining "lifted" vars to the actual variable + block = locally { + implicit class CountOps(val self: IdMap[DefinitionOne,Int]) { + def +++(other: IdMap[DefinitionOne,Int]): IdMap[DefinitionOne,Int] = + (self.keysIterator ++ other.keysIterator).map { defn => + defn -> (self.getOrElse(defn, 0) + other.getOrElse(defn, 0)) + }.to(IdMap) + def |||(other: IdMap[DefinitionOne,Int]): IdMap[DefinitionOne,Int] = + (self.keysIterator ++ other.keysIterator).map { defn => + defn -> (self.getOrElse(defn, 0) max other.getOrElse(defn, 0)) + }.to(IdMap) + } block.rewrite(Rewritable.TopDownFirstStrategy) { - case PCalLabeledStatements(label, body) => - ??? + case labeldStmts@PCalLabeledStatements(label, body) => + var assignmentCountsStmt = IdMap.empty[PCalStatement,IdMap[DefinitionOne,Int]] + + def calculateAssignmentCounts(body: List[PCalStatement]): IdMap[DefinitionOne,Int] = { + var result = IdMap.empty[DefinitionOne,Int] + body.foreach(_.visit(Visitable.TopDownFirstStrategy) { + case stmt: PCalStatement if assignmentCountsStmt.contains(stmt) => assignmentCountsStmt(stmt) + case PCalIf(_, yes, no) => + result +++= (calculateAssignmentCounts(yes) ||| calculateAssignmentCounts(no)) + case PCalEither(cases) => + result +++= cases.iterator.map(calculateAssignmentCounts).reduce(_ ||| _) + case PCalAssignment(List(PCalAssignmentPair(lhs: PCalAssignmentLhsIdentifier, _))) => + result = result.updated(lhs.refersTo, result.getOrElse(lhs.refersTo, 0) + 1) + }) + result + } + + body.foreach(_.visit(Visitable.BottomUpFirstStrategy) { + case stmt: PCalStatement => + val counts = calculateAssignmentCounts(List(stmt)) + assignmentCountsStmt = assignmentCountsStmt.updated(stmt, counts) + }) + + var assignmentCountsMap = IdMap.empty[List[PCalStatement],IdMap[DefinitionOne,Int]] + def assignmentCounts(stmts: List[PCalStatement]): IdMap[DefinitionOne,Int] = + assignmentCountsMap.getOrElse(stmts, { + val result = stmts match { + case Nil => IdMap.empty[DefinitionOne,Int] + case hd :: tl => assignmentCountsStmt(hd) +++ assignmentCounts(tl) + } + assignmentCountsMap = assignmentCountsMap.updated(stmts, result) + result + }) + + object TailJumpStmts { + // match all cases where a block of PCal ends in a jump + def unapply(stmts: List[PCalStatement]): Option[List[PCalStatement]] = + stmts match { + case PCalGoto(_) :: Nil => Some(stmts) + case PCalCall(_, _) :: (((PCalReturn() | PCalGoto(_)) :: Nil) | Nil) => Some(stmts) + case PCalExtensionStatement(MPCalCall(_, _)) :: (((PCalReturn() | PCalGoto(_)) :: Nil) | Nil) => Some(stmts) + case Nil => Some(Nil) + case _ => None + } + } + + def impl(stmts: List[PCalStatement], substitutions: IdMap[DefinitionOne,DefinitionOne], lifted: List[(DefinitionOne,DefinitionOne)]): List[PCalStatement] = { + def performSubstitutions(stmt: PCalStatement): PCalStatement = + stmt.rewrite(Rewritable.BottomUpOnceStrategy) { + case ident@TLAGeneralIdentifier(_, pfx) if substitutions.contains(ident.refersTo) => + val sub = substitutions(ident.refersTo) + ident.withChildren(Iterator(sub.identifier.asInstanceOf[Definition.ScopeIdentifierName].name, pfx)).setRefersTo(sub) + } + + @tailrec + def endsInJump(stmts: List[PCalStatement]): Boolean = + stmts match { + case TailJumpStmts(stmts) if stmts.nonEmpty => true + case _ :: tl => endsInJump(tl) + case Nil => false + } + + // concatenates two blocks, but only if the "first" block won't jump away, making the second unreachable + // if that would be the case, it just returns the first block + def jumpAwareConcat(beforeStmts: List[PCalStatement], afterStmts: List[PCalStatement]): List[PCalStatement] = + if(endsInJump(beforeStmts)) { + beforeStmts + } else { + beforeStmts ::: afterStmts + } + + stmts match { + case TailJumpStmts(tailStmts) => + // make "official" any prior writes bound to "with" stmts which were not written out already + lifted.map { + case liftedFrom -> liftedTo => + PCalAssignment(List(PCalAssignmentPair( + PCalAssignmentLhsIdentifier(liftedFrom.identifier.asInstanceOf[Definition.ScopeIdentifierName].name).setRefersTo(liftedFrom), + TLAGeneralIdentifier(liftedTo.identifier.asInstanceOf[Definition.ScopeIdentifierName].name, Nil).setRefersTo(liftedTo), + ))) + } ::: tailStmts.mapConserve(performSubstitutions) // make sure call args get replaced, because they might use with-bound names that have changed + case hd :: tl => + val hdRewritten = performSubstitutions(hd) + hdRewritten match { + case PCalAssignment(List(PCalAssignmentPair(lhs: PCalAssignmentLhsIdentifier, rhs))) if assignmentCounts(tl).getOrElse(lhs.refersTo, 0) >= 1 => + val rebind = PCalVariableDeclarationValue(TLAIdentifier(nameCleaner.cleanName(lhs.identifier.id)), rhs) + List(PCalWith(List(rebind), + impl(tl, substitutions.updated(lhs.refersTo, rebind), (lhs.refersTo, rebind) :: lifted) + )) + case stmt @PCalAssignment(List(PCalAssignmentPair(lhs: PCalAssignmentLhsIdentifier, _))) if assignmentCounts(tl).getOrElse(lhs.refersTo, 0) == 0 => + // if this was the last assignment, leave it intact, and remove data that would have a second "last assignment" generated at end of block + stmt :: impl(tl, substitutions - lhs.refersTo, lifted.filter(_._1 ne lhs.refersTo)) + case PCalWith(bindings, body) if tl.isEmpty => + List(PCalWith(bindings, impl(body, substitutions, lifted))) + case PCalWith(bindings, body) => + // push the remaining statements inside the body, so lifted assignments are guaranteed to be in scope + // for the entire critical section. to avoid name collisions, conservatively rename all bindings to fresh names + val renamedbBindings = bindings.map { + case PCalVariableDeclarationValue(name, value) => + PCalVariableDeclarationValue(TLAIdentifier(nameCleaner.cleanName(name.id)), value) + case PCalVariableDeclarationSet(name, set) => + PCalVariableDeclarationSet(TLAIdentifier(nameCleaner.cleanName(name.id)), set) + } + List(PCalWith(renamedbBindings, + impl(body ::: tl, substitutions ++ (bindings.iterator zip renamedbBindings), lifted))) + case PCalIf(cond, yes, no) => + List(PCalIf( + cond, + impl(jumpAwareConcat(yes, tl), substitutions, lifted), + impl(jumpAwareConcat(no, tl), substitutions, lifted))) + case PCalEither(cases) => + List(PCalEither(cases.map(cse => impl(jumpAwareConcat(cse, tl), substitutions, lifted)))) + case stmt => + stmt :: impl(tl, substitutions, lifted) + } + } + } + + labeldStmts.withChildren(Iterator(label, impl(body, IdMap.empty, Nil))) } - }*/ + } PCalAlgorithm( name = block.name, diff --git a/src/pgo/trans/PlusCalCodeGenPassS.txt b/src/pgo/trans/PlusCalCodeGenPassS.txt deleted file mode 100644 index a2061f673..000000000 --- a/src/pgo/trans/PlusCalCodeGenPassS.txt +++ /dev/null @@ -1,760 +0,0 @@ -package pgo.trans - -import pgo.model.tla._ -import pgo.trans.intermediate.UnsupportedFeatureIssue -import pgo.trans.passes.codegen.NameCleaner -import pgo.trans.passes.codegen.pluscal.ExpandedProcedureMatch -import pgo.trans.passes.codegen.pluscal.NameCleanerSeedGatherer.gatherNameCleanerSeed - -import scala.collection.{View, mutable} -import scala.jdk.CollectionConverters._ - -final case class PlusCalCodeGenPassContext(nameCleaner: NameCleaner, - proceduresToExpand: Map[String,PlusCalProcedure], - expandedProcedures: mutable.ListBuffer[PlusCalProcedure], - expandedProcedureCache: mutable.HashMap[ExpandedProcedureMatch,PlusCalProcedure], - mappingMacros: Map[String,ModularPlusCalMappingMacro], - archetypes: Map[String,ModularPlusCalArchetype]) - -object PlusCalCodeGenPassS { - abstract class MappingMacroReadExpander { - def expand(readVar: TLAExpression, readSink: TLAExpression=>List[PlusCalStatement]): List[PlusCalStatement] - } - abstract class MappingMacroWriteExpander { - def expand(writeVar: TLAExpression, writeSink: TLAExpression=>List[PlusCalStatement]): List[PlusCalStatement] - } - final class MappingMacroExpander(val read: MappingMacroReadExpander, val write: MappingMacroWriteExpander, val isFnMapped: Boolean) - - private final case class ProcedureExpansionSignature(procUID: UID, macroParams: List[Option[TLARef]]) - - class ReadWriteReferencesCounter { self => - type CountsMap = Map[TLADefinitionOne,Int] - private val underlying = mutable.HashMap[PlusCalStatement,(CountsMap,CountsMap)]() - private val underlyingAggregates = mutable.HashMap[View[PlusCalStatement],(CountsMap,CountsMap)]() - - private def implExpr(expr: TLAExpression): CountsMap = - TLAUtils.mapReduceExpr(Map.empty: CountsMap) { - case ident: TLAGeneralIdentifier => - join( - Map(ident.getRefersTo -> 1), - ident.prefix.view.flatMap(part => part.getParameters.asScala.view.map(implExpr)).reduce(join)) - case ref: TLARef => - Map(ref.getRefersTo -> 1) - }(join)(expr) - - private def join(left: CountsMap, right: CountsMap): CountsMap = - (View.from(left) ++ right).groupMapReduce(_._1)(_._2)(_ + _) - - private def join(lefts: (CountsMap,CountsMap), rights: (CountsMap,CountsMap)): (CountsMap,CountsMap) = - (join(lefts._1, rights._1), join(lefts._2, rights._2)) - - def apply(stmt: PlusCalStatement): (CountsMap, CountsMap) = - underlying.getOrElseUpdate(stmt, { - stmt.accept(new PlusCalStatementVisitor[(CountsMap,CountsMap),RuntimeException] { - private def emptyPair: (CountsMap,CountsMap) = (Map.empty, Map.empty) - override def visit(plusCalLabeledStatements: PlusCalLabeledStatements): (CountsMap,CountsMap) = - self(plusCalLabeledStatements.statements) - override def visit(plusCalWhile: PlusCalWhile): (CountsMap,CountsMap) = ??? - override def visit(plusCalIf: PlusCalIf): (CountsMap,CountsMap) = ??? - override def visit(plusCalEither: PlusCalEither): (CountsMap,CountsMap) = ??? - override def visit(plusCalAssignment: PlusCalAssignment): (CountsMap,CountsMap) = - plusCalAssignment.getPairs.asScala.view.map { pair => - def implLhs(lhs: TLAExpression): (CountsMap,CountsMap) = - lhs match { - case ident: TLAGeneralIdentifier => - (Map.empty, Map(ident.getRefersTo -> 1)) - case dot: TLADot => implLhs(dot.getExpression) - case fnCall: TLAFunctionCall => - val (innerReads, innerWrites) = implLhs(fnCall.getFunction) - val paramReads = fnCall.getParams.asScala.view.map(implExpr).reduce(join) - (join(paramReads, innerReads), innerWrites) - } - val (lhsReads, lhsWrites) = implLhs(pair.getLhs) - (join(lhsReads, implExpr(pair.getRhs)), lhsWrites) - }.reduce(join) - override def visit(plusCalReturn: PlusCalReturn): (CountsMap,CountsMap) = emptyPair - override def visit(plusCalSkip: PlusCalSkip): (CountsMap,CountsMap) = emptyPair - override def visit(plusCalCall: PlusCalCall): (CountsMap,CountsMap) = ??? - override def visit(macroCall: PlusCalMacroCall): (CountsMap,CountsMap) = ??? - override def visit(plusCalWith: PlusCalWith): (CountsMap,CountsMap) = ??? - override def visit(plusCalPrint: PlusCalPrint): (CountsMap,CountsMap) = ??? - override def visit(plusCalAssert: PlusCalAssert): (CountsMap,CountsMap) = ??? - override def visit(plusCalAwait: PlusCalAwait): (CountsMap,CountsMap) = ??? - override def visit(plusCalGoto: PlusCalGoto): (CountsMap,CountsMap) = ??? - override def visit(modularPlusCalYield: ModularPlusCalYield): (CountsMap,CountsMap) = ??? - }) - }) - - def apply(stmts: Iterable[PlusCalStatement]): (CountsMap,CountsMap) = - underlyingAggregates.getOrElseUpdate(stmts.view, { - if(stmts.isEmpty) { - (Map.empty, Map.empty) - } else { - join(self(stmts.head), self(stmts.view.tail)) - } - }) - } - - private object LhsHead { - def unapply(expr: TLAExpression): Option[TLAGeneralIdentifier] = - expr match { - case ident: TLAGeneralIdentifier => Some(ident) - case dot: TLADot => LhsHead.unapply(dot.getExpression) - case fnCall: TLAFunctionCall => LhsHead.unapply(fnCall.getFunction) - case _ => None - } - } - - def pcalStatementExpandMacros(statement: PlusCalStatement, mappingMacros: Map[TLADefinitionOne, MappingMacroExpander], macros: Map[String,PlusCalMacro], nameCleaner: NameCleaner): List[PlusCalStatement] = { - - def readExprs(exprs: List[TLAExpression], body: List[TLAExpression]=>List[PlusCalStatement]): List[PlusCalStatement] = { - def impl(elems: List[TLAExpression], convertedExprs: List[TLAExpression]): List[PlusCalStatement] = - elems match { - case Nil => - body(convertedExprs.reverse) - case hd :: tl => - implExprRead(hd, { hdRead => - impl(tl, hdRead :: convertedExprs) - }) - } - impl(exprs, Nil) - } - - def readGeneralIdentifierPrefix(parts: List[TLAGeneralIdentifierPart], body: List[TLAGeneralIdentifierPart]=>List[PlusCalStatement]): List[PlusCalStatement] = { - def impl(parts: List[TLAGeneralIdentifierPart], readParts: List[TLAGeneralIdentifierPart]): List[PlusCalStatement] = - parts match { - case Nil => - body(readParts.reverse) - case part :: restParts => - readExprs(part.getParameters.asScala.toList, { paramsRead => - impl(restParts, new TLAGeneralIdentifierPart(part.getLocation, part.getIdentifier, paramsRead.asJava) :: readParts) - }) - } - impl(parts, Nil) - } - - def implExprRead(expr: TLAExpression, body: TLAExpression=>List[PlusCalStatement]): List[PlusCalStatement] = { - object MappingMacroCandidate { - def unapply(expr: TLAExpression): Option[TLAGeneralIdentifier] = - expr match { - case ident: TLAGeneralIdentifier => Some(ident) - case fnCall: TLAFunctionCall => - fnCall.getFunction match { - case ident: TLAGeneralIdentifier => - // match a function call iff the mapping macro is function-mapped - mappingMacros.get(ident.getRefersTo).flatMap { mm => - if(mm.isFnMapped) Some(ident) else None - } - case _ => None - } - case _ => None - } - } - expr match { - case MappingMacroCandidate(ident) if mappingMacros.contains(ident.getRefersTo) => - // edge case: if expr is a function call and its arguments are candidates for mapping macro expansion, - // expand those before the current mapping macro - def preprocessExpr(expr: TLAExpression, body: TLAExpression=>List[PlusCalStatement]): List[PlusCalStatement] = - expr match { - case _: TLAGeneralIdentifier => body(expr) - case fnCall: TLAFunctionCall => - readExprs(fnCall.getParams.asScala.toList, { paramsRead => - body(new TLAFunctionCall(fnCall.getLocation, fnCall.getFunction, paramsRead.asJava)) - }) - } - preprocessExpr(expr, { expr => - val macroExpander = mappingMacros(ident.getRefersTo) - assert(ident.prefix.isEmpty) - macroExpander.read.expand(expr, { expr => - // make sure the value that was read is immediately bound by a with statement, to avoid any assignments - // nested inside `body` interfering with any variable reads nested inside the value's expression - val tmpVarName = new TLAIdentifier(ident.getLocation, nameCleaner.cleanName(ident.name.getId)) - val tmpVarDecl = new PlusCalVariableDeclaration(ident.getLocation, tmpVarName, false, false, expr) - val tmpGeneralIdent = new TLAGeneralIdentifier(ident.getLocation, tmpVarName, Nil) - tmpGeneralIdent.setRefersTo(tmpVarDecl) - List(new PlusCalWith(ident.getLocation, List(tmpVarDecl).asJava, body(tmpGeneralIdent).asJava)) - }) - }) - case _ => - expr.accept(new TLAExpressionVisitor[List[PlusCalStatement],RuntimeException] { - override def visit(tlaFunctionCall: TLAFunctionCall): List[PlusCalStatement] = - readExprs(tlaFunctionCall.getParams.asScala.toList, { readParams => - implExprRead(tlaFunctionCall.getFunction, { fnRead => - body(new TLAFunctionCall(tlaFunctionCall.getLocation, fnRead, readParams.asJava)) - }) - }) - override def visit(tlaBinOp: TLABinOp): List[PlusCalStatement] = - readGeneralIdentifierPrefix(tlaBinOp.getPrefix.asScala.toList, { prefixRead => - readExprs(List(tlaBinOp.getLHS, tlaBinOp.getRHS), { - case List(lhsRead, rhsRead) => - val op = new TLABinOp(tlaBinOp.getLocation, tlaBinOp.getOperation, prefixRead.asJava, lhsRead, rhsRead) - op.setRefersTo(tlaBinOp.getRefersTo) - body(op) - }) - }) - override def visit(tlaBool: TLABool): List[PlusCalStatement] = body(tlaBool) - override def visit(tlaCase: TLACase): List[PlusCalStatement] = ??? - override def visit(tlaDot: TLADot): List[PlusCalStatement] = - implExprRead(tlaDot.getExpression, { exprRead => - body(new TLADot(tlaDot.getLocation, exprRead, tlaDot.getField)) - }) - override def visit(tlaExistential: TLAExistential): List[PlusCalStatement] = ??? - override def visit(tlaFairness: TLAFairness): List[PlusCalStatement] = ??? - override def visit(tlaFunction: TLAFunction): List[PlusCalStatement] = ??? - override def visit(tlaFunctionSet: TLAFunctionSet): List[PlusCalStatement] = ??? - override def visit(tlaFunctionSubstitution: TLAFunctionSubstitution): List[PlusCalStatement] = - implExprRead(tlaFunctionSubstitution.getSource, { sourceRead => - def readSubstitutionPairs(substitutions: List[TLAFunctionSubstitutionPair], substitutionsRead: List[TLAFunctionSubstitutionPair]): List[PlusCalStatement] = - substitutions match { - case Nil => - body(new TLAFunctionSubstitution(tlaFunctionSubstitution.getLocation, sourceRead, substitutionsRead.reverse.asJava)) - case sub :: restSubs => - def readKeys(keys: List[TLASubstitutionKey], readKeysAcc: List[TLASubstitutionKey]): List[PlusCalStatement] = - keys match { - case Nil => - implExprRead(sub.getValue, { readValue => - readSubstitutionPairs(restSubs, new TLAFunctionSubstitutionPair(sub.getLocation, readKeysAcc.reverse.asJava, readValue) :: restSubs) - }) - case key :: restKeys => - readExprs(key.getIndices.asScala.toList, { indicesRead => - readKeys(restKeys, new TLASubstitutionKey(key.getLocation, indicesRead.asJava) :: readKeysAcc) - }) - } - readKeys(sub.getKeys.asScala.toList, Nil) - } - readSubstitutionPairs(tlaFunctionSubstitution.getSubstitutions.asScala.toList, Nil) - }) - override def visit(tlaIf: TLAIf): List[PlusCalStatement] = - readExprs(List(tlaIf.getCond, tlaIf.getTval, tlaIf.getFval), { - case List(readCond, readTVal, readFVal) => - body(new TLAIf(tlaIf.getLocation, readCond, readTVal, readFVal)) - }) - override def visit(tlaLet: TLALet): List[PlusCalStatement] = ??? - override def visit(tlaGeneralIdentifier: TLAGeneralIdentifier): List[PlusCalStatement] = - readGeneralIdentifierPrefix(tlaGeneralIdentifier.prefix, { prefixRead => - body(new TLAGeneralIdentifier(tlaGeneralIdentifier.getLocation, tlaGeneralIdentifier.name, prefixRead)) - }) - override def visit(tlaTuple: TLATuple): List[PlusCalStatement] = - readExprs(tlaTuple.getElements.asScala.toList, { readExprs => - body(new TLATuple(tlaTuple.getLocation, readExprs.reverse.asJava)) - }) - override def visit(tlaMaybeAction: TLAMaybeAction): List[PlusCalStatement] = ??? // makes no sense here - override def visit(tlaNumber: TLANumber): List[PlusCalStatement] = body(tlaNumber) - override def visit(tlaOperatorCall: TLAOperatorCall): List[PlusCalStatement] = ??? - override def visit(tlaQuantifiedExistential: TLAQuantifiedExistential): List[PlusCalStatement] = ??? - override def visit(tlaQuantifiedUniversal: TLAQuantifiedUniversal): List[PlusCalStatement] = ??? - override def visit(tlaRecordConstructor: TLARecordConstructor): List[PlusCalStatement] = ??? - override def visit(tlaRecordSet: TLARecordSet): List[PlusCalStatement] = ??? - override def visit(tlaRef: TLARef): List[PlusCalStatement] = ??? - override def visit(tlaRequiredAction: TLARequiredAction): List[PlusCalStatement] = ??? - override def visit(tlaSetConstructor: TLASetConstructor): List[PlusCalStatement] = ??? - override def visit(tlaSetComprehension: TLASetComprehension): List[PlusCalStatement] = ??? - override def visit(tlaSetRefinement: TLASetRefinement): List[PlusCalStatement] = ??? - override def visit(tlaSpecialVariableVariable: TLASpecialVariableVariable): List[PlusCalStatement] = ??? - override def visit(tlaSpecialVariableValue: TLASpecialVariableValue): List[PlusCalStatement] = ??? - override def visit(tlaString: TLAString): List[PlusCalStatement] = body(tlaString) - override def visit(tlaUnary: TLAUnary): List[PlusCalStatement] = ??? - override def visit(tlaUniversal: TLAUniversal): List[PlusCalStatement] = ??? - override def visit(plusCalDefaultInitValue: PlusCalDefaultInitValue): List[PlusCalStatement] = ??? - }) - } - } - - def substExpr(expr: TLAExpression)(implicit subst: Map[TLADefinitionOne,TLAExpression]): TLAExpression = - TLAUtils.rewriteExprPre { - case ident: TLAGeneralIdentifier if subst.contains(ident.getRefersTo) => - subst(ident.getRefersTo) - case ref: TLARef if subst.contains(ref.getRefersTo) => - ??? - }(expr) - - def implStmt(stmt: PlusCalStatement)(implicit subst: Map[TLADefinitionOne,TLAExpression], visitedMacros: Set[String]): List[PlusCalStatement] = - stmt.accept(new PlusCalStatementVisitor[List[PlusCalStatement],RuntimeException] { - override def visit(plusCalLabeledStatements: PlusCalLabeledStatements): List[PlusCalStatement] = - List(new PlusCalLabeledStatements( - plusCalLabeledStatements.getLocation, - plusCalLabeledStatements.label, - plusCalLabeledStatements.statements.flatMap(implStmt))) - override def visit(plusCalWhile: PlusCalWhile): List[PlusCalStatement] = ??? // unreachable - override def visit(plusCalIf: PlusCalIf): List[PlusCalStatement] = - // note: this, and several other cases, prevents a predictable translation of statements located after a yield - // expression in a mapping macro, due to what might happen if multiple reads occur in one expression. TODO: reject these cases? - implExprRead(substExpr(plusCalIf.getCondition), { readCondition => - List(new PlusCalIf( - plusCalIf.getLocation, - readCondition, - plusCalIf.getYes.asScala.flatMap(implStmt).asJava, - plusCalIf.getNo.asScala.flatMap(implStmt).asJava)) - }) - override def visit(plusCalEither: PlusCalEither): List[PlusCalStatement] = - List(new PlusCalEither(plusCalEither.getLocation, plusCalEither.getCases.asScala.map { caseStmts => - caseStmts.asScala.flatMap(implStmt).asJava - }.asJava)) - override def visit(plusCalAssignment: PlusCalAssignment): List[PlusCalStatement] = - readExprs(plusCalAssignment.getPairs.asScala.iterator.map(_.getRhs).toList, { readExprs => - val bindingVarDecls = readExprs.map { readExpr => - val tmpVarName = new TLAIdentifier(readExpr.getLocation, nameCleaner.cleanName("assignRhs")) - new PlusCalVariableDeclaration(readExpr.getLocation, tmpVarName, false, false, readExpr) - } - val boundRhss = bindingVarDecls.map { varDecl => - val ident = new TLAGeneralIdentifier(varDecl.getLocation, varDecl.getName, Nil) - ident.setRefersTo(varDecl) - ident - } - val body = (plusCalAssignment.getPairs.asScala.iterator zip boundRhss).flatMap { - case (assignmentPair, boundRhs) => - substExpr(assignmentPair.getLhs) match { - case lhsSubst @LhsHead(ident) if mappingMacros.contains(ident.getRefersTo) => - val mappingMacroExpander = mappingMacros(ident.getRefersTo) - mappingMacroExpander.write.expand(lhsSubst, { exprWrite => - List(new PlusCalAssignment( - assignmentPair.getLocation, - List(new PlusCalAssignmentPair(assignmentPair.getLocation, lhsSubst, exprWrite)).asJava)) - }) - case lhsSubst => - List(new PlusCalAssignment( - assignmentPair.getLocation, - List(new PlusCalAssignmentPair(assignmentPair.getLocation, lhsSubst, boundRhs)).asJava)) - } - }.toList - List(new PlusCalWith(plusCalAssignment.getLocation, bindingVarDecls.asJava, body.asJava)) - }) - override def visit(plusCalReturn: PlusCalReturn): List[PlusCalStatement] = List(plusCalReturn) - override def visit(plusCalSkip: PlusCalSkip): List[PlusCalStatement] = List(plusCalSkip) - override def visit(plusCalCall: PlusCalCall): List[PlusCalStatement] = ??? // TODO - override def visit(macroCall: PlusCalMacroCall): List[PlusCalStatement] = { - if(visitedMacros(macroCall.getTarget)) { - ??? - } - val mcr = macros(macroCall.getTarget) - assert(mcr.getParams.asScala.size == macroCall.getArguments.asScala.size) - val innerSubst = subst ++ (mcr.getParams.asScala.view zip macroCall.getArguments.asScala.view.map(substExpr)) - mcr.getBody.asScala.view.flatMap(implStmt(_)(subst = innerSubst, visitedMacros = visitedMacros + mcr.getName)).toList - } - override def visit(plusCalWith: PlusCalWith): List[PlusCalStatement] = - readExprs(plusCalWith.getVariables.asScala.iterator.map(_.getValue).map(substExpr).toList, { exprsRead => - List(new PlusCalWith(plusCalWith.getLocation, (plusCalWith.getVariables.asScala.iterator zip exprsRead).map { - case (decl, valExpr) => new PlusCalVariableDeclaration(decl.getLocation, decl.getName, decl.isRef, decl.isSet, valExpr) - }.toList.asJava, plusCalWith.getBody.asScala.flatMap(implStmt).asJava)) - }) - override def visit(plusCalPrint: PlusCalPrint): List[PlusCalStatement] = - implExprRead(substExpr(plusCalPrint.getValue), { readVal => - List(new PlusCalPrint(plusCalPrint.getLocation, readVal)) - }) - override def visit(plusCalAssert: PlusCalAssert): List[PlusCalStatement] = - implExprRead(substExpr(plusCalAssert.getCondition), { readCond => - List(new PlusCalAssert(plusCalAssert.getLocation, readCond)) - }) - override def visit(plusCalAwait: PlusCalAwait): List[PlusCalStatement] = - implExprRead(substExpr(plusCalAwait.getCondition), { readCond => - List(new PlusCalAwait(plusCalAwait.getLocation, readCond)) - }) - override def visit(plusCalGoto: PlusCalGoto): List[PlusCalStatement] = List(plusCalGoto) - override def visit(modularPlusCalYield: ModularPlusCalYield): List[PlusCalStatement] = ??? // bad - }) - - implStmt(statement)(subst = Map.empty, visitedMacros = Set.empty) - } - - private final case class TailBlock(loc: SourceLocation, label: PlusCalLabel, stmts: List[PlusCalStatement]) - private final case class TailBlockConversion(unlabeledStmts: mutable.ListBuffer[PlusCalStatement], - tailBlocks: mutable.ListBuffer[TailBlock], - hasFallthrough: Boolean) - - private def pcalStatementsToTailBlockForm(stmts: List[PlusCalStatement], fallthroughLabel: Option[PlusCalLabel]): TailBlockConversion = { - def pcalStatementToTailBlockForm(stmt: PlusCalStatement, fallthroughLabel: Option[PlusCalLabel]): TailBlockConversion = - stmt.accept(new PlusCalStatementVisitor[TailBlockConversion,RuntimeException] { - override def visit(plusCalLabeledStatements: PlusCalLabeledStatements): TailBlockConversion = ??? - - override def visit(plusCalWhile: PlusCalWhile): TailBlockConversion = { - // problem: you need to fall through to the label _above_ the while, easier to just desugar into if + goto - // first - ??? - } - - override def visit(plusCalIf: PlusCalIf): TailBlockConversion = { - val TailBlockConversion(unlabeledStmtsYes, tailBlocksYes, hasFallthroughYes) = - pcalStatementsToTailBlockForm(plusCalIf.getYes.asScala.toList, fallthroughLabel = fallthroughLabel) - val TailBlockConversion(unlabeledStmtsNo, tailBlocksNo, hasFallthroughNo) = - pcalStatementsToTailBlockForm(plusCalIf.getNo.asScala.toList, fallthroughLabel = fallthroughLabel) - - TailBlockConversion( - unlabeledStmts = mutable.ListBuffer( - new PlusCalIf(plusCalIf.getLocation, plusCalIf.getCondition, unlabeledStmtsYes.asJava, unlabeledStmtsNo.asJava)), - tailBlocks = tailBlocksYes ++= tailBlocksNo, - hasFallthrough = hasFallthroughYes || hasFallthroughNo) - } - - override def visit(plusCalEither: PlusCalEither): TailBlockConversion = { - val tailBlockConversions = plusCalEither.getCases.asScala.toList.map { branch => - pcalStatementsToTailBlockForm(branch.asScala.toList, fallthroughLabel = fallthroughLabel) - } - TailBlockConversion( - unlabeledStmts = mutable.ListBuffer( - new PlusCalEither(plusCalEither.getLocation, tailBlockConversions.map(_.unlabeledStmts.asJava).asJava)), - tailBlocks = tailBlockConversions.foldLeft(mutable.ListBuffer[TailBlock]())(_ ++= _.tailBlocks), - hasFallthrough = tailBlockConversions.exists(_.hasFallthrough)) - } - - override def visit(plusCalAssignment: PlusCalAssignment): TailBlockConversion = - TailBlockConversion( - unlabeledStmts = mutable.ListBuffer(plusCalAssignment), - tailBlocks = mutable.ListBuffer(), - hasFallthrough = true) - - override def visit(plusCalReturn: PlusCalReturn): TailBlockConversion = - TailBlockConversion( - unlabeledStmts = mutable.ListBuffer(plusCalReturn), - tailBlocks = mutable.ListBuffer(), - hasFallthrough = false) - - override def visit(plusCalSkip: PlusCalSkip): TailBlockConversion = - TailBlockConversion( - unlabeledStmts = mutable.ListBuffer(plusCalSkip), - tailBlocks = mutable.ListBuffer(), - hasFallthrough = true) - - override def visit(plusCalCall: PlusCalCall): TailBlockConversion = - TailBlockConversion( - unlabeledStmts = mutable.ListBuffer(plusCalCall), - tailBlocks = mutable.ListBuffer(), - hasFallthrough = false) - - override def visit(macroCall: PlusCalMacroCall): TailBlockConversion = { - // problem: what if the macro body ends in a goto? unlikely, but a goto is not a label - // easier to expand macros before doing this - ??? - } - - override def visit(plusCalWith: PlusCalWith): TailBlockConversion = { - val TailBlockConversion(unlabeledStmts, mutable.ListBuffer(), hasFallthrough) = - pcalStatementsToTailBlockForm(plusCalWith.getBody.asScala.toList, fallthroughLabel = fallthroughLabel) - TailBlockConversion( - unlabeledStmts = mutable.ListBuffer( - new PlusCalWith(plusCalWith.getLocation, plusCalWith.getVariables, unlabeledStmts.toList.asJava)), - tailBlocks = mutable.ListBuffer(), - hasFallthrough = hasFallthrough) - } - - override def visit(plusCalPrint: PlusCalPrint): TailBlockConversion = - TailBlockConversion( - unlabeledStmts = mutable.ListBuffer(plusCalPrint), - tailBlocks = mutable.ListBuffer(), - hasFallthrough = true) - - override def visit(plusCalAssert: PlusCalAssert): TailBlockConversion = - TailBlockConversion( - unlabeledStmts = mutable.ListBuffer(plusCalAssert), - tailBlocks = mutable.ListBuffer(), - hasFallthrough = true) - - override def visit(plusCalAwait: PlusCalAwait): TailBlockConversion = - TailBlockConversion( - unlabeledStmts = mutable.ListBuffer(plusCalAwait), - tailBlocks = mutable.ListBuffer(), - hasFallthrough = true) - - override def visit(plusCalGoto: PlusCalGoto): TailBlockConversion = - TailBlockConversion( - unlabeledStmts = mutable.ListBuffer(plusCalGoto), - tailBlocks = mutable.ListBuffer(), - hasFallthrough = false) - - override def visit(modularPlusCalYield: ModularPlusCalYield): TailBlockConversion = - TailBlockConversion( - unlabeledStmts = mutable.ListBuffer(modularPlusCalYield), - tailBlocks = mutable.ListBuffer(), - hasFallthrough = true) - }) - - val unlabeledStmts = stmts.filterNot(_.isInstanceOf[PlusCalLabeledStatements]) - val labeledStmts = stmts.collect { case stmt: PlusCalLabeledStatements => stmt } - - // PCal semantics assertion: any labeled statements must follow unlabeled statements - assert(unlabeledStmts.view ++ labeledStmts == stmts.view) - // each statement has a fallthrough label: - // - any unlabeled statement's fallthrough label is - // a) the first labeled statement's label - // b) the fallthrough label passed in - // - any labeled statement's fallthrough label is: - // a) the next labeled statement's label - // b) if there is no next labeled statement, the passed in fallthrough label - val fallthroughLabels: List[Option[PlusCalLabel]] = - unlabeledStmts.map(_ => labeledStmts.headOption.map(_.label).orElse(fallthroughLabel)) ++ - labeledStmts.tail.map(stmt => Some(stmt.label)) :+ fallthroughLabel - // if this isn't true, we have a problem (PlusCal semantics violation) - assert(fallthroughLabels.size == stmts.size) - - (stmts zip fallthroughLabels).foldLeft(TailBlockConversion(mutable.ListBuffer(), mutable.ListBuffer(), true)) { (acc, pair) => - val (stmt, fallthroughLabel) = pair - (acc, stmt) match { - case (tc @TailBlockConversion(unlabeledStmts, tailBlocks @mutable.ListBuffer(), hasFallthrough), stmt: PlusCalLabeledStatements) => - val TailBlockConversion(innerUnlabeledStmts, innerTailBlocks, innerHasFallthrough) = - pcalStatementsToTailBlockForm(stmt.statements, fallthroughLabel = fallthroughLabel) - - // this is our first label, so we generate a trailing goto that points to it - // ... but only if it doesn't already contain some other control flow - if(hasFallthrough) { - unlabeledStmts += new PlusCalGoto(stmt.label.getLocation, stmt.label.getName) - } - // if the label body has a fallthrough, plug it with a goto to the fallthrough label - if(innerHasFallthrough) { - fallthroughLabel match { - case None => innerUnlabeledStmts += new PlusCalGoto(SourceLocation.unknown(), "done") - case Some(fallthroughLabel) => - innerUnlabeledStmts += new PlusCalGoto(fallthroughLabel.getLocation, fallthroughLabel.getName) - } - } - - tailBlocks += TailBlock(stmt.label.getLocation, stmt.label, innerUnlabeledStmts.toList) - tailBlocks ++= innerTailBlocks - tc.copy(hasFallthrough = false) // can't have fallthrough, we prevented it above - case (tc @TailBlockConversion(unlabeledStmts, tailBlocks @mutable.ListBuffer(), hasFallthrough), stmt) => - val TailBlockConversion(innerUnlabeledStmts, innerTailBlocks, innerHasFallthrough) = - pcalStatementToTailBlockForm(stmt, fallthroughLabel = fallthroughLabel) - unlabeledStmts ++= innerUnlabeledStmts - - // innerTailBlocks may or may not be empty. - // if empty, keep gathering unlabeled stmts - // if not, we should only encounter further labeled statements at this level - tailBlocks ++= innerTailBlocks - // if the statement has a fallthrough, so do we; if it doesn't, we don't either - tc.copy(hasFallthrough = hasFallthrough && innerHasFallthrough) - case (tc @TailBlockConversion(_, tailBlocks, false), stmt: PlusCalLabeledStatements) => - // in case a label has already encountered, we know: - // no fallthrough from previous statement (prev was a label, which prevents this) - val TailBlockConversion(innerUnlabeledStmts, innerTailBlocks, innerHasFallthrough) = - pcalStatementsToTailBlockForm(stmt.statements, fallthroughLabel = fallthroughLabel) - // if the label body has a fallthrough, plug it with a goto - if(innerHasFallthrough) { - fallthroughLabel match { - case None => innerUnlabeledStmts += new PlusCalGoto(SourceLocation.unknown(), "done") - case Some(fallthroughLabel) => - innerUnlabeledStmts += new PlusCalGoto(fallthroughLabel.getLocation, fallthroughLabel.getName) - } - } - tailBlocks += TailBlock(stmt.label.getLocation, stmt.label, innerUnlabeledStmts.toList) - tailBlocks ++= innerTailBlocks - tc - } - } - } - - private def mpcalAdjustAssignments(tailBlockForm: TailBlockConversion, nameCleaner: NameCleaner): TailBlockConversion = { - val countReadWriteReferences = new ReadWriteReferencesCounter - - def implStmts(stmts: List[PlusCalStatement])(implicit lifted: Map[TLADefinitionOne,(TLAGeneralIdentifier,TLAGeneralIdentifier)], - renamings: Map[TLADefinitionOne,SourceLocation=>TLAGeneralIdentifier]): List[PlusCalStatement] = { - stmts match { - case Nil => - lifted.toList.sortBy(_._1.identifier.getId).map { - case (_, (tempBinding, underlyingVar)) => - ??? // TODO: assign temp binding of lifted name to the underlying name, to ensure the resulting value is visible at the next step - } - case stmt :: restStmts => - stmt.accept(new PlusCalStatementVisitor[List[PlusCalStatement],RuntimeException] { - override def visit(plusCalLabeledStatements: PlusCalLabeledStatements): List[PlusCalStatement] = ??? // should be unreachable - override def visit(plusCalWhile: PlusCalWhile): List[PlusCalStatement] = ??? // should be unreachable - override def visit(plusCalIf: PlusCalIf): List[PlusCalStatement] = - List(new PlusCalIf( - plusCalIf.getLocation, - ??? /* TODO: renaming in cond */, - implStmts(plusCalIf.getYes.asScala.toList ::: restStmts).asJava, - implStmts(plusCalIf.getNo.asScala.toList ::: restStmts).asJava)) - override def visit(plusCalEither: PlusCalEither): List[PlusCalStatement] = - List(new PlusCalEither( - plusCalEither.getLocation, - plusCalEither.getCases.asScala.map { cse => - implStmts(cse.asScala.toList ::: restStmts).asJava - }.asJava)) - override def visit(plusCalAssignment: PlusCalAssignment): List[PlusCalStatement] = { - assert(plusCalAssignment.getPairs.asScala.size == 1) - val pair = plusCalAssignment.getPairs.asScala.head - val (readCounts, writeCounts) = countReadWriteReferences(restStmts) - val LhsHead(headIdent) = pair.getLhs - val renamedRhs = ??? // renamed RHS - if(writeCounts.getOrElse(headIdent.getRefersTo, 0) > 0) { - ??? // TODO: insert clean with-binding - // also, ensure the binding is reflected in lifted, so it can be tracked / reverted later, if needed. - // and also, flatten out function-assignment semantics into the appropriate pure record update ops - } else { - val renamedLhs = ??? // renamed RHS - val renamedAssignment = new PlusCalAssignment(plusCalAssignment.getLocation, List( - new PlusCalAssignmentPair(pair.getLocation, renamedLhs, renamedRhs) - ).asJava) - // lifted tracks which names we still need to assign to when we're done. if this counts as a last - // assignment, we're done with it and can discard it. - // this won't happen e.g if one branch of a conditional makes another assignment, but the other does not - renamedAssignment :: implStmts(restStmts)(lifted = lifted.removed(headIdent.getRefersTo), renamings = renamings) - } - } - override def visit(plusCalReturn: PlusCalReturn): List[PlusCalStatement] = - plusCalReturn :: implStmts(restStmts) - override def visit(plusCalSkip: PlusCalSkip): List[PlusCalStatement] = - plusCalSkip :: implStmts(restStmts) - override def visit(plusCalCall: PlusCalCall): List[PlusCalStatement] = ??? - override def visit(macroCall: PlusCalMacroCall): List[PlusCalStatement] = ??? // unreachable - override def visit(plusCalWith: PlusCalWith): List[PlusCalStatement] = { - ??? // TODO: blindly rename the bound name to avoid scoping conflicts, absorb all subsequent stmts - } - override def visit(plusCalPrint: PlusCalPrint): List[PlusCalStatement] = ??? - override def visit(plusCalAssert: PlusCalAssert): List[PlusCalStatement] = ??? - override def visit(plusCalAwait: PlusCalAwait): List[PlusCalStatement] = ??? - override def visit(plusCalGoto: PlusCalGoto): List[PlusCalStatement] = - plusCalGoto :: implStmts(restStmts) - override def visit(modularPlusCalYield: ModularPlusCalYield): List[PlusCalStatement] = ??? // unreachable - }) - } - } - - TailBlockConversion( - unlabeledStmts = implStmts(tailBlockForm.unlabeledStmts.result())(lifted = Map.empty, renamings = Map.empty).to(mutable.ListBuffer), - tailBlocks = tailBlockForm.tailBlocks.mapInPlace { - case TailBlock(loc, label, stmts) => TailBlock(loc, label, implStmts(stmts)(lifted = Map.empty, renamings = Map.empty)) - }, - hasFallthrough = tailBlockForm.hasFallthrough) - } - - def mpcalExpandArchetype(archetype: ModularPlusCalArchetype, instance: ModularPlusCalInstance, - mappingMacros: Map[String, ModularPlusCalMappingMacro], - macros: Map[String,PlusCalMacro], - nameCleaner: NameCleaner): PlusCalProcess = { - val instanceVariables = mutable.ListBuffer[PlusCalVariableDeclaration]() - val exprSubstitutionsBuilder = Map.newBuilder[UID,SourceLocation=>TLAExpression] - - // TODO: add way to avoid adding dummy locals when archetype is well-behaved and doesn't write to a non-ref input - - (archetype.getParams.asScala.iterator zip instance.getArguments.asScala.iterator).foreach { - case (decl, arg: TLARef) => - exprSubstitutionsBuilder += ((decl.getUID, { loc => - val id = new TLAGeneralIdentifier(loc, new TLAIdentifier(loc, arg.getTarget), Nil) - id.setRefersTo(arg.getRefersTo) - id - })) - case (decl, arg: TLAGeneralIdentifier) => - ??? - case (decl, expr) => - val freshName = nameCleaner.cleanName(decl.getName.getId) - val freshId = new TLAIdentifier(expr.getLocation, freshName) - val instanceDecl = new PlusCalVariableDeclaration(expr.getLocation, freshId, false, false, expr) - instanceVariables += instanceDecl - exprSubstitutionsBuilder += ((decl.getUID, { loc => - val id = new TLAGeneralIdentifier(loc, new TLAIdentifier(loc, freshName), Nil) - id.setRefersTo(instanceDecl) - id - })) - } - - val exprSubstitutions = exprSubstitutionsBuilder.result() - - instance.getMappings.asScala.foreach { mapping => - mappingMacros.get(mapping.getTarget.getName) match { - case None => ??? - case Some(mcr) => - val param = mapping.getVariable match { - case name: ModularPlusCalMappingVariableName => - archetype.getParams.asScala.find(_.getName.getId == name.getName).get - case position: ModularPlusCalMappingVariablePosition => - archetype.getParams.asScala.apply(position.getPosition - 1) - case _ => ??? - } - ??? // TODO - } - } - - val mappingMacroExpanders: Map[TLADefinitionOne,MappingMacroExpander] = ??? - - new PlusCalProcess( - instance.getLocation, - instance.getName, - instance.getFairness, - (archetype.getVariables.asScala.toList ++ instanceVariables.toList).asJava, - archetype.getBody.asScala.flatMap(pcalStatementExpandMacros(_, mappingMacroExpanders, macros, nameCleaner)).asJava) - } - - def perform(ctx: IssueContext, tlaModule: TLAModule, modularPlusCalBlock: ModularPlusCalBlock): PlusCalAlgorithm = { - val nameCleanerSeed = (gatherNameCleanerSeed(tlaModule) ++ gatherNameCleanerSeed(modularPlusCalBlock)) - .to(mutable.HashSet) - val nameCleaner = new NameCleaner(nameCleanerSeed.asJava) - - // procedures with `ref` in their arguments need macro expansion; those without do not - val (proceduresWithRefs,proceduresWithoutRefs) = - modularPlusCalBlock.procedures.partition(_.getParams.asScala.exists(_.isRef)) - - val proceduresToExpand = proceduresWithRefs.iterator.map(proc => proc.getName -> proc).toMap - val archetypes = modularPlusCalBlock.archetypes.iterator.map(arch => arch.getName -> arch).toMap - val mappingMacros = modularPlusCalBlock.mappingMacros.iterator.map(m => m.getName -> m).toMap - val macros = modularPlusCalBlock.macros.iterator.map(m => m.getName -> m).toMap - - val expandedProcedures = mutable.ListBuffer[PlusCalProcedure]() - val expandedProcedureCache = mutable.HashMap[ExpandedProcedureMatch,PlusCalProcedure]() - - val expandedMPCalInstances = - modularPlusCalBlock.instances.map { instance => - archetypes.get(instance.getTarget) match { - case None => ??? - case Some(archetype) => - mpcalExpandArchetype(archetype, instance, mappingMacros, macros, nameCleaner) - } - } - - val adjustedMPCalInstances = - expandedMPCalInstances.map { instance => - val initialTailBlockConversion = - pcalStatementsToTailBlockForm(instance.getBody.asScala.toList, fallthroughLabel = None) - val adjustedTailBlockConversion = mpcalAdjustAssignments(initialTailBlockConversion, nameCleaner) - new PlusCalProcess( - instance.getLocation, - instance.getName, - instance.getFairness, - instance.getVariables, - (adjustedTailBlockConversion.unlabeledStmts.view ++ adjustedTailBlockConversion.tailBlocks.view.map { - case TailBlock(loc, label, stmts) => - new PlusCalLabeledStatements(loc, label, stmts) - }).toList.asJava) - } - - val expandedPCalProcesses = - modularPlusCalBlock.processes.accept(new PlusCalProcessesVisitor[List[PlusCalProcess],RuntimeException] { - override def visit(singleProcess: PlusCalSingleProcess): List[PlusCalProcess] = Nil // catch this special case below - - override def visit(multiProcess: PlusCalMultiProcess): List[PlusCalProcess] = - multiProcess.getProcesses.asScala.view.map { proc => - new PlusCalProcess( - proc.getLocation, - proc.getName, - proc.getFairness, - proc.getVariables, - proc.getBody.asScala.flatMap(pcalStatementExpandMacros(_, Map.empty, macros, nameCleaner)).asJava) - }.toList - }) - - // rearrange the list of processes back into a PlusCalProcesses structure, and optionally handle the single-process - // form that was skipped above, if no additional processes were generated during expansion (from instances) - val expandedProcesses = modularPlusCalBlock.processes.accept(new PlusCalProcessesVisitor[PlusCalProcesses,RuntimeException] { - override def visit(singleProcess: PlusCalSingleProcess): PlusCalProcesses = - if(expandedMPCalInstances.nonEmpty) { - throw new UnsupportedFeatureIssue("single process with instances") - } else { - new PlusCalSingleProcess( - singleProcess.getLocation, - singleProcess.getBody.asScala.flatMap(pcalStatementExpandMacros(_, Map.empty, macros, nameCleaner)).asJava) - } - - override def visit(multiProcess: PlusCalMultiProcess): PlusCalProcesses = - new PlusCalMultiProcess( - multiProcess.getLocation, - (expandedMPCalInstances.view ++ expandedPCalProcesses).toList.asJava) - }) - - new PlusCalAlgorithm( - modularPlusCalBlock.getLocation, - PlusCalFairness.UNFAIR, - modularPlusCalBlock.name, - modularPlusCalBlock.variables.asJava, - Nil.asJava, - (proceduresWithoutRefs ++ expandedProcedures.toList).asJava, - modularPlusCalBlock.units.asJava, - expandedProcesses) - } -} diff --git a/test/files/pcalgen/dqueue.tla.expectpcal b/test/files/pcalgen/dqueue.tla.expectpcal new file mode 100644 index 000000000..1dbd9bff5 --- /dev/null +++ b/test/files/pcalgen/dqueue.tla.expectpcal @@ -0,0 +1,279 @@ +----------------------------- MODULE dqueue ----------------------------- +(***************************************************************************) +(* Distributed queue using Modular PlusCal. *) +(***************************************************************************) + +EXTENDS Naturals, Sequences, TLC + +CONSTANTS BUFFER_SIZE, NUM_CONSUMERS, PRODUCER + + +(*************************************************************************** +--mpcal dqueue { + define { + (* total nodes in the system: number of consumers + the producer *) + NUM_NODES == NUM_CONSUMERS + 1 + } + + mapping macro TCPChannel { + read { + await Len($variable) > 0; + with (msg = Head($variable)) { + $variable := Tail($variable); + yield msg; + }; + } + + write { + await Len($variable) < BUFFER_SIZE; + yield Append($variable, $value); + } + } + + mapping macro CyclicReads { + read { + $variable := ($variable + 1) % BUFFER_SIZE; + yield $variable; + + } + + write { yield $variable } + } + + (* consumer: Processes one element read from the network at a time, infinitely *) + archetype AConsumer(ref net[_], ref proc) { + c: while (TRUE) { + (* request more data to the producer by sending your own identifier + over the network *) + c1: net[PRODUCER] := self; + + (* processes the piece of data the producer sends back over the network + by writing to a "processor" abstract interface *) + c2: proc := net[self]; + } + } + + archetype AProducer(ref net[_], ref s) + variable requester; { + p: while (TRUE) { + (* wait for a consumer to request data *) + p1: requester := net[self]; + + (* send some data to the requester coming from a "stream" abstract interface *) + p2: net[requester] := s; + } + } + + variables network = [id \in 0..NUM_NODES-1 |-> <<>>], + processor = 0, + stream = 0; + + fair process (Consumer \in 1..NUM_CONSUMERS) == instance AConsumer(ref network[_], ref processor) + mapping network[_] via TCPChannel; + fair process (Producer \in {PRODUCER}) == instance AProducer(ref network[_], ref stream) + mapping network[_] via TCPChannel + mapping stream via CyclicReads; +} + + + +\* BEGIN PLUSCAL TRANSLATION +--algorithm dqueue { + variables network = [id \in (0) .. ((NUM_NODES) - (1)) |-> <<>>]; processor = 0; stream = 0; + define{ + NUM_NODES == (NUM_CONSUMERS) + (1) + } + + fair process (Consumer \in (1) .. (NUM_CONSUMERS)) + { + c: + if(TRUE) { + goto c1; + }; + c1: + with (value1 = self) { + await (Len((network)[PRODUCER])) < (BUFFER_SIZE); + network := [network EXCEPT ![PRODUCER] = Append((network)[PRODUCER], value1)]; + goto c2; + }; + c2: + await (Len((network)[self])) > (0); + with (msg0 = Head((network)[self])) { + network := [network EXCEPT ![self] = Tail((network)[self])]; + with (yielded_net1 = msg0) { + proc := yielded_net1; + goto c; + }; + }; + } + + fair process (Producer \in {PRODUCER}) + variables requester; + { + p: + if(TRUE) { + goto p1; + }; + p1: + await (Len((network)[self])) > (0); + with (msg1 = Head((network)[self])) { + network := [network EXCEPT ![self] = Tail((network)[self])]; + with (yielded_net00 = msg1) { + requester := yielded_net00; + goto p2; + }; + }; + p2: + stream := ((stream) + (1)) % (BUFFER_SIZE); + with (yielded_s0 = stream) { + with (value00 = yielded_s0) { + await (Len((network)[requester])) < (BUFFER_SIZE); + network := [network EXCEPT ![requester] = Append((network)[requester], value00)]; + goto p; + }; + }; + } +} + +\* END PLUSCAL TRANSLATION + + + + + +***************************************************************************) +\* BEGIN TRANSLATION PCal-e64ab9284c1a4c5172f564abb6f099c4 +CONSTANT defaultInitValue +VARIABLES network, processor, stream, netWrite, netRead, procWrite, netWrite0, + procWrite0, netRead0, netWrite1, sRead, sWrite, netWrite2, sWrite0, + pc + +(* define statement *) +NUM_NODES == (NUM_CONSUMERS) + (1) + +VARIABLE requester + +vars == << network, processor, stream, netWrite, netRead, procWrite, + netWrite0, procWrite0, netRead0, netWrite1, sRead, sWrite, + netWrite2, sWrite0, pc, requester >> + +ProcSet == ((1) .. (NUM_CONSUMERS)) \cup ({PRODUCER}) + +Init == (* Global variables *) + /\ network = [id \in (0) .. ((NUM_NODES) - (1)) |-> <<>>] + /\ processor = 0 + /\ stream = 0 + /\ netWrite = defaultInitValue + /\ netRead = defaultInitValue + /\ procWrite = defaultInitValue + /\ netWrite0 = defaultInitValue + /\ procWrite0 = defaultInitValue + /\ netRead0 = defaultInitValue + /\ netWrite1 = defaultInitValue + /\ sRead = defaultInitValue + /\ sWrite = defaultInitValue + /\ netWrite2 = defaultInitValue + /\ sWrite0 = defaultInitValue + (* Process Producer *) + /\ requester = [self \in {PRODUCER} |-> defaultInitValue] + /\ pc = [self \in ProcSet |-> CASE self \in (1) .. (NUM_CONSUMERS) -> "c" + [] self \in {PRODUCER} -> "p"] + +c(self) == /\ pc[self] = "c" + /\ IF TRUE + THEN /\ pc' = [pc EXCEPT ![self] = "c1"] + /\ UNCHANGED << network, processor, netWrite0, + procWrite0 >> + ELSE /\ netWrite0' = network + /\ procWrite0' = processor + /\ network' = netWrite0' + /\ processor' = procWrite0' + /\ pc' = [pc EXCEPT ![self] = "Done"] + /\ UNCHANGED << stream, netWrite, netRead, procWrite, netRead0, + netWrite1, sRead, sWrite, netWrite2, sWrite0, + requester >> + +c1(self) == /\ pc[self] = "c1" + /\ (Len(network[PRODUCER])) < (BUFFER_SIZE) + /\ netWrite' = [network EXCEPT ![PRODUCER] = Append(network[PRODUCER], self)] + /\ network' = netWrite' + /\ pc' = [pc EXCEPT ![self] = "c2"] + /\ UNCHANGED << processor, stream, netRead, procWrite, netWrite0, + procWrite0, netRead0, netWrite1, sRead, sWrite, + netWrite2, sWrite0, requester >> + +c2(self) == /\ pc[self] = "c2" + /\ (Len(network[self])) > (0) + /\ LET msg0 == Head(network[self]) IN + /\ netWrite' = [network EXCEPT ![self] = Tail(network[self])] + /\ netRead' = msg0 + /\ procWrite' = netRead' + /\ network' = netWrite' + /\ processor' = procWrite' + /\ pc' = [pc EXCEPT ![self] = "c"] + /\ UNCHANGED << stream, netWrite0, procWrite0, netRead0, netWrite1, + sRead, sWrite, netWrite2, sWrite0, requester >> + +Consumer(self) == c(self) \/ c1(self) \/ c2(self) + +p(self) == /\ pc[self] = "p" + /\ IF TRUE + THEN /\ pc' = [pc EXCEPT ![self] = "p1"] + /\ UNCHANGED << network, stream, netWrite2, sWrite0 >> + ELSE /\ netWrite2' = network + /\ sWrite0' = stream + /\ network' = netWrite2' + /\ stream' = sWrite0' + /\ pc' = [pc EXCEPT ![self] = "Done"] + /\ UNCHANGED << processor, netWrite, netRead, procWrite, netWrite0, + procWrite0, netRead0, netWrite1, sRead, sWrite, + requester >> + +p1(self) == /\ pc[self] = "p1" + /\ (Len(network[self])) > (0) + /\ LET msg1 == Head(network[self]) IN + /\ netWrite1' = [network EXCEPT ![self] = Tail(network[self])] + /\ netRead0' = msg1 + /\ requester' = [requester EXCEPT ![self] = netRead0'] + /\ network' = netWrite1' + /\ pc' = [pc EXCEPT ![self] = "p2"] + /\ UNCHANGED << processor, stream, netWrite, netRead, procWrite, + netWrite0, procWrite0, sRead, sWrite, netWrite2, + sWrite0 >> + +p2(self) == /\ pc[self] = "p2" + /\ sWrite' = ((stream) + (1)) % (BUFFER_SIZE) + /\ sRead' = sWrite' + /\ (Len(network[requester[self]])) < (BUFFER_SIZE) + /\ netWrite1' = [network EXCEPT ![requester[self]] = Append(network[requester[self]], sRead')] + /\ network' = netWrite1' + /\ stream' = sWrite' + /\ pc' = [pc EXCEPT ![self] = "p"] + /\ UNCHANGED << processor, netWrite, netRead, procWrite, netWrite0, + procWrite0, netRead0, netWrite2, sWrite0, + requester >> + +Producer(self) == p(self) \/ p1(self) \/ p2(self) + +(* Allow infinite stuttering to prevent deadlock on termination. *) +Terminating == /\ \A self \in ProcSet: pc[self] = "Done" + /\ UNCHANGED vars + +Next == (\E self \in (1) .. (NUM_CONSUMERS): Consumer(self)) + \/ (\E self \in {PRODUCER}: Producer(self)) + \/ Terminating + +Spec == /\ Init /\ [][Next]_vars + /\ \A self \in (1) .. (NUM_CONSUMERS) : WF_vars(Consumer(self)) + /\ \A self \in {PRODUCER} : WF_vars(Producer(self)) + +Termination == <>(\A self \in ProcSet: pc[self] = "Done") + +\* END TRANSLATION TLA-3b32e33f9317d9065792b6369f21a56b +============================================================================= +\* Modification History +\* Last modified Fri Dec 18 02:02:58 PST 2020 by finn +\* Last modified Mon Apr 01 02:11:17 PDT 2019 by minh +\* Last modified Tue Jan 22 18:38:13 PST 2019 by rmc +\* Last modified Wed Oct 12 02:41:48 PDT 2011 by lamport +\* Created Mon Oct 10 06:26:47 PDT 2011 by lamport diff --git a/test/files/pcalgen/load_balancer.tla.expectpcal b/test/files/pcalgen/load_balancer.tla.expectpcal new file mode 100644 index 000000000..5783a8e0c --- /dev/null +++ b/test/files/pcalgen/load_balancer.tla.expectpcal @@ -0,0 +1,573 @@ +----------------------------- MODULE load_balancer ----------------------------- +(***************************************************************************) +(* Specifies a simple load balancer. *) +(***************************************************************************) + +\* Extends some built-in TLA+ modules +EXTENDS Naturals, Sequences, TLC + +\* The `TCPChannel` mapping macro used in this specification is parameterized +\* by a `BUFFER_SIZE` constant. This value controls the number of messages being +\* held in a buffer by each process. Processes trying to send a message to another +\* process with a full buffer wil "block" (not be scheduled by TLC). +CONSTANT BUFFER_SIZE + +\* Define a constant identifier for the load balancer. +CONSTANT LoadBalancerId + +\* The number of servers and clients in the model checking setup. +CONSTANTS NUM_SERVERS, NUM_CLIENTS + +\* TLC should assume that both numbers are greater than zero (i.e., we always +\* have at least one server and one client). Note, however, that increasing +\* these numbers makes the number of states to be checked by TLC to grow +\* exponentially. +ASSUME NUM_SERVERS > 0 /\ NUM_CLIENTS > 0 + +\* GET_PAGE is a label attached to messages sent from the clients to +\* the load balancer. +CONSTANTS GET_PAGE + +\* Represents a file that can be returned by the server +CONSTANT WEB_PAGE + +(*************************************************************************** +--mpcal LoadBalancer { + define { + \* total nodes in the system: + \* number of clients + number of servers + the load balancer + NUM_NODES == NUM_CLIENTS + NUM_SERVERS + 1 + } + + \* The TCPChannel mapping macro models a communication channel + \* between two processes using TCP-like semantics. In particular: + \* + \* - reading from the channel "blocks" unless there is a message + \* ready to be read. + \* - message delivery is reliable and ordered (i.e., FIFO). + mapping macro TCPChannel { + read { + await Len($variable) > 0; + with (msg = Head($variable)) { + $variable := Tail($variable); + yield msg; + }; + } + + write { + await Len($variable) < BUFFER_SIZE; + yield Append($variable, $value); + } + } + + \* Mapping macros keep implementation-specific behavior that we don't + \* want to model check outside of our archetype definitions. + \* In the case of this load balancer, how a server retrieves a web page + \* is orthogonal to the correctness of the properties we are interested + \* to check with this specification. + \* + \* This mapping macro abstracts the process of reading a web page by + \* always returning the `WEB_PAGE` constant when the variable is read. + \* + \* Since "writing" to this mapping is meaningless, the attempting to write + \* to a variable mapped with WebPage will result in a model checking + \* error (see `assert(FALSE)` in the write definition). + mapping macro WebPages { + read { + yield WEB_PAGE; + } + + write { + assert(FALSE); + yield $value; + } + } + + \* ALoadBalancer is the archetype that defines the behavior of + \* the load balancer process. The `mailboxes` parameter represents + \* connections to all nodes in the system. + archetype ALoadBalancer(ref mailboxes) + + \* Local variables of this archetype: + variables + \* Holds messages received by the load balancer (sent + \* by clients) + msg, + + \* identifier attached to every message sent to servers by + \* the load balancer. + next = 0; + { + main: + while (TRUE) { + + \* waits for a message to be received. Upon receipt, the `assert` + \* call ensures that the message is of type `GET_PAGE`, the only + \* type of message supported in this simple specification. + \* + \* Every message received by the load balancer is expected to + \* be a record of the following type. + \* + \* [message_type : Int, client_id : Int, path: Interface{}] + \* + \* Note that tuples are 1-indexed. + rcvMsg: + msg := mailboxes[LoadBalancerId]; + assert(msg.message_type = GET_PAGE); + + \* the load balancer needs to forward the client request to the + \* server, who will process the request and send a web page back to + \* the client. + \* + \* The message sent to the server is a tuple in the format: + \* + \* [message_id : Int, client_id : Int, path: Interface{}] + \* + \* We send the client ID here so that the server can directly + \* reply to a client, bypassing the load balancer. This is usually + \* not what happens in practice, but the model is simple + \* enough for our (illustrative) purposes. + sendServer: + next := (next % NUM_SERVERS) + 1; + mailboxes[next] := [message_id |-> next, client_id |-> msg.client_id, path |-> msg.path]; + } + } + + \* AServer is the archetype that defines the behavior of the servers + \* in our system. The two parameters it recieves are: + \* + \* - mailboxes: contains connections to every node in the system + \* - file_system: abstraction of a real file system. In practice, + \* this is implementation specific and irrelevant for + \* the properties we want to check in this specification + archetype AServer(ref mailboxes, file_system) + + \* Local variables + variable + \* temporary buffer to hold incoming messages + msg; + { + serverLoop: + while (TRUE) { + + \* waits for an incoming message. Note that the only process + \* that sends messages to the server is the load balancer process + \* (defined according to the ALoadBalancer archetype) and the + \* message has the type [message_id : Int, client_id : Int] + rcvReq: + msg := mailboxes[self]; + + sendPage: + \* sends a web page (read from `file_system`) back to the requester + \* i.e., the client. + mailboxes[msg.client_id] := file_system[msg.path]; + } + } + + \* Client processes are given integer identifiers starting from NUM_SERVERS+1. + \* Keep in mind that this "range" notation in PlusCal defines a set, and is + \* _inclusive_ (i.e., NUM_SERVERS+NUM_CLIENTS+1 is part of the set). + \* + \* The parameters received by a client are: + \* + \* - mailboxes: contains connections to every node in the system + \* - instream: a stream of inputs to the client + \* - outstream: an output stream, where the client sends the messages it receives + \* from servers. + archetype AClient(ref mailboxes, instream, ref outstream) + + \* Local variables + variable + \* Temporary buffers to hold messages + req, resp; + { + clientLoop: + while (TRUE) { + + \* First, the client makes a request to the load balancer. + \* The format of the message is a tuple: + \* + \* [message_type : Int, client_id : Int, path : Interface{}]. + \* + \* If you check the ALoadBalancer definition, this is the message format + \* expected there. + \* + \* Remember that `self` is an implicitly defined, immutable variable that + \* contains the process identifier of the "running" process. + clientRequest: + req := [message_type |-> GET_PAGE, client_id |-> self, path |-> instream]; + mailboxes[LoadBalancerId] := req; + + \* Clients then wait for the response to the previously sent request. + \* Since there is only one type of web page in this simple specification + \* (defined by the WEB_PAGE constant), we assert here that the message + \* received indeed is equal our expected web page. + clientReceive: + resp := mailboxes[self]; + outstream := resp; + } + } + + \* GLOBAL VARIABLES *\ + + variables + \* our network is modeled as a function from node identifier + \* to a sequence of incoming messages + network = [id \in 0..(NUM_NODES-1) |-> <<>>], + + \* set as input and output "streams" + in = 0, out = 0, + + fs = [f \in {in} |-> WEB_PAGE]; + + \* PROCESS INSTANTIATION *\ + + \* The system has a single load balancer entity, instantiated from the ALoadBalancer + \* archetype. The model of our network is going to be the one defined by the TCPChannel + \* mapping macro in all instantiations. + fair process (LoadBalancer = LoadBalancerId) == instance ALoadBalancer(ref network) + mapping network[_] via TCPChannel; + + \* Instantiate `NUM_SERVERS` server processes according to the AServer archetype. + \* We map the page stream according to the WebPages mapping macro since this is + \* an implementation detail that needs to be specified during implementation at + \* a later stage. + fair process (Servers \in 1..NUM_SERVERS) == instance AServer(ref network, fs) + mapping network[_] via TCPChannel + mapping fs[_] via WebPages; + + fair process (Client \in (NUM_SERVERS+1)..(NUM_SERVERS+NUM_CLIENTS)) == instance AClient(ref network, in, ref out) + mapping network[_] via TCPChannel; +} + + + +\* BEGIN PLUSCAL TRANSLATION +--algorithm LoadBalancer { + variables network = [id \in (0) .. ((NUM_NODES) - (1)) |-> <<>>]; in = 0; out = 0; fs = [f \in {in} |-> WEB_PAGE]; + define{ + NUM_NODES == ((NUM_CLIENTS) + (NUM_SERVERS)) + (1) + } + + fair process (LoadBalancer = LoadBalancerId) + variables msg; next = 0; + { + main: + if(TRUE) { + goto rcvMsg; + }; + rcvMsg: + await (Len((network)[LoadBalancerId])) > (0); + with (msg0 = Head((network)[LoadBalancerId])) { + network := [network EXCEPT ![LoadBalancerId] = Tail((network)[LoadBalancerId])]; + with (yielded_mailboxes2 = msg0) { + msg := yielded_mailboxes2; + assert ((msg).message_type) = (GET_PAGE); + goto sendServer; + }; + }; + sendServer: + next := ((next) % (NUM_SERVERS)) + (1); + with (value2 = [message_id |-> next, client_id |-> (msg).client_id, path |-> (msg).path]) { + await (Len((network)[next])) < (BUFFER_SIZE); + network := [network EXCEPT ![next] = Append((network)[next], value2)]; + goto main; + }; + } + + fair process (Servers \in (1) .. (NUM_SERVERS)) + variables msg; file_system = fs; + { + serverLoop: + if(TRUE) { + goto rcvReq; + }; + rcvReq: + await (Len((network)[self])) > (0); + with (msg1 = Head((network)[self])) { + network := [network EXCEPT ![self] = Tail((network)[self])]; + with (yielded_mailboxes00 = msg1) { + msg := yielded_mailboxes00; + goto sendPage; + }; + }; + sendPage: + with (yielded_file_system0 = WEB_PAGE) { + with (value00 = yielded_file_system0) { + await (Len((network)[(msg).client_id])) < (BUFFER_SIZE); + network := [network EXCEPT ![(msg).client_id] = Append((network)[(msg).client_id], value00)]; + goto serverLoop; + }; + }; + } + + fair process (Client \in ((NUM_SERVERS) + (1)) .. ((NUM_SERVERS) + (NUM_CLIENTS))) + variables req; resp; instream = in; + { + clientLoop: + if(TRUE) { + goto clientRequest; + }; + clientRequest: + req := [message_type |-> GET_PAGE, client_id |-> self, path |-> instream]; + with (value10 = req) { + await (Len((network)[LoadBalancerId])) < (BUFFER_SIZE); + network := [network EXCEPT ![LoadBalancerId] = Append((network)[LoadBalancerId], value10)]; + goto clientReceive; + }; + clientReceive: + await (Len((network)[self])) > (0); + with (msg2 = Head((network)[self])) { + network := [network EXCEPT ![self] = Tail((network)[self])]; + with (yielded_mailboxes10 = msg2) { + resp := yielded_mailboxes10; + outstream := resp; + goto clientLoop; + }; + }; + } +} + +\* END PLUSCAL TRANSLATION + + + + +***************************************************************************) +\* BEGIN TRANSLATION PCal-4500c0fe7eed005c96be5ba74dff2461 +\* Process variable msg of process LoadBalancer at line 250 col 15 changed to msg_ +CONSTANT defaultInitValue +VARIABLES network, in, out, fs, mailboxesRead, mailboxesWrite, + mailboxesWrite0, mailboxesRead0, mailboxesWrite1, file_systemRead, + mailboxesWrite2, instreamRead, mailboxesWrite3, mailboxesRead1, + outstreamWrite, mailboxesWrite4, outstreamWrite0, pc + +(* define statement *) +NUM_NODES == ((NUM_CLIENTS) + (NUM_SERVERS)) + (1) + +VARIABLES msg_, next, msg, req, resp + +vars == << network, in, out, fs, mailboxesRead, mailboxesWrite, + mailboxesWrite0, mailboxesRead0, mailboxesWrite1, file_systemRead, + mailboxesWrite2, instreamRead, mailboxesWrite3, mailboxesRead1, + outstreamWrite, mailboxesWrite4, outstreamWrite0, pc, msg_, next, + msg, req, resp >> + +ProcSet == {LoadBalancerId} \cup ((1) .. (NUM_SERVERS)) \cup (((NUM_SERVERS) + (1)) .. ((NUM_SERVERS) + (NUM_CLIENTS))) + +Init == (* Global variables *) + /\ network = [id \in (0) .. ((NUM_NODES) - (1)) |-> <<>>] + /\ in = 0 + /\ out = 0 + /\ fs = [f \in {in} |-> WEB_PAGE] + /\ mailboxesRead = defaultInitValue + /\ mailboxesWrite = defaultInitValue + /\ mailboxesWrite0 = defaultInitValue + /\ mailboxesRead0 = defaultInitValue + /\ mailboxesWrite1 = defaultInitValue + /\ file_systemRead = defaultInitValue + /\ mailboxesWrite2 = defaultInitValue + /\ instreamRead = defaultInitValue + /\ mailboxesWrite3 = defaultInitValue + /\ mailboxesRead1 = defaultInitValue + /\ outstreamWrite = defaultInitValue + /\ mailboxesWrite4 = defaultInitValue + /\ outstreamWrite0 = defaultInitValue + (* Process LoadBalancer *) + /\ msg_ = defaultInitValue + /\ next = 0 + (* Process Servers *) + /\ msg = [self \in (1) .. (NUM_SERVERS) |-> defaultInitValue] + (* Process Client *) + /\ req = [self \in ((NUM_SERVERS) + (1)) .. ((NUM_SERVERS) + (NUM_CLIENTS)) |-> defaultInitValue] + /\ resp = [self \in ((NUM_SERVERS) + (1)) .. ((NUM_SERVERS) + (NUM_CLIENTS)) |-> defaultInitValue] + /\ pc = [self \in ProcSet |-> CASE self = LoadBalancerId -> "main" + [] self \in (1) .. (NUM_SERVERS) -> "serverLoop" + [] self \in ((NUM_SERVERS) + (1)) .. ((NUM_SERVERS) + (NUM_CLIENTS)) -> "clientLoop"] + +main == /\ pc[LoadBalancerId] = "main" + /\ IF TRUE + THEN /\ pc' = [pc EXCEPT ![LoadBalancerId] = "rcvMsg"] + /\ UNCHANGED << network, mailboxesWrite0 >> + ELSE /\ mailboxesWrite0' = network + /\ network' = mailboxesWrite0' + /\ pc' = [pc EXCEPT ![LoadBalancerId] = "Done"] + /\ UNCHANGED << in, out, fs, mailboxesRead, mailboxesWrite, + mailboxesRead0, mailboxesWrite1, file_systemRead, + mailboxesWrite2, instreamRead, mailboxesWrite3, + mailboxesRead1, outstreamWrite, mailboxesWrite4, + outstreamWrite0, msg_, next, msg, req, resp >> + +rcvMsg == /\ pc[LoadBalancerId] = "rcvMsg" + /\ (Len(network[LoadBalancerId])) > (0) + /\ LET msg0 == Head(network[LoadBalancerId]) IN + /\ mailboxesWrite' = [network EXCEPT ![LoadBalancerId] = Tail(network[LoadBalancerId])] + /\ mailboxesRead' = msg0 + /\ msg_' = mailboxesRead' + /\ Assert(((msg_').message_type) = (GET_PAGE), + "Failure of assertion at line 261, column 21.") + /\ network' = mailboxesWrite' + /\ pc' = [pc EXCEPT ![LoadBalancerId] = "sendServer"] + /\ UNCHANGED << in, out, fs, mailboxesWrite0, mailboxesRead0, + mailboxesWrite1, file_systemRead, mailboxesWrite2, + instreamRead, mailboxesWrite3, mailboxesRead1, + outstreamWrite, mailboxesWrite4, outstreamWrite0, + next, msg, req, resp >> + +sendServer == /\ pc[LoadBalancerId] = "sendServer" + /\ next' = ((next) % (NUM_SERVERS)) + (1) + /\ (Len(network[next'])) < (BUFFER_SIZE) + /\ mailboxesWrite' = [network EXCEPT ![next'] = Append(network[next'], [message_id |-> next', client_id |-> (msg_).client_id, path |-> (msg_).path])] + /\ network' = mailboxesWrite' + /\ pc' = [pc EXCEPT ![LoadBalancerId] = "main"] + /\ UNCHANGED << in, out, fs, mailboxesRead, mailboxesWrite0, + mailboxesRead0, mailboxesWrite1, file_systemRead, + mailboxesWrite2, instreamRead, mailboxesWrite3, + mailboxesRead1, outstreamWrite, mailboxesWrite4, + outstreamWrite0, msg_, msg, req, resp >> + +LoadBalancer == main \/ rcvMsg \/ sendServer + +serverLoop(self) == /\ pc[self] = "serverLoop" + /\ IF TRUE + THEN /\ pc' = [pc EXCEPT ![self] = "rcvReq"] + /\ UNCHANGED << network, mailboxesWrite2 >> + ELSE /\ mailboxesWrite2' = network + /\ network' = mailboxesWrite2' + /\ pc' = [pc EXCEPT ![self] = "Done"] + /\ UNCHANGED << in, out, fs, mailboxesRead, mailboxesWrite, + mailboxesWrite0, mailboxesRead0, + mailboxesWrite1, file_systemRead, + instreamRead, mailboxesWrite3, + mailboxesRead1, outstreamWrite, + mailboxesWrite4, outstreamWrite0, msg_, + next, msg, req, resp >> + +rcvReq(self) == /\ pc[self] = "rcvReq" + /\ (Len(network[self])) > (0) + /\ LET msg1 == Head(network[self]) IN + /\ mailboxesWrite1' = [network EXCEPT ![self] = Tail(network[self])] + /\ mailboxesRead0' = msg1 + /\ msg' = [msg EXCEPT ![self] = mailboxesRead0'] + /\ network' = mailboxesWrite1' + /\ pc' = [pc EXCEPT ![self] = "sendPage"] + /\ UNCHANGED << in, out, fs, mailboxesRead, mailboxesWrite, + mailboxesWrite0, file_systemRead, + mailboxesWrite2, instreamRead, mailboxesWrite3, + mailboxesRead1, outstreamWrite, + mailboxesWrite4, outstreamWrite0, msg_, next, + req, resp >> + +sendPage(self) == /\ pc[self] = "sendPage" + /\ file_systemRead' = WEB_PAGE + /\ (Len(network[(msg[self]).client_id])) < (BUFFER_SIZE) + /\ mailboxesWrite1' = [network EXCEPT ![(msg[self]).client_id] = Append(network[(msg[self]).client_id], file_systemRead')] + /\ network' = mailboxesWrite1' + /\ pc' = [pc EXCEPT ![self] = "serverLoop"] + /\ UNCHANGED << in, out, fs, mailboxesRead, mailboxesWrite, + mailboxesWrite0, mailboxesRead0, + mailboxesWrite2, instreamRead, + mailboxesWrite3, mailboxesRead1, + outstreamWrite, mailboxesWrite4, + outstreamWrite0, msg_, next, msg, req, resp >> + +Servers(self) == serverLoop(self) \/ rcvReq(self) \/ sendPage(self) + +clientLoop(self) == /\ pc[self] = "clientLoop" + /\ IF TRUE + THEN /\ pc' = [pc EXCEPT ![self] = "clientRequest"] + /\ UNCHANGED << network, out, mailboxesWrite4, + outstreamWrite0 >> + ELSE /\ mailboxesWrite4' = network + /\ outstreamWrite0' = out + /\ network' = mailboxesWrite4' + /\ out' = outstreamWrite0' + /\ pc' = [pc EXCEPT ![self] = "Done"] + /\ UNCHANGED << in, fs, mailboxesRead, mailboxesWrite, + mailboxesWrite0, mailboxesRead0, + mailboxesWrite1, file_systemRead, + mailboxesWrite2, instreamRead, + mailboxesWrite3, mailboxesRead1, + outstreamWrite, msg_, next, msg, req, resp >> + +clientRequest(self) == /\ pc[self] = "clientRequest" + /\ instreamRead' = in + /\ req' = [req EXCEPT ![self] = [message_type |-> GET_PAGE, client_id |-> self, path |-> instreamRead']] + /\ (Len(network[LoadBalancerId])) < (BUFFER_SIZE) + /\ mailboxesWrite3' = [network EXCEPT ![LoadBalancerId] = Append(network[LoadBalancerId], req'[self])] + /\ network' = mailboxesWrite3' + /\ pc' = [pc EXCEPT ![self] = "clientReceive"] + /\ UNCHANGED << in, out, fs, mailboxesRead, + mailboxesWrite, mailboxesWrite0, + mailboxesRead0, mailboxesWrite1, + file_systemRead, mailboxesWrite2, + mailboxesRead1, outstreamWrite, + mailboxesWrite4, outstreamWrite0, msg_, + next, msg, resp >> + +clientReceive(self) == /\ pc[self] = "clientReceive" + /\ (Len(network[self])) > (0) + /\ LET msg2 == Head(network[self]) IN + /\ mailboxesWrite3' = [network EXCEPT ![self] = Tail(network[self])] + /\ mailboxesRead1' = msg2 + /\ resp' = [resp EXCEPT ![self] = mailboxesRead1'] + /\ outstreamWrite' = resp'[self] + /\ network' = mailboxesWrite3' + /\ out' = outstreamWrite' + /\ pc' = [pc EXCEPT ![self] = "clientLoop"] + /\ UNCHANGED << in, fs, mailboxesRead, mailboxesWrite, + mailboxesWrite0, mailboxesRead0, + mailboxesWrite1, file_systemRead, + mailboxesWrite2, instreamRead, + mailboxesWrite4, outstreamWrite0, msg_, + next, msg, req >> + +Client(self) == clientLoop(self) \/ clientRequest(self) + \/ clientReceive(self) + +(* Allow infinite stuttering to prevent deadlock on termination. *) +Terminating == /\ \A self \in ProcSet: pc[self] = "Done" + /\ UNCHANGED vars + +Next == LoadBalancer + \/ (\E self \in (1) .. (NUM_SERVERS): Servers(self)) + \/ (\E self \in ((NUM_SERVERS) + (1)) .. ((NUM_SERVERS) + (NUM_CLIENTS)): Client(self)) + \/ Terminating + +Spec == /\ Init /\ [][Next]_vars + /\ WF_vars(LoadBalancer) + /\ \A self \in (1) .. (NUM_SERVERS) : WF_vars(Servers(self)) + /\ \A self \in ((NUM_SERVERS) + (1)) .. ((NUM_SERVERS) + (NUM_CLIENTS)) : WF_vars(Client(self)) + +Termination == <>(\A self \in ProcSet: pc[self] = "Done") + +\* END TRANSLATION TLA-91fe3e564ee1f74fb78055868c4540bc + + +(* INVARIANTS *) + + +\* This is an _invariant_ of our specification: in other words, +\* we expect the BuffersOk predicate to always be true in every step of execution +BufferOk(node) == Len(network[node]) >= 0 /\ Len(network[node]) <= BUFFER_SIZE +BuffersOk == \A node \in DOMAIN network : BufferOk(node) + + +(* PROPERTIES *) + +\* This is a property we would like to check about our specification. +\* Properties are defined using _temporal logic_. In this specific example, +\* we want to make sure that every client that requests a web page (i.e., are +\* in the 'clientRequest' label) eventually receive a response (i.e., are +\* in the 'clientReceive' label). In order to specify this property, we have to +\* write the formula as if the client enters 'clientReceive' label, it will +\* eventually successfully receive a response and then go back to issuing +\* another request in the 'clientRequest' label. +ReceivesPage(client) == pc[client] = "clientReceive" ~> pc[client] = "clientRequest" +ClientsOk == \A client \in (NUM_SERVERS+1)..(NUM_SERVERS+NUM_CLIENTS) : ReceivesPage(client) + +============================================================================= +\* Modification History +\* Last modified Mon Dec 21 03:17:07 PST 2020 by finn +\* Last modified Sun Mar 31 21:53:44 PDT 2019 by minh +\* Last modified Wed Feb 27 14:42:14 PST 2019 by rmc diff --git a/test/files/pcalgen/replicated_kv.tla.expectpcal b/test/files/pcalgen/replicated_kv.tla.expectpcal new file mode 100644 index 000000000..d5dac2693 --- /dev/null +++ b/test/files/pcalgen/replicated_kv.tla.expectpcal @@ -0,0 +1,3170 @@ +----------------------------- MODULE replicated_kv ----------------------------- +(***************************************************************************************) +(* Specifies a simple replicated Key-Value store in MPCal. *) +(* *) +(* Specifies a replicated state machines (RSM) approach as described in: *) +(* *) +(* Implementing fault-tolerant services using the state machine approach: a tutorial. *) +(* http://dl.acm.org/citation.cfm?id=98167 *) +(***************************************************************************************) + +\* Use some built-in TLA+ modules +EXTENDS Integers, Sequences, FiniteSets, TLC + +\* Constant Definitions +\* -------------------- + +\* Defines the size of the network buffer in a FIFOChannel (the mapping macro). +\* +\* TLC will explore states with up to `BUFFER_SIZE` messages being held on the buffer. +\* If the communication buffer is full, a process that attempts to send a message will not +\* run until a message on the other end of the channel is received. +CONSTANT BUFFER_SIZE + +\* Defines the number of key-value store replicas and clients in the system. The specification +\* is orthogonal to these numbers. Note, however, that increasing the number of replicas and/or +\* clients exponentially increases the state space that TLC needs to explore in order to model +\* check your specification. +CONSTANTS NUM_REPLICAS, NUM_CLIENTS + +\* When a client sends a message to a replica, the client needs to be able to identify +\* what type of message it just received. These constants below are such labels. Make sure +\* to give them distinct concrete values when model checking. +CONSTANTS DISCONNECT_MSG, GET_MSG, PUT_MSG, NULL_MSG + +\* labels that identify a payload corresponds to the response of a previously issues Get +\* or Put request. +CONSTANTS GET_RESPONSE, PUT_RESPONSE + +\* an arbitrary `NULL` value. We model the underlying key-value store as a function from +\* a certain key-space (function domain) to this `NULL` element. When a client issues a `PUT` +\* request, the database is updated and the key being set no longer maps to `NULL`. +CONSTANT NULL + +\* Defines which keys are used by clients when performing Get and Put operations +\* Since we are interested to test properties like message stability detection +\* and the semantics of the database, we keep these constant throughout model checking. +CONSTANT GET_KEY, PUT_KEY + +\* Whenever clients issue PUT requests, they set keys to the value declared in this constant. +CONSTANT PUT_VALUE + +\* Defines the set of keys a client may set. In this specification, we restrict +\* it to them to GET_KEY and PUT_KEY +KeySpace == { GET_KEY, PUT_KEY } + +\* These constants allow PlusCal processes to derive their client identifiers from +\* their PlusCal identifiers. +GET_ORDER == 0 +PUT_ORDER == 1 +DISCONNECT_ORDER == 2 +NULL_ORDER == 3 + +\* We have clients that perform each of the operations supported by our Replicated KV-store: +\* Get, Put, Disconnect, and ClockUpdate (or 'null' request). PlusCal requires that every process +\* has a unique identifier. The set definitions below just ensure that our clients have +\* consecutive identifiers. +GetSet == (NUM_REPLICAS)..(NUM_REPLICAS+NUM_CLIENTS-1) +PutSet == (NUM_REPLICAS+NUM_CLIENTS)..(NUM_REPLICAS + 2*NUM_CLIENTS - 1) +DisconnectSet == (NUM_REPLICAS+2*NUM_CLIENTS)..(NUM_REPLICAS+3*NUM_CLIENTS-1) +NullSet == (NUM_REPLICAS+3*NUM_CLIENTS)..(NUM_REPLICAS+4*NUM_CLIENTS-1) + +(*************************************************************************** +--mpcal ReplicatedKV { + define { + \* Define NUM_NODES to be the total number of nodes in the system, i.e., the number of + \* clients plus the number of replicas + NUM_NODES == NUM_REPLICAS + NUM_CLIENTS + + \* Each replica and each client in the system need an identifier. By default, replicas + \* are identified from 1 to NUM_REPLICAS, and the clients are identified from NUM_REPLICAS+1 + \* to NUM_NODES. It is important that identifiers are unique, consecutive and non-overlapping, + \* due to the way we are modeling our network in this specification. + ReplicaSet == 0..(NUM_REPLICAS-1) + ClientSet == NUM_REPLICAS..(NUM_NODES-1) + } + + \* Broadcasts a certain `msg` to `nodes` with identifiers ranging from + \* `domainStart` to `domainEnd`. + \* + \* Only returns once every message has been sent (i.e., it may "block" if + \* the buffer of one of the receivers is full). + macro Broadcast(nodes, i, until, msg, clock) { + while (i <= until /\ clock # -1) { + nodes[i] := msg; + i := i + 1; + } + } + + \* Models a FIFO channel. Messages are always delivered. Every process + \* can have up to `BUFFER_SIZE` messages in its buffer before being + \* processed. + mapping macro FIFOChannel { + read { + await Len($variable) > 0; + with (msg = Head($variable)) { + $variable := Tail($variable); + yield msg; + }; + } + + write { + await Len($variable) < BUFFER_SIZE; + yield Append($variable, $value); + } + } + + \* The following mapping macros make sure that archetypes that + \* perform client functions read the correct client identifier with + \* respect to their PlusCal process identifier (`self`). + + mapping macro GetClientId { + read { yield self - (NUM_CLIENTS * GET_ORDER); } + write { assert(FALSE); yield $value; } + } + + mapping macro PutClientId { + read { yield self - (NUM_CLIENTS * PUT_ORDER); } + write { assert(FALSE); yield $value; } + } + + mapping macro DisconnectClientId { + read { yield self - (NUM_CLIENTS * DISCONNECT_ORDER); } + write { assert(FALSE); yield $value; } + } + + mapping macro NullClientId { + read { yield self - (NUM_CLIENTS * NULL_ORDER); } + write { assert(FALSE); yield $value; } + } + + \* Mapping via identity is sometimes necessary in order to inform + \* the compiler that a certain resource is to be function mapped, but + \* no meaningful manipulation on reads and writes is necessary. + mapping macro Identity { + read { yield $variable; } + write { yield $value; } + } + + \* This archetype defines the behavior of the replica servers in the system. + \* Its parameters are: + \* + \* - clients: connections to all clients in the system; it needs to wait + \* for client requests in order to perform operations. + \* - replicas: connections to replicas. Since replicas do not talk to each + \* other, this parameter is only used in order to listen to + \* incoming messages. + \* - kv: the underlying "database". When 'put' requests become stable, this + \* database is updated to include the value being set by the client. + archetype AReplica(ref clients, replicas, ref kv) + + \* Local state in a replica: + variables + \* Each replica knows which clients are live (i.e., haven't disconnected) + \* Initially, all clients are live. + liveClients = ClientSet, + + \* Replicas remember which requests are pending (i.e., have not been + \* replied yet). This variable maps client identifiers to a sequence + \* of pending requests + pendingRequests = [c \in liveClients |-> <<>>], + + \* Temporary variables: holds messages that are stable + stableMessages = <<>>, + + \* incremented during in loops + i, + + \* temporary variable: holds the first pending message from + \* a client. The first pending message has the lowest logical + \* clock in the sequence (logical clocks are monotonically increasing) + firstPending, + + \* temporary variables used while finding the set of stable + \* messages. + timestamp, + nextClient, + lowestPending, + chooseMessage, + + \* the replica needs to know the logical clocks of the last + \* message received by each client in order to determine + \* request stability. + currentClocks = [c \in liveClients |-> 0]; + + \* determines the lowest logical clock value seen from all + \* clients. Any pending messages with timestamp lower than this + \* can be considered stable. + minClock, + + \* controls while loop execution. See the 'findStableRequestsLoop' + \* step for more information + continue, + + \* temporary variable: live clients that have pending + \* messages (stable or not) + pendingClients, + + \* Used when iterating over sets of clients + clientsIter, + + \* used to hold messages sent/received by the replica + msg, + + \* put requests were successful + ok, + + \* holds keys/values to be read from/written to the database + key, + val; { + + \* Main replica loop. In each iteration of the loop, the replica: + \* + \* 1. Waits for incoming messages from clients; + \* 2. Finds stable messages; + \* 3. Replies to all stable messages. + replicaLoop: + while (TRUE) { + + stableMessages := <<>>; + continue := TRUE; + + \* Waits for an incoming message from any client. This statement will + \* "block" the replica until a message is read into 'msg'. + \* See definition of client archetypes for the format of the messages. + receiveClientRequest: + msg := replicas[self]; + + \* if the message received is a disconnection from a client, + \* remove the client from the set of live clients + clientDisconnected: + if (msg.op = DISCONNECT_MSG) { + liveClients := liveClients \ {msg.client}; + }; + + \* if the message is a Get request: + replicaGetRequest: + if (msg.op = GET_MSG) { + \* safety assertion: a client requesting for a key must be live + assert(msg.client \in liveClients); + + \* update our records of the current logical clock of the + \* requesting client. + currentClocks[msg.client] := msg.timestamp; + + \* make this a pending message (to be dealt with later, during + \* stability check) + pendingRequests[msg.client] := Append(pendingRequests[msg.client], msg); + }; + + \* if the message is a Put request: similar to Get request. + replicaPutRequest: + if (msg.op = PUT_MSG) { + currentClocks[msg.client] := msg.timestamp; + pendingRequests[msg.client] := Append(pendingRequests[msg.client], msg); + }; + + \* if the message is a clock update from a client, inspect the logical clock + \* to check if it's lower than that of any other message seen before. + replicaNullRequest: + if (msg.op = NULL_MSG) { + currentClocks[msg.client] := msg.timestamp; + }; + + \* Message stability + \* ----------------- + \* + \* The replica needs to detect when messages become stable, and then respond to + \* those messages. Finding out which messages are stable and totally ordering them + \* is crucial for the correctness of the algorithm. If message stability does not work + \* correctly in the replicas, the database may get inconsistent across replicas + \* (if operations are applied in a different order), or clients may get "stuck" + \* (if stable messages are not replied). + + + \* This is the main loop that finds which of the pending requests (if any) are stable + findStableRequestsLoop: + while (continue) { + + \* only consider clients that have messages pending + pendingClients := {c \in liveClients : Len(pendingRequests[c]) > 0}; + + \* if two messages have the same logical clock, total ordering is enforced + \* based on the client identifier: requests from smaller client identifiers + \* are applied first + nextClient := NUM_NODES + 1; + + clientsIter := liveClients; + i := 0; + minClock := 0; + + \* in order to find the set of stable messages, we need to determine + \* the lowest logical clock among our set of live clients. Then, every + \* pending message with a timestamp greater than 'minClock' can be + \* considered stable. + findMinClock: + while (i < Cardinality(clientsIter)) { + with (client \in clientsIter) { + if (minClock = 0 \/ currentClocks[client] < minClock) { + minClock := currentClocks[client]; + }; + + clientsIter := clientsIter \ {client}; + } + }; + + \* this variable holds the timestamp of the request with the lowest clock + \* value that is pending and stable + lowestPending := minClock + 1; + + i := 0; + + \* find the next stable message to be processed + findMinClient: + while (i < Cardinality(pendingClients)) { + with (client \in pendingClients) { + + \* for each client with pending requests: + \* - inspect the first pending message (by definition, the message with + \* lowest clock from that client) + \* - extract the timestamp from the message + \* - record the client and timestamp in case this is the "oldest" message + + firstPending := Head(pendingRequests[client]); + assert(firstPending.op = GET_MSG \/ firstPending.op = PUT_MSG); + timestamp := firstPending.timestamp; + + \* a message is only stable if its timestamp is lower than + \* minClock + if (timestamp < minClock) { + + \* this is the next stable message if it has the lowest + \* timestamp seen so far; if the timestamp is the same as + \* the lowest seen so far, do a client-id comparison + chooseMessage := (timestamp < lowestPending) \/ ((timestamp = lowestPending) /\ (client < nextClient)); + if (chooseMessage) { + nextClient := client; + lowestPending := timestamp; + } + }; + + pendingClients := pendingClients \ {client}; + } + }; + + \* add the next stable message to the 'stableMessages' sequence. + \* if 'lowestPending' is >= 'minClock', it means no more stable messages + \* are pending, and we can leave this loop. + addStableMessage: + if (lowestPending < minClock) { + msg := Head(pendingRequests[nextClient]); + pendingRequests[nextClient] := Tail(pendingRequests[nextClient]); + + stableMessages := Append(stableMessages, msg); + } else { + continue := FALSE; + } + }; + + i := 1; + + \* iterate over our sequence of 'stableMessages' built in the previous + \* step, responding to each of them in order. + respondPendingRequestsLoop: + while (i <= Len(stableMessages)) { + msg := stableMessages[i]; + i := i + 1; + + respondStableGet: + if (msg.op = GET_MSG) { + key := msg.key; + val := kv[key]; + + \* send the value read from the database back to the client + clients[msg.reply_to] := [type |-> GET_RESPONSE, result |-> val]; + }; + + respondStablePut: + if (msg.op = PUT_MSG) { + key := msg.key; + val := msg.value; + + \* update our database and send an OK back to the client + kv[key] := val; + + clients[msg.reply_to] := [type |-> PUT_RESPONSE, result |-> ok]; + }; + } + } + } + + \* Client Definitions + \* ------------------ + \* + \* The following archetypes define the client functions as specified in A1. + \* Note that these operations are the "logical" versions of the API: for example, + \* a Put archetype here sends a "Put" message to all replicas. + \* + \* In all of the definitions below, note that 'clocks' represent the client's + \* logical clock. However, upon disconnection, the clock is set to '-1', and + \* clients know to terminate when that happens. + + + \* Specifies a Get request from a client. Arguments: + \* + \* - clientId: client identifier, used by the replica to identify which client is + \* performing the operation + \* - replicas: connections to replica servers + \* - clients: connections to clients. Used only to listen for incoming messages + \* from replicas (i.e., to send the value of the key being read). + \* - key: the key being read. This *must* belong to the KeySpace set. + \* - clock: The initial logical clock + \* + \* A Get message sent to the replica is a record in the following format: + \* + \* [op: GET_MSG, key: key, client: client_id, timestamp: lamport_clock] + archetype Get(clientId, ref replicas, clients, key, ref clock, spin, ref outside) + variable continue = TRUE, getReq, getResp; + { + \* Loop until disconnected + getLoop: + while (continue) { + getRequest: + \* if disconnected, return + if (clock[clientId] = -1) { + continue := FALSE + } else { + \* increment the logical clock, and construct a valid + \* Get message. + clock[clientId] := clock[clientId] + 1; + getReq := [op |-> GET_MSG, key |-> key, client |-> clientId, timestamp |-> clock[clientId], reply_to |-> self]; + + \* Choose some replica from the set of replicas to send this + \* request to + with (dst \in ReplicaSet) { + replicas[dst] := getReq; + }; + + getReply: + if (clock[clientId] = -1) { + \* Client disconnected -- terminate + continue := FALSE; + } else { + \* Waits for the response from the replica + getResp := clients[self]; + assert(getResp.type = GET_RESPONSE); + outside := getResp.result; + } + }; + + getCheckSpin: + if (~spin) { + continue := FALSE; + } + } + } + + \* Specifies a Put request from a client. Arguments: + \* + \* - clientId: client identifier, used by the replica to identify which client is + \* performing the operation + \* - replicas: connection to the replicas. + \* - clients: connection to the clients. Used to read incoming messages (response + \* from the Put request + \* - key: the key being set. + \* - value: the value being written to the key + \* - clock: Lamport clocks + \* + \* A Put message sent to the replica is a record in the following format: + \* + \* [op: PUT_MSG, key: key, value: value, client: client_id, timestamp: lamport_clock] + archetype Put(clientId, ref replicas, clients, key, value, ref clock, spin, ref outside) + variables continue = TRUE, i, j, putReq, putResp; + { + \* Loops indefinitely until disconnected + putLoop: + while (continue) { + putRequest: + \* if disconnected, return + if (clock[clientId] = -1) { + continue := FALSE; + } else { + \* increment the logical clock, construct the payload to be sent + \* to the replica, and set 'locked' to TRUE + clock[clientId] := clock[clientId] + 1; + putReq := [op |-> PUT_MSG, key |-> key, value |-> value, client |-> clientId, timestamp |-> clock[clientId], reply_to |-> self]; + i := 0; + j := 0; + + \* Put requests must be broadcast to all replicas + putBroadcast: + Broadcast(replicas, j, NUM_REPLICAS-1, putReq, clock[clientId]); + + \* wait for a response from all replicas, and allow other + \* calls to the replica to happen after that. + putResponse: + while (i < Cardinality(ReplicaSet)) { + if (clock[clientId] = -1) { + continue := FALSE; + goto putLoop; + } else { + putResp := clients[self]; + assert(putResp.type = PUT_RESPONSE); + + i := i + 1; + } + }; + + putComplete: + outside := PUT_RESPONSE; + }; + + putCheckSpin: + if (~spin) { + continue := FALSE; + } + } + } + + \* Specifies a Disconnect message from the client. + \* + \* A Disconnect message sent to the replica is a record in the following format: + \* + \* [op: DISCONNECT_MSG, client: client_id] + archetype Disconnect(clientId, ref replicas, ref clock) + variables msg, j; + { + sendDisconnectRequest: + msg := [op |-> DISCONNECT_MSG, client |-> clientId]; + + \* setting the logical clock internally to -1 indicates that this client + \* has disconnected. Other operations terminate accordingly. + clock[clientId] := -1; + j := 0; + + \* Disconnection messages need to be broadcast to all replicas. + \* "Clock" is set to zero because the replica is disconnected but we + \* *do* want to broadcast that message + disconnectBroadcast: + Broadcast(replicas, j, NUM_REPLICAS-1, msg, 0); + } + + \* Specifies a ClockUpdate ('null') message from the client. + \* If the client has disconnected, no more clock updates are sent. + \* + \* A ClockUpdate message sent to the replica is a record in the following format: + \* + \* [op: NULL_MSG, client: client_id, timestamp: logical_clock] + archetype ClockUpdate(clientId, ref replicas, ref clock, spin) + variables continue = TRUE, j, msg; + { + clockUpdateLoop: + while (continue) { + \* if we have disconnected, return + if (clock[clientId] = -1) { + continue := FALSE; + } else { + \* tick the lock and construct the message accordingly + clock[clientId] := clock[clientId] + 1; + msg := [op |-> NULL_MSG, client |-> clientId, timestamp |-> clock[clientId]]; + j := 0; + + nullBroadcast: + \* clock update messages must be broadcast to all replicas. + Broadcast(replicas, j, NUM_REPLICAS-1, msg, clock[clientId]); + }; + + nullCheckSpin: + if (~spin) { + continue := FALSE; + } + } + } + + \* Global Variables + \* ---------------- + + variables + \* queue of incoming messages for each of the replicas + replicasNetwork = [id \in ReplicaSet |-> <<>>], + + \* all clients performing operations in this model + allClients = GetSet \cup PutSet \cup DisconnectSet \cup NullSet, + + \* queue of incoming messages for each of the clients + clientMailboxes = [id \in allClients |-> <<>>], + + \* client identifier: to be appropriately mapped + cid = 0, + + \* communication channel with the caller; astracted + \* in this specification + out = 0, + + \* all clocks set to 0 initially + clocks = [c \in ClientSet |-> 0]; + + + \* Process Instantiations + \* ---------------------- + \* + \* This is where the archetypes defined above are instantiated into actual PlusCal + \* processes. We instantiate NUM_REPLICAS replica servers and NUM_CLIENTS client + \* processes for each possible client operation. TLC will be responsible for + \* exploring the different orderings in which these clients and replicas + \* may interact. + + + \* Instantiate replica servers. The network model used is the one defined in + \* the FIFOChannel mapping macro. + fair process (Replica \in ReplicaSet) == instance AReplica(ref clientMailboxes, replicasNetwork, [k \in KeySpace |-> NULL]) + mapping @1[_] via FIFOChannel + mapping @2[_] via FIFOChannel + mapping @3[_] via Identity; + + \* Instantiate clients: + + fair process (GetClient \in GetSet) == instance Get(cid, ref replicasNetwork, clientMailboxes, GET_KEY, ref clocks, TRUE, ref out) + mapping cid via GetClientId + mapping replicasNetwork[_] via FIFOChannel + mapping clientMailboxes[_] via FIFOChannel + mapping clocks[_] via Identity; + + fair process (PutClient \in PutSet) == instance Put(cid, ref replicasNetwork, clientMailboxes, PUT_KEY, PUT_VALUE, ref clocks, TRUE, ref out) + mapping cid via PutClientId + mapping replicasNetwork[_] via FIFOChannel + mapping clientMailboxes[_] via FIFOChannel + mapping clocks[_] via Identity; + + fair process (DisconnectClient \in DisconnectSet) == instance Disconnect(cid, ref replicasNetwork, ref clocks) + mapping cid via DisconnectClientId + mapping replicasNetwork[_] via FIFOChannel + mapping clocks[_] via Identity; + + fair process (ClockUpdateClient \in NullSet) == instance ClockUpdate(cid, ref replicasNetwork, ref clocks, TRUE) + mapping cid via NullClientId + mapping replicasNetwork[_] via FIFOChannel + mapping clocks[_] via Identity; +} + + + +\* BEGIN PLUSCAL TRANSLATION +--algorithm ReplicatedKV { + variables replicasNetwork = [id \in ReplicaSet |-> <<>>]; allClients = (((GetSet) \union (PutSet)) \union (DisconnectSet)) \union (NullSet); clientMailboxes = [id \in allClients |-> <<>>]; cid = 0; out = 0; clocks = [c \in ClientSet |-> 0]; + define{ + NUM_NODES == (NUM_REPLICAS) + (NUM_CLIENTS) + ReplicaSet == (0) .. ((NUM_REPLICAS) - (1)) + ClientSet == (NUM_REPLICAS) .. ((NUM_NODES) - (1)) + } + + fair process (Replica \in ReplicaSet) + variables liveClients = ClientSet; pendingRequests = [c \in liveClients |-> <<>>]; stableMessages = <<>>; i; firstPending; timestamp; nextClient; lowestPending; chooseMessage; currentClocks = [c \in liveClients |-> 0]; minClock; continue; pendingClients; clientsIter; msg; ok; key; val; replicas = replicasNetwork; kv = [k \in KeySpace |-> NULL]; + { + replicaLoop: + if(TRUE) { + stableMessages := <<>>; + continue := TRUE; + goto receiveClientRequest; + }; + receiveClientRequest: + await (Len((replicas)[self])) > (0); + with (msg0 = Head((replicas)[self])) { + replicas := [replicas EXCEPT ![self] = Tail((replicas)[self])]; + with (yielded_replicas0 = msg0) { + msg := yielded_replicas0; + goto clientDisconnected; + }; + }; + clientDisconnected: + if(((msg).op) = (DISCONNECT_MSG)) { + liveClients := (liveClients) \ ({(msg).client}); + goto replicaGetRequest; + } else { + goto replicaGetRequest; + }; + replicaGetRequest: + if(((msg).op) = (GET_MSG)) { + assert ((msg).client) \in (liveClients); + currentClocks := [currentClocks EXCEPT ![(msg).client] = (msg).timestamp]; + pendingRequests := [pendingRequests EXCEPT ![(msg).client] = Append((pendingRequests)[(msg).client], msg)]; + goto replicaPutRequest; + } else { + goto replicaPutRequest; + }; + replicaPutRequest: + if(((msg).op) = (PUT_MSG)) { + currentClocks := [currentClocks EXCEPT ![(msg).client] = (msg).timestamp]; + pendingRequests := [pendingRequests EXCEPT ![(msg).client] = Append((pendingRequests)[(msg).client], msg)]; + goto replicaNullRequest; + } else { + goto replicaNullRequest; + }; + replicaNullRequest: + if(((msg).op) = (NULL_MSG)) { + currentClocks := [currentClocks EXCEPT ![(msg).client] = (msg).timestamp]; + goto findStableRequestsLoop; + } else { + goto findStableRequestsLoop; + }; + findStableRequestsLoop: + if(continue) { + pendingClients := {c \in liveClients : (Len((pendingRequests)[c])) > (0)}; + nextClient := (NUM_NODES) + (1); + clientsIter := liveClients; + i := 0; + minClock := 0; + goto findMinClock; + } else { + i := 1; + goto respondPendingRequestsLoop; + }; + findMinClock: + if((i) < (Cardinality(clientsIter))) { + with (client \in clientsIter) { + if(((minClock) = (0)) \/ (((currentClocks)[client]) < (minClock))) { + minClock := (currentClocks)[client]; + clientsIter := (clientsIter) \ ({client}); + goto findMinClock; + } else { + clientsIter := (clientsIter) \ ({client}); + goto findMinClock; + }; + }; + } else { + lowestPending := (minClock) + (1); + i := 0; + goto findMinClient; + }; + findMinClient: + if((i) < (Cardinality(pendingClients))) { + with (client \in pendingClients) { + firstPending := Head((pendingRequests)[client]); + assert (((firstPending).op) = (GET_MSG)) \/ (((firstPending).op) = (PUT_MSG)); + timestamp := (firstPending).timestamp; + if((timestamp) < (minClock)) { + chooseMessage := ((timestamp) < (lowestPending)) \/ (((timestamp) = (lowestPending)) /\ ((client) < (nextClient))); + if(chooseMessage) { + nextClient := client; + lowestPending := timestamp; + pendingClients := (pendingClients) \ ({client}); + goto findMinClient; + } else { + pendingClients := (pendingClients) \ ({client}); + goto findMinClient; + }; + } else { + pendingClients := (pendingClients) \ ({client}); + goto findMinClient; + }; + }; + } else { + goto addStableMessage; + }; + addStableMessage: + if((lowestPending) < (minClock)) { + msg := Head((pendingRequests)[nextClient]); + pendingRequests := [pendingRequests EXCEPT ![nextClient] = Tail((pendingRequests)[nextClient])]; + stableMessages := Append(stableMessages, msg); + goto findStableRequestsLoop; + } else { + continue := FALSE; + goto findStableRequestsLoop; + }; + respondPendingRequestsLoop: + if((i) <= (Len(stableMessages))) { + msg := (stableMessages)[i]; + i := (i) + (1); + goto respondStableGet; + } else { + goto replicaLoop; + }; + respondStableGet: + if(((msg).op) = (GET_MSG)) { + key := (msg).key; + with (yielded_kv0 = (kv)[key]) { + val := yielded_kv0; + with (value00 = [type |-> GET_RESPONSE, result |-> val]) { + await (Len((clientMailboxes)[(msg).reply_to])) < (BUFFER_SIZE); + clientMailboxes := [clientMailboxes EXCEPT ![(msg).reply_to] = Append((clientMailboxes)[(msg).reply_to], value00)]; + goto respondStablePut; + }; + }; + } else { + goto respondStablePut; + }; + respondStablePut: + if(((msg).op) = (PUT_MSG)) { + key := (msg).key; + val := (msg).value; + with (value11 = val) { + kv := [kv EXCEPT ![key] = value11]; + with (value20 = [type |-> PUT_RESPONSE, result |-> ok]) { + await (Len((clientMailboxes)[(msg).reply_to])) < (BUFFER_SIZE); + clientMailboxes := [clientMailboxes EXCEPT ![(msg).reply_to] = Append((clientMailboxes)[(msg).reply_to], value20)]; + goto respondPendingRequestsLoop; + }; + }; + } else { + goto respondPendingRequestsLoop; + }; + } + + fair process (GetClient \in GetSet) + variables continue = TRUE; getReq; getResp; clientId = cid; clients = clientMailboxes; key = GET_KEY; spin = TRUE; + { + getLoop: + if(continue) { + goto getRequest; + }; + getRequest: + with (yielded_clock1 = (clocks)[clientId]) { + if((yielded_clock1) = (- (1))) { + continue := FALSE; + goto getCheckSpin; + } else { + with (yielded_clientId7 = (self) - ((NUM_CLIENTS) * (GET_ORDER))) { + with (yielded_clock12 = (clocks)[clientId]) { + with (value30 = (yielded_clock12) + (1)) { + clocks := [clocks EXCEPT ![yielded_clientId7] = value30]; + with (yielded_clientId00 = (self) - ((NUM_CLIENTS) * (GET_ORDER))) { + with (yielded_clock00 = (clocks)[clientId]) { + getReq := [op |-> GET_MSG, key |-> key, client |-> yielded_clientId00, timestamp |-> yielded_clock00, reply_to |-> self]; + with (dst \in ReplicaSet) { + with (value40 = getReq) { + await (Len((replicasNetwork)[dst])) < (BUFFER_SIZE); + replicasNetwork := [replicasNetwork EXCEPT ![dst] = Append((replicasNetwork)[dst], value40)]; + goto getReply; + }; + }; + }; + }; + }; + }; + }; + }; + }; + getReply: + with (yielded_clock2 = (clocks)[clientId]) { + if((yielded_clock2) = (- (1))) { + continue := FALSE; + goto getCheckSpin; + } else { + await (Len((clients)[self])) > (0); + with (msg1 = Head((clients)[self])) { + clients := [clients EXCEPT ![self] = Tail((clients)[self])]; + with (yielded_clients1 = msg1) { + getResp := yielded_clients1; + assert ((getResp).type) = (GET_RESPONSE); + outside := (getResp).result; + goto getCheckSpin; + }; + }; + }; + }; + getCheckSpin: + if(~ (spin)) { + continue := FALSE; + goto getLoop; + } else { + goto getLoop; + }; + } + + fair process (PutClient \in PutSet) + variables continue = TRUE; i; j; putReq; putResp; clientId = cid; clients = clientMailboxes; key = PUT_KEY; value = PUT_VALUE; spin = TRUE; + { + putLoop: + if(continue) { + goto putRequest; + }; + putRequest: + with (yielded_clock5 = (clocks)[clientId]) { + if((yielded_clock5) = (- (1))) { + continue := FALSE; + goto putCheckSpin; + } else { + with (yielded_clientId10 = (self) - ((NUM_CLIENTS) * (PUT_ORDER))) { + with (yielded_clock30 = (clocks)[clientId]) { + with (value50 = (yielded_clock30) + (1)) { + clocks := [clocks EXCEPT ![yielded_clientId10] = value50]; + with (yielded_clientId20 = (self) - ((NUM_CLIENTS) * (PUT_ORDER))) { + with (yielded_clock40 = (clocks)[clientId]) { + putReq := [op |-> PUT_MSG, key |-> key, value |-> value, client |-> yielded_clientId20, timestamp |-> yielded_clock40, reply_to |-> self]; + i := 0; + j := 0; + goto putBroadcast; + }; + }; + }; + }; + }; + }; + }; + putBroadcast: + with (yielded_clock6 = (clocks)[clientId]) { + if(((j) <= ((NUM_REPLICAS) - (1))) /\ ((yielded_clock6) # (- (1)))) { + with (value60 = putReq) { + await (Len((replicasNetwork)[j])) < (BUFFER_SIZE); + replicasNetwork := [replicasNetwork EXCEPT ![j] = Append((replicasNetwork)[j], value60)]; + j := (j) + (1); + goto putBroadcast; + }; + } else { + goto putResponse; + }; + }; + putResponse: + if((i) < (Cardinality(ReplicaSet))) { + with (yielded_clock7 = (clocks)[clientId]) { + if((yielded_clock7) = (- (1))) { + continue := FALSE; + goto putLoop; + } else { + await (Len((clients)[self])) > (0); + with (msg2 = Head((clients)[self])) { + clients := [clients EXCEPT ![self] = Tail((clients)[self])]; + with (yielded_clients00 = msg2) { + putResp := yielded_clients00; + assert ((putResp).type) = (PUT_RESPONSE); + i := (i) + (1); + goto putResponse; + }; + }; + }; + }; + } else { + goto putComplete; + }; + putComplete: + outside := PUT_RESPONSE; + goto putCheckSpin; + putCheckSpin: + if(~ (spin)) { + continue := FALSE; + goto putLoop; + } else { + goto putLoop; + }; + } + + fair process (DisconnectClient \in DisconnectSet) + variables msg; j; clientId = cid; + { + sendDisconnectRequest: + with (yielded_clientId30 = (self) - ((NUM_CLIENTS) * (DISCONNECT_ORDER))) { + msg := [op |-> DISCONNECT_MSG, client |-> yielded_clientId30]; + with (yielded_clientId40 = (self) - ((NUM_CLIENTS) * (DISCONNECT_ORDER))) { + with (value70 = - (1)) { + clocks := [clocks EXCEPT ![yielded_clientId40] = value70]; + j := 0; + goto disconnectBroadcast; + }; + }; + }; + disconnectBroadcast: + if(((j) <= ((NUM_REPLICAS) - (1))) /\ ((0) # (- (1)))) { + with (value80 = msg) { + await (Len((replicasNetwork)[j])) < (BUFFER_SIZE); + replicasNetwork := [replicasNetwork EXCEPT ![j] = Append((replicasNetwork)[j], value80)]; + j := (j) + (1); + goto disconnectBroadcast; + }; + }; + } + + fair process (ClockUpdateClient \in NullSet) + variables continue = TRUE; j; msg; clientId = cid; spin = TRUE; + { + clockUpdateLoop: + if(continue) { + with (yielded_clock10 = (clocks)[clientId]) { + if((yielded_clock10) = (- (1))) { + continue := FALSE; + goto nullCheckSpin; + } else { + with (yielded_clientId50 = (self) - ((NUM_CLIENTS) * (NULL_ORDER))) { + with (yielded_clock80 = (clocks)[clientId]) { + with (value90 = (yielded_clock80) + (1)) { + clocks := [clocks EXCEPT ![yielded_clientId50] = value90]; + with (yielded_clientId60 = (self) - ((NUM_CLIENTS) * (NULL_ORDER))) { + with (yielded_clock90 = (clocks)[clientId]) { + msg := [op |-> NULL_MSG, client |-> yielded_clientId60, timestamp |-> yielded_clock90]; + j := 0; + goto nullBroadcast; + }; + }; + }; + }; + }; + }; + }; + }; + nullBroadcast: + with (yielded_clock11 = (clocks)[clientId]) { + if(((j) <= ((NUM_REPLICAS) - (1))) /\ ((yielded_clock11) # (- (1)))) { + with (value100 = msg) { + await (Len((replicasNetwork)[j])) < (BUFFER_SIZE); + replicasNetwork := [replicasNetwork EXCEPT ![j] = Append((replicasNetwork)[j], value100)]; + j := (j) + (1); + goto nullBroadcast; + }; + } else { + goto nullCheckSpin; + }; + }; + nullCheckSpin: + if(~ (spin)) { + continue := FALSE; + goto clockUpdateLoop; + } else { + goto clockUpdateLoop; + }; + } +} + +\* END PLUSCAL TRANSLATION + + + +***************************************************************************) +\* BEGIN TRANSLATION - the hash of the PCal code: PCal-edda648b9b148ad88bcb79bb7a4a821b +\* Process variable i of process Replica at line 659 col 148 changed to i_ +\* Process variable continue of process Replica at line 659 col 271 changed to continue_ +\* Process variable msg of process Replica at line 659 col 310 changed to msg_ +\* Process variable continue of process GetClient at line 808 col 33 changed to continue_G +\* Process variable continue of process PutClient at line 889 col 34 changed to continue_P +\* Process variable j of process PutClient at line 889 col 54 changed to j_ +\* Process variable msg of process DisconnectClient at line 992 col 15 changed to msg_D +\* Process variable j of process DisconnectClient at line 992 col 20 changed to j_D +CONSTANT defaultInitValue +VARIABLES replicasNetwork, allClients, clientMailboxes, cid, out, clocks, + replicasRead, replicasWrite, kvRead, clientsWrite, clientsWrite0, + kvWrite, kvWrite0, clientsWrite1, clientsWrite2, kvWrite1, + replicasWrite0, clientsWrite3, kvWrite2, clientIdRead, clockRead, + clientIdRead0, clockRead0, clientIdRead1, clockWrite, keyRead, + clientIdRead2, clientIdRead3, clockRead1, replicasWrite1, + clientsRead, clientsWrite4, outsideWrite, clientsWrite5, + outsideWrite0, clockWrite0, replicasWrite2, clientsWrite6, + outsideWrite1, spinRead, clockWrite1, replicasWrite3, clientsWrite7, + outsideWrite2, clientIdRead4, clockRead2, clientIdRead5, clockRead3, + clientIdRead6, clockWrite2, keyRead0, valueRead, clientIdRead7, + clientIdRead8, clockRead4, replicasWrite4, replicasWrite5, + clientsRead0, clientsWrite8, clientsWrite9, clientsWrite10, + outsideWrite3, clockWrite3, replicasWrite6, clientsWrite11, + outsideWrite4, spinRead0, clockWrite4, replicasWrite7, + clientsWrite12, outsideWrite5, clientIdRead9, clientIdRead10, + clockWrite5, replicasWrite8, replicasWrite9, clientIdRead11, + clockRead5, clientIdRead12, clockRead6, clientIdRead13, clockWrite6, + clientIdRead14, clientIdRead15, clockRead7, replicasWrite10, + replicasWrite11, clockWrite7, replicasWrite12, spinRead1, + clockWrite8, replicasWrite13, pc + +(* define statement *) +NUM_NODES == (NUM_REPLICAS) + (NUM_CLIENTS) +ReplicaSet == (0) .. ((NUM_REPLICAS) - (1)) +ClientSet == (NUM_REPLICAS) .. ((NUM_NODES) - (1)) + +VARIABLES kvLocal, liveClients, pendingRequests, stableMessages, i_, + firstPending, timestamp, nextClient, lowestPending, chooseMessage, + currentClocks, minClock, continue_, pendingClients, clientsIter, + msg_, ok, key, val, spinLocal, continue_G, getReq, getResp, + spinLocal0, continue_P, i, j_, putReq, putResp, msg_D, j_D, + spinLocal1, continue, j, msg + +vars == << replicasNetwork, allClients, clientMailboxes, cid, out, clocks, + replicasRead, replicasWrite, kvRead, clientsWrite, clientsWrite0, + kvWrite, kvWrite0, clientsWrite1, clientsWrite2, kvWrite1, + replicasWrite0, clientsWrite3, kvWrite2, clientIdRead, clockRead, + clientIdRead0, clockRead0, clientIdRead1, clockWrite, keyRead, + clientIdRead2, clientIdRead3, clockRead1, replicasWrite1, + clientsRead, clientsWrite4, outsideWrite, clientsWrite5, + outsideWrite0, clockWrite0, replicasWrite2, clientsWrite6, + outsideWrite1, spinRead, clockWrite1, replicasWrite3, + clientsWrite7, outsideWrite2, clientIdRead4, clockRead2, + clientIdRead5, clockRead3, clientIdRead6, clockWrite2, keyRead0, + valueRead, clientIdRead7, clientIdRead8, clockRead4, + replicasWrite4, replicasWrite5, clientsRead0, clientsWrite8, + clientsWrite9, clientsWrite10, outsideWrite3, clockWrite3, + replicasWrite6, clientsWrite11, outsideWrite4, spinRead0, + clockWrite4, replicasWrite7, clientsWrite12, outsideWrite5, + clientIdRead9, clientIdRead10, clockWrite5, replicasWrite8, + replicasWrite9, clientIdRead11, clockRead5, clientIdRead12, + clockRead6, clientIdRead13, clockWrite6, clientIdRead14, + clientIdRead15, clockRead7, replicasWrite10, replicasWrite11, + clockWrite7, replicasWrite12, spinRead1, clockWrite8, + replicasWrite13, pc, kvLocal, liveClients, pendingRequests, + stableMessages, i_, firstPending, timestamp, nextClient, + lowestPending, chooseMessage, currentClocks, minClock, continue_, + pendingClients, clientsIter, msg_, ok, key, val, spinLocal, + continue_G, getReq, getResp, spinLocal0, continue_P, i, j_, putReq, + putResp, msg_D, j_D, spinLocal1, continue, j, msg >> + +ProcSet == (ReplicaSet) \cup (GetSet) \cup (PutSet) \cup (DisconnectSet) \cup (NullSet) + +Init == (* Global variables *) + /\ replicasNetwork = [id \in ReplicaSet |-> <<>>] + /\ allClients = ((((GetSet) \cup (PutSet)) \cup (DisconnectSet)) \cup (NullSet)) + /\ clientMailboxes = [id \in allClients |-> <<>>] + /\ cid = 0 + /\ out = 0 + /\ clocks = [c \in ClientSet |-> 0] + /\ replicasRead = defaultInitValue + /\ replicasWrite = defaultInitValue + /\ kvRead = defaultInitValue + /\ clientsWrite = defaultInitValue + /\ clientsWrite0 = defaultInitValue + /\ kvWrite = defaultInitValue + /\ kvWrite0 = defaultInitValue + /\ clientsWrite1 = defaultInitValue + /\ clientsWrite2 = defaultInitValue + /\ kvWrite1 = defaultInitValue + /\ replicasWrite0 = defaultInitValue + /\ clientsWrite3 = defaultInitValue + /\ kvWrite2 = defaultInitValue + /\ clientIdRead = defaultInitValue + /\ clockRead = defaultInitValue + /\ clientIdRead0 = defaultInitValue + /\ clockRead0 = defaultInitValue + /\ clientIdRead1 = defaultInitValue + /\ clockWrite = defaultInitValue + /\ keyRead = defaultInitValue + /\ clientIdRead2 = defaultInitValue + /\ clientIdRead3 = defaultInitValue + /\ clockRead1 = defaultInitValue + /\ replicasWrite1 = defaultInitValue + /\ clientsRead = defaultInitValue + /\ clientsWrite4 = defaultInitValue + /\ outsideWrite = defaultInitValue + /\ clientsWrite5 = defaultInitValue + /\ outsideWrite0 = defaultInitValue + /\ clockWrite0 = defaultInitValue + /\ replicasWrite2 = defaultInitValue + /\ clientsWrite6 = defaultInitValue + /\ outsideWrite1 = defaultInitValue + /\ spinRead = defaultInitValue + /\ clockWrite1 = defaultInitValue + /\ replicasWrite3 = defaultInitValue + /\ clientsWrite7 = defaultInitValue + /\ outsideWrite2 = defaultInitValue + /\ clientIdRead4 = defaultInitValue + /\ clockRead2 = defaultInitValue + /\ clientIdRead5 = defaultInitValue + /\ clockRead3 = defaultInitValue + /\ clientIdRead6 = defaultInitValue + /\ clockWrite2 = defaultInitValue + /\ keyRead0 = defaultInitValue + /\ valueRead = defaultInitValue + /\ clientIdRead7 = defaultInitValue + /\ clientIdRead8 = defaultInitValue + /\ clockRead4 = defaultInitValue + /\ replicasWrite4 = defaultInitValue + /\ replicasWrite5 = defaultInitValue + /\ clientsRead0 = defaultInitValue + /\ clientsWrite8 = defaultInitValue + /\ clientsWrite9 = defaultInitValue + /\ clientsWrite10 = defaultInitValue + /\ outsideWrite3 = defaultInitValue + /\ clockWrite3 = defaultInitValue + /\ replicasWrite6 = defaultInitValue + /\ clientsWrite11 = defaultInitValue + /\ outsideWrite4 = defaultInitValue + /\ spinRead0 = defaultInitValue + /\ clockWrite4 = defaultInitValue + /\ replicasWrite7 = defaultInitValue + /\ clientsWrite12 = defaultInitValue + /\ outsideWrite5 = defaultInitValue + /\ clientIdRead9 = defaultInitValue + /\ clientIdRead10 = defaultInitValue + /\ clockWrite5 = defaultInitValue + /\ replicasWrite8 = defaultInitValue + /\ replicasWrite9 = defaultInitValue + /\ clientIdRead11 = defaultInitValue + /\ clockRead5 = defaultInitValue + /\ clientIdRead12 = defaultInitValue + /\ clockRead6 = defaultInitValue + /\ clientIdRead13 = defaultInitValue + /\ clockWrite6 = defaultInitValue + /\ clientIdRead14 = defaultInitValue + /\ clientIdRead15 = defaultInitValue + /\ clockRead7 = defaultInitValue + /\ replicasWrite10 = defaultInitValue + /\ replicasWrite11 = defaultInitValue + /\ clockWrite7 = defaultInitValue + /\ replicasWrite12 = defaultInitValue + /\ spinRead1 = defaultInitValue + /\ clockWrite8 = defaultInitValue + /\ replicasWrite13 = defaultInitValue + (* Process Replica *) + /\ kvLocal = [self \in ReplicaSet |-> [k \in KeySpace |-> NULL]] + /\ liveClients = [self \in ReplicaSet |-> ClientSet] + /\ pendingRequests = [self \in ReplicaSet |-> [c \in liveClients[self] |-> <<>>]] + /\ stableMessages = [self \in ReplicaSet |-> <<>>] + /\ i_ = [self \in ReplicaSet |-> defaultInitValue] + /\ firstPending = [self \in ReplicaSet |-> defaultInitValue] + /\ timestamp = [self \in ReplicaSet |-> defaultInitValue] + /\ nextClient = [self \in ReplicaSet |-> defaultInitValue] + /\ lowestPending = [self \in ReplicaSet |-> defaultInitValue] + /\ chooseMessage = [self \in ReplicaSet |-> defaultInitValue] + /\ currentClocks = [self \in ReplicaSet |-> [c \in liveClients[self] |-> 0]] + /\ minClock = [self \in ReplicaSet |-> defaultInitValue] + /\ continue_ = [self \in ReplicaSet |-> defaultInitValue] + /\ pendingClients = [self \in ReplicaSet |-> defaultInitValue] + /\ clientsIter = [self \in ReplicaSet |-> defaultInitValue] + /\ msg_ = [self \in ReplicaSet |-> defaultInitValue] + /\ ok = [self \in ReplicaSet |-> defaultInitValue] + /\ key = [self \in ReplicaSet |-> defaultInitValue] + /\ val = [self \in ReplicaSet |-> defaultInitValue] + (* Process GetClient *) + /\ spinLocal = [self \in GetSet |-> TRUE] + /\ continue_G = [self \in GetSet |-> TRUE] + /\ getReq = [self \in GetSet |-> defaultInitValue] + /\ getResp = [self \in GetSet |-> defaultInitValue] + (* Process PutClient *) + /\ spinLocal0 = [self \in PutSet |-> TRUE] + /\ continue_P = [self \in PutSet |-> TRUE] + /\ i = [self \in PutSet |-> defaultInitValue] + /\ j_ = [self \in PutSet |-> defaultInitValue] + /\ putReq = [self \in PutSet |-> defaultInitValue] + /\ putResp = [self \in PutSet |-> defaultInitValue] + (* Process DisconnectClient *) + /\ msg_D = [self \in DisconnectSet |-> defaultInitValue] + /\ j_D = [self \in DisconnectSet |-> defaultInitValue] + (* Process ClockUpdateClient *) + /\ spinLocal1 = [self \in NullSet |-> TRUE] + /\ continue = [self \in NullSet |-> TRUE] + /\ j = [self \in NullSet |-> defaultInitValue] + /\ msg = [self \in NullSet |-> defaultInitValue] + /\ pc = [self \in ProcSet |-> CASE self \in ReplicaSet -> "replicaLoop" + [] self \in GetSet -> "getLoop" + [] self \in PutSet -> "putLoop" + [] self \in DisconnectSet -> "sendDisconnectRequest" + [] self \in NullSet -> "clockUpdateLoop"] + +replicaLoop(self) == /\ pc[self] = "replicaLoop" + /\ IF TRUE + THEN /\ stableMessages' = [stableMessages EXCEPT ![self] = <<>>] + /\ continue_' = [continue_ EXCEPT ![self] = TRUE] + /\ pc' = [pc EXCEPT ![self] = "receiveClientRequest"] + /\ UNCHANGED << replicasNetwork, + clientMailboxes, + replicasWrite0, clientsWrite3, + kvWrite2, kvLocal >> + ELSE /\ replicasWrite0' = replicasNetwork + /\ clientsWrite3' = clientMailboxes + /\ kvWrite2' = kvLocal[self] + /\ clientMailboxes' = clientsWrite3' + /\ replicasNetwork' = replicasWrite0' + /\ kvLocal' = [kvLocal EXCEPT ![self] = kvWrite2'] + /\ pc' = [pc EXCEPT ![self] = "Done"] + /\ UNCHANGED << stableMessages, continue_ >> + /\ UNCHANGED << allClients, cid, out, clocks, + replicasRead, replicasWrite, kvRead, + clientsWrite, clientsWrite0, kvWrite, + kvWrite0, clientsWrite1, clientsWrite2, + kvWrite1, clientIdRead, clockRead, + clientIdRead0, clockRead0, clientIdRead1, + clockWrite, keyRead, clientIdRead2, + clientIdRead3, clockRead1, replicasWrite1, + clientsRead, clientsWrite4, outsideWrite, + clientsWrite5, outsideWrite0, clockWrite0, + replicasWrite2, clientsWrite6, + outsideWrite1, spinRead, clockWrite1, + replicasWrite3, clientsWrite7, + outsideWrite2, clientIdRead4, clockRead2, + clientIdRead5, clockRead3, clientIdRead6, + clockWrite2, keyRead0, valueRead, + clientIdRead7, clientIdRead8, clockRead4, + replicasWrite4, replicasWrite5, + clientsRead0, clientsWrite8, + clientsWrite9, clientsWrite10, + outsideWrite3, clockWrite3, + replicasWrite6, clientsWrite11, + outsideWrite4, spinRead0, clockWrite4, + replicasWrite7, clientsWrite12, + outsideWrite5, clientIdRead9, + clientIdRead10, clockWrite5, + replicasWrite8, replicasWrite9, + clientIdRead11, clockRead5, + clientIdRead12, clockRead6, + clientIdRead13, clockWrite6, + clientIdRead14, clientIdRead15, + clockRead7, replicasWrite10, + replicasWrite11, clockWrite7, + replicasWrite12, spinRead1, clockWrite8, + replicasWrite13, liveClients, + pendingRequests, i_, firstPending, + timestamp, nextClient, lowestPending, + chooseMessage, currentClocks, minClock, + pendingClients, clientsIter, msg_, ok, + key, val, spinLocal, continue_G, getReq, + getResp, spinLocal0, continue_P, i, j_, + putReq, putResp, msg_D, j_D, spinLocal1, + continue, j, msg >> + +receiveClientRequest(self) == /\ pc[self] = "receiveClientRequest" + /\ (Len(replicasNetwork[self])) > (0) + /\ LET msg0 == Head(replicasNetwork[self]) IN + /\ replicasWrite' = [replicasNetwork EXCEPT ![self] = Tail(replicasNetwork[self])] + /\ replicasRead' = msg0 + /\ msg_' = [msg_ EXCEPT ![self] = replicasRead'] + /\ replicasNetwork' = replicasWrite' + /\ pc' = [pc EXCEPT ![self] = "clientDisconnected"] + /\ UNCHANGED << allClients, clientMailboxes, cid, + out, clocks, kvRead, + clientsWrite, clientsWrite0, + kvWrite, kvWrite0, clientsWrite1, + clientsWrite2, kvWrite1, + replicasWrite0, clientsWrite3, + kvWrite2, clientIdRead, + clockRead, clientIdRead0, + clockRead0, clientIdRead1, + clockWrite, keyRead, + clientIdRead2, clientIdRead3, + clockRead1, replicasWrite1, + clientsRead, clientsWrite4, + outsideWrite, clientsWrite5, + outsideWrite0, clockWrite0, + replicasWrite2, clientsWrite6, + outsideWrite1, spinRead, + clockWrite1, replicasWrite3, + clientsWrite7, outsideWrite2, + clientIdRead4, clockRead2, + clientIdRead5, clockRead3, + clientIdRead6, clockWrite2, + keyRead0, valueRead, + clientIdRead7, clientIdRead8, + clockRead4, replicasWrite4, + replicasWrite5, clientsRead0, + clientsWrite8, clientsWrite9, + clientsWrite10, outsideWrite3, + clockWrite3, replicasWrite6, + clientsWrite11, outsideWrite4, + spinRead0, clockWrite4, + replicasWrite7, clientsWrite12, + outsideWrite5, clientIdRead9, + clientIdRead10, clockWrite5, + replicasWrite8, replicasWrite9, + clientIdRead11, clockRead5, + clientIdRead12, clockRead6, + clientIdRead13, clockWrite6, + clientIdRead14, clientIdRead15, + clockRead7, replicasWrite10, + replicasWrite11, clockWrite7, + replicasWrite12, spinRead1, + clockWrite8, replicasWrite13, + kvLocal, liveClients, + pendingRequests, stableMessages, + i_, firstPending, timestamp, + nextClient, lowestPending, + chooseMessage, currentClocks, + minClock, continue_, + pendingClients, clientsIter, ok, + key, val, spinLocal, continue_G, + getReq, getResp, spinLocal0, + continue_P, i, j_, putReq, + putResp, msg_D, j_D, spinLocal1, + continue, j, msg >> + +clientDisconnected(self) == /\ pc[self] = "clientDisconnected" + /\ IF ((msg_[self]).op) = (DISCONNECT_MSG) + THEN /\ liveClients' = [liveClients EXCEPT ![self] = (liveClients[self]) \ ({(msg_[self]).client})] + ELSE /\ TRUE + /\ UNCHANGED liveClients + /\ pc' = [pc EXCEPT ![self] = "replicaGetRequest"] + /\ UNCHANGED << replicasNetwork, allClients, + clientMailboxes, cid, out, clocks, + replicasRead, replicasWrite, + kvRead, clientsWrite, + clientsWrite0, kvWrite, kvWrite0, + clientsWrite1, clientsWrite2, + kvWrite1, replicasWrite0, + clientsWrite3, kvWrite2, + clientIdRead, clockRead, + clientIdRead0, clockRead0, + clientIdRead1, clockWrite, keyRead, + clientIdRead2, clientIdRead3, + clockRead1, replicasWrite1, + clientsRead, clientsWrite4, + outsideWrite, clientsWrite5, + outsideWrite0, clockWrite0, + replicasWrite2, clientsWrite6, + outsideWrite1, spinRead, + clockWrite1, replicasWrite3, + clientsWrite7, outsideWrite2, + clientIdRead4, clockRead2, + clientIdRead5, clockRead3, + clientIdRead6, clockWrite2, + keyRead0, valueRead, clientIdRead7, + clientIdRead8, clockRead4, + replicasWrite4, replicasWrite5, + clientsRead0, clientsWrite8, + clientsWrite9, clientsWrite10, + outsideWrite3, clockWrite3, + replicasWrite6, clientsWrite11, + outsideWrite4, spinRead0, + clockWrite4, replicasWrite7, + clientsWrite12, outsideWrite5, + clientIdRead9, clientIdRead10, + clockWrite5, replicasWrite8, + replicasWrite9, clientIdRead11, + clockRead5, clientIdRead12, + clockRead6, clientIdRead13, + clockWrite6, clientIdRead14, + clientIdRead15, clockRead7, + replicasWrite10, replicasWrite11, + clockWrite7, replicasWrite12, + spinRead1, clockWrite8, + replicasWrite13, kvLocal, + pendingRequests, stableMessages, + i_, firstPending, timestamp, + nextClient, lowestPending, + chooseMessage, currentClocks, + minClock, continue_, + pendingClients, clientsIter, msg_, + ok, key, val, spinLocal, + continue_G, getReq, getResp, + spinLocal0, continue_P, i, j_, + putReq, putResp, msg_D, j_D, + spinLocal1, continue, j, msg >> + +replicaGetRequest(self) == /\ pc[self] = "replicaGetRequest" + /\ IF ((msg_[self]).op) = (GET_MSG) + THEN /\ Assert(((msg_[self]).client) \in (liveClients[self]), + "Failure of assertion at line 681, column 25.") + /\ currentClocks' = [currentClocks EXCEPT ![self][msg_[self].client] = (msg_[self]).timestamp] + /\ pendingRequests' = [pendingRequests EXCEPT ![self][msg_[self].client] = Append(pendingRequests[self][(msg_[self]).client], msg_[self])] + ELSE /\ TRUE + /\ UNCHANGED << pendingRequests, + currentClocks >> + /\ pc' = [pc EXCEPT ![self] = "replicaPutRequest"] + /\ UNCHANGED << replicasNetwork, allClients, + clientMailboxes, cid, out, clocks, + replicasRead, replicasWrite, kvRead, + clientsWrite, clientsWrite0, + kvWrite, kvWrite0, clientsWrite1, + clientsWrite2, kvWrite1, + replicasWrite0, clientsWrite3, + kvWrite2, clientIdRead, clockRead, + clientIdRead0, clockRead0, + clientIdRead1, clockWrite, keyRead, + clientIdRead2, clientIdRead3, + clockRead1, replicasWrite1, + clientsRead, clientsWrite4, + outsideWrite, clientsWrite5, + outsideWrite0, clockWrite0, + replicasWrite2, clientsWrite6, + outsideWrite1, spinRead, + clockWrite1, replicasWrite3, + clientsWrite7, outsideWrite2, + clientIdRead4, clockRead2, + clientIdRead5, clockRead3, + clientIdRead6, clockWrite2, + keyRead0, valueRead, clientIdRead7, + clientIdRead8, clockRead4, + replicasWrite4, replicasWrite5, + clientsRead0, clientsWrite8, + clientsWrite9, clientsWrite10, + outsideWrite3, clockWrite3, + replicasWrite6, clientsWrite11, + outsideWrite4, spinRead0, + clockWrite4, replicasWrite7, + clientsWrite12, outsideWrite5, + clientIdRead9, clientIdRead10, + clockWrite5, replicasWrite8, + replicasWrite9, clientIdRead11, + clockRead5, clientIdRead12, + clockRead6, clientIdRead13, + clockWrite6, clientIdRead14, + clientIdRead15, clockRead7, + replicasWrite10, replicasWrite11, + clockWrite7, replicasWrite12, + spinRead1, clockWrite8, + replicasWrite13, kvLocal, + liveClients, stableMessages, i_, + firstPending, timestamp, nextClient, + lowestPending, chooseMessage, + minClock, continue_, pendingClients, + clientsIter, msg_, ok, key, val, + spinLocal, continue_G, getReq, + getResp, spinLocal0, continue_P, i, + j_, putReq, putResp, msg_D, j_D, + spinLocal1, continue, j, msg >> + +replicaPutRequest(self) == /\ pc[self] = "replicaPutRequest" + /\ IF ((msg_[self]).op) = (PUT_MSG) + THEN /\ currentClocks' = [currentClocks EXCEPT ![self][msg_[self].client] = (msg_[self]).timestamp] + /\ pendingRequests' = [pendingRequests EXCEPT ![self][msg_[self].client] = Append(pendingRequests[self][(msg_[self]).client], msg_[self])] + ELSE /\ TRUE + /\ UNCHANGED << pendingRequests, + currentClocks >> + /\ pc' = [pc EXCEPT ![self] = "replicaNullRequest"] + /\ UNCHANGED << replicasNetwork, allClients, + clientMailboxes, cid, out, clocks, + replicasRead, replicasWrite, kvRead, + clientsWrite, clientsWrite0, + kvWrite, kvWrite0, clientsWrite1, + clientsWrite2, kvWrite1, + replicasWrite0, clientsWrite3, + kvWrite2, clientIdRead, clockRead, + clientIdRead0, clockRead0, + clientIdRead1, clockWrite, keyRead, + clientIdRead2, clientIdRead3, + clockRead1, replicasWrite1, + clientsRead, clientsWrite4, + outsideWrite, clientsWrite5, + outsideWrite0, clockWrite0, + replicasWrite2, clientsWrite6, + outsideWrite1, spinRead, + clockWrite1, replicasWrite3, + clientsWrite7, outsideWrite2, + clientIdRead4, clockRead2, + clientIdRead5, clockRead3, + clientIdRead6, clockWrite2, + keyRead0, valueRead, clientIdRead7, + clientIdRead8, clockRead4, + replicasWrite4, replicasWrite5, + clientsRead0, clientsWrite8, + clientsWrite9, clientsWrite10, + outsideWrite3, clockWrite3, + replicasWrite6, clientsWrite11, + outsideWrite4, spinRead0, + clockWrite4, replicasWrite7, + clientsWrite12, outsideWrite5, + clientIdRead9, clientIdRead10, + clockWrite5, replicasWrite8, + replicasWrite9, clientIdRead11, + clockRead5, clientIdRead12, + clockRead6, clientIdRead13, + clockWrite6, clientIdRead14, + clientIdRead15, clockRead7, + replicasWrite10, replicasWrite11, + clockWrite7, replicasWrite12, + spinRead1, clockWrite8, + replicasWrite13, kvLocal, + liveClients, stableMessages, i_, + firstPending, timestamp, nextClient, + lowestPending, chooseMessage, + minClock, continue_, pendingClients, + clientsIter, msg_, ok, key, val, + spinLocal, continue_G, getReq, + getResp, spinLocal0, continue_P, i, + j_, putReq, putResp, msg_D, j_D, + spinLocal1, continue, j, msg >> + +replicaNullRequest(self) == /\ pc[self] = "replicaNullRequest" + /\ IF ((msg_[self]).op) = (NULL_MSG) + THEN /\ currentClocks' = [currentClocks EXCEPT ![self][msg_[self].client] = (msg_[self]).timestamp] + ELSE /\ TRUE + /\ UNCHANGED currentClocks + /\ pc' = [pc EXCEPT ![self] = "findStableRequestsLoop"] + /\ UNCHANGED << replicasNetwork, allClients, + clientMailboxes, cid, out, clocks, + replicasRead, replicasWrite, + kvRead, clientsWrite, + clientsWrite0, kvWrite, kvWrite0, + clientsWrite1, clientsWrite2, + kvWrite1, replicasWrite0, + clientsWrite3, kvWrite2, + clientIdRead, clockRead, + clientIdRead0, clockRead0, + clientIdRead1, clockWrite, keyRead, + clientIdRead2, clientIdRead3, + clockRead1, replicasWrite1, + clientsRead, clientsWrite4, + outsideWrite, clientsWrite5, + outsideWrite0, clockWrite0, + replicasWrite2, clientsWrite6, + outsideWrite1, spinRead, + clockWrite1, replicasWrite3, + clientsWrite7, outsideWrite2, + clientIdRead4, clockRead2, + clientIdRead5, clockRead3, + clientIdRead6, clockWrite2, + keyRead0, valueRead, clientIdRead7, + clientIdRead8, clockRead4, + replicasWrite4, replicasWrite5, + clientsRead0, clientsWrite8, + clientsWrite9, clientsWrite10, + outsideWrite3, clockWrite3, + replicasWrite6, clientsWrite11, + outsideWrite4, spinRead0, + clockWrite4, replicasWrite7, + clientsWrite12, outsideWrite5, + clientIdRead9, clientIdRead10, + clockWrite5, replicasWrite8, + replicasWrite9, clientIdRead11, + clockRead5, clientIdRead12, + clockRead6, clientIdRead13, + clockWrite6, clientIdRead14, + clientIdRead15, clockRead7, + replicasWrite10, replicasWrite11, + clockWrite7, replicasWrite12, + spinRead1, clockWrite8, + replicasWrite13, kvLocal, + liveClients, pendingRequests, + stableMessages, i_, firstPending, + timestamp, nextClient, + lowestPending, chooseMessage, + minClock, continue_, + pendingClients, clientsIter, msg_, + ok, key, val, spinLocal, + continue_G, getReq, getResp, + spinLocal0, continue_P, i, j_, + putReq, putResp, msg_D, j_D, + spinLocal1, continue, j, msg >> + +findStableRequestsLoop(self) == /\ pc[self] = "findStableRequestsLoop" + /\ IF continue_[self] + THEN /\ pendingClients' = [pendingClients EXCEPT ![self] = {c \in liveClients[self] : (Len(pendingRequests[self][c])) > (0)}] + /\ nextClient' = [nextClient EXCEPT ![self] = (NUM_NODES) + (1)] + /\ clientsIter' = [clientsIter EXCEPT ![self] = liveClients[self]] + /\ i_' = [i_ EXCEPT ![self] = 0] + /\ minClock' = [minClock EXCEPT ![self] = 0] + /\ pc' = [pc EXCEPT ![self] = "findMinClock"] + ELSE /\ i_' = [i_ EXCEPT ![self] = 1] + /\ pc' = [pc EXCEPT ![self] = "respondPendingRequestsLoop"] + /\ UNCHANGED << nextClient, + minClock, + pendingClients, + clientsIter >> + /\ UNCHANGED << replicasNetwork, allClients, + clientMailboxes, cid, out, + clocks, replicasRead, + replicasWrite, kvRead, + clientsWrite, clientsWrite0, + kvWrite, kvWrite0, + clientsWrite1, clientsWrite2, + kvWrite1, replicasWrite0, + clientsWrite3, kvWrite2, + clientIdRead, clockRead, + clientIdRead0, clockRead0, + clientIdRead1, clockWrite, + keyRead, clientIdRead2, + clientIdRead3, clockRead1, + replicasWrite1, clientsRead, + clientsWrite4, outsideWrite, + clientsWrite5, outsideWrite0, + clockWrite0, replicasWrite2, + clientsWrite6, outsideWrite1, + spinRead, clockWrite1, + replicasWrite3, clientsWrite7, + outsideWrite2, clientIdRead4, + clockRead2, clientIdRead5, + clockRead3, clientIdRead6, + clockWrite2, keyRead0, + valueRead, clientIdRead7, + clientIdRead8, clockRead4, + replicasWrite4, replicasWrite5, + clientsRead0, clientsWrite8, + clientsWrite9, clientsWrite10, + outsideWrite3, clockWrite3, + replicasWrite6, clientsWrite11, + outsideWrite4, spinRead0, + clockWrite4, replicasWrite7, + clientsWrite12, outsideWrite5, + clientIdRead9, clientIdRead10, + clockWrite5, replicasWrite8, + replicasWrite9, clientIdRead11, + clockRead5, clientIdRead12, + clockRead6, clientIdRead13, + clockWrite6, clientIdRead14, + clientIdRead15, clockRead7, + replicasWrite10, + replicasWrite11, clockWrite7, + replicasWrite12, spinRead1, + clockWrite8, replicasWrite13, + kvLocal, liveClients, + pendingRequests, + stableMessages, firstPending, + timestamp, lowestPending, + chooseMessage, currentClocks, + continue_, msg_, ok, key, val, + spinLocal, continue_G, getReq, + getResp, spinLocal0, + continue_P, i, j_, putReq, + putResp, msg_D, j_D, + spinLocal1, continue, j, msg >> + +findMinClock(self) == /\ pc[self] = "findMinClock" + /\ IF (i_[self]) < (Cardinality(clientsIter[self])) + THEN /\ \E client \in clientsIter[self]: + /\ IF ((minClock[self]) = (0)) \/ ((currentClocks[self][client]) < (minClock[self])) + THEN /\ minClock' = [minClock EXCEPT ![self] = currentClocks[self][client]] + ELSE /\ TRUE + /\ UNCHANGED minClock + /\ clientsIter' = [clientsIter EXCEPT ![self] = (clientsIter[self]) \ ({client})] + /\ pc' = [pc EXCEPT ![self] = "findMinClock"] + /\ UNCHANGED << i_, lowestPending >> + ELSE /\ lowestPending' = [lowestPending EXCEPT ![self] = (minClock[self]) + (1)] + /\ i_' = [i_ EXCEPT ![self] = 0] + /\ pc' = [pc EXCEPT ![self] = "findMinClient"] + /\ UNCHANGED << minClock, clientsIter >> + /\ UNCHANGED << replicasNetwork, allClients, + clientMailboxes, cid, out, clocks, + replicasRead, replicasWrite, kvRead, + clientsWrite, clientsWrite0, kvWrite, + kvWrite0, clientsWrite1, clientsWrite2, + kvWrite1, replicasWrite0, clientsWrite3, + kvWrite2, clientIdRead, clockRead, + clientIdRead0, clockRead0, clientIdRead1, + clockWrite, keyRead, clientIdRead2, + clientIdRead3, clockRead1, + replicasWrite1, clientsRead, + clientsWrite4, outsideWrite, + clientsWrite5, outsideWrite0, + clockWrite0, replicasWrite2, + clientsWrite6, outsideWrite1, spinRead, + clockWrite1, replicasWrite3, + clientsWrite7, outsideWrite2, + clientIdRead4, clockRead2, clientIdRead5, + clockRead3, clientIdRead6, clockWrite2, + keyRead0, valueRead, clientIdRead7, + clientIdRead8, clockRead4, + replicasWrite4, replicasWrite5, + clientsRead0, clientsWrite8, + clientsWrite9, clientsWrite10, + outsideWrite3, clockWrite3, + replicasWrite6, clientsWrite11, + outsideWrite4, spinRead0, clockWrite4, + replicasWrite7, clientsWrite12, + outsideWrite5, clientIdRead9, + clientIdRead10, clockWrite5, + replicasWrite8, replicasWrite9, + clientIdRead11, clockRead5, + clientIdRead12, clockRead6, + clientIdRead13, clockWrite6, + clientIdRead14, clientIdRead15, + clockRead7, replicasWrite10, + replicasWrite11, clockWrite7, + replicasWrite12, spinRead1, clockWrite8, + replicasWrite13, kvLocal, liveClients, + pendingRequests, stableMessages, + firstPending, timestamp, nextClient, + chooseMessage, currentClocks, continue_, + pendingClients, msg_, ok, key, val, + spinLocal, continue_G, getReq, getResp, + spinLocal0, continue_P, i, j_, putReq, + putResp, msg_D, j_D, spinLocal1, + continue, j, msg >> + +findMinClient(self) == /\ pc[self] = "findMinClient" + /\ IF (i_[self]) < (Cardinality(pendingClients[self])) + THEN /\ \E client \in pendingClients[self]: + /\ firstPending' = [firstPending EXCEPT ![self] = Head(pendingRequests[self][client])] + /\ Assert((((firstPending'[self]).op) = (GET_MSG)) \/ (((firstPending'[self]).op) = (PUT_MSG)), + "Failure of assertion at line 722, column 37.") + /\ timestamp' = [timestamp EXCEPT ![self] = (firstPending'[self]).timestamp] + /\ IF (timestamp'[self]) < (minClock[self]) + THEN /\ chooseMessage' = [chooseMessage EXCEPT ![self] = ((timestamp'[self]) < (lowestPending[self])) \/ (((timestamp'[self]) = (lowestPending[self])) /\ ((client) < (nextClient[self])))] + /\ IF chooseMessage'[self] + THEN /\ nextClient' = [nextClient EXCEPT ![self] = client] + /\ lowestPending' = [lowestPending EXCEPT ![self] = timestamp'[self]] + ELSE /\ TRUE + /\ UNCHANGED << nextClient, + lowestPending >> + ELSE /\ TRUE + /\ UNCHANGED << nextClient, + lowestPending, + chooseMessage >> + /\ pendingClients' = [pendingClients EXCEPT ![self] = (pendingClients[self]) \ ({client})] + /\ pc' = [pc EXCEPT ![self] = "findMinClient"] + ELSE /\ pc' = [pc EXCEPT ![self] = "addStableMessage"] + /\ UNCHANGED << firstPending, timestamp, + nextClient, lowestPending, + chooseMessage, + pendingClients >> + /\ UNCHANGED << replicasNetwork, allClients, + clientMailboxes, cid, out, clocks, + replicasRead, replicasWrite, kvRead, + clientsWrite, clientsWrite0, kvWrite, + kvWrite0, clientsWrite1, clientsWrite2, + kvWrite1, replicasWrite0, clientsWrite3, + kvWrite2, clientIdRead, clockRead, + clientIdRead0, clockRead0, + clientIdRead1, clockWrite, keyRead, + clientIdRead2, clientIdRead3, + clockRead1, replicasWrite1, clientsRead, + clientsWrite4, outsideWrite, + clientsWrite5, outsideWrite0, + clockWrite0, replicasWrite2, + clientsWrite6, outsideWrite1, spinRead, + clockWrite1, replicasWrite3, + clientsWrite7, outsideWrite2, + clientIdRead4, clockRead2, + clientIdRead5, clockRead3, + clientIdRead6, clockWrite2, keyRead0, + valueRead, clientIdRead7, clientIdRead8, + clockRead4, replicasWrite4, + replicasWrite5, clientsRead0, + clientsWrite8, clientsWrite9, + clientsWrite10, outsideWrite3, + clockWrite3, replicasWrite6, + clientsWrite11, outsideWrite4, + spinRead0, clockWrite4, replicasWrite7, + clientsWrite12, outsideWrite5, + clientIdRead9, clientIdRead10, + clockWrite5, replicasWrite8, + replicasWrite9, clientIdRead11, + clockRead5, clientIdRead12, clockRead6, + clientIdRead13, clockWrite6, + clientIdRead14, clientIdRead15, + clockRead7, replicasWrite10, + replicasWrite11, clockWrite7, + replicasWrite12, spinRead1, clockWrite8, + replicasWrite13, kvLocal, liveClients, + pendingRequests, stableMessages, i_, + currentClocks, minClock, continue_, + clientsIter, msg_, ok, key, val, + spinLocal, continue_G, getReq, getResp, + spinLocal0, continue_P, i, j_, putReq, + putResp, msg_D, j_D, spinLocal1, + continue, j, msg >> + +addStableMessage(self) == /\ pc[self] = "addStableMessage" + /\ IF (lowestPending[self]) < (minClock[self]) + THEN /\ msg_' = [msg_ EXCEPT ![self] = Head(pendingRequests[self][nextClient[self]])] + /\ pendingRequests' = [pendingRequests EXCEPT ![self][nextClient[self]] = Tail(pendingRequests[self][nextClient[self]])] + /\ stableMessages' = [stableMessages EXCEPT ![self] = Append(stableMessages[self], msg_'[self])] + /\ pc' = [pc EXCEPT ![self] = "findStableRequestsLoop"] + /\ UNCHANGED continue_ + ELSE /\ continue_' = [continue_ EXCEPT ![self] = FALSE] + /\ pc' = [pc EXCEPT ![self] = "findStableRequestsLoop"] + /\ UNCHANGED << pendingRequests, + stableMessages, msg_ >> + /\ UNCHANGED << replicasNetwork, allClients, + clientMailboxes, cid, out, clocks, + replicasRead, replicasWrite, kvRead, + clientsWrite, clientsWrite0, kvWrite, + kvWrite0, clientsWrite1, + clientsWrite2, kvWrite1, + replicasWrite0, clientsWrite3, + kvWrite2, clientIdRead, clockRead, + clientIdRead0, clockRead0, + clientIdRead1, clockWrite, keyRead, + clientIdRead2, clientIdRead3, + clockRead1, replicasWrite1, + clientsRead, clientsWrite4, + outsideWrite, clientsWrite5, + outsideWrite0, clockWrite0, + replicasWrite2, clientsWrite6, + outsideWrite1, spinRead, clockWrite1, + replicasWrite3, clientsWrite7, + outsideWrite2, clientIdRead4, + clockRead2, clientIdRead5, + clockRead3, clientIdRead6, + clockWrite2, keyRead0, valueRead, + clientIdRead7, clientIdRead8, + clockRead4, replicasWrite4, + replicasWrite5, clientsRead0, + clientsWrite8, clientsWrite9, + clientsWrite10, outsideWrite3, + clockWrite3, replicasWrite6, + clientsWrite11, outsideWrite4, + spinRead0, clockWrite4, + replicasWrite7, clientsWrite12, + outsideWrite5, clientIdRead9, + clientIdRead10, clockWrite5, + replicasWrite8, replicasWrite9, + clientIdRead11, clockRead5, + clientIdRead12, clockRead6, + clientIdRead13, clockWrite6, + clientIdRead14, clientIdRead15, + clockRead7, replicasWrite10, + replicasWrite11, clockWrite7, + replicasWrite12, spinRead1, + clockWrite8, replicasWrite13, + kvLocal, liveClients, i_, + firstPending, timestamp, nextClient, + lowestPending, chooseMessage, + currentClocks, minClock, + pendingClients, clientsIter, ok, key, + val, spinLocal, continue_G, getReq, + getResp, spinLocal0, continue_P, i, + j_, putReq, putResp, msg_D, j_D, + spinLocal1, continue, j, msg >> + +respondPendingRequestsLoop(self) == /\ pc[self] = "respondPendingRequestsLoop" + /\ IF (i_[self]) <= (Len(stableMessages[self])) + THEN /\ msg_' = [msg_ EXCEPT ![self] = stableMessages[self][i_[self]]] + /\ i_' = [i_ EXCEPT ![self] = (i_[self]) + (1)] + /\ pc' = [pc EXCEPT ![self] = "respondStableGet"] + /\ UNCHANGED << clientMailboxes, + clientsWrite2, + kvWrite1, + kvLocal >> + ELSE /\ clientsWrite2' = clientMailboxes + /\ kvWrite1' = kvLocal[self] + /\ clientMailboxes' = clientsWrite2' + /\ kvLocal' = [kvLocal EXCEPT ![self] = kvWrite1'] + /\ pc' = [pc EXCEPT ![self] = "replicaLoop"] + /\ UNCHANGED << i_, msg_ >> + /\ UNCHANGED << replicasNetwork, + allClients, cid, out, + clocks, replicasRead, + replicasWrite, kvRead, + clientsWrite, + clientsWrite0, kvWrite, + kvWrite0, clientsWrite1, + replicasWrite0, + clientsWrite3, kvWrite2, + clientIdRead, clockRead, + clientIdRead0, clockRead0, + clientIdRead1, clockWrite, + keyRead, clientIdRead2, + clientIdRead3, clockRead1, + replicasWrite1, + clientsRead, clientsWrite4, + outsideWrite, + clientsWrite5, + outsideWrite0, clockWrite0, + replicasWrite2, + clientsWrite6, + outsideWrite1, spinRead, + clockWrite1, + replicasWrite3, + clientsWrite7, + outsideWrite2, + clientIdRead4, clockRead2, + clientIdRead5, clockRead3, + clientIdRead6, clockWrite2, + keyRead0, valueRead, + clientIdRead7, + clientIdRead8, clockRead4, + replicasWrite4, + replicasWrite5, + clientsRead0, + clientsWrite8, + clientsWrite9, + clientsWrite10, + outsideWrite3, clockWrite3, + replicasWrite6, + clientsWrite11, + outsideWrite4, spinRead0, + clockWrite4, + replicasWrite7, + clientsWrite12, + outsideWrite5, + clientIdRead9, + clientIdRead10, + clockWrite5, + replicasWrite8, + replicasWrite9, + clientIdRead11, clockRead5, + clientIdRead12, clockRead6, + clientIdRead13, + clockWrite6, + clientIdRead14, + clientIdRead15, clockRead7, + replicasWrite10, + replicasWrite11, + clockWrite7, + replicasWrite12, spinRead1, + clockWrite8, + replicasWrite13, + liveClients, + pendingRequests, + stableMessages, + firstPending, timestamp, + nextClient, lowestPending, + chooseMessage, + currentClocks, minClock, + continue_, pendingClients, + clientsIter, ok, key, val, + spinLocal, continue_G, + getReq, getResp, + spinLocal0, continue_P, i, + j_, putReq, putResp, msg_D, + j_D, spinLocal1, continue, + j, msg >> + +respondStableGet(self) == /\ pc[self] = "respondStableGet" + /\ IF ((msg_[self]).op) = (GET_MSG) + THEN /\ key' = [key EXCEPT ![self] = (msg_[self]).key] + /\ kvRead' = kvLocal[self][key'[self]] + /\ val' = [val EXCEPT ![self] = kvRead'] + /\ (Len(clientMailboxes[(msg_[self]).reply_to])) < (BUFFER_SIZE) + /\ clientsWrite' = [clientMailboxes EXCEPT ![(msg_[self]).reply_to] = Append(clientMailboxes[(msg_[self]).reply_to], [type |-> GET_RESPONSE, result |-> val'[self]])] + /\ clientsWrite0' = clientsWrite' + /\ clientMailboxes' = clientsWrite0' + ELSE /\ clientsWrite0' = clientMailboxes + /\ clientMailboxes' = clientsWrite0' + /\ UNCHANGED << kvRead, clientsWrite, key, + val >> + /\ pc' = [pc EXCEPT ![self] = "respondStablePut"] + /\ UNCHANGED << replicasNetwork, allClients, cid, + out, clocks, replicasRead, + replicasWrite, kvWrite, kvWrite0, + clientsWrite1, clientsWrite2, + kvWrite1, replicasWrite0, + clientsWrite3, kvWrite2, + clientIdRead, clockRead, + clientIdRead0, clockRead0, + clientIdRead1, clockWrite, keyRead, + clientIdRead2, clientIdRead3, + clockRead1, replicasWrite1, + clientsRead, clientsWrite4, + outsideWrite, clientsWrite5, + outsideWrite0, clockWrite0, + replicasWrite2, clientsWrite6, + outsideWrite1, spinRead, clockWrite1, + replicasWrite3, clientsWrite7, + outsideWrite2, clientIdRead4, + clockRead2, clientIdRead5, + clockRead3, clientIdRead6, + clockWrite2, keyRead0, valueRead, + clientIdRead7, clientIdRead8, + clockRead4, replicasWrite4, + replicasWrite5, clientsRead0, + clientsWrite8, clientsWrite9, + clientsWrite10, outsideWrite3, + clockWrite3, replicasWrite6, + clientsWrite11, outsideWrite4, + spinRead0, clockWrite4, + replicasWrite7, clientsWrite12, + outsideWrite5, clientIdRead9, + clientIdRead10, clockWrite5, + replicasWrite8, replicasWrite9, + clientIdRead11, clockRead5, + clientIdRead12, clockRead6, + clientIdRead13, clockWrite6, + clientIdRead14, clientIdRead15, + clockRead7, replicasWrite10, + replicasWrite11, clockWrite7, + replicasWrite12, spinRead1, + clockWrite8, replicasWrite13, + kvLocal, liveClients, + pendingRequests, stableMessages, i_, + firstPending, timestamp, nextClient, + lowestPending, chooseMessage, + currentClocks, minClock, continue_, + pendingClients, clientsIter, msg_, + ok, spinLocal, continue_G, getReq, + getResp, spinLocal0, continue_P, i, + j_, putReq, putResp, msg_D, j_D, + spinLocal1, continue, j, msg >> + +respondStablePut(self) == /\ pc[self] = "respondStablePut" + /\ IF ((msg_[self]).op) = (PUT_MSG) + THEN /\ key' = [key EXCEPT ![self] = (msg_[self]).key] + /\ val' = [val EXCEPT ![self] = (msg_[self]).value] + /\ kvWrite' = [kvLocal[self] EXCEPT ![key'[self]] = val'[self]] + /\ (Len(clientMailboxes[(msg_[self]).reply_to])) < (BUFFER_SIZE) + /\ clientsWrite' = [clientMailboxes EXCEPT ![(msg_[self]).reply_to] = Append(clientMailboxes[(msg_[self]).reply_to], [type |-> PUT_RESPONSE, result |-> ok[self]])] + /\ kvWrite0' = kvWrite' + /\ clientsWrite1' = clientsWrite' + /\ clientMailboxes' = clientsWrite1' + /\ kvLocal' = [kvLocal EXCEPT ![self] = kvWrite0'] + /\ pc' = [pc EXCEPT ![self] = "respondPendingRequestsLoop"] + ELSE /\ kvWrite0' = kvLocal[self] + /\ clientsWrite1' = clientMailboxes + /\ clientMailboxes' = clientsWrite1' + /\ kvLocal' = [kvLocal EXCEPT ![self] = kvWrite0'] + /\ pc' = [pc EXCEPT ![self] = "respondPendingRequestsLoop"] + /\ UNCHANGED << clientsWrite, kvWrite, + key, val >> + /\ UNCHANGED << replicasNetwork, allClients, cid, + out, clocks, replicasRead, + replicasWrite, kvRead, clientsWrite0, + clientsWrite2, kvWrite1, + replicasWrite0, clientsWrite3, + kvWrite2, clientIdRead, clockRead, + clientIdRead0, clockRead0, + clientIdRead1, clockWrite, keyRead, + clientIdRead2, clientIdRead3, + clockRead1, replicasWrite1, + clientsRead, clientsWrite4, + outsideWrite, clientsWrite5, + outsideWrite0, clockWrite0, + replicasWrite2, clientsWrite6, + outsideWrite1, spinRead, clockWrite1, + replicasWrite3, clientsWrite7, + outsideWrite2, clientIdRead4, + clockRead2, clientIdRead5, + clockRead3, clientIdRead6, + clockWrite2, keyRead0, valueRead, + clientIdRead7, clientIdRead8, + clockRead4, replicasWrite4, + replicasWrite5, clientsRead0, + clientsWrite8, clientsWrite9, + clientsWrite10, outsideWrite3, + clockWrite3, replicasWrite6, + clientsWrite11, outsideWrite4, + spinRead0, clockWrite4, + replicasWrite7, clientsWrite12, + outsideWrite5, clientIdRead9, + clientIdRead10, clockWrite5, + replicasWrite8, replicasWrite9, + clientIdRead11, clockRead5, + clientIdRead12, clockRead6, + clientIdRead13, clockWrite6, + clientIdRead14, clientIdRead15, + clockRead7, replicasWrite10, + replicasWrite11, clockWrite7, + replicasWrite12, spinRead1, + clockWrite8, replicasWrite13, + liveClients, pendingRequests, + stableMessages, i_, firstPending, + timestamp, nextClient, lowestPending, + chooseMessage, currentClocks, + minClock, continue_, pendingClients, + clientsIter, msg_, ok, spinLocal, + continue_G, getReq, getResp, + spinLocal0, continue_P, i, j_, + putReq, putResp, msg_D, j_D, + spinLocal1, continue, j, msg >> + +Replica(self) == replicaLoop(self) \/ receiveClientRequest(self) + \/ clientDisconnected(self) \/ replicaGetRequest(self) + \/ replicaPutRequest(self) \/ replicaNullRequest(self) + \/ findStableRequestsLoop(self) \/ findMinClock(self) + \/ findMinClient(self) \/ addStableMessage(self) + \/ respondPendingRequestsLoop(self) + \/ respondStableGet(self) \/ respondStablePut(self) + +getLoop(self) == /\ pc[self] = "getLoop" + /\ IF continue_G[self] + THEN /\ pc' = [pc EXCEPT ![self] = "getRequest"] + /\ UNCHANGED << replicasNetwork, clientMailboxes, + out, clocks, clockWrite1, + replicasWrite3, clientsWrite7, + outsideWrite2 >> + ELSE /\ clockWrite1' = clocks + /\ replicasWrite3' = replicasNetwork + /\ clientsWrite7' = clientMailboxes + /\ outsideWrite2' = out + /\ replicasNetwork' = replicasWrite3' + /\ clientMailboxes' = clientsWrite7' + /\ clocks' = clockWrite1' + /\ out' = outsideWrite2' + /\ pc' = [pc EXCEPT ![self] = "Done"] + /\ UNCHANGED << allClients, cid, replicasRead, replicasWrite, + kvRead, clientsWrite, clientsWrite0, kvWrite, + kvWrite0, clientsWrite1, clientsWrite2, + kvWrite1, replicasWrite0, clientsWrite3, + kvWrite2, clientIdRead, clockRead, + clientIdRead0, clockRead0, clientIdRead1, + clockWrite, keyRead, clientIdRead2, + clientIdRead3, clockRead1, replicasWrite1, + clientsRead, clientsWrite4, outsideWrite, + clientsWrite5, outsideWrite0, clockWrite0, + replicasWrite2, clientsWrite6, outsideWrite1, + spinRead, clientIdRead4, clockRead2, + clientIdRead5, clockRead3, clientIdRead6, + clockWrite2, keyRead0, valueRead, + clientIdRead7, clientIdRead8, clockRead4, + replicasWrite4, replicasWrite5, clientsRead0, + clientsWrite8, clientsWrite9, clientsWrite10, + outsideWrite3, clockWrite3, replicasWrite6, + clientsWrite11, outsideWrite4, spinRead0, + clockWrite4, replicasWrite7, clientsWrite12, + outsideWrite5, clientIdRead9, clientIdRead10, + clockWrite5, replicasWrite8, replicasWrite9, + clientIdRead11, clockRead5, clientIdRead12, + clockRead6, clientIdRead13, clockWrite6, + clientIdRead14, clientIdRead15, clockRead7, + replicasWrite10, replicasWrite11, clockWrite7, + replicasWrite12, spinRead1, clockWrite8, + replicasWrite13, kvLocal, liveClients, + pendingRequests, stableMessages, i_, + firstPending, timestamp, nextClient, + lowestPending, chooseMessage, currentClocks, + minClock, continue_, pendingClients, + clientsIter, msg_, ok, key, val, spinLocal, + continue_G, getReq, getResp, spinLocal0, + continue_P, i, j_, putReq, putResp, msg_D, + j_D, spinLocal1, continue, j, msg >> + +getRequest(self) == /\ pc[self] = "getRequest" + /\ clientIdRead' = (self) - ((NUM_CLIENTS) * (GET_ORDER)) + /\ clockRead' = clocks[clientIdRead'] + /\ IF (clockRead') = (-(1)) + THEN /\ continue_G' = [continue_G EXCEPT ![self] = FALSE] + /\ clockWrite0' = clocks + /\ replicasWrite2' = replicasNetwork + /\ clientsWrite6' = clientMailboxes + /\ outsideWrite1' = out + /\ replicasNetwork' = replicasWrite2' + /\ clientMailboxes' = clientsWrite6' + /\ clocks' = clockWrite0' + /\ out' = outsideWrite1' + /\ pc' = [pc EXCEPT ![self] = "getCheckSpin"] + /\ UNCHANGED << clientIdRead0, clockRead0, + clientIdRead1, clockWrite, + keyRead, clientIdRead2, + clientIdRead3, clockRead1, + replicasWrite1, getReq >> + ELSE /\ clientIdRead0' = (self) - ((NUM_CLIENTS) * (GET_ORDER)) + /\ clockRead0' = clocks[clientIdRead0'] + /\ clientIdRead1' = (self) - ((NUM_CLIENTS) * (GET_ORDER)) + /\ clockWrite' = [clocks EXCEPT ![clientIdRead1'] = (clockRead0') + (1)] + /\ keyRead' = GET_KEY + /\ clientIdRead2' = (self) - ((NUM_CLIENTS) * (GET_ORDER)) + /\ clientIdRead3' = (self) - ((NUM_CLIENTS) * (GET_ORDER)) + /\ clockRead1' = clockWrite'[clientIdRead3'] + /\ getReq' = [getReq EXCEPT ![self] = [op |-> GET_MSG, key |-> keyRead', client |-> clientIdRead2', timestamp |-> clockRead1', reply_to |-> self]] + /\ \E dst \in ReplicaSet: + /\ (Len(replicasNetwork[dst])) < (BUFFER_SIZE) + /\ replicasWrite1' = [replicasNetwork EXCEPT ![dst] = Append(replicasNetwork[dst], getReq'[self])] + /\ replicasNetwork' = replicasWrite1' + /\ clocks' = clockWrite' + /\ pc' = [pc EXCEPT ![self] = "getReply"] + /\ UNCHANGED << clientMailboxes, out, + clockWrite0, replicasWrite2, + clientsWrite6, outsideWrite1, + continue_G >> + /\ UNCHANGED << allClients, cid, replicasRead, + replicasWrite, kvRead, clientsWrite, + clientsWrite0, kvWrite, kvWrite0, + clientsWrite1, clientsWrite2, kvWrite1, + replicasWrite0, clientsWrite3, kvWrite2, + clientsRead, clientsWrite4, outsideWrite, + clientsWrite5, outsideWrite0, spinRead, + clockWrite1, replicasWrite3, clientsWrite7, + outsideWrite2, clientIdRead4, clockRead2, + clientIdRead5, clockRead3, clientIdRead6, + clockWrite2, keyRead0, valueRead, + clientIdRead7, clientIdRead8, clockRead4, + replicasWrite4, replicasWrite5, + clientsRead0, clientsWrite8, clientsWrite9, + clientsWrite10, outsideWrite3, clockWrite3, + replicasWrite6, clientsWrite11, + outsideWrite4, spinRead0, clockWrite4, + replicasWrite7, clientsWrite12, + outsideWrite5, clientIdRead9, + clientIdRead10, clockWrite5, + replicasWrite8, replicasWrite9, + clientIdRead11, clockRead5, clientIdRead12, + clockRead6, clientIdRead13, clockWrite6, + clientIdRead14, clientIdRead15, clockRead7, + replicasWrite10, replicasWrite11, + clockWrite7, replicasWrite12, spinRead1, + clockWrite8, replicasWrite13, kvLocal, + liveClients, pendingRequests, + stableMessages, i_, firstPending, + timestamp, nextClient, lowestPending, + chooseMessage, currentClocks, minClock, + continue_, pendingClients, clientsIter, + msg_, ok, key, val, spinLocal, getResp, + spinLocal0, continue_P, i, j_, putReq, + putResp, msg_D, j_D, spinLocal1, continue, + j, msg >> + +getReply(self) == /\ pc[self] = "getReply" + /\ clientIdRead' = (self) - ((NUM_CLIENTS) * (GET_ORDER)) + /\ clockRead' = clocks[clientIdRead'] + /\ IF (clockRead') = (-(1)) + THEN /\ continue_G' = [continue_G EXCEPT ![self] = FALSE] + /\ clientsWrite5' = clientMailboxes + /\ outsideWrite0' = out + /\ clientMailboxes' = clientsWrite5' + /\ out' = outsideWrite0' + /\ UNCHANGED << clientsRead, clientsWrite4, + outsideWrite, getResp >> + ELSE /\ (Len(clientMailboxes[self])) > (0) + /\ LET msg1 == Head(clientMailboxes[self]) IN + /\ clientsWrite4' = [clientMailboxes EXCEPT ![self] = Tail(clientMailboxes[self])] + /\ clientsRead' = msg1 + /\ getResp' = [getResp EXCEPT ![self] = clientsRead'] + /\ Assert(((getResp'[self]).type) = (GET_RESPONSE), + "Failure of assertion at line 857, column 33.") + /\ outsideWrite' = (getResp'[self]).result + /\ clientsWrite5' = clientsWrite4' + /\ outsideWrite0' = outsideWrite' + /\ clientMailboxes' = clientsWrite5' + /\ out' = outsideWrite0' + /\ UNCHANGED continue_G + /\ pc' = [pc EXCEPT ![self] = "getCheckSpin"] + /\ UNCHANGED << replicasNetwork, allClients, cid, clocks, + replicasRead, replicasWrite, kvRead, + clientsWrite, clientsWrite0, kvWrite, + kvWrite0, clientsWrite1, clientsWrite2, + kvWrite1, replicasWrite0, clientsWrite3, + kvWrite2, clientIdRead0, clockRead0, + clientIdRead1, clockWrite, keyRead, + clientIdRead2, clientIdRead3, clockRead1, + replicasWrite1, clockWrite0, replicasWrite2, + clientsWrite6, outsideWrite1, spinRead, + clockWrite1, replicasWrite3, clientsWrite7, + outsideWrite2, clientIdRead4, clockRead2, + clientIdRead5, clockRead3, clientIdRead6, + clockWrite2, keyRead0, valueRead, + clientIdRead7, clientIdRead8, clockRead4, + replicasWrite4, replicasWrite5, clientsRead0, + clientsWrite8, clientsWrite9, clientsWrite10, + outsideWrite3, clockWrite3, replicasWrite6, + clientsWrite11, outsideWrite4, spinRead0, + clockWrite4, replicasWrite7, clientsWrite12, + outsideWrite5, clientIdRead9, clientIdRead10, + clockWrite5, replicasWrite8, replicasWrite9, + clientIdRead11, clockRead5, clientIdRead12, + clockRead6, clientIdRead13, clockWrite6, + clientIdRead14, clientIdRead15, clockRead7, + replicasWrite10, replicasWrite11, + clockWrite7, replicasWrite12, spinRead1, + clockWrite8, replicasWrite13, kvLocal, + liveClients, pendingRequests, stableMessages, + i_, firstPending, timestamp, nextClient, + lowestPending, chooseMessage, currentClocks, + minClock, continue_, pendingClients, + clientsIter, msg_, ok, key, val, spinLocal, + getReq, spinLocal0, continue_P, i, j_, + putReq, putResp, msg_D, j_D, spinLocal1, + continue, j, msg >> + +getCheckSpin(self) == /\ pc[self] = "getCheckSpin" + /\ spinRead' = spinLocal[self] + /\ IF ~(spinRead') + THEN /\ continue_G' = [continue_G EXCEPT ![self] = FALSE] + /\ pc' = [pc EXCEPT ![self] = "getLoop"] + ELSE /\ pc' = [pc EXCEPT ![self] = "getLoop"] + /\ UNCHANGED continue_G + /\ UNCHANGED << replicasNetwork, allClients, + clientMailboxes, cid, out, clocks, + replicasRead, replicasWrite, kvRead, + clientsWrite, clientsWrite0, kvWrite, + kvWrite0, clientsWrite1, clientsWrite2, + kvWrite1, replicasWrite0, clientsWrite3, + kvWrite2, clientIdRead, clockRead, + clientIdRead0, clockRead0, clientIdRead1, + clockWrite, keyRead, clientIdRead2, + clientIdRead3, clockRead1, + replicasWrite1, clientsRead, + clientsWrite4, outsideWrite, + clientsWrite5, outsideWrite0, + clockWrite0, replicasWrite2, + clientsWrite6, outsideWrite1, + clockWrite1, replicasWrite3, + clientsWrite7, outsideWrite2, + clientIdRead4, clockRead2, clientIdRead5, + clockRead3, clientIdRead6, clockWrite2, + keyRead0, valueRead, clientIdRead7, + clientIdRead8, clockRead4, + replicasWrite4, replicasWrite5, + clientsRead0, clientsWrite8, + clientsWrite9, clientsWrite10, + outsideWrite3, clockWrite3, + replicasWrite6, clientsWrite11, + outsideWrite4, spinRead0, clockWrite4, + replicasWrite7, clientsWrite12, + outsideWrite5, clientIdRead9, + clientIdRead10, clockWrite5, + replicasWrite8, replicasWrite9, + clientIdRead11, clockRead5, + clientIdRead12, clockRead6, + clientIdRead13, clockWrite6, + clientIdRead14, clientIdRead15, + clockRead7, replicasWrite10, + replicasWrite11, clockWrite7, + replicasWrite12, spinRead1, clockWrite8, + replicasWrite13, kvLocal, liveClients, + pendingRequests, stableMessages, i_, + firstPending, timestamp, nextClient, + lowestPending, chooseMessage, + currentClocks, minClock, continue_, + pendingClients, clientsIter, msg_, ok, + key, val, spinLocal, getReq, getResp, + spinLocal0, continue_P, i, j_, putReq, + putResp, msg_D, j_D, spinLocal1, + continue, j, msg >> + +GetClient(self) == getLoop(self) \/ getRequest(self) \/ getReply(self) + \/ getCheckSpin(self) + +putLoop(self) == /\ pc[self] = "putLoop" + /\ IF continue_P[self] + THEN /\ pc' = [pc EXCEPT ![self] = "putRequest"] + /\ UNCHANGED << replicasNetwork, clientMailboxes, + out, clocks, clockWrite4, + replicasWrite7, clientsWrite12, + outsideWrite5 >> + ELSE /\ clockWrite4' = clocks + /\ replicasWrite7' = replicasNetwork + /\ clientsWrite12' = clientMailboxes + /\ outsideWrite5' = out + /\ replicasNetwork' = replicasWrite7' + /\ clientMailboxes' = clientsWrite12' + /\ clocks' = clockWrite4' + /\ out' = outsideWrite5' + /\ pc' = [pc EXCEPT ![self] = "Done"] + /\ UNCHANGED << allClients, cid, replicasRead, replicasWrite, + kvRead, clientsWrite, clientsWrite0, kvWrite, + kvWrite0, clientsWrite1, clientsWrite2, + kvWrite1, replicasWrite0, clientsWrite3, + kvWrite2, clientIdRead, clockRead, + clientIdRead0, clockRead0, clientIdRead1, + clockWrite, keyRead, clientIdRead2, + clientIdRead3, clockRead1, replicasWrite1, + clientsRead, clientsWrite4, outsideWrite, + clientsWrite5, outsideWrite0, clockWrite0, + replicasWrite2, clientsWrite6, outsideWrite1, + spinRead, clockWrite1, replicasWrite3, + clientsWrite7, outsideWrite2, clientIdRead4, + clockRead2, clientIdRead5, clockRead3, + clientIdRead6, clockWrite2, keyRead0, + valueRead, clientIdRead7, clientIdRead8, + clockRead4, replicasWrite4, replicasWrite5, + clientsRead0, clientsWrite8, clientsWrite9, + clientsWrite10, outsideWrite3, clockWrite3, + replicasWrite6, clientsWrite11, outsideWrite4, + spinRead0, clientIdRead9, clientIdRead10, + clockWrite5, replicasWrite8, replicasWrite9, + clientIdRead11, clockRead5, clientIdRead12, + clockRead6, clientIdRead13, clockWrite6, + clientIdRead14, clientIdRead15, clockRead7, + replicasWrite10, replicasWrite11, clockWrite7, + replicasWrite12, spinRead1, clockWrite8, + replicasWrite13, kvLocal, liveClients, + pendingRequests, stableMessages, i_, + firstPending, timestamp, nextClient, + lowestPending, chooseMessage, currentClocks, + minClock, continue_, pendingClients, + clientsIter, msg_, ok, key, val, spinLocal, + continue_G, getReq, getResp, spinLocal0, + continue_P, i, j_, putReq, putResp, msg_D, + j_D, spinLocal1, continue, j, msg >> + +putRequest(self) == /\ pc[self] = "putRequest" + /\ clientIdRead4' = (self) - ((NUM_CLIENTS) * (PUT_ORDER)) + /\ clockRead2' = clocks[clientIdRead4'] + /\ IF (clockRead2') = (-(1)) + THEN /\ continue_P' = [continue_P EXCEPT ![self] = FALSE] + /\ clockWrite3' = clocks + /\ replicasWrite6' = replicasNetwork + /\ clientsWrite11' = clientMailboxes + /\ outsideWrite4' = out + /\ replicasNetwork' = replicasWrite6' + /\ clientMailboxes' = clientsWrite11' + /\ clocks' = clockWrite3' + /\ out' = outsideWrite4' + /\ pc' = [pc EXCEPT ![self] = "putCheckSpin"] + /\ UNCHANGED << clientIdRead5, clockRead3, + clientIdRead6, clockWrite2, + keyRead0, valueRead, + clientIdRead7, clientIdRead8, + clockRead4, i, j_, putReq >> + ELSE /\ clientIdRead5' = (self) - ((NUM_CLIENTS) * (PUT_ORDER)) + /\ clockRead3' = clocks[clientIdRead5'] + /\ clientIdRead6' = (self) - ((NUM_CLIENTS) * (PUT_ORDER)) + /\ clockWrite2' = [clocks EXCEPT ![clientIdRead6'] = (clockRead3') + (1)] + /\ keyRead0' = PUT_KEY + /\ valueRead' = PUT_VALUE + /\ clientIdRead7' = (self) - ((NUM_CLIENTS) * (PUT_ORDER)) + /\ clientIdRead8' = (self) - ((NUM_CLIENTS) * (PUT_ORDER)) + /\ clockRead4' = clockWrite2'[clientIdRead8'] + /\ putReq' = [putReq EXCEPT ![self] = [op |-> PUT_MSG, key |-> keyRead0', value |-> valueRead', client |-> clientIdRead7', timestamp |-> clockRead4', reply_to |-> self]] + /\ i' = [i EXCEPT ![self] = 0] + /\ j_' = [j_ EXCEPT ![self] = 0] + /\ clocks' = clockWrite2' + /\ pc' = [pc EXCEPT ![self] = "putBroadcast"] + /\ UNCHANGED << replicasNetwork, + clientMailboxes, out, + clockWrite3, replicasWrite6, + clientsWrite11, outsideWrite4, + continue_P >> + /\ UNCHANGED << allClients, cid, replicasRead, + replicasWrite, kvRead, clientsWrite, + clientsWrite0, kvWrite, kvWrite0, + clientsWrite1, clientsWrite2, kvWrite1, + replicasWrite0, clientsWrite3, kvWrite2, + clientIdRead, clockRead, clientIdRead0, + clockRead0, clientIdRead1, clockWrite, + keyRead, clientIdRead2, clientIdRead3, + clockRead1, replicasWrite1, clientsRead, + clientsWrite4, outsideWrite, clientsWrite5, + outsideWrite0, clockWrite0, replicasWrite2, + clientsWrite6, outsideWrite1, spinRead, + clockWrite1, replicasWrite3, clientsWrite7, + outsideWrite2, replicasWrite4, + replicasWrite5, clientsRead0, + clientsWrite8, clientsWrite9, + clientsWrite10, outsideWrite3, spinRead0, + clockWrite4, replicasWrite7, + clientsWrite12, outsideWrite5, + clientIdRead9, clientIdRead10, clockWrite5, + replicasWrite8, replicasWrite9, + clientIdRead11, clockRead5, clientIdRead12, + clockRead6, clientIdRead13, clockWrite6, + clientIdRead14, clientIdRead15, clockRead7, + replicasWrite10, replicasWrite11, + clockWrite7, replicasWrite12, spinRead1, + clockWrite8, replicasWrite13, kvLocal, + liveClients, pendingRequests, + stableMessages, i_, firstPending, + timestamp, nextClient, lowestPending, + chooseMessage, currentClocks, minClock, + continue_, pendingClients, clientsIter, + msg_, ok, key, val, spinLocal, continue_G, + getReq, getResp, spinLocal0, putResp, + msg_D, j_D, spinLocal1, continue, j, msg >> + +putBroadcast(self) == /\ pc[self] = "putBroadcast" + /\ clientIdRead4' = (self) - ((NUM_CLIENTS) * (PUT_ORDER)) + /\ clockRead2' = clocks[clientIdRead4'] + /\ IF ((j_[self]) <= ((NUM_REPLICAS) - (1))) /\ ((clockRead2') # (-(1))) + THEN /\ (Len(replicasNetwork[j_[self]])) < (BUFFER_SIZE) + /\ replicasWrite4' = [replicasNetwork EXCEPT ![j_[self]] = Append(replicasNetwork[j_[self]], putReq[self])] + /\ j_' = [j_ EXCEPT ![self] = (j_[self]) + (1)] + /\ replicasWrite5' = replicasWrite4' + /\ replicasNetwork' = replicasWrite5' + /\ pc' = [pc EXCEPT ![self] = "putBroadcast"] + ELSE /\ replicasWrite5' = replicasNetwork + /\ replicasNetwork' = replicasWrite5' + /\ pc' = [pc EXCEPT ![self] = "putResponse"] + /\ UNCHANGED << replicasWrite4, j_ >> + /\ UNCHANGED << allClients, clientMailboxes, cid, out, + clocks, replicasRead, replicasWrite, + kvRead, clientsWrite, clientsWrite0, + kvWrite, kvWrite0, clientsWrite1, + clientsWrite2, kvWrite1, replicasWrite0, + clientsWrite3, kvWrite2, clientIdRead, + clockRead, clientIdRead0, clockRead0, + clientIdRead1, clockWrite, keyRead, + clientIdRead2, clientIdRead3, clockRead1, + replicasWrite1, clientsRead, + clientsWrite4, outsideWrite, + clientsWrite5, outsideWrite0, + clockWrite0, replicasWrite2, + clientsWrite6, outsideWrite1, spinRead, + clockWrite1, replicasWrite3, + clientsWrite7, outsideWrite2, + clientIdRead5, clockRead3, clientIdRead6, + clockWrite2, keyRead0, valueRead, + clientIdRead7, clientIdRead8, clockRead4, + clientsRead0, clientsWrite8, + clientsWrite9, clientsWrite10, + outsideWrite3, clockWrite3, + replicasWrite6, clientsWrite11, + outsideWrite4, spinRead0, clockWrite4, + replicasWrite7, clientsWrite12, + outsideWrite5, clientIdRead9, + clientIdRead10, clockWrite5, + replicasWrite8, replicasWrite9, + clientIdRead11, clockRead5, + clientIdRead12, clockRead6, + clientIdRead13, clockWrite6, + clientIdRead14, clientIdRead15, + clockRead7, replicasWrite10, + replicasWrite11, clockWrite7, + replicasWrite12, spinRead1, clockWrite8, + replicasWrite13, kvLocal, liveClients, + pendingRequests, stableMessages, i_, + firstPending, timestamp, nextClient, + lowestPending, chooseMessage, + currentClocks, minClock, continue_, + pendingClients, clientsIter, msg_, ok, + key, val, spinLocal, continue_G, getReq, + getResp, spinLocal0, continue_P, i, + putReq, putResp, msg_D, j_D, spinLocal1, + continue, j, msg >> + +putResponse(self) == /\ pc[self] = "putResponse" + /\ IF (i[self]) < (Cardinality(ReplicaSet)) + THEN /\ clientIdRead4' = (self) - ((NUM_CLIENTS) * (PUT_ORDER)) + /\ clockRead2' = clocks[clientIdRead4'] + /\ IF (clockRead2') = (-(1)) + THEN /\ continue_P' = [continue_P EXCEPT ![self] = FALSE] + /\ clientsWrite9' = clientMailboxes + /\ clientsWrite10' = clientsWrite9' + /\ clientMailboxes' = clientsWrite10' + /\ pc' = [pc EXCEPT ![self] = "putLoop"] + /\ UNCHANGED << clientsRead0, + clientsWrite8, i, + putResp >> + ELSE /\ (Len(clientMailboxes[self])) > (0) + /\ LET msg2 == Head(clientMailboxes[self]) IN + /\ clientsWrite8' = [clientMailboxes EXCEPT ![self] = Tail(clientMailboxes[self])] + /\ clientsRead0' = msg2 + /\ putResp' = [putResp EXCEPT ![self] = clientsRead0'] + /\ Assert(((putResp'[self]).type) = (PUT_RESPONSE), + "Failure of assertion at line 952, column 37.") + /\ i' = [i EXCEPT ![self] = (i[self]) + (1)] + /\ clientsWrite9' = clientsWrite8' + /\ clientsWrite10' = clientsWrite9' + /\ clientMailboxes' = clientsWrite10' + /\ pc' = [pc EXCEPT ![self] = "putResponse"] + /\ UNCHANGED continue_P + ELSE /\ clientsWrite10' = clientMailboxes + /\ clientMailboxes' = clientsWrite10' + /\ pc' = [pc EXCEPT ![self] = "putComplete"] + /\ UNCHANGED << clientIdRead4, clockRead2, + clientsRead0, clientsWrite8, + clientsWrite9, continue_P, i, + putResp >> + /\ UNCHANGED << replicasNetwork, allClients, cid, out, + clocks, replicasRead, replicasWrite, + kvRead, clientsWrite, clientsWrite0, + kvWrite, kvWrite0, clientsWrite1, + clientsWrite2, kvWrite1, replicasWrite0, + clientsWrite3, kvWrite2, clientIdRead, + clockRead, clientIdRead0, clockRead0, + clientIdRead1, clockWrite, keyRead, + clientIdRead2, clientIdRead3, clockRead1, + replicasWrite1, clientsRead, + clientsWrite4, outsideWrite, + clientsWrite5, outsideWrite0, clockWrite0, + replicasWrite2, clientsWrite6, + outsideWrite1, spinRead, clockWrite1, + replicasWrite3, clientsWrite7, + outsideWrite2, clientIdRead5, clockRead3, + clientIdRead6, clockWrite2, keyRead0, + valueRead, clientIdRead7, clientIdRead8, + clockRead4, replicasWrite4, + replicasWrite5, outsideWrite3, + clockWrite3, replicasWrite6, + clientsWrite11, outsideWrite4, spinRead0, + clockWrite4, replicasWrite7, + clientsWrite12, outsideWrite5, + clientIdRead9, clientIdRead10, + clockWrite5, replicasWrite8, + replicasWrite9, clientIdRead11, + clockRead5, clientIdRead12, clockRead6, + clientIdRead13, clockWrite6, + clientIdRead14, clientIdRead15, + clockRead7, replicasWrite10, + replicasWrite11, clockWrite7, + replicasWrite12, spinRead1, clockWrite8, + replicasWrite13, kvLocal, liveClients, + pendingRequests, stableMessages, i_, + firstPending, timestamp, nextClient, + lowestPending, chooseMessage, + currentClocks, minClock, continue_, + pendingClients, clientsIter, msg_, ok, + key, val, spinLocal, continue_G, getReq, + getResp, spinLocal0, j_, putReq, msg_D, + j_D, spinLocal1, continue, j, msg >> + +putComplete(self) == /\ pc[self] = "putComplete" + /\ outsideWrite3' = PUT_RESPONSE + /\ out' = outsideWrite3' + /\ pc' = [pc EXCEPT ![self] = "putCheckSpin"] + /\ UNCHANGED << replicasNetwork, allClients, + clientMailboxes, cid, clocks, + replicasRead, replicasWrite, kvRead, + clientsWrite, clientsWrite0, kvWrite, + kvWrite0, clientsWrite1, clientsWrite2, + kvWrite1, replicasWrite0, clientsWrite3, + kvWrite2, clientIdRead, clockRead, + clientIdRead0, clockRead0, clientIdRead1, + clockWrite, keyRead, clientIdRead2, + clientIdRead3, clockRead1, replicasWrite1, + clientsRead, clientsWrite4, outsideWrite, + clientsWrite5, outsideWrite0, clockWrite0, + replicasWrite2, clientsWrite6, + outsideWrite1, spinRead, clockWrite1, + replicasWrite3, clientsWrite7, + outsideWrite2, clientIdRead4, clockRead2, + clientIdRead5, clockRead3, clientIdRead6, + clockWrite2, keyRead0, valueRead, + clientIdRead7, clientIdRead8, clockRead4, + replicasWrite4, replicasWrite5, + clientsRead0, clientsWrite8, + clientsWrite9, clientsWrite10, + clockWrite3, replicasWrite6, + clientsWrite11, outsideWrite4, spinRead0, + clockWrite4, replicasWrite7, + clientsWrite12, outsideWrite5, + clientIdRead9, clientIdRead10, + clockWrite5, replicasWrite8, + replicasWrite9, clientIdRead11, + clockRead5, clientIdRead12, clockRead6, + clientIdRead13, clockWrite6, + clientIdRead14, clientIdRead15, + clockRead7, replicasWrite10, + replicasWrite11, clockWrite7, + replicasWrite12, spinRead1, clockWrite8, + replicasWrite13, kvLocal, liveClients, + pendingRequests, stableMessages, i_, + firstPending, timestamp, nextClient, + lowestPending, chooseMessage, + currentClocks, minClock, continue_, + pendingClients, clientsIter, msg_, ok, + key, val, spinLocal, continue_G, getReq, + getResp, spinLocal0, continue_P, i, j_, + putReq, putResp, msg_D, j_D, spinLocal1, + continue, j, msg >> + +putCheckSpin(self) == /\ pc[self] = "putCheckSpin" + /\ spinRead0' = spinLocal0[self] + /\ IF ~(spinRead0') + THEN /\ continue_P' = [continue_P EXCEPT ![self] = FALSE] + /\ pc' = [pc EXCEPT ![self] = "putLoop"] + ELSE /\ pc' = [pc EXCEPT ![self] = "putLoop"] + /\ UNCHANGED continue_P + /\ UNCHANGED << replicasNetwork, allClients, + clientMailboxes, cid, out, clocks, + replicasRead, replicasWrite, kvRead, + clientsWrite, clientsWrite0, kvWrite, + kvWrite0, clientsWrite1, clientsWrite2, + kvWrite1, replicasWrite0, clientsWrite3, + kvWrite2, clientIdRead, clockRead, + clientIdRead0, clockRead0, clientIdRead1, + clockWrite, keyRead, clientIdRead2, + clientIdRead3, clockRead1, + replicasWrite1, clientsRead, + clientsWrite4, outsideWrite, + clientsWrite5, outsideWrite0, + clockWrite0, replicasWrite2, + clientsWrite6, outsideWrite1, spinRead, + clockWrite1, replicasWrite3, + clientsWrite7, outsideWrite2, + clientIdRead4, clockRead2, clientIdRead5, + clockRead3, clientIdRead6, clockWrite2, + keyRead0, valueRead, clientIdRead7, + clientIdRead8, clockRead4, + replicasWrite4, replicasWrite5, + clientsRead0, clientsWrite8, + clientsWrite9, clientsWrite10, + outsideWrite3, clockWrite3, + replicasWrite6, clientsWrite11, + outsideWrite4, clockWrite4, + replicasWrite7, clientsWrite12, + outsideWrite5, clientIdRead9, + clientIdRead10, clockWrite5, + replicasWrite8, replicasWrite9, + clientIdRead11, clockRead5, + clientIdRead12, clockRead6, + clientIdRead13, clockWrite6, + clientIdRead14, clientIdRead15, + clockRead7, replicasWrite10, + replicasWrite11, clockWrite7, + replicasWrite12, spinRead1, clockWrite8, + replicasWrite13, kvLocal, liveClients, + pendingRequests, stableMessages, i_, + firstPending, timestamp, nextClient, + lowestPending, chooseMessage, + currentClocks, minClock, continue_, + pendingClients, clientsIter, msg_, ok, + key, val, spinLocal, continue_G, getReq, + getResp, spinLocal0, i, j_, putReq, + putResp, msg_D, j_D, spinLocal1, + continue, j, msg >> + +PutClient(self) == putLoop(self) \/ putRequest(self) \/ putBroadcast(self) + \/ putResponse(self) \/ putComplete(self) + \/ putCheckSpin(self) + +sendDisconnectRequest(self) == /\ pc[self] = "sendDisconnectRequest" + /\ clientIdRead9' = (self) - ((NUM_CLIENTS) * (DISCONNECT_ORDER)) + /\ msg_D' = [msg_D EXCEPT ![self] = [op |-> DISCONNECT_MSG, client |-> clientIdRead9']] + /\ clientIdRead10' = (self) - ((NUM_CLIENTS) * (DISCONNECT_ORDER)) + /\ clockWrite5' = [clocks EXCEPT ![clientIdRead10'] = -(1)] + /\ j_D' = [j_D EXCEPT ![self] = 0] + /\ clocks' = clockWrite5' + /\ pc' = [pc EXCEPT ![self] = "disconnectBroadcast"] + /\ UNCHANGED << replicasNetwork, allClients, + clientMailboxes, cid, out, + replicasRead, replicasWrite, + kvRead, clientsWrite, + clientsWrite0, kvWrite, + kvWrite0, clientsWrite1, + clientsWrite2, kvWrite1, + replicasWrite0, clientsWrite3, + kvWrite2, clientIdRead, + clockRead, clientIdRead0, + clockRead0, clientIdRead1, + clockWrite, keyRead, + clientIdRead2, clientIdRead3, + clockRead1, replicasWrite1, + clientsRead, clientsWrite4, + outsideWrite, clientsWrite5, + outsideWrite0, clockWrite0, + replicasWrite2, clientsWrite6, + outsideWrite1, spinRead, + clockWrite1, replicasWrite3, + clientsWrite7, outsideWrite2, + clientIdRead4, clockRead2, + clientIdRead5, clockRead3, + clientIdRead6, clockWrite2, + keyRead0, valueRead, + clientIdRead7, clientIdRead8, + clockRead4, replicasWrite4, + replicasWrite5, clientsRead0, + clientsWrite8, clientsWrite9, + clientsWrite10, outsideWrite3, + clockWrite3, replicasWrite6, + clientsWrite11, outsideWrite4, + spinRead0, clockWrite4, + replicasWrite7, clientsWrite12, + outsideWrite5, replicasWrite8, + replicasWrite9, clientIdRead11, + clockRead5, clientIdRead12, + clockRead6, clientIdRead13, + clockWrite6, clientIdRead14, + clientIdRead15, clockRead7, + replicasWrite10, + replicasWrite11, clockWrite7, + replicasWrite12, spinRead1, + clockWrite8, replicasWrite13, + kvLocal, liveClients, + pendingRequests, stableMessages, + i_, firstPending, timestamp, + nextClient, lowestPending, + chooseMessage, currentClocks, + minClock, continue_, + pendingClients, clientsIter, + msg_, ok, key, val, spinLocal, + continue_G, getReq, getResp, + spinLocal0, continue_P, i, j_, + putReq, putResp, spinLocal1, + continue, j, msg >> + +disconnectBroadcast(self) == /\ pc[self] = "disconnectBroadcast" + /\ IF ((j_D[self]) <= ((NUM_REPLICAS) - (1))) /\ ((0) # (-(1))) + THEN /\ (Len(replicasNetwork[j_D[self]])) < (BUFFER_SIZE) + /\ replicasWrite8' = [replicasNetwork EXCEPT ![j_D[self]] = Append(replicasNetwork[j_D[self]], msg_D[self])] + /\ j_D' = [j_D EXCEPT ![self] = (j_D[self]) + (1)] + /\ replicasWrite9' = replicasWrite8' + /\ replicasNetwork' = replicasWrite9' + /\ pc' = [pc EXCEPT ![self] = "disconnectBroadcast"] + ELSE /\ replicasWrite9' = replicasNetwork + /\ replicasNetwork' = replicasWrite9' + /\ pc' = [pc EXCEPT ![self] = "Done"] + /\ UNCHANGED << replicasWrite8, j_D >> + /\ UNCHANGED << allClients, clientMailboxes, cid, + out, clocks, replicasRead, + replicasWrite, kvRead, + clientsWrite, clientsWrite0, + kvWrite, kvWrite0, clientsWrite1, + clientsWrite2, kvWrite1, + replicasWrite0, clientsWrite3, + kvWrite2, clientIdRead, clockRead, + clientIdRead0, clockRead0, + clientIdRead1, clockWrite, + keyRead, clientIdRead2, + clientIdRead3, clockRead1, + replicasWrite1, clientsRead, + clientsWrite4, outsideWrite, + clientsWrite5, outsideWrite0, + clockWrite0, replicasWrite2, + clientsWrite6, outsideWrite1, + spinRead, clockWrite1, + replicasWrite3, clientsWrite7, + outsideWrite2, clientIdRead4, + clockRead2, clientIdRead5, + clockRead3, clientIdRead6, + clockWrite2, keyRead0, valueRead, + clientIdRead7, clientIdRead8, + clockRead4, replicasWrite4, + replicasWrite5, clientsRead0, + clientsWrite8, clientsWrite9, + clientsWrite10, outsideWrite3, + clockWrite3, replicasWrite6, + clientsWrite11, outsideWrite4, + spinRead0, clockWrite4, + replicasWrite7, clientsWrite12, + outsideWrite5, clientIdRead9, + clientIdRead10, clockWrite5, + clientIdRead11, clockRead5, + clientIdRead12, clockRead6, + clientIdRead13, clockWrite6, + clientIdRead14, clientIdRead15, + clockRead7, replicasWrite10, + replicasWrite11, clockWrite7, + replicasWrite12, spinRead1, + clockWrite8, replicasWrite13, + kvLocal, liveClients, + pendingRequests, stableMessages, + i_, firstPending, timestamp, + nextClient, lowestPending, + chooseMessage, currentClocks, + minClock, continue_, + pendingClients, clientsIter, msg_, + ok, key, val, spinLocal, + continue_G, getReq, getResp, + spinLocal0, continue_P, i, j_, + putReq, putResp, msg_D, + spinLocal1, continue, j, msg >> + +DisconnectClient(self) == sendDisconnectRequest(self) + \/ disconnectBroadcast(self) + +clockUpdateLoop(self) == /\ pc[self] = "clockUpdateLoop" + /\ IF continue[self] + THEN /\ clientIdRead11' = (self) - ((NUM_CLIENTS) * (NULL_ORDER)) + /\ clockRead5' = clocks[clientIdRead11'] + /\ IF (clockRead5') = (-(1)) + THEN /\ continue' = [continue EXCEPT ![self] = FALSE] + /\ clockWrite7' = clocks + /\ replicasWrite12' = replicasNetwork + /\ replicasNetwork' = replicasWrite12' + /\ clocks' = clockWrite7' + /\ pc' = [pc EXCEPT ![self] = "nullCheckSpin"] + /\ UNCHANGED << clientIdRead12, + clockRead6, + clientIdRead13, + clockWrite6, + clientIdRead14, + clientIdRead15, + clockRead7, j, + msg >> + ELSE /\ clientIdRead12' = (self) - ((NUM_CLIENTS) * (NULL_ORDER)) + /\ clockRead6' = clocks[clientIdRead12'] + /\ clientIdRead13' = (self) - ((NUM_CLIENTS) * (NULL_ORDER)) + /\ clockWrite6' = [clocks EXCEPT ![clientIdRead13'] = (clockRead6') + (1)] + /\ clientIdRead14' = (self) - ((NUM_CLIENTS) * (NULL_ORDER)) + /\ clientIdRead15' = (self) - ((NUM_CLIENTS) * (NULL_ORDER)) + /\ clockRead7' = clockWrite6'[clientIdRead15'] + /\ msg' = [msg EXCEPT ![self] = [op |-> NULL_MSG, client |-> clientIdRead14', timestamp |-> clockRead7']] + /\ j' = [j EXCEPT ![self] = 0] + /\ clocks' = clockWrite6' + /\ pc' = [pc EXCEPT ![self] = "nullBroadcast"] + /\ UNCHANGED << replicasNetwork, + clockWrite7, + replicasWrite12, + continue >> + /\ UNCHANGED << clockWrite8, + replicasWrite13 >> + ELSE /\ clockWrite8' = clocks + /\ replicasWrite13' = replicasNetwork + /\ replicasNetwork' = replicasWrite13' + /\ clocks' = clockWrite8' + /\ pc' = [pc EXCEPT ![self] = "Done"] + /\ UNCHANGED << clientIdRead11, clockRead5, + clientIdRead12, clockRead6, + clientIdRead13, + clockWrite6, + clientIdRead14, + clientIdRead15, clockRead7, + clockWrite7, + replicasWrite12, continue, + j, msg >> + /\ UNCHANGED << allClients, clientMailboxes, cid, out, + replicasRead, replicasWrite, kvRead, + clientsWrite, clientsWrite0, kvWrite, + kvWrite0, clientsWrite1, + clientsWrite2, kvWrite1, + replicasWrite0, clientsWrite3, + kvWrite2, clientIdRead, clockRead, + clientIdRead0, clockRead0, + clientIdRead1, clockWrite, keyRead, + clientIdRead2, clientIdRead3, + clockRead1, replicasWrite1, + clientsRead, clientsWrite4, + outsideWrite, clientsWrite5, + outsideWrite0, clockWrite0, + replicasWrite2, clientsWrite6, + outsideWrite1, spinRead, clockWrite1, + replicasWrite3, clientsWrite7, + outsideWrite2, clientIdRead4, + clockRead2, clientIdRead5, clockRead3, + clientIdRead6, clockWrite2, keyRead0, + valueRead, clientIdRead7, + clientIdRead8, clockRead4, + replicasWrite4, replicasWrite5, + clientsRead0, clientsWrite8, + clientsWrite9, clientsWrite10, + outsideWrite3, clockWrite3, + replicasWrite6, clientsWrite11, + outsideWrite4, spinRead0, clockWrite4, + replicasWrite7, clientsWrite12, + outsideWrite5, clientIdRead9, + clientIdRead10, clockWrite5, + replicasWrite8, replicasWrite9, + replicasWrite10, replicasWrite11, + spinRead1, kvLocal, liveClients, + pendingRequests, stableMessages, i_, + firstPending, timestamp, nextClient, + lowestPending, chooseMessage, + currentClocks, minClock, continue_, + pendingClients, clientsIter, msg_, ok, + key, val, spinLocal, continue_G, + getReq, getResp, spinLocal0, + continue_P, i, j_, putReq, putResp, + msg_D, j_D, spinLocal1 >> + +nullCheckSpin(self) == /\ pc[self] = "nullCheckSpin" + /\ spinRead1' = spinLocal1[self] + /\ IF ~(spinRead1') + THEN /\ continue' = [continue EXCEPT ![self] = FALSE] + /\ pc' = [pc EXCEPT ![self] = "clockUpdateLoop"] + ELSE /\ pc' = [pc EXCEPT ![self] = "clockUpdateLoop"] + /\ UNCHANGED continue + /\ UNCHANGED << replicasNetwork, allClients, + clientMailboxes, cid, out, clocks, + replicasRead, replicasWrite, kvRead, + clientsWrite, clientsWrite0, kvWrite, + kvWrite0, clientsWrite1, clientsWrite2, + kvWrite1, replicasWrite0, clientsWrite3, + kvWrite2, clientIdRead, clockRead, + clientIdRead0, clockRead0, + clientIdRead1, clockWrite, keyRead, + clientIdRead2, clientIdRead3, + clockRead1, replicasWrite1, clientsRead, + clientsWrite4, outsideWrite, + clientsWrite5, outsideWrite0, + clockWrite0, replicasWrite2, + clientsWrite6, outsideWrite1, spinRead, + clockWrite1, replicasWrite3, + clientsWrite7, outsideWrite2, + clientIdRead4, clockRead2, + clientIdRead5, clockRead3, + clientIdRead6, clockWrite2, keyRead0, + valueRead, clientIdRead7, clientIdRead8, + clockRead4, replicasWrite4, + replicasWrite5, clientsRead0, + clientsWrite8, clientsWrite9, + clientsWrite10, outsideWrite3, + clockWrite3, replicasWrite6, + clientsWrite11, outsideWrite4, + spinRead0, clockWrite4, replicasWrite7, + clientsWrite12, outsideWrite5, + clientIdRead9, clientIdRead10, + clockWrite5, replicasWrite8, + replicasWrite9, clientIdRead11, + clockRead5, clientIdRead12, clockRead6, + clientIdRead13, clockWrite6, + clientIdRead14, clientIdRead15, + clockRead7, replicasWrite10, + replicasWrite11, clockWrite7, + replicasWrite12, clockWrite8, + replicasWrite13, kvLocal, liveClients, + pendingRequests, stableMessages, i_, + firstPending, timestamp, nextClient, + lowestPending, chooseMessage, + currentClocks, minClock, continue_, + pendingClients, clientsIter, msg_, ok, + key, val, spinLocal, continue_G, getReq, + getResp, spinLocal0, continue_P, i, j_, + putReq, putResp, msg_D, j_D, spinLocal1, + j, msg >> + +nullBroadcast(self) == /\ pc[self] = "nullBroadcast" + /\ clientIdRead11' = (self) - ((NUM_CLIENTS) * (NULL_ORDER)) + /\ clockRead5' = clocks[clientIdRead11'] + /\ IF ((j[self]) <= ((NUM_REPLICAS) - (1))) /\ ((clockRead5') # (-(1))) + THEN /\ (Len(replicasNetwork[j[self]])) < (BUFFER_SIZE) + /\ replicasWrite10' = [replicasNetwork EXCEPT ![j[self]] = Append(replicasNetwork[j[self]], msg[self])] + /\ j' = [j EXCEPT ![self] = (j[self]) + (1)] + /\ replicasWrite11' = replicasWrite10' + /\ replicasNetwork' = replicasWrite11' + /\ pc' = [pc EXCEPT ![self] = "nullBroadcast"] + ELSE /\ replicasWrite11' = replicasNetwork + /\ replicasNetwork' = replicasWrite11' + /\ pc' = [pc EXCEPT ![self] = "nullCheckSpin"] + /\ UNCHANGED << replicasWrite10, j >> + /\ UNCHANGED << allClients, clientMailboxes, cid, out, + clocks, replicasRead, replicasWrite, + kvRead, clientsWrite, clientsWrite0, + kvWrite, kvWrite0, clientsWrite1, + clientsWrite2, kvWrite1, replicasWrite0, + clientsWrite3, kvWrite2, clientIdRead, + clockRead, clientIdRead0, clockRead0, + clientIdRead1, clockWrite, keyRead, + clientIdRead2, clientIdRead3, + clockRead1, replicasWrite1, clientsRead, + clientsWrite4, outsideWrite, + clientsWrite5, outsideWrite0, + clockWrite0, replicasWrite2, + clientsWrite6, outsideWrite1, spinRead, + clockWrite1, replicasWrite3, + clientsWrite7, outsideWrite2, + clientIdRead4, clockRead2, + clientIdRead5, clockRead3, + clientIdRead6, clockWrite2, keyRead0, + valueRead, clientIdRead7, clientIdRead8, + clockRead4, replicasWrite4, + replicasWrite5, clientsRead0, + clientsWrite8, clientsWrite9, + clientsWrite10, outsideWrite3, + clockWrite3, replicasWrite6, + clientsWrite11, outsideWrite4, + spinRead0, clockWrite4, replicasWrite7, + clientsWrite12, outsideWrite5, + clientIdRead9, clientIdRead10, + clockWrite5, replicasWrite8, + replicasWrite9, clientIdRead12, + clockRead6, clientIdRead13, clockWrite6, + clientIdRead14, clientIdRead15, + clockRead7, clockWrite7, + replicasWrite12, spinRead1, clockWrite8, + replicasWrite13, kvLocal, liveClients, + pendingRequests, stableMessages, i_, + firstPending, timestamp, nextClient, + lowestPending, chooseMessage, + currentClocks, minClock, continue_, + pendingClients, clientsIter, msg_, ok, + key, val, spinLocal, continue_G, getReq, + getResp, spinLocal0, continue_P, i, j_, + putReq, putResp, msg_D, j_D, spinLocal1, + continue, msg >> + +ClockUpdateClient(self) == clockUpdateLoop(self) \/ nullCheckSpin(self) + \/ nullBroadcast(self) + +(* Allow infinite stuttering to prevent deadlock on termination. *) +Terminating == /\ \A self \in ProcSet: pc[self] = "Done" + /\ UNCHANGED vars + +Next == (\E self \in ReplicaSet: Replica(self)) + \/ (\E self \in GetSet: GetClient(self)) + \/ (\E self \in PutSet: PutClient(self)) + \/ (\E self \in DisconnectSet: DisconnectClient(self)) + \/ (\E self \in NullSet: ClockUpdateClient(self)) + \/ Terminating + +Spec == /\ Init /\ [][Next]_vars + /\ \A self \in ReplicaSet : WF_vars(Replica(self)) + /\ \A self \in GetSet : WF_vars(GetClient(self)) + /\ \A self \in PutSet : WF_vars(PutClient(self)) + /\ \A self \in DisconnectSet : WF_vars(DisconnectClient(self)) + /\ \A self \in NullSet : WF_vars(ClockUpdateClient(self)) + +Termination == <>(\A self \in ProcSet: pc[self] = "Done") + +\* END TRANSLATION - the hash of the generated TLA code (remove to silence divergence warnings): TLA-bac0bd5a9581fcaaf62a0704717e8973 + +\* This predicate is true when all client processes are finished. +AllClientsDisconnected == \A client \in allClients : pc[client] = "Done" + + +\* Invariants +\* ********** + +\* These ensure that, in all states explored by TLC, the buffers (from client to replica and vice versa) +\* are within bounds. Using the FIFOChannel mapping macro is sufficient for this invariant to +\* hold. +BufferOk(net, node) == Len(net[node]) >= 0 /\ Len(net[node]) <= BUFFER_SIZE +ClientBuffersOk == \A node \in DOMAIN clientMailboxes : BufferOk(clientMailboxes, node) +ReplicaBuffersOk == \A node \in DOMAIN replicasNetwork : BufferOk(replicasNetwork, node) +AllBuffersOk == ClientBuffersOk /\ ReplicaBuffersOk + +\* This invariant tests that message stability detection in the replica is safe: +\* every message considered stable must have a timestamp lower than the current logical +\* clock of any live client. +MessageStability == \A replica \in ReplicaSet : + LET stable == stableMessages[replica] + alive == { c \in ClientSet : clocks[c] > 0 } + IN + Len(stable) > 0 => + \A m_id \in DOMAIN stable : + \A client \in alive : stable[m_id].timestamp < clocks[client] + + +\* Put semantics: once a client has been notified that a Put request was succesful +\* every replica must have the updated value. +PersistentPut == \A client \in PutSet : + pc[client] = "putComplete" => \A replica \in ReplicaSet : kvLocal[replica][PUT_KEY] = PUT_VALUE + + +\* Properties +\* ********** + +\* Logical clocks are monotonically increasing. This property checks that in every state, +\* pending messages in the replicas have increasing timestamps (or the process disconnected) +ClockIncreased == clocks' /= clocks => + \E c \in ClientSet : clocks'[c] = clocks[c]+1 \/ clocks'[c] = -1 + +MonotonicallyIncreasingClocks == [][ClockIncreased]_<> + + +\* Safety of disconnection: once a client has disconnected (and sent a message to all replicas +\* informing of that event), then the logical clock of that client should remain +\* unchanced -- i.e., no more messages from that client should be seen in the system. +DisconnectionSafe == \A client \in ClientSet : <>[](clocks[client] = -1) + +============================================================================= +\* Modification History +\* Last modified Mon Dec 21 03:02:11 PST 2020 by finn +\* Last modified Thu Apr 11 09:46:33 PDT 2019 by rmc +\* Last modified Wed Feb 27 12:42:52 PST 2019 by minh From 7a4ac7809e293034f88ee22a19f1c02f765e3921 Mon Sep 17 00:00:00 2001 From: fhackett Date: Mon, 31 May 2021 19:45:41 -0700 Subject: [PATCH 08/27] WIP: testing infrastructure; needs archetype resource implementations --- distsys/archetypes.go | 270 ++++ .../pgo/distsys => distsys}/barrier.go | 0 .../runtime/pgo/distsys => distsys}/client.go | 0 .../pgo/distsys => distsys}/connections.go | 0 .../pgo/distsys => distsys}/data_store.go | 0 .../distsys => distsys}/data_store_test.go | 0 .../pgo/distsys => distsys}/distsys.go | 2 +- .../pgo/distsys => distsys}/distsys_test.go | 0 {src/runtime/pgo/distsys => distsys}/etcd.go | 0 distsys/go.mod | 11 + distsys/go.sum | 190 +++ distsys/mpcal.go | 86 ++ .../pgo/distsys => distsys}/processutil.go | 0 .../distsys => distsys}/processutil_test.go | 0 .../distsys => distsys}/state_ownership.go | 0 .../state_ownership_test.go | 0 .../pgo/distsys => distsys}/state_server.go | 0 distsys/tlaplus.go | 340 +++++ src/pgo/PGo.scala | 8 +- src/pgo/model/mpcal/AST.scala | 19 +- src/pgo/model/tla/AST.scala | 2 + src/pgo/parser/MPCalParser.scala | 16 +- src/pgo/parser/ParsingErrors.scala | 10 +- src/pgo/trans/MPCalGoCodegenPass.scala | 676 ++++++++- src/pgo/trans/MPCalPCalCodegenPass.scala | 29 +- src/pgo/trans/MPCalSemanticCheckPass.scala | 115 +- src/pgo/trans/PCalRenderPass.scala | 11 +- src/pgo/util/Description.scala | 59 +- src/pgo/util/MPCalPassUtils.scala | 15 + src/runtime/pgo/distsys/archetypes.go | 1296 ----------------- .../AssignmentRules.tla | 0 .../CallLabelingRules.tla | 0 .../IfEitherLabelingRules.tla | 0 .../LabelBeforeWhile.tla | 0 .../LabelNotDefined.tla | 0 .../MPCalKindMatching.tla | 15 +- .../{semantics => general}/MacroRules.tla | 0 .../MappingMacroWithCallGoto.tla | 0 .../MappingWithLabels.tla | 0 .../{semantics => general}/NoFirstLabel.tla | 2 +- .../RecursiveMacroRules.tla | 0 .../{semantics => general}/ReservedLabels.tla | 0 .../ReturnGotoLabelingRules.tla | 0 .../{semantics => general}/WithRules.tla | 0 test/files/{pcalgen => general}/dqueue.tla | 0 .../dqueue.tla.expectpcal | 0 .../general/dqueue.tla.gotests/dqueue.go | 197 +++ .../general/dqueue.tla.gotests/dqueue_test.go | 27 + test/files/general/dqueue.tla.gotests/go.mod | 7 + .../{pcalgen => general}/load_balancer.tla | 8 +- .../load_balancer.tla.expectpcal | 0 .../{pcalgen => general}/replicated_kv.tla | 0 .../replicated_kv.tla.expectpcal | 0 test/pgo/GoGenFileTests.scala | 29 +- test/pgo/PCalGenFileTests.scala | 6 +- 55 files changed, 2019 insertions(+), 1427 deletions(-) create mode 100644 distsys/archetypes.go rename {src/runtime/pgo/distsys => distsys}/barrier.go (100%) rename {src/runtime/pgo/distsys => distsys}/client.go (100%) rename {src/runtime/pgo/distsys => distsys}/connections.go (100%) rename {src/runtime/pgo/distsys => distsys}/data_store.go (100%) rename {src/runtime/pgo/distsys => distsys}/data_store_test.go (100%) rename {src/runtime/pgo/distsys => distsys}/distsys.go (99%) rename {src/runtime/pgo/distsys => distsys}/distsys_test.go (100%) rename {src/runtime/pgo/distsys => distsys}/etcd.go (100%) create mode 100644 distsys/go.mod create mode 100644 distsys/go.sum create mode 100644 distsys/mpcal.go rename {src/runtime/pgo/distsys => distsys}/processutil.go (100%) rename {src/runtime/pgo/distsys => distsys}/processutil_test.go (100%) rename {src/runtime/pgo/distsys => distsys}/state_ownership.go (100%) rename {src/runtime/pgo/distsys => distsys}/state_ownership_test.go (100%) rename {src/runtime/pgo/distsys => distsys}/state_server.go (100%) create mode 100644 distsys/tlaplus.go delete mode 100644 src/runtime/pgo/distsys/archetypes.go rename test/files/{semantics => general}/AssignmentRules.tla (100%) rename test/files/{semantics => general}/CallLabelingRules.tla (100%) rename test/files/{semantics => general}/IfEitherLabelingRules.tla (100%) rename test/files/{semantics => general}/LabelBeforeWhile.tla (100%) rename test/files/{semantics => general}/LabelNotDefined.tla (100%) rename test/files/{semantics => general}/MPCalKindMatching.tla (59%) rename test/files/{semantics => general}/MacroRules.tla (100%) rename test/files/{semantics => general}/MappingMacroWithCallGoto.tla (100%) rename test/files/{semantics => general}/MappingWithLabels.tla (100%) rename test/files/{semantics => general}/NoFirstLabel.tla (94%) rename test/files/{semantics => general}/RecursiveMacroRules.tla (100%) rename test/files/{semantics => general}/ReservedLabels.tla (100%) rename test/files/{semantics => general}/ReturnGotoLabelingRules.tla (100%) rename test/files/{semantics => general}/WithRules.tla (100%) rename test/files/{pcalgen => general}/dqueue.tla (100%) rename test/files/{pcalgen => general}/dqueue.tla.expectpcal (100%) create mode 100644 test/files/general/dqueue.tla.gotests/dqueue.go create mode 100644 test/files/general/dqueue.tla.gotests/dqueue_test.go create mode 100644 test/files/general/dqueue.tla.gotests/go.mod rename test/files/{pcalgen => general}/load_balancer.tla (99%) rename test/files/{pcalgen => general}/load_balancer.tla.expectpcal (100%) rename test/files/{pcalgen => general}/replicated_kv.tla (100%) rename test/files/{pcalgen => general}/replicated_kv.tla.expectpcal (100%) diff --git a/distsys/archetypes.go b/distsys/archetypes.go new file mode 100644 index 000000000..efb9db4c7 --- /dev/null +++ b/distsys/archetypes.go @@ -0,0 +1,270 @@ +package distsys + +import ( + "container/list" + "encoding/gob" + "errors" + "io" + "net" + "time" +) + +var Aborted = errors.New("MPCal critical section aborted") + +type ArchetypeResource interface { + Abort() + PreCommit() error + Commit() + ReadValue() (TLAValue, error) + WriteValue(value TLAValue) error + Index(index TLAValue) (ArchetypeResource, error) +} + +type ArchetypeResourceLeafMixin struct{} + +var ArchetypeResourceLeafIndexedError = errors.New("internal error: attempted to index a leaf archetype resource") + +func (ArchetypeResourceLeafMixin) Index(TLAValue) (ArchetypeResource, error) { + return nil, ArchetypeResourceLeafIndexedError +} + +type ArchetypeResourceMapMixin struct{} + +var ArchetypeResourceMapReadWriteError = errors.New("internal error: attempted to read/write a map archetype resource") + +func (ArchetypeResourceMapMixin) ReadValue() (TLAValue, error) { + return TLAValue{}, ArchetypeResourceMapReadWriteError +} + +func (ArchetypeResourceMapMixin) WriteValue(TLAValue) error { + return ArchetypeResourceMapReadWriteError +} + +//////////////////////////////////////////////// +//// ARCHETYPE RESOURCES //// +//////////////////////////////////////////////// + +// A bare-bones resource: just holds and buffers a TLAValue +// -------------------------------------------------------- + +type LocalArchetypeResource struct { + ArchetypeResourceLeafMixin + hasOldValue bool + value, oldValue TLAValue +} + +func NewLocalArchetypeResource(value TLAValue) *LocalArchetypeResource { + return &LocalArchetypeResource{ + hasOldValue: false, + value: value, + } +} + +func (res *LocalArchetypeResource) Abort() { + if res.hasOldValue { + res.value = res.oldValue + res.hasOldValue = false + res.oldValue = TLAValue{} + } +} + +func (res *LocalArchetypeResource) PreCommit() error { + return nil +} + +func (res *LocalArchetypeResource) Commit() { + res.hasOldValue = false + res.oldValue = TLAValue{} +} + +func (res *LocalArchetypeResource) ReadValue() (TLAValue, error) { + return res.value, nil +} + +func (res *LocalArchetypeResource) WriteValue(value TLAValue) error { + if !res.hasOldValue { + res.oldValue = res.value + res.hasOldValue = true + } + res.value = value + return nil +} + +// Global State as Archetype Resource +// ---------------------------------- + +// TODO: recreate + +// Mailboxes as Archetype Resource +// ------------------------------- + +type TCPMailboxesArchetypeResource struct { + ArchetypeResourceMapMixin + Listener net.Listener + inputChannel chan TLAValue + buffer *list.List + elementsRead []TLAValue +} + +var _ ArchetypeResource = &TCPMailboxesArchetypeResource{} + +const ( + tcpNetworkBegin = iota + tcpNetworkValue + tcpNetworkPreCommit + tcpNetworkPreCommitAck + tcpNetworkCommit +) + +type tcpNetworkMsg struct { + Tag int + Value TLAValue +} + +func NewTCPMailboxesArchetypeResource(address string) (res *TCPMailboxesArchetypeResource, err error) { + listener, err := net.Listen("tcp", address) + if err != nil { + return + } + inputChannel := make(chan TLAValue, 100) + go func() { + for { + conn, err := listener.Accept() + if err != nil { + break + } + go func() { + decoder := gob.NewDecoder(conn) + encoder := gob.NewEncoder(conn) + var msgBuffer []TLAValue + for { + var msg tcpNetworkMsg + err := decoder.Decode(&msg) + if err != nil { + if errors.Is(err, io.EOF) || errors.Is(err, io.ErrUnexpectedEOF) { + return + } + panic(err) // TODO: actually handle this + } + switch msg.Tag { + case tcpNetworkBegin: + msgBuffer = nil + case tcpNetworkValue: + msgBuffer = append(msgBuffer, msg.Value) + case tcpNetworkPreCommit: + err = encoder.Encode(&tcpNetworkMsg{Tag: tcpNetworkPreCommitAck}) + if err != nil { + panic(err) + } + case tcpNetworkCommit: + for _, msg := range msgBuffer { + inputChannel <- msg + } + msgBuffer = nil + default: + panic("???") + } + } + }() + } + }() + return &TCPMailboxesArchetypeResource{ + Listener: listener, + inputChannel: inputChannel, + buffer: list.New(), + }, nil +} + +func (res *TCPMailboxesArchetypeResource) pumpNetwork() error { + if res.buffer.Len() == 0 { + select { + case nextElem := <-res.inputChannel: + res.buffer.PushBack(nextElem) + return nil + case <-time.After(20 * time.Millisecond): + return Aborted + } + } else { + return nil + } +} + +func (res *TCPMailboxesArchetypeResource) Index(index TLAValue) (ArchetypeResource, error) { + panic("???") +} + +func (res *TCPMailboxesArchetypeResource) Abort() { + for _, elem := range res.elementsRead { + res.buffer.PushFront(elem) + } + res.elementsRead = nil +} + +func (res *TCPMailboxesArchetypeResource) PreCommit() error { + return nil +} + +func (res *TCPMailboxesArchetypeResource) Commit() { + res.elementsRead = nil +} + +type TCPMailboxRemoteArchetypeResource struct { + ArchetypeResourceLeafMixin + hasBegun bool + remoteAddress string + conn net.Conn + encoder gob.Encoder + decoder gob.Decoder +} + +var _ ArchetypeResource = &TCPMailboxRemoteArchetypeResource{} + +func (res *TCPMailboxRemoteArchetypeResource) ReadValue() (TLAValue, error) { + return TLAValue{}, errors.New("tried to read from non-local TCP mailbox") +} + +func (res *TCPMailboxRemoteArchetypeResource) WriteValue(value TLAValue) (err error) { + if !res.hasBegun { + if res.conn == nil { + res.conn, err = net.Dial("tcp", res.remoteAddress) + if err != nil { + return err + } + } + err = res.encoder.Encode(tcpNetworkMsg{Tag: tcpNetworkBegin}) + if err != nil { + return err + } + } + return res.encoder.Encode(tcpNetworkMsg{Tag: tcpNetworkValue, Value: value}) +} + +func (res *TCPMailboxRemoteArchetypeResource) Abort() { + res.hasBegun = false +} + +func (res *TCPMailboxRemoteArchetypeResource) PreCommit() error { + err := res.encoder.Encode(tcpNetworkMsg{Tag: tcpNetworkPreCommit}) + if err != nil { + res.conn = nil + return Aborted + } + var msg tcpNetworkMsg + err = res.decoder.Decode(&msg) + if msg.Tag != tcpNetworkPreCommitAck { + panic("???") + } + return nil +} + +func (res *TCPMailboxRemoteArchetypeResource) Commit() { + res.hasBegun = false + err := res.encoder.Encode(tcpNetworkMsg{Tag: tcpNetworkCommit}) + if err != nil { + panic(err) // can't support this failure... + } +} + +type TCPMailboxLocalArchetypeResource struct { + ArchetypeResourceLeafMixin +} diff --git a/src/runtime/pgo/distsys/barrier.go b/distsys/barrier.go similarity index 100% rename from src/runtime/pgo/distsys/barrier.go rename to distsys/barrier.go diff --git a/src/runtime/pgo/distsys/client.go b/distsys/client.go similarity index 100% rename from src/runtime/pgo/distsys/client.go rename to distsys/client.go diff --git a/src/runtime/pgo/distsys/connections.go b/distsys/connections.go similarity index 100% rename from src/runtime/pgo/distsys/connections.go rename to distsys/connections.go diff --git a/src/runtime/pgo/distsys/data_store.go b/distsys/data_store.go similarity index 100% rename from src/runtime/pgo/distsys/data_store.go rename to distsys/data_store.go diff --git a/src/runtime/pgo/distsys/data_store_test.go b/distsys/data_store_test.go similarity index 100% rename from src/runtime/pgo/distsys/data_store_test.go rename to distsys/data_store_test.go diff --git a/src/runtime/pgo/distsys/distsys.go b/distsys/distsys.go similarity index 99% rename from src/runtime/pgo/distsys/distsys.go rename to distsys/distsys.go index 35e391f40..22c4067bf 100644 --- a/src/runtime/pgo/distsys/distsys.go +++ b/distsys/distsys.go @@ -1,7 +1,7 @@ package distsys import ( - "github.com/mitchellh/hashstructure" + "github.com/mitchellh/hashstructure/v2" "bytes" "encoding/gob" diff --git a/src/runtime/pgo/distsys/distsys_test.go b/distsys/distsys_test.go similarity index 100% rename from src/runtime/pgo/distsys/distsys_test.go rename to distsys/distsys_test.go diff --git a/src/runtime/pgo/distsys/etcd.go b/distsys/etcd.go similarity index 100% rename from src/runtime/pgo/distsys/etcd.go rename to distsys/etcd.go diff --git a/distsys/go.mod b/distsys/go.mod new file mode 100644 index 000000000..3ac273bd9 --- /dev/null +++ b/distsys/go.mod @@ -0,0 +1,11 @@ +module github.com/UBC-NSS/pgo/distsys + +go 1.14 + +require ( + github.com/benbjohnson/immutable v0.3.0 + github.com/mitchellh/hashstructure/v2 v2.0.1 + github.com/onsi/ginkgo v1.16.2 + github.com/onsi/gomega v1.12.0 + go.etcd.io/etcd/client/v2 v2.305.0-beta.3 +) diff --git a/distsys/go.sum b/distsys/go.sum new file mode 100644 index 000000000..7a8f97d25 --- /dev/null +++ b/distsys/go.sum @@ -0,0 +1,190 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd/v22 v22.3.1/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/mitchellh/hashstructure/v2 v2.0.1 h1:L60q1+q7cXE4JeEJJKMnh2brFIe3rZxCihYAB61ypAY= +github.com/mitchellh/hashstructure/v2 v2.0.1/go.mod h1:MG3aRVU/N29oo/V/IhBX8GR/zz4kQkprJgF2EVszyDE= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.16.2 h1:HFB2fbVIlhIfCfOW81bZFbiC/RvnpXSdhbF2/DJr134= +github.com/onsi/ginkgo v1.16.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.12.0 h1:p4oGGk2M2UJc0wWN4lHFvIB71lxsh0T/UiKCCgFADY8= +github.com/onsi/gomega v1.12.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.etcd.io/etcd v0.5.0-alpha.5 h1:VOolFSo3XgsmnYDLozjvZ6JL6AAwIDu1Yx1y+4EYLDo= +go.etcd.io/etcd v3.3.25+incompatible h1:V1RzkZJj9LqsJRy+TUBgpWSbZXITLB819lstuTFoZOY= +go.etcd.io/etcd/api/v3 v3.5.0-beta.3 h1:FdNjTxZpH98oWWTtOjhz0EU7sILw9giVIW+M3dzZFOg= +go.etcd.io/etcd/api/v3 v3.5.0-beta.3/go.mod h1:yF0YUmBghT48aC0/eTFrhULo+uKQAr5spQQ6sRhPauE= +go.etcd.io/etcd/client/pkg/v3 v3.5.0-beta.3 h1:fh2cSzLD4OeGVy164WtilS9hAQYmQ2BC6Fh/akRR1b0= +go.etcd.io/etcd/client/pkg/v3 v3.5.0-beta.3/go.mod h1:a+pbz+UrcOpvve1Qxf6tGovi15PjgtRhi0QTO2Nlc4U= +go.etcd.io/etcd/client/v2 v2.305.0-beta.3 h1:tYAN7hKzGE6dDjdgZqRCwXLMwaSliWJ/CZmxhYz73Yc= +go.etcd.io/etcd/client/v2 v2.305.0-beta.3/go.mod h1:sWZG9/Oa2nspIl/4MBllUgm25QoQYNiuek6xCXTdEj8= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/zap v1.16.1-0.20210329175301-c23abee72d19/go.mod h1:aMfIlz3TDBfB0BwTCKFU1XbEmj9zevr5S5LcBr85MXw= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 h1:DzZ89McO9/gWPsQXS/FVKAlG02ZjaQ6AlZRBimEYOd0= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da h1:b3NXsE2LusjYGGjL5bxEVZZORm/YEFFrWFjR8eFrw/c= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/distsys/mpcal.go b/distsys/mpcal.go new file mode 100644 index 000000000..3bc4eb97f --- /dev/null +++ b/distsys/mpcal.go @@ -0,0 +1,86 @@ +package distsys + +func WhileCatchingPanics(fns ...func() TLAValue) (result []TLAValue, err error) { + defer func() { + if r := recover(); r != nil { + result = nil + err = r.(error) + } + }() + for _, fn := range fns { + result = append(result, fn()) + } + return +} + +type PCalSectionContext struct { + resources []ArchetypeResource +} + +func NewPCalSectionContext() *PCalSectionContext { + return &PCalSectionContext{} +} + +func (ctx *PCalSectionContext) recordResource(res ArchetypeResource) { + for _, existingRes := range ctx.resources { + if existingRes == res { + return + } + } + ctx.resources = append(ctx.resources, res) +} + +func (ctx *PCalSectionContext) Abort() { + for i := len(ctx.resources) - 1; i >= 0; i-- { + ctx.resources[i].Abort() + } +} + +func (ctx *PCalSectionContext) Commit() (err error) { + for i := len(ctx.resources) - 1; i >= 0; i-- { + err = ctx.resources[i].PreCommit() + if err != nil { + break + } + } + if err != nil { + for i := len(ctx.resources) - 1; i >= 0; i-- { + ctx.resources[i].Abort() + } + } else { + for i := len(ctx.resources) - 1; i >= 0; i-- { + ctx.resources[i].Commit() + } + } + return +} + +func (ctx *PCalSectionContext) Write(resource ArchetypeResource, indices []TLAValue, value TLAValue) error { + ctx.recordResource(resource) + if len(indices) == 0 { + return resource.WriteValue(value) + } else { + resAtIndex, err := resource.Index(indices[0]) + if err != nil { + return err + } + return ctx.Write(resAtIndex, indices[1:], value) + } +} + +func (ctx *PCalSectionContext) Read(resource ArchetypeResource, indices []TLAValue) TLAValue { + ctx.recordResource(resource) + if len(indices) == 0 { + value, err := resource.ReadValue() + if err != nil { + panic(err) + } + return value + } else { + resAtIndex, err := resource.Index(indices[0]) + if err != nil { + panic(err) + } + return ctx.Read(resAtIndex, indices[1:]) + } +} diff --git a/src/runtime/pgo/distsys/processutil.go b/distsys/processutil.go similarity index 100% rename from src/runtime/pgo/distsys/processutil.go rename to distsys/processutil.go diff --git a/src/runtime/pgo/distsys/processutil_test.go b/distsys/processutil_test.go similarity index 100% rename from src/runtime/pgo/distsys/processutil_test.go rename to distsys/processutil_test.go diff --git a/src/runtime/pgo/distsys/state_ownership.go b/distsys/state_ownership.go similarity index 100% rename from src/runtime/pgo/distsys/state_ownership.go rename to distsys/state_ownership.go diff --git a/src/runtime/pgo/distsys/state_ownership_test.go b/distsys/state_ownership_test.go similarity index 100% rename from src/runtime/pgo/distsys/state_ownership_test.go rename to distsys/state_ownership_test.go diff --git a/src/runtime/pgo/distsys/state_server.go b/distsys/state_server.go similarity index 100% rename from src/runtime/pgo/distsys/state_server.go rename to distsys/state_server.go diff --git a/distsys/tlaplus.go b/distsys/tlaplus.go new file mode 100644 index 000000000..6b6a5220b --- /dev/null +++ b/distsys/tlaplus.go @@ -0,0 +1,340 @@ +package distsys + +import ( + "encoding/binary" + "encoding/gob" + "errors" + "fmt" + "github.com/benbjohnson/immutable" + "hash/fnv" + "strconv" + "strings" +) + +var TLATypeError = errors.New("TLA+ type error") + +func init() { + gob.Register(tlaValueBool(true)) + gob.Register(tlaValueNumber(0)) + gob.Register(tlaValueString("")) + gob.Register(tlaValueSet{}) + gob.Register(tlaValueTuple{}) +} + +type TLAValue struct { + data tlaValueImpl +} + +func (v TLAValue) Hash() uint32 { + if v.data == nil { + return 0 + } else { + return v.data.Hash() + } +} + +func (v TLAValue) Equal(other TLAValue) bool { + if v.data == nil && other.data == nil { + return true + } else if v.data == nil || other.data == nil { + return false + } else { + return v.data.Equal(other) + } +} + +func (v TLAValue) String() string { + if v.data == nil { + return "defaultInitValue" + } else { + return v.data.String() + } +} + +func (v TLAValue) AsBool() bool { + switch data := v.data.(type) { + case tlaValueBool: + return bool(data) + default: + panic(TLATypeError) + } +} + +func (v TLAValue) AsNumber() int32 { + switch data := v.data.(type) { + case tlaValueNumber: + return int32(data) + default: + panic(TLATypeError) + } +} + +func (v TLAValue) AsString() string { + switch data := v.data.(type) { + case tlaValueString: + return string(data) + default: + panic(TLATypeError) + } +} + +func (v TLAValue) AsSet() immutable.Map { + switch data := v.data.(type) { + case tlaValueSet: + return immutable.Map(data) + default: + panic(TLATypeError) + } +} + +func (v TLAValue) AsTuple() immutable.List { + switch data := v.data.(type) { + case tlaValueTuple: + return immutable.List(data) + default: + panic(TLATypeError) + } +} + +func (v TLAValue) IsTrue() bool { + return v.AsBool() +} + +func (v TLAValue) SelectElement() TLAValue { + set := v.AsSet() + it := set.Iterator() + if !it.Done() { + key, _ := it.Next() + return key.(TLAValue) + } else { + panic(fmt.Errorf("")) + } +} + + +type TLAValueHasher struct{} + +func (TLAValueHasher) Hash(key interface{}) uint32 { + return key.(TLAValue).Hash() +} + +func (hasher TLAValueHasher) Equal(a, b interface{}) bool { + return a.(TLAValue).Equal(b.(TLAValue)) +} + +type tlaValueImpl interface { + Hash() uint32 + Equal(other TLAValue) bool + String() string +} + +type tlaValueBool bool + +var TLA_TRUE = TLAValue{tlaValueBool(true)} +var TLA_FALSE = TLAValue{tlaValueBool(false)} + +func (v tlaValueBool) Hash() uint32 { + h := fnv.New32() + err := binary.Write(h, binary.LittleEndian, bool(v)) + if err != nil { + panic(err) + } + return h.Sum32() +} + +func (v tlaValueBool) Equal(other TLAValue) bool { + return bool(v) == other.AsBool() +} + +func (v tlaValueBool) String() string { + if v { + return "TRUE" + } else { + return "FALSE" + } +} + +type tlaValueNumber int32 + +func NewTLANumber(num int32) TLAValue { + return TLAValue{tlaValueNumber(num)} +} + +func (v tlaValueNumber) Hash() uint32 { + h := fnv.New32() + err := binary.Write(h, binary.LittleEndian, int32(v)) + if err != nil { + panic(err) + } + return h.Sum32() +} + +func (v tlaValueNumber) Equal(other TLAValue) bool { + return int32(v) == other.AsNumber() +} + +func (v tlaValueNumber) String() string { + return strconv.FormatInt(int64(v), 10) +} + +func TLA_PlusSymbol(lhs, rhs TLAValue) TLAValue { + return TLAValue{tlaValueNumber(lhs.AsNumber() + rhs.AsNumber())} +} + +type tlaValueString string + +func NewTLAString(value string) TLAValue { + return TLAValue{tlaValueString(value)} +} + +func (v tlaValueString) Hash() uint32 { + vC := string(v) + h := fnv.New32() + _, err := h.Write([]byte(vC)) + if err != nil { + panic(err) + } + return h.Sum32() +} + +func (v tlaValueString) Equal(other TLAValue) bool { + return string(v) == other.AsString() +} + +func (v tlaValueString) String() string { + return strconv.Quote(string(v)) +} + +type tlaValueSet immutable.Map + +func NewTLASet(members ...TLAValue) TLAValue { + builder := immutable.NewMapBuilder(TLAValueHasher{}) + for _, member := range members { + builder.Set(member, true) + } + return TLAValue{tlaValueSet(*builder.Map())} +} + +func (v tlaValueSet) Hash() uint32 { + vC := immutable.Map(v) + var hash uint32 = 0 + it := vC.Iterator() + for !it.Done() { + key, _ := it.Next() + keyV := key.(TLAValue) + // use XOR combination, so that all the set members are hashed out of order + hash ^= keyV.Hash() + } + h := fnv.New32() + err := binary.Write(h, binary.LittleEndian, hash) + if err != nil { + panic(err) + } + return h.Sum32() +} + +func (v tlaValueSet) Equal(other TLAValue) bool { + vC := immutable.Map(v) + oC := other.AsSet() + if vC.Len() != oC.Len() { + return false + } else { + it := vC.Iterator() + for !it.Done() { + k, _ := it.Next() + _, ok := oC.Get(k) + if !ok { + return false + } + } + it = oC.Iterator() + for !it.Done() { + k, _ := it.Next() + _, ok := vC.Get(k) + if !ok { + return false + } + } + return true + } +} + +func (v tlaValueSet) String() string { + builder := strings.Builder{} + builder.WriteString("{") + vC := immutable.Map(v) + it := vC.Iterator() + first := true + for !it.Done() { + if first { + first = false + } else { + builder.WriteString(", ") + } + elem, _ := it.Next() + builder.WriteString(elem.(TLAValue).String()) + } + builder.WriteString("}") + return builder.String() +} + +type tlaValueTuple immutable.List + +func NewTLATuple(members ...TLAValue) TLAValue { + builder := immutable.NewListBuilder() + for _, member := range members { + builder.Append(member) + } + return TLAValue{tlaValueTuple(*builder.List())} +} + +func (v tlaValueTuple) Hash() uint32 { + vC := immutable.List(v) + h := fnv.New32() + it := vC.Iterator() + for !it.Done() { + _, member := it.Next() + memberV := member.(TLAValue) + err := binary.Write(h, binary.LittleEndian, memberV.Hash()) + if err != nil { + panic(err) + } + } + return h.Sum32() +} + +func (v tlaValueTuple) Equal(other TLAValue) bool { + vC := immutable.List(v) + oC := other.AsTuple() + if vC.Len() != oC.Len() { + return false + } + it1, it2 := vC.Iterator(), oC.Iterator() + for !it1.Done() || !it2.Done() { + _, elem1 := it1.Next() + _, elem2 := it2.Next() + if !elem1.(TLAValue).data.Equal(elem2.(TLAValue)) { + return false + } + } + return true +} + +func (v tlaValueTuple) String() string { + vC := immutable.List(v) + builder := strings.Builder{} + builder.WriteString("<<") + it := vC.Iterator() + first := true + for !it.Done() { + if first { + first = false + } else { + builder.WriteString(", ") + } + _, elem := it.Next() + builder.WriteString(elem.(TLAValue).String()) + } + builder.WriteString(">>") + return builder.String() +} diff --git a/src/pgo/PGo.scala b/src/pgo/PGo.scala index 9c4c0b2d1..4067b6904 100644 --- a/src/pgo/PGo.scala +++ b/src/pgo/PGo.scala @@ -82,17 +82,17 @@ object PGo { MPCalSemanticCheckPass(tlaModule, mpcalBlock) mpcalBlock = MPCalNormalizePass(tlaModule, mpcalBlock) - val goCode = MPCalGoCodegenPass(mpcalBlock, packageName = config.GoGenCmd.packageName.toOption) - os.write(config.GoGenCmd.outFile(), goCode.linesIterator) + val goCode = MPCalGoCodegenPass(tlaModule, mpcalBlock, packageName = config.GoGenCmd.packageName.toOption) + os.write.over(config.GoGenCmd.outFile(), goCode.linesIterator.map(line => s"$line\n")) case config.PCalGenCmd => var (tlaModule, mpcalBlock) = parseMPCal(config.PCalGenCmd.specFile()) MPCalSemanticCheckPass(tlaModule, mpcalBlock) mpcalBlock = MPCalNormalizePass(tlaModule, mpcalBlock) - val pcalAlgorithm = MPCalPCalCodegenPass(mpcalBlock) + val pcalAlgorithm = MPCalPCalCodegenPass(tlaModule, mpcalBlock) val renderedPCal = PCalRenderPass(pcalAlgorithm) - val tempOutput = os.temp.apply(dir = os.pwd) + val tempOutput = os.temp(dir = os.pwd) locally { val PCalBeginTranslation = raw"""\s*\\\*\s+BEGIN\s+PLUSCAL\s+TRANSLATION""".r val PCalEndTranslation = raw"""\s*\\\*\s+END\s+PLUSCAL\s+TRANSLATION""".r diff --git a/src/pgo/model/mpcal/AST.scala b/src/pgo/model/mpcal/AST.scala index 34c54303b..b99a9081a 100644 --- a/src/pgo/model/mpcal/AST.scala +++ b/src/pgo/model/mpcal/AST.scala @@ -1,6 +1,6 @@ package pgo.model.mpcal -import pgo.model.{Definition, DefinitionOne, RefersTo, Rewritable, SourceLocatable, Visitable} +import pgo.model.{Definition, DefinitionOne, RefersTo, Rewritable, SourceLocatable} import pgo.model.tla._ import pgo.model.pcal._ @@ -9,13 +9,7 @@ sealed abstract class MPCalNode extends Rewritable with SourceLocatable { super.decorateLike(succ.setSourceLocation(sourceLocation)) } -sealed abstract class MPCalParamExpr extends MPCalNode with RefersTo[DefinitionOne] { - def name: TLAIdentifier - def mappingCount: Int -} - -final case class MPCalRefExpr(override val name: TLAIdentifier, override val mappingCount: Int) extends MPCalParamExpr -final case class MPCalValExpr(override val name: TLAIdentifier, override val mappingCount: Int) extends MPCalParamExpr +final case class MPCalRefExpr(name: TLAIdentifier, mappingCount: Int) extends MPCalNode with RefersTo[DefinitionOne] final case class MPCalDollarValue() extends MPCalNode @@ -23,17 +17,16 @@ final case class MPCalDollarVariable() extends MPCalNode final case class MPCalYield(expr: TLAExpression) extends MPCalNode -final case class MPCalCall(target: TLAIdentifier, arguments: List[Either[MPCalParamExpr,TLAExpression]]) extends MPCalNode with RefersTo[MPCalProcedure] +final case class MPCalCall(target: TLAIdentifier, arguments: List[Either[MPCalRefExpr,TLAExpression]]) extends MPCalNode with RefersTo[MPCalProcedure] sealed abstract class MPCalParam extends MPCalNode with DefinitionOne { def name: TLAIdentifier - def mappingCount: Int override def arity: Int = 0 override def identifier: Definition.ScopeIdentifier = Definition.ScopeIdentifierName(name) } -final case class MPCalRefParam(override val name: TLAIdentifier, override val mappingCount: Int) extends MPCalParam -final case class MPCalValParam(override val name: TLAIdentifier, override val mappingCount: Int) extends MPCalParam +final case class MPCalRefParam(override val name: TLAIdentifier, mappingCount: Int) extends MPCalParam +final case class MPCalValParam(override val name: TLAIdentifier) extends MPCalParam final case class MPCalBlock(name: TLAIdentifier, units: List[TLAUnit], macros: List[PCalMacro], mpcalProcedures: List[MPCalProcedure], mappingMacros: List[MPCalMappingMacro], archetypes: List[MPCalArchetype], @@ -51,7 +44,7 @@ final case class MPCalArchetype(name: TLAIdentifier, selfDecl: TLADefiningIdenti variables: List[PCalVariableDeclaration], body: List[PCalStatement]) extends MPCalNode with RefersTo.HasReferences final case class MPCalInstance(selfDecl: PCalVariableDeclarationBound, fairness: PCalFairness, - archetypeName: TLAIdentifier, arguments: List[Either[MPCalParamExpr,TLAExpression]], + archetypeName: TLAIdentifier, arguments: List[Either[MPCalRefExpr,TLAExpression]], mappings: List[MPCalMapping]) extends MPCalNode with RefersTo[MPCalArchetype] final case class MPCalMapping(target: MPCalMappingTarget, mappingMacroIdentifier: TLAIdentifier) extends MPCalNode with RefersTo[MPCalMappingMacro] diff --git a/src/pgo/model/tla/AST.scala b/src/pgo/model/tla/AST.scala index d3d19569b..472bcd7fb 100644 --- a/src/pgo/model/tla/AST.scala +++ b/src/pgo/model/tla/AST.scala @@ -69,6 +69,8 @@ object TLASymbol { */ def stringReprUsage: String = representations.head + def productPrefix: String + def precedenceLow: Int = TLAMeta.prefixOperators.get(representations.head).map(_._1) .orElse(TLAMeta.infixOperators.get(representations.head).map(_._1)) diff --git a/src/pgo/parser/MPCalParser.scala b/src/pgo/parser/MPCalParser.scala index 633b53d5d..8d4a00516 100644 --- a/src/pgo/parser/MPCalParser.scala +++ b/src/pgo/parser/MPCalParser.scala @@ -7,7 +7,6 @@ import pgo.model.pcal._ import pgo.model.tla._ import pgo.util.Description -import Description._ trait MPCalParser extends PCalParser { import pgo.parser.MPCalParserContext._ @@ -21,7 +20,7 @@ trait MPCalParser extends PCalParser { def mpcalParam(implicit ctx: MPCalParserContext): Parser[MPCalParam] = withSourceLocation { "ref" ~> ws ~> tlaIdentifierExpr ~ (ws ~> mpcalRefSuffix) ^^ { case id ~ mappingCount => MPCalRefParam(id, mappingCount)} | - (tlaIdentifierExpr <~ ws) ~ mpcalRefSuffix ^^ { case id ~ mappingCount => MPCalValParam(id, mappingCount) } + (tlaIdentifierExpr <~ ws) ^^ MPCalValParam } def mpcalArchetype(implicit ctx: MPCalParserContext): Parser[MPCalArchetype] = @@ -83,7 +82,7 @@ trait MPCalParser extends PCalParser { (ws ~> "process" ~> ws ~> "(" ~> pcalVarDeclBound <~ ws <~ ")") ~ (ws ~> "==" ~> ws ~> "instance" ~> ws ~> tlaIdentifierExpr) ~ (ws ~> "(" ~> ws ~> repsep(mpcalParamExpr ^^ { - case TLAExtensionExpression(pExp: MPCalParamExpr) => Left(pExp) + case TLAExtensionExpression(pExp: MPCalRefExpr) => Left(pExp) case expr: TLAExpression => Right(expr) }, ws ~> "," ~> ws) <~ ws <~ ")") ).flatMap { @@ -168,12 +167,9 @@ trait MPCalParser extends PCalParser { def mpcalParamExpr(implicit ctx: PCalParserContext): Parser[TLAExpression] = withSourceLocation { querySourceLocation { - ("ref" ~> ws ~> tlaIdentifierExpr ~ (ws ~> mpcalRefSuffix) ^^ { + "ref" ~> ws ~> tlaIdentifierExpr ~ (ws ~> mpcalRefSuffix) ^^ { case id ~ mappingCount => (id, MPCalRefExpr(id, mappingCount)) - } | - tlaIdentifierExpr ~ (ws ~> mpcalRefSuffix) ^^ { - case id ~ mappingCount => (id, MPCalValExpr(id, mappingCount)) - }) + } } .map { case (loc, (id, ref)) => @@ -250,7 +246,7 @@ trait MPCalParser extends PCalParser { result = result.rewrite() { case call @PCalCall(target, args) if mpcalProcedureMap.contains(target) => val transformedArgs = args.map { - case TLAExtensionExpression(pExp: MPCalParamExpr) => Left(pExp) + case TLAExtensionExpression(pExp: MPCalRefExpr) => Left(pExp) case expr => Right(expr) } PCalExtensionStatement(MPCalCall(target, transformedArgs) @@ -284,7 +280,7 @@ object MPCalParser extends MPCalParser with ParsingUtils { } // ensure no dandling ref or [_] are left in random expressions result.visit(Visitable.BottomUpFirstStrategy) { - case TLAExtensionExpression(pExp: MPCalParamExpr) => + case TLAExtensionExpression(pExp: MPCalRefExpr) => assert(false, s"ref or [_] found in wrong expression context: these syntaxes may only be used directly as arguments to an MPCal procedure call: ${pExp.sourceLocation}") } result diff --git a/src/pgo/parser/ParsingErrors.scala b/src/pgo/parser/ParsingErrors.scala index 2e2d1fe0f..8154efb81 100644 --- a/src/pgo/parser/ParsingErrors.scala +++ b/src/pgo/parser/ParsingErrors.scala @@ -11,13 +11,17 @@ sealed abstract class ParsingError(override val sourceLocation: SourceLocation, } final case class DefinitionLookupError(pfx: List[TLAGeneralIdentifierPart], id: Definition.ScopeIdentifier) extends ParsingError( - id.sourceLocation,d"identifier ${pfx.mkString("!")}${if(pfx.nonEmpty){"!"} else {""}}$id does not refer to a known definition") + id.sourceLocation,d"identifier ${pfx.mkString("!")}${if(pfx.nonEmpty){"!"} else {""}}${ + id match { + case Definition.ScopeIdentifierName(name) => name.id + case Definition.ScopeIdentifierSymbol(symbol) => symbol.symbol.stringReprUsage + }} does not refer to a known definition") final case class DoesNotExtendAModuleError(id: Definition.ScopeIdentifierName, badDefn: DefinitionOne) extends ParsingError( - id.sourceLocation,d"${id.name.id} does not refer to a module. actually refers to $badDefn") + id.sourceLocation,d"${id.name.id} does not refer to a module. actually refers to ${badDefn.toString}") final case class ModuleNotFoundError(id: Definition.ScopeIdentifierName) extends ParsingError( - id.sourceLocation,d"module $id not found") + id.sourceLocation,d"module ${id.name.id} not found") final case class MacroLookupError(target: TLAIdentifier) extends ParsingError( target.sourceLocation, d"could not find definition for macro `${target.id}`") diff --git a/src/pgo/trans/MPCalGoCodegenPass.scala b/src/pgo/trans/MPCalGoCodegenPass.scala index ff2a6276d..88a521435 100644 --- a/src/pgo/trans/MPCalGoCodegenPass.scala +++ b/src/pgo/trans/MPCalGoCodegenPass.scala @@ -1,10 +1,678 @@ package pgo.trans -import pgo.model.PGoError -import pgo.model.mpcal.MPCalBlock -import pgo.util.Description +import pgo.model.{Definition, PGoError, RefersTo, Visitable} +import pgo.model.mpcal._ +import pgo.model.pcal._ +import pgo.model.tla._ +import pgo.util.{Description, IdMap, NameCleaner} +import Description._ +import pgo.model.tla.BuiltinModules.TLABuiltinOperator +import pgo.util.MPCalPassUtils.MappedRead +import pgo.util.Unreachable.!!! + +import java.util.Locale +import scala.annotation.tailrec +import scala.collection.{View, mutable} object MPCalGoCodegenPass { + private val TLAValue = "distsys.TLAValue" + private val ArchetypeResource = "distsys.ArchetypeResource" + private val LocalArchetypeResource = "*distsys.LocalArchetypeResource" + val goKeywords: List[String] = + """ + |break default func interface select + |case defer go map struct + |chan else goto package switch + |const fallthrough if range type + |continue for import return var + |""".stripMargin.split(' ').view.filter(_.nonEmpty).toList + + sealed abstract class Binding { + val bind: String + } + final case class IndependentCallableBinding(bind: String) extends Binding + final case class DependentCallableBinding(bind: String) extends Binding + final case class FixedValueBinding(bind: String) extends Binding + final case class ResourceBinding(bind: String) extends Binding + + case class GoCodegenContext(nameCleaner: NameCleaner, bindings: IdMap[RefersTo.HasReferences,Binding] = IdMap.empty, + errOpt: Option[Description] = None, constantsOpt: Option[String] = None, + sectionCtxOpt: Option[Description] = None, currentLabelOpt: Option[Description] = None, + resourceMappingCounts: IdMap[RefersTo.HasReferences,Int] = IdMap.empty) { + def err: Description = errOpt.get + def constants: String = constantsOpt.get + def sectionCtx: Description = sectionCtxOpt.get + def currentLabel: Description = currentLabelOpt.get + def cleanName[T](hint: String)(fn: String => T): T = + fn(nameCleaner.cleanName(hint)) + } + + def toGoPublicName(id: String): String = + id.capitalize + + def translateBody(body: List[PCalStatement])(implicit ctx: GoCodegenContext): Description = { + assert(body.forall(_.isInstanceOf[PCalLabeledStatements])) + + val pcalEithers = locally { + val acc = mutable.ListBuffer.empty[PCalEither] + body.foreach(_.visit(Visitable.BottomUpFirstStrategy) { + case either@PCalEither(_) => acc += either + }) + acc.result() + } + val fairnessCounterNames = pcalEithers.view + .map(either => either -> ctx.nameCleaner.cleanName("fairnessCounter")) + .to(IdMap) + + def readExprs(exprs: List[TLAExpression])(fn: Description=>Description)(implicit ctx: GoCodegenContext): Description = { + ctx.cleanName("exprReads") { exprReads => + d"\nvar $exprReads []$TLAValue" + + d"\n$exprReads, ${ctx.err} = distsys.WhileCatchingPanics(${ + exprs.map { expr => + d"func() $TLAValue { return ${translateExpr(expr)} }" + }.separateBy(d", ") + })" + + d"\nif ${ctx.err} != nil {${ + (d"\n${ctx.sectionCtx}.Abort()" + + d"\nif ${ctx.err} == distsys.Aborted {${ + d"\ngoto ${ctx.currentLabel}".indented + }\n} else {${ + d"\nreturn ${ctx.err}".indented + }\n}").indented + }\n}" + + fn(exprReads.toDescription) + } + } + + def commit(body: =>Description)(implicit ctx: GoCodegenContext): Description = + d"\nswitch ${ctx.err} = ${ctx.sectionCtx}.Commit(); ${ctx.err} {" + + d"\ncase error(nil):" + + body.indented + + d"\ncase distsys.Aborted:" + + d"\ngoto ${ctx.currentLabel}".indented + + d"\ndefault:" + + d"\nreturn ${ctx.err}".indented + + d"\n}" + + def impl(stmts: List[PCalStatement], pfxDesc: Description = d"")(implicit ctx: GoCodegenContext): Description = + stmts match { + case Nil => + d"$pfxDesc\n// no statements" + case PCalGoto(target) :: Nil => + pfxDesc + commit(d"\ngoto $target") + case PCalReturn() :: Nil => + pfxDesc + commit(d"\nreturn nil") + case PCalExtensionStatement(call@MPCalCall(_, arguments)) :: restStmts => + val exprArgs = arguments.collect { case Right(expr) => expr } + val exprArgIndices = exprArgs.view.zipWithIndex.to(IdMap) + pfxDesc + readExprs(exprArgs) { exprReads => + commit { + val IndependentCallableBinding(nameToCall) = ctx.bindings(call.refersTo) + d"\n${ctx.err} = $nameToCall(${ctx.constants}${ + arguments.map { + case Left(ref) => d", ${ctx.bindings(ref.refersTo).bind}" + case Right(expr) => d", $exprReads[${exprArgIndices(expr)}]" + } + })" + + d"\nif ${ctx.err} != nil {${ + d"\nreturn err".indented + }\n}" + + (restStmts match { + case PCalGoto(target) :: Nil => + d"\ngoto $target" + case PCalReturn() :: Nil => + d"\nreturn nil" + }) + } + } + case stmt :: restStmts => + val result = stmt match { + case PCalAssert(condition) => + readExprs(List(condition)) { exprReads => + d"\nif !$exprReads[0].IsTrue() {${ + (d"\n${ctx.sectionCtx}.Abort()" + + d"\nreturn distsys.AssertionFailed").indented + }\n}" + } + case PCalAssignment(List(PCalAssignmentPair(lhs, rhs))) => + @tailrec + def gatherLhsIndices(lhs: PCalAssignmentLhs, acc: mutable.ListBuffer[TLAExpression]): List[TLAExpression] = + lhs match { + case PCalAssignmentLhsIdentifier(_) => acc.result() + case PCalAssignmentLhsProjection(lhs, projections) => + if (projections.size == 1) { + acc.prepend(projections.head) + } else { + acc.prepend(TLATuple(projections)) + } + gatherLhsIndices(lhs, acc) + case PCalAssignmentLhsExtension(_) => !!! + } + + @tailrec + def findLhsIdent(lhs: PCalAssignmentLhs): PCalAssignmentLhsIdentifier = + lhs match { + case ident: PCalAssignmentLhsIdentifier => ident + case PCalAssignmentLhsProjection(lhs, _) => findLhsIdent(lhs) + case PCalAssignmentLhsExtension(_) => !!! + } + + readExprs(rhs :: gatherLhsIndices(lhs, mutable.ListBuffer.empty)) { exprReads => + d"\n${ctx.err} = ${ctx.sectionCtx}.Write(${ctx.bindings(findLhsIdent(lhs).refersTo).bind}, $exprReads[1:], $exprReads[0])" + + d"\nif ${ctx.err} != nil {${ + (d"\n${ctx.sectionCtx}.Abort()" + + d"\nif ${ctx.err} == distsys.Aborted {${ + d"\ngoto ${ctx.currentLabel}".indented + }\n} else {${ + d"\nreturn ${ctx.err}".indented + }\n}").indented + }\n}" + } + case PCalAwait(condition) => + readExprs(List(condition)) { exprReads => + d"\nif !$exprReads[0].IsTrue() {${ + (d"\n${ctx.sectionCtx}.Abort()" + + d"\ngoto ${ctx.currentLabel}").indented + }\n}" + } + case PCalCall(_, _) => !!! // replaced by MPCalCall above + case either@PCalEither(cases) => + ctx.cleanName(s"fairnessCounterCurrent") { fairnessCounterCurrent => + d"\n$fairnessCounterCurrent := ${fairnessCounterNames(either)}" + + d"\n${fairnessCounterNames(either)} = ${fairnessCounterNames(either)} + 1 % ${cases.size}" + + d"\nswitch $fairnessCounterCurrent {${ + cases.view.zipWithIndex.map { + case (body, idx) => + d"\ncase $idx:" + + impl(body).indented + }.flattenDescriptions + + d"\ndefault:" + + d"""\npanic("current branch if either matches no code paths!")""".indented + }\n}" + } + case PCalIf(condition, yes, no) => + readExprs(List(condition)) { exprReads => + d"\nif $exprReads[0].IsTrue() {${ + impl(yes).indented + }\n} else {${ + impl(no).indented + }\n}" + } + case PCalLabeledStatements(_, _) => !!! + case PCalMacroCall(_, _) => !!! + case PCalPrint(value) => + readExprs(List(value)) { exprReads => + d"\n$exprReads[0].PCalPrint()" + } + case PCalSkip() => + d"\n// skip" + case PCalWhile(_, _) => !!! + case PCalWith(variables, body) => + readExprs(variables.map { + case PCalVariableDeclarationValue(_, value) => value + case PCalVariableDeclarationSet(_, set) => set + }) { exprReads => + val oldCtx = ctx + val cleanedNames = variables.map(decl => ctx.nameCleaner.cleanName(decl.name.id)) + (variables.view.zipWithIndex zip cleanedNames).map { + case ((PCalVariableDeclarationValue(_, _), idx), name) => + d"\nvar $name $TLAValue = $exprReads[$idx]" + case ((PCalVariableDeclarationSet(_, _), idx), name) => + d"\nvar $name $TLAValue = $exprReads[$idx].SelectElement()" + }.toList.flattenDescriptions + { + implicit val ctx: GoCodegenContext = oldCtx.copy( + bindings = oldCtx.bindings ++ (variables.view zip cleanedNames.view.map(FixedValueBinding))) + impl(body) + } + } + } + impl(restStmts, pfxDesc = pfxDesc + result) + } + + ctx.cleanName("err") { err => + d"\nvar $err error" + + pcalEithers.map { either => + d"\nvar ${fairnessCounterNames(either)} int = 0" + }.flattenDescriptions + + d"\n" + + body.map { + case PCalLabeledStatements(label, statements) => + d"\n${label.name}: {${ + ctx.cleanName("sectionCtx") { sectionCtx => + (d"\n$sectionCtx := distsys.NewPCalSectionContext()" + + impl(statements)(ctx = ctx.copy( + errOpt = Some(err.toDescription), + sectionCtxOpt = Some(sectionCtx.toDescription), + currentLabelOpt = Some(label.name.toDescription), + ))).indented + } + }\n}" + case _ => !!! + }.flattenDescriptions + } + } + + def translateExpr(expression: TLAExpression)(implicit ctx: GoCodegenContext): Description = + expression match { + case TLAString(value) => + d"""distsys.NewTLAString("${ + value.flatMap { + case '"' => "\\\"" + case '\\' => "\\\\" + case '\t' => "\\t" + case '\n' => "\\n" + case '\f' => "\\f" + case '\r' => "\\r" + case ch => ch.toString + } + }")""" + case TLANumber(value, _) => + d"""distsys.NewTLANumber(${ + value match { + case TLANumber.IntValue(value) => value.toString() + case TLANumber.DecimalValue(value) => ??? //value.toString() // FIXME: should we be able to support this? + } + })""" + case expr@MappedRead(mappingCount, ident) if ctx.resourceMappingCounts.get(ident.refersTo).contains(mappingCount) => + @tailrec + def findIndices(expr: TLAExpression, acc: mutable.ListBuffer[TLAExpression]): List[TLAExpression] = + expr match { + case _: TLAGeneralIdentifier => acc.result() + case TLAFunctionCall(fn, params) => + if(params.size == 1) { + acc.prepend(params.head) + } else { + acc.prepend(TLATuple(params)) + } + findIndices(fn, acc) + } + + val indices = findIndices(expr, mutable.ListBuffer.empty).map(translateExpr).separateBy(d", ") + d"${ctx.sectionCtx}.Read(${ctx.bindings(ident.refersTo).bind}, []$TLAValue{$indices})" + case ident@TLAGeneralIdentifier(_, prefix) => + assert(prefix.isEmpty) + ctx.bindings(ident.refersTo) match { + case IndependentCallableBinding(bind) => + // only makes sense when: + // - passing an operator to an operator + // - reading an arity 0 built-in (which is basically like a constant) + bind.toDescription + case DependentCallableBinding(bind) => + val cleanArgs = View.fill(ident.refersTo.arity)(ctx.nameCleaner.cleanName("arg")).toList + d"func(${cleanArgs.view.map(arg => d"$arg $TLAValue").separateBy(d", ")}) $TLAValue {${ + d"\nreturn $bind(${ctx.constants}${cleanArgs.view.map(arg => d", $arg").flattenDescriptions})" + }\n}" + case FixedValueBinding(bind) => bind.toDescription + case ResourceBinding(bind) => d"${ctx.sectionCtx}.Read($bind, []$TLAValue{})" + } + case TLADot(lhs, identifier) => + d"${translateExpr(lhs)}.ApplyFunction(${ + d"""distsys.NewTLAString("${identifier.id}")""" + })" + case call@TLAOperatorCall(_, prefix, arguments) => + assert(prefix.isEmpty) + ctx.bindings(call.refersTo) match { + case IndependentCallableBinding(bind) => + d"$bind(${arguments.map(translateExpr).separateBy(d", ")})" + case DependentCallableBinding(bind) => + d"$bind(${ctx.constants}, ${arguments.map(translateExpr).separateBy(d", ")})" + } + case TLAIf(cond, tval, fval) => + d"func() {${ + (d"\nif ${translateExpr(cond)}.IsTrue() {" + + d"\nreturn ${translateExpr(tval)}".indented + + d"\n} else {" + + d"\nreturn ${translateExpr(fval)}".indented + + d"\n}").indented + }\n}()" + case TLALet(defs, body) => + val origCtx = ctx + d"func() $TLAValue {${ + val defnNames = defs.view.map { + case defn@TLAOperatorDefinition(name, _, _, _) => + defn -> origCtx.nameCleaner.cleanName(name match { + case Definition.ScopeIdentifierName(name) => name.id + case Definition.ScopeIdentifierSymbol(symbol) => symbol.symbol.productPrefix + }) + }.to(IdMap) + implicit val ctx: GoCodegenContext = origCtx.copy(bindings = origCtx.bindings ++ defs.view.map { + case defn@TLAOperatorDefinition(_, Nil, _, _) => defn -> FixedValueBinding(defnNames(defn)) + case defn@TLAOperatorDefinition(_, _, _, _) => defn -> IndependentCallableBinding(defnNames(defn)) + }) + val origCtx2 = ctx + (defs.view.map { + case defn@TLAOperatorDefinition(_, Nil, body, _) => + d"\nvar ${defnNames(defn)} $TLAValue = ${translateExpr(body)}" + case defn@TLAOperatorDefinition(_, args, body, _) => + val opDeclNames = args.view.map { + case decl@TLAOpDecl(variant) => + variant match { + case TLAOpDecl.NamedVariant(ident, _) => decl -> origCtx2.nameCleaner.cleanName(ident.id) + case TLAOpDecl.SymbolVariant(sym) => decl -> origCtx2.nameCleaner.cleanName(sym.symbol.productPrefix) + } + }.to(IdMap) + implicit val ctx: GoCodegenContext = origCtx2.copy(bindings = origCtx2.bindings ++ args.view.map { + case decl@TLAOpDecl(variant) => + variant match { + case TLAOpDecl.NamedVariant(_, 0) => decl -> FixedValueBinding(opDeclNames(decl)) + case TLAOpDecl.NamedVariant(_, _) => decl -> IndependentCallableBinding(opDeclNames(decl)) + case TLAOpDecl.SymbolVariant(_) => decl -> IndependentCallableBinding(opDeclNames(decl)) + } + }) + d"\n${defnNames(defn)} := func(${args.view.map { opDecl => + if(opDecl.arity == 0) { + d"${opDeclNames(opDecl)} $TLAValue" + } else { + d"${opDeclNames(opDecl)} func(${View.fill(opDecl.arity)(TLAValue.toDescription).flattenDescriptions}) $TLAValue" + } + }.separateBy(d", ")}) $TLAValue {${ + d"\nreturn ${translateExpr(body)}".indented + }\n}" + case _ => !!! + }.flattenDescriptions + d"\nreturn ${translateExpr(body)}").indented + }\n}()" + case TLACase(arms, other) => + d"func() $TLAValue {${ + d"switch {${ + arms.map { + case TLACaseArm(cond, result) => + d"\ncase ${translateExpr(cond)}.IsTrue():" + + d"\nreturn ${translateExpr(result)}".indented + }.flattenDescriptions + + d"\ndefault:" + + other.map(other => d"\nreturn ${translateExpr(other)}") + .getOrElse(d"""\npanic("no cases matched for TLA+ case expression!")""").indented + }\n}" + }\n}()" + case TLAMaybeAction(_, _) => !!! + case TLARequiredAction(_, _) => !!! + case TLAFairness(_, _, _) => !!! + case TLAFunction(args, body) => + ctx.cleanName("args") { argsName => + val origCtx = ctx + d"distsys.NewTLAFunction([]$TLAValue{${args.view.map(_.set).map(translateExpr).separateBy(d", ")}}, func($argsName []$TLAValue) $TLAValue {${ + val argIds = args.view.flatMap { + case TLAQuantifierBound(TLAQuantifierBound.IdsType, List(id), _) => + Some(id -> origCtx.nameCleaner.cleanName(id.id.id)) + case TLAQuantifierBound(TLAQuantifierBound.TupleType, elements, _) => + elements.view.map(id => id -> origCtx.nameCleaner.cleanName(id.id.id)) + }.to(IdMap) + implicit val ctx: GoCodegenContext = origCtx.copy(bindings = origCtx.bindings ++ argIds.map { + case id -> name => id -> FixedValueBinding(name) + }) + (args.view.zipWithIndex.flatMap { + case (TLAQuantifierBound(TLAQuantifierBound.IdsType, List(id), _), idx) => + List(d"\nvar ${argIds(id)} $TLAValue = $argsName[$idx]") + case (TLAQuantifierBound(TLAQuantifierBound.TupleType, elements, _), idx) => + elements.view.zipWithIndex.map { + case (element, elemIdx) => + d"\nvar ${argIds(element)} $TLAValue = $argsName[$idx].FunctionApply(distsys.NewTLANumber($elemIdx))" + } + }.flattenDescriptions + d"\nreturn ${translateExpr(body)}").indented + }\n})" + } + case TLAFunctionCall(function, params) => + d"${translateExpr(function)}.FunctionApply(${ + if(params.size == 1) { + translateExpr(params.head) + } else { + d"distsys.NewTLATuple(${ + params.view.map(translateExpr).separateBy(d", ") + })" + } + })" + case TLAFunctionSet(from, to) => + d"distsys.NewTLAFunctionSet(${translateExpr(from)}, ${translateExpr(to)})" + case TLAFunctionSubstitution(source, substitutions) => ??? + case at@TLAFunctionSubstitutionAt() => + val FixedValueBinding(name) = ctx.bindings(at.refersTo) + name.toDescription + case TLAQuantifiedExistential(bounds, body) => ??? + case TLAQuantifiedUniversal(bounds, body) => ??? + case TLAExistential(_, _) => !!! + case TLAUniversal(_, _) => !!! + case TLASetConstructor(contents) => + d"distsys.NewTLASet(${contents.view.map(translateExpr).separateBy(d", ")})" + case TLASetRefinement(binding, when) => ??? + case TLASetComprehension(body, bounds) => ??? + case TLATuple(elements) => + d"distsys.NewTLATuple(${elements.view.map(translateExpr).separateBy(d", ")})" + case TLARecordConstructor(fields) => + d"distsys.NewTLARecord([]distsys.TLARecordField{${ + fields.view.map { + case TLARecordConstructorField(name, value) => + d"""{"${name.id}", ${translateExpr(value)}}""" + }.separateBy(d", ") + }})" + case TLARecordSet(fields) => + d"distsys.NewTLARecordSet([]distsys.TLARecordField{${ + fields.view.map { + case TLARecordSetField(name, set) => d"""{"${name.id}", ${translateExpr(set)}}""" + }.separateBy(d", ") + }})" + } + @throws[PGoError] - def apply(mpcalBlock: MPCalBlock, packageName: Option[String]): Description = ??? + def apply(tlaModule: TLAModule, mpcalBlock: MPCalBlock, packageName: Option[String]): Description = { + val nameCleaner = new NameCleaner + goKeywords.foreach(nameCleaner.addKnownName) + nameCleaner.addKnownName("distsys") + + val Constants = nameCleaner.cleanName("Constants") + + val tlaExtDefns = (BuiltinModules.Intrinsics.members.view ++ tlaModule.exts.flatMap { + case TLAModuleRefBuiltin(module) => module.members.view + case TLAModuleRefModule(module) => ??? // TODO: actually implement modules + }).toList + + val tlaExtDefnNames = tlaExtDefns.view.map { + case defn@TLABuiltinOperator(_, identifier, _) => + identifier match { + case Definition.ScopeIdentifierName(name) => + defn -> s"distsys.TLA_${name.id}" + case Definition.ScopeIdentifierSymbol(symbol) => + defn -> s"distsys.TLA_${symbol.symbol.productPrefix}" + } + }.to(IdMap) + + val tlaUnits = (tlaModule.units.view.collect { + case defn: TLAOperatorDefinition => defn + } ++ mpcalBlock.units.view).toList + + val tlaUnitNames: IdMap[TLAUnit,String] = tlaUnits.view.map { + case defn@TLAOperatorDefinition(name, _, _, _) => + name match { + case Definition.ScopeIdentifierName(name) => + defn -> nameCleaner.cleanName(toGoPublicName(name.id)) + case Definition.ScopeIdentifierSymbol(symbol) => + defn -> nameCleaner.cleanName(toGoPublicName(symbol.symbol.productPrefix)) + } + }.to(IdMap) + + val constantDecls = tlaModule.units.view.collect { + case TLAConstantDeclaration(constants) => constants + }.flatten.toList + + // depends on the "constants" parameter, has to be scoped _within_ any top-level definition + val constantNames = constantDecls.view.map { + case decl@TLAOpDecl(variant) => + variant match { + case TLAOpDecl.NamedVariant(ident, _) => decl -> nameCleaner.cleanName(toGoPublicName(ident.id)) + case TLAOpDecl.SymbolVariant(sym) => decl -> nameCleaner.cleanName(toGoPublicName(sym.symbol.productPrefix)) + } + }.to(IdMap) + + implicit val ctx: GoCodegenContext = GoCodegenContext( + nameCleaner = nameCleaner, + bindings = (mpcalBlock.mpcalProcedures.view.map { proc => + proc -> IndependentCallableBinding(nameCleaner.cleanName(toGoPublicName(proc.name.id))) + } ++ mpcalBlock.archetypes.view.map { arch => + arch -> IndependentCallableBinding(nameCleaner.cleanName(toGoPublicName(arch.name.id))) + } ++ tlaExtDefnNames.map { + case defn -> name => defn -> IndependentCallableBinding(name) + } ++ tlaUnits.view.map { defn => + defn.asInstanceOf[RefersTo.HasReferences] -> DependentCallableBinding(tlaUnitNames(defn)) + }).to(IdMap) + ) + + d"package ${packageName.getOrElse(mpcalBlock.name.id.toLowerCase(Locale.ROOT)): String}\n" + + d"""\nimport "github.com/UBC-NSS/pgo/distsys"\n""" + + d"\ntype $Constants struct {${ + constantDecls.map { + case decl@TLAOpDecl(variant) => + variant match { + case TLAOpDecl.NamedVariant(_, 0) => + d"\n${constantNames(decl)} $TLAValue" + case TLAOpDecl.NamedVariant(_, arity) => + d"\n${constantNames(decl)} func(${View.fill(arity)(TLAValue.toDescription).separateBy(d", ")} $TLAValue" + case TLAOpDecl.SymbolVariant(sym) => + val arity = if (sym.symbol.isPrefix) 1 else if (sym.symbol.isPostfix) 1 else { assert(sym.symbol.isInfix); 2 } + d"\n${constantNames(decl)} func(${View.fill(arity)(TLAValue.toDescription).separateBy(d", ")} $TLAValue" + } + }.flattenDescriptions.indented + }\n}\n" + + tlaUnits.view.map { + case defn@TLAOperatorDefinition(name, args, body, _) => + ctx.cleanName("constants") { constants => + val origCtx = ctx + val argNames = args.view.map { + case decl@TLAOpDecl(variant) => + variant match { + case TLAOpDecl.NamedVariant(ident, 0) => + decl -> FixedValueBinding(nameCleaner.cleanName(ident.id)) + case TLAOpDecl.NamedVariant(ident, _) => + decl -> IndependentCallableBinding(nameCleaner.cleanName(ident.id)) + case TLAOpDecl.SymbolVariant(sym) => + decl -> IndependentCallableBinding(nameCleaner.cleanName(sym.symbol.productPrefix)) + } + }.to(IdMap) + d"\nfunc ${tlaUnitNames(defn)}($constants $Constants${args.view.map { + case decl@TLAOpDecl(variant) => + variant match { + case TLAOpDecl.NamedVariant(_, 0) => d", ${argNames(decl).bind} $TLAValue" + case TLAOpDecl.NamedVariant(_, arity) => d", ${argNames(decl).bind} func(${View.fill(arity)(TLAValue.toDescription).separateBy(d", ")}) $TLAValue" + case TLAOpDecl.SymbolVariant(sym) => + val arity = if(sym.symbol.isInfix) 2 else 1 + d", ${argNames(decl).bind} func(${View.fill(arity)(TLAValue.toDescription).separateBy(d", ")}) $TLAValue" + } + }.flattenDescriptions}) $TLAValue {${ + implicit val ctx: GoCodegenContext = origCtx.copy(bindings = origCtx.bindings ++ argNames ++ constantDecls.view.map { + case decl@TLAOpDecl(variant) => + variant match { + case TLAOpDecl.NamedVariant(_, 0) => decl -> FixedValueBinding(s"$constants.${constantNames(decl)}") + case TLAOpDecl.NamedVariant(_, _) => decl -> IndependentCallableBinding(s"$constants.${constantNames(decl)}") + case TLAOpDecl.SymbolVariant(_) => decl -> IndependentCallableBinding(s"$constants.${constantNames(decl)}") + } + }) + d"\nreturn ${translateExpr(body)}".indented + }\n}\n" + } + }.flattenDescriptions + + mpcalBlock.mpcalProcedures.view.map { proc => + val origCtx = ctx + ctx.cleanName("constants") { constants => + val paramNames = proc.params.view.map { + case param@MPCalRefParam(name, _) => param -> nameCleaner.cleanName(name.id) + case param@MPCalValParam(name) => param -> nameCleaner.cleanName(name.id) + }.to(IdMap) + val paramLocalNames = proc.params.view.collect { + case param@MPCalValParam(name) => param -> nameCleaner.cleanName(name.id) + }.to(IdMap) + val varNames = proc.variables.view.map { + case decl@PCalPVariableDeclaration(name, _) => decl -> nameCleaner.cleanName(name.id) + }.to(IdMap) + + implicit val ctx: GoCodegenContext = origCtx.copy( + bindings = origCtx.bindings ++ + paramNames.collect { case (param: MPCalRefParam) -> name => param -> ResourceBinding(name) } ++ + paramLocalNames.view.map { case param -> name => param -> ResourceBinding(name) } ++ + varNames.view.map { case v -> name => v -> ResourceBinding(name) } ++ + constantDecls.view.map { + case decl@TLAOpDecl(variant) => + variant match { + case TLAOpDecl.NamedVariant(_, 0) => decl -> FixedValueBinding(s"$constants.${constantNames(decl)}") + case TLAOpDecl.NamedVariant(_, _) => decl -> IndependentCallableBinding(s"$constants.${constantNames(decl)}") + case TLAOpDecl.SymbolVariant(_) => decl -> IndependentCallableBinding(s"$constants.${constantNames(decl)}") + } + }, + resourceMappingCounts = proc.params.view.collect { + case param@MPCalRefParam(_, mappingCount) => param -> mappingCount + }.to(IdMap), + ) + d"\nfunc ${ctx.bindings(proc).bind}($constants $Constants${ + proc.params.view.map { + case param: MPCalRefParam => d", ${paramNames(param)} $ArchetypeResource" + case param: MPCalValParam => d", ${paramNames(param)} $TLAValue" + }.flattenDescriptions + }) error {${ + (proc.params.view.collect { + case param: MPCalValParam => + d"\nvar ${paramLocalNames(param)} $ArchetypeResource = distsys.NewLocalArchetypeResource(${paramNames(param)})" + }.flattenDescriptions + + proc.variables.view.map { + case decl@PCalPVariableDeclaration(_, valueOpt) => + d"\nvar ${varNames(decl)} $TLAValue${valueOpt.map(value => d" = ${translateExpr(value)}").getOrElse(d"")}" + }.flattenDescriptions + + translateBody(proc.body)).indented + }\n}\n" + } + }.flattenDescriptions + + mpcalBlock.archetypes.view.map { arch => + val origCtx = ctx + ctx.cleanName("self") { self => + ctx.cleanName("constants") { constants => + val paramNames = arch.params.view.map { + case param@MPCalRefParam(name, _) => param -> nameCleaner.cleanName(name.id) + case param@MPCalValParam(name) => param -> nameCleaner.cleanName(name.id) + }.to(IdMap) + val paramLocalNames = arch.params.view.collect { + case param@MPCalValParam(name) => param -> nameCleaner.cleanName(name.id) + }.to(IdMap) + val varNames = arch.variables.view.map { decl => + decl -> nameCleaner.cleanName(decl.name.id) + }.to(IdMap) + + implicit val ctx: GoCodegenContext = origCtx.copy( + bindings = origCtx.bindings ++ + List(arch.selfDecl -> FixedValueBinding(self)) ++ + paramNames.collect { case (param: MPCalRefParam) -> name => param -> ResourceBinding(name) } ++ + paramLocalNames.view.map { case param -> name => param -> ResourceBinding(name) } ++ + varNames.view.map { case v -> name => v -> ResourceBinding(name) } ++ + constantDecls.view.map { + case decl@TLAOpDecl(variant) => + variant match { + case TLAOpDecl.NamedVariant(_, 0) => decl -> FixedValueBinding(s"$constants.${constantNames(decl)}") + case TLAOpDecl.NamedVariant(_, _) => decl -> IndependentCallableBinding(s"$constants.${constantNames(decl)}") + case TLAOpDecl.SymbolVariant(_) => decl -> IndependentCallableBinding(s"$constants.${constantNames(decl)}") + } + }, + resourceMappingCounts = arch.params.view.collect { + case param@MPCalRefParam(_, mappingCount) => param -> mappingCount + }.to(IdMap), + ) + + d"\nfunc ${ctx.bindings(arch).bind}($self $TLAValue, $constants $Constants${ + arch.params.view.map { + case param@MPCalRefParam(_, _) => d", ${paramNames(param)} $ArchetypeResource" + case param@MPCalValParam(_) => d", ${paramNames(param)} $TLAValue" + }.flattenDescriptions + }) error {${ + (arch.params.view.collect { + case param: MPCalValParam => + d"\nvar ${paramLocalNames(param)} $ArchetypeResource = distsys.NewLocalArchetypeResource(${paramNames(param)})" + }.flattenDescriptions + + arch.variables.view.map { + case decl@PCalVariableDeclarationEmpty(_) => + d"\nvar ${varNames(decl)} $ArchetypeResource = distsys.NewLocalArchetypeResource($TLAValue{})" + case decl@PCalVariableDeclarationSet(_, set) => + d"\nvar ${varNames(decl)} $ArchetypeResource = distsys.NewLocalArchetypeResource(${translateExpr(set)}.SelectElement())" + case decl@PCalVariableDeclarationValue(_, value) => + d"\nvar ${varNames(decl)} $ArchetypeResource = distsys.NewLocalArchetypeResource(${translateExpr(value)})" + }.flattenDescriptions + + translateBody(arch.body)).indented + }\n}\n" + } + } + }.flattenDescriptions + } } diff --git a/src/pgo/trans/MPCalPCalCodegenPass.scala b/src/pgo/trans/MPCalPCalCodegenPass.scala index a63cb2139..a01d51ff7 100644 --- a/src/pgo/trans/MPCalPCalCodegenPass.scala +++ b/src/pgo/trans/MPCalPCalCodegenPass.scala @@ -4,6 +4,7 @@ import pgo.model.{Definition, DefinitionOne, PGoError, RefersTo, Rewritable, Vis import pgo.model.mpcal._ import pgo.model.pcal._ import pgo.model.tla._ +import pgo.util.MPCalPassUtils.MappedRead import pgo.util.Unreachable.!!! import pgo.util.{IdMap, NameCleaner} @@ -12,10 +13,13 @@ import scala.collection.mutable object MPCalPCalCodegenPass { @throws[PGoError] - def apply(mpcalBlock: MPCalBlock): PCalAlgorithm = { + def apply(tlaModule: TLAModule, mpcalBlock: MPCalBlock): PCalAlgorithm = { var block: MPCalBlock = mpcalBlock val nameCleaner = new NameCleaner + tlaModule.visit(Visitable.BottomUpFirstStrategy) { + case TLAIdentifier(id) => nameCleaner.addKnownName(id) + } block.visit(Visitable.BottomUpFirstStrategy) { case TLAIdentifier(id) => nameCleaner.addKnownName(id) } @@ -38,20 +42,6 @@ object MPCalPCalCodegenPass { // - for a non-ref [_] param, the identity of the mapping to be applied (but not the identity of what is referenced, as it is taken by-value) val mpcalProcedureCache = mutable.HashMap[List[TLAExpression],PCalProcedure]() - object MappedRead { - @tailrec - private def unapplyImpl(expr: TLAExpression, mappingCount: Int): Option[(Int,TLAGeneralIdentifier)] = - expr match { - case TLAFunctionCall(fn, _) => - unapplyImpl(fn, mappingCount + 1) - case ident: TLAGeneralIdentifier => Some((mappingCount, ident)) - case _ => None - } - - def unapply(expr: TLAExpression): Option[(Int,TLAGeneralIdentifier)] = - unapplyImpl(expr, mappingCount = 0) - } - def updateStmt(stmt: PCalStatement)(implicit mappingsMap: IdMap[DefinitionOne,(Int,MPCalMappingMacro)], substitutions: IdMap[RefersTo.HasReferences,DefinitionOne]): List[PCalStatement] = { var stmtSink: List[PCalStatement] => List[PCalStatement] = identity @@ -212,9 +202,6 @@ object MPCalPCalCodegenPass { (arguments.iterator zip archetype.params).foreach { case Left(arg @MPCalRefExpr(_, _)) -> param => substitutionsBuilder += param -> arg.refersTo - case Left(arg @MPCalValExpr(_, _)) -> param => - variables += PCalVariableDeclarationValue(param.name, TLAGeneralIdentifier(arg.name, Nil).setRefersTo(arg.refersTo)) - substitutionsBuilder += param -> variables.last case Right(expr) -> param => variables += PCalVariableDeclarationValue(param.name, expr) substitutionsBuilder += param -> variables.last @@ -416,14 +403,14 @@ object MPCalPCalCodegenPass { case PCalWith(bindings, body) => // push the remaining statements inside the body, so lifted assignments are guaranteed to be in scope // for the entire critical section. to avoid name collisions, conservatively rename all bindings to fresh names - val renamedbBindings = bindings.map { + val renamedBindings = bindings.map { case PCalVariableDeclarationValue(name, value) => PCalVariableDeclarationValue(TLAIdentifier(nameCleaner.cleanName(name.id)), value) case PCalVariableDeclarationSet(name, set) => PCalVariableDeclarationSet(TLAIdentifier(nameCleaner.cleanName(name.id)), set) } - List(PCalWith(renamedbBindings, - impl(body ::: tl, substitutions ++ (bindings.iterator zip renamedbBindings), lifted))) + List(PCalWith(renamedBindings, + impl(body ::: tl, substitutions ++ (bindings.iterator zip renamedBindings), lifted))) case PCalIf(cond, yes, no) => List(PCalIf( cond, diff --git a/src/pgo/trans/MPCalSemanticCheckPass.scala b/src/pgo/trans/MPCalSemanticCheckPass.scala index aa89b12b3..f99afaaa1 100644 --- a/src/pgo/trans/MPCalSemanticCheckPass.scala +++ b/src/pgo/trans/MPCalSemanticCheckPass.scala @@ -1,11 +1,10 @@ package pgo.trans -import pgo.model.{DefinitionOne, PGoError, SourceLocatable, SourceLocation, Visitable} +import pgo.model.{DefinitionOne, PGoError, RefersTo, SourceLocatable, SourceLocation, Visitable} import pgo.model.mpcal._ import pgo.model.pcal._ import pgo.model.tla._ import pgo.util.{Description, IdMap, IdSet, MPCalPassUtils} - import Description._ import scala.annotation.tailrec @@ -42,6 +41,11 @@ object MPCalSemanticCheckPass { usage.sourceLocation, d"reference to kinded definition at ${ defn.sourceLocation.longDescription }\n does not match") + + final case class PClArityMismatch(usage: SourceLocatable, defn: SourceLocatable) extends Error( + usage.sourceLocation, d"call arity at ${ + defn.sourceLocation.longDescription + }\n does not match") } @throws[PGoError] @@ -285,13 +289,26 @@ object MPCalSemanticCheckPass { MPCalPassUtils.forEachBody(mpcalBlock)((body, _) => checkInBody(body)) } + // for each PCal procedure call, the argument count must match parameter count at the definition + locally { + mpcalBlock.visit(Visitable.TopDownFirstStrategy) { + case call@PCalCall(_, arguments) => + if(call.refersTo.params.size != arguments.size) { + errors += SemanticError.PClArityMismatch(usage = call, defn = call.refersTo) + } + } + } + // enforce kind-matching for MPCal params (ref vs. non-ref, number of mappings) locally { def checkMPCalParamRefs(body: List[PCalStatement], params: List[MPCalParam]): Unit = { val paramsMap = params.view.map(p => (p: DefinitionOne) -> p).to(IdMap) body.foreach { stmt => - stmt.visit(Visitable.BottomUpFirstStrategy) { - case PCalAssignmentPair(lhs, _) => + lazy val impl: PartialFunction[Visitable,Unit] = { + case PCalAssignmentPair(lhs, rhs) => + // make sure to actually process assignment RHS + rhs.visit(Visitable.TopDownFirstStrategy)(impl) + @tailrec def findMappingCount(lhs: PCalAssignmentLhs, acc: Int = 0): Int = lhs match { @@ -300,11 +317,11 @@ object MPCalSemanticCheckPass { } @tailrec - def findDefn(lhs: PCalAssignmentLhs): Option[MPCalParam] = + def findDefn(lhs: PCalAssignmentLhs): Option[MPCalRefParam] = lhs match { case lhs @PCalAssignmentLhsIdentifier(_) => lhs.refersTo match { - case p: MPCalParam => Some(p) + case p: MPCalRefParam => Some(p) case _ => None } case PCalAssignmentLhsProjection(lhs, _) => findDefn(lhs) @@ -317,27 +334,38 @@ object MPCalSemanticCheckPass { errors += SemanticError.MPCalKindMismatchError(usage = lhs, defn = defn) } } - case ref @MPCalValExpr(_, mappingCount) => - paramsMap(ref.refersTo) match { - case defn @ MPCalRefParam(_, mappingCountP) => - if(mappingCountP > mappingCount) { - errors += SemanticError.MPCalKindMismatchError(usage = ref, defn = defn) - } - case defn @MPCalValParam(_, mappingCountP) => - if(mappingCountP > mappingCount) { - errors += SemanticError.MPCalKindMismatchError(usage = ref, defn = defn) - } - } case ref @MPCalRefExpr(_, mappingCount) => paramsMap(ref.refersTo) match { case defn @ MPCalRefParam(_, mappingCountP) => if(mappingCountP > mappingCount) { errors += SemanticError.MPCalKindMismatchError(usage = ref, defn = defn) } - case defn @MPCalValParam(_, _) => - errors += SemanticError.MPCalKindMismatchError(usage = ref, defn = defn) + case _: MPCalValParam => // pass; always OK } + case expr@MPCalPassUtils.MappedRead(mappingCount, ident) if (paramsMap.get(ident.refersTo) match { + case Some(MPCalRefParam(_, mappingCountP)) => mappingCount >= mappingCountP + case Some(MPCalValParam(_)) => true // it's a value, anything goes + case _ => false + }) => + // if this is reached, we found an appropriate expression-level usage of a function-mapped param. + // however, we may have missed issues in argument-position for the involved function applications + // so we explicitly recurse over the arguments, knowing our expression can only be function applications + // and idents + @tailrec + def checkMappingArgs(expr: TLAExpression): Unit = + expr match { + case TLAGeneralIdentifier(_, Nil) => + case TLAFunctionCall(function, params) => + params.foreach(_.visit(Visitable.TopDownFirstStrategy)(impl)) + checkMappingArgs(function) + } + + checkMappingArgs(expr) + case ref: RefersTo[DefinitionOne @unchecked] with SourceLocatable if ref.refersTo.isInstanceOf[DefinitionOne] && paramsMap.contains(ref.refersTo) => + errors += SemanticError.MPCalKindMismatchError(usage = ref, defn = paramsMap(ref.refersTo)) } + + stmt.visit(Visitable.TopDownFirstStrategy)(impl) } } @@ -349,32 +377,51 @@ object MPCalSemanticCheckPass { case instance @MPCalInstance(_, _, _, arguments, mappings) => val archetype = instance.refersTo mappings.foreach { - case MPCalMapping(target @MPCalMappingTarget(position, mappingCount), id) => + case MPCalMapping(target @MPCalMappingTarget(position, mappingCount), _) => arguments(position) match { - case Left(param) => param match { - case MPCalRefExpr(_, mappingCountP) => - if(mappingCount < mappingCountP) { - errors += SemanticError.MPCalKindMismatchError(usage = target, defn = param) - } - case MPCalValExpr(_, mappingCountP) => - if(mappingCount < mappingCountP) { - errors += SemanticError.MPCalKindMismatchError(usage = target, defn = param) - } - } - case Right(_) => // any mappings work here, we'll add an underlying variable if we have to; TODO: is this true? + case Left(param@MPCalRefExpr(_, mappingCountP)) => + if(mappingCount != mappingCountP) { + errors += SemanticError.MPCalKindMismatchError(usage = target, defn = param) + } + case Right(_) => // any mappings work here, we'll add an underlying variable if we have to } } (archetype.params.view zip arguments.view).foreach { case (MPCalRefParam(_, mappingCountP), Left(MPCalRefExpr(_, mappingCount))) if mappingCount == mappingCountP => // ok - case (MPCalRefParam(_, 0), Right(_)) => // ok (see TODO above..?) - case (MPCalValParam(_, 0), Right(_)) => // ok - case (MPCalValParam(_, mappingCountP), Left(MPCalValExpr(_, mappingCount))) if mappingCount == mappingCountP => // ok + case (MPCalRefParam(_, 0), Right(_)) => // ok, we'll add an underlying variable if we have to case (param, Left(arg)) => errors += SemanticError.MPCalKindMismatchError(usage = arg, defn = param) case (param, Right(arg)) => errors += SemanticError.MPCalKindMismatchError(usage = arg, defn = param) } } + + def checkMPCalParamUsage(arguments: List[Either[MPCalRefExpr,TLAExpression]], params: List[MPCalParam]): Unit = + (arguments.view zip params.view).foreach { + case (Left(MPCalRefExpr(_, mappingCount)), MPCalRefParam(_, mappingCountP)) if mappingCount == mappingCountP => // ok + case (Right(_: TLAExpression), MPCalValParam(_)) => // ok + case (eitherArg, param) => + val arg: SourceLocatable = eitherArg match { + case Left(value) => value + case Right(value) => value + } + errors += SemanticError.MPCalKindMismatchError(usage = arg, defn = param) + } + + mpcalBlock.visit(Visitable.TopDownFirstStrategy) { + case instance@MPCalInstance(_, _, _, arguments, _) => + if(instance.refersTo.params.size != arguments.size) { + errors += SemanticError.PClArityMismatch(usage = instance, defn = instance.refersTo) + } else { + checkMPCalParamUsage(arguments, instance.refersTo.params) + } + case PCalExtensionStatement(call@MPCalCall(_, arguments)) => + if(call.refersTo.params.size != arguments.size) { + errors += SemanticError.PClArityMismatch(usage = call, defn = call.refersTo) + } else { + checkMPCalParamUsage(arguments, call.refersTo.params) + } + } } if(errors.nonEmpty) { diff --git a/src/pgo/trans/PCalRenderPass.scala b/src/pgo/trans/PCalRenderPass.scala index e1d457363..2258976af 100644 --- a/src/pgo/trans/PCalRenderPass.scala +++ b/src/pgo/trans/PCalRenderPass.scala @@ -235,13 +235,10 @@ object PCalRenderPass { def describeStatement(stmt: PCalStatement): Description = stmt match { case PCalExtensionStatement(MPCalCall(target, arguments)) => - d"call $target(${ + d"call ${target.id}(${ arguments.view.map { - case Left(pExp: MPCalParamExpr) => - pExp match { - case MPCalRefExpr(name, mappingCount) => d"ref ${name.id}${View.fill(mappingCount)(d"[_]").flattenDescriptions}" - case MPCalValExpr(name, mappingCount) => d"${name.id}${View.fill(mappingCount)(d"[_]").flattenDescriptions}" - } + case Left(MPCalRefExpr(name, mappingCount)) => + d"ref ${name.id}${View.fill(mappingCount)(d"[_]").flattenDescriptions}" case Right(expr) => describeExpr(expr) }.separateBy(d", ") })" @@ -371,7 +368,7 @@ object PCalRenderPass { d"variables${ variables.view.map { case PCalPVariableDeclaration(name, value) => - d" ${name.id}${value.map(v => d" = ${describeExpr(v)};")}" + d" ${name.id}${value.map(v => d" = ${describeExpr(v)};").getOrElse(d"")}" }.flattenDescriptions }" } else d"" diff --git a/src/pgo/util/Description.scala b/src/pgo/util/Description.scala index 12c68333c..e02210a82 100644 --- a/src/pgo/util/Description.scala +++ b/src/pgo/util/Description.scala @@ -10,7 +10,12 @@ private case object DescriptionDedentPart extends DescriptionPart private final case class DescriptionStringPart(str: String) extends DescriptionPart private final case class DescriptionEmbedPart(embed: Any) extends DescriptionPart -final class Description private (private val parts: View[DescriptionPart]) { +final class Description private (private val parts: View[DescriptionPart]) extends Description.Describable { + def +(other: Description): Description = + new Description(parts ++ other.parts) + + override def description: Description = this + def indented: Description = new Description(View(DescriptionIndentPart) ++ parts ++ View(DescriptionDedentPart)) @@ -105,6 +110,22 @@ object Description { partsBuffer.result().view } + abstract class Describable { + def description: Description + } + + implicit class DescribableDescriptions(descriptions: Iterable[Description]) extends Describable { + override def description: Description = descriptions.flattenDescriptions + } + + implicit class DescribableString(str: String) extends Describable { + override def description: Description = str.toDescription + } + + implicit class DescribableNumber[T : Numeric](num: T) extends Describable { + override def description: Description = num.toString.toDescription + } + implicit class IterableFlattenDescriptions(val descList: Iterable[Description]) extends AnyVal { def flattenDescriptions: Description = new Description(descList.view.flatMap(_.parts)) @@ -125,32 +146,28 @@ object Description { } implicit class DescriptionHelper(val ctx: StringContext) extends AnyVal { - private def mkDesc(parts: Seq[String], args: Seq[Any]): Description = { + private def mkDesc(args: Seq[Describable]): Description = { val parts = Description.stringToDescriptionParts(StringContext.processEscapes(ctx.parts.head)) ++ (args.view zip ctx.parts.view.tail).flatMap { case (arg, part) => - (arg match { - case arg: Description => arg.parts - case str: String => Description.stringToDescriptionParts(str) - case any => View(DescriptionEmbedPart(any)) - }) ++ Description.stringToDescriptionParts(StringContext.processEscapes(part)) + arg.description.parts ++ Description.stringToDescriptionParts(StringContext.processEscapes(part)) } new Description(parts) } - def d(args: Any*): Description = mkDesc(ctx.parts, args) - - def dd(args: Any*): Description = { - var foundPipe = false - val mappedParts = ctx.parts.map { part => - StringContext.processEscapes(part).flatMap { - case '\n' => foundPipe = false; "\n" - case _ if !foundPipe => "" - case '|' => foundPipe = true; "" - case ch => ch.toString - } - } - mkDesc(mappedParts, args) - } + def d(args: Describable*): Description = mkDesc(args) + +// def dd(args: Any*): Description = { +// var foundPipe = false +// val mappedParts = ctx.parts.map { part => +// StringContext.processEscapes(part).flatMap { +// case '\n' => foundPipe = false; "\n" +// case _ if !foundPipe => "" +// case '|' => foundPipe = true; "" +// case ch => ch.toString +// } +// } +// mkDesc(mappedParts, args) +// } } } diff --git a/src/pgo/util/MPCalPassUtils.scala b/src/pgo/util/MPCalPassUtils.scala index 3bf770937..64329d7ed 100644 --- a/src/pgo/util/MPCalPassUtils.scala +++ b/src/pgo/util/MPCalPassUtils.scala @@ -6,6 +6,7 @@ import pgo.model.pcal._ import pgo.model.tla._ import Description._ +import scala.annotation.tailrec import scala.collection.mutable object MPCalPassUtils { @@ -190,4 +191,18 @@ object MPCalPassUtils { containsLabels } + + object MappedRead { + @tailrec + private def unapplyImpl(expr: TLAExpression, mappingCount: Int): Option[(Int,TLAGeneralIdentifier)] = + expr match { + case TLAFunctionCall(fn, _) => + unapplyImpl(fn, mappingCount + 1) + case ident: TLAGeneralIdentifier => Some((mappingCount, ident)) + case _ => None + } + + def unapply(expr: TLAExpression): Option[(Int,TLAGeneralIdentifier)] = + unapplyImpl(expr, mappingCount = 0) + } } diff --git a/src/runtime/pgo/distsys/archetypes.go b/src/runtime/pgo/distsys/archetypes.go deleted file mode 100644 index 324ac46aa..000000000 --- a/src/runtime/pgo/distsys/archetypes.go +++ /dev/null @@ -1,1296 +0,0 @@ -package distsys - -import ( - "fmt" - "io/ioutil" - "net/rpc" - "os" - "path" - "reflect" - "sort" - "strconv" - "strings" - "sync" - "sync/atomic" - "time" -) - -// ResourceAccess indicates what type of access the a caller is requesting. -type ResourceAccess int - -// ResourceInternalError represents errros that happen when -// interacting with an archetype resource. When a -// ResourceInternalError is returned by a call to Acquire(), Read(), -// Write() or Release(), the error is propagated back to the caller. -type ResourceInternalError struct { - cause string -} - -func (err *ResourceInternalError) Error() string { - return fmt.Sprintf("Internal error: %s", err.cause) -} - -// AbortRetryError represents the situation where a failure has -// occurrred that prevents the system from making progress. The atomic -// step should be rolleback and tried again. If this error is returned -// by a call to Acquire(), Read() or Write(), the action will be -// retried. -type AbortRetryError struct { - cause string -} - -func (err *AbortRetryError) Error() string { - return fmt.Sprintf("Abort and retry: %s", err.cause) -} - -const ( - READ_ACCESS = iota + 1 - WRITE_ACCESS - - LOCK_NUM_RETRIES = 10 - LOCK_WAIT = 20 // ms - - RPC_SUCCESS = iota - MAILBOX_IS_FULL_ERROR -) - -// priorities associated with each archetype resource implementation. -// Used to ensure acquisition happens in consistent order -var ( - priorityCounter uint64 - priorityMap map[reflect.Type]uint64 -) - -func init() { - atomic.StoreUint64(&priorityCounter, 0) - priorityMap = map[reflect.Type]uint64{} - - // Register resources provided by the runtime - RegisterResource(&GlobalVariable{}) - RegisterResource(&Mailbox{}) - RegisterResource(&LocalChannelResource{}) - RegisterResource(&FileResource{}) - RegisterResource(&ImmutableResource{}) - RegisterResource(&LocallySharedResource{}) - RegisterResource(&AtomicInteger{}) - RegisterResource(&SleepResource{}) -} - -// RegisterResource assigns a priority to the type of the resource -// passed. Calling this function more than once for the same resource -// type is an error. -func RegisterResource(resource interface{}) { - resourceType := reflect.TypeOf(resource).Elem() - - if _, exists := priorityMap[resourceType]; exists { - panic(fmt.Sprintf("Resource type already registered: %T", resource)) - } - - priorityMap[reflect.TypeOf(resource).Elem()] = atomic.AddUint64(&priorityCounter, 1) -} - -// newLock creates a new synchronization lock based on Go channels. -func newLock() chan int { - ch := make(chan int, 1) - ch <- 0 // lock starts out unlocked - - return ch -} - -// tryLock attempts to get access to a lock. Attempt is tried -// LOCK_NUM_RETRIES waiting LOCK_WAIT milliseconds between each -// attempt. Returns a boolean indicating whether access was -// acquired or not. -func tryLock(lock <-chan int) bool { - for i := 0; i < LOCK_NUM_RETRIES; i++ { - select { - case <-lock: - return true - - default: - time.Sleep(time.Duration(LOCK_WAIT) * time.Millisecond) - } - } - - return false -} - -// releaseLock releases a previously acquired lock (with -// tryLock). Panics if the lock is not currently locked. -func releaseLock(lock chan<- int) { - select { - case lock <- 0: - return - default: - // fmt.Printf("Warning: Attempt to release unlocked lock\n") - // panic("Attempt to release unlocked lock") - } -} - -// ArchetypeResource defines the interface that parameters passed to functions -// derived from Modular PlusCal's archetypes must implement. -type ArchetypeResource interface { - // Acquire attempts to get access to a resource with read and/or write - // permissions. Returns a boolean indicating whether it was successful. - Acquire(access ResourceAccess) error - - // Read returns the current value associated with a resource. - // Resource needs to have been acquired first. - Read() (interface{}, error) - - // Write receives a new value that the underlying resource is - // supposed to be set to. - Write(value interface{}) error - - // Release causes the calling process to cease having access to the - // shared resource. Any written changes to the underlying values - // are committed. - Release() error - - // Abort indicates an error situation. Access must be released, - // and any state changed while the resource was accquired is - // rolled back to its previous value, before acquisition - Abort() error - - // Less compares one archetype resource with another. Since - // archetype resources are ordered based on priority, Less() is - // only invoked to determine how to order two different resources - // of the same priority. For that reason it is safe to cast - // the `other` argument to the concrete implementation of this - // interface when implementing Less. - Less(other ArchetypeResource) bool -} - -// ArchetypeResourceCollection represents archetype resources that are -// mapped via function calls in Modular PlusCal. Instead of using -// regular indexing operations, the Get allows implementations to -// provide custom archetype resources that depend on the value being -// indexed. -type ArchetypeResourceCollection interface { - // Get receives as input the value being indexed on, and returns - // the corresponding archetype resource. Note that different - // implementations have specific requirements for the type of - // `value`. - // - // Note that the resource returned by Get() must either be - // stateless *or* Get() must return the same resource when called - // with the same `value` argument - Get(value interface{}) ArchetypeResource -} - -// SortableArchetypeResource represents a collection of archetype -// resources. This type implements the functions necessary to enable -// a collection of archetype resources to be sorted using Go's -// `sort.Sort` utility. -type SortableArchetypeResource []ArchetypeResource - -func (s SortableArchetypeResource) Len() int { - return len(s) -} - -// Sorting occurs in-place. -func (s SortableArchetypeResource) Swap(i, j int) { - s[i], s[j] = s[j], s[i] -} - -func (s SortableArchetypeResource) Less(i, j int) bool { - // if the resource was not registered, panic - typeI := reflect.TypeOf(s[i]).Elem() - if _, exists := priorityMap[typeI]; !exists { - panic(fmt.Sprintf("Resource type not registered: %T", s[i])) - } - - typeJ := reflect.TypeOf(s[j]).Elem() - if _, exists := priorityMap[typeJ]; !exists { - panic(fmt.Sprintf("Resource type not registered: %T", s[j])) - } - - prioI := priorityMap[typeI] - prioJ := priorityMap[typeJ] - - // if the priorities are different, return the one with lowest - // priority - if prioI != prioJ { - return prioI < prioJ - } - - // same priority: do type-specific comparison - return s[i].Less(s[j]) -} - -// AcquireResources acquires a series of resources (concrete -// implementations of the `ArchetypeResource` interface) and returns -// an error in case one of the resources cannot be acquired. This -// function makes sure that resources are acquired in proper order -// (i.e., according to the resource's implementation of `Less`). -func AcquireResources(access ResourceAccess, resources ...ArchetypeResource) error { - // sort the resources to be acquired according to their - // implementation of `Less` - sort.Sort(SortableArchetypeResource(resources)) - numAcquired := 0 - - // resources are now ordered - for _, r := range resources { - err := r.Acquire(access) - - // if there is an error acquiring one of the resources, abort access - // to all of the previously acquired resources and return the error - if err != nil { - for i := 0; i < numAcquired; i++ { - resources[i].Abort() - } - - return err - } - - numAcquired++ - } - - return nil -} - -// ReleaseResources releases a collection of archetype resources -// simultaneously. If the values associated with these archetypes were -// updated (via Write calls on the archetypes), this will make the -// changes visible (committed). It makes sure that resources are -// released according to the order defined by the resource's -// implementation of `Less`. -func ReleaseResources(resources ...ArchetypeResource) error { - sort.Sort(SortableArchetypeResource(resources)) - numAcquired := 0 - var err error - - for _, r := range resources { - err = r.Release() - - // if there is an error releasing one of the resources, abort all - // subsequent resources and return the error - if err != nil { - for i := numAcquired; i < len(resources); i++ { - resources[i].Abort() - } - } - - numAcquired++ - } - - return err -} - -// AbortResources releases (without modification) a collection of -// archetype resources simulaneously. It makes sure that resources are -// released according to the order defined by the resource's -// implementation of `Less`. -func AbortResources(resources ...ArchetypeResource) error { - sort.Sort(SortableArchetypeResource(resources)) - - for _, r := range resources { - if err := r.Abort(); err != nil { - return err - } - } - - return nil -} - -//////////////////////////////////////////////// -//// ARCHETYPE RESOURCES //// -//////////////////////////////////////////////// - -// Global State as Archetype Resource -// ---------------------------------- - -// Global variable is one type of archetype resource. It is backed by the -// StateServer implementation in this package. -type GlobalVariable struct { - name string - stateServer *StateServer - refs VarReferences - writtenValue interface{} -} - -// Variable is a convenience function to create a GlobalVariable struct from -// a previously configured StateServer. The returned GlobalVariable can be -// passed to archetypes, and the state represented by this variable will be -// managed by all peers in the system. -func (ss *StateServer) Variable(name string) *GlobalVariable { - return &GlobalVariable{ - name: name, - stateServer: ss, - refs: nil, - writtenValue: nil, - } -} - -// Acquire wraps the underlying StateServer struct, creating a proper BorrowSpec -// and attempting to borrow the value from this node's peers in the network. -func (v *GlobalVariable) Acquire(access ResourceAccess) error { - if v.refs != nil { - return &ResourceInternalError{fmt.Sprintf("variable %s already acquired", v.name)} - } - - var spec BorrowSpec - - if access&READ_ACCESS != 0 { - spec.ReadNames = []string{v.name} - } - - if access&WRITE_ACCESS != 0 { - spec.WriteNames = []string{v.name} - } - - refs, err := v.stateServer.Acquire(&spec) - if err != nil { - return &ResourceInternalError{err.Error()} - } - - v.refs = refs - return nil -} - -// Read returns the value associated with a global variable. It *must* -// have been acquired before. -func (v *GlobalVariable) Read() (interface{}, error) { - return v.refs.Get(v.name), nil -} - -// Write updates previously obtained references (via `Acquire`) to -// the value passed to this function. -func (v *GlobalVariable) Write(value interface{}) error { - v.writtenValue = value - return nil -} - -// Release makes changes made while the variable was acquired visible -// to other processes. -func (v *GlobalVariable) Release() error { - if v.writtenValue != nil { - v.refs.Set(v.name, v.writtenValue) - } - - err := v.stateServer.Release(v.refs) - v.refs = nil - - if err != nil { - return &ResourceInternalError{err.Error()} - } - - return nil -} - -// Abort releases access (previously obtained via `Acquire`) without modifying -// the underlying value of a variable. -func (v *GlobalVariable) Abort() error { - err := v.stateServer.Release(v.refs) - v.refs = nil - - if err != nil { - return &ResourceInternalError{err.Error()} - } - - return nil -} - -// Less implements ordering between global variables by performing -// lexicographical sorting over their names. -func (v *GlobalVariable) Less(other ArchetypeResource) bool { - gv := other.(*GlobalVariable) - return strings.Compare(v.name, gv.name) < 0 -} - -// Mailboxes as Archetype Resource -// ------------------------------- - -// Receiver represents the interface exposed by mailboxes. When data -// is received by a process, the data is sent across the underlying Go -// channel and can be read on calls to 'Read'. -type Receiver struct { - ch chan interface{} -} - -// Receive receives data from the other end of the channel. -func (r *Receiver) Receive(val *interface{}, result *int) error { - select { - case r.ch <- *val: - *result = RPC_SUCCESS - default: - *result = MAILBOX_IS_FULL_ERROR - } - - return nil -} - -func mailboxErrorDescription(e int) string { - if e == MAILBOX_IS_FULL_ERROR { - return "Destination mailbox is full" - } else { - return fmt.Sprintf("Unknown mailbox error code: %d", e) - } -} - -// Mailbox is an implementation of `ArchetypeResource` that provides -// an abstraction of a queue of messages that are waiting to be -// processed by some process. Other processes compiled by PGo are able -// to communicate with the running process by means of sending -// messages (Write() calls); processes may then read the next message -// available in their queues. -type Mailbox struct { - name string // internal name exposed via RPC - version int // version of this service being created - selfNames []string // identifiers deployed at the node that created the mailbox - configuration map[string]string // configuration of the system (PlusCal process -> IP address) - conns *Connections // the set of connections to nodes within the system - readAttempts int // number of times to attempt a read when no message is buffered - waitDuration int // how long to wait between two read attempts (in ms) - readBuf []interface{} // messages read from the channel - writeBuf []interface{} // messages waiting to be sent when the channel is released - readChan chan interface{} // reads are buffered through Go channels - timeout uint // how long to wait for RPC calls - readingAborted bool // whether we are reading messages from a previously aborted transaction - lock sync.Mutex // exclusive access to internal buffers -} - -// service returns the name of the RPC service associated with this -// mailbox. -func (mbox *Mailbox) service() string { - return "Mailbox_" + mbox.name + "_" + strconv.Itoa(mbox.version) -} - -func (mbox *Mailbox) callAsync(function string, args interface{}, ok *int) *rpc.Call { - fName := mbox.service() + "." + function - addr := mbox.configuration[mbox.name] - return mbox.conns.GetConnection(addr).Go(fName, &args, ok, nil) -} - -func (mbox *Mailbox) sendMessage(msg interface{}) error { - var result int - call := mbox.callAsync("Receive", msg, &result) - - checkRPCResult := func() error { - if result != RPC_SUCCESS { - return fmt.Errorf("Mailbox communication error: %s", mailboxErrorDescription(result)) - } - - return nil - } - - // a timeout of 0 indicates that the system TCP timeout should be - // used - if mbox.timeout == 0 { - <-call.Done - if call.Error != nil { - return call.Error - } - - return checkRPCResult() - } - - // send the message asynchronously; if it times out, return an - // error - select { - case <-call.Done: - if call.Error != nil { - return call.Error - } - - return checkRPCResult() - - case <-time.After(time.Duration(mbox.timeout) * time.Millisecond): - return fmt.Errorf("Timed out: %v", mbox.service()) - } -} - -func tryRead(ch chan interface{}, attempts, wait int) (interface{}, bool) { - for i := 0; i < attempts; i++ { - select { - case msg := <-ch: - return msg, true - case <-time.After(time.Duration(wait) * time.Millisecond): - // pass - } - } - - return nil, false -} - -func stringInList(target string, list []string) bool { - for _, s := range list { - if target == s { - return true - } - } - - return false -} - -// MailboxRef represents a reference to some mailbox. It can be local -// (if the process 'id' is the same as the mailbox being referenced), -// or remote (if they are different). -// -// Processes can send messages to other processes by appending to -// their message queues. -// -// The message queue (mailbox) contains at most 'bufferSize' -// elements. Sending a message to a process with a full queue causes -// the requester to block until sufficient space in the queue is -// available. -// -// The `timeout` argument indicates how long RPC calls should wait for -// the reply of a function call. Passing a timeout of 0 causes the -// runtime to not employ any timeout mechanism (falling back to the -// underlying system's TCP timeout). -func MailboxRef(name string, version int, conns *Connections, configuration map[string]string, ids []string, bufferSize uint, timeout uint) (*Mailbox, error) { - mbox := &Mailbox{ - name: name, - version: version, - selfNames: ids, - configuration: configuration, - conns: conns, - readAttempts: 2, - waitDuration: 20, - readBuf: []interface{}{}, - writeBuf: []interface{}{}, - timeout: timeout, - readingAborted: false, - } - - // if the reference is for the mailbox of the current process, - // expose RPC calls that allow other processes to send messages to - // it. - if stringInList(name, ids) { - readChan := make(chan interface{}, bufferSize) - receiver := &Receiver{readChan} - mbox.readChan = readChan - - if err := conns.ExposeImplementation(mbox.service(), receiver); err != nil { - return nil, err - } - } - - return mbox, nil -} - -// Acquire is a no-op for mailboxes -func (_ *Mailbox) Acquire(_ ResourceAccess) error { - return nil -} - -// Read attempts to read a message; in cases there are none, it -// returns an AbortRetryError. It is enforced that processes can only -// read messages from their own mailboxes. -func (mbox *Mailbox) Read() (interface{}, error) { - if !stringInList(mbox.name, mbox.selfNames) { - panic(fmt.Sprintf("Tried to read non-local mailbox %s (attempted by %s)", mbox.name, mbox.selfNames)) - } - - mbox.lock.Lock() - defer mbox.lock.Unlock() - - // if we are still reading messages from an aborted session - if mbox.readingAborted { - // read from the buffer of previously read messages (pop from - // the queue) - if len(mbox.readBuf) > 0 { - msg := mbox.readBuf[0] - mbox.readBuf = mbox.readBuf[1:] - return msg, nil - } else { - // if there are no more previously read messages, we are - // no longer reading from a previous transaction - mbox.readingAborted = false - } - } - - // if we are not reading from a previous transaction, wait for - // incoming messages on the mailbox - var msg interface{} - var ok bool - if msg, ok = tryRead(mbox.readChan, mbox.readAttempts, mbox.waitDuration); !ok { - return nil, &AbortRetryError{"No messages in the buffer"} - } - - mbox.readBuf = append(mbox.readBuf, msg) - return msg, nil -} - -// Write saves a message with the value given in a buffer to be sent -// later, when the channel is released. -func (mbox *Mailbox) Write(value interface{}) error { - mbox.lock.Lock() - defer mbox.lock.Unlock() - - mbox.writeBuf = append(mbox.writeBuf, value) - return nil -} - -// Release sends each message given to Write() to the destination -// mailbox. -func (mbox *Mailbox) Release() error { - mbox.lock.Lock() - defer mbox.lock.Unlock() - - // send each message written to the resource while it was - // acquired. Returns an error if sending any message failed - for _, msg := range mbox.writeBuf { - if err := mbox.sendMessage(msg); err != nil { - // return &ResourceInternalError{err.Error()} - // TODO: this should return a proper ResourceInternalError - return nil - } - } - - // erase read and write buffers - mbox.readBuf = []interface{}{} - mbox.writeBuf = []interface{}{} - return nil -} - -// Abort erases messages passed using Write and returns. It keeps the -// buffer of read messages so that, when the channel is next acquired, -// the same messages will be read again -func (mbox *Mailbox) Abort() error { - mbox.lock.Lock() - defer mbox.lock.Unlock() - - mbox.writeBuf = []interface{}{} - mbox.readingAborted = true - return nil -} - -// Less implements ordering among mailboxes by doing lexicographical -// sorting over the names of the services exposed over RPC. -func (mbox *Mailbox) Less(other ArchetypeResource) bool { - otherMBox := other.(*Mailbox) - return strings.Compare(mbox.service(), otherMBox.service()) < 0 -} - -// Local Channels as Archetype Resource -// ------------------------------------ - -// LocalChannelResource represents an archetype resource backed by a -// regular Go channel. The main use-case for channels as resources is -// being able to control the execution of long-running archetypes. -// Parameters can be sent via channels and the result of the -// computation performed can also be transmitted via channels. -type LocalChannelResource struct { - name string // channel identifier - ch chan interface{} // the underlying Go channel - readAttempts int // how many times to try to read from a channel - waitDuration int // how long to wait between each attempt (in ms) - lock chan int // guarantees access to the underlying channel is exclusive - readBuf []interface{} // keeps track of read values - writeBuf []interface{} // values written to the channel; sent when the resource is released -} - -// NewLocalChannel creates a LocalChannelResource. The caller does not -// need to know about the underlying Go channel. -func NewLocalChannel(name string, bufferSize int) *LocalChannelResource { - return &LocalChannelResource{ - name: name, - lock: newLock(), - ch: make(chan interface{}, bufferSize), - readAttempts: 2, - waitDuration: 20, - readBuf: []interface{}{}, - writeBuf: []interface{}{}, - } -} - -// Acquire tries to get exclusive access to the local channel. -func (localCh *LocalChannelResource) Acquire(access ResourceAccess) error { - if !tryLock(localCh.lock) { - return &AbortRetryError{"Could not acquire LocalChannelResource"} - } - - return nil -} - -// Read waits for data to be available in the underlying Go channel. -func (localCh *LocalChannelResource) Read() (interface{}, error) { - var val interface{} - var ok bool - - if val, ok = tryRead(localCh.ch, localCh.readAttempts, localCh.waitDuration); !ok { - return nil, &AbortRetryError{"No messages in the channel"} - } - - localCh.readBuf = append(localCh.readBuf, val) - return val, nil -} - -// Write sends a value over the channel. -func (localCh *LocalChannelResource) Write(value interface{}) error { - localCh.writeBuf = append(localCh.writeBuf, value) - return nil -} - -// Release writes values written to the channel while the resource was -// acquired. -func (localCh *LocalChannelResource) Release() error { - // send written values over the channel - for _, val := range localCh.writeBuf { - localCh.ch <- val - } - - // erase read and written values - localCh.readBuf = []interface{}{} - localCh.writeBuf = []interface{}{} - - // release access to the channel - releaseLock(localCh.lock) - return nil -} - -// Abort undoes any read performed while the channel was acquired -func (localCh *LocalChannelResource) Abort() error { - // reverse read values - for i := len(localCh.readBuf)/2 - 1; i >= 0; i-- { - opp := len(localCh.readBuf) - 1 - i - localCh.readBuf[i], localCh.readBuf[opp] = localCh.readBuf[opp], localCh.readBuf[i] - } - - // send the read values back - for _, val := range localCh.readBuf { - localCh.ch <- val - } - - // erase read and written values - localCh.readBuf = []interface{}{} - localCh.writeBuf = []interface{}{} - - // release access to the channel - releaseLock(localCh.lock) - return nil -} - -// Less implements ordering among instances of -// LocalChannelResource. Lexicographical comparison on their names is -// used. -func (localCh *LocalChannelResource) Less(other ArchetypeResource) bool { - ch := other.(*LocalChannelResource) - return strings.Compare(localCh.name, ch.name) < 0 -} - -// Send writes data to the channel so that the receiving end can see -// it (on a Read call). This is supposed to be called by code outside -// archetypes. -func (localCh *LocalChannelResource) Send(value interface{}) { - localCh.ch <- value -} - -// Receive reads data from the channel so that results can be -// collected. This is supposed to be called by code outside -// archetypes. -func (localCh *LocalChannelResource) Receive() interface{} { - return <-localCh.ch -} - -// Files as Archetype Resource -// --------------------------- - -// FileResource implements files in the system as archetype resources. -type FileResource struct { - path string // absolute path to the file - fd *os.File // the underlying file descriptor. - contents []byte // if the file has been previously read or written, hold contents in buffer - dirty bool // whether the file has been written -} - -// NewFileResource creates a FileResource for the file under `path`. -func NewFileResource(path string) *FileResource { - return &FileResource{ - path: path, - contents: nil, - dirty: false, - } -} - -// Acquire attempts to open the underlying file with appropriate -// permissions. Returns an error if it cannot be done. -func (file *FileResource) Acquire(access ResourceAccess) error { - perms := os.O_RDONLY - if access&WRITE_ACCESS != 0 { - perms = os.O_RDWR - } - - fd, err := os.OpenFile(file.path, perms|os.O_CREATE, 0644) - if err != nil { - return &ResourceInternalError{err.Error()} - } - - file.fd = fd - return nil -} - -// Read returns a buffer with all the contents of the underlying file. -// Panics if reading there is a an error reading the file. -func (file *FileResource) Read() (interface{}, error) { - if file.contents == nil { - data, err := ioutil.ReadAll(file.fd) - - // IO error: let the calller handle it - if err != nil { - return nil, &ResourceInternalError{err.Error()} - } - - file.contents = data - } - - return file.contents, nil -} - -// Write saves the value to be written in an internal -// buffer. Subsequent Read() calls will return the newly written -// value. Note that `value` *must* be []byte. -func (file *FileResource) Write(value interface{}) error { - file.contents = value.([]byte) - file.dirty = true - - return nil -} - -// Release writes any previously written contents to the underlying -// file, and closes it. -func (file *FileResource) Release() error { - if file.fd != nil { - if file.dirty { - _, err := file.fd.Write(file.contents) - - if err != nil { - return &ResourceInternalError{err.Error()} - } - } - - return file.fd.Close() - } - - return nil -} - -// Abort closes the underlying file -func (file *FileResource) Abort() error { - return file.fd.Close() -} - -// Less implements ordering. The file path is used to order instances -// of FileResource. -func (file *FileResource) Less(other ArchetypeResource) bool { - otherFile := other.(*FileResource) - return strings.Compare(file.path, otherFile.path) < 0 -} - -// Immutable Values as Archetype Resources -// --------------------------------------- - -type ImmutableResource struct { - value interface{} -} - -// NewImmutableResource creates a new immutable archetype resource -// wrapping the `value` passed. -func NewImmutableResource(value interface{}) *ImmutableResource { - return &ImmutableResource{value} -} - -// Acquire is a no-op for immutable resources -func (_ *ImmutableResource) Acquire(_ ResourceAccess) error { - return nil -} - -// Read returns the underlying value -func (resource *ImmutableResource) Read() (interface{}, error) { - return resource.value, nil -} - -// Write panics (the resource is immutable) -func (_ *ImmutableResource) Write(value interface{}) error { - panic("Attempted to write immutable resource") -} - -// Release is a no-op for immutable resources -func (_ *ImmutableResource) Release() error { - return nil -} - -// Abort is a no-op for immutable resources -func (_ *ImmutableResource) Abort() error { - return nil -} - -// Less is a no-op. Immutable resources are agnostic to ordering. -func (_ *ImmutableResource) Less(_ ArchetypeResource) bool { - return false -} - -// Locally Shared Variables as Archetype Resources -// ----------------------------------------------- - -// LocallySharedResource represents some value that is shared only locally, -// i.e., within the same Go process. -type LocallySharedResource struct { - name string // resource identifier - val interface{} // the value being shared - writtenBuf interface{} // buffer of previous writes - lock chan int // mutex to guarantee exclusive access -} - -// NewLocallySharedResource creates a new shared resource that can be -// used as a resource archetype -func NewLocallySharedResource(name string, val interface{}) *LocallySharedResource { - return &LocallySharedResource{ - name: name, - val: val, - writtenBuf: nil, - lock: newLock(), - } -} - -// Acquire locks the resource for exclusive access -func (resource *LocallySharedResource) Acquire(_ ResourceAccess) error { - if !tryLock(resource.lock) { - return &AbortRetryError{"Could not acquire LocallySharedResource"} - } - - return nil -} - -// Read returns the current value of the resource -func (resource *LocallySharedResource) Read() (interface{}, error) { - if resource.writtenBuf != nil { - return resource.writtenBuf, nil - } - - return resource.val, nil -} - -// Write updates the value of the underlying shared resource -func (resource *LocallySharedResource) Write(value interface{}) error { - resource.writtenBuf = value - return nil -} - -// Release writes any written value to the underlying shared value and -// returns -func (resource *LocallySharedResource) Release() error { - if resource.writtenBuf != nil { - resource.val = resource.writtenBuf - } - - releaseLock(resource.lock) - return nil -} - -// Abort erases any values passed using Write and returns. -func (resource *LocallySharedResource) Abort() error { - resource.writtenBuf = nil - releaseLock(resource.lock) - - return nil -} - -// Less implements ordering among locally shared -// resources. Lexicographical order on the resource name is used. -func (resource *LocallySharedResource) Less(other ArchetypeResource) bool { - otherResource := other.(*LocallySharedResource) - return strings.Compare(resource.name, otherResource.name) < 0 -} - -// AtomicIntegers as Archetype Resources -// ------------------------------------- - -// AtomicInteger wraps an integer value that can be read from and -// written to without acquiring locks. It makes use of the sync/atomic -// Go package in order to ensure reads and writes are consistent and -// isolated. -type AtomicInteger struct { - name string // used to enforce consistent ordering - value int32 // the current value of the underlying integer - writtenValue *int32 // uncommitted write, if any -} - -// NewAtomicInteger creates an atomic Integer initialized with the -// value passed as argument -func NewAtomicInteger(name string, initial int32) *AtomicInteger { - return &AtomicInteger{ - name: name, - value: initial, - } -} - -// Acquire is a no-op for atomic integers -func (_ AtomicInteger) Acquire(_ ResourceAccess) error { - return nil -} - -// Read returns the current value of the resource -func (aint *AtomicInteger) Read() (interface{}, error) { - if aint.writtenValue != nil { - return int(*aint.writtenValue), nil - } - - return int(atomic.LoadInt32(&aint.value)), nil -} - -// Write updates the value of the underlying integer -func (aint *AtomicInteger) Write(value interface{}) error { - intValue := int32(value.(int)) - aint.writtenValue = &intValue - - return nil -} - -// Release writes any written value to the underlying atomic integer -// and returns. -func (aint *AtomicInteger) Release() error { - if aint.writtenValue != nil { - atomic.StoreInt32(&aint.value, *aint.writtenValue) - } - - return nil -} - -// Abort erases any values passed using Write and returns. -func (aint *AtomicInteger) Abort() error { - aint.writtenValue = nil - return nil -} - -// Less implements ordering among atomic integer resources. -// Lexicographical order on the resource name is used. -func (aint *AtomicInteger) Less(other ArchetypeResource) bool { - otherResource := other.(*AtomicInteger) - return strings.Compare(aint.name, otherResource.name) < 0 -} - -// Sleeping as Archetype Resources -// ------------------------------- - -// SleepResource allows implementations to sleep an arbitrary duration -// while executing an archetype. -type SleepResource struct { - name string // resource name, for ordering - unit time.Duration // seconds, milliseconds, ... -} - -// NewSleepResource creates a resource that sleeps for the specified -// amount of time when the resource is written to. The parameter given -// indicates the unit used when the resource is used (i.e., seconds, -// milliseconds, etc.) -func NewSleepResource(name string, unit time.Duration) *SleepResource { - return &SleepResource{ - name: name, - unit: unit, - } -} - -// Acquire is a no-op for sleep resources -func (_ *SleepResource) Acquire(_ ResourceAccess) error { - return nil -} - -// Read panics if invoked. Sleep resources should not be read from! -func (_ *SleepResource) Read() (interface{}, error) { - panic("Attempted to read SleepResource") -} - -// Write sleeps for the specified amount of time (must be an integer) -func (s *SleepResource) Write(value interface{}) error { - t := value.(int) - - time.Sleep(time.Duration(t) * s.unit) - return nil -} - -// Release is a no-op for sleep resources -func (_ *SleepResource) Release() error { - return nil -} - -// Abort is a no-op for sleep resources -func (_ *SleepResource) Abort() error { - return nil -} - -// Less implements ordering among sleep resources -// Lexicographical order on the resource name is used. -func (s *SleepResource) Less(other ArchetypeResource) bool { - otherResource := other.(*SleepResource) - return strings.Compare(s.name, otherResource.name) < 0 -} - -///////////////////////////////////////////////////////////////////////// -//// ARCHETYPE RESOURCE COLLECTIONS //// -/////////////////////////////////////////////////////////////////////// - -// Slices as Archetype Resource Collections -// ---------------------------------------- - -// ArchetypeResourceSlice implements implements an -// ArchetypeResourceCollection by mapping Get calls as straightforward -// indexing operations on the underlying slice. -type ArchetypeResourceSlice []ArchetypeResource - -// Get returns the archetype resource at a given index. The `value` -// passed must be an integer. -func (slice ArchetypeResourceSlice) Get(value interface{}) ArchetypeResource { - index := value.(int) - return slice[index] -} - -// File System Directories as Archetype Resource Collections -// --------------------------------------------------------- - -// FileSystemDirectory represents an archetype resource that makes the -// files in a certain directory available, implementing the -// ArchetypeResourceCollection interface -type FileSystemDirectory struct { - root string // path to the directory under which files will be accessed - resources map[string]*FileResource // maps previously retrieved files -} - -// NewFileSystemDirectory returns an implementation of -// ArchetypeResourceCollection for accessing files under a root -// directory. -func NewFileSystemDirectory(root string) *FileSystemDirectory { - return &FileSystemDirectory{ - root: root, - resources: map[string]*FileResource{}, - } -} - -// Get returns the archetype resource file corresponding to the path -// (relative to the root) given as argument. The `value` given must be -// a string. -func (dir *FileSystemDirectory) Get(value interface{}) ArchetypeResource { - relativePath := value.(string) - - if _, ok := dir.resources[relativePath]; !ok { - absolutePath := path.Join(string(dir.root), relativePath) - dir.resources[relativePath] = NewFileResource(absolutePath) - } - - return dir.resources[relativePath] -} - -// Singleton collections as Archetype Resource Collection -// ------------------------------------------------------ - -// SingletonCollectionResource imeplements the -// ArchetypeResourceCollection by trivially always returning the same -// resource for every index. -type SingletonCollectionResource struct { - resource ArchetypeResource -} - -// NewSingletonCollection returns a SingletonCollectionResource -// wrapping the resource given -func NewSingletonCollection(resource ArchetypeResource) SingletonCollectionResource { - return SingletonCollectionResource{resource} -} - -// Get returns the underlying ArchetypeResource. -func (singleton SingletonCollectionResource) Get(_ interface{}) ArchetypeResource { - return singleton.resource -} - -// Maps as Archetype Resource Collections -// -------------------------------------- - -// ArchetypeResourceMap implements the ArchetypeResourceCollection -// interface and allows Get operations to index on keys of the map. -type ArchetypeResourceMap struct { - resources map[interface{}]*LocallySharedResource - counter uint - lock sync.Mutex -} - -func NewArchetypeResourceMap() *ArchetypeResourceMap { - return &ArchetypeResourceMap{ - resources: map[interface{}]*LocallySharedResource{}, - } -} - -// Get returns a LocallySharedResource with the value on the given -// `key`. -func (m *ArchetypeResourceMap) Get(key interface{}) ArchetypeResource { - m.lock.Lock() - if _, ok := m.resources[key]; !ok { - // the name is irrelevant here since function-mapped resources - // are acquired at the time of use - m.resources[key] = NewLocallySharedResource(fmt.Sprintf("mapResource_%d", m.counter), nil) - } - m.counter++ - - m.lock.Unlock() - return m.resources[key] -} - -// ToMap returns a Go map representation of the map archetype -// resource. Any attempts to Get() a value from the map will block -// while this operation is in progress. -func (m *ArchetypeResourceMap) ToMap() map[interface{}]interface{} { - // make sure the map cannot be changed while we convert the data - // to a Go map - m.lock.Lock() - - result := map[interface{}]interface{}{} - for k, v := range m.resources { - if v.val != nil { - result[k] = v.val - } - } - - m.lock.Unlock() - return result -} - -// Resource Pools as Archetype Resource Collections -// ------------------------------------------------ - -// ResourcePool implements a pool of archetype resources that can be -// shared among multiple processes in a system. -type ResourcePool struct { - size int // the number of resources in the pool - resources []ArchetypeResource // the actual resources being shared - free chan int // channel containing indices into 'resources' that are free -} - -// NewResourcePool creates a resource pool of a given 'size'. The -// 'factory' function is used to create an archetype resource in the -// pool. It is called 'size' types to create the initial pool. -func NewResourcePool(size int, factory func() ArchetypeResource) *ResourcePool { - pool := &ResourcePool{ - resources: make([]ArchetypeResource, size), - free: make(chan int, size), - } - - // initialize resources and free list - for i := 0; i < size; i++ { - pool.resources[i] = factory() - pool.free <- i - } - - return pool -} - -// Retrieve obtains a free resource in the pool. Blocks until one is -// available if no resources are available at the time of the request. -// Returns a 'handle' that must be returned when the caller is done -// using the resource. -func (pool *ResourcePool) Retrieve() (ArchetypeResource, int) { - handle := <-pool.free - return pool.resources[handle], handle -} - -// Return marks a previously retrieved resource as free again. -func (pool *ResourcePool) Return(handle int) { - pool.free <- handle -} - -// Get returns the resource associated with the given value -// (handle). It is an error to pass a value that has not been -// previously retrieved. -func (pool *ResourcePool) Get(value interface{}) ArchetypeResource { - handle := value.(int) - return pool.resources[handle] -} diff --git a/test/files/semantics/AssignmentRules.tla b/test/files/general/AssignmentRules.tla similarity index 100% rename from test/files/semantics/AssignmentRules.tla rename to test/files/general/AssignmentRules.tla diff --git a/test/files/semantics/CallLabelingRules.tla b/test/files/general/CallLabelingRules.tla similarity index 100% rename from test/files/semantics/CallLabelingRules.tla rename to test/files/general/CallLabelingRules.tla diff --git a/test/files/semantics/IfEitherLabelingRules.tla b/test/files/general/IfEitherLabelingRules.tla similarity index 100% rename from test/files/semantics/IfEitherLabelingRules.tla rename to test/files/general/IfEitherLabelingRules.tla diff --git a/test/files/semantics/LabelBeforeWhile.tla b/test/files/general/LabelBeforeWhile.tla similarity index 100% rename from test/files/semantics/LabelBeforeWhile.tla rename to test/files/general/LabelBeforeWhile.tla diff --git a/test/files/semantics/LabelNotDefined.tla b/test/files/general/LabelNotDefined.tla similarity index 100% rename from test/files/semantics/LabelNotDefined.tla rename to test/files/general/LabelNotDefined.tla diff --git a/test/files/semantics/MPCalKindMatching.tla b/test/files/general/MPCalKindMatching.tla similarity index 59% rename from test/files/semantics/MPCalKindMatching.tla rename to test/files/general/MPCalKindMatching.tla index 951a6f636..4edb44142 100644 --- a/test/files/semantics/MPCalKindMatching.tla +++ b/test/files/general/MPCalKindMatching.tla @@ -2,12 +2,21 @@ EXTENDS Sequences, FiniteSets, Integers (* --mpcal MPCalKindMatching { - procedure Proc(ref a[_]) { + procedure Proc(ref a[_]) + variables x; + { l2: call Proc((*:: expectedError: MPCalKindMismatchError *) a); - l4: call Proc2(ref a[_]); + l4: call Proc2(ref a[_][_]); l5: a[2] := 3; l3: (*:: expectedError: MPCalKindMismatchError *) a := 3; l6: a[5][6] := 3; + l7: x := (*:: expectedError: MPCalKindMismatchError *) a; + l8: x := a[3]; + l9: x := a[(*:: expectedError: MPCalKindMismatchError *) a]; + l10: x := a[3][4]; + l11: call Proc((*:: expectedError: MPCalKindMismatchError *) ref a); + l12: call Proc(ref a[_]); + l13: call Proc((*:: expectedError: MPCalKindMismatchError *) ref a[_][_]); } procedure Proc2(ref b[_][_]) { @@ -20,7 +29,7 @@ EXTENDS Sequences, FiniteSets, Integers variables myVar; - process (A = 42) == instance Arch((*:: expectedError: MPCalKindMismatchError *) myVar[_]); + process (A = 42) == instance Arch(ref myVar[_]); process (B = 43) == instance Arch((*:: expectedError: MPCalKindMismatchError *) ref myVar); diff --git a/test/files/semantics/MacroRules.tla b/test/files/general/MacroRules.tla similarity index 100% rename from test/files/semantics/MacroRules.tla rename to test/files/general/MacroRules.tla diff --git a/test/files/semantics/MappingMacroWithCallGoto.tla b/test/files/general/MappingMacroWithCallGoto.tla similarity index 100% rename from test/files/semantics/MappingMacroWithCallGoto.tla rename to test/files/general/MappingMacroWithCallGoto.tla diff --git a/test/files/semantics/MappingWithLabels.tla b/test/files/general/MappingWithLabels.tla similarity index 100% rename from test/files/semantics/MappingWithLabels.tla rename to test/files/general/MappingWithLabels.tla diff --git a/test/files/semantics/NoFirstLabel.tla b/test/files/general/NoFirstLabel.tla similarity index 94% rename from test/files/semantics/NoFirstLabel.tla rename to test/files/general/NoFirstLabel.tla index 0017fc021..b2554e14b 100644 --- a/test/files/semantics/NoFirstLabel.tla +++ b/test/files/general/NoFirstLabel.tla @@ -2,7 +2,7 @@ EXTENDS Sequences, FiniteSets, Integers (* --mpcal NoFirstLabel { - procedure MPCalProc(a^) { + procedure MPCalProc(a) { \*:: expectedError: LabelRequiredError print(2 + 2); } diff --git a/test/files/semantics/RecursiveMacroRules.tla b/test/files/general/RecursiveMacroRules.tla similarity index 100% rename from test/files/semantics/RecursiveMacroRules.tla rename to test/files/general/RecursiveMacroRules.tla diff --git a/test/files/semantics/ReservedLabels.tla b/test/files/general/ReservedLabels.tla similarity index 100% rename from test/files/semantics/ReservedLabels.tla rename to test/files/general/ReservedLabels.tla diff --git a/test/files/semantics/ReturnGotoLabelingRules.tla b/test/files/general/ReturnGotoLabelingRules.tla similarity index 100% rename from test/files/semantics/ReturnGotoLabelingRules.tla rename to test/files/general/ReturnGotoLabelingRules.tla diff --git a/test/files/semantics/WithRules.tla b/test/files/general/WithRules.tla similarity index 100% rename from test/files/semantics/WithRules.tla rename to test/files/general/WithRules.tla diff --git a/test/files/pcalgen/dqueue.tla b/test/files/general/dqueue.tla similarity index 100% rename from test/files/pcalgen/dqueue.tla rename to test/files/general/dqueue.tla diff --git a/test/files/pcalgen/dqueue.tla.expectpcal b/test/files/general/dqueue.tla.expectpcal similarity index 100% rename from test/files/pcalgen/dqueue.tla.expectpcal rename to test/files/general/dqueue.tla.expectpcal diff --git a/test/files/general/dqueue.tla.gotests/dqueue.go b/test/files/general/dqueue.tla.gotests/dqueue.go new file mode 100644 index 000000000..e43ae9821 --- /dev/null +++ b/test/files/general/dqueue.tla.gotests/dqueue.go @@ -0,0 +1,197 @@ +package dqueue + +import "github.com/UBC-NSS/pgo/distsys" + +type Constants struct { + BUFFER_SIZE distsys.TLAValue + NUM_CONSUMERS distsys.TLAValue + PRODUCER distsys.TLAValue +} + +func NUM_NODES(constants Constants) distsys.TLAValue { + return distsys.TLA_PlusSymbol(constants.NUM_CONSUMERS, distsys.NewTLANumber(1)) +} + +func AConsumer(self distsys.TLAValue, constants0 Constants, net distsys.ArchetypeResource, proc distsys.ArchetypeResource) error { + var err error + + c: { + sectionCtx := distsys.NewPCalSectionContext() + var exprReads []distsys.TLAValue + exprReads, err = distsys.WhileCatchingPanics(func() distsys.TLAValue { return distsys.TLA_TRUE }) + if err != nil { + sectionCtx.Abort() + if err == distsys.Aborted { + goto c + } else { + return err + } + } + if exprReads[0].IsTrue() { + switch err = sectionCtx.Commit(); err { + case error(nil): + goto c1 + case distsys.Aborted: + goto c + default: + return err + } + } else { + // no statements + } + // no statements + } + c1: { + sectionCtx0 := distsys.NewPCalSectionContext() + var exprReads0 []distsys.TLAValue + exprReads0, err = distsys.WhileCatchingPanics(func() distsys.TLAValue { return self }, func() distsys.TLAValue { return constants0.PRODUCER }) + if err != nil { + sectionCtx0.Abort() + if err == distsys.Aborted { + goto c1 + } else { + return err + } + } + err = sectionCtx0.Write(net, exprReads0[1:], exprReads0[0]) + if err != nil { + sectionCtx0.Abort() + if err == distsys.Aborted { + goto c1 + } else { + return err + } + } + switch err = sectionCtx0.Commit(); err { + case error(nil): + goto c2 + case distsys.Aborted: + goto c1 + default: + return err + } + } + c2: { + sectionCtx1 := distsys.NewPCalSectionContext() + var exprReads1 []distsys.TLAValue + exprReads1, err = distsys.WhileCatchingPanics(func() distsys.TLAValue { return sectionCtx1.Read(net, []distsys.TLAValue{self}) }) + if err != nil { + sectionCtx1.Abort() + if err == distsys.Aborted { + goto c2 + } else { + return err + } + } + err = sectionCtx1.Write(proc, exprReads1[1:], exprReads1[0]) + if err != nil { + sectionCtx1.Abort() + if err == distsys.Aborted { + goto c2 + } else { + return err + } + } + switch err = sectionCtx1.Commit(); err { + case error(nil): + goto c + case distsys.Aborted: + goto c2 + default: + return err + } + } +} + +func AProducer(self0 distsys.TLAValue, constants1 Constants, net0 distsys.ArchetypeResource, s distsys.ArchetypeResource) error { + var requester distsys.ArchetypeResource = distsys.NewLocalArchetypeResource(distsys.TLAValue{}) + var err0 error + + p: { + sectionCtx2 := distsys.NewPCalSectionContext() + var exprReads2 []distsys.TLAValue + exprReads2, err0 = distsys.WhileCatchingPanics(func() distsys.TLAValue { return distsys.TLA_TRUE }) + if err0 != nil { + sectionCtx2.Abort() + if err0 == distsys.Aborted { + goto p + } else { + return err0 + } + } + if exprReads2[0].IsTrue() { + switch err0 = sectionCtx2.Commit(); err0 { + case error(nil): + goto p1 + case distsys.Aborted: + goto p + default: + return err0 + } + } else { + // no statements + } + // no statements + } + p1: { + sectionCtx3 := distsys.NewPCalSectionContext() + var exprReads3 []distsys.TLAValue + exprReads3, err0 = distsys.WhileCatchingPanics(func() distsys.TLAValue { return sectionCtx3.Read(net0, []distsys.TLAValue{self0}) }) + if err0 != nil { + sectionCtx3.Abort() + if err0 == distsys.Aborted { + goto p1 + } else { + return err0 + } + } + err0 = sectionCtx3.Write(requester, exprReads3[1:], exprReads3[0]) + if err0 != nil { + sectionCtx3.Abort() + if err0 == distsys.Aborted { + goto p1 + } else { + return err0 + } + } + switch err0 = sectionCtx3.Commit(); err0 { + case error(nil): + goto p2 + case distsys.Aborted: + goto p1 + default: + return err0 + } + } + p2: { + sectionCtx4 := distsys.NewPCalSectionContext() + var exprReads4 []distsys.TLAValue + exprReads4, err0 = distsys.WhileCatchingPanics(func() distsys.TLAValue { return sectionCtx4.Read(s, []distsys.TLAValue{}) }, func() distsys.TLAValue { return sectionCtx4.Read(requester, []distsys.TLAValue{}) }) + if err0 != nil { + sectionCtx4.Abort() + if err0 == distsys.Aborted { + goto p2 + } else { + return err0 + } + } + err0 = sectionCtx4.Write(net0, exprReads4[1:], exprReads4[0]) + if err0 != nil { + sectionCtx4.Abort() + if err0 == distsys.Aborted { + goto p2 + } else { + return err0 + } + } + switch err0 = sectionCtx4.Commit(); err0 { + case error(nil): + goto p + case distsys.Aborted: + goto p2 + default: + return err0 + } + } +} + diff --git a/test/files/general/dqueue.tla.gotests/dqueue_test.go b/test/files/general/dqueue.tla.gotests/dqueue_test.go new file mode 100644 index 000000000..805b1ca05 --- /dev/null +++ b/test/files/general/dqueue.tla.gotests/dqueue_test.go @@ -0,0 +1,27 @@ +package dqueue + +import ( + "github.com/UBC-NSS/pgo/distsys" + "testing" +) + +func TestNUM_NODES(t *testing.T) { + result := NUM_NODES(Constants{NUM_CONSUMERS: distsys.NewTLANumber(12)}) + if result.AsNumber() != 13 { + t.Errorf("NUM_CONSUMERS should have yielded 13, got %v", result) + } +} + +func TestAConsumer(t *testing.T) { + t.Run("one consumer", func(t *testing.T) { + + go func() { + err := AConsumer(distsys.TLAValue{}, Constants{}, nil, nil) + if err != nil { + panic(err) + } + }() + + }) + t.Fail() +} diff --git a/test/files/general/dqueue.tla.gotests/go.mod b/test/files/general/dqueue.tla.gotests/go.mod new file mode 100644 index 000000000..ffe02464a --- /dev/null +++ b/test/files/general/dqueue.tla.gotests/go.mod @@ -0,0 +1,7 @@ +module example.org/dqueue + +go 1.14 + +replace github.com/UBC-NSS/pgo/distsys => ../../../../distsys + +require github.com/UBC-NSS/pgo/distsys v0.0.0-00010101000000-000000000000 diff --git a/test/files/pcalgen/load_balancer.tla b/test/files/general/load_balancer.tla similarity index 99% rename from test/files/pcalgen/load_balancer.tla rename to test/files/general/load_balancer.tla index a43888fb7..bb164c29a 100644 --- a/test/files/pcalgen/load_balancer.tla +++ b/test/files/general/load_balancer.tla @@ -140,7 +140,7 @@ CONSTANT WEB_PAGE \* - file_system: abstraction of a real file system. In practice, \* this is implementation specific and irrelevant for \* the properties we want to check in this specification - archetype AServer(ref mailboxes, file_system) + archetype AServer(ref mailboxes, ref file_system[_]) \* Local variables variable @@ -174,7 +174,7 @@ CONSTANT WEB_PAGE \* - instream: a stream of inputs to the client \* - outstream: an output stream, where the client sends the messages it receives \* from servers. - archetype AClient(ref mailboxes, instream, ref outstream) + archetype AClient(ref mailboxes[_], ref instream, ref outstream) \* Local variables variable @@ -232,11 +232,11 @@ CONSTANT WEB_PAGE \* We map the page stream according to the WebPages mapping macro since this is \* an implementation detail that needs to be specified during implementation at \* a later stage. - fair process (Servers \in 1..NUM_SERVERS) == instance AServer(ref network, fs) + fair process (Servers \in 1..NUM_SERVERS) == instance AServer(ref network, ref fs[_]) mapping network[_] via TCPChannel mapping fs[_] via WebPages; - fair process (Client \in (NUM_SERVERS+1)..(NUM_SERVERS+NUM_CLIENTS)) == instance AClient(ref network, in, ref out) + fair process (Client \in (NUM_SERVERS+1)..(NUM_SERVERS+NUM_CLIENTS)) == instance AClient(ref network[_], ref in, ref out) mapping network[_] via TCPChannel; } diff --git a/test/files/pcalgen/load_balancer.tla.expectpcal b/test/files/general/load_balancer.tla.expectpcal similarity index 100% rename from test/files/pcalgen/load_balancer.tla.expectpcal rename to test/files/general/load_balancer.tla.expectpcal diff --git a/test/files/pcalgen/replicated_kv.tla b/test/files/general/replicated_kv.tla similarity index 100% rename from test/files/pcalgen/replicated_kv.tla rename to test/files/general/replicated_kv.tla diff --git a/test/files/pcalgen/replicated_kv.tla.expectpcal b/test/files/general/replicated_kv.tla.expectpcal similarity index 100% rename from test/files/pcalgen/replicated_kv.tla.expectpcal rename to test/files/general/replicated_kv.tla.expectpcal diff --git a/test/pgo/GoGenFileTests.scala b/test/pgo/GoGenFileTests.scala index 7165258e7..e33bcb7a4 100644 --- a/test/pgo/GoGenFileTests.scala +++ b/test/pgo/GoGenFileTests.scala @@ -1,18 +1,41 @@ package pgo +import scala.util.control.NonFatal + class GoGenFileTests extends FileTestSuite { + lazy val goExe: String = sys.env.getOrElse("GO_EXE", "go") + override val testFiles: List[os.Path] = (os.list.stream(os.pwd / "test" / "files" / "gogen") ++ - os.list.stream(os.pwd / "test" / "files" / "semantics")) + os.list.stream(os.pwd / "test" / "files" / "general")) .filter(_.last.endsWith(".tla")) .toList testFiles.foreach { testFile => test(s"gogen ${testFile.relativeTo(os.pwd)}") { - val outFile = os.temp() + val outDir = os.temp.dir() + val goTestsDir = testFile / os.up / s"${testFile.last}.gotests" + if(os.isDir(goTestsDir)) { // should only do something useful when PGo isn't expected to error out + os.copy.over(from = goTestsDir, to = outDir, createFolders = true) + // rewrite go.mod to point to the absolute path of our local copy of the distsys library + val distsysReplaceRgx = raw"""replace github.com/UBC-NSS/pgo/distsys => .*""".r + os.write.over(outDir / "go.mod", os.read.lines(outDir / "go.mod").view.flatMap { + case distsysReplaceRgx() => Some(s"replace github.com/UBC-NSS/pgo/distsys => ${os.pwd / "distsys"}") + case line => Some(line) + }.map(line => s"$line\n")) + } + val outFile = outDir / s"${testFile.baseName}.go" val errors = PGo.run(Seq("gogen", "-s", testFile.toString(), "-o", outFile.toString())) checkErrors(errors, testFile) if(errors.isEmpty) { - // TODO: check Go compilation + if(!sys.env.contains("TESTS_DO_NOT_WRITE")) { + // unless the environment var above is set, write the output file into the test files, so the test can + // be debugged / manipulated using standard Go tools + os.write.over(goTestsDir / outFile.last, outFile.toSource) + } + // try to run tests in Go, subprocess failure will count as a test failure + // see above for where to find generated code to debug + os.proc(goExe, "build").call(cwd = outDir) + os.proc(goExe, "test").call(cwd = outDir) } } } diff --git a/test/pgo/PCalGenFileTests.scala b/test/pgo/PCalGenFileTests.scala index 3b1e9968e..60993870e 100644 --- a/test/pgo/PCalGenFileTests.scala +++ b/test/pgo/PCalGenFileTests.scala @@ -6,7 +6,7 @@ import scala.jdk.CollectionConverters._ class PCalGenFileTests extends FileTestSuite { override val testFiles: List[os.Path] = (os.list.stream(os.pwd / "test" / "files" / "pcalgen") ++ - os.list.stream(os.pwd / "test" / "files" / "semantics")) + os.list.stream(os.pwd / "test" / "files" / "general")) .filter(_.last.endsWith(".tla")) .toList @@ -25,7 +25,9 @@ class PCalGenFileTests extends FileTestSuite { withClue(diff.asScala.mkString("\n")) { if(expectedLines != actualLines) { - os.write.over(testFile / os.up / s"${testFile.last}.outpcal", data = tmpFile.toSource) + if(!sys.env.contains("TESTS_DO_NOT_WRITE")) { + os.write.over(testFile / os.up / s"${testFile.last}.outpcal", data = tmpFile.toSource) + } fail(s"expected PCal codegen did not match actual") } } From a201f952a282286d378d51c39ba6b5d27487ea04 Mon Sep 17 00:00:00 2001 From: fhackett Date: Thu, 1 Jul 2021 07:04:41 -0700 Subject: [PATCH 09/27] WIP: basic MVP network resources; dqueue tests pass --- distsys/archetypes.go | 806 +++++++++++++++--- distsys/mpcal.go | 252 ++++-- distsys/tlaplus.go | 333 +++++++- src/pgo/PGo.scala | 5 +- src/pgo/trans/MPCalGoCodegenPass.scala | 531 ++++++------ .../general/dqueue.tla.gotests/dqueue.go | 276 +++--- .../general/dqueue.tla.gotests/dqueue_test.go | 89 +- test/files/general/load_balancer.tla | 8 +- .../general/load_balancer.tla.expectpcal | 18 +- .../general/load_balancer.tla.gotests/go.mod | 7 + .../load_balancer.go | 333 ++++++++ .../load_balancer_test.go | 8 + test/files/general/replicated_kv.tla | 32 +- test/pgo/GoGenFileTests.scala | 3 + 14 files changed, 2028 insertions(+), 673 deletions(-) create mode 100644 test/files/general/load_balancer.tla.gotests/go.mod create mode 100644 test/files/general/load_balancer.tla.gotests/load_balancer.go create mode 100644 test/files/general/load_balancer.tla.gotests/load_balancer_test.go diff --git a/distsys/archetypes.go b/distsys/archetypes.go index efb9db4c7..8661eaea4 100644 --- a/distsys/archetypes.go +++ b/distsys/archetypes.go @@ -1,20 +1,27 @@ package distsys import ( + "bytes" "container/list" "encoding/gob" "errors" + "fmt" + "github.com/benbjohnson/immutable" "io" + "log" "net" + "sync" "time" ) -var Aborted = errors.New("MPCal critical section aborted") +var CriticalSectionAborted = errors.New("MPCal critical section aborted") type ArchetypeResource interface { - Abort() - PreCommit() error - Commit() + gob.GobDecoder + gob.GobEncoder + Abort() chan struct{} + PreCommit() chan error + Commit() chan struct{} ReadValue() (TLAValue, error) WriteValue(value TLAValue) error Index(index TLAValue) (ArchetypeResource, error) @@ -49,47 +56,356 @@ func (ArchetypeResourceMapMixin) WriteValue(TLAValue) error { type LocalArchetypeResource struct { ArchetypeResourceLeafMixin - hasOldValue bool - value, oldValue TLAValue + record localArchetypeResourceRecord } -func NewLocalArchetypeResource(value TLAValue) *LocalArchetypeResource { - return &LocalArchetypeResource{ - hasOldValue: false, - value: value, - } +type localArchetypeResourceRecord struct { + IsInitialized bool // start-up flag, to avoid setting up state again when reloading from disk + HasOldValue bool + Value, OldValue TLAValue +} + +var _ ArchetypeResource = &LocalArchetypeResource{} + +func EnsureLocalArchetypeResource(ensurer MPCalContextResourceEnsurer, value TLAValue) ArchetypeResourceHandle { + return ensurer(&LocalArchetypeResource{}, func(resource ArchetypeResource) { + res := resource.(*LocalArchetypeResource) + if !res.record.IsInitialized { + res.record.IsInitialized = true + res.record.Value = value + } + }) } -func (res *LocalArchetypeResource) Abort() { - if res.hasOldValue { - res.value = res.oldValue - res.hasOldValue = false - res.oldValue = TLAValue{} +func (res *LocalArchetypeResource) Abort() chan struct{} { + if res.record.HasOldValue { + res.record.Value = res.record.OldValue + res.record.HasOldValue = false + res.record.OldValue = TLAValue{} } + return nil } -func (res *LocalArchetypeResource) PreCommit() error { +func (res *LocalArchetypeResource) PreCommit() chan error { return nil } -func (res *LocalArchetypeResource) Commit() { - res.hasOldValue = false - res.oldValue = TLAValue{} +func (res *LocalArchetypeResource) Commit() chan struct{} { + res.record.HasOldValue = false + res.record.OldValue = TLAValue{} + return nil } func (res *LocalArchetypeResource) ReadValue() (TLAValue, error) { - return res.value, nil + return res.record.Value, nil } func (res *LocalArchetypeResource) WriteValue(value TLAValue) error { - if !res.hasOldValue { - res.oldValue = res.value - res.hasOldValue = true + if !res.record.HasOldValue { + res.record.OldValue = res.record.Value + res.record.HasOldValue = true + } + res.record.Value = value + return nil +} + +func (res *LocalArchetypeResource) GobDecode(input []byte) error { + buf := bytes.NewBuffer(input) + decoder := gob.NewDecoder(buf) + return decoder.Decode(&res.record) +} + +func (res *LocalArchetypeResource) GobEncode() ([]byte, error) { + var buf bytes.Buffer + encoder := gob.NewEncoder(&buf) + err := encoder.Encode(&res.record) + if err != nil { + return nil, err + } + return buf.Bytes(), nil +} + +// Input channel resource: a read-only data source backed by an externally-controlled Go channel +// --------------------------------------------------------------------------------------------- + +type InputChannelResource struct { + ArchetypeResourceLeafMixin + channel <-chan TLAValue + buffer []TLAValue +} + +var _ ArchetypeResource = &InputChannelResource{} + +func EnsureInputChannelResource(ensurer MPCalContextResourceEnsurer, channel <-chan TLAValue) ArchetypeResourceHandle { + return ensurer(&InputChannelResource{}, func(resource ArchetypeResource) { + res := resource.(*InputChannelResource) + res.channel = channel + }) +} + +func (res *InputChannelResource) Abort() chan struct{} { + return nil +} + +func (res *InputChannelResource) PreCommit() chan error { + return nil +} + +func (res *InputChannelResource) Commit() chan struct{} { + res.buffer = nil + return nil +} + +func (res *InputChannelResource) ReadValue() (TLAValue, error) { + if len(res.buffer) > 0 { + value := res.buffer[0] + res.buffer = res.buffer[1:] + return value, nil + } + + select { + case value := <-res.channel: + res.buffer = append(res.buffer, value) + return value, nil + case <-time.After(time.Millisecond * 20): + return TLAValue{}, CriticalSectionAborted } - res.value = value +} + +func (res *InputChannelResource) WriteValue(value TLAValue) error { + panic(fmt.Errorf("attempted to write %v to an input channel resource", value)) +} + +func (res *InputChannelResource) GobDecode(input []byte) error { + panic("implement me") +} + +func (res *InputChannelResource) GobEncode() ([]byte, error) { + panic("implement me") +} + +// Output channel resource: a write-only resource backed by an externally-readable Go channel +// ------------------------------------------------------------------------------------------ + +type OutputChannelResource struct { + ArchetypeResourceLeafMixin + channel chan <-TLAValue + buffer []TLAValue +} + +var _ ArchetypeResource = &OutputChannelResource{} + +func EnsureOutputChannelResource(ensurer MPCalContextResourceEnsurer, channel chan <-TLAValue) ArchetypeResourceHandle { + return ensurer(&OutputChannelResource{}, func(resource ArchetypeResource) { + res := resource.(*OutputChannelResource) + res.channel = channel + }) +} + +func (res *OutputChannelResource) Abort() chan struct{} { + res.buffer = nil + return nil +} + +func (res *OutputChannelResource) PreCommit() chan error { return nil } +func (res *OutputChannelResource) Commit() chan struct{} { + ch := make(chan struct{}) + go func() { + for _, value := range res.buffer { + res.channel <- value + } + res.buffer = nil + ch <- struct{}{} + }() + return ch +} + +func (res *OutputChannelResource) ReadValue() (TLAValue, error) { + panic(fmt.Errorf("attempted to read from an input channel resource")) +} + +func (res *OutputChannelResource) WriteValue(value TLAValue) error { + res.buffer = append(res.buffer, value) + return nil +} + +func (res *OutputChannelResource) GobDecode(i []byte) error { + panic("implement me") +} + +func (res *OutputChannelResource) GobEncode() ([]byte, error) { + panic("implement me") +} + +// A generic map resource, with hooks to programmatically and serializably realize child resources during execution +// ---------------------------------------------------------------------------------------------------------------- + +type IncrementalArchetypeMapResource struct { + ArchetypeResourceMapMixin + realizedMap *immutable.Map + FillFunction func(IncrementalArchetypeMapResourceEnsurer, TLAValue) +} + +type incrementalArchetypeMapResourceRecord struct { + Key TLAValue + Value ArchetypeResource +} + +type IncrementalArchetypeMapResourceEnsurer func(blank ArchetypeResource, configFn func(ArchetypeResource)) + +var _ ArchetypeResource = &IncrementalArchetypeMapResource{} + +func EnsureIncrementalArchetypeMapResource(ensurer MPCalContextResourceEnsurer, fillFunction func(IncrementalArchetypeMapResourceEnsurer, TLAValue)) ArchetypeResourceHandle { + return ensurer(&IncrementalArchetypeMapResource{}, func(resource ArchetypeResource) { + resource.(*IncrementalArchetypeMapResource).EnsureConfig(fillFunction) + }) +} + +func (res *IncrementalArchetypeMapResource) EnsureConfig(fillFunction func(IncrementalArchetypeMapResourceEnsurer, TLAValue)) { + if res.realizedMap == nil { + res.realizedMap = immutable.NewMap(TLAValueHasher{}) + } + // this should only happen once, because, once it happens, FillFunction will be set. + // this structure allows sub-resources to set up any static non-serializable information, if they have just + // previously been deserialized. + if res.FillFunction == nil { + res.FillFunction = fillFunction + it := res.realizedMap.Iterator() + for !it.Done() { + key, value := it.Next() + fillFunction(func(_ ArchetypeResource, configFn func(ArchetypeResource)) { + configFn(value.(ArchetypeResource)) + }, key.(TLAValue)) + } + } +} + +func (res *IncrementalArchetypeMapResource) Index(index TLAValue) (ArchetypeResource, error) { + var resource ArchetypeResource + res.FillFunction(func (blank ArchetypeResource, configFn func(ArchetypeResource)) { + if subRes, ok := res.realizedMap.Get(index); ok { + resource = subRes.(ArchetypeResource) + } else { + configFn(blank) + res.realizedMap = res.realizedMap.Set(index, blank) + resource = blank + } + }, index) + return resource, nil +} + +func (res *IncrementalArchetypeMapResource) PreCommit() chan error { + var nonTrivialPreCommits []chan error + it := res.realizedMap.Iterator() + for !it.Done() { + _, subRes := it.Next() + ch := subRes.(ArchetypeResource).PreCommit() + if ch != nil { + nonTrivialPreCommits = append(nonTrivialPreCommits, ch) + } + } + if len(nonTrivialPreCommits) == 0 { + return nil + } + outCh := make(chan error) + go func() { + var err error + for _, ch := range nonTrivialPreCommits { + err = <-ch + if err != nil { + break + } + } + outCh<- err + }() + return outCh +} + +func (res *IncrementalArchetypeMapResource) Commit() chan struct{} { + var nonTrivialCommits []chan struct{} + it := res.realizedMap.Iterator() + for !it.Done() { + _, subRes := it.Next() + ch := subRes.(ArchetypeResource).Commit() + if ch != nil { + nonTrivialCommits = append(nonTrivialCommits, ch) + } + } + if len(nonTrivialCommits) == 0 { + return nil + } + outCh := make(chan struct{}) + go func() { + for _, ch := range nonTrivialCommits { + <-ch + } + outCh<- struct{}{} + }() + return outCh +} + +func (res *IncrementalArchetypeMapResource) Abort() chan struct{} { + var nonTrivialAborts []chan struct{} + it := res.realizedMap.Iterator() + for !it.Done() { + _, subRes := it.Next() + ch := subRes.(ArchetypeResource).Abort() + if ch != nil { + nonTrivialAborts = append(nonTrivialAborts, ch) + } + } + if len(nonTrivialAborts) == 0 { + return nil + } + outCh := make(chan struct{}) + go func() { + for _, ch := range nonTrivialAborts { + <-ch + } + outCh<- struct{}{} + }() + return outCh +} + +func (res *IncrementalArchetypeMapResource) GobDecode(input []byte) error { + buf := bytes.NewBuffer(input) + decoder := gob.NewDecoder(buf) + builder := immutable.NewMapBuilder(TLAValueHasher{}) + for { + var record incrementalArchetypeMapResourceRecord + err := decoder.Decode(&record) + if err != nil { + if errors.Is(err, io.EOF) { + res.realizedMap = builder.Map() + return nil + } else { + return err + } + } + builder.Set(record.Key, record.Value) + } +} + +func (res *IncrementalArchetypeMapResource) GobEncode() ([]byte, error) { + var buf bytes.Buffer + encoder := gob.NewEncoder(&buf) + it := res.realizedMap.Iterator() + for !it.Done() { + key, value := it.Next() + err := encoder.Encode(incrementalArchetypeMapResourceRecord{ + Key: key.(TLAValue), + Value: value.(ArchetypeResource), + }) + if err != nil { + return nil, err + } + } + return buf.Bytes(), nil +} + // Global State as Archetype Resource // ---------------------------------- @@ -99,15 +415,9 @@ func (res *LocalArchetypeResource) WriteValue(value TLAValue) error { // ------------------------------- type TCPMailboxesArchetypeResource struct { - ArchetypeResourceMapMixin - Listener net.Listener - inputChannel chan TLAValue - buffer *list.List - elementsRead []TLAValue + IncrementalArchetypeMapResource } -var _ ArchetypeResource = &TCPMailboxesArchetypeResource{} - const ( tcpNetworkBegin = iota tcpNetworkValue @@ -116,155 +426,375 @@ const ( tcpNetworkCommit ) -type tcpNetworkMsg struct { - Tag int - Value TLAValue +var _ ArchetypeResource = &TCPMailboxesArchetypeResource{} + +type TCPMailboxKind int + +const ( + TCPMailboxesLocal = iota + TCPMailboxesRemote +) + +func EnsureTCPMailboxesArchetypeResource(ensurer MPCalContextResourceEnsurer, addressMappingFn func(TLAValue) (TCPMailboxKind, string)) ArchetypeResourceHandle { + return ensurer(&TCPMailboxesArchetypeResource{}, func(resource ArchetypeResource) { + res := resource.(*TCPMailboxesArchetypeResource) + res.EnsureConfig(func(ensurer IncrementalArchetypeMapResourceEnsurer, index TLAValue) { + tpe, addr := addressMappingFn(index) + switch tpe { + case TCPMailboxesLocal: + ensurer(&TCPMailboxLocalArchetypeResource{}, func(resource ArchetypeResource) { + r := resource.(*TCPMailboxLocalArchetypeResource) + r.EnsureConfig(addr) + }) + case TCPMailboxesRemote: + ensurer(&TCPMailboxRemoteArchetypeResource{}, func(resource ArchetypeResource) { + r := resource.(*TCPMailboxRemoteArchetypeResource) + r.EnsureConfig(addr) + }) + default: + panic(fmt.Errorf("invalid TCP mailbox type %d for address %s: expected local or remote, which are %d or %d", tpe, addr, TCPMailboxesLocal, TCPMailboxesRemote)) + } + }) + }) } -func NewTCPMailboxesArchetypeResource(address string) (res *TCPMailboxesArchetypeResource, err error) { - listener, err := net.Listen("tcp", address) - if err != nil { - return +type TCPMailboxLocalArchetypeResource struct { + ArchetypeResourceLeafMixin + listenAddr string + + listener net.Listener + buffer *list.List + bufferFillNotify chan struct{} + bufferLock sync.Mutex + + bufferSize int + + readBacklog []TLAValue + readsInProgress []TLAValue +} + +var _ ArchetypeResource = &TCPMailboxLocalArchetypeResource{} + +func (res *TCPMailboxLocalArchetypeResource) ensureSetup() { + res.bufferLock.Lock() + defer res.bufferLock.Unlock() + + if res.buffer == nil { + res.buffer = list.New() } - inputChannel := make(chan TLAValue, 100) - go func() { - for { - conn, err := listener.Accept() - if err != nil { - break - } - go func() { - decoder := gob.NewDecoder(conn) - encoder := gob.NewEncoder(conn) - var msgBuffer []TLAValue - for { - var msg tcpNetworkMsg - err := decoder.Decode(&msg) - if err != nil { - if errors.Is(err, io.EOF) || errors.Is(err, io.ErrUnexpectedEOF) { - return + + if res.bufferFillNotify == nil { + // ideally, the notification count should be equal to buffer size, but, for reliability, we sometimes + // store an oversize buffer. in this case, surreptitiously bump the channel size to avoid deadlock + notifyCount := res.bufferSize + if res.buffer.Len() > notifyCount { + notifyCount = res.buffer.Len() + } + res.bufferFillNotify = make(chan struct{}, notifyCount) + for i := 0; i < notifyCount; i++ { + res.bufferFillNotify <- struct{}{} + } + } + + if res.listener == nil { + var err error + res.listener, err = net.Listen("tcp", res.listenAddr) + if err != nil { + log.Fatalf("could not listen on address %s", res.listenAddr) + } + go func() { + for { + conn, err := res.listener.Accept() + if err != nil { + log.Fatalf("error listening on %s", res.listenAddr) + } + go func() { + var err error + encoder := gob.NewEncoder(conn) + decoder := gob.NewDecoder(conn) + var localBuffer []TLAValue + hasBegun := false + for { + if err != nil { + log.Printf("network error: %s", err.Error()) + break } - panic(err) // TODO: actually handle this - } - switch msg.Tag { - case tcpNetworkBegin: - msgBuffer = nil - case tcpNetworkValue: - msgBuffer = append(msgBuffer, msg.Value) - case tcpNetworkPreCommit: - err = encoder.Encode(&tcpNetworkMsg{Tag: tcpNetworkPreCommitAck}) + var tag int + err = decoder.Decode(&tag) if err != nil { - panic(err) + continue } - case tcpNetworkCommit: - for _, msg := range msgBuffer { - inputChannel <- msg + switch tag { + case tcpNetworkBegin: + if localBuffer != nil { + localBuffer = nil + } + hasBegun = true + case tcpNetworkValue: + var value TLAValue + err = decoder.Decode(&value) + if err != nil { + continue + } + localBuffer = append(localBuffer, value) + case tcpNetworkPreCommit: + err = encoder.Encode(struct{}{}) + if err != nil { + continue + } + case tcpNetworkCommit: + // when crash-proofing, we need a way to identify repeat commits + // _when an old commit was successful but didn't persist due to crash_ + // could be done by: + // - send a unique incrementing counter on pre-commit + // - commit-er sends this id on commit, and we store this commit attempt in a persistent set + // alongside the buffer itself + // - receiving two commits for the same id can be detected by looking in the set, in which + // case do nothing and reply that the thing is done. + // - starting a new critical section sends the id of the remote's last commit, which + // indicates that commit was successful, and that the id can be removed from the set + if !hasBegun { + err = encoder.Encode(true) + if err != nil { + continue + } + } else { + func() { + res.bufferLock.Lock() + defer res.bufferLock.Unlock() + // TODO: store buffer durably + for _, val := range localBuffer { + res.buffer.PushBack(val) + } + // store buffer as a locked structure, use channels to notify when important change happen + // - when the channel becomes not-full, notify any potential writers + // - when the channel becomes not-empty, notify the reader + }() + err = encoder.Encode(false) + if err != nil { + continue + } + hasBegun = false // TODO: also store durably? + // push notifications _after_ the buffer has been filled, so we guarantee that + // a filled version of the buffer has been atomically saved, while allowing + // us to block for a long time without the complication of holding a lock on the buffer + for range localBuffer { + res.bufferFillNotify <- struct{}{} + } + } } - msgBuffer = nil - default: - panic("???") } - } - }() - } - }() - return &TCPMailboxesArchetypeResource{ - Listener: listener, - inputChannel: inputChannel, - buffer: list.New(), - }, nil -} - -func (res *TCPMailboxesArchetypeResource) pumpNetwork() error { - if res.buffer.Len() == 0 { - select { - case nextElem := <-res.inputChannel: - res.buffer.PushBack(nextElem) - return nil - case <-time.After(20 * time.Millisecond): - return Aborted - } - } else { - return nil + err = conn.Close() + if err != nil { + log.Printf("error closing connection: %s", err.Error()) + } + }() + } + }() } } -func (res *TCPMailboxesArchetypeResource) Index(index TLAValue) (ArchetypeResource, error) { - panic("???") +func (res *TCPMailboxLocalArchetypeResource) EnsureConfig(addr string) { + res.listenAddr = addr + res.ensureSetup() } -func (res *TCPMailboxesArchetypeResource) Abort() { - for _, elem := range res.elementsRead { - res.buffer.PushFront(elem) - } - res.elementsRead = nil +func (res *TCPMailboxLocalArchetypeResource) Abort() chan struct{} { + res.readBacklog = append(res.readBacklog, res.readsInProgress...) + res.readsInProgress = nil + return nil } -func (res *TCPMailboxesArchetypeResource) PreCommit() error { +func (res *TCPMailboxLocalArchetypeResource) PreCommit() chan error { return nil } -func (res *TCPMailboxesArchetypeResource) Commit() { - res.elementsRead = nil +func (res *TCPMailboxLocalArchetypeResource) Commit() chan struct{} { + res.readsInProgress = nil + return nil +} + +func (res *TCPMailboxLocalArchetypeResource) ReadValue() (TLAValue, error) { + // if a critical section previously aborted, already-read values will be here + if len(res.readBacklog) > 0 { + value := res.readBacklog[0] + res.readBacklog[0] = TLAValue{} + res.readBacklog = res.readBacklog[1:] + return value, nil + } + + // otherwise, either pull a notification + atomically read a value from the buffer, or time out + select { + case <-res.bufferFillNotify: + res.bufferLock.Lock() + defer res.bufferLock.Unlock() + frontElem := res.buffer.Front() + poppedValue := frontElem.Value.(TLAValue) + res.buffer.Remove(frontElem) + res.readsInProgress = append(res.readsInProgress, poppedValue) + return poppedValue, nil + case <-time.After(20 * time.Millisecond): + return TLAValue{}, CriticalSectionAborted + } +} + +func (res *TCPMailboxLocalArchetypeResource) WriteValue(value TLAValue) error { + panic(fmt.Errorf("attempted to write value %v to a local mailbox archetype resource", value)) +} + +func (res *TCPMailboxLocalArchetypeResource) GobDecode(i []byte) error { + panic("implement me") +} + +func (res *TCPMailboxLocalArchetypeResource) GobEncode() ([]byte, error) { + panic("implement me") } type TCPMailboxRemoteArchetypeResource struct { ArchetypeResourceLeafMixin - hasBegun bool - remoteAddress string + dialAddr string + + inCriticalSection bool conn net.Conn - encoder gob.Encoder - decoder gob.Decoder + connEncoder *gob.Encoder + connDecoder *gob.Decoder + sendBuffer []TLAValue } var _ ArchetypeResource = &TCPMailboxRemoteArchetypeResource{} -func (res *TCPMailboxRemoteArchetypeResource) ReadValue() (TLAValue, error) { - return TLAValue{}, errors.New("tried to read from non-local TCP mailbox") +func (res *TCPMailboxRemoteArchetypeResource) EnsureConfig(addr string) { + res.dialAddr = addr +} + +func (res *TCPMailboxRemoteArchetypeResource) ensureConnection() error { + if res.conn == nil { + var err error + res.conn, err = net.Dial("tcp", res.dialAddr) + if err != nil { + log.Printf("failed to dial %s, aborting after 50ms: %v", res.dialAddr, err) + time.Sleep(time.Millisecond * 50) + return CriticalSectionAborted + } + res.connEncoder = gob.NewEncoder(res.conn) + res.connDecoder = gob.NewDecoder(res.conn) + } + return nil +} + +func (res *TCPMailboxRemoteArchetypeResource) Abort() chan struct{} { + res.sendBuffer = nil + // nothing to do; the remote end tolerates just starting over with no explanation + return nil } -func (res *TCPMailboxRemoteArchetypeResource) WriteValue(value TLAValue) (err error) { - if !res.hasBegun { - if res.conn == nil { - res.conn, err = net.Dial("tcp", res.remoteAddress) +func (res *TCPMailboxRemoteArchetypeResource) PreCommit() chan error { + ch := make(chan error, 1) + go func() { + var err error + { + err = res.connEncoder.Encode(tcpNetworkPreCommit) if err != nil { - return err + goto handleError + } + var ack struct{} + err = res.connDecoder.Decode(&ack) + if err != nil { + goto handleError } + ch <- nil + return } - err = res.encoder.Encode(tcpNetworkMsg{Tag: tcpNetworkBegin}) - if err != nil { - return err + handleError: + log.Printf("network error while performing pre-commit handshake, aborting: %v", err) + res.conn = nil + ch <- CriticalSectionAborted + }() + return ch +} + +func (res *TCPMailboxRemoteArchetypeResource) Commit() chan struct{} { + ch := make(chan struct{}, 1) + go func() { + var err error + outerLoop: + for { + if err != nil { + log.Printf("network error during commit, resetting: %v", err) + res.conn = nil + } + err = res.ensureConnection() + if err != nil { + continue outerLoop + } + err = res.connEncoder.Encode(tcpNetworkCommit) + if err != nil { + continue outerLoop + } + var shouldResend bool + err = res.connDecoder.Decode(&shouldResend) + if err != nil { + continue outerLoop + } + if shouldResend { + err = res.connEncoder.Encode(tcpNetworkBegin) + if err != nil { + continue outerLoop + } + for _, value := range res.sendBuffer { + err = res.connEncoder.Encode(tcpNetworkValue) + if err != nil { + continue outerLoop + } + err = res.connEncoder.Encode(&value) + if err != nil { + continue outerLoop + } + } + continue outerLoop + } + res.sendBuffer = nil + ch <- struct{}{} + return } - } - return res.encoder.Encode(tcpNetworkMsg{Tag: tcpNetworkValue, Value: value}) + }() + return ch } -func (res *TCPMailboxRemoteArchetypeResource) Abort() { - res.hasBegun = false +func (res *TCPMailboxRemoteArchetypeResource) ReadValue() (TLAValue, error) { + panic(fmt.Errorf("attempted to read from a remote mailbox archetype resource")) } -func (res *TCPMailboxRemoteArchetypeResource) PreCommit() error { - err := res.encoder.Encode(tcpNetworkMsg{Tag: tcpNetworkPreCommit}) +func (res *TCPMailboxRemoteArchetypeResource) WriteValue(value TLAValue) error { + err := res.ensureConnection() if err != nil { - res.conn = nil - return Aborted + return err + } + if !res.inCriticalSection { + err = res.connEncoder.Encode(tcpNetworkBegin) + if err != nil { + goto handleError + } } - var msg tcpNetworkMsg - err = res.decoder.Decode(&msg) - if msg.Tag != tcpNetworkPreCommitAck { - panic("???") + err = res.connEncoder.Encode(tcpNetworkValue) + if err != nil { + goto handleError + } + err = res.connEncoder.Encode(&value) + if err != nil { + goto handleError } return nil +handleError: + log.Printf("network error during remote value write, aborting: %v", err) + res.conn = nil + return CriticalSectionAborted } -func (res *TCPMailboxRemoteArchetypeResource) Commit() { - res.hasBegun = false - err := res.encoder.Encode(tcpNetworkMsg{Tag: tcpNetworkCommit}) - if err != nil { - panic(err) // can't support this failure... - } +func (res *TCPMailboxRemoteArchetypeResource) GobDecode(i []byte) error { + panic("implement me") } -type TCPMailboxLocalArchetypeResource struct { - ArchetypeResourceLeafMixin +func (res *TCPMailboxRemoteArchetypeResource) GobEncode() ([]byte, error) { + panic("implement me") } diff --git a/distsys/mpcal.go b/distsys/mpcal.go index 3bc4eb97f..43e08b6d2 100644 --- a/distsys/mpcal.go +++ b/distsys/mpcal.go @@ -1,86 +1,232 @@ package distsys -func WhileCatchingPanics(fns ...func() TLAValue) (result []TLAValue, err error) { - defer func() { - if r := recover(); r != nil { - result = nil - err = r.(error) - } - }() - for _, fn := range fns { - result = append(result, fn()) +import ( + "errors" + "fmt" +) + +var AssertionFailed = errors.New("assertion failed") + +type ArchetypeResourceHandle struct { + Tag int + Index int + Name string +} + +const ( + ArchetypeResourceNamedTag = iota + ArchetypeResourceIndexedTag +) + +type MPCalDurableStorageRecord struct { + Resources []ArchetypeResource + Frame int + FrameStack []int + ResourcesByName map[string]ArchetypeResource + CommitPending map[ArchetypeResourceHandle]bool +} + +func (record *MPCalDurableStorageRecord) getResourceByHandle(handle ArchetypeResourceHandle) ArchetypeResource { + switch handle.Tag { + case ArchetypeResourceNamedTag: + return record.ResourcesByName[handle.Name] + case ArchetypeResourceIndexedTag: + return record.Resources[handle.Index] + default: + panic(fmt.Errorf("could not find archetype resource by handle %v", handle)) } - return } -type PCalSectionContext struct { - resources []ArchetypeResource +type MPCalDurableStorage interface { + RecoverResources() (rec *MPCalDurableStorageRecord, err error) + SnapshotResources(rec *MPCalDurableStorageRecord) } -func NewPCalSectionContext() *PCalSectionContext { - return &PCalSectionContext{} +type MPCalContext struct { + durableStorage MPCalDurableStorage + record MPCalDurableStorageRecord } -func (ctx *PCalSectionContext) recordResource(res ArchetypeResource) { - for _, existingRes := range ctx.resources { - if existingRes == res { - return +func NewMPCalContext(durableStorage MPCalDurableStorage) (*MPCalContext, error) { + record, err := durableStorage.RecoverResources() + if err != nil { + return nil, err + } + if record == nil { + record = &MPCalDurableStorageRecord{ + ResourcesByName: make(map[string]ArchetypeResource), + } + } + if record.CommitPending != nil { + var nonTrivialOutstandingCommits []chan struct{} + for resHandle := range record.CommitPending { + ch := record.getResourceByHandle(resHandle).Commit() + if ch != nil { + nonTrivialOutstandingCommits = append(nonTrivialOutstandingCommits, ch) + } + } + for _, ch := range nonTrivialOutstandingCommits { + <-ch } + for resHandle := range record.CommitPending { + delete(record.CommitPending, resHandle) + } + durableStorage.SnapshotResources(record) } - ctx.resources = append(ctx.resources, res) + return &MPCalContext{ + durableStorage: durableStorage, + record: *record, + }, nil } -func (ctx *PCalSectionContext) Abort() { - for i := len(ctx.resources) - 1; i >= 0; i-- { - ctx.resources[i].Abort() + +type MPCalContextArchetypeConfigFn func(durability MPCalDurableStorage, resource ArchetypeResource) + +type MPCalContextResourceEnsurer func(blank ArchetypeResource, configFn func(resource ArchetypeResource)) ArchetypeResourceHandle + +func (ctx *MPCalContext) ResourceEnsurerByName(name string) MPCalContextResourceEnsurer { + return func(blank ArchetypeResource, configFn func(ArchetypeResource)) ArchetypeResourceHandle { + resource, ok := ctx.record.ResourcesByName[name] + if !ok { + ctx.record.ResourcesByName[name] = blank + resource = blank + } + configFn(resource) + return ArchetypeResourceHandle{ + Tag: ArchetypeResourceNamedTag, + Name: name, + } } } -func (ctx *PCalSectionContext) Commit() (err error) { - for i := len(ctx.resources) - 1; i >= 0; i-- { - err = ctx.resources[i].PreCommit() - if err != nil { - break +func (ctx *MPCalContext) ResourceEnsurerPositional() MPCalContextResourceEnsurer { + return func(blank ArchetypeResource, configFn func(ArchetypeResource)) ArchetypeResourceHandle { + var resource ArchetypeResource + if ctx.record.Frame == len(ctx.record.Resources) { + resource = blank + ctx.record.Resources = append(ctx.record.Resources, blank) + } else { + resource = ctx.record.Resources[ctx.record.Frame] + } + configFn(resource) + resourcePosition := ctx.record.Frame + ctx.record.Frame += 1 + return ArchetypeResourceHandle{ + Tag: ArchetypeResourceIndexedTag, + Index: resourcePosition, } } - if err != nil { - for i := len(ctx.resources) - 1; i >= 0; i-- { - ctx.resources[i].Abort() +} + +func (ctx *MPCalContext) PositionalResourceStackPush() { + ctx.record.FrameStack = append(ctx.record.FrameStack, ctx.record.Frame) +} + +func (ctx *MPCalContext) PositionalResourceStackPop() { + ctx.record.Frame = ctx.record.FrameStack[len(ctx.record.FrameStack) - 1] + ctx.record.FrameStack = ctx.record.FrameStack[:len(ctx.record.FrameStack) - 1] + ctx.record.Resources = ctx.record.Resources[:ctx.record.Frame] +} + +func (ctx *MPCalContext) Abort() { + if ctx.record.CommitPending == nil { + return + } + var nonTrivialAborts []chan struct{} + for resHandle := range ctx.record.CommitPending { + ch := ctx.record.getResourceByHandle(resHandle).Abort() + if ch != nil { + nonTrivialAborts = append(nonTrivialAborts, ch) } - } else { - for i := len(ctx.resources) - 1; i >= 0; i-- { - ctx.resources[i].Commit() + } + for _, ch := range nonTrivialAborts { + <-ch + } + + // clear any touched resources (compiler will optimise this, see https://golang.org/doc/go1.11#performance-compiler) + for resHandle := range ctx.record.CommitPending { + delete(ctx.record.CommitPending, resHandle) + } +} + +func (ctx *MPCalContext) Commit() (err error) { + if ctx.record.CommitPending == nil { + return // in the unlikely event this is reachable, skip it + } + + // dispatch all parts of the pre-commit phase asynchronously, so we only wait as long as the slowest resource + var nonTrivialPreCommits []chan error + for resHandle := range ctx.record.CommitPending { + ch := ctx.record.getResourceByHandle(resHandle).PreCommit() + if ch != nil { + nonTrivialPreCommits = append(nonTrivialPreCommits, ch) + } + } + for _, ch := range nonTrivialPreCommits { + localErr := <-ch + if localErr != nil { + err = localErr + } + } + + // if there was an error, stop now, and expect either (1) total crash of (2) Abort to be called + if err != nil { + return + } + + // we commit to committing, so apply any durable persistence here, so we recover to this point if we crash + ctx.durableStorage.SnapshotResources(&ctx.record) + + // same as above, run all the commit processes async + var nonTrivialCommits []chan struct{} + for resHandle := range ctx.record.CommitPending { + ch := ctx.record.getResourceByHandle(resHandle).Commit() + if ch != nil { + nonTrivialCommits = append(nonTrivialCommits, ch) } } + for _, ch := range nonTrivialCommits { + <-ch + } + + // if we have not crashed, we successfully committed everything, so snapshot state again, but without + // the in-progress commit, as we are done. + for resHandle := range ctx.record.CommitPending { + delete(ctx.record.CommitPending, resHandle) + } + ctx.durableStorage.SnapshotResources(&ctx.record) return } -func (ctx *PCalSectionContext) Write(resource ArchetypeResource, indices []TLAValue, value TLAValue) error { - ctx.recordResource(resource) - if len(indices) == 0 { - return resource.WriteValue(value) - } else { - resAtIndex, err := resource.Index(indices[0]) - if err != nil { - return err - } - return ctx.Write(resAtIndex, indices[1:], value) +func (ctx *MPCalContext) ensureCriticalSectionWith(handle ArchetypeResourceHandle) { + if ctx.record.CommitPending == nil { + ctx.record.CommitPending = make(map[ArchetypeResourceHandle]bool) } + ctx.record.CommitPending[handle] = true } -func (ctx *PCalSectionContext) Read(resource ArchetypeResource, indices []TLAValue) TLAValue { - ctx.recordResource(resource) - if len(indices) == 0 { - value, err := resource.ReadValue() +func (ctx *MPCalContext) Write(handle ArchetypeResourceHandle, indices []TLAValue, value TLAValue) (err error) { + ctx.ensureCriticalSectionWith(handle) + res := ctx.record.getResourceByHandle(handle) + for _, index := range indices { + res, err = res.Index(index) if err != nil { - panic(err) + return } - return value - } else { - resAtIndex, err := resource.Index(indices[0]) + } + err = res.WriteValue(value) + return +} + +func (ctx *MPCalContext) Read(handle ArchetypeResourceHandle, indices []TLAValue) (value TLAValue, err error) { + ctx.ensureCriticalSectionWith(handle) + res := ctx.record.getResourceByHandle(handle) + for _, index := range indices { + res, err = res.Index(index) if err != nil { - panic(err) + return } - return ctx.Read(resAtIndex, indices[1:]) } + value, err = res.ReadValue() + return } diff --git a/distsys/tlaplus.go b/distsys/tlaplus.go index 6b6a5220b..4bb38d070 100644 --- a/distsys/tlaplus.go +++ b/distsys/tlaplus.go @@ -1,12 +1,14 @@ package distsys import ( + "bytes" "encoding/binary" "encoding/gob" "errors" "fmt" "github.com/benbjohnson/immutable" "hash/fnv" + "io" "strconv" "strings" ) @@ -14,17 +16,19 @@ import ( var TLATypeError = errors.New("TLA+ type error") func init() { - gob.Register(tlaValueBool(true)) + gob.Register(tlaValueBool(false)) gob.Register(tlaValueNumber(0)) gob.Register(tlaValueString("")) - gob.Register(tlaValueSet{}) - gob.Register(tlaValueTuple{}) + gob.Register(&tlaValueSet{}) + gob.Register(&tlaValueTuple{}) } type TLAValue struct { data tlaValueImpl } +var _ fmt.Stringer = TLAValue{} + func (v TLAValue) Hash() uint32 { if v.data == nil { return 0 @@ -51,12 +55,25 @@ func (v TLAValue) String() string { } } +func (v *TLAValue) GobDecode(input []byte) error { + buf := bytes.NewBuffer(input) + decoder := gob.NewDecoder(buf) + return decoder.Decode(&v.data) +} + +func (v *TLAValue) GobEncode() ([]byte, error) { + var buf bytes.Buffer + encoder := gob.NewEncoder(&buf) + err := encoder.Encode(&v.data) + return buf.Bytes(), err +} + func (v TLAValue) AsBool() bool { switch data := v.data.(type) { case tlaValueBool: return bool(data) default: - panic(TLATypeError) + panic(fmt.Errorf("%w: %v is not a boolean", TLATypeError, v)) } } @@ -65,7 +82,7 @@ func (v TLAValue) AsNumber() int32 { case tlaValueNumber: return int32(data) default: - panic(TLATypeError) + panic(fmt.Errorf("%w: %v is not a number", TLATypeError, v)) } } @@ -74,30 +91,35 @@ func (v TLAValue) AsString() string { case tlaValueString: return string(data) default: - panic(TLATypeError) + panic(fmt.Errorf("%w: %v is not a string", TLATypeError, v)) } } -func (v TLAValue) AsSet() immutable.Map { +func (v TLAValue) AsSet() *immutable.Map { switch data := v.data.(type) { - case tlaValueSet: - return immutable.Map(data) + case *tlaValueSet: + return data.Map default: - panic(TLATypeError) + panic(fmt.Errorf("%w: %v is not a set", TLATypeError, v)) } } -func (v TLAValue) AsTuple() immutable.List { +func (v TLAValue) AsTuple() *immutable.List { switch data := v.data.(type) { - case tlaValueTuple: - return immutable.List(data) + case *tlaValueTuple: + return data.List default: - panic(TLATypeError) + panic(fmt.Errorf("%w: %v is not a tuple", TLATypeError, v)) } } -func (v TLAValue) IsTrue() bool { - return v.AsBool() +func (v TLAValue) AsFunction() *tlaValueFunction { + switch data := v.data.(type) { + case *tlaValueFunction: + return data + default: + panic(fmt.Errorf("%w: %v is not a function", TLATypeError, v)) + } } func (v TLAValue) SelectElement() TLAValue { @@ -107,18 +129,42 @@ func (v TLAValue) SelectElement() TLAValue { key, _ := it.Next() return key.(TLAValue) } else { - panic(fmt.Errorf("")) + panic(fmt.Errorf("tried to select an element of %v, which was an empty set", v)) } } +func (v TLAValue) ApplyFunction(argument TLAValue) TLAValue { + switch data := v.data.(type) { + case *tlaValueTuple: + return data.Get(int(argument.AsNumber())).(TLAValue) + case *tlaValueFunction: + value, ok := data.Get(argument) + if !ok { + panic(fmt.Errorf("function %v's domain does not contain index %v", v, argument)) + } + return value.(TLAValue) + default: + panic(fmt.Errorf("%w: could not apply %v", TLATypeError, v)) + } +} + +func TLA_EqualsSymbol(lhs, rhs TLAValue) TLAValue { + if lhs.Equal(rhs) { + return TLA_TRUE + } else { + return TLA_FALSE + } +} type TLAValueHasher struct{} +var _ immutable.Hasher = TLAValueHasher{} + func (TLAValueHasher) Hash(key interface{}) uint32 { return key.(TLAValue).Hash() } -func (hasher TLAValueHasher) Equal(a, b interface{}) bool { +func (TLAValueHasher) Equal(a, b interface{}) bool { return a.(TLAValue).Equal(b.(TLAValue)) } @@ -130,6 +176,8 @@ type tlaValueImpl interface { type tlaValueBool bool +var _ tlaValueImpl = tlaValueBool(false) + var TLA_TRUE = TLAValue{tlaValueBool(true)} var TLA_FALSE = TLAValue{tlaValueBool(false)} @@ -156,6 +204,8 @@ func (v tlaValueBool) String() string { type tlaValueNumber int32 +var _ tlaValueImpl = tlaValueNumber(0) + func NewTLANumber(num int32) TLAValue { return TLAValue{tlaValueNumber(num)} } @@ -178,11 +228,17 @@ func (v tlaValueNumber) String() string { } func TLA_PlusSymbol(lhs, rhs TLAValue) TLAValue { - return TLAValue{tlaValueNumber(lhs.AsNumber() + rhs.AsNumber())} + return NewTLANumber(lhs.AsNumber() + rhs.AsNumber()) +} + +func TLA_PercentSymbol(lhs, rhs TLAValue) TLAValue { + return NewTLANumber(lhs.AsNumber() % rhs.AsNumber()) } type tlaValueString string +var _ tlaValueImpl = tlaValueString("") + func NewTLAString(value string) TLAValue { return TLAValue{tlaValueString(value)} } @@ -205,20 +261,23 @@ func (v tlaValueString) String() string { return strconv.Quote(string(v)) } -type tlaValueSet immutable.Map +type tlaValueSet struct { + *immutable.Map +} + +var _ tlaValueImpl = new(tlaValueSet) func NewTLASet(members ...TLAValue) TLAValue { builder := immutable.NewMapBuilder(TLAValueHasher{}) for _, member := range members { builder.Set(member, true) } - return TLAValue{tlaValueSet(*builder.Map())} + return TLAValue{&tlaValueSet{builder.Map()}} } -func (v tlaValueSet) Hash() uint32 { - vC := immutable.Map(v) +func (v *tlaValueSet) Hash() uint32 { var hash uint32 = 0 - it := vC.Iterator() + it := v.Iterator() for !it.Done() { key, _ := it.Next() keyV := key.(TLAValue) @@ -233,13 +292,12 @@ func (v tlaValueSet) Hash() uint32 { return h.Sum32() } -func (v tlaValueSet) Equal(other TLAValue) bool { - vC := immutable.Map(v) +func (v *tlaValueSet) Equal(other TLAValue) bool { oC := other.AsSet() - if vC.Len() != oC.Len() { + if v.Len() != oC.Len() { return false } else { - it := vC.Iterator() + it := v.Iterator() for !it.Done() { k, _ := it.Next() _, ok := oC.Get(k) @@ -250,7 +308,7 @@ func (v tlaValueSet) Equal(other TLAValue) bool { it = oC.Iterator() for !it.Done() { k, _ := it.Next() - _, ok := vC.Get(k) + _, ok := v.Get(k) if !ok { return false } @@ -259,11 +317,10 @@ func (v tlaValueSet) Equal(other TLAValue) bool { } } -func (v tlaValueSet) String() string { +func (v *tlaValueSet) String() string { builder := strings.Builder{} builder.WriteString("{") - vC := immutable.Map(v) - it := vC.Iterator() + it := v.Iterator() first := true for !it.Done() { if first { @@ -278,20 +335,56 @@ func (v tlaValueSet) String() string { return builder.String() } -type tlaValueTuple immutable.List +func (v *tlaValueSet) GobEncode() ([]byte, error) { + var buf bytes.Buffer + encoder := gob.NewEncoder(&buf) + it := v.Iterator() + for !it.Done() { + elem, _ := it.Next() + err := encoder.Encode(elem.(TLAValue)) + if err != nil { + return nil, err + } + } + return buf.Bytes(), nil +} + +func (v *tlaValueSet) GobDecode(input []byte) error { + buf := bytes.NewBuffer(input) + decoder := gob.NewDecoder(buf) + builder := immutable.NewMapBuilder(TLAValueHasher{}) + for { + var elem TLAValue + err := decoder.Decode(&elem) + if err != nil { + if errors.Is(err, io.EOF) { + v.Map = builder.Map() + return nil + } else { + return err + } + } + builder.Set(elem, true) + } +} + +type tlaValueTuple struct { + *immutable.List +} + +var _ tlaValueImpl = new(tlaValueTuple) func NewTLATuple(members ...TLAValue) TLAValue { builder := immutable.NewListBuilder() for _, member := range members { builder.Append(member) } - return TLAValue{tlaValueTuple(*builder.List())} + return TLAValue{&tlaValueTuple{builder.List()}} } -func (v tlaValueTuple) Hash() uint32 { - vC := immutable.List(v) +func (v *tlaValueTuple) Hash() uint32 { h := fnv.New32() - it := vC.Iterator() + it := v.Iterator() for !it.Done() { _, member := it.Next() memberV := member.(TLAValue) @@ -303,13 +396,12 @@ func (v tlaValueTuple) Hash() uint32 { return h.Sum32() } -func (v tlaValueTuple) Equal(other TLAValue) bool { - vC := immutable.List(v) - oC := other.AsTuple() - if vC.Len() != oC.Len() { +func (v *tlaValueTuple) Equal(other TLAValue) bool { + otherTuple := other.AsTuple() + if v.Len() != otherTuple.Len() { return false } - it1, it2 := vC.Iterator(), oC.Iterator() + it1, it2 := v.Iterator(), otherTuple.Iterator() for !it1.Done() || !it2.Done() { _, elem1 := it1.Next() _, elem2 := it2.Next() @@ -320,11 +412,10 @@ func (v tlaValueTuple) Equal(other TLAValue) bool { return true } -func (v tlaValueTuple) String() string { - vC := immutable.List(v) +func (v *tlaValueTuple) String() string { builder := strings.Builder{} builder.WriteString("<<") - it := vC.Iterator() + it := v.Iterator() first := true for !it.Done() { if first { @@ -338,3 +429,155 @@ func (v tlaValueTuple) String() string { builder.WriteString(">>") return builder.String() } + +func (v *tlaValueTuple) GobEncode() ([]byte, error) { + var buf bytes.Buffer + encoder := gob.NewEncoder(&buf) + it := v.Iterator() + for !it.Done() { + _, elem := it.Next() + err := encoder.Encode(elem) + if err != nil { + return nil, err + } + } + return buf.Bytes(), nil +} + +func (v *tlaValueTuple) GobDecode(input []byte) error { + buf := bytes.NewBuffer(input) + decoder := gob.NewDecoder(buf) + builder := immutable.NewListBuilder() + for { + var elem TLAValue + err := decoder.Decode(&elem) + if err != nil { + if errors.Is(err, io.EOF) { + v.List = builder.List() + return nil + } else { + return err + } + } + builder.Append(elem) + } +} + +type tlaValueFunction struct { + *immutable.Map + domain, rng *TLAValue +} + +type TLARecordField struct { + Key, Value TLAValue +} + +func (field TLARecordField) Hash() uint32 { + h := fnv.New32() + err := binary.Write(h, binary.LittleEndian, field.Key.Hash()) + if err != nil { + panic(err) + } + err = binary.Write(h, binary.LittleEndian, field.Value.Hash()) + if err != nil { + panic(err) + } + return h.Sum32() +} + +var _ tlaValueImpl = &tlaValueFunction{} + +func NewTLARecord(pairs []TLARecordField) TLAValue { + builder := immutable.NewMapBuilder(TLAValueHasher{}) + for _, pair := range pairs { + builder.Set(pair.Key, pair.Value) + } + return TLAValue{&tlaValueFunction{Map: builder.Map()}} +} + +func (v *tlaValueFunction) Hash() uint32 { + var hash uint32 + it := v.Iterator() + for !it.Done() { + key, value := it.Next() + hash ^= TLARecordField{Key: key.(TLAValue), Value: value.(TLAValue)}.Hash() + } + h := fnv.New32() + err := binary.Write(h, binary.LittleEndian, hash) + if err != nil { + panic(err) + } + return h.Sum32() +} + +func (v *tlaValueFunction) Equal(other TLAValue) bool { + otherFunction := other.AsFunction() + if v.Len() != otherFunction.Len() { + return false + } + it := v.Iterator() + for !it.Done() { + key, value := it.Next() + otherValue, ok := otherFunction.Get(key) + if !ok || !value.(TLAValue).Equal(otherValue.(TLAValue)) { + return false + } + } + return true +} + +func (v *tlaValueFunction) String() string { + builder := strings.Builder{} + builder.WriteString("[") + first := true + it := v.Iterator() + for !it.Done() { + key, value := it.Next() + if first { + first = false + } else { + builder.WriteString(", ") + } + builder.WriteString(key.(TLAValue).String()) + builder.WriteString(" |-> ") + builder.WriteString(value.(TLAValue).String()) + } + builder.WriteString("]") + return builder.String() +} + +func (v *tlaValueFunction) GobEncode() ([]byte, error) { + var buf bytes.Buffer + encoder := gob.NewEncoder(&buf) + it := v.Iterator() + for !it.Done() { + key, value := it.Next() + err := encoder.Encode(TLARecordField{ + Key: key.(TLAValue), + Value: value.(TLAValue), + }) + if err != nil { + return nil, err + } + } + return buf.Bytes(), nil +} + +func (v *tlaValueFunction) GobDecode(input []byte) error { + buf := bytes.NewBuffer(input) + decoder := gob.NewDecoder(buf) + builder := immutable.NewMapBuilder(TLAValueHasher{}) + for { + var field TLARecordField + err := decoder.Decode(&field) + if err != nil { + if errors.Is(err, io.EOF) { + v.Map = builder.Map() + return nil + } else { + return err + } + } + builder.Set(field.Key, field.Value) + } +} diff --git a/src/pgo/PGo.scala b/src/pgo/PGo.scala index 4067b6904..252be07cf 100644 --- a/src/pgo/PGo.scala +++ b/src/pgo/PGo.scala @@ -128,7 +128,10 @@ object PGo { } Nil } catch { - case err: PGoError => err.errors + case err: PGoError => + err.errors + // ensure you don't see the same msg twice + .distinctBy(e => (e.sourceLocation.longDescription + d"\n" + e.description).linesIterator.mkString("\n")) } } diff --git a/src/pgo/trans/MPCalGoCodegenPass.scala b/src/pgo/trans/MPCalGoCodegenPass.scala index 88a521435..1cad235e4 100644 --- a/src/pgo/trans/MPCalGoCodegenPass.scala +++ b/src/pgo/trans/MPCalGoCodegenPass.scala @@ -1,6 +1,6 @@ package pgo.trans -import pgo.model.{Definition, PGoError, RefersTo, Visitable} +import pgo.model.{Definition, DefinitionOne, PGoError, RefersTo, Rewritable, Visitable} import pgo.model.mpcal._ import pgo.model.pcal._ import pgo.model.tla._ @@ -16,8 +16,7 @@ import scala.collection.{View, mutable} object MPCalGoCodegenPass { private val TLAValue = "distsys.TLAValue" - private val ArchetypeResource = "distsys.ArchetypeResource" - private val LocalArchetypeResource = "*distsys.LocalArchetypeResource" + private val ArchetypeResourceHandle = "distsys.ArchetypeResourceHandle" val goKeywords: List[String] = """ |break default func interface select @@ -36,13 +35,11 @@ object MPCalGoCodegenPass { final case class ResourceBinding(bind: String) extends Binding case class GoCodegenContext(nameCleaner: NameCleaner, bindings: IdMap[RefersTo.HasReferences,Binding] = IdMap.empty, - errOpt: Option[Description] = None, constantsOpt: Option[String] = None, - sectionCtxOpt: Option[Description] = None, currentLabelOpt: Option[Description] = None, - resourceMappingCounts: IdMap[RefersTo.HasReferences,Int] = IdMap.empty) { + errOpt: Option[Description] = None, + ctxName: String, selfName: String, constantsName: String, constantsTypeName: String, + resourceMappingCounts: IdMap[RefersTo.HasReferences,Int] = IdMap.empty + ) { def err: Description = errOpt.get - def constants: String = constantsOpt.get - def sectionCtx: Description = sectionCtxOpt.get - def currentLabel: Description = currentLabelOpt.get def cleanName[T](hint: String)(fn: String => T): T = fn(nameCleaner.cleanName(hint)) } @@ -50,8 +47,12 @@ object MPCalGoCodegenPass { def toGoPublicName(id: String): String = id.capitalize - def translateBody(body: List[PCalStatement])(implicit ctx: GoCodegenContext): Description = { + def translateMPCalCallable(callableName: String, selfDeclOpt: Option[TLADefiningIdentifier], params: List[MPCalParam], variables: List[PCalVariableDeclaration], body: List[PCalStatement])(implicit ctx: GoCodegenContext): Description = { assert(body.forall(_.isInstanceOf[PCalLabeledStatements])) + val nameCleaner = ctx.nameCleaner + + val programCounterResourceName = nameCleaner.cleanName("programCounter") + val err = nameCleaner.cleanName("err") val pcalEithers = locally { val acc = mutable.ListBuffer.empty[PCalEither] @@ -64,54 +65,112 @@ object MPCalGoCodegenPass { .map(either => either -> ctx.nameCleaner.cleanName("fairnessCounter")) .to(IdMap) - def readExprs(exprs: List[TLAExpression])(fn: Description=>Description)(implicit ctx: GoCodegenContext): Description = { - ctx.cleanName("exprReads") { exprReads => - d"\nvar $exprReads []$TLAValue" + - d"\n$exprReads, ${ctx.err} = distsys.WhileCatchingPanics(${ - exprs.map { expr => - d"func() $TLAValue { return ${translateExpr(expr)} }" - }.separateBy(d", ") - })" + - d"\nif ${ctx.err} != nil {${ - (d"\n${ctx.sectionCtx}.Abort()" + - d"\nif ${ctx.err} == distsys.Aborted {${ - d"\ngoto ${ctx.currentLabel}".indented - }\n} else {${ - d"\nreturn ${ctx.err}".indented - }\n}").indented - }\n}" + - fn(exprReads.toDescription) + val labelBinds = body.view.map { + case PCalLabeledStatements(label, statements) => + label.name -> s"${ctx.nameCleaner.cleanName(label.name)}LabelTag" + }.toMap + + def readExpr(expr: TLAExpression, hint: String = "resourceRead")(fn: Description=>Description)(implicit ctx: GoCodegenContext): Description = { + val resourceReads = mutable.ListBuffer[(DefinitionOne,PCalVariableDeclarationEmpty,List[TLAExpression])]() + lazy val readReplacer: PartialFunction[Rewritable,Rewritable] = { + case expr@MappedRead(mappingCount, ident) if ctx.resourceMappingCounts.get(ident.refersTo).contains(mappingCount) => + @tailrec + def findIndices(expr: TLAExpression, acc: mutable.ListBuffer[TLAExpression]): List[TLAExpression] = + expr match { + case _: TLAGeneralIdentifier => acc.result() + case TLAFunctionCall(fn, params) => + if(params.size == 1) { + acc.prepend(params.head) + } else { + acc.prepend(TLATuple(params)) + } + findIndices(fn, acc) + } + + val indices = findIndices(expr, mutable.ListBuffer.empty).map(_.rewrite(Rewritable.TopDownFirstStrategy)(readReplacer)) + val cleanName = ctx.nameCleaner.cleanName(hint) + val replacementDefn = PCalVariableDeclarationEmpty(TLAIdentifier(cleanName)) + val replacementAST = TLAGeneralIdentifier(TLAIdentifier(cleanName), Nil).setRefersTo(replacementDefn) + resourceReads += ((ident.refersTo, replacementDefn, indices)) + replacementAST + case ident@TLAGeneralIdentifier(_, prefix) => + assert(prefix.isEmpty) + ctx.bindings(ident.refersTo) match { + case ResourceBinding(_) => + val cleanName = ctx.nameCleaner.cleanName(hint) + val replacementDefn = PCalVariableDeclarationEmpty(TLAIdentifier(cleanName)) + val replacementAST = TLAGeneralIdentifier(TLAIdentifier(cleanName), Nil).setRefersTo(replacementDefn) + resourceReads += ((ident.refersTo, replacementDefn, Nil)) + replacementAST + case _ => ident + } } + val exprWithReads = expr.rewrite(Rewritable.TopDownFirstStrategy)(readReplacer) + val origCtx = ctx + locally { + implicit val ctx: GoCodegenContext = origCtx.copy(bindings = origCtx.bindings ++ resourceReads.view.map { + case (_, replaceDefn, _) => replaceDefn -> FixedValueBinding(replaceDefn.name.id) + }) + resourceReads.view.map { + case (defn, replaceDefn, indices) => + d"\nvar ${replaceDefn.name.id} $TLAValue" + + d"\n${replaceDefn.name.id}, ${ctx.err} = ${ctx.ctxName}.Read(${ctx.bindings(defn).bind}, []$TLAValue{${indices.view.map(translateExpr)}})" + + d"\nif ${ctx.err} != nil {${ + d"\ncontinue".indented + }\n}" + }.flattenDescriptions + + fn(translateExpr(exprWithReads)) + } + } + + def readExprs(exprs: List[(TLAExpression,String)])(fn: List[Description]=>Description)(implicit ctx: GoCodegenContext): Description = { + def impl(exprs: List[(TLAExpression,String)], acc: mutable.ListBuffer[Description]): Description = + exprs match { + case Nil => fn(acc.result()) + case (expr, hint) :: restExprs => + readExpr(expr, hint = hint) { exprRead => + acc.append(exprRead) + impl(restExprs, acc) + } + } + + impl(exprs, mutable.ListBuffer[Description]()) } def commit(body: =>Description)(implicit ctx: GoCodegenContext): Description = - d"\nswitch ${ctx.err} = ${ctx.sectionCtx}.Commit(); ${ctx.err} {" + - d"\ncase error(nil):" + - body.indented + - d"\ncase distsys.Aborted:" + - d"\ngoto ${ctx.currentLabel}".indented + - d"\ndefault:" + - d"\nreturn ${ctx.err}".indented + - d"\n}" + d"\n${ctx.err} = ${ctx.ctxName}.Commit()" + + d"\nif ${ctx.err} != nil {${ + d"\ncontinue".indented + }\n}" + + body + + def goto(label: String)(implicit ctx: GoCodegenContext): Description = + d"\n${ctx.err} = ${ctx.ctxName}.Write($programCounterResourceName, []$TLAValue{}, distsys.NewTLANumber(${labelBinds(label)}))" + + d"\nif ${ctx.err} != nil {${ + d"\ncontinue".indented + }\n}" def impl(stmts: List[PCalStatement], pfxDesc: Description = d"")(implicit ctx: GoCodegenContext): Description = stmts match { case Nil => d"$pfxDesc\n// no statements" case PCalGoto(target) :: Nil => - pfxDesc + commit(d"\ngoto $target") + pfxDesc + goto(target) + commit(d"") case PCalReturn() :: Nil => pfxDesc + commit(d"\nreturn nil") case PCalExtensionStatement(call@MPCalCall(_, arguments)) :: restStmts => - val exprArgs = arguments.collect { case Right(expr) => expr } + ??? // generate a jump to a separate, synthetic block. this block will have its own PC, and control will + // go through it to call the procedure. When the procedure returns, that block will take care of executing + // the correct jump (not considered: tail calls). + /*val exprArgs = arguments.collect { case Right(expr) => expr } val exprArgIndices = exprArgs.view.zipWithIndex.to(IdMap) pfxDesc + readExprs(exprArgs) { exprReads => commit { val IndependentCallableBinding(nameToCall) = ctx.bindings(call.refersTo) - d"\n${ctx.err} = $nameToCall(${ctx.constants}${ + d"\n${ctx.err} = $nameToCall(${ctx.constantsName}${ arguments.map { case Left(ref) => d", ${ctx.bindings(ref.refersTo).bind}" - case Right(expr) => d", $exprReads[${exprArgIndices(expr)}]" + case Right(expr) => d", ${exprReads(exprArgIndices(expr))}" } })" + d"\nif ${ctx.err} != nil {${ @@ -124,14 +183,17 @@ object MPCalGoCodegenPass { d"\nreturn nil" }) } - } + }*/ case stmt :: restStmts => val result = stmt match { case PCalAssert(condition) => - readExprs(List(condition)) { exprReads => - d"\nif !$exprReads[0].IsTrue() {${ - (d"\n${ctx.sectionCtx}.Abort()" + - d"\nreturn distsys.AssertionFailed").indented + val conditionExpr = condition + readExpr(condition, hint = "condition") { condition => + d"\nif !$condition.AsBool() {${ + (d"""\n${ctx.err} = fmt.Errorf("%w: ${ + escapeStringToGo(PCalRenderPass.describeExpr(conditionExpr).linesIterator.mkString("\n")) + }", distsys.AssertionFailed)""" + + d"\ncontinue").indented }\n}" } case PCalAssignment(List(PCalAssignmentPair(lhs, rhs))) => @@ -157,22 +219,17 @@ object MPCalGoCodegenPass { case PCalAssignmentLhsExtension(_) => !!! } - readExprs(rhs :: gatherLhsIndices(lhs, mutable.ListBuffer.empty)) { exprReads => - d"\n${ctx.err} = ${ctx.sectionCtx}.Write(${ctx.bindings(findLhsIdent(lhs).refersTo).bind}, $exprReads[1:], $exprReads[0])" + + readExprs((rhs, "exprRead") :: gatherLhsIndices(lhs, mutable.ListBuffer.empty).map(_ -> "indexRead")) { exprReads => + d"\n${ctx.err} = ${ctx.ctxName}.Write(${ctx.bindings(findLhsIdent(lhs).refersTo).bind}, []$TLAValue{${exprReads.tail.separateBy(d", ")}}, ${exprReads.head})" + d"\nif ${ctx.err} != nil {${ - (d"\n${ctx.sectionCtx}.Abort()" + - d"\nif ${ctx.err} == distsys.Aborted {${ - d"\ngoto ${ctx.currentLabel}".indented - }\n} else {${ - d"\nreturn ${ctx.err}".indented - }\n}").indented + d"\ncontinue".indented }\n}" } case PCalAwait(condition) => - readExprs(List(condition)) { exprReads => - d"\nif !$exprReads[0].IsTrue() {${ - (d"\n${ctx.sectionCtx}.Abort()" + - d"\ngoto ${ctx.currentLabel}").indented + readExpr(condition, hint = "condition") { condition => + d"\nif !$condition.AsBool() {${ + (d"\n${ctx.err} = distsys.CriticalSectionAborted" + + d"\ncontinue").indented }\n}" } case PCalCall(_, _) => !!! // replaced by MPCalCall above @@ -187,12 +244,12 @@ object MPCalGoCodegenPass { impl(body).indented }.flattenDescriptions + d"\ndefault:" + - d"""\npanic("current branch if either matches no code paths!")""".indented + d"""\npanic("current branch of either matches no code paths!")""".indented }\n}" } case PCalIf(condition, yes, no) => - readExprs(List(condition)) { exprReads => - d"\nif $exprReads[0].IsTrue() {${ + readExpr(condition, hint = "condition") { condition => + d"\nif $condition.AsBool() {${ impl(yes).indented }\n} else {${ impl(no).indented @@ -201,24 +258,24 @@ object MPCalGoCodegenPass { case PCalLabeledStatements(_, _) => !!! case PCalMacroCall(_, _) => !!! case PCalPrint(value) => - readExprs(List(value)) { exprReads => - d"\n$exprReads[0].PCalPrint()" + readExpr(value, hint = "toPrint") { value => + d"\n$value.PCalPrint()" } case PCalSkip() => d"\n// skip" case PCalWhile(_, _) => !!! case PCalWith(variables, body) => readExprs(variables.map { - case PCalVariableDeclarationValue(_, value) => value - case PCalVariableDeclarationSet(_, set) => set + case PCalVariableDeclarationValue(name, value) => (value, s"${name.id}Read") + case PCalVariableDeclarationSet(name, set) => (set, s"${name.id}Read") }) { exprReads => val oldCtx = ctx val cleanedNames = variables.map(decl => ctx.nameCleaner.cleanName(decl.name.id)) - (variables.view.zipWithIndex zip cleanedNames).map { - case ((PCalVariableDeclarationValue(_, _), idx), name) => - d"\nvar $name $TLAValue = $exprReads[$idx]" - case ((PCalVariableDeclarationSet(_, _), idx), name) => - d"\nvar $name $TLAValue = $exprReads[$idx].SelectElement()" + ((variables.view zip exprReads) zip cleanedNames).map { + case ((PCalVariableDeclarationValue(_, _), read), name) => + d"\nvar $name $TLAValue = $read" + case ((PCalVariableDeclarationSet(_, _), read), name) => + d"\nvar $name $TLAValue = $read.SelectElement()" }.toList.flattenDescriptions + { implicit val ctx: GoCodegenContext = oldCtx.copy( bindings = oldCtx.bindings ++ (variables.view zip cleanedNames.view.map(FixedValueBinding))) @@ -229,43 +286,114 @@ object MPCalGoCodegenPass { impl(restStmts, pfxDesc = pfxDesc + result) } - ctx.cleanName("err") { err => - d"\nvar $err error" + - pcalEithers.map { either => - d"\nvar ${fairnessCounterNames(either)} int = 0" - }.flattenDescriptions + - d"\n" + - body.map { - case PCalLabeledStatements(label, statements) => - d"\n${label.name}: {${ - ctx.cleanName("sectionCtx") { sectionCtx => - (d"\n$sectionCtx := distsys.NewPCalSectionContext()" + - impl(statements)(ctx = ctx.copy( - errOpt = Some(err.toDescription), - sectionCtxOpt = Some(sectionCtx.toDescription), - currentLabelOpt = Some(label.name.toDescription), - ))).indented - } - }\n}" - case _ => !!! + val paramNames = params.view.map { + case param@MPCalRefParam(name, _) => param -> nameCleaner.cleanName(name.id) + case param@MPCalValParam(name) => param -> nameCleaner.cleanName(name.id) + }.to(IdMap) + val paramLocalNames = params.view.collect { + case param@MPCalValParam(name) => param -> nameCleaner.cleanName(name.id) + }.to(IdMap) + val varNames = variables.view.map { decl => + decl -> nameCleaner.cleanName(decl.name.id) + }.to(IdMap) + + val origCtx = ctx + locally { + implicit val ctx: GoCodegenContext = origCtx.copy( + bindings = origCtx.bindings ++ + selfDeclOpt.map(selfDecl => selfDecl -> FixedValueBinding(origCtx.selfName)) ++ + paramNames.collect { case (param: MPCalRefParam) -> name => param -> ResourceBinding(name) } ++ + paramLocalNames.view.map { case param -> name => param -> ResourceBinding(name) } ++ + varNames.view.map { case v -> name => v -> ResourceBinding(name) }, + errOpt = Some(err.toDescription), + resourceMappingCounts = params.view.collect { + case param@MPCalRefParam(_, mappingCount) => param -> mappingCount + }.to(IdMap), + ) + + def ensureLocalResource(value: Description): Description = + d"distsys.EnsureLocalArchetypeResource(${ctx.ctxName}.ResourceEnsurerPositional(), $value)" + + d"\nfunc $callableName(${ctx.ctxName} *distsys.MPCalContext, ${ctx.selfName} $TLAValue, ${ctx.constantsName} ${ctx.constantsTypeName}${ + params.view.map { + case param@MPCalRefParam(_, _) => d", ${paramNames(param)} $ArchetypeResourceHandle" + case param@MPCalValParam(_) => d", ${paramNames(param)} $TLAValue" }.flattenDescriptions + }) error {${ + (d"\nvar ${ctx.err} error" + + d"\n// label tags" + + d"\nconst (${ + (d"\n${labelBinds(body.head.asInstanceOf[PCalLabeledStatements].label.name)} = iota" + + body.view.tail.map { + case PCalLabeledStatements(label, _) => + d"\n${labelBinds(label.name)}" + }.flattenDescriptions).indented + }\n)" + + d"\n$programCounterResourceName := ${ensureLocalResource { + val firstLabel = labelBinds(body.head.asInstanceOf[PCalLabeledStatements].label.name) + d"distsys.NewTLANumber($firstLabel)" + }}" + + params.view.collect { + case param: MPCalValParam => + d"\n${paramLocalNames(param)} := ${ensureLocalResource(paramNames(param).toDescription)}" + }.flattenDescriptions + + variables.view.map { + case decl@PCalVariableDeclarationEmpty(_) => + d"\n${varNames(decl)} := ${ensureLocalResource(d"$TLAValue{}")}" + case decl@PCalVariableDeclarationSet(_, set) => + d"\n${varNames(decl)} := ${ensureLocalResource(d"${translateExpr(set)}.SelectElement()")}" + case decl@PCalVariableDeclarationValue(_, value) => + d"\n${varNames(decl)} := ${ensureLocalResource(translateExpr(value))}" + }.flattenDescriptions + + pcalEithers.map { either => + d"\nvar ${fairnessCounterNames(either)} int = 0" + }.flattenDescriptions + + d"\n" + + d"\nfor {${ + (d"\nif $err != nil {${ + (d"\nif $err == distsys.CriticalSectionAborted {${ + (d"\nctx.Abort()" + + d"\n$err = nil").indented + }\n} else {${ + d"\nreturn $err".indented + }\n}").indented + }\n}" + + ctx.cleanName("labelTag") { labelTag => + d"\n$labelTag, ${ctx.err} := ${ctx.ctxName}.Read($programCounterResourceName, []$TLAValue{})" + + d"\nif ${ctx.err} != nil {${ + d"\nreturn ${ctx.err}".indented + }\n}" + + d"\nswitch $labelTag.AsNumber() {${ + body.map { + case PCalLabeledStatements(label, statements) => + d"\ncase ${labelBinds(label.name)}:${ + impl(statements).indented + }" + } + }\ndefault:${ + d"""\nreturn fmt.Errorf("invalid program counter %v", $labelTag)""".indented + }\n}" + }).indented + }\n}").indented + }\n}\n" } } + def escapeStringToGo(str: String): String = + str.flatMap { + case '"' => "\\\"" + case '\\' => "\\\\" + case '\t' => "\\t" + case '\n' => "\\n" + case '\f' => "\\f" + case '\r' => "\\r" + case ch => ch.toString + } + def translateExpr(expression: TLAExpression)(implicit ctx: GoCodegenContext): Description = expression match { case TLAString(value) => - d"""distsys.NewTLAString("${ - value.flatMap { - case '"' => "\\\"" - case '\\' => "\\\\" - case '\t' => "\\t" - case '\n' => "\\n" - case '\f' => "\\f" - case '\r' => "\\r" - case ch => ch.toString - } - }")""" + d"""distsys.NewTLAString("${escapeStringToGo(value)}")""" case TLANumber(value, _) => d"""distsys.NewTLANumber(${ value match { @@ -288,7 +416,7 @@ object MPCalGoCodegenPass { } val indices = findIndices(expr, mutable.ListBuffer.empty).map(translateExpr).separateBy(d", ") - d"${ctx.sectionCtx}.Read(${ctx.bindings(ident.refersTo).bind}, []$TLAValue{$indices})" + d"${ctx.ctxName}.Read(${ctx.bindings(ident.refersTo).bind}, []$TLAValue{$indices})" case ident@TLAGeneralIdentifier(_, prefix) => assert(prefix.isEmpty) ctx.bindings(ident.refersTo) match { @@ -300,10 +428,10 @@ object MPCalGoCodegenPass { case DependentCallableBinding(bind) => val cleanArgs = View.fill(ident.refersTo.arity)(ctx.nameCleaner.cleanName("arg")).toList d"func(${cleanArgs.view.map(arg => d"$arg $TLAValue").separateBy(d", ")}) $TLAValue {${ - d"\nreturn $bind(${ctx.constants}${cleanArgs.view.map(arg => d", $arg").flattenDescriptions})" + d"\nreturn $bind(${ctx.constantsName}${cleanArgs.view.map(arg => d", $arg").flattenDescriptions})" }\n}" case FixedValueBinding(bind) => bind.toDescription - case ResourceBinding(bind) => d"${ctx.sectionCtx}.Read($bind, []$TLAValue{})" + case ResourceBinding(_) => !!! } case TLADot(lhs, identifier) => d"${translateExpr(lhs)}.ApplyFunction(${ @@ -315,11 +443,11 @@ object MPCalGoCodegenPass { case IndependentCallableBinding(bind) => d"$bind(${arguments.map(translateExpr).separateBy(d", ")})" case DependentCallableBinding(bind) => - d"$bind(${ctx.constants}, ${arguments.map(translateExpr).separateBy(d", ")})" + d"$bind(${ctx.constantsName}, ${arguments.map(translateExpr).separateBy(d", ")})" } case TLAIf(cond, tval, fval) => d"func() {${ - (d"\nif ${translateExpr(cond)}.IsTrue() {" + + (d"\nif ${translateExpr(cond)}.AsBool() {" + d"\nreturn ${translateExpr(tval)}".indented + d"\n} else {" + d"\nreturn ${translateExpr(fval)}".indented + @@ -376,7 +504,7 @@ object MPCalGoCodegenPass { d"switch {${ arms.map { case TLACaseArm(cond, result) => - d"\ncase ${translateExpr(cond)}.IsTrue():" + + d"\ncase ${translateExpr(cond)}.AsBool():" + d"\nreturn ${translateExpr(result)}".indented }.flattenDescriptions + d"\ndefault:" + @@ -441,15 +569,15 @@ object MPCalGoCodegenPass { d"distsys.NewTLARecord([]distsys.TLARecordField{${ fields.view.map { case TLARecordConstructorField(name, value) => - d"""{"${name.id}", ${translateExpr(value)}}""" - }.separateBy(d", ") - }})" + d"""\n{distsys.NewTLAString("${name.id}"), ${translateExpr(value)}},""" + }.flattenDescriptions.indented + }${if(fields.nonEmpty) d"\n" else d""}})" case TLARecordSet(fields) => d"distsys.NewTLARecordSet([]distsys.TLARecordField{${ fields.view.map { - case TLARecordSetField(name, set) => d"""{"${name.id}", ${translateExpr(set)}}""" - }.separateBy(d", ") - }})" + case TLARecordSetField(name, set) => d"""\n{distsys.NewTLAString("${name.id}"), ${translateExpr(set)}},""" + }.flattenDescriptions.indented + }${if(fields.nonEmpty) d"\n" else d""}})" } @throws[PGoError] @@ -502,21 +630,39 @@ object MPCalGoCodegenPass { } }.to(IdMap) + val ctxName = nameCleaner.cleanName("ctx") + val selfName = nameCleaner.cleanName("self") + val constantsName = nameCleaner.cleanName("constants") + implicit val ctx: GoCodegenContext = GoCodegenContext( nameCleaner = nameCleaner, + ctxName = ctxName, + selfName = selfName, + constantsName = constantsName, + constantsTypeName = Constants, bindings = (mpcalBlock.mpcalProcedures.view.map { proc => proc -> IndependentCallableBinding(nameCleaner.cleanName(toGoPublicName(proc.name.id))) } ++ mpcalBlock.archetypes.view.map { arch => arch -> IndependentCallableBinding(nameCleaner.cleanName(toGoPublicName(arch.name.id))) } ++ tlaExtDefnNames.map { case defn -> name => defn -> IndependentCallableBinding(name) + } ++ constantDecls.view.map { + case decl@TLAOpDecl(variant) => + variant match { + case TLAOpDecl.NamedVariant(_, 0) => decl -> FixedValueBinding(s"$constantsName.${constantNames(decl)}") + case TLAOpDecl.NamedVariant(_, _) => decl -> IndependentCallableBinding(s"$constantsName.${constantNames(decl)}") + case TLAOpDecl.SymbolVariant(_) => decl -> IndependentCallableBinding(s"$constantsName.${constantNames(decl)}") + } } ++ tlaUnits.view.map { defn => defn.asInstanceOf[RefersTo.HasReferences] -> DependentCallableBinding(tlaUnitNames(defn)) }).to(IdMap) ) d"package ${packageName.getOrElse(mpcalBlock.name.id.toLowerCase(Locale.ROOT)): String}\n" + - d"""\nimport "github.com/UBC-NSS/pgo/distsys"\n""" + + d"\nimport (${ + (d"""\n"github.com/UBC-NSS/pgo/distsys"""" + + d"""\n"fmt"""").indented + })\n" + d"\ntype $Constants struct {${ constantDecls.map { case decl@TLAOpDecl(variant) => @@ -533,146 +679,35 @@ object MPCalGoCodegenPass { }\n}\n" + tlaUnits.view.map { case defn@TLAOperatorDefinition(name, args, body, _) => - ctx.cleanName("constants") { constants => - val origCtx = ctx - val argNames = args.view.map { - case decl@TLAOpDecl(variant) => - variant match { - case TLAOpDecl.NamedVariant(ident, 0) => - decl -> FixedValueBinding(nameCleaner.cleanName(ident.id)) - case TLAOpDecl.NamedVariant(ident, _) => - decl -> IndependentCallableBinding(nameCleaner.cleanName(ident.id)) - case TLAOpDecl.SymbolVariant(sym) => - decl -> IndependentCallableBinding(nameCleaner.cleanName(sym.symbol.productPrefix)) - } - }.to(IdMap) - d"\nfunc ${tlaUnitNames(defn)}($constants $Constants${args.view.map { - case decl@TLAOpDecl(variant) => - variant match { - case TLAOpDecl.NamedVariant(_, 0) => d", ${argNames(decl).bind} $TLAValue" - case TLAOpDecl.NamedVariant(_, arity) => d", ${argNames(decl).bind} func(${View.fill(arity)(TLAValue.toDescription).separateBy(d", ")}) $TLAValue" - case TLAOpDecl.SymbolVariant(sym) => - val arity = if(sym.symbol.isInfix) 2 else 1 - d", ${argNames(decl).bind} func(${View.fill(arity)(TLAValue.toDescription).separateBy(d", ")}) $TLAValue" - } - }.flattenDescriptions}) $TLAValue {${ - implicit val ctx: GoCodegenContext = origCtx.copy(bindings = origCtx.bindings ++ argNames ++ constantDecls.view.map { - case decl@TLAOpDecl(variant) => - variant match { - case TLAOpDecl.NamedVariant(_, 0) => decl -> FixedValueBinding(s"$constants.${constantNames(decl)}") - case TLAOpDecl.NamedVariant(_, _) => decl -> IndependentCallableBinding(s"$constants.${constantNames(decl)}") - case TLAOpDecl.SymbolVariant(_) => decl -> IndependentCallableBinding(s"$constants.${constantNames(decl)}") - } - }) - d"\nreturn ${translateExpr(body)}".indented - }\n}\n" - } - }.flattenDescriptions + - mpcalBlock.mpcalProcedures.view.map { proc => - val origCtx = ctx - ctx.cleanName("constants") { constants => - val paramNames = proc.params.view.map { - case param@MPCalRefParam(name, _) => param -> nameCleaner.cleanName(name.id) - case param@MPCalValParam(name) => param -> nameCleaner.cleanName(name.id) - }.to(IdMap) - val paramLocalNames = proc.params.view.collect { - case param@MPCalValParam(name) => param -> nameCleaner.cleanName(name.id) - }.to(IdMap) - val varNames = proc.variables.view.map { - case decl@PCalPVariableDeclaration(name, _) => decl -> nameCleaner.cleanName(name.id) + val origCtx = ctx + val argNames = args.view.map { + case decl@TLAOpDecl(variant) => + variant match { + case TLAOpDecl.NamedVariant(ident, 0) => + decl -> FixedValueBinding(nameCleaner.cleanName(ident.id)) + case TLAOpDecl.NamedVariant(ident, _) => + decl -> IndependentCallableBinding(nameCleaner.cleanName(ident.id)) + case TLAOpDecl.SymbolVariant(sym) => + decl -> IndependentCallableBinding(nameCleaner.cleanName(sym.symbol.productPrefix)) + } }.to(IdMap) - - implicit val ctx: GoCodegenContext = origCtx.copy( - bindings = origCtx.bindings ++ - paramNames.collect { case (param: MPCalRefParam) -> name => param -> ResourceBinding(name) } ++ - paramLocalNames.view.map { case param -> name => param -> ResourceBinding(name) } ++ - varNames.view.map { case v -> name => v -> ResourceBinding(name) } ++ - constantDecls.view.map { - case decl@TLAOpDecl(variant) => - variant match { - case TLAOpDecl.NamedVariant(_, 0) => decl -> FixedValueBinding(s"$constants.${constantNames(decl)}") - case TLAOpDecl.NamedVariant(_, _) => decl -> IndependentCallableBinding(s"$constants.${constantNames(decl)}") - case TLAOpDecl.SymbolVariant(_) => decl -> IndependentCallableBinding(s"$constants.${constantNames(decl)}") - } - }, - resourceMappingCounts = proc.params.view.collect { - case param@MPCalRefParam(_, mappingCount) => param -> mappingCount - }.to(IdMap), - ) - d"\nfunc ${ctx.bindings(proc).bind}($constants $Constants${ - proc.params.view.map { - case param: MPCalRefParam => d", ${paramNames(param)} $ArchetypeResource" - case param: MPCalValParam => d", ${paramNames(param)} $TLAValue" - }.flattenDescriptions - }) error {${ - (proc.params.view.collect { - case param: MPCalValParam => - d"\nvar ${paramLocalNames(param)} $ArchetypeResource = distsys.NewLocalArchetypeResource(${paramNames(param)})" - }.flattenDescriptions + - proc.variables.view.map { - case decl@PCalPVariableDeclaration(_, valueOpt) => - d"\nvar ${varNames(decl)} $TLAValue${valueOpt.map(value => d" = ${translateExpr(value)}").getOrElse(d"")}" - }.flattenDescriptions + - translateBody(proc.body)).indented + d"\nfunc ${tlaUnitNames(defn)}($constantsName $Constants${args.view.map { + case decl@TLAOpDecl(variant) => + variant match { + case TLAOpDecl.NamedVariant(_, 0) => d", ${argNames(decl).bind} $TLAValue" + case TLAOpDecl.NamedVariant(_, arity) => d", ${argNames(decl).bind} func(${View.fill(arity)(TLAValue.toDescription).separateBy(d", ")}) $TLAValue" + case TLAOpDecl.SymbolVariant(sym) => + val arity = if(sym.symbol.isInfix) 2 else 1 + d", ${argNames(decl).bind} func(${View.fill(arity)(TLAValue.toDescription).separateBy(d", ")}) $TLAValue" + } + }.flattenDescriptions}) $TLAValue {${ + implicit val ctx: GoCodegenContext = origCtx.copy(bindings = origCtx.bindings ++ argNames) + d"\nreturn ${translateExpr(body)}".indented }\n}\n" - } - }.flattenDescriptions + + }.flattenDescriptions + // TODO: procedures mpcalBlock.archetypes.view.map { arch => - val origCtx = ctx - ctx.cleanName("self") { self => - ctx.cleanName("constants") { constants => - val paramNames = arch.params.view.map { - case param@MPCalRefParam(name, _) => param -> nameCleaner.cleanName(name.id) - case param@MPCalValParam(name) => param -> nameCleaner.cleanName(name.id) - }.to(IdMap) - val paramLocalNames = arch.params.view.collect { - case param@MPCalValParam(name) => param -> nameCleaner.cleanName(name.id) - }.to(IdMap) - val varNames = arch.variables.view.map { decl => - decl -> nameCleaner.cleanName(decl.name.id) - }.to(IdMap) - - implicit val ctx: GoCodegenContext = origCtx.copy( - bindings = origCtx.bindings ++ - List(arch.selfDecl -> FixedValueBinding(self)) ++ - paramNames.collect { case (param: MPCalRefParam) -> name => param -> ResourceBinding(name) } ++ - paramLocalNames.view.map { case param -> name => param -> ResourceBinding(name) } ++ - varNames.view.map { case v -> name => v -> ResourceBinding(name) } ++ - constantDecls.view.map { - case decl@TLAOpDecl(variant) => - variant match { - case TLAOpDecl.NamedVariant(_, 0) => decl -> FixedValueBinding(s"$constants.${constantNames(decl)}") - case TLAOpDecl.NamedVariant(_, _) => decl -> IndependentCallableBinding(s"$constants.${constantNames(decl)}") - case TLAOpDecl.SymbolVariant(_) => decl -> IndependentCallableBinding(s"$constants.${constantNames(decl)}") - } - }, - resourceMappingCounts = arch.params.view.collect { - case param@MPCalRefParam(_, mappingCount) => param -> mappingCount - }.to(IdMap), - ) - - d"\nfunc ${ctx.bindings(arch).bind}($self $TLAValue, $constants $Constants${ - arch.params.view.map { - case param@MPCalRefParam(_, _) => d", ${paramNames(param)} $ArchetypeResource" - case param@MPCalValParam(_) => d", ${paramNames(param)} $TLAValue" - }.flattenDescriptions - }) error {${ - (arch.params.view.collect { - case param: MPCalValParam => - d"\nvar ${paramLocalNames(param)} $ArchetypeResource = distsys.NewLocalArchetypeResource(${paramNames(param)})" - }.flattenDescriptions + - arch.variables.view.map { - case decl@PCalVariableDeclarationEmpty(_) => - d"\nvar ${varNames(decl)} $ArchetypeResource = distsys.NewLocalArchetypeResource($TLAValue{})" - case decl@PCalVariableDeclarationSet(_, set) => - d"\nvar ${varNames(decl)} $ArchetypeResource = distsys.NewLocalArchetypeResource(${translateExpr(set)}.SelectElement())" - case decl@PCalVariableDeclarationValue(_, value) => - d"\nvar ${varNames(decl)} $ArchetypeResource = distsys.NewLocalArchetypeResource(${translateExpr(value)})" - }.flattenDescriptions + - translateBody(arch.body)).indented - }\n}\n" - } - } + translateMPCalCallable(ctx.bindings(arch).bind, + selfDeclOpt = Some(arch.selfDecl), params = arch.params, variables = arch.variables, body = arch.body) }.flattenDescriptions } } diff --git a/test/files/general/dqueue.tla.gotests/dqueue.go b/test/files/general/dqueue.tla.gotests/dqueue.go index e43ae9821..9fc70ca1d 100644 --- a/test/files/general/dqueue.tla.gotests/dqueue.go +++ b/test/files/general/dqueue.tla.gotests/dqueue.go @@ -1,6 +1,8 @@ package dqueue -import "github.com/UBC-NSS/pgo/distsys" +import ( + "github.com/UBC-NSS/pgo/distsys" + "fmt") type Constants struct { BUFFER_SIZE distsys.TLAValue @@ -12,185 +14,163 @@ func NUM_NODES(constants Constants) distsys.TLAValue { return distsys.TLA_PlusSymbol(constants.NUM_CONSUMERS, distsys.NewTLANumber(1)) } -func AConsumer(self distsys.TLAValue, constants0 Constants, net distsys.ArchetypeResource, proc distsys.ArchetypeResource) error { +func AConsumer(ctx *distsys.MPCalContext, self distsys.TLAValue, constants Constants, net distsys.ArchetypeResourceHandle, proc distsys.ArchetypeResourceHandle) error { var err error + // label tags + const ( + cLabelTag = iota + c1LabelTag + c2LabelTag + ) + programCounter := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.NewTLANumber(cLabelTag)) - c: { - sectionCtx := distsys.NewPCalSectionContext() - var exprReads []distsys.TLAValue - exprReads, err = distsys.WhileCatchingPanics(func() distsys.TLAValue { return distsys.TLA_TRUE }) + for { if err != nil { - sectionCtx.Abort() - if err == distsys.Aborted { - goto c + if err == distsys.CriticalSectionAborted { + ctx.Abort() + err = nil } else { return err } } - if exprReads[0].IsTrue() { - switch err = sectionCtx.Commit(); err { - case error(nil): - goto c1 - case distsys.Aborted: - goto c - default: - return err - } - } else { - // no statements - } - // no statements - } - c1: { - sectionCtx0 := distsys.NewPCalSectionContext() - var exprReads0 []distsys.TLAValue - exprReads0, err = distsys.WhileCatchingPanics(func() distsys.TLAValue { return self }, func() distsys.TLAValue { return constants0.PRODUCER }) - if err != nil { - sectionCtx0.Abort() - if err == distsys.Aborted { - goto c1 - } else { - return err - } - } - err = sectionCtx0.Write(net, exprReads0[1:], exprReads0[0]) + labelTag, err := ctx.Read(programCounter, []distsys.TLAValue{}) if err != nil { - sectionCtx0.Abort() - if err == distsys.Aborted { - goto c1 - } else { - return err - } - } - switch err = sectionCtx0.Commit(); err { - case error(nil): - goto c2 - case distsys.Aborted: - goto c1 - default: return err } - } - c2: { - sectionCtx1 := distsys.NewPCalSectionContext() - var exprReads1 []distsys.TLAValue - exprReads1, err = distsys.WhileCatchingPanics(func() distsys.TLAValue { return sectionCtx1.Read(net, []distsys.TLAValue{self}) }) - if err != nil { - sectionCtx1.Abort() - if err == distsys.Aborted { - goto c2 + switch labelTag.AsNumber() { + case cLabelTag: + if distsys.TLA_TRUE.AsBool() { + err = ctx.Write(programCounter, []distsys.TLAValue{}, distsys.NewTLANumber(c1LabelTag)) + if err != nil { + continue + } + err = ctx.Commit() + if err != nil { + continue + } } else { - return err + // no statements } - } - err = sectionCtx1.Write(proc, exprReads1[1:], exprReads1[0]) - if err != nil { - sectionCtx1.Abort() - if err == distsys.Aborted { - goto c2 - } else { - return err + // no statements + case c1LabelTag: + err = ctx.Write(net, []distsys.TLAValue{constants.PRODUCER}, self) + if err != nil { + continue + } + err = ctx.Write(programCounter, []distsys.TLAValue{}, distsys.NewTLANumber(c2LabelTag)) + if err != nil { + continue + } + err = ctx.Commit() + if err != nil { + continue + } + case c2LabelTag: + var exprRead distsys.TLAValue + exprRead, err = ctx.Read(net, []distsys.TLAValue{self}) + if err != nil { + continue + } + err = ctx.Write(proc, []distsys.TLAValue{}, exprRead) + if err != nil { + continue + } + err = ctx.Write(programCounter, []distsys.TLAValue{}, distsys.NewTLANumber(cLabelTag)) + if err != nil { + continue + } + err = ctx.Commit() + if err != nil { + continue } - } - switch err = sectionCtx1.Commit(); err { - case error(nil): - goto c - case distsys.Aborted: - goto c2 default: - return err + return fmt.Errorf("invalid program counter %v", labelTag) } } } -func AProducer(self0 distsys.TLAValue, constants1 Constants, net0 distsys.ArchetypeResource, s distsys.ArchetypeResource) error { - var requester distsys.ArchetypeResource = distsys.NewLocalArchetypeResource(distsys.TLAValue{}) +func AProducer(ctx *distsys.MPCalContext, self distsys.TLAValue, constants Constants, net0 distsys.ArchetypeResourceHandle, s distsys.ArchetypeResourceHandle) error { var err0 error + // label tags + const ( + pLabelTag = iota + p1LabelTag + p2LabelTag + ) + programCounter0 := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.NewTLANumber(pLabelTag)) + requester := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.TLAValue{}) - p: { - sectionCtx2 := distsys.NewPCalSectionContext() - var exprReads2 []distsys.TLAValue - exprReads2, err0 = distsys.WhileCatchingPanics(func() distsys.TLAValue { return distsys.TLA_TRUE }) - if err0 != nil { - sectionCtx2.Abort() - if err0 == distsys.Aborted { - goto p - } else { - return err0 - } - } - if exprReads2[0].IsTrue() { - switch err0 = sectionCtx2.Commit(); err0 { - case error(nil): - goto p1 - case distsys.Aborted: - goto p - default: - return err0 - } - } else { - // no statements - } - // no statements - } - p1: { - sectionCtx3 := distsys.NewPCalSectionContext() - var exprReads3 []distsys.TLAValue - exprReads3, err0 = distsys.WhileCatchingPanics(func() distsys.TLAValue { return sectionCtx3.Read(net0, []distsys.TLAValue{self0}) }) + for { if err0 != nil { - sectionCtx3.Abort() - if err0 == distsys.Aborted { - goto p1 + if err0 == distsys.CriticalSectionAborted { + ctx.Abort() + err0 = nil } else { return err0 } } - err0 = sectionCtx3.Write(requester, exprReads3[1:], exprReads3[0]) + labelTag0, err0 := ctx.Read(programCounter0, []distsys.TLAValue{}) if err0 != nil { - sectionCtx3.Abort() - if err0 == distsys.Aborted { - goto p1 - } else { - return err0 - } - } - switch err0 = sectionCtx3.Commit(); err0 { - case error(nil): - goto p2 - case distsys.Aborted: - goto p1 - default: return err0 } - } - p2: { - sectionCtx4 := distsys.NewPCalSectionContext() - var exprReads4 []distsys.TLAValue - exprReads4, err0 = distsys.WhileCatchingPanics(func() distsys.TLAValue { return sectionCtx4.Read(s, []distsys.TLAValue{}) }, func() distsys.TLAValue { return sectionCtx4.Read(requester, []distsys.TLAValue{}) }) - if err0 != nil { - sectionCtx4.Abort() - if err0 == distsys.Aborted { - goto p2 + switch labelTag0.AsNumber() { + case pLabelTag: + if distsys.TLA_TRUE.AsBool() { + err0 = ctx.Write(programCounter0, []distsys.TLAValue{}, distsys.NewTLANumber(p1LabelTag)) + if err0 != nil { + continue + } + err0 = ctx.Commit() + if err0 != nil { + continue + } } else { - return err0 + // no statements } - } - err0 = sectionCtx4.Write(net0, exprReads4[1:], exprReads4[0]) - if err0 != nil { - sectionCtx4.Abort() - if err0 == distsys.Aborted { - goto p2 - } else { - return err0 + // no statements + case p1LabelTag: + var exprRead0 distsys.TLAValue + exprRead0, err0 = ctx.Read(net0, []distsys.TLAValue{self}) + if err0 != nil { + continue + } + err0 = ctx.Write(requester, []distsys.TLAValue{}, exprRead0) + if err0 != nil { + continue + } + err0 = ctx.Write(programCounter0, []distsys.TLAValue{}, distsys.NewTLANumber(p2LabelTag)) + if err0 != nil { + continue + } + err0 = ctx.Commit() + if err0 != nil { + continue + } + case p2LabelTag: + var exprRead1 distsys.TLAValue + exprRead1, err0 = ctx.Read(s, []distsys.TLAValue{}) + if err0 != nil { + continue + } + var indexRead distsys.TLAValue + indexRead, err0 = ctx.Read(requester, []distsys.TLAValue{}) + if err0 != nil { + continue + } + err0 = ctx.Write(net0, []distsys.TLAValue{indexRead}, exprRead1) + if err0 != nil { + continue + } + err0 = ctx.Write(programCounter0, []distsys.TLAValue{}, distsys.NewTLANumber(pLabelTag)) + if err0 != nil { + continue + } + err0 = ctx.Commit() + if err0 != nil { + continue } - } - switch err0 = sectionCtx4.Commit(); err0 { - case error(nil): - goto p - case distsys.Aborted: - goto p2 default: - return err0 + return fmt.Errorf("invalid program counter %v", labelTag0) } } } diff --git a/test/files/general/dqueue.tla.gotests/dqueue_test.go b/test/files/general/dqueue.tla.gotests/dqueue_test.go index 805b1ca05..f294e9659 100644 --- a/test/files/general/dqueue.tla.gotests/dqueue_test.go +++ b/test/files/general/dqueue.tla.gotests/dqueue_test.go @@ -12,16 +12,87 @@ func TestNUM_NODES(t *testing.T) { } } -func TestAConsumer(t *testing.T) { - t.Run("one consumer", func(t *testing.T) { +type dummyDurableStorage struct{} - go func() { - err := AConsumer(distsys.TLAValue{}, Constants{}, nil, nil) - if err != nil { - panic(err) +var _ distsys.MPCalDurableStorage = &dummyDurableStorage{} + + +func (d dummyDurableStorage) RecoverResources() (rec *distsys.MPCalDurableStorageRecord, err error) { + return nil, nil +} + +func (d dummyDurableStorage) SnapshotResources(rec *distsys.MPCalDurableStorageRecord) { + // pass +} + +func TestProducerConsumer(t *testing.T) { + producerCtx, err := distsys.NewMPCalContext(&dummyDurableStorage{}) + if err != nil { + panic(err) + } + producerSelf := distsys.NewTLANumber(1) + producerInputChannel := make(chan distsys.TLAValue, 3) + + consumerCtx, err := distsys.NewMPCalContext(&dummyDurableStorage{}) + if err != nil { + panic(err) + } + consumerSelf := distsys.NewTLANumber(2) + consumerOutputChannel := make(chan distsys.TLAValue, 3) + + constants := Constants{ + PRODUCER: producerSelf, + } + + go func() { + network := distsys.EnsureTCPMailboxesArchetypeResource(producerCtx.ResourceEnsurerByName("network"), func(index distsys.TLAValue) (distsys.TCPMailboxKind, string) { + switch index.AsNumber() { + case 1: + return distsys.TCPMailboxesLocal, "localhost:8001" + case 2: + return distsys.TCPMailboxesRemote, "localhost:8002" + default: + panic("TODO") } - }() + }) + s := distsys.EnsureInputChannelResource(producerCtx.ResourceEnsurerByName("s"), producerInputChannel) + err := AProducer(producerCtx, producerSelf, constants, network, s) + if err != nil { + panic(err) + } + }() - }) - t.Fail() + go func() { + network := distsys.EnsureTCPMailboxesArchetypeResource(consumerCtx.ResourceEnsurerByName("network"), func(index distsys.TLAValue) (distsys.TCPMailboxKind, string) { + switch index.AsNumber() { + case 1: + return distsys.TCPMailboxesRemote, "localhost:8001" + case 2: + return distsys.TCPMailboxesLocal, "localhost:8002" + default: + panic("TODO") + } + }) + proc := distsys.EnsureOutputChannelResource(consumerCtx.ResourceEnsurerByName("proc"), consumerOutputChannel) + err := AConsumer(consumerCtx, consumerSelf, constants, network, proc) + if err != nil { + panic(err) + } + }() + + producedValues := []distsys.TLAValue{ + distsys.NewTLAString("foo"), + distsys.NewTLAString("bar"), + distsys.NewTLAString("ping"), + } + for _, value := range producedValues { + producerInputChannel <- value + } + + consumedValues := []distsys.TLAValue{<-consumerOutputChannel, <-consumerOutputChannel, <-consumerOutputChannel} + close(consumerOutputChannel) + + if len(consumedValues) != len(producedValues) || !consumedValues[0].Equal(producedValues[0]) || !consumedValues[1].Equal(producedValues[1]) || !consumedValues[2].Equal(producedValues[2]) { + t.Errorf("Consumed values %v did not match produced values %v", consumedValues, producedValues) + } } diff --git a/test/files/general/load_balancer.tla b/test/files/general/load_balancer.tla index bb164c29a..e6b1e91bd 100644 --- a/test/files/general/load_balancer.tla +++ b/test/files/general/load_balancer.tla @@ -86,7 +86,7 @@ CONSTANT WEB_PAGE \* ALoadBalancer is the archetype that defines the behavior of \* the load balancer process. The `mailboxes` parameter represents \* connections to all nodes in the system. - archetype ALoadBalancer(ref mailboxes) + archetype ALoadBalancer(ref mailboxes[_]) \* Local variables of this archetype: variables @@ -140,7 +140,7 @@ CONSTANT WEB_PAGE \* - file_system: abstraction of a real file system. In practice, \* this is implementation specific and irrelevant for \* the properties we want to check in this specification - archetype AServer(ref mailboxes, ref file_system[_]) + archetype AServer(ref mailboxes[_], ref file_system[_]) \* Local variables variable @@ -225,14 +225,14 @@ CONSTANT WEB_PAGE \* The system has a single load balancer entity, instantiated from the ALoadBalancer \* archetype. The model of our network is going to be the one defined by the TCPChannel \* mapping macro in all instantiations. - fair process (LoadBalancer = LoadBalancerId) == instance ALoadBalancer(ref network) + fair process (LoadBalancer = LoadBalancerId) == instance ALoadBalancer(ref network[_]) mapping network[_] via TCPChannel; \* Instantiate `NUM_SERVERS` server processes according to the AServer archetype. \* We map the page stream according to the WebPages mapping macro since this is \* an implementation detail that needs to be specified during implementation at \* a later stage. - fair process (Servers \in 1..NUM_SERVERS) == instance AServer(ref network, ref fs[_]) + fair process (Servers \in 1..NUM_SERVERS) == instance AServer(ref network[_], ref fs[_]) mapping network[_] via TCPChannel mapping fs[_] via WebPages; diff --git a/test/files/general/load_balancer.tla.expectpcal b/test/files/general/load_balancer.tla.expectpcal index 5783a8e0c..b75abbb22 100644 --- a/test/files/general/load_balancer.tla.expectpcal +++ b/test/files/general/load_balancer.tla.expectpcal @@ -86,7 +86,7 @@ CONSTANT WEB_PAGE \* ALoadBalancer is the archetype that defines the behavior of \* the load balancer process. The `mailboxes` parameter represents \* connections to all nodes in the system. - archetype ALoadBalancer(ref mailboxes) + archetype ALoadBalancer(ref mailboxes[_]) \* Local variables of this archetype: variables @@ -140,7 +140,7 @@ CONSTANT WEB_PAGE \* - file_system: abstraction of a real file system. In practice, \* this is implementation specific and irrelevant for \* the properties we want to check in this specification - archetype AServer(ref mailboxes, file_system) + archetype AServer(ref mailboxes[_], ref file_system[_]) \* Local variables variable @@ -174,7 +174,7 @@ CONSTANT WEB_PAGE \* - instream: a stream of inputs to the client \* - outstream: an output stream, where the client sends the messages it receives \* from servers. - archetype AClient(ref mailboxes, instream, ref outstream) + archetype AClient(ref mailboxes[_], ref instream, ref outstream) \* Local variables variable @@ -225,18 +225,18 @@ CONSTANT WEB_PAGE \* The system has a single load balancer entity, instantiated from the ALoadBalancer \* archetype. The model of our network is going to be the one defined by the TCPChannel \* mapping macro in all instantiations. - fair process (LoadBalancer = LoadBalancerId) == instance ALoadBalancer(ref network) + fair process (LoadBalancer = LoadBalancerId) == instance ALoadBalancer(ref network[_]) mapping network[_] via TCPChannel; \* Instantiate `NUM_SERVERS` server processes according to the AServer archetype. \* We map the page stream according to the WebPages mapping macro since this is \* an implementation detail that needs to be specified during implementation at \* a later stage. - fair process (Servers \in 1..NUM_SERVERS) == instance AServer(ref network, fs) + fair process (Servers \in 1..NUM_SERVERS) == instance AServer(ref network[_], ref fs[_]) mapping network[_] via TCPChannel mapping fs[_] via WebPages; - fair process (Client \in (NUM_SERVERS+1)..(NUM_SERVERS+NUM_CLIENTS)) == instance AClient(ref network, in, ref out) + fair process (Client \in (NUM_SERVERS+1)..(NUM_SERVERS+NUM_CLIENTS)) == instance AClient(ref network[_], ref in, ref out) mapping network[_] via TCPChannel; } @@ -276,7 +276,7 @@ CONSTANT WEB_PAGE } fair process (Servers \in (1) .. (NUM_SERVERS)) - variables msg; file_system = fs; + variables msg; { serverLoop: if(TRUE) { @@ -302,14 +302,14 @@ CONSTANT WEB_PAGE } fair process (Client \in ((NUM_SERVERS) + (1)) .. ((NUM_SERVERS) + (NUM_CLIENTS))) - variables req; resp; instream = in; + variables req; resp; { clientLoop: if(TRUE) { goto clientRequest; }; clientRequest: - req := [message_type |-> GET_PAGE, client_id |-> self, path |-> instream]; + req := [message_type |-> GET_PAGE, client_id |-> self, path |-> in]; with (value10 = req) { await (Len((network)[LoadBalancerId])) < (BUFFER_SIZE); network := [network EXCEPT ![LoadBalancerId] = Append((network)[LoadBalancerId], value10)]; diff --git a/test/files/general/load_balancer.tla.gotests/go.mod b/test/files/general/load_balancer.tla.gotests/go.mod new file mode 100644 index 000000000..ff2cc2b53 --- /dev/null +++ b/test/files/general/load_balancer.tla.gotests/go.mod @@ -0,0 +1,7 @@ +module example.org/load_balancer + +go 1.14 + +replace github.com/UBC-NSS/pgo/distsys => ../../../../distsys + +require github.com/UBC-NSS/pgo/distsys v0.0.0-00010101000000-000000000000 diff --git a/test/files/general/load_balancer.tla.gotests/load_balancer.go b/test/files/general/load_balancer.tla.gotests/load_balancer.go new file mode 100644 index 000000000..9db4d3548 --- /dev/null +++ b/test/files/general/load_balancer.tla.gotests/load_balancer.go @@ -0,0 +1,333 @@ +package loadbalancer + +import ( + "github.com/UBC-NSS/pgo/distsys" + "fmt") + +type Constants struct { + BUFFER_SIZE distsys.TLAValue + LoadBalancerId distsys.TLAValue + NUM_SERVERS distsys.TLAValue + NUM_CLIENTS distsys.TLAValue + GET_PAGE distsys.TLAValue + WEB_PAGE distsys.TLAValue +} + +func NUM_NODES(constants Constants) distsys.TLAValue { + return distsys.TLA_PlusSymbol(distsys.TLA_PlusSymbol(constants.NUM_CLIENTS, constants.NUM_SERVERS), distsys.NewTLANumber(1)) +} + +func ALoadBalancer(ctx *distsys.MPCalContext, self distsys.TLAValue, constants Constants, mailboxes distsys.ArchetypeResourceHandle) error { + var err error + // label tags + const ( + mainLabelTag = iota + rcvMsgLabelTag + sendServerLabelTag + ) + programCounter := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.NewTLANumber(mainLabelTag)) + msg := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.TLAValue{}) + next := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.NewTLANumber(0)) + + for { + if err != nil { + if err == distsys.CriticalSectionAborted { + ctx.Abort() + err = nil + } else { + return err + } + } + labelTag, err := ctx.Read(programCounter, []distsys.TLAValue{}) + if err != nil { + return err + } + switch labelTag.AsNumber() { + case mainLabelTag: + if distsys.TLA_TRUE.AsBool() { + err = ctx.Write(programCounter, []distsys.TLAValue{}, distsys.NewTLANumber(rcvMsgLabelTag)) + if err != nil { + continue + } + err = ctx.Commit() + if err != nil { + continue + } + } else { + // no statements + } + // no statements + case rcvMsgLabelTag: + var exprRead distsys.TLAValue + exprRead, err = ctx.Read(mailboxes, []distsys.TLAValue{constants.LoadBalancerId}) + if err != nil { + continue + } + err = ctx.Write(msg, []distsys.TLAValue{}, exprRead) + if err != nil { + continue + } + var condition distsys.TLAValue + condition, err = ctx.Read(msg, []distsys.TLAValue{}) + if err != nil { + continue + } + if !distsys.TLA_EqualsSymbol(condition.ApplyFunction(distsys.NewTLAString("message_type")), constants.GET_PAGE).AsBool() { + err = fmt.Errorf("%w: ((msg).message_type) = (GET_PAGE)", distsys.AssertionFailed) + continue + } + err = ctx.Write(programCounter, []distsys.TLAValue{}, distsys.NewTLANumber(sendServerLabelTag)) + if err != nil { + continue + } + err = ctx.Commit() + if err != nil { + continue + } + case sendServerLabelTag: + var exprRead0 distsys.TLAValue + exprRead0, err = ctx.Read(next, []distsys.TLAValue{}) + if err != nil { + continue + } + err = ctx.Write(next, []distsys.TLAValue{}, distsys.TLA_PlusSymbol(distsys.TLA_PercentSymbol(exprRead0, constants.NUM_SERVERS), distsys.NewTLANumber(1))) + if err != nil { + continue + } + var exprRead1 distsys.TLAValue + exprRead1, err = ctx.Read(next, []distsys.TLAValue{}) + if err != nil { + continue + } + var exprRead2 distsys.TLAValue + exprRead2, err = ctx.Read(msg, []distsys.TLAValue{}) + if err != nil { + continue + } + var exprRead3 distsys.TLAValue + exprRead3, err = ctx.Read(msg, []distsys.TLAValue{}) + if err != nil { + continue + } + var indexRead distsys.TLAValue + indexRead, err = ctx.Read(next, []distsys.TLAValue{}) + if err != nil { + continue + } + err = ctx.Write(mailboxes, []distsys.TLAValue{indexRead}, distsys.NewTLARecord([]distsys.TLARecordField{ + {distsys.NewTLAString("message_id"), exprRead1}, + {distsys.NewTLAString("client_id"), exprRead2.ApplyFunction(distsys.NewTLAString("client_id"))}, + {distsys.NewTLAString("path"), exprRead3.ApplyFunction(distsys.NewTLAString("path"))}, + })) + if err != nil { + continue + } + err = ctx.Write(programCounter, []distsys.TLAValue{}, distsys.NewTLANumber(mainLabelTag)) + if err != nil { + continue + } + err = ctx.Commit() + if err != nil { + continue + } + default: + return fmt.Errorf("invalid program counter %v", labelTag) + } + } +} + +func AServer(ctx *distsys.MPCalContext, self distsys.TLAValue, constants Constants, mailboxes0 distsys.ArchetypeResourceHandle, file_system distsys.ArchetypeResourceHandle) error { + var err0 error + // label tags + const ( + serverLoopLabelTag = iota + rcvReqLabelTag + sendPageLabelTag + ) + programCounter0 := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.NewTLANumber(serverLoopLabelTag)) + msg0 := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.TLAValue{}) + + for { + if err0 != nil { + if err0 == distsys.CriticalSectionAborted { + ctx.Abort() + err0 = nil + } else { + return err0 + } + } + labelTag0, err0 := ctx.Read(programCounter0, []distsys.TLAValue{}) + if err0 != nil { + return err0 + } + switch labelTag0.AsNumber() { + case serverLoopLabelTag: + if distsys.TLA_TRUE.AsBool() { + err0 = ctx.Write(programCounter0, []distsys.TLAValue{}, distsys.NewTLANumber(rcvReqLabelTag)) + if err0 != nil { + continue + } + err0 = ctx.Commit() + if err0 != nil { + continue + } + } else { + // no statements + } + // no statements + case rcvReqLabelTag: + var exprRead4 distsys.TLAValue + exprRead4, err0 = ctx.Read(mailboxes0, []distsys.TLAValue{self}) + if err0 != nil { + continue + } + err0 = ctx.Write(msg0, []distsys.TLAValue{}, exprRead4) + if err0 != nil { + continue + } + err0 = ctx.Write(programCounter0, []distsys.TLAValue{}, distsys.NewTLANumber(sendPageLabelTag)) + if err0 != nil { + continue + } + err0 = ctx.Commit() + if err0 != nil { + continue + } + case sendPageLabelTag: + var exprRead5 distsys.TLAValue + exprRead5, err0 = ctx.Read(msg0, []distsys.TLAValue{}) + if err0 != nil { + continue + } + var exprRead6 distsys.TLAValue + exprRead6, err0 = ctx.Read(file_system, []distsys.TLAValue{exprRead5.ApplyFunction(distsys.NewTLAString("path"))}) + if err0 != nil { + continue + } + var indexRead0 distsys.TLAValue + indexRead0, err0 = ctx.Read(msg0, []distsys.TLAValue{}) + if err0 != nil { + continue + } + err0 = ctx.Write(mailboxes0, []distsys.TLAValue{indexRead0.ApplyFunction(distsys.NewTLAString("client_id"))}, exprRead6) + if err0 != nil { + continue + } + err0 = ctx.Write(programCounter0, []distsys.TLAValue{}, distsys.NewTLANumber(serverLoopLabelTag)) + if err0 != nil { + continue + } + err0 = ctx.Commit() + if err0 != nil { + continue + } + default: + return fmt.Errorf("invalid program counter %v", labelTag0) + } + } +} + +func AClient(ctx *distsys.MPCalContext, self distsys.TLAValue, constants Constants, mailboxes1 distsys.ArchetypeResourceHandle, instream distsys.ArchetypeResourceHandle, outstream distsys.ArchetypeResourceHandle) error { + var err1 error + // label tags + const ( + clientLoopLabelTag = iota + clientRequestLabelTag + clientReceiveLabelTag + ) + programCounter1 := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.NewTLANumber(clientLoopLabelTag)) + req := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.TLAValue{}) + resp := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.TLAValue{}) + + for { + if err1 != nil { + if err1 == distsys.CriticalSectionAborted { + ctx.Abort() + err1 = nil + } else { + return err1 + } + } + labelTag1, err1 := ctx.Read(programCounter1, []distsys.TLAValue{}) + if err1 != nil { + return err1 + } + switch labelTag1.AsNumber() { + case clientLoopLabelTag: + if distsys.TLA_TRUE.AsBool() { + err1 = ctx.Write(programCounter1, []distsys.TLAValue{}, distsys.NewTLANumber(clientRequestLabelTag)) + if err1 != nil { + continue + } + err1 = ctx.Commit() + if err1 != nil { + continue + } + } else { + // no statements + } + // no statements + case clientRequestLabelTag: + var exprRead7 distsys.TLAValue + exprRead7, err1 = ctx.Read(instream, []distsys.TLAValue{}) + if err1 != nil { + continue + } + err1 = ctx.Write(req, []distsys.TLAValue{}, distsys.NewTLARecord([]distsys.TLARecordField{ + {distsys.NewTLAString("message_type"), constants.GET_PAGE}, + {distsys.NewTLAString("client_id"), self}, + {distsys.NewTLAString("path"), exprRead7}, + })) + if err1 != nil { + continue + } + var exprRead8 distsys.TLAValue + exprRead8, err1 = ctx.Read(req, []distsys.TLAValue{}) + if err1 != nil { + continue + } + err1 = ctx.Write(mailboxes1, []distsys.TLAValue{constants.LoadBalancerId}, exprRead8) + if err1 != nil { + continue + } + err1 = ctx.Write(programCounter1, []distsys.TLAValue{}, distsys.NewTLANumber(clientReceiveLabelTag)) + if err1 != nil { + continue + } + err1 = ctx.Commit() + if err1 != nil { + continue + } + case clientReceiveLabelTag: + var exprRead9 distsys.TLAValue + exprRead9, err1 = ctx.Read(mailboxes1, []distsys.TLAValue{self}) + if err1 != nil { + continue + } + err1 = ctx.Write(resp, []distsys.TLAValue{}, exprRead9) + if err1 != nil { + continue + } + var exprRead10 distsys.TLAValue + exprRead10, err1 = ctx.Read(resp, []distsys.TLAValue{}) + if err1 != nil { + continue + } + err1 = ctx.Write(outstream, []distsys.TLAValue{}, exprRead10) + if err1 != nil { + continue + } + err1 = ctx.Write(programCounter1, []distsys.TLAValue{}, distsys.NewTLANumber(clientLoopLabelTag)) + if err1 != nil { + continue + } + err1 = ctx.Commit() + if err1 != nil { + continue + } + default: + return fmt.Errorf("invalid program counter %v", labelTag1) + } + } +} + diff --git a/test/files/general/load_balancer.tla.gotests/load_balancer_test.go b/test/files/general/load_balancer.tla.gotests/load_balancer_test.go new file mode 100644 index 000000000..53f85b7f6 --- /dev/null +++ b/test/files/general/load_balancer.tla.gotests/load_balancer_test.go @@ -0,0 +1,8 @@ +package loadbalancer + +import "testing" + +func TestOneServer(t *testing.T) { + // TODO: test 1 client, 1 server scenario + t.Fail() +} diff --git a/test/files/general/replicated_kv.tla b/test/files/general/replicated_kv.tla index d8301990d..7cb601225 100644 --- a/test/files/general/replicated_kv.tla +++ b/test/files/general/replicated_kv.tla @@ -156,7 +156,7 @@ NullSet == (NUM_REPLICAS+3*NUM_CLIENTS)..(NUM_REPLICAS+4*NUM_CLIENTS-1) \* incoming messages. \* - kv: the underlying "database". When 'put' requests become stable, this \* database is updated to include the value being set by the client. - archetype AReplica(ref clients, replicas, ref kv) + archetype AReplica(ref clients[_], ref replicas[_], ref kv[_]) \* Local state in a replica: variables @@ -423,7 +423,7 @@ NullSet == (NUM_REPLICAS+3*NUM_CLIENTS)..(NUM_REPLICAS+4*NUM_CLIENTS-1) \* A Get message sent to the replica is a record in the following format: \* \* [op: GET_MSG, key: key, client: client_id, timestamp: lamport_clock] - archetype Get(clientId, ref replicas, clients, key, ref clock, spin, ref outside) + archetype Get(ref clientId, ref replicas[_], ref clients[_], key, ref clock[_], spin, ref outside) variable continue = TRUE, getReq, getResp; { \* Loop until disconnected @@ -478,7 +478,7 @@ NullSet == (NUM_REPLICAS+3*NUM_CLIENTS)..(NUM_REPLICAS+4*NUM_CLIENTS-1) \* A Put message sent to the replica is a record in the following format: \* \* [op: PUT_MSG, key: key, value: value, client: client_id, timestamp: lamport_clock] - archetype Put(clientId, ref replicas, clients, key, value, ref clock, spin, ref outside) + archetype Put(ref clientId, ref replicas[_], ref clients[_], key, value, ref clock[_], spin, ref outside) variables continue = TRUE, i, j, putReq, putResp; { \* Loops indefinitely until disconnected @@ -531,7 +531,7 @@ NullSet == (NUM_REPLICAS+3*NUM_CLIENTS)..(NUM_REPLICAS+4*NUM_CLIENTS-1) \* A Disconnect message sent to the replica is a record in the following format: \* \* [op: DISCONNECT_MSG, client: client_id] - archetype Disconnect(clientId, ref replicas, ref clock) + archetype Disconnect(ref clientId, ref replicas[_], ref clock[_]) variables msg, j; { sendDisconnectRequest: @@ -555,7 +555,7 @@ NullSet == (NUM_REPLICAS+3*NUM_CLIENTS)..(NUM_REPLICAS+4*NUM_CLIENTS-1) \* A ClockUpdate message sent to the replica is a record in the following format: \* \* [op: NULL_MSG, client: client_id, timestamp: logical_clock] - archetype ClockUpdate(clientId, ref replicas, ref clock, spin) + archetype ClockUpdate(ref clientId, ref replicas[_], ref clock[_], spin) variables continue = TRUE, j, msg; { clockUpdateLoop: @@ -617,34 +617,30 @@ NullSet == (NUM_REPLICAS+3*NUM_CLIENTS)..(NUM_REPLICAS+4*NUM_CLIENTS-1) \* Instantiate replica servers. The network model used is the one defined in \* the FIFOChannel mapping macro. - fair process (Replica \in ReplicaSet) == instance AReplica(ref clientMailboxes, replicasNetwork, [k \in KeySpace |-> NULL]) + fair process (Replica \in ReplicaSet) == instance AReplica(ref clientMailboxes[_], ref replicasNetwork[_], [k \in KeySpace |-> NULL]) mapping @1[_] via FIFOChannel mapping @2[_] via FIFOChannel mapping @3[_] via Identity; \* Instantiate clients: - fair process (GetClient \in GetSet) == instance Get(cid, ref replicasNetwork, clientMailboxes, GET_KEY, ref clocks, TRUE, ref out) + fair process (GetClient \in GetSet) == instance Get(ref cid, ref replicasNetwork[_], ref clientMailboxes[_], GET_KEY, ref clocks[_], TRUE, ref out) mapping cid via GetClientId mapping replicasNetwork[_] via FIFOChannel - mapping clientMailboxes[_] via FIFOChannel - mapping clocks[_] via Identity; + mapping clientMailboxes[_] via FIFOChannel; - fair process (PutClient \in PutSet) == instance Put(cid, ref replicasNetwork, clientMailboxes, PUT_KEY, PUT_VALUE, ref clocks, TRUE, ref out) + fair process (PutClient \in PutSet) == instance Put(ref cid, ref replicasNetwork[_], ref clientMailboxes[_], PUT_KEY, PUT_VALUE, ref clocks[_], TRUE, ref out) mapping cid via PutClientId mapping replicasNetwork[_] via FIFOChannel - mapping clientMailboxes[_] via FIFOChannel - mapping clocks[_] via Identity; + mapping clientMailboxes[_] via FIFOChannel; - fair process (DisconnectClient \in DisconnectSet) == instance Disconnect(cid, ref replicasNetwork, ref clocks) + fair process (DisconnectClient \in DisconnectSet) == instance Disconnect(ref cid, ref replicasNetwork[_], ref clocks[_]) mapping cid via DisconnectClientId - mapping replicasNetwork[_] via FIFOChannel - mapping clocks[_] via Identity; + mapping replicasNetwork[_] via FIFOChannel; - fair process (ClockUpdateClient \in NullSet) == instance ClockUpdate(cid, ref replicasNetwork, ref clocks, TRUE) + fair process (ClockUpdateClient \in NullSet) == instance ClockUpdate(ref cid, ref replicasNetwork[_], ref clocks[_], TRUE) mapping cid via NullClientId - mapping replicasNetwork[_] via FIFOChannel - mapping clocks[_] via Identity; + mapping replicasNetwork[_] via FIFOChannel; } \* BEGIN PLUSCAL TRANSLATION diff --git a/test/pgo/GoGenFileTests.scala b/test/pgo/GoGenFileTests.scala index e33bcb7a4..80d4a11bc 100644 --- a/test/pgo/GoGenFileTests.scala +++ b/test/pgo/GoGenFileTests.scala @@ -14,6 +14,7 @@ class GoGenFileTests extends FileTestSuite { test(s"gogen ${testFile.relativeTo(os.pwd)}") { val outDir = os.temp.dir() val goTestsDir = testFile / os.up / s"${testFile.last}.gotests" + if(os.isDir(goTestsDir)) { // should only do something useful when PGo isn't expected to error out os.copy.over(from = goTestsDir, to = outDir, createFolders = true) // rewrite go.mod to point to the absolute path of our local copy of the distsys library @@ -23,10 +24,12 @@ class GoGenFileTests extends FileTestSuite { case line => Some(line) }.map(line => s"$line\n")) } + val outFile = outDir / s"${testFile.baseName}.go" val errors = PGo.run(Seq("gogen", "-s", testFile.toString(), "-o", outFile.toString())) checkErrors(errors, testFile) if(errors.isEmpty) { + assert(os.exists(goTestsDir)) // sanity if(!sys.env.contains("TESTS_DO_NOT_WRITE")) { // unless the environment var above is set, write the output file into the test files, so the test can // be debugged / manipulated using standard Go tools From 1b6b980c6f53c1e23c619882d398397e048e3d12 Mon Sep 17 00:00:00 2001 From: fhackett Date: Thu, 1 Jul 2021 15:43:04 -0700 Subject: [PATCH 10/27] add comments to LocalArchetypeResource, run go fmt --- distsys/archetypes.go | 42 +- distsys/mpcal.go | 21 +- distsys/tlaplus.go | 770 +++++++++--------- .../general/dqueue.tla.gotests/dqueue.go | 324 ++++---- .../general/dqueue.tla.gotests/dqueue_test.go | 1 - .../load_balancer.go | 630 +++++++------- 6 files changed, 894 insertions(+), 894 deletions(-) diff --git a/distsys/archetypes.go b/distsys/archetypes.go index 8661eaea4..9d8b13d6f 100644 --- a/distsys/archetypes.go +++ b/distsys/archetypes.go @@ -61,7 +61,9 @@ type LocalArchetypeResource struct { type localArchetypeResourceRecord struct { IsInitialized bool // start-up flag, to avoid setting up state again when reloading from disk - HasOldValue bool + HasOldValue bool // if true, this resource has already been written in this critical section + // if this resource is already written in this critical section, OldValue contains prev value + // Value always contains the "current" value Value, OldValue TLAValue } @@ -131,7 +133,7 @@ func (res *LocalArchetypeResource) GobEncode() ([]byte, error) { type InputChannelResource struct { ArchetypeResourceLeafMixin channel <-chan TLAValue - buffer []TLAValue + buffer []TLAValue } var _ ArchetypeResource = &InputChannelResource{} @@ -189,13 +191,13 @@ func (res *InputChannelResource) GobEncode() ([]byte, error) { type OutputChannelResource struct { ArchetypeResourceLeafMixin - channel chan <-TLAValue - buffer []TLAValue + channel chan<- TLAValue + buffer []TLAValue } var _ ArchetypeResource = &OutputChannelResource{} -func EnsureOutputChannelResource(ensurer MPCalContextResourceEnsurer, channel chan <-TLAValue) ArchetypeResourceHandle { +func EnsureOutputChannelResource(ensurer MPCalContextResourceEnsurer, channel chan<- TLAValue) ArchetypeResourceHandle { return ensurer(&OutputChannelResource{}, func(resource ArchetypeResource) { res := resource.(*OutputChannelResource) res.channel = channel @@ -250,7 +252,7 @@ type IncrementalArchetypeMapResource struct { } type incrementalArchetypeMapResourceRecord struct { - Key TLAValue + Key TLAValue Value ArchetypeResource } @@ -285,7 +287,7 @@ func (res *IncrementalArchetypeMapResource) EnsureConfig(fillFunction func(Incre func (res *IncrementalArchetypeMapResource) Index(index TLAValue) (ArchetypeResource, error) { var resource ArchetypeResource - res.FillFunction(func (blank ArchetypeResource, configFn func(ArchetypeResource)) { + res.FillFunction(func(blank ArchetypeResource, configFn func(ArchetypeResource)) { if subRes, ok := res.realizedMap.Get(index); ok { resource = subRes.(ArchetypeResource) } else { @@ -319,7 +321,7 @@ func (res *IncrementalArchetypeMapResource) PreCommit() chan error { break } } - outCh<- err + outCh <- err }() return outCh } @@ -342,7 +344,7 @@ func (res *IncrementalArchetypeMapResource) Commit() chan struct{} { for _, ch := range nonTrivialCommits { <-ch } - outCh<- struct{}{} + outCh <- struct{}{} }() return outCh } @@ -365,7 +367,7 @@ func (res *IncrementalArchetypeMapResource) Abort() chan struct{} { for _, ch := range nonTrivialAborts { <-ch } - outCh<- struct{}{} + outCh <- struct{}{} }() return outCh } @@ -396,7 +398,7 @@ func (res *IncrementalArchetypeMapResource) GobEncode() ([]byte, error) { for !it.Done() { key, value := it.Next() err := encoder.Encode(incrementalArchetypeMapResourceRecord{ - Key: key.(TLAValue), + Key: key.(TLAValue), Value: value.(ArchetypeResource), }) if err != nil { @@ -462,14 +464,14 @@ type TCPMailboxLocalArchetypeResource struct { ArchetypeResourceLeafMixin listenAddr string - listener net.Listener - buffer *list.List + listener net.Listener + buffer *list.List bufferFillNotify chan struct{} - bufferLock sync.Mutex + bufferLock sync.Mutex bufferSize int - readBacklog []TLAValue + readBacklog []TLAValue readsInProgress []TLAValue } @@ -655,10 +657,10 @@ type TCPMailboxRemoteArchetypeResource struct { dialAddr string inCriticalSection bool - conn net.Conn - connEncoder *gob.Encoder - connDecoder *gob.Decoder - sendBuffer []TLAValue + conn net.Conn + connEncoder *gob.Encoder + connDecoder *gob.Decoder + sendBuffer []TLAValue } var _ ArchetypeResource = &TCPMailboxRemoteArchetypeResource{} @@ -717,7 +719,7 @@ func (res *TCPMailboxRemoteArchetypeResource) Commit() chan struct{} { ch := make(chan struct{}, 1) go func() { var err error - outerLoop: + outerLoop: for { if err != nil { log.Printf("network error during commit, resetting: %v", err) diff --git a/distsys/mpcal.go b/distsys/mpcal.go index 43e08b6d2..aa2d17bda 100644 --- a/distsys/mpcal.go +++ b/distsys/mpcal.go @@ -8,9 +8,9 @@ import ( var AssertionFailed = errors.New("assertion failed") type ArchetypeResourceHandle struct { - Tag int + Tag int Index int - Name string + Name string } const ( @@ -19,11 +19,11 @@ const ( ) type MPCalDurableStorageRecord struct { - Resources []ArchetypeResource - Frame int - FrameStack []int + Resources []ArchetypeResource + Frame int + FrameStack []int ResourcesByName map[string]ArchetypeResource - CommitPending map[ArchetypeResourceHandle]bool + CommitPending map[ArchetypeResourceHandle]bool } func (record *MPCalDurableStorageRecord) getResourceByHandle(handle ArchetypeResourceHandle) ArchetypeResource { @@ -44,7 +44,7 @@ type MPCalDurableStorage interface { type MPCalContext struct { durableStorage MPCalDurableStorage - record MPCalDurableStorageRecord + record MPCalDurableStorageRecord } func NewMPCalContext(durableStorage MPCalDurableStorage) (*MPCalContext, error) { @@ -75,11 +75,10 @@ func NewMPCalContext(durableStorage MPCalDurableStorage) (*MPCalContext, error) } return &MPCalContext{ durableStorage: durableStorage, - record: *record, + record: *record, }, nil } - type MPCalContextArchetypeConfigFn func(durability MPCalDurableStorage, resource ArchetypeResource) type MPCalContextResourceEnsurer func(blank ArchetypeResource, configFn func(resource ArchetypeResource)) ArchetypeResourceHandle @@ -123,8 +122,8 @@ func (ctx *MPCalContext) PositionalResourceStackPush() { } func (ctx *MPCalContext) PositionalResourceStackPop() { - ctx.record.Frame = ctx.record.FrameStack[len(ctx.record.FrameStack) - 1] - ctx.record.FrameStack = ctx.record.FrameStack[:len(ctx.record.FrameStack) - 1] + ctx.record.Frame = ctx.record.FrameStack[len(ctx.record.FrameStack)-1] + ctx.record.FrameStack = ctx.record.FrameStack[:len(ctx.record.FrameStack)-1] ctx.record.Resources = ctx.record.Resources[:ctx.record.Frame] } diff --git a/distsys/tlaplus.go b/distsys/tlaplus.go index 4bb38d070..c2383b345 100644 --- a/distsys/tlaplus.go +++ b/distsys/tlaplus.go @@ -1,159 +1,159 @@ package distsys import ( - "bytes" - "encoding/binary" - "encoding/gob" - "errors" - "fmt" - "github.com/benbjohnson/immutable" - "hash/fnv" - "io" - "strconv" - "strings" + "bytes" + "encoding/binary" + "encoding/gob" + "errors" + "fmt" + "github.com/benbjohnson/immutable" + "hash/fnv" + "io" + "strconv" + "strings" ) var TLATypeError = errors.New("TLA+ type error") func init() { - gob.Register(tlaValueBool(false)) - gob.Register(tlaValueNumber(0)) - gob.Register(tlaValueString("")) - gob.Register(&tlaValueSet{}) - gob.Register(&tlaValueTuple{}) + gob.Register(tlaValueBool(false)) + gob.Register(tlaValueNumber(0)) + gob.Register(tlaValueString("")) + gob.Register(&tlaValueSet{}) + gob.Register(&tlaValueTuple{}) } type TLAValue struct { - data tlaValueImpl + data tlaValueImpl } var _ fmt.Stringer = TLAValue{} func (v TLAValue) Hash() uint32 { - if v.data == nil { - return 0 - } else { - return v.data.Hash() - } + if v.data == nil { + return 0 + } else { + return v.data.Hash() + } } func (v TLAValue) Equal(other TLAValue) bool { - if v.data == nil && other.data == nil { - return true - } else if v.data == nil || other.data == nil { - return false - } else { - return v.data.Equal(other) - } + if v.data == nil && other.data == nil { + return true + } else if v.data == nil || other.data == nil { + return false + } else { + return v.data.Equal(other) + } } func (v TLAValue) String() string { - if v.data == nil { - return "defaultInitValue" - } else { - return v.data.String() - } + if v.data == nil { + return "defaultInitValue" + } else { + return v.data.String() + } } func (v *TLAValue) GobDecode(input []byte) error { - buf := bytes.NewBuffer(input) - decoder := gob.NewDecoder(buf) - return decoder.Decode(&v.data) + buf := bytes.NewBuffer(input) + decoder := gob.NewDecoder(buf) + return decoder.Decode(&v.data) } func (v *TLAValue) GobEncode() ([]byte, error) { - var buf bytes.Buffer - encoder := gob.NewEncoder(&buf) - err := encoder.Encode(&v.data) - return buf.Bytes(), err + var buf bytes.Buffer + encoder := gob.NewEncoder(&buf) + err := encoder.Encode(&v.data) + return buf.Bytes(), err } func (v TLAValue) AsBool() bool { - switch data := v.data.(type) { - case tlaValueBool: - return bool(data) - default: - panic(fmt.Errorf("%w: %v is not a boolean", TLATypeError, v)) - } + switch data := v.data.(type) { + case tlaValueBool: + return bool(data) + default: + panic(fmt.Errorf("%w: %v is not a boolean", TLATypeError, v)) + } } func (v TLAValue) AsNumber() int32 { - switch data := v.data.(type) { - case tlaValueNumber: - return int32(data) - default: - panic(fmt.Errorf("%w: %v is not a number", TLATypeError, v)) - } + switch data := v.data.(type) { + case tlaValueNumber: + return int32(data) + default: + panic(fmt.Errorf("%w: %v is not a number", TLATypeError, v)) + } } func (v TLAValue) AsString() string { - switch data := v.data.(type) { - case tlaValueString: - return string(data) - default: - panic(fmt.Errorf("%w: %v is not a string", TLATypeError, v)) - } + switch data := v.data.(type) { + case tlaValueString: + return string(data) + default: + panic(fmt.Errorf("%w: %v is not a string", TLATypeError, v)) + } } func (v TLAValue) AsSet() *immutable.Map { - switch data := v.data.(type) { - case *tlaValueSet: - return data.Map - default: - panic(fmt.Errorf("%w: %v is not a set", TLATypeError, v)) - } + switch data := v.data.(type) { + case *tlaValueSet: + return data.Map + default: + panic(fmt.Errorf("%w: %v is not a set", TLATypeError, v)) + } } func (v TLAValue) AsTuple() *immutable.List { - switch data := v.data.(type) { - case *tlaValueTuple: - return data.List - default: - panic(fmt.Errorf("%w: %v is not a tuple", TLATypeError, v)) - } + switch data := v.data.(type) { + case *tlaValueTuple: + return data.List + default: + panic(fmt.Errorf("%w: %v is not a tuple", TLATypeError, v)) + } } func (v TLAValue) AsFunction() *tlaValueFunction { - switch data := v.data.(type) { - case *tlaValueFunction: - return data - default: - panic(fmt.Errorf("%w: %v is not a function", TLATypeError, v)) - } + switch data := v.data.(type) { + case *tlaValueFunction: + return data + default: + panic(fmt.Errorf("%w: %v is not a function", TLATypeError, v)) + } } func (v TLAValue) SelectElement() TLAValue { - set := v.AsSet() - it := set.Iterator() - if !it.Done() { - key, _ := it.Next() - return key.(TLAValue) - } else { - panic(fmt.Errorf("tried to select an element of %v, which was an empty set", v)) - } + set := v.AsSet() + it := set.Iterator() + if !it.Done() { + key, _ := it.Next() + return key.(TLAValue) + } else { + panic(fmt.Errorf("tried to select an element of %v, which was an empty set", v)) + } } func (v TLAValue) ApplyFunction(argument TLAValue) TLAValue { - switch data := v.data.(type) { - case *tlaValueTuple: - return data.Get(int(argument.AsNumber())).(TLAValue) - case *tlaValueFunction: - value, ok := data.Get(argument) - if !ok { - panic(fmt.Errorf("function %v's domain does not contain index %v", v, argument)) - } - return value.(TLAValue) - default: - panic(fmt.Errorf("%w: could not apply %v", TLATypeError, v)) - } + switch data := v.data.(type) { + case *tlaValueTuple: + return data.Get(int(argument.AsNumber())).(TLAValue) + case *tlaValueFunction: + value, ok := data.Get(argument) + if !ok { + panic(fmt.Errorf("function %v's domain does not contain index %v", v, argument)) + } + return value.(TLAValue) + default: + panic(fmt.Errorf("%w: could not apply %v", TLATypeError, v)) + } } func TLA_EqualsSymbol(lhs, rhs TLAValue) TLAValue { - if lhs.Equal(rhs) { - return TLA_TRUE - } else { - return TLA_FALSE - } + if lhs.Equal(rhs) { + return TLA_TRUE + } else { + return TLA_FALSE + } } type TLAValueHasher struct{} @@ -161,17 +161,17 @@ type TLAValueHasher struct{} var _ immutable.Hasher = TLAValueHasher{} func (TLAValueHasher) Hash(key interface{}) uint32 { - return key.(TLAValue).Hash() + return key.(TLAValue).Hash() } func (TLAValueHasher) Equal(a, b interface{}) bool { - return a.(TLAValue).Equal(b.(TLAValue)) + return a.(TLAValue).Equal(b.(TLAValue)) } type tlaValueImpl interface { - Hash() uint32 - Equal(other TLAValue) bool - String() string + Hash() uint32 + Equal(other TLAValue) bool + String() string } type tlaValueBool bool @@ -182,24 +182,24 @@ var TLA_TRUE = TLAValue{tlaValueBool(true)} var TLA_FALSE = TLAValue{tlaValueBool(false)} func (v tlaValueBool) Hash() uint32 { - h := fnv.New32() - err := binary.Write(h, binary.LittleEndian, bool(v)) - if err != nil { - panic(err) - } - return h.Sum32() + h := fnv.New32() + err := binary.Write(h, binary.LittleEndian, bool(v)) + if err != nil { + panic(err) + } + return h.Sum32() } func (v tlaValueBool) Equal(other TLAValue) bool { - return bool(v) == other.AsBool() + return bool(v) == other.AsBool() } func (v tlaValueBool) String() string { - if v { - return "TRUE" - } else { - return "FALSE" - } + if v { + return "TRUE" + } else { + return "FALSE" + } } type tlaValueNumber int32 @@ -207,32 +207,32 @@ type tlaValueNumber int32 var _ tlaValueImpl = tlaValueNumber(0) func NewTLANumber(num int32) TLAValue { - return TLAValue{tlaValueNumber(num)} + return TLAValue{tlaValueNumber(num)} } func (v tlaValueNumber) Hash() uint32 { - h := fnv.New32() - err := binary.Write(h, binary.LittleEndian, int32(v)) - if err != nil { - panic(err) - } - return h.Sum32() + h := fnv.New32() + err := binary.Write(h, binary.LittleEndian, int32(v)) + if err != nil { + panic(err) + } + return h.Sum32() } func (v tlaValueNumber) Equal(other TLAValue) bool { - return int32(v) == other.AsNumber() + return int32(v) == other.AsNumber() } func (v tlaValueNumber) String() string { - return strconv.FormatInt(int64(v), 10) + return strconv.FormatInt(int64(v), 10) } func TLA_PlusSymbol(lhs, rhs TLAValue) TLAValue { - return NewTLANumber(lhs.AsNumber() + rhs.AsNumber()) + return NewTLANumber(lhs.AsNumber() + rhs.AsNumber()) } func TLA_PercentSymbol(lhs, rhs TLAValue) TLAValue { - return NewTLANumber(lhs.AsNumber() % rhs.AsNumber()) + return NewTLANumber(lhs.AsNumber() % rhs.AsNumber()) } type tlaValueString string @@ -240,344 +240,344 @@ type tlaValueString string var _ tlaValueImpl = tlaValueString("") func NewTLAString(value string) TLAValue { - return TLAValue{tlaValueString(value)} + return TLAValue{tlaValueString(value)} } func (v tlaValueString) Hash() uint32 { - vC := string(v) - h := fnv.New32() - _, err := h.Write([]byte(vC)) - if err != nil { - panic(err) - } - return h.Sum32() + vC := string(v) + h := fnv.New32() + _, err := h.Write([]byte(vC)) + if err != nil { + panic(err) + } + return h.Sum32() } func (v tlaValueString) Equal(other TLAValue) bool { - return string(v) == other.AsString() + return string(v) == other.AsString() } func (v tlaValueString) String() string { - return strconv.Quote(string(v)) + return strconv.Quote(string(v)) } type tlaValueSet struct { - *immutable.Map + *immutable.Map } var _ tlaValueImpl = new(tlaValueSet) func NewTLASet(members ...TLAValue) TLAValue { - builder := immutable.NewMapBuilder(TLAValueHasher{}) - for _, member := range members { - builder.Set(member, true) - } - return TLAValue{&tlaValueSet{builder.Map()}} + builder := immutable.NewMapBuilder(TLAValueHasher{}) + for _, member := range members { + builder.Set(member, true) + } + return TLAValue{&tlaValueSet{builder.Map()}} } func (v *tlaValueSet) Hash() uint32 { - var hash uint32 = 0 - it := v.Iterator() - for !it.Done() { - key, _ := it.Next() - keyV := key.(TLAValue) - // use XOR combination, so that all the set members are hashed out of order - hash ^= keyV.Hash() - } - h := fnv.New32() - err := binary.Write(h, binary.LittleEndian, hash) - if err != nil { - panic(err) - } - return h.Sum32() + var hash uint32 = 0 + it := v.Iterator() + for !it.Done() { + key, _ := it.Next() + keyV := key.(TLAValue) + // use XOR combination, so that all the set members are hashed out of order + hash ^= keyV.Hash() + } + h := fnv.New32() + err := binary.Write(h, binary.LittleEndian, hash) + if err != nil { + panic(err) + } + return h.Sum32() } func (v *tlaValueSet) Equal(other TLAValue) bool { - oC := other.AsSet() - if v.Len() != oC.Len() { - return false - } else { - it := v.Iterator() - for !it.Done() { - k, _ := it.Next() - _, ok := oC.Get(k) - if !ok { - return false - } - } - it = oC.Iterator() - for !it.Done() { - k, _ := it.Next() - _, ok := v.Get(k) - if !ok { - return false - } - } - return true - } + oC := other.AsSet() + if v.Len() != oC.Len() { + return false + } else { + it := v.Iterator() + for !it.Done() { + k, _ := it.Next() + _, ok := oC.Get(k) + if !ok { + return false + } + } + it = oC.Iterator() + for !it.Done() { + k, _ := it.Next() + _, ok := v.Get(k) + if !ok { + return false + } + } + return true + } } func (v *tlaValueSet) String() string { - builder := strings.Builder{} - builder.WriteString("{") - it := v.Iterator() - first := true - for !it.Done() { - if first { - first = false - } else { - builder.WriteString(", ") - } - elem, _ := it.Next() - builder.WriteString(elem.(TLAValue).String()) - } - builder.WriteString("}") - return builder.String() + builder := strings.Builder{} + builder.WriteString("{") + it := v.Iterator() + first := true + for !it.Done() { + if first { + first = false + } else { + builder.WriteString(", ") + } + elem, _ := it.Next() + builder.WriteString(elem.(TLAValue).String()) + } + builder.WriteString("}") + return builder.String() } func (v *tlaValueSet) GobEncode() ([]byte, error) { - var buf bytes.Buffer - encoder := gob.NewEncoder(&buf) - it := v.Iterator() - for !it.Done() { - elem, _ := it.Next() - err := encoder.Encode(elem.(TLAValue)) - if err != nil { - return nil, err - } - } - return buf.Bytes(), nil + var buf bytes.Buffer + encoder := gob.NewEncoder(&buf) + it := v.Iterator() + for !it.Done() { + elem, _ := it.Next() + err := encoder.Encode(elem.(TLAValue)) + if err != nil { + return nil, err + } + } + return buf.Bytes(), nil } func (v *tlaValueSet) GobDecode(input []byte) error { - buf := bytes.NewBuffer(input) - decoder := gob.NewDecoder(buf) - builder := immutable.NewMapBuilder(TLAValueHasher{}) - for { - var elem TLAValue - err := decoder.Decode(&elem) - if err != nil { - if errors.Is(err, io.EOF) { - v.Map = builder.Map() - return nil - } else { - return err - } - } - builder.Set(elem, true) - } + buf := bytes.NewBuffer(input) + decoder := gob.NewDecoder(buf) + builder := immutable.NewMapBuilder(TLAValueHasher{}) + for { + var elem TLAValue + err := decoder.Decode(&elem) + if err != nil { + if errors.Is(err, io.EOF) { + v.Map = builder.Map() + return nil + } else { + return err + } + } + builder.Set(elem, true) + } } type tlaValueTuple struct { - *immutable.List + *immutable.List } var _ tlaValueImpl = new(tlaValueTuple) func NewTLATuple(members ...TLAValue) TLAValue { - builder := immutable.NewListBuilder() - for _, member := range members { - builder.Append(member) - } - return TLAValue{&tlaValueTuple{builder.List()}} + builder := immutable.NewListBuilder() + for _, member := range members { + builder.Append(member) + } + return TLAValue{&tlaValueTuple{builder.List()}} } func (v *tlaValueTuple) Hash() uint32 { - h := fnv.New32() - it := v.Iterator() - for !it.Done() { - _, member := it.Next() - memberV := member.(TLAValue) - err := binary.Write(h, binary.LittleEndian, memberV.Hash()) - if err != nil { - panic(err) - } - } - return h.Sum32() + h := fnv.New32() + it := v.Iterator() + for !it.Done() { + _, member := it.Next() + memberV := member.(TLAValue) + err := binary.Write(h, binary.LittleEndian, memberV.Hash()) + if err != nil { + panic(err) + } + } + return h.Sum32() } func (v *tlaValueTuple) Equal(other TLAValue) bool { - otherTuple := other.AsTuple() - if v.Len() != otherTuple.Len() { - return false - } - it1, it2 := v.Iterator(), otherTuple.Iterator() - for !it1.Done() || !it2.Done() { - _, elem1 := it1.Next() - _, elem2 := it2.Next() - if !elem1.(TLAValue).data.Equal(elem2.(TLAValue)) { - return false - } - } - return true + otherTuple := other.AsTuple() + if v.Len() != otherTuple.Len() { + return false + } + it1, it2 := v.Iterator(), otherTuple.Iterator() + for !it1.Done() || !it2.Done() { + _, elem1 := it1.Next() + _, elem2 := it2.Next() + if !elem1.(TLAValue).data.Equal(elem2.(TLAValue)) { + return false + } + } + return true } func (v *tlaValueTuple) String() string { - builder := strings.Builder{} - builder.WriteString("<<") - it := v.Iterator() - first := true - for !it.Done() { - if first { - first = false - } else { - builder.WriteString(", ") - } - _, elem := it.Next() - builder.WriteString(elem.(TLAValue).String()) - } - builder.WriteString(">>") - return builder.String() + builder := strings.Builder{} + builder.WriteString("<<") + it := v.Iterator() + first := true + for !it.Done() { + if first { + first = false + } else { + builder.WriteString(", ") + } + _, elem := it.Next() + builder.WriteString(elem.(TLAValue).String()) + } + builder.WriteString(">>") + return builder.String() } func (v *tlaValueTuple) GobEncode() ([]byte, error) { - var buf bytes.Buffer - encoder := gob.NewEncoder(&buf) - it := v.Iterator() - for !it.Done() { - _, elem := it.Next() - err := encoder.Encode(elem) - if err != nil { - return nil, err - } - } - return buf.Bytes(), nil + var buf bytes.Buffer + encoder := gob.NewEncoder(&buf) + it := v.Iterator() + for !it.Done() { + _, elem := it.Next() + err := encoder.Encode(elem) + if err != nil { + return nil, err + } + } + return buf.Bytes(), nil } func (v *tlaValueTuple) GobDecode(input []byte) error { - buf := bytes.NewBuffer(input) - decoder := gob.NewDecoder(buf) - builder := immutable.NewListBuilder() - for { - var elem TLAValue - err := decoder.Decode(&elem) - if err != nil { - if errors.Is(err, io.EOF) { - v.List = builder.List() - return nil - } else { - return err - } - } - builder.Append(elem) - } + buf := bytes.NewBuffer(input) + decoder := gob.NewDecoder(buf) + builder := immutable.NewListBuilder() + for { + var elem TLAValue + err := decoder.Decode(&elem) + if err != nil { + if errors.Is(err, io.EOF) { + v.List = builder.List() + return nil + } else { + return err + } + } + builder.Append(elem) + } } type tlaValueFunction struct { - *immutable.Map - domain, rng *TLAValue + *immutable.Map + domain, rng *TLAValue } type TLARecordField struct { - Key, Value TLAValue + Key, Value TLAValue } func (field TLARecordField) Hash() uint32 { - h := fnv.New32() - err := binary.Write(h, binary.LittleEndian, field.Key.Hash()) - if err != nil { - panic(err) - } - err = binary.Write(h, binary.LittleEndian, field.Value.Hash()) - if err != nil { - panic(err) - } - return h.Sum32() + h := fnv.New32() + err := binary.Write(h, binary.LittleEndian, field.Key.Hash()) + if err != nil { + panic(err) + } + err = binary.Write(h, binary.LittleEndian, field.Value.Hash()) + if err != nil { + panic(err) + } + return h.Sum32() } var _ tlaValueImpl = &tlaValueFunction{} func NewTLARecord(pairs []TLARecordField) TLAValue { - builder := immutable.NewMapBuilder(TLAValueHasher{}) - for _, pair := range pairs { - builder.Set(pair.Key, pair.Value) - } - return TLAValue{&tlaValueFunction{Map: builder.Map()}} + builder := immutable.NewMapBuilder(TLAValueHasher{}) + for _, pair := range pairs { + builder.Set(pair.Key, pair.Value) + } + return TLAValue{&tlaValueFunction{Map: builder.Map()}} } func (v *tlaValueFunction) Hash() uint32 { - var hash uint32 - it := v.Iterator() - for !it.Done() { - key, value := it.Next() - hash ^= TLARecordField{Key: key.(TLAValue), Value: value.(TLAValue)}.Hash() - } - h := fnv.New32() - err := binary.Write(h, binary.LittleEndian, hash) - if err != nil { - panic(err) - } - return h.Sum32() + var hash uint32 + it := v.Iterator() + for !it.Done() { + key, value := it.Next() + hash ^= TLARecordField{Key: key.(TLAValue), Value: value.(TLAValue)}.Hash() + } + h := fnv.New32() + err := binary.Write(h, binary.LittleEndian, hash) + if err != nil { + panic(err) + } + return h.Sum32() } func (v *tlaValueFunction) Equal(other TLAValue) bool { - otherFunction := other.AsFunction() - if v.Len() != otherFunction.Len() { - return false - } - it := v.Iterator() - for !it.Done() { - key, value := it.Next() - otherValue, ok := otherFunction.Get(key) - if !ok || !value.(TLAValue).Equal(otherValue.(TLAValue)) { - return false - } - } - return true + otherFunction := other.AsFunction() + if v.Len() != otherFunction.Len() { + return false + } + it := v.Iterator() + for !it.Done() { + key, value := it.Next() + otherValue, ok := otherFunction.Get(key) + if !ok || !value.(TLAValue).Equal(otherValue.(TLAValue)) { + return false + } + } + return true } func (v *tlaValueFunction) String() string { - builder := strings.Builder{} - builder.WriteString("[") - first := true - it := v.Iterator() - for !it.Done() { - key, value := it.Next() - if first { - first = false - } else { - builder.WriteString(", ") - } - builder.WriteString(key.(TLAValue).String()) - builder.WriteString(" |-> ") - builder.WriteString(value.(TLAValue).String()) - } - builder.WriteString("]") - return builder.String() + builder := strings.Builder{} + builder.WriteString("[") + first := true + it := v.Iterator() + for !it.Done() { + key, value := it.Next() + if first { + first = false + } else { + builder.WriteString(", ") + } + builder.WriteString(key.(TLAValue).String()) + builder.WriteString(" |-> ") + builder.WriteString(value.(TLAValue).String()) + } + builder.WriteString("]") + return builder.String() } func (v *tlaValueFunction) GobEncode() ([]byte, error) { - var buf bytes.Buffer - encoder := gob.NewEncoder(&buf) - it := v.Iterator() - for !it.Done() { - key, value := it.Next() - err := encoder.Encode(TLARecordField{ - Key: key.(TLAValue), - Value: value.(TLAValue), - }) - if err != nil { - return nil, err - } - } - return buf.Bytes(), nil + var buf bytes.Buffer + encoder := gob.NewEncoder(&buf) + it := v.Iterator() + for !it.Done() { + key, value := it.Next() + err := encoder.Encode(TLARecordField{ + Key: key.(TLAValue), + Value: value.(TLAValue), + }) + if err != nil { + return nil, err + } + } + return buf.Bytes(), nil } func (v *tlaValueFunction) GobDecode(input []byte) error { - buf := bytes.NewBuffer(input) - decoder := gob.NewDecoder(buf) - builder := immutable.NewMapBuilder(TLAValueHasher{}) - for { - var field TLARecordField - err := decoder.Decode(&field) - if err != nil { - if errors.Is(err, io.EOF) { - v.Map = builder.Map() - return nil - } else { - return err - } - } - builder.Set(field.Key, field.Value) - } + buf := bytes.NewBuffer(input) + decoder := gob.NewDecoder(buf) + builder := immutable.NewMapBuilder(TLAValueHasher{}) + for { + var field TLARecordField + err := decoder.Decode(&field) + if err != nil { + if errors.Is(err, io.EOF) { + v.Map = builder.Map() + return nil + } else { + return err + } + } + builder.Set(field.Key, field.Value) + } } diff --git a/test/files/general/dqueue.tla.gotests/dqueue.go b/test/files/general/dqueue.tla.gotests/dqueue.go index 9fc70ca1d..e37946c62 100644 --- a/test/files/general/dqueue.tla.gotests/dqueue.go +++ b/test/files/general/dqueue.tla.gotests/dqueue.go @@ -1,177 +1,177 @@ package dqueue import ( - "github.com/UBC-NSS/pgo/distsys" - "fmt") + "fmt" + "github.com/UBC-NSS/pgo/distsys" +) type Constants struct { - BUFFER_SIZE distsys.TLAValue - NUM_CONSUMERS distsys.TLAValue - PRODUCER distsys.TLAValue + BUFFER_SIZE distsys.TLAValue + NUM_CONSUMERS distsys.TLAValue + PRODUCER distsys.TLAValue } func NUM_NODES(constants Constants) distsys.TLAValue { - return distsys.TLA_PlusSymbol(constants.NUM_CONSUMERS, distsys.NewTLANumber(1)) + return distsys.TLA_PlusSymbol(constants.NUM_CONSUMERS, distsys.NewTLANumber(1)) } func AConsumer(ctx *distsys.MPCalContext, self distsys.TLAValue, constants Constants, net distsys.ArchetypeResourceHandle, proc distsys.ArchetypeResourceHandle) error { - var err error - // label tags - const ( - cLabelTag = iota - c1LabelTag - c2LabelTag - ) - programCounter := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.NewTLANumber(cLabelTag)) - - for { - if err != nil { - if err == distsys.CriticalSectionAborted { - ctx.Abort() - err = nil - } else { - return err - } - } - labelTag, err := ctx.Read(programCounter, []distsys.TLAValue{}) - if err != nil { - return err - } - switch labelTag.AsNumber() { - case cLabelTag: - if distsys.TLA_TRUE.AsBool() { - err = ctx.Write(programCounter, []distsys.TLAValue{}, distsys.NewTLANumber(c1LabelTag)) - if err != nil { - continue - } - err = ctx.Commit() - if err != nil { - continue - } - } else { - // no statements - } - // no statements - case c1LabelTag: - err = ctx.Write(net, []distsys.TLAValue{constants.PRODUCER}, self) - if err != nil { - continue - } - err = ctx.Write(programCounter, []distsys.TLAValue{}, distsys.NewTLANumber(c2LabelTag)) - if err != nil { - continue - } - err = ctx.Commit() - if err != nil { - continue - } - case c2LabelTag: - var exprRead distsys.TLAValue - exprRead, err = ctx.Read(net, []distsys.TLAValue{self}) - if err != nil { - continue - } - err = ctx.Write(proc, []distsys.TLAValue{}, exprRead) - if err != nil { - continue - } - err = ctx.Write(programCounter, []distsys.TLAValue{}, distsys.NewTLANumber(cLabelTag)) - if err != nil { - continue - } - err = ctx.Commit() - if err != nil { - continue - } - default: - return fmt.Errorf("invalid program counter %v", labelTag) - } - } + var err error + // label tags + const ( + cLabelTag = iota + c1LabelTag + c2LabelTag + ) + programCounter := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.NewTLANumber(cLabelTag)) + + for { + if err != nil { + if err == distsys.CriticalSectionAborted { + ctx.Abort() + err = nil + } else { + return err + } + } + labelTag, err := ctx.Read(programCounter, []distsys.TLAValue{}) + if err != nil { + return err + } + switch labelTag.AsNumber() { + case cLabelTag: + if distsys.TLA_TRUE.AsBool() { + err = ctx.Write(programCounter, []distsys.TLAValue{}, distsys.NewTLANumber(c1LabelTag)) + if err != nil { + continue + } + err = ctx.Commit() + if err != nil { + continue + } + } else { + // no statements + } + // no statements + case c1LabelTag: + err = ctx.Write(net, []distsys.TLAValue{constants.PRODUCER}, self) + if err != nil { + continue + } + err = ctx.Write(programCounter, []distsys.TLAValue{}, distsys.NewTLANumber(c2LabelTag)) + if err != nil { + continue + } + err = ctx.Commit() + if err != nil { + continue + } + case c2LabelTag: + var exprRead distsys.TLAValue + exprRead, err = ctx.Read(net, []distsys.TLAValue{self}) + if err != nil { + continue + } + err = ctx.Write(proc, []distsys.TLAValue{}, exprRead) + if err != nil { + continue + } + err = ctx.Write(programCounter, []distsys.TLAValue{}, distsys.NewTLANumber(cLabelTag)) + if err != nil { + continue + } + err = ctx.Commit() + if err != nil { + continue + } + default: + return fmt.Errorf("invalid program counter %v", labelTag) + } + } } func AProducer(ctx *distsys.MPCalContext, self distsys.TLAValue, constants Constants, net0 distsys.ArchetypeResourceHandle, s distsys.ArchetypeResourceHandle) error { - var err0 error - // label tags - const ( - pLabelTag = iota - p1LabelTag - p2LabelTag - ) - programCounter0 := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.NewTLANumber(pLabelTag)) - requester := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.TLAValue{}) - - for { - if err0 != nil { - if err0 == distsys.CriticalSectionAborted { - ctx.Abort() - err0 = nil - } else { - return err0 - } - } - labelTag0, err0 := ctx.Read(programCounter0, []distsys.TLAValue{}) - if err0 != nil { - return err0 - } - switch labelTag0.AsNumber() { - case pLabelTag: - if distsys.TLA_TRUE.AsBool() { - err0 = ctx.Write(programCounter0, []distsys.TLAValue{}, distsys.NewTLANumber(p1LabelTag)) - if err0 != nil { - continue - } - err0 = ctx.Commit() - if err0 != nil { - continue - } - } else { - // no statements - } - // no statements - case p1LabelTag: - var exprRead0 distsys.TLAValue - exprRead0, err0 = ctx.Read(net0, []distsys.TLAValue{self}) - if err0 != nil { - continue - } - err0 = ctx.Write(requester, []distsys.TLAValue{}, exprRead0) - if err0 != nil { - continue - } - err0 = ctx.Write(programCounter0, []distsys.TLAValue{}, distsys.NewTLANumber(p2LabelTag)) - if err0 != nil { - continue - } - err0 = ctx.Commit() - if err0 != nil { - continue - } - case p2LabelTag: - var exprRead1 distsys.TLAValue - exprRead1, err0 = ctx.Read(s, []distsys.TLAValue{}) - if err0 != nil { - continue - } - var indexRead distsys.TLAValue - indexRead, err0 = ctx.Read(requester, []distsys.TLAValue{}) - if err0 != nil { - continue - } - err0 = ctx.Write(net0, []distsys.TLAValue{indexRead}, exprRead1) - if err0 != nil { - continue - } - err0 = ctx.Write(programCounter0, []distsys.TLAValue{}, distsys.NewTLANumber(pLabelTag)) - if err0 != nil { - continue - } - err0 = ctx.Commit() - if err0 != nil { - continue - } - default: - return fmt.Errorf("invalid program counter %v", labelTag0) - } - } -} + var err0 error + // label tags + const ( + pLabelTag = iota + p1LabelTag + p2LabelTag + ) + programCounter0 := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.NewTLANumber(pLabelTag)) + requester := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.TLAValue{}) + for { + if err0 != nil { + if err0 == distsys.CriticalSectionAborted { + ctx.Abort() + err0 = nil + } else { + return err0 + } + } + labelTag0, err0 := ctx.Read(programCounter0, []distsys.TLAValue{}) + if err0 != nil { + return err0 + } + switch labelTag0.AsNumber() { + case pLabelTag: + if distsys.TLA_TRUE.AsBool() { + err0 = ctx.Write(programCounter0, []distsys.TLAValue{}, distsys.NewTLANumber(p1LabelTag)) + if err0 != nil { + continue + } + err0 = ctx.Commit() + if err0 != nil { + continue + } + } else { + // no statements + } + // no statements + case p1LabelTag: + var exprRead0 distsys.TLAValue + exprRead0, err0 = ctx.Read(net0, []distsys.TLAValue{self}) + if err0 != nil { + continue + } + err0 = ctx.Write(requester, []distsys.TLAValue{}, exprRead0) + if err0 != nil { + continue + } + err0 = ctx.Write(programCounter0, []distsys.TLAValue{}, distsys.NewTLANumber(p2LabelTag)) + if err0 != nil { + continue + } + err0 = ctx.Commit() + if err0 != nil { + continue + } + case p2LabelTag: + var exprRead1 distsys.TLAValue + exprRead1, err0 = ctx.Read(s, []distsys.TLAValue{}) + if err0 != nil { + continue + } + var indexRead distsys.TLAValue + indexRead, err0 = ctx.Read(requester, []distsys.TLAValue{}) + if err0 != nil { + continue + } + err0 = ctx.Write(net0, []distsys.TLAValue{indexRead}, exprRead1) + if err0 != nil { + continue + } + err0 = ctx.Write(programCounter0, []distsys.TLAValue{}, distsys.NewTLANumber(pLabelTag)) + if err0 != nil { + continue + } + err0 = ctx.Commit() + if err0 != nil { + continue + } + default: + return fmt.Errorf("invalid program counter %v", labelTag0) + } + } +} diff --git a/test/files/general/dqueue.tla.gotests/dqueue_test.go b/test/files/general/dqueue.tla.gotests/dqueue_test.go index f294e9659..dbc83ad42 100644 --- a/test/files/general/dqueue.tla.gotests/dqueue_test.go +++ b/test/files/general/dqueue.tla.gotests/dqueue_test.go @@ -16,7 +16,6 @@ type dummyDurableStorage struct{} var _ distsys.MPCalDurableStorage = &dummyDurableStorage{} - func (d dummyDurableStorage) RecoverResources() (rec *distsys.MPCalDurableStorageRecord, err error) { return nil, nil } diff --git a/test/files/general/load_balancer.tla.gotests/load_balancer.go b/test/files/general/load_balancer.tla.gotests/load_balancer.go index 9db4d3548..025484587 100644 --- a/test/files/general/load_balancer.tla.gotests/load_balancer.go +++ b/test/files/general/load_balancer.tla.gotests/load_balancer.go @@ -1,333 +1,333 @@ package loadbalancer import ( - "github.com/UBC-NSS/pgo/distsys" - "fmt") + "fmt" + "github.com/UBC-NSS/pgo/distsys" +) type Constants struct { - BUFFER_SIZE distsys.TLAValue - LoadBalancerId distsys.TLAValue - NUM_SERVERS distsys.TLAValue - NUM_CLIENTS distsys.TLAValue - GET_PAGE distsys.TLAValue - WEB_PAGE distsys.TLAValue + BUFFER_SIZE distsys.TLAValue + LoadBalancerId distsys.TLAValue + NUM_SERVERS distsys.TLAValue + NUM_CLIENTS distsys.TLAValue + GET_PAGE distsys.TLAValue + WEB_PAGE distsys.TLAValue } func NUM_NODES(constants Constants) distsys.TLAValue { - return distsys.TLA_PlusSymbol(distsys.TLA_PlusSymbol(constants.NUM_CLIENTS, constants.NUM_SERVERS), distsys.NewTLANumber(1)) + return distsys.TLA_PlusSymbol(distsys.TLA_PlusSymbol(constants.NUM_CLIENTS, constants.NUM_SERVERS), distsys.NewTLANumber(1)) } func ALoadBalancer(ctx *distsys.MPCalContext, self distsys.TLAValue, constants Constants, mailboxes distsys.ArchetypeResourceHandle) error { - var err error - // label tags - const ( - mainLabelTag = iota - rcvMsgLabelTag - sendServerLabelTag - ) - programCounter := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.NewTLANumber(mainLabelTag)) - msg := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.TLAValue{}) - next := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.NewTLANumber(0)) - - for { - if err != nil { - if err == distsys.CriticalSectionAborted { - ctx.Abort() - err = nil - } else { - return err - } - } - labelTag, err := ctx.Read(programCounter, []distsys.TLAValue{}) - if err != nil { - return err - } - switch labelTag.AsNumber() { - case mainLabelTag: - if distsys.TLA_TRUE.AsBool() { - err = ctx.Write(programCounter, []distsys.TLAValue{}, distsys.NewTLANumber(rcvMsgLabelTag)) - if err != nil { - continue - } - err = ctx.Commit() - if err != nil { - continue - } - } else { - // no statements - } - // no statements - case rcvMsgLabelTag: - var exprRead distsys.TLAValue - exprRead, err = ctx.Read(mailboxes, []distsys.TLAValue{constants.LoadBalancerId}) - if err != nil { - continue - } - err = ctx.Write(msg, []distsys.TLAValue{}, exprRead) - if err != nil { - continue - } - var condition distsys.TLAValue - condition, err = ctx.Read(msg, []distsys.TLAValue{}) - if err != nil { - continue - } - if !distsys.TLA_EqualsSymbol(condition.ApplyFunction(distsys.NewTLAString("message_type")), constants.GET_PAGE).AsBool() { - err = fmt.Errorf("%w: ((msg).message_type) = (GET_PAGE)", distsys.AssertionFailed) - continue - } - err = ctx.Write(programCounter, []distsys.TLAValue{}, distsys.NewTLANumber(sendServerLabelTag)) - if err != nil { - continue - } - err = ctx.Commit() - if err != nil { - continue - } - case sendServerLabelTag: - var exprRead0 distsys.TLAValue - exprRead0, err = ctx.Read(next, []distsys.TLAValue{}) - if err != nil { - continue - } - err = ctx.Write(next, []distsys.TLAValue{}, distsys.TLA_PlusSymbol(distsys.TLA_PercentSymbol(exprRead0, constants.NUM_SERVERS), distsys.NewTLANumber(1))) - if err != nil { - continue - } - var exprRead1 distsys.TLAValue - exprRead1, err = ctx.Read(next, []distsys.TLAValue{}) - if err != nil { - continue - } - var exprRead2 distsys.TLAValue - exprRead2, err = ctx.Read(msg, []distsys.TLAValue{}) - if err != nil { - continue - } - var exprRead3 distsys.TLAValue - exprRead3, err = ctx.Read(msg, []distsys.TLAValue{}) - if err != nil { - continue - } - var indexRead distsys.TLAValue - indexRead, err = ctx.Read(next, []distsys.TLAValue{}) - if err != nil { - continue - } - err = ctx.Write(mailboxes, []distsys.TLAValue{indexRead}, distsys.NewTLARecord([]distsys.TLARecordField{ - {distsys.NewTLAString("message_id"), exprRead1}, - {distsys.NewTLAString("client_id"), exprRead2.ApplyFunction(distsys.NewTLAString("client_id"))}, - {distsys.NewTLAString("path"), exprRead3.ApplyFunction(distsys.NewTLAString("path"))}, - })) - if err != nil { - continue - } - err = ctx.Write(programCounter, []distsys.TLAValue{}, distsys.NewTLANumber(mainLabelTag)) - if err != nil { - continue - } - err = ctx.Commit() - if err != nil { - continue - } - default: - return fmt.Errorf("invalid program counter %v", labelTag) - } - } + var err error + // label tags + const ( + mainLabelTag = iota + rcvMsgLabelTag + sendServerLabelTag + ) + programCounter := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.NewTLANumber(mainLabelTag)) + msg := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.TLAValue{}) + next := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.NewTLANumber(0)) + + for { + if err != nil { + if err == distsys.CriticalSectionAborted { + ctx.Abort() + err = nil + } else { + return err + } + } + labelTag, err := ctx.Read(programCounter, []distsys.TLAValue{}) + if err != nil { + return err + } + switch labelTag.AsNumber() { + case mainLabelTag: + if distsys.TLA_TRUE.AsBool() { + err = ctx.Write(programCounter, []distsys.TLAValue{}, distsys.NewTLANumber(rcvMsgLabelTag)) + if err != nil { + continue + } + err = ctx.Commit() + if err != nil { + continue + } + } else { + // no statements + } + // no statements + case rcvMsgLabelTag: + var exprRead distsys.TLAValue + exprRead, err = ctx.Read(mailboxes, []distsys.TLAValue{constants.LoadBalancerId}) + if err != nil { + continue + } + err = ctx.Write(msg, []distsys.TLAValue{}, exprRead) + if err != nil { + continue + } + var condition distsys.TLAValue + condition, err = ctx.Read(msg, []distsys.TLAValue{}) + if err != nil { + continue + } + if !distsys.TLA_EqualsSymbol(condition.ApplyFunction(distsys.NewTLAString("message_type")), constants.GET_PAGE).AsBool() { + err = fmt.Errorf("%w: ((msg).message_type) = (GET_PAGE)", distsys.AssertionFailed) + continue + } + err = ctx.Write(programCounter, []distsys.TLAValue{}, distsys.NewTLANumber(sendServerLabelTag)) + if err != nil { + continue + } + err = ctx.Commit() + if err != nil { + continue + } + case sendServerLabelTag: + var exprRead0 distsys.TLAValue + exprRead0, err = ctx.Read(next, []distsys.TLAValue{}) + if err != nil { + continue + } + err = ctx.Write(next, []distsys.TLAValue{}, distsys.TLA_PlusSymbol(distsys.TLA_PercentSymbol(exprRead0, constants.NUM_SERVERS), distsys.NewTLANumber(1))) + if err != nil { + continue + } + var exprRead1 distsys.TLAValue + exprRead1, err = ctx.Read(next, []distsys.TLAValue{}) + if err != nil { + continue + } + var exprRead2 distsys.TLAValue + exprRead2, err = ctx.Read(msg, []distsys.TLAValue{}) + if err != nil { + continue + } + var exprRead3 distsys.TLAValue + exprRead3, err = ctx.Read(msg, []distsys.TLAValue{}) + if err != nil { + continue + } + var indexRead distsys.TLAValue + indexRead, err = ctx.Read(next, []distsys.TLAValue{}) + if err != nil { + continue + } + err = ctx.Write(mailboxes, []distsys.TLAValue{indexRead}, distsys.NewTLARecord([]distsys.TLARecordField{ + {distsys.NewTLAString("message_id"), exprRead1}, + {distsys.NewTLAString("client_id"), exprRead2.ApplyFunction(distsys.NewTLAString("client_id"))}, + {distsys.NewTLAString("path"), exprRead3.ApplyFunction(distsys.NewTLAString("path"))}, + })) + if err != nil { + continue + } + err = ctx.Write(programCounter, []distsys.TLAValue{}, distsys.NewTLANumber(mainLabelTag)) + if err != nil { + continue + } + err = ctx.Commit() + if err != nil { + continue + } + default: + return fmt.Errorf("invalid program counter %v", labelTag) + } + } } func AServer(ctx *distsys.MPCalContext, self distsys.TLAValue, constants Constants, mailboxes0 distsys.ArchetypeResourceHandle, file_system distsys.ArchetypeResourceHandle) error { - var err0 error - // label tags - const ( - serverLoopLabelTag = iota - rcvReqLabelTag - sendPageLabelTag - ) - programCounter0 := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.NewTLANumber(serverLoopLabelTag)) - msg0 := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.TLAValue{}) - - for { - if err0 != nil { - if err0 == distsys.CriticalSectionAborted { - ctx.Abort() - err0 = nil - } else { - return err0 - } - } - labelTag0, err0 := ctx.Read(programCounter0, []distsys.TLAValue{}) - if err0 != nil { - return err0 - } - switch labelTag0.AsNumber() { - case serverLoopLabelTag: - if distsys.TLA_TRUE.AsBool() { - err0 = ctx.Write(programCounter0, []distsys.TLAValue{}, distsys.NewTLANumber(rcvReqLabelTag)) - if err0 != nil { - continue - } - err0 = ctx.Commit() - if err0 != nil { - continue - } - } else { - // no statements - } - // no statements - case rcvReqLabelTag: - var exprRead4 distsys.TLAValue - exprRead4, err0 = ctx.Read(mailboxes0, []distsys.TLAValue{self}) - if err0 != nil { - continue - } - err0 = ctx.Write(msg0, []distsys.TLAValue{}, exprRead4) - if err0 != nil { - continue - } - err0 = ctx.Write(programCounter0, []distsys.TLAValue{}, distsys.NewTLANumber(sendPageLabelTag)) - if err0 != nil { - continue - } - err0 = ctx.Commit() - if err0 != nil { - continue - } - case sendPageLabelTag: - var exprRead5 distsys.TLAValue - exprRead5, err0 = ctx.Read(msg0, []distsys.TLAValue{}) - if err0 != nil { - continue - } - var exprRead6 distsys.TLAValue - exprRead6, err0 = ctx.Read(file_system, []distsys.TLAValue{exprRead5.ApplyFunction(distsys.NewTLAString("path"))}) - if err0 != nil { - continue - } - var indexRead0 distsys.TLAValue - indexRead0, err0 = ctx.Read(msg0, []distsys.TLAValue{}) - if err0 != nil { - continue - } - err0 = ctx.Write(mailboxes0, []distsys.TLAValue{indexRead0.ApplyFunction(distsys.NewTLAString("client_id"))}, exprRead6) - if err0 != nil { - continue - } - err0 = ctx.Write(programCounter0, []distsys.TLAValue{}, distsys.NewTLANumber(serverLoopLabelTag)) - if err0 != nil { - continue - } - err0 = ctx.Commit() - if err0 != nil { - continue - } - default: - return fmt.Errorf("invalid program counter %v", labelTag0) - } - } + var err0 error + // label tags + const ( + serverLoopLabelTag = iota + rcvReqLabelTag + sendPageLabelTag + ) + programCounter0 := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.NewTLANumber(serverLoopLabelTag)) + msg0 := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.TLAValue{}) + + for { + if err0 != nil { + if err0 == distsys.CriticalSectionAborted { + ctx.Abort() + err0 = nil + } else { + return err0 + } + } + labelTag0, err0 := ctx.Read(programCounter0, []distsys.TLAValue{}) + if err0 != nil { + return err0 + } + switch labelTag0.AsNumber() { + case serverLoopLabelTag: + if distsys.TLA_TRUE.AsBool() { + err0 = ctx.Write(programCounter0, []distsys.TLAValue{}, distsys.NewTLANumber(rcvReqLabelTag)) + if err0 != nil { + continue + } + err0 = ctx.Commit() + if err0 != nil { + continue + } + } else { + // no statements + } + // no statements + case rcvReqLabelTag: + var exprRead4 distsys.TLAValue + exprRead4, err0 = ctx.Read(mailboxes0, []distsys.TLAValue{self}) + if err0 != nil { + continue + } + err0 = ctx.Write(msg0, []distsys.TLAValue{}, exprRead4) + if err0 != nil { + continue + } + err0 = ctx.Write(programCounter0, []distsys.TLAValue{}, distsys.NewTLANumber(sendPageLabelTag)) + if err0 != nil { + continue + } + err0 = ctx.Commit() + if err0 != nil { + continue + } + case sendPageLabelTag: + var exprRead5 distsys.TLAValue + exprRead5, err0 = ctx.Read(msg0, []distsys.TLAValue{}) + if err0 != nil { + continue + } + var exprRead6 distsys.TLAValue + exprRead6, err0 = ctx.Read(file_system, []distsys.TLAValue{exprRead5.ApplyFunction(distsys.NewTLAString("path"))}) + if err0 != nil { + continue + } + var indexRead0 distsys.TLAValue + indexRead0, err0 = ctx.Read(msg0, []distsys.TLAValue{}) + if err0 != nil { + continue + } + err0 = ctx.Write(mailboxes0, []distsys.TLAValue{indexRead0.ApplyFunction(distsys.NewTLAString("client_id"))}, exprRead6) + if err0 != nil { + continue + } + err0 = ctx.Write(programCounter0, []distsys.TLAValue{}, distsys.NewTLANumber(serverLoopLabelTag)) + if err0 != nil { + continue + } + err0 = ctx.Commit() + if err0 != nil { + continue + } + default: + return fmt.Errorf("invalid program counter %v", labelTag0) + } + } } func AClient(ctx *distsys.MPCalContext, self distsys.TLAValue, constants Constants, mailboxes1 distsys.ArchetypeResourceHandle, instream distsys.ArchetypeResourceHandle, outstream distsys.ArchetypeResourceHandle) error { - var err1 error - // label tags - const ( - clientLoopLabelTag = iota - clientRequestLabelTag - clientReceiveLabelTag - ) - programCounter1 := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.NewTLANumber(clientLoopLabelTag)) - req := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.TLAValue{}) - resp := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.TLAValue{}) - - for { - if err1 != nil { - if err1 == distsys.CriticalSectionAborted { - ctx.Abort() - err1 = nil - } else { - return err1 - } - } - labelTag1, err1 := ctx.Read(programCounter1, []distsys.TLAValue{}) - if err1 != nil { - return err1 - } - switch labelTag1.AsNumber() { - case clientLoopLabelTag: - if distsys.TLA_TRUE.AsBool() { - err1 = ctx.Write(programCounter1, []distsys.TLAValue{}, distsys.NewTLANumber(clientRequestLabelTag)) - if err1 != nil { - continue - } - err1 = ctx.Commit() - if err1 != nil { - continue - } - } else { - // no statements - } - // no statements - case clientRequestLabelTag: - var exprRead7 distsys.TLAValue - exprRead7, err1 = ctx.Read(instream, []distsys.TLAValue{}) - if err1 != nil { - continue - } - err1 = ctx.Write(req, []distsys.TLAValue{}, distsys.NewTLARecord([]distsys.TLARecordField{ - {distsys.NewTLAString("message_type"), constants.GET_PAGE}, - {distsys.NewTLAString("client_id"), self}, - {distsys.NewTLAString("path"), exprRead7}, - })) - if err1 != nil { - continue - } - var exprRead8 distsys.TLAValue - exprRead8, err1 = ctx.Read(req, []distsys.TLAValue{}) - if err1 != nil { - continue - } - err1 = ctx.Write(mailboxes1, []distsys.TLAValue{constants.LoadBalancerId}, exprRead8) - if err1 != nil { - continue - } - err1 = ctx.Write(programCounter1, []distsys.TLAValue{}, distsys.NewTLANumber(clientReceiveLabelTag)) - if err1 != nil { - continue - } - err1 = ctx.Commit() - if err1 != nil { - continue - } - case clientReceiveLabelTag: - var exprRead9 distsys.TLAValue - exprRead9, err1 = ctx.Read(mailboxes1, []distsys.TLAValue{self}) - if err1 != nil { - continue - } - err1 = ctx.Write(resp, []distsys.TLAValue{}, exprRead9) - if err1 != nil { - continue - } - var exprRead10 distsys.TLAValue - exprRead10, err1 = ctx.Read(resp, []distsys.TLAValue{}) - if err1 != nil { - continue - } - err1 = ctx.Write(outstream, []distsys.TLAValue{}, exprRead10) - if err1 != nil { - continue - } - err1 = ctx.Write(programCounter1, []distsys.TLAValue{}, distsys.NewTLANumber(clientLoopLabelTag)) - if err1 != nil { - continue - } - err1 = ctx.Commit() - if err1 != nil { - continue - } - default: - return fmt.Errorf("invalid program counter %v", labelTag1) - } - } -} + var err1 error + // label tags + const ( + clientLoopLabelTag = iota + clientRequestLabelTag + clientReceiveLabelTag + ) + programCounter1 := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.NewTLANumber(clientLoopLabelTag)) + req := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.TLAValue{}) + resp := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.TLAValue{}) + for { + if err1 != nil { + if err1 == distsys.CriticalSectionAborted { + ctx.Abort() + err1 = nil + } else { + return err1 + } + } + labelTag1, err1 := ctx.Read(programCounter1, []distsys.TLAValue{}) + if err1 != nil { + return err1 + } + switch labelTag1.AsNumber() { + case clientLoopLabelTag: + if distsys.TLA_TRUE.AsBool() { + err1 = ctx.Write(programCounter1, []distsys.TLAValue{}, distsys.NewTLANumber(clientRequestLabelTag)) + if err1 != nil { + continue + } + err1 = ctx.Commit() + if err1 != nil { + continue + } + } else { + // no statements + } + // no statements + case clientRequestLabelTag: + var exprRead7 distsys.TLAValue + exprRead7, err1 = ctx.Read(instream, []distsys.TLAValue{}) + if err1 != nil { + continue + } + err1 = ctx.Write(req, []distsys.TLAValue{}, distsys.NewTLARecord([]distsys.TLARecordField{ + {distsys.NewTLAString("message_type"), constants.GET_PAGE}, + {distsys.NewTLAString("client_id"), self}, + {distsys.NewTLAString("path"), exprRead7}, + })) + if err1 != nil { + continue + } + var exprRead8 distsys.TLAValue + exprRead8, err1 = ctx.Read(req, []distsys.TLAValue{}) + if err1 != nil { + continue + } + err1 = ctx.Write(mailboxes1, []distsys.TLAValue{constants.LoadBalancerId}, exprRead8) + if err1 != nil { + continue + } + err1 = ctx.Write(programCounter1, []distsys.TLAValue{}, distsys.NewTLANumber(clientReceiveLabelTag)) + if err1 != nil { + continue + } + err1 = ctx.Commit() + if err1 != nil { + continue + } + case clientReceiveLabelTag: + var exprRead9 distsys.TLAValue + exprRead9, err1 = ctx.Read(mailboxes1, []distsys.TLAValue{self}) + if err1 != nil { + continue + } + err1 = ctx.Write(resp, []distsys.TLAValue{}, exprRead9) + if err1 != nil { + continue + } + var exprRead10 distsys.TLAValue + exprRead10, err1 = ctx.Read(resp, []distsys.TLAValue{}) + if err1 != nil { + continue + } + err1 = ctx.Write(outstream, []distsys.TLAValue{}, exprRead10) + if err1 != nil { + continue + } + err1 = ctx.Write(programCounter1, []distsys.TLAValue{}, distsys.NewTLANumber(clientLoopLabelTag)) + if err1 != nil { + continue + } + err1 = ctx.Commit() + if err1 != nil { + continue + } + default: + return fmt.Errorf("invalid program counter %v", labelTag1) + } + } +} From 1cc0dc97b724c8121aa5307ee9b59d0cc2d90a49 Mon Sep 17 00:00:00 2001 From: fhackett Date: Mon, 5 Jul 2021 14:25:26 -0700 Subject: [PATCH 11/27] WIP: fix bugs in kv_store spec compilation --- src/pgo/trans/MPCalGoCodegenPass.scala | 7 +- src/pgo/trans/MPCalSemanticCheckPass.scala | 72 +++-- src/pgo/util/TLAExprInterpreter.scala | 290 +++++++++++++++++++++ test/files/general/MPCalKindMatching.tla | 2 +- 4 files changed, 327 insertions(+), 44 deletions(-) create mode 100644 src/pgo/util/TLAExprInterpreter.scala diff --git a/src/pgo/trans/MPCalGoCodegenPass.scala b/src/pgo/trans/MPCalGoCodegenPass.scala index 1cad235e4..499c834f6 100644 --- a/src/pgo/trans/MPCalGoCodegenPass.scala +++ b/src/pgo/trans/MPCalGoCodegenPass.scala @@ -95,14 +95,15 @@ object MPCalGoCodegenPass { replacementAST case ident@TLAGeneralIdentifier(_, prefix) => assert(prefix.isEmpty) - ctx.bindings(ident.refersTo) match { - case ResourceBinding(_) => + ctx.bindings.get(ident.refersTo) match { + case Some(ResourceBinding(_)) => val cleanName = ctx.nameCleaner.cleanName(hint) val replacementDefn = PCalVariableDeclarationEmpty(TLAIdentifier(cleanName)) val replacementAST = TLAGeneralIdentifier(TLAIdentifier(cleanName), Nil).setRefersTo(replacementDefn) resourceReads += ((ident.refersTo, replacementDefn, Nil)) replacementAST - case _ => ident + case Some(_) => ident // does not bind a resource; needs no read process + case _ => ident // an expression-local variable, bound by let or some quantifier. also needs no read process } } val exprWithReads = expr.rewrite(Rewritable.TopDownFirstStrategy)(readReplacer) diff --git a/src/pgo/trans/MPCalSemanticCheckPass.scala b/src/pgo/trans/MPCalSemanticCheckPass.scala index f99afaaa1..5f8166896 100644 --- a/src/pgo/trans/MPCalSemanticCheckPass.scala +++ b/src/pgo/trans/MPCalSemanticCheckPass.scala @@ -51,6 +51,7 @@ object MPCalSemanticCheckPass { @throws[PGoError] def apply(tlaModule: TLAModule, mpcalBlock: MPCalBlock): Unit = { val errors = mutable.ListBuffer[SemanticError.Error]() + var block = mpcalBlock // enforce that the first statement / top-level statements in: // - procedures @@ -65,7 +66,7 @@ object MPCalSemanticCheckPass { errors += SemanticError.LabelRequiredError(stmt) } } - mpcalBlock.visit(Visitable.TopDownFirstStrategy) { + block.visit(Visitable.TopDownFirstStrategy) { case MPCalArchetype(_, _, _, _, body) => checkInBody(body) case MPCalProcedure(_, _, _, body) => checkInBody(body) case PCalProcedure(_, _, _, body) => checkInBody(body) @@ -81,7 +82,7 @@ object MPCalSemanticCheckPass { errors += SemanticError.LabelForbiddenError(label) } - mpcalBlock.visit(Visitable.TopDownFirstStrategy) { + block.visit(Visitable.TopDownFirstStrategy) { case m: PCalMacro => requireNoLabels(m) case mm: MPCalMappingMacro => requireNoLabels(mm) case w: PCalWith => requireNoLabels(w) @@ -89,13 +90,13 @@ object MPCalSemanticCheckPass { } // enforce reserved label names - mpcalBlock.visit(Visitable.BottomUpFirstStrategy) { + block.visit(Visitable.BottomUpFirstStrategy) { case PCalLabeledStatements(label, _) if label.name == "Error" || label.name == "Done" => errors += SemanticError.ReservedLabelError(label) } // enforce non-recursive macros - val hasRecursiveMacro: Boolean = locally { + block = locally { var hasRecursiveMacro = false def checkNonRec(visitable: Visitable, macrosBeingExpanded: Map[String,PCalMacroCall]): Unit = visitable.visit(Visitable.TopDownFirstStrategy) { @@ -111,11 +112,18 @@ object MPCalSemanticCheckPass { } } - checkNonRec(mpcalBlock, Map.empty) - hasRecursiveMacro + checkNonRec(block, Map.empty) + + if(!hasRecursiveMacro) { + MPCalPassUtils.rewriteEachBody(block) { (body, lexicalScope) => + MPCalPassUtils.expandMacroCalls(body, lexicalScope) + } + } else { + block + } } - val containsLabels: IdSet[PCalStatement] = MPCalPassUtils.gatherContainsLabels(mpcalBlock) + val containsLabels: IdSet[PCalStatement] = MPCalPassUtils.gatherContainsLabels(block) val tailStatements: IdMap[PCalStatement,Vector[PCalStatement]] = locally { var tailStatements = IdMap.empty[PCalStatement,Vector[PCalStatement]] @@ -130,8 +138,6 @@ object MPCalSemanticCheckPass { no.view.map(gatherTailStatements).lastOption.getOrElse(Vector.empty) case PCalLabeledStatements(_, statements) => statements.view.map(gatherTailStatements).last - case macroCall @PCalMacroCall(_, _) if !hasRecursiveMacro => - macroCall.refersTo.body.view.map(gatherTailStatements).lastOption.getOrElse(Vector.empty) case PCalWhile(_, body) => body.view.map(gatherTailStatements).lastOption.getOrElse(Vector.empty) case PCalWith(_, body) => @@ -142,7 +148,7 @@ object MPCalSemanticCheckPass { result } - mpcalBlock.visit(Visitable.TopDownFirstStrategy) { + block.visit(Visitable.TopDownFirstStrategy) { case stmt: PCalStatement => gatherTailStatements(stmt) } @@ -161,15 +167,7 @@ object MPCalSemanticCheckPass { } // check that all while statements are directly inside labels (accounting for macro expansion, if that's sound) - checkWhileLabelPlacement { - if(!hasRecursiveMacro) { - MPCalPassUtils.rewriteEachBody(mpcalBlock) { (body, lexicalScope) => - MPCalPassUtils.expandMacroCalls(body, lexicalScope) - } - } else { - mpcalBlock - } - } + checkWhileLabelPlacement(block) // check whether statements that must be followed by a label are followed by a label locally { @@ -203,7 +201,7 @@ object MPCalSemanticCheckPass { } // visit all parts of the MPCal block that contain a list of statements - mpcalBlock.visit(Visitable.BottomUpFirstStrategy) { + block.visit(Visitable.BottomUpFirstStrategy) { case MPCalMappingMacro(_, readBody, writeBody, _) => checkInBody(readBody) checkInBody(writeBody) @@ -226,7 +224,7 @@ object MPCalSemanticCheckPass { // enforce multiple assignment rules locally { - def checkInBody(assignedVars: Map[TLAIdentifier,TLAIdentifier], contextualBindings: Map[String,DefinitionOne], body: List[PCalStatement]): Map[TLAIdentifier,TLAIdentifier] = + def checkInBody(assignedVars: Map[TLAIdentifier,TLAIdentifier], body: List[PCalStatement]): Map[TLAIdentifier,TLAIdentifier] = body.view.scanLeft(assignedVars) { (assignedVars, stmt) => stmt match { case PCalAssignment(pairs) => @@ -249,28 +247,20 @@ object MPCalSemanticCheckPass { assignedVars.updated(lhsId, lhsId) }.last case PCalEither(cases) => - cases.map(checkInBody(assignedVars, contextualBindings, _)).reduce(_ ++ _) + cases.map(checkInBody(assignedVars, _)).reduce(_ ++ _) case PCalIf(_, yes, no) => - checkInBody(assignedVars, contextualBindings, yes) ++ checkInBody(assignedVars, contextualBindings, no) + checkInBody(assignedVars, yes) ++ checkInBody(assignedVars, no) case PCalLabeledStatements(_, statements) => - checkInBody(Map.empty, contextualBindings, statements) + checkInBody(Map.empty, statements) Map.empty - case macroCall: PCalMacroCall if !hasRecursiveMacro => - checkInBody( - assignedVars, - contextualBindings, - MPCalPassUtils.expandMacroCalls(List(macroCall), contextualBindings)) - case PCalWhile(_, body) => checkInBody(assignedVars, contextualBindings, body) + case PCalWhile(_, body) => checkInBody(assignedVars, body) case PCalWith(bindings, body) => - checkInBody( - assignedVars, - bindings.foldLeft(contextualBindings)((contextualBindings, b) => contextualBindings.updated(b.name.id, b)), - body) + checkInBody(assignedVars, body) case _ => assignedVars } }.last - MPCalPassUtils.forEachBody(mpcalBlock)((body, contextualBindings) => checkInBody(Map.empty, contextualBindings, body)) + MPCalPassUtils.forEachBody(block)((body, _) => checkInBody(Map.empty, body)) } // for each PCal "body", every goto must refer to a defined label @@ -286,12 +276,12 @@ object MPCalSemanticCheckPass { }) } - MPCalPassUtils.forEachBody(mpcalBlock)((body, _) => checkInBody(body)) + MPCalPassUtils.forEachBody(block)((body, _) => checkInBody(body)) } // for each PCal procedure call, the argument count must match parameter count at the definition locally { - mpcalBlock.visit(Visitable.TopDownFirstStrategy) { + block.visit(Visitable.TopDownFirstStrategy) { case call@PCalCall(_, arguments) => if(call.refersTo.params.size != arguments.size) { errors += SemanticError.PClArityMismatch(usage = call, defn = call.refersTo) @@ -369,7 +359,7 @@ object MPCalSemanticCheckPass { } } - mpcalBlock.visit(Visitable.TopDownFirstStrategy) { + block.visit(Visitable.TopDownFirstStrategy) { case MPCalArchetype(_, _, params, _, body) => checkMPCalParamRefs(body, params) case MPCalProcedure(_, params, _, body) => @@ -388,7 +378,8 @@ object MPCalSemanticCheckPass { } (archetype.params.view zip arguments.view).foreach { case (MPCalRefParam(_, mappingCountP), Left(MPCalRefExpr(_, mappingCount))) if mappingCount == mappingCountP => // ok - case (MPCalRefParam(_, 0), Right(_)) => // ok, we'll add an underlying variable if we have to + case (MPCalRefParam(_, _), Right(_)) => // ok, we'll add an underlying variable if we have to + case (MPCalValParam(_), Right(_)) => // ok, pass by value case (param, Left(arg)) => errors += SemanticError.MPCalKindMismatchError(usage = arg, defn = param) case (param, Right(arg)) => @@ -400,6 +391,7 @@ object MPCalSemanticCheckPass { (arguments.view zip params.view).foreach { case (Left(MPCalRefExpr(_, mappingCount)), MPCalRefParam(_, mappingCountP)) if mappingCount == mappingCountP => // ok case (Right(_: TLAExpression), MPCalValParam(_)) => // ok + case (Right(_: TLAExpression), MPCalRefParam(_, _)) => // special case: we should generate a synthetic local case (eitherArg, param) => val arg: SourceLocatable = eitherArg match { case Left(value) => value @@ -408,7 +400,7 @@ object MPCalSemanticCheckPass { errors += SemanticError.MPCalKindMismatchError(usage = arg, defn = param) } - mpcalBlock.visit(Visitable.TopDownFirstStrategy) { + block.visit(Visitable.TopDownFirstStrategy) { case instance@MPCalInstance(_, _, _, arguments, _) => if(instance.refersTo.params.size != arguments.size) { errors += SemanticError.PClArityMismatch(usage = instance, defn = instance.refersTo) diff --git a/src/pgo/util/TLAExprInterpreter.scala b/src/pgo/util/TLAExprInterpreter.scala new file mode 100644 index 000000000..77a430bd9 --- /dev/null +++ b/src/pgo/util/TLAExprInterpreter.scala @@ -0,0 +1,290 @@ +package pgo.util + +import pgo.model.Definition +import pgo.model.tla.BuiltinModules.TLABuiltinOperator +import pgo.model.tla._ + +import scala.annotation.tailrec + +object TLAExprInterpreter { + sealed abstract class TLAValue + final case class TLAValueBool(value: Boolean) extends TLAValue + final case class TLAValueNumber(value: Int) extends TLAValue + final case class TLAValueString(value: String) extends TLAValue + final case class TLAValueSet(value: Set[TLAValue]) extends TLAValue + final case class TLAValueTuple(value: List[TLAValue]) extends TLAValue + final case class TLAValueFunction(value: Map[TLAValue,TLAValue]) extends TLAValue + + lazy val builtinOperators: IdMap[TLABuiltinOperator,List[TLAValue]=>TLAValue] = IdMap.empty + + def interpret(expr: TLAExpression)(implicit env: Map[String,TLAValue]): TLAValue = + expr match { + case TLAString(value) => TLAValueString(value) + case TLANumber(value, _) => + value match { + case TLANumber.IntValue(value) => TLAValueNumber(value.intValue) + } + case TLAGeneralIdentifier(name, prefix) => + assert(prefix.isEmpty) + env(name.id) + case TLADot(lhs, identifier) => + interpret(lhs) match { + case TLAValueFunction(value) => value(identifier.id) + } + case opcall@TLAOperatorCall(_, _, arguments) => + opcall.refersTo match { + case builtin: BuiltinModules.TLABuiltinOperator => + builtinOperators(builtin)(arguments.map(interpret)) + case TLAOperatorDefinition(_, args, body, _) => + assert(args.size == arguments.size) + assert(args.forall(_.variant.isInstanceOf[TLAOpDecl.NamedVariant])) + val argNames = args.view.map(_.variant.asInstanceOf[TLAOpDecl.NamedVariant].ident.id) + val argValues = arguments.map(interpret) + interpret(body)(env = env ++ (argNames zip argValues)) + } + case TLAIf(cond, tval, fval) => + interpret(cond) match { + case TLAValueBool(value) => + if(value) interpret(tval) else interpret(fval) + } + case TLALet(defs, body) => + @tailrec + def impl(defs: List[TLAUnit])(implicit env: Map[String,TLAValue]): TLAValue = + defs match { + case Nil => interpret(body) + case unit :: restUnits => + unit match { + case TLAOperatorDefinition(name, args, body, _) if args.isEmpty => + val strName = name match { + case Definition.ScopeIdentifierName(name) => name.id + case Definition.ScopeIdentifierSymbol(symbol) => symbol.symbol.stringReprDefn + } + impl(restUnits)(env = env.updated(strName, interpret(body))) + case _: TLAOperatorDefinition => + // for definitions with args, they will be called by TLAOperatorCall, and scoping is done already + impl(restUnits) + } + } + + impl(defs) + case TLACase(arms, other) => + @tailrec + def armEval(arms: List[TLACaseArm]): TLAValue = + arms match { + case Nil => other match { + case Some(value) => interpret(value) + } + case TLACaseArm(cond, result) :: otherArms => + interpret(cond) match { + case TLAValueBool(value) => + if(value) { + interpret(result) + } else { + armEval(otherArms) + } + } + } + + armEval(arms) + case TLAFunction(args, body) => + def impl(args: List[TLAQuantifierBound], acc: List[TLAValue])(implicit env: Map[String,TLAValue]): Iterator[(TLAValue,TLAValue)] = + args match { + case Nil => Iterator.single(TLAValueTuple(acc) -> interpret(body)) + case TLAQuantifierBound(tpe, ids, set) :: restArgs => + interpret(set) match { + case TLAValueSet(setValue) => + tpe match { + case TLAQuantifierBound.IdsType => + val List(id) = ids + setValue.iterator.flatMap { v => + impl(restArgs, acc :+ v)(env = env.updated(id.id.id, v)) + } + case TLAQuantifierBound.TupleType => + setValue.iterator.flatMap { + case v@TLAValueTuple(elems) => + assert(elems.size == ids.size) + impl(restArgs, acc :+ v)(env = env ++ (ids.view.map(_.id.id) zip elems)) + } + } + } + } + + TLAValueFunction(impl(args, Nil).toMap) + case TLAFunctionCall(function, params) => + val paramValue = params match { + case List(singleParam) => interpret(singleParam) + case params => TLAValueTuple(params.map(interpret)) + } + interpret(function) match { + case TLAValueTuple(value) => + paramValue match { + case TLAValueNumber(idx) => value(idx) + } + case TLAValueFunction(value) => value(paramValue) + } + case TLAFunctionSet(from, to) => + (interpret(from), interpret(to)) match { + case (TLAValueSet(fromSet), TLAValueSet(toSet)) => + TLAValueSet { + val keyList = fromSet.toList + val valueList = toSet.toList + val valueSets = keyList.iterator.foldLeft(Iterator.single(Nil: List[TLAValue])) { (acc, _) => + acc.flatMap(lst => valueList.iterator.map(v => v :: lst)) + } + valueSets.map(valueSet => TLAValueFunction((keyList zip valueSet).toMap)).toSet + } + } + case TLAFunctionSubstitution(source, substitutions) => + substitutions.foldLeft(interpret(source)) { (fnValue, sub) => + val TLAFunctionSubstitutionPair(_, keys, value) = sub + def subKeys(keys: List[TLAFunctionSubstitutionKey], origValue: TLAValue): TLAValue = + keys match { + case Nil => interpret(value)(env = env.updated("@", origValue)) + case TLAFunctionSubstitutionKey(indices) :: restKeys => + val indexValue = indices match { + case List(index) => interpret(index) + case indices => TLAValueTuple(indices.map(interpret)) + } + origValue match { + case TLAValueFunction(origFn) => + TLAValueFunction(origFn.updated(indexValue, subKeys(restKeys, origFn(indexValue)))) + } + } + + subKeys(keys, fnValue) + } + case TLAFunctionSubstitutionAt() => env("@") + case TLAQuantifiedExistential(bounds, body) => + def impl(bounds: List[TLAQuantifierBound])(implicit env: Map[String,TLAValue]): TLAValue = + bounds match { + case Nil => interpret(body) + case TLAQuantifierBound(tpe, ids, set) :: restBounds => + val setValue = interpret(set) + tpe match { + case TLAQuantifierBound.IdsType => + val List(id) = ids + setValue match { + case TLAValueSet(setValue) => + TLAValueBool(setValue.exists { v => + impl(restBounds)(env = env.updated(id.id.id, v)) match { + case TLAValueBool(value) => value + } + }) + } + case TLAQuantifierBound.TupleType => + setValue match { + case TLAValueSet(setValue) => + TLAValueBool(setValue.exists { + case TLAValueTuple(elems) => + assert(elems.size == ids.size) + impl(restBounds)(env = env ++ (ids.view.map(_.id.id) zip elems)) match { + case TLAValueBool(value) => value + } + }) + } + } + } + + impl(bounds) + case TLAQuantifiedUniversal(bounds, body) => + def impl(bounds: List[TLAQuantifierBound])(implicit env: Map[String,TLAValue]): TLAValue = + bounds match { + case Nil => interpret(body) + case TLAQuantifierBound(tpe, ids, set) :: restBounds => + val setValue = interpret(set) + tpe match { + case TLAQuantifierBound.IdsType => + val List(id) = ids + setValue match { + case TLAValueSet(setValue) => + TLAValueBool(setValue.forall { v => + impl(restBounds)(env = env.updated(id.id.id, v)) match { + case TLAValueBool(value) => value + } + }) + } + case TLAQuantifierBound.TupleType => + setValue match { + case TLAValueSet(setValue) => + TLAValueBool(setValue.forall { + case TLAValueTuple(elems) => + assert(elems.size == ids.size) + impl(restBounds)(env = env ++ (ids.view.map(_.id.id) zip elems)) match { + case TLAValueBool(value) => value + } + }) + } + } + } + + impl(bounds) + case TLASetConstructor(contents) => + TLAValueSet(contents.view.map(interpret).toSet) + case TLASetRefinement(TLAQuantifierBound(tpe, ids, set), when) => + interpret(set) match { + case TLAValueSet(setValue) => + tpe match { + case TLAQuantifierBound.IdsType => + val List(id) = ids + TLAValueSet(setValue.filter { v => + interpret(when)(env = env.updated(id.id.id, v)) match { + case TLAValueBool(value) => value + } + }) + case TLAQuantifierBound.TupleType => + TLAValueSet(setValue.filter { + case TLAValueTuple(elems) => + assert(elems.size == ids.size) + interpret(when)(env = env ++ (ids.view.map(_.id.id) zip elems)) match { + case TLAValueBool(value) => value + } + }) + } + } + case TLASetComprehension(body, bounds) => + def impl(bounds: List[TLAQuantifierBound])(implicit env: Map[String,TLAValue]): Iterator[TLAValue] = + bounds match { + case Nil => Iterator.single(interpret(body)) + case TLAQuantifierBound(tpe, ids, set) :: restBounds => + interpret(set) match { + case TLAValueSet(setValue) => + tpe match { + case TLAQuantifierBound.IdsType => + val List(id) = ids + setValue.iterator.flatMap { v => + impl(restBounds)(env = env.updated(id.id.id, v)) + } + case TLAQuantifierBound.TupleType => + setValue.iterator.flatMap { + case TLAValueTuple(elems) => + assert(ids.size == elems.size) + impl(restBounds)(env = env ++ (ids.view.map(_.id.id) zip elems)) + } + } + } + } + + TLAValueSet(impl(bounds).toSet) + case TLATuple(elements) => + TLAValueTuple(elements.map(interpret)) + case TLARecordConstructor(fields) => + TLAValueFunction(fields.view.map { + case TLARecordConstructorField(name, value) => + TLAValueString(name.id) -> interpret(value) + }.toMap) + case TLARecordSet(fields) => + def impl(fields: List[TLARecordSetField], acc: Map[TLAValue,TLAValue]): Iterator[TLAValue] = + fields match { + case Nil => Iterator.single(TLAValueFunction(acc)) + case TLARecordSetField(name, set) :: restFields => + interpret(set) match { + case TLAValueSet(setValue) => + setValue.iterator.flatMap { v => + impl(restFields, acc.updated(name.id, v)) + } + } + } + + TLAValueSet(impl(fields, Map.empty).toSet) + } +} diff --git a/test/files/general/MPCalKindMatching.tla b/test/files/general/MPCalKindMatching.tla index 4edb44142..ca85ffc1a 100644 --- a/test/files/general/MPCalKindMatching.tla +++ b/test/files/general/MPCalKindMatching.tla @@ -33,7 +33,7 @@ EXTENDS Sequences, FiniteSets, Integers process (B = 43) == instance Arch((*:: expectedError: MPCalKindMismatchError *) ref myVar); - process (C = 44) == instance Arch((*:: expectedError: MPCalKindMismatchError *) myVar); + process (C = 44) == instance Arch(myVar); \* will generate a synthetic local var process (D = 45) == instance Arch((*:: expectedError: MPCalKindMismatchError *) ref myVar[_][_]); } From a76041df6c0422279c3696ca290479299c274289 Mon Sep 17 00:00:00 2001 From: fhackett Date: Thu, 8 Jul 2021 15:25:16 -0700 Subject: [PATCH 12/27] WIP: initial fuzz testing; implement Go operators; some resulting fixes --- build.sbt | 3 +- distsys/go.sum | 12 +- distsys/tlaplus.go | 294 +++++++- src/pgo/model/tla/AST.scala | 8 +- src/pgo/parser/PCalParser.scala | 11 +- src/pgo/parser/TLAParser.scala | 3 +- src/pgo/trans/MPCalGoCodegenPass.scala | 13 +- src/pgo/trans/MPCalNormalizePass.scala | 3 +- src/pgo/trans/PCalRenderPass.scala | 32 +- src/pgo/util/TLAExprInterpreter.scala | 710 ++++++++++++------ test/files/general/dqueue.tla.expectpcal | 4 + .../general/dqueue.tla.gotests/dqueue.go | 24 +- .../general/load_balancer.tla.expectpcal | 6 + .../load_balancer.go | 36 +- .../general/replicated_kv.tla.expectpcal | 190 +++-- test/pgo/TLAExpressionFuzzTests.scala | 224 ++++++ 16 files changed, 1190 insertions(+), 383 deletions(-) create mode 100644 test/pgo/TLAExpressionFuzzTests.scala diff --git a/build.sbt b/build.sbt index d476391ea..3fc22ee44 100644 --- a/build.sbt +++ b/build.sbt @@ -15,5 +15,6 @@ libraryDependencies += "io.spray" %% "spray-json" % "1.3.6" libraryDependencies += "org.scala-lang.modules" %% "scala-parser-combinators" % "1.2.0-M1" libraryDependencies += "com.lihaoyi" %% "os-lib" % "0.7.3" -libraryDependencies += "org.scalatest" %% "scalatest" % "3.2.2" % Test +libraryDependencies += "org.scalatest" %% "scalatest" % "3.2.9" % Test +libraryDependencies += "org.scalatestplus" %% "scalacheck-1-15" % "3.2.9.0" % Test libraryDependencies += "io.github.java-diff-utils" % "java-diff-utils" % "4.9" % Test \ No newline at end of file diff --git a/distsys/go.sum b/distsys/go.sum index 7a8f97d25..b1c34bccb 100644 --- a/distsys/go.sum +++ b/distsys/go.sum @@ -2,6 +2,8 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/benbjohnson/immutable v0.3.0 h1:TVRhuZx2wG9SZ0LRdqlbs9S5BZ6Y24hJEHTCgWHZEIw= +github.com/benbjohnson/immutable v0.3.0/go.mod h1:uc6OHo6PN2++n98KHLxW8ef4W42ylHiQSENghE1ezxI= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= @@ -10,6 +12,7 @@ github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmf github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd/v22 v22.3.1/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -36,12 +39,14 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -70,17 +75,17 @@ github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1y github.com/onsi/gomega v1.12.0 h1:p4oGGk2M2UJc0wWN4lHFvIB71lxsh0T/UiKCCgFADY8= github.com/onsi/gomega v1.12.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.etcd.io/etcd v0.5.0-alpha.5 h1:VOolFSo3XgsmnYDLozjvZ6JL6AAwIDu1Yx1y+4EYLDo= -go.etcd.io/etcd v3.3.25+incompatible h1:V1RzkZJj9LqsJRy+TUBgpWSbZXITLB819lstuTFoZOY= go.etcd.io/etcd/api/v3 v3.5.0-beta.3 h1:FdNjTxZpH98oWWTtOjhz0EU7sILw9giVIW+M3dzZFOg= go.etcd.io/etcd/api/v3 v3.5.0-beta.3/go.mod h1:yF0YUmBghT48aC0/eTFrhULo+uKQAr5spQQ6sRhPauE= go.etcd.io/etcd/client/pkg/v3 v3.5.0-beta.3 h1:fh2cSzLD4OeGVy164WtilS9hAQYmQ2BC6Fh/akRR1b0= @@ -152,6 +157,7 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -175,7 +181,9 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= diff --git a/distsys/tlaplus.go b/distsys/tlaplus.go index c2383b345..e1d238403 100644 --- a/distsys/tlaplus.go +++ b/distsys/tlaplus.go @@ -9,6 +9,7 @@ import ( "github.com/benbjohnson/immutable" "hash/fnv" "io" + "math" "strconv" "strings" ) @@ -68,6 +69,12 @@ func (v *TLAValue) GobEncode() ([]byte, error) { return buf.Bytes(), err } +func require(req bool, msg string) { + if !req { + panic(fmt.Errorf("%w: %s", TLATypeError, msg)) + } +} + func (v TLAValue) AsBool() bool { switch data := v.data.(type) { case tlaValueBool: @@ -148,12 +155,16 @@ func (v TLAValue) ApplyFunction(argument TLAValue) TLAValue { } } +func (v TLAValue) PCalPrint() { + fmt.Println(v) +} + func TLA_EqualsSymbol(lhs, rhs TLAValue) TLAValue { - if lhs.Equal(rhs) { - return TLA_TRUE - } else { - return TLA_FALSE - } + return NewTLABool(lhs.Equal(rhs)) +} + +func TLA_NotEqualsSymbol(lhs, rhs TLAValue) TLAValue { + return NewTLABool(!lhs.Equal(rhs)) } type TLAValueHasher struct{} @@ -180,6 +191,15 @@ var _ tlaValueImpl = tlaValueBool(false) var TLA_TRUE = TLAValue{tlaValueBool(true)} var TLA_FALSE = TLAValue{tlaValueBool(false)} +var TLA_BOOLEAN = NewTLASet(TLA_TRUE, TLA_FALSE) + +func NewTLABool(v bool) TLAValue { + if v { + return TLA_TRUE + } else { + return TLA_FALSE + } +} func (v tlaValueBool) Hash() uint32 { h := fnv.New32() @@ -202,6 +222,26 @@ func (v tlaValueBool) String() string { } } +func TLA_LogicalAndSymbol(lhs, rhs TLAValue) TLAValue { + return NewTLABool(lhs.AsBool() && rhs.AsBool()) +} + +func TLA_LogicalOrSymbol(lhs, rhs TLAValue) TLAValue { + return NewTLABool(lhs.AsBool() || rhs.AsBool()) +} + +func TLA_LogicalNotSymbol(v TLAValue) TLAValue { + return NewTLABool(!v.AsBool()) +} + +func TLA_ImpliesSymbol(lhs, rhs TLAValue) TLAValue { + return NewTLABool(!lhs.AsBool() || rhs.AsBool()) +} + +func TLA_EquivSymbol(lhs, rhs TLAValue) TLAValue { + return NewTLABool(lhs.AsBool() == rhs.AsBool()) +} + type tlaValueNumber int32 var _ tlaValueImpl = tlaValueNumber(0) @@ -210,6 +250,10 @@ func NewTLANumber(num int32) TLAValue { return TLAValue{tlaValueNumber(num)} } +// FIXME: better error handling +var TLA_Nat = TLAValue{} +var TLA_Int = TLAValue{} + func (v tlaValueNumber) Hash() uint32 { h := fnv.New32() err := binary.Write(h, binary.LittleEndian, int32(v)) @@ -231,8 +275,57 @@ func TLA_PlusSymbol(lhs, rhs TLAValue) TLAValue { return NewTLANumber(lhs.AsNumber() + rhs.AsNumber()) } +func TLA_MinusSymbol(lhs, rhs TLAValue) TLAValue { + return NewTLANumber(lhs.AsNumber() - rhs.AsNumber()) +} + +func TLA_AsteriskSymbol(lhs, rhs TLAValue) TLAValue { + return NewTLANumber(lhs.AsNumber() * rhs.AsNumber()) +} + +func TLA_SuperscriptSymbol(lhs, rhs TLAValue) TLAValue { + return NewTLANumber(int32(math.Pow(float64(lhs.AsNumber()), float64(rhs.AsNumber())))) +} + +func TLA_LessThanOrEqualSymbol(lhs, rhs TLAValue) TLAValue { + return NewTLABool(lhs.AsNumber() <= rhs.AsNumber()) +} + +func TLA_GreaterThanOrEqualSymbol(lhs, rhs TLAValue) TLAValue { + return NewTLABool(lhs.AsNumber() >= rhs.AsNumber()) +} + +func TLA_LessThanSymbol(lhs, rhs TLAValue) TLAValue { + return NewTLABool(lhs.AsNumber() < rhs.AsNumber()) +} + +func TLA_GreaterThanSymbol(lhs, rhs TLAValue) TLAValue { + return NewTLABool(lhs.AsNumber() > rhs.AsNumber()) +} + +func TLA_DotDotSymbol(lhs, rhs TLAValue) TLAValue { + from, to := lhs.AsNumber(), rhs.AsNumber() + builder := immutable.NewListBuilder() + for i := from; i <= to; i++ { + builder.Append(i) + } + return TLAValue{&tlaValueTuple{builder.List()}} +} + +func TLA_DivSymbol(lhs, rhs TLAValue) TLAValue { + rhsNum := rhs.AsNumber() + require(rhsNum != 0, "divisor must not be 0") + return NewTLANumber(lhs.AsNumber() / rhsNum) +} + func TLA_PercentSymbol(lhs, rhs TLAValue) TLAValue { - return NewTLANumber(lhs.AsNumber() % rhs.AsNumber()) + rhsNum := rhs.AsNumber() + require(rhsNum != 0, "divisor must not be 0") + return NewTLANumber(lhs.AsNumber() % rhsNum) +} + +func TLA_NegationSymbol(v TLAValue) TLAValue { + return NewTLANumber(-v.AsNumber()) } type tlaValueString string @@ -368,6 +461,112 @@ func (v *tlaValueSet) GobDecode(input []byte) error { } } +func TLA_InSymbol(lhs, rhs TLAValue) TLAValue { + set := rhs.AsSet() + _, ok := set.Get(lhs) + return NewTLABool(ok) +} + +func TLA_NotInSymbol(lhs, rhs TLAValue) TLAValue { + set := rhs.AsSet() + _, ok := set.Get(lhs) + return NewTLABool(!ok) +} + +func TLA_IntersectSymbol(lhs, rhs TLAValue) TLAValue { + lhsSet, rhsSet := lhs.AsSet(), rhs.AsSet() + builder := immutable.NewMapBuilder(TLAValueHasher{}) + it := lhsSet.Iterator() + for !it.Done() { + elem, _ := it.Next() + if _, ok := rhsSet.Get(elem); ok { + builder.Set(elem, true) + } + } + return TLAValue{&tlaValueSet{builder.Map()}} +} + +func TLA_UnionSymbol(lhs, rhs TLAValue) TLAValue { + lhsSet, rhsSet := lhs.AsSet(), rhs.AsSet() + builder := immutable.NewMapBuilder(TLAValueHasher{}) + it := lhsSet.Iterator() + for !it.Done() { + v, _ := it.Next() + builder.Set(v, true) + } + it = rhsSet.Iterator() + for !it.Done() { + v, _ := it.Next() + builder.Set(v, true) + } + return TLAValue{&tlaValueSet{builder.Map()}} +} + +func TLA_SubsetOrEqualSymbol(lhs, rhs TLAValue) TLAValue { + lhsSet, rhsSet := lhs.AsSet(), rhs.AsSet() + it := lhsSet.Iterator() + for !it.Done() { + elem, _ := it.Next() + _, ok := rhsSet.Get(elem) + if !ok { + return TLA_FALSE + } + } + return TLA_TRUE +} + +func TLA_BackslashSymbol(lhs, rhs TLAValue) TLAValue { + lhsSet, rhsSet := lhs.AsSet(), rhs.AsSet() + builder := immutable.NewMapBuilder(TLAValueHasher{}) + it := lhsSet.Iterator() + for !it.Done() { + elem, _ := it.Next() + if _, ok := rhsSet.Get(elem); !ok { + builder.Set(elem, true) + } + } + return TLAValue{&tlaValueSet{builder.Map()}} +} + +func TLA_PrefixSubsetSymbol(v TLAValue) TLAValue { + set := v.AsSet() + builder := immutable.NewMapBuilder(TLAValueHasher{}) + shrinkingSet := set + it := set.Iterator() + for !it.Done() { + elem, _ := it.Next() + builder.Set(shrinkingSet, true) + shrinkingSet = shrinkingSet.Delete(elem) + } + builder.Set(shrinkingSet, true) // add the empty set + return TLAValue{&tlaValueSet{builder.Map()}} +} + +func TLA_PrefixUnionSymbol(v TLAValue) TLAValue { + setOfSets := v.AsSet() + builder := immutable.NewMapBuilder(TLAValueHasher{}) + it := setOfSets.Iterator() + for !it.Done() { + elem, _ := it.Next() + set := elem.(TLAValue).AsSet() + innerIt := set.Iterator() + for !innerIt.Done() { + elem, _ := it.Next() + builder.Set(elem, true) + } + } + return TLAValue{&tlaValueSet{builder.Map()}} +} + +func TLA_IsFiniteSet(v TLAValue) TLAValue { + _ = v.AsSet() // it should at least _be_ a set, even if we're sure it's finite + return TLA_TRUE +} + +func TLA_Cardinality(v TLAValue) TLAValue { + return NewTLANumber(int32(v.AsSet().Len())) +} + type tlaValueTuple struct { *immutable.List } @@ -463,9 +662,54 @@ func (v *tlaValueTuple) GobDecode(input []byte) error { } } +func TLA_Seq(v TLAValue) TLAValue { + panic("implement me") +} + +func TLA_Len(v TLAValue) TLAValue { + return NewTLANumber(int32(v.AsTuple().Len())) +} + +func TLA_OSymbol(lhs, rhs TLAValue) TLAValue { + lhsTuple, rhsTuple := lhs.AsTuple(), rhs.AsTuple() + it := rhsTuple.Iterator() + for !it.Done() { + _, elem := it.Next() + lhsTuple = lhsTuple.Append(elem) + } + return TLAValue{&tlaValueTuple{lhsTuple}} +} + +func TLA_Append(lhs, rhs TLAValue) TLAValue { + return TLAValue{&tlaValueTuple{lhs.AsTuple().Append(rhs)}} +} + +func TLA_Head(v TLAValue) TLAValue { + tuple := v.AsTuple() + require(tuple.Len() > 0, "to call Head, tuple must not be empty") + return tuple.Get(0).(TLAValue) +} + +func TLA_Tail(v TLAValue) TLAValue { + tuple := v.AsTuple() + require(tuple.Len() > 0, "to call Tail, tuple must not be empty") + return TLAValue{&tlaValueTuple{tuple.Slice(1, tuple.Len())}} +} + +func TLA_SubSeq(v, m, n TLAValue) TLAValue { + tuple := v.AsTuple() + from, to := int(m.AsNumber()), int(n.AsNumber()) + require(from <= to && from >= 0 && to <= tuple.Len(), "to call SubSeq, from and to indices must be in-bounds") + return TLAValue{&tlaValueTuple{tuple.Slice(from-1, to)}} +} + +// TODO: TLA_SelectSeq, uses predicate +func TLA_SelectSeq(a, b TLAValue) TLAValue { + panic("implement me") +} + type tlaValueFunction struct { *immutable.Map - domain, rng *TLAValue } type TLARecordField struct { @@ -492,7 +736,30 @@ func NewTLARecord(pairs []TLARecordField) TLAValue { for _, pair := range pairs { builder.Set(pair.Key, pair.Value) } - return TLAValue{&tlaValueFunction{Map: builder.Map()}} + return TLAValue{&tlaValueFunction{builder.Map()}} +} + +func NewTLARecordSet(pairs []TLARecordField) TLAValue { + recordSet := immutable.NewMap(TLAValueHasher{}) + // start with a set of one empty map + recordSet = recordSet.Set(TLAValue{&tlaValueFunction{immutable.NewMap(TLAValueHasher{})}}, true) + for _, pair := range pairs { + fieldValueSet := pair.Value.AsSet() + builder := immutable.NewMapBuilder(TLAValueHasher{}) + // iterate over accumulated set of records, and add every possible value for this field, from fieldValueSet + it := recordSet.Iterator() + for !it.Done() { + acc, _ := it.Next() + accFn := acc.(TLAValue).AsFunction() + valIt := fieldValueSet.Iterator() + for !valIt.Done() { + val, _ := valIt.Next() + builder.Set(TLAValue{&tlaValueFunction{accFn.Set(pair.Key, val)}}, true) + } + } + recordSet = builder.Map() + } + return TLAValue{&tlaValueSet{recordSet}} } func (v *tlaValueFunction) Hash() uint32 { @@ -581,3 +848,14 @@ func (v *tlaValueFunction) GobDecode(input []byte) error { builder.Set(field.Key, field.Value) } } + +func TLA_DomainSymbol(v TLAValue) TLAValue { + fn := v.AsFunction() + builder := immutable.NewMapBuilder(TLAValueHasher{}) + it := fn.Iterator() + for !it.Done() { + domainElem, _ := it.Next() + builder.Set(domainElem, true) + } + return TLAValue{&tlaValueSet{builder.Map()}} +} diff --git a/src/pgo/model/tla/AST.scala b/src/pgo/model/tla/AST.scala index 472bcd7fb..e0a7c32c9 100644 --- a/src/pgo/model/tla/AST.scala +++ b/src/pgo/model/tla/AST.scala @@ -418,10 +418,14 @@ final case class TLASetComprehension(body: TLAExpression, bounds: List[TLAQuanti final case class TLATuple(elements: List[TLAExpression]) extends TLAExpression -final case class TLARecordConstructor(fields: List[TLARecordConstructorField]) extends TLAExpression +final case class TLARecordConstructor(fields: List[TLARecordConstructorField]) extends TLAExpression { + require(fields.nonEmpty) +} final case class TLARecordConstructorField(name: TLAIdentifier, value: TLAExpression) extends TLANode -final case class TLARecordSet(fields: List[TLARecordSetField]) extends TLAExpression +final case class TLARecordSet(fields: List[TLARecordSetField]) extends TLAExpression { + require(fields.nonEmpty) +} final case class TLARecordSetField(name: TLAIdentifier, set: TLAExpression) extends TLANode diff --git a/src/pgo/parser/PCalParser.scala b/src/pgo/parser/PCalParser.scala index 1e141f26e..65e6223f1 100644 --- a/src/pgo/parser/PCalParser.scala +++ b/src/pgo/parser/PCalParser.scala @@ -60,9 +60,13 @@ trait PCalParser extends TLAParser { rec | success(Nil) } - def pcalLhsId(implicit ctx: PCalParserContext): Parser[PCalAssignmentLhs] = + def pcalLhsId(implicit ctx: PCalParserContext): Parser[PCalAssignmentLhs] = { + val lhsPart: Parser[Any] = + ("." ~> ws ~> tlaIdentifier) | + ("[" ~> ws ~> rep1sep(tlaExpression, ws ~> "," ~> ws) <~ ws <~ "]") + withSourceLocation { - tlaIdentifierExpr <~ guard(ws ~> (":=" | "[" | ".")) ^^ { id => // avoid accidentally matching labels + tlaIdentifierExpr <~ guard(ws ~> repsep(lhsPart, ws) ~> ws ~> ":=") ^^ { id => // avoid accidentally matching non-assignments ctx.ctx.lookupDefinition(List(Definition.ScopeIdentifierName(id))) match { case Some(defn) => val result = PCalAssignmentLhsIdentifier(id) @@ -78,8 +82,9 @@ trait PCalParser extends TLAParser { } } } + } - def pcalLhs(implicit ctx: PCalParserContext): Parser[PCalAssignmentLhs] = { + def pcalLhs(implicit ctx: PCalParserContext): Parser[PCalAssignmentLhs] = { def rec(lhs: PCalAssignmentLhs): Parser[PCalAssignmentLhs] = opt(ws ~> withSourceLocation { "." ~> ws ~> tlaIdentifierExpr ^^ (id => PCalAssignmentLhsProjection(lhs, List(TLAString(id.id).setSourceLocation(id.sourceLocation)))) | diff --git a/src/pgo/parser/TLAParser.scala b/src/pgo/parser/TLAParser.scala index a8011dfd2..98021c954 100644 --- a/src/pgo/parser/TLAParser.scala +++ b/src/pgo/parser/TLAParser.scala @@ -824,7 +824,8 @@ trait TLAParser extends RegexParsers { def tlaModuleBeforeTranslation(implicit ctx: TLAParserContext): Parser[TLAModule] = withSourceLocation { - val translationTag = "\\*" <~ rep("*") <~ rep(" ") <~ "BEGIN" <~ rep(" ") <~ "TRANSLATION" + val translationTag = ("\\*" <~ rep("*") <~ rep(" ") <~ "BEGIN" <~ rep(" ") <~ "TRANSLATION") + .withFailureMessage("\\* expected: for scoping reasons, an MPCal-compilable TLA+ module must contain a `\\* BEGIN TRANSLATION` tag") val wsWithoutTranslationTag = rep(regex("""\s+""".r) | tlaMultilineComment | not(translationTag) ~> tlaLineComment) diff --git a/src/pgo/trans/MPCalGoCodegenPass.scala b/src/pgo/trans/MPCalGoCodegenPass.scala index 499c834f6..3a5e77dc4 100644 --- a/src/pgo/trans/MPCalGoCodegenPass.scala +++ b/src/pgo/trans/MPCalGoCodegenPass.scala @@ -65,10 +65,10 @@ object MPCalGoCodegenPass { .map(either => either -> ctx.nameCleaner.cleanName("fairnessCounter")) .to(IdMap) - val labelBinds = body.view.map { + val labelBinds = (body.view.map { case PCalLabeledStatements(label, statements) => label.name -> s"${ctx.nameCleaner.cleanName(label.name)}LabelTag" - }.toMap + } ++ List("Done" -> "DoneLabelTag")).toMap def readExpr(expr: TLAExpression, hint: String = "resourceRead")(fn: Description=>Description)(implicit ctx: GoCodegenContext): Description = { val resourceReads = mutable.ListBuffer[(DefinitionOne,PCalVariableDeclarationEmpty,List[TLAExpression])]() @@ -328,7 +328,8 @@ object MPCalGoCodegenPass { body.view.tail.map { case PCalLabeledStatements(label, _) => d"\n${labelBinds(label.name)}" - }.flattenDescriptions).indented + }.flattenDescriptions + + d"\nDoneLabelTag").indented }\n)" + d"\n$programCounterResourceName := ${ensureLocalResource { val firstLabel = labelBinds(body.head.asInstanceOf[PCalLabeledStatements].label.name) @@ -370,7 +371,9 @@ object MPCalGoCodegenPass { d"\ncase ${labelBinds(label.name)}:${ impl(statements).indented }" - } + }.flattenDescriptions + + d"\ncase DoneLabelTag:" + + d"\nreturn nil".indented }\ndefault:${ d"""\nreturn fmt.Errorf("invalid program counter %v", $labelTag)""".indented }\n}" @@ -447,7 +450,7 @@ object MPCalGoCodegenPass { d"$bind(${ctx.constantsName}, ${arguments.map(translateExpr).separateBy(d", ")})" } case TLAIf(cond, tval, fval) => - d"func() {${ + d"func() $TLAValue {${ (d"\nif ${translateExpr(cond)}.AsBool() {" + d"\nreturn ${translateExpr(tval)}".indented + d"\n} else {" + diff --git a/src/pgo/trans/MPCalNormalizePass.scala b/src/pgo/trans/MPCalNormalizePass.scala index 475406a10..efe2e41ca 100644 --- a/src/pgo/trans/MPCalNormalizePass.scala +++ b/src/pgo/trans/MPCalNormalizePass.scala @@ -136,7 +136,8 @@ object MPCalNormalizePass { body match { case PCalLabeledStatements(_, _) :: _ => assert(body.forall(_.isInstanceOf[PCalLabeledStatements])) - transBlocks(body.asInstanceOf[List[PCalLabeledStatements]], None, Iterator.empty).toList + // add a dummy label "Done", which is valid, in that it jumps to end-of-program, as the "last" critical section should + transBlocks(body.asInstanceOf[List[PCalLabeledStatements]], Some(PCalLabel("Done", PCalLabel.NoModifier)), Iterator.empty).toList case _ => assert(body.forall(!containsLabels(_))) body diff --git a/src/pgo/trans/PCalRenderPass.scala b/src/pgo/trans/PCalRenderPass.scala index 2258976af..d6ff5eda4 100644 --- a/src/pgo/trans/PCalRenderPass.scala +++ b/src/pgo/trans/PCalRenderPass.scala @@ -139,19 +139,27 @@ object PCalRenderPass { case TLATuple(elements) => d"<<${elements.view.map(describeExpr).separateBy(d", ")}>>" case TLARecordConstructor(fields) => - d"[${ - fields.view.map { - case TLARecordConstructorField(name, value) => - d"${name.id} |-> ${describeExpr(value)}" - }.separateBy(d", ") - }]" + if(fields.isEmpty) { + d"[ ]" // or else this empty case will be parsed as the temporal "always" prefix operator + } else { + d"[${ + fields.view.map { + case TLARecordConstructorField(name, value) => + d"${name.id} |-> ${describeExpr(value)}" + }.separateBy(d", ") + }]" + } case TLARecordSet(fields) => - d"[${ - fields.view.map { - case TLARecordSetField(name, set) => - d"${name.id} : ${describeExpr(set)}" - }.separateBy(d", ") - }]" + if(fields.isEmpty) { + d"[ ]" // same as above, avoids confusion with temporal "always" operator [] + } else { + d"[${ + fields.view.map { + case TLARecordSetField(name, set) => + d"${name.id} : ${describeExpr(set)}" + }.separateBy(d", ") + }]" + } } def describeOpDecl(opDecl: TLAOpDecl): Description = diff --git a/src/pgo/util/TLAExprInterpreter.scala b/src/pgo/util/TLAExprInterpreter.scala index 77a430bd9..1ef39a556 100644 --- a/src/pgo/util/TLAExprInterpreter.scala +++ b/src/pgo/util/TLAExprInterpreter.scala @@ -1,290 +1,506 @@ package pgo.util -import pgo.model.Definition -import pgo.model.tla.BuiltinModules.TLABuiltinOperator +import pgo.model.{Definition, DefinitionOne} import pgo.model.tla._ import scala.annotation.tailrec object TLAExprInterpreter { + final case class Unsupported() extends RuntimeException("unsupported") + final case class TypeError() extends RuntimeException("TLA+ type error") + sealed abstract class TLAValue final case class TLAValueBool(value: Boolean) extends TLAValue final case class TLAValueNumber(value: Int) extends TLAValue final case class TLAValueString(value: String) extends TLAValue final case class TLAValueSet(value: Set[TLAValue]) extends TLAValue - final case class TLAValueTuple(value: List[TLAValue]) extends TLAValue + final case class TLAValueTuple(value: Vector[TLAValue]) extends TLAValue final case class TLAValueFunction(value: Map[TLAValue,TLAValue]) extends TLAValue - lazy val builtinOperators: IdMap[TLABuiltinOperator,List[TLAValue]=>TLAValue] = IdMap.empty + lazy val builtinOperators: IdMap[DefinitionOne,List[TLAValue]=>TLAValue] = + IdMap( + BuiltinModules.Intrinsics.memberSym(TLASymbol.LogicalAndSymbol) -> { + case List(TLAValueBool(lhs), TLAValueBool(rhs)) => TLAValueBool(lhs && rhs) + }, + BuiltinModules.Intrinsics.memberSym(TLASymbol.LogicalOrSymbol) -> { + case List(TLAValueBool(lhs), TLAValueBool(rhs)) => TLAValueBool(lhs || rhs) + }, + BuiltinModules.Intrinsics.memberSym(TLASymbol.LogicalNotSymbol) -> { + case List(TLAValueBool(op)) => TLAValueBool(!op) + }, + BuiltinModules.Intrinsics.memberSym(TLASymbol.ImpliesSymbol) -> { + case List(TLAValueBool(lhs), TLAValueBool(rhs)) => TLAValueBool(!lhs || rhs) + }, + BuiltinModules.Intrinsics.memberSym(TLASymbol.EquivSymbol) -> { + case List(TLAValueBool(lhs), TLAValueBool(rhs)) => TLAValueBool(lhs == rhs) + }, + BuiltinModules.Intrinsics.memberAlpha("TRUE") -> { + case Nil => TLAValueBool(true) + }, + BuiltinModules.Intrinsics.memberAlpha("FALSE") -> { + case Nil => TLAValueBool(false) + }, + BuiltinModules.Intrinsics.memberAlpha("BOOLEAN") -> { + case Nil => TLAValueSet(Set(TLAValueBool(true), TLAValueBool(false))) + }, - def interpret(expr: TLAExpression)(implicit env: Map[String,TLAValue]): TLAValue = - expr match { - case TLAString(value) => TLAValueString(value) - case TLANumber(value, _) => - value match { - case TLANumber.IntValue(value) => TLAValueNumber(value.intValue) - } - case TLAGeneralIdentifier(name, prefix) => - assert(prefix.isEmpty) - env(name.id) - case TLADot(lhs, identifier) => - interpret(lhs) match { - case TLAValueFunction(value) => value(identifier.id) - } - case opcall@TLAOperatorCall(_, _, arguments) => - opcall.refersTo match { - case builtin: BuiltinModules.TLABuiltinOperator => - builtinOperators(builtin)(arguments.map(interpret)) - case TLAOperatorDefinition(_, args, body, _) => - assert(args.size == arguments.size) - assert(args.forall(_.variant.isInstanceOf[TLAOpDecl.NamedVariant])) - val argNames = args.view.map(_.variant.asInstanceOf[TLAOpDecl.NamedVariant].ident.id) - val argValues = arguments.map(interpret) - interpret(body)(env = env ++ (argNames zip argValues)) - } - case TLAIf(cond, tval, fval) => - interpret(cond) match { - case TLAValueBool(value) => - if(value) interpret(tval) else interpret(fval) - } - case TLALet(defs, body) => - @tailrec - def impl(defs: List[TLAUnit])(implicit env: Map[String,TLAValue]): TLAValue = - defs match { - case Nil => interpret(body) - case unit :: restUnits => - unit match { - case TLAOperatorDefinition(name, args, body, _) if args.isEmpty => - val strName = name match { - case Definition.ScopeIdentifierName(name) => name.id - case Definition.ScopeIdentifierSymbol(symbol) => symbol.symbol.stringReprDefn - } - impl(restUnits)(env = env.updated(strName, interpret(body))) - case _: TLAOperatorDefinition => - // for definitions with args, they will be called by TLAOperatorCall, and scoping is done already - impl(restUnits) - } - } + BuiltinModules.Intrinsics.memberSym(TLASymbol.EqualsSymbol) -> { + case List(TLAValueSet(lhs), TLAValueSet(rhs)) => TLAValueBool(lhs == rhs) + }, + BuiltinModules.Intrinsics.memberSym(TLASymbol.NotEqualsSymbol) -> { + case List(TLAValueSet(lhs), TLAValueSet(rhs)) => TLAValueBool(lhs != rhs) + }, + BuiltinModules.Intrinsics.memberSym(TLASymbol.InSymbol) -> { + case List(lhs, TLAValueSet(rhs)) => TLAValueBool(rhs.contains(lhs)) + }, + BuiltinModules.Intrinsics.memberSym(TLASymbol.NotInSymbol) -> { + case List(lhs, TLAValueSet(rhs)) => TLAValueBool(!rhs.contains(lhs)) + }, + BuiltinModules.Intrinsics.memberSym(TLASymbol.IntersectSymbol) -> { + case List(TLAValueSet(lhs), TLAValueSet(rhs)) => TLAValueSet(lhs & rhs) + }, + BuiltinModules.Intrinsics.memberSym(TLASymbol.UnionSymbol) -> { + case List(TLAValueSet(lhs), TLAValueSet(rhs)) => TLAValueSet(lhs | rhs) + }, + BuiltinModules.Intrinsics.memberSym(TLASymbol.SubsetOrEqualSymbol) -> { + case List(TLAValueSet(lhs), TLAValueSet(rhs)) => TLAValueBool(lhs.subsetOf(rhs)) + }, + BuiltinModules.Intrinsics.memberSym(TLASymbol.BackslashSymbol) -> { + case List(TLAValueSet(lhs), TLAValueSet(rhs)) => TLAValueSet(lhs.diff(rhs)) + }, + BuiltinModules.Intrinsics.memberSym(TLASymbol.PrefixUnionSymbol) -> { + case List(TLAValueSet(set)) => TLAValueSet(set.subsets().map(TLAValueSet).toSet) + }, + BuiltinModules.Intrinsics.memberSym(TLASymbol.PrefixUnionSymbol) -> { + case List(TLAValueSet(set)) => + TLAValueSet(set.view.map { + case TLAValueSet(memberSet) => memberSet + }.foldLeft(Set.empty[TLAValue])(_ | _)) + }, - impl(defs) - case TLACase(arms, other) => - @tailrec - def armEval(arms: List[TLACaseArm]): TLAValue = - arms match { - case Nil => other match { - case Some(value) => interpret(value) - } - case TLACaseArm(cond, result) :: otherArms => - interpret(cond) match { - case TLAValueBool(value) => - if(value) { - interpret(result) - } else { - armEval(otherArms) - } - } - } + BuiltinModules.Intrinsics.memberSym(TLASymbol.DomainSymbol) -> { + case List(TLAValueFunction(fn)) => TLAValueSet(fn.keySet) + }, - armEval(arms) - case TLAFunction(args, body) => - def impl(args: List[TLAQuantifierBound], acc: List[TLAValue])(implicit env: Map[String,TLAValue]): Iterator[(TLAValue,TLAValue)] = - args match { - case Nil => Iterator.single(TLAValueTuple(acc) -> interpret(body)) - case TLAQuantifierBound(tpe, ids, set) :: restArgs => - interpret(set) match { - case TLAValueSet(setValue) => - tpe match { - case TLAQuantifierBound.IdsType => - val List(id) = ids - setValue.iterator.flatMap { v => - impl(restArgs, acc :+ v)(env = env.updated(id.id.id, v)) - } - case TLAQuantifierBound.TupleType => - setValue.iterator.flatMap { - case v@TLAValueTuple(elems) => - assert(elems.size == ids.size) - impl(restArgs, acc :+ v)(env = env ++ (ids.view.map(_.id.id) zip elems)) - } - } - } + BuiltinModules.Intrinsics.memberAlpha("STRING") -> { case Nil => throw Unsupported() }, + + BuiltinModules.Intrinsics.memberSym(TLASymbol.PrimeSymbol) -> { _ => throw Unsupported() }, + BuiltinModules.Intrinsics.memberSym(TLASymbol.EnabledSymbol) -> { _ => throw Unsupported() }, + BuiltinModules.Intrinsics.memberSym(TLASymbol.UnchangedSymbol) -> { _ => throw Unsupported() }, + BuiltinModules.Intrinsics.memberSym(TLASymbol.CDotSymbol) -> { _ => throw Unsupported() }, + + BuiltinModules.Intrinsics.memberSym(TLASymbol.TLAlwaysSymbol) -> { _ => throw Unsupported() }, + BuiltinModules.Intrinsics.memberSym(TLASymbol.TLEventuallySymbol) -> { _ => throw Unsupported() }, + BuiltinModules.Intrinsics.memberSym(TLASymbol.SequencingSymbol) -> { _ => throw Unsupported() }, + BuiltinModules.Intrinsics.memberSym(TLASymbol.PlusArrowSymbol) -> { _ => throw Unsupported() }, + + BuiltinModules.TLC.memberAlpha("Print") -> { case List(_, _) => throw Unsupported() }, + BuiltinModules.TLC.memberAlpha("PrintT") -> { case List(_) => throw Unsupported() }, + BuiltinModules.TLC.memberAlpha("Assert") -> { + case List(TLAValueBool(cond), out) => + assert(cond, out.toString) + TLAValueBool(true) + }, + BuiltinModules.TLC.memberAlpha("JavaTime") -> { case Nil => throw Unsupported() }, + BuiltinModules.TLC.memberAlpha(":>") -> { _ => throw Unsupported() }, + BuiltinModules.TLC.memberAlpha("@@") -> { _ => throw Unsupported() }, + BuiltinModules.TLC.memberAlpha("Permutations") -> { _ => throw Unsupported() }, + BuiltinModules.TLC.memberAlpha("SortSeq") -> { _ => throw Unsupported() }, + + BuiltinModules.Sequences.memberAlpha("Seq") -> { _ => throw Unsupported() }, + BuiltinModules.Sequences.memberAlpha("Len") -> { + case List(TLAValueTuple(elems)) => TLAValueNumber(elems.size) + }, + BuiltinModules.Sequences.memberSym(TLASymbol.OSymbol) -> { + case List(TLAValueTuple(lhs), TLAValueTuple(rhs)) => TLAValueTuple(lhs ++ rhs) + }, + BuiltinModules.Sequences.memberAlpha("Append") -> { + case List(TLAValueTuple(elems), elem) => TLAValueTuple(elems :+ elem) + }, + BuiltinModules.Sequences.memberAlpha("Head") -> { + case List(TLAValueTuple(elems)) => + require(elems.nonEmpty) + elems.head + }, + BuiltinModules.Sequences.memberAlpha("Tail") -> { + case List(TLAValueTuple(elems)) => + require(elems.nonEmpty) + TLAValueTuple(elems.tail) + }, + BuiltinModules.Sequences.memberAlpha("SubSeq") -> { + case List(TLAValueTuple(elems), TLAValueNumber(from), TLAValueNumber(to)) => + TLAValueTuple(elems.slice(from, to + 1)) + }, + BuiltinModules.Sequences.memberAlpha("SelectSeq") -> { _ => throw Unsupported() }, + + BuiltinModules.FiniteSets.memberAlpha("IsFiniteSet") -> { + case List(candidate) => + candidate match { + case TLAValueSet(_) => TLAValueBool(true) + case _ => TLAValueBool(false) } + }, + BuiltinModules.FiniteSets.memberAlpha("Cardinality") -> { + case List(TLAValueSet(set)) => TLAValueNumber(set.size) + }, + + BuiltinModules.Bags.memberAlpha("IsABag") -> { case List(_) => throw Unsupported() }, + BuiltinModules.Bags.memberAlpha("BagToSet") -> { case List(_) => throw Unsupported() }, + BuiltinModules.Bags.memberAlpha("SetToBag") -> { case List(_) => throw Unsupported() }, + BuiltinModules.Bags.memberAlpha("BagIn") -> { case List(_, _) => throw Unsupported() }, + BuiltinModules.Bags.memberAlpha("EmptyBag") -> { case Nil => throw Unsupported() }, + BuiltinModules.Bags.memberAlpha("CopiesIn") -> { case List(_, _) => throw Unsupported() }, + BuiltinModules.Bags.memberSym(TLASymbol.OPlusSymbol) -> { _ => throw Unsupported() }, + BuiltinModules.Bags.memberSym(TLASymbol.OMinusSymbol) -> { _ => throw Unsupported() }, + BuiltinModules.Bags.memberAlpha("BagUnion") -> { case List(_) => throw Unsupported() }, + BuiltinModules.Bags.memberSym(TLASymbol.SquareSupersetOrEqualSymbol) -> { _ => throw Unsupported() }, + BuiltinModules.Bags.memberAlpha("SubBag") -> { case List(_) => throw Unsupported() }, + BuiltinModules.Bags.memberAlpha("BagOfAll") -> { case List(_, _) => throw Unsupported() }, + BuiltinModules.Bags.memberAlpha("BagCardinality") -> { case List(_) => throw Unsupported() }, + + BuiltinModules.Peano.memberAlpha("PeanoAxioms") -> { case List(_, _, _) => throw Unsupported() }, + BuiltinModules.Peano.memberAlpha("Succ") -> { case Nil => throw Unsupported() }, + BuiltinModules.Peano.memberAlpha("Nat") -> { case Nil => throw Unsupported() }, + BuiltinModules.Peano.memberAlpha("Zero") -> { case Nil => TLAValueNumber(0) }, + + BuiltinModules.ProtoReals.memberAlpha("IsModelOfReals") -> { case List(_, _, _, _) => throw Unsupported() }, + BuiltinModules.ProtoReals.memberAlpha("RM") -> { case Nil => throw Unsupported() }, + BuiltinModules.ProtoReals.memberAlpha("Real") -> { case Nil => throw Unsupported() }, + BuiltinModules.ProtoReals.memberAlpha("Infinity") -> { case Nil => throw Unsupported() }, + BuiltinModules.ProtoReals.memberAlpha("MinusInfinity") -> { case Nil => throw Unsupported() }, + BuiltinModules.ProtoReals.memberSym(TLASymbol.PlusSymbol) -> { + case List(TLAValueNumber(lhs), TLAValueNumber(rhs)) => TLAValueNumber(math.addExact(lhs, rhs)) + }, + BuiltinModules.ProtoReals.memberSym(TLASymbol.AsteriskSymbol) -> { + case List(TLAValueNumber(lhs), TLAValueNumber(rhs)) => TLAValueNumber(math.multiplyExact(lhs, rhs)) + }, + BuiltinModules.ProtoReals.memberSym(TLASymbol.LessThanOrEqualSymbol) -> { + case List(TLAValueNumber(lhs), TLAValueNumber(rhs)) => TLAValueBool(lhs <= rhs) + }, + BuiltinModules.ProtoReals.memberSym(TLASymbol.MinusSymbol) -> { + case List(TLAValueNumber(lhs), TLAValueNumber(rhs)) => TLAValueNumber(math.subtractExact(lhs, rhs)) + }, + BuiltinModules.ProtoReals.memberSym(TLASymbol.SlashSymbol) -> { case List(_, _) => throw Unsupported() }, + BuiltinModules.ProtoReals.memberAlpha("Int") -> { case Nil => throw Unsupported() }, + BuiltinModules.ProtoReals.memberSym(TLASymbol.SuperscriptSymbol) -> { + case List(TLAValueNumber(lhs), TLAValueNumber(rhs)) => TLAValueNumber(math.pow(lhs, rhs).toInt) + }, + + BuiltinModules.Naturals.memberSym(TLASymbol.GreaterThanOrEqualSymbol) -> { + case List(TLAValueNumber(lhs), TLAValueNumber(rhs)) => TLAValueBool(lhs >= rhs) + }, + BuiltinModules.Naturals.memberSym(TLASymbol.LessThanSymbol) -> { + case List(TLAValueNumber(lhs), TLAValueNumber(rhs)) => TLAValueBool(lhs < rhs) + }, + BuiltinModules.Naturals.memberSym(TLASymbol.GreaterThanSymbol) -> { + case List(TLAValueNumber(lhs), TLAValueNumber(rhs)) => TLAValueBool(lhs > rhs) + }, + BuiltinModules.Naturals.memberSym(TLASymbol.DotDotSymbol) -> { + case List(TLAValueNumber(from), TLAValueNumber(until)) => + TLAValueSet((from to until).view.map(TLAValueNumber).toSet) + }, + BuiltinModules.Naturals.memberSym(TLASymbol.DivSymbol) -> { + case List(TLAValueNumber(lhs), TLAValueNumber(rhs)) => + require(rhs != 0) + TLAValueNumber(math.floorDiv(lhs, rhs)) + }, + BuiltinModules.Naturals.memberSym(TLASymbol.PercentSymbol) -> { + case List(TLAValueNumber(lhs), TLAValueNumber(rhs)) => + require(rhs != 0) + TLAValueNumber(math.floorMod(lhs, rhs)) + }, + + BuiltinModules.Integers.memberAlpha("Int") -> { _ => throw Unsupported() }, + BuiltinModules.Integers.memberSym(TLASymbol.NegationSymbol) -> { + case List(TLAValueNumber(num)) => TLAValueNumber(-num) + }, - TLAValueFunction(impl(args, Nil).toMap) - case TLAFunctionCall(function, params) => - val paramValue = params match { - case List(singleParam) => interpret(singleParam) - case params => TLAValueTuple(params.map(interpret)) - } - interpret(function) match { - case TLAValueTuple(value) => - paramValue match { - case TLAValueNumber(idx) => value(idx) + BuiltinModules.Reals.memberAlpha("Real") -> { _ => throw Unsupported() }, + BuiltinModules.Reals.memberSym(TLASymbol.SlashSymbol) -> { _ => throw Unsupported() }, + BuiltinModules.Reals.memberAlpha("Infinity") -> { _ => throw Unsupported() }, + ) + + def interpret(expr: TLAExpression)(implicit env: Map[String,TLAValue]): TLAValue = { + try { + expr match { + case TLAString(value) => TLAValueString(value) + case TLANumber(value, _) => + value match { + case TLANumber.IntValue(value) => TLAValueNumber(value.intValue) + } + case ident@TLAGeneralIdentifier(name, prefix) => + assert(prefix.isEmpty) + env.getOrElse(name.id, { + builtinOperators(ident.refersTo)(Nil) + }) + case TLADot(lhs, identifier) => + interpret(lhs) match { + case TLAValueFunction(value) => + require(value.contains(identifier.id)) + value(identifier.id) + } + case opcall@TLAOperatorCall(_, _, arguments) => + opcall.refersTo match { + case builtin: BuiltinModules.TLABuiltinOperator => + builtinOperators(builtin)(arguments.map(interpret)) + case TLAOperatorDefinition(_, args, body, _) => + assert(args.size == arguments.size) + assert(args.forall(_.variant.isInstanceOf[TLAOpDecl.NamedVariant])) + val argNames = args.view.map(_.variant.asInstanceOf[TLAOpDecl.NamedVariant].ident.id) + val argValues = arguments.map(interpret) + interpret(body)(env = env ++ (argNames zip argValues)) + } + case TLAIf(cond, tval, fval) => + interpret(cond) match { + case TLAValueBool(value) => + if (value) interpret(tval) else interpret(fval) + } + case TLALet(defs, body) => + @tailrec + def impl(defs: List[TLAUnit])(implicit env: Map[String, TLAValue]): TLAValue = + defs match { + case Nil => interpret(body) + case unit :: restUnits => + unit match { + case TLAOperatorDefinition(name, args, body, _) if args.isEmpty => + val strName = name match { + case Definition.ScopeIdentifierName(name) => name.id + case Definition.ScopeIdentifierSymbol(symbol) => symbol.symbol.stringReprDefn + } + impl(restUnits)(env = env.updated(strName, interpret(body))) + case _: TLAOperatorDefinition => + // for definitions with args, they will be called by TLAOperatorCall, and scoping is done already + impl(restUnits) + } } - case TLAValueFunction(value) => value(paramValue) - } - case TLAFunctionSet(from, to) => - (interpret(from), interpret(to)) match { - case (TLAValueSet(fromSet), TLAValueSet(toSet)) => - TLAValueSet { - val keyList = fromSet.toList - val valueList = toSet.toList - val valueSets = keyList.iterator.foldLeft(Iterator.single(Nil: List[TLAValue])) { (acc, _) => - acc.flatMap(lst => valueList.iterator.map(v => v :: lst)) + + impl(defs) + case TLACase(arms, other) => + @tailrec + def armEval(arms: List[TLACaseArm]): TLAValue = + arms match { + case Nil => other match { + case Some(value) => interpret(value) } - valueSets.map(valueSet => TLAValueFunction((keyList zip valueSet).toMap)).toSet - } - } - case TLAFunctionSubstitution(source, substitutions) => - substitutions.foldLeft(interpret(source)) { (fnValue, sub) => - val TLAFunctionSubstitutionPair(_, keys, value) = sub - def subKeys(keys: List[TLAFunctionSubstitutionKey], origValue: TLAValue): TLAValue = - keys match { - case Nil => interpret(value)(env = env.updated("@", origValue)) - case TLAFunctionSubstitutionKey(indices) :: restKeys => - val indexValue = indices match { - case List(index) => interpret(index) - case indices => TLAValueTuple(indices.map(interpret)) - } - origValue match { - case TLAValueFunction(origFn) => - TLAValueFunction(origFn.updated(indexValue, subKeys(restKeys, origFn(indexValue)))) + case TLACaseArm(cond, result) :: otherArms => + interpret(cond) match { + case TLAValueBool(value) => + if (value) { + interpret(result) + } else { + armEval(otherArms) + } } } - subKeys(keys, fnValue) - } - case TLAFunctionSubstitutionAt() => env("@") - case TLAQuantifiedExistential(bounds, body) => - def impl(bounds: List[TLAQuantifierBound])(implicit env: Map[String,TLAValue]): TLAValue = - bounds match { - case Nil => interpret(body) - case TLAQuantifierBound(tpe, ids, set) :: restBounds => - val setValue = interpret(set) - tpe match { - case TLAQuantifierBound.IdsType => - val List(id) = ids - setValue match { - case TLAValueSet(setValue) => - TLAValueBool(setValue.exists { v => - impl(restBounds)(env = env.updated(id.id.id, v)) match { - case TLAValueBool(value) => value + armEval(arms) + case TLAFunction(args, body) => + def impl(args: List[TLAQuantifierBound], acc: Vector[TLAValue])(implicit env: Map[String, TLAValue]): Iterator[(TLAValue, TLAValue)] = + args match { + case Nil => Iterator.single(TLAValueTuple(acc) -> interpret(body)) + case TLAQuantifierBound(tpe, ids, set) :: restArgs => + interpret(set) match { + case TLAValueSet(setValue) => + tpe match { + case TLAQuantifierBound.IdsType => + val List(id) = ids + setValue.iterator.flatMap { v => + impl(restArgs, acc :+ v)(env = env.updated(id.id.id, v)) } - }) - } - case TLAQuantifierBound.TupleType => - setValue match { - case TLAValueSet(setValue) => - TLAValueBool(setValue.exists { - case TLAValueTuple(elems) => - assert(elems.size == ids.size) - impl(restBounds)(env = env ++ (ids.view.map(_.id.id) zip elems)) match { - case TLAValueBool(value) => value - } - }) - } + case TLAQuantifierBound.TupleType => + setValue.iterator.flatMap { + case v@TLAValueTuple(elems) => + assert(elems.size == ids.size) + impl(restArgs, acc :+ v)(env = env ++ (ids.view.map(_.id.id) zip elems)) + } + } + } + } + + TLAValueFunction(impl(args, Vector.empty).toMap) + case TLAFunctionCall(function, params) => + val paramValue = params match { + case List(singleParam) => interpret(singleParam) + case params => TLAValueTuple(params.view.map(interpret).toVector) + } + interpret(function) match { + case TLAValueTuple(value) => + paramValue match { + case TLAValueNumber(idx) => value(idx) + } + case TLAValueFunction(value) => value(paramValue) + } + case TLAFunctionSet(from, to) => + (interpret(from), interpret(to)) match { + case (TLAValueSet(fromSet), TLAValueSet(toSet)) => + TLAValueSet { + val keyList = fromSet.toList + val valueList = toSet.toList + val valueSets = keyList.iterator.foldLeft(Iterator.single(Nil: List[TLAValue])) { (acc, _) => + acc.flatMap(lst => valueList.iterator.map(v => v :: lst)) + } + valueSets.map(valueSet => TLAValueFunction((keyList zip valueSet).toMap)).toSet } } + case TLAFunctionSubstitution(source, substitutions) => + substitutions.foldLeft(interpret(source)) { (fnValue, sub) => + val TLAFunctionSubstitutionPair(_, keys, value) = sub - impl(bounds) - case TLAQuantifiedUniversal(bounds, body) => - def impl(bounds: List[TLAQuantifierBound])(implicit env: Map[String,TLAValue]): TLAValue = - bounds match { - case Nil => interpret(body) - case TLAQuantifierBound(tpe, ids, set) :: restBounds => - val setValue = interpret(set) - tpe match { - case TLAQuantifierBound.IdsType => - val List(id) = ids - setValue match { - case TLAValueSet(setValue) => - TLAValueBool(setValue.forall { v => - impl(restBounds)(env = env.updated(id.id.id, v)) match { - case TLAValueBool(value) => value - } - }) + def subKeys(keys: List[TLAFunctionSubstitutionKey], origValue: TLAValue): TLAValue = + keys match { + case Nil => interpret(value)(env = env.updated("@", origValue)) + case TLAFunctionSubstitutionKey(indices) :: restKeys => + val indexValue = indices match { + case List(index) => interpret(index) + case indices => TLAValueTuple(indices.view.map(interpret).toVector) } - case TLAQuantifierBound.TupleType => - setValue match { - case TLAValueSet(setValue) => - TLAValueBool(setValue.forall { - case TLAValueTuple(elems) => - assert(elems.size == ids.size) - impl(restBounds)(env = env ++ (ids.view.map(_.id.id) zip elems)) match { - case TLAValueBool(value) => value - } - }) + origValue match { + case TLAValueFunction(origFn) => + TLAValueFunction(origFn.updated(indexValue, subKeys(restKeys, origFn(indexValue)))) } } + + subKeys(keys, fnValue) } + case TLAFunctionSubstitutionAt() => env("@") + case TLAQuantifiedExistential(bounds, body) => + def impl(bounds: List[TLAQuantifierBound])(implicit env: Map[String, TLAValue]): TLAValue = + bounds match { + case Nil => interpret(body) + case TLAQuantifierBound(tpe, ids, set) :: restBounds => + val setValue = interpret(set) + tpe match { + case TLAQuantifierBound.IdsType => + val List(id) = ids + setValue match { + case TLAValueSet(setValue) => + TLAValueBool(setValue.exists { v => + impl(restBounds)(env = env.updated(id.id.id, v)) match { + case TLAValueBool(value) => value + } + }) + } + case TLAQuantifierBound.TupleType => + setValue match { + case TLAValueSet(setValue) => + TLAValueBool(setValue.exists { + case TLAValueTuple(elems) => + require(elems.size == ids.size) + impl(restBounds)(env = env ++ (ids.view.map(_.id.id) zip elems)) match { + case TLAValueBool(value) => value + } + }) + } + } + } - impl(bounds) - case TLASetConstructor(contents) => - TLAValueSet(contents.view.map(interpret).toSet) - case TLASetRefinement(TLAQuantifierBound(tpe, ids, set), when) => - interpret(set) match { - case TLAValueSet(setValue) => - tpe match { - case TLAQuantifierBound.IdsType => - val List(id) = ids - TLAValueSet(setValue.filter { v => - interpret(when)(env = env.updated(id.id.id, v)) match { - case TLAValueBool(value) => value - } - }) - case TLAQuantifierBound.TupleType => - TLAValueSet(setValue.filter { - case TLAValueTuple(elems) => - assert(elems.size == ids.size) - interpret(when)(env = env ++ (ids.view.map(_.id.id) zip elems)) match { - case TLAValueBool(value) => value + impl(bounds) + case TLAQuantifiedUniversal(bounds, body) => + def impl(bounds: List[TLAQuantifierBound])(implicit env: Map[String, TLAValue]): TLAValue = + bounds match { + case Nil => interpret(body) + case TLAQuantifierBound(tpe, ids, set) :: restBounds => + val setValue = interpret(set) + tpe match { + case TLAQuantifierBound.IdsType => + val List(id) = ids + setValue match { + case TLAValueSet(setValue) => + TLAValueBool(setValue.forall { v => + impl(restBounds)(env = env.updated(id.id.id, v)) match { + case TLAValueBool(value) => value + } + }) + } + case TLAQuantifierBound.TupleType => + setValue match { + case TLAValueSet(setValue) => + TLAValueBool(setValue.forall { + case TLAValueTuple(elems) => + require(elems.size == ids.size) + impl(restBounds)(env = env ++ (ids.view.map(_.id.id) zip elems)) match { + case TLAValueBool(value) => value + } + }) } - }) + } } - } - case TLASetComprehension(body, bounds) => - def impl(bounds: List[TLAQuantifierBound])(implicit env: Map[String,TLAValue]): Iterator[TLAValue] = - bounds match { - case Nil => Iterator.single(interpret(body)) - case TLAQuantifierBound(tpe, ids, set) :: restBounds => - interpret(set) match { - case TLAValueSet(setValue) => - tpe match { - case TLAQuantifierBound.IdsType => - val List(id) = ids - setValue.iterator.flatMap { v => - impl(restBounds)(env = env.updated(id.id.id, v)) - } - case TLAQuantifierBound.TupleType => - setValue.iterator.flatMap { - case TLAValueTuple(elems) => - assert(ids.size == elems.size) - impl(restBounds)(env = env ++ (ids.view.map(_.id.id) zip elems)) + + impl(bounds) + case TLASetConstructor(contents) => + TLAValueSet(contents.view.map(interpret).toSet) + case TLASetRefinement(TLAQuantifierBound(tpe, ids, set), when) => + interpret(set) match { + case TLAValueSet(setValue) => + tpe match { + case TLAQuantifierBound.IdsType => + val List(id) = ids + TLAValueSet(setValue.filter { v => + interpret(when)(env = env.updated(id.id.id, v)) match { + case TLAValueBool(value) => value + } + }) + case TLAQuantifierBound.TupleType => + TLAValueSet(setValue.filter { + case TLAValueTuple(elems) => + require(elems.size == ids.size) + interpret(when)(env = env ++ (ids.view.map(_.id.id) zip elems)) match { + case TLAValueBool(value) => value } - } + }) } } + case TLASetComprehension(body, bounds) => + def impl(bounds: List[TLAQuantifierBound])(implicit env: Map[String, TLAValue]): Iterator[TLAValue] = + bounds match { + case Nil => Iterator.single(interpret(body)) + case TLAQuantifierBound(tpe, ids, set) :: restBounds => + interpret(set) match { + case TLAValueSet(setValue) => + tpe match { + case TLAQuantifierBound.IdsType => + val List(id) = ids + setValue.iterator.flatMap { v => + impl(restBounds)(env = env.updated(id.id.id, v)) + } + case TLAQuantifierBound.TupleType => + setValue.iterator.flatMap { + case TLAValueTuple(elems) => + require(ids.size == elems.size) + impl(restBounds)(env = env ++ (ids.view.map(_.id.id) zip elems)) + } + } + } + } - TLAValueSet(impl(bounds).toSet) - case TLATuple(elements) => - TLAValueTuple(elements.map(interpret)) - case TLARecordConstructor(fields) => - TLAValueFunction(fields.view.map { - case TLARecordConstructorField(name, value) => - TLAValueString(name.id) -> interpret(value) - }.toMap) - case TLARecordSet(fields) => - def impl(fields: List[TLARecordSetField], acc: Map[TLAValue,TLAValue]): Iterator[TLAValue] = - fields match { - case Nil => Iterator.single(TLAValueFunction(acc)) - case TLARecordSetField(name, set) :: restFields => - interpret(set) match { - case TLAValueSet(setValue) => - setValue.iterator.flatMap { v => - impl(restFields, acc.updated(name.id, v)) + TLAValueSet(impl(bounds).toSet) + case TLATuple(elements) => + TLAValueTuple(elements.view.map(interpret).toVector) + case TLARecordConstructor(fields) => + TLAValueFunction(fields.view.map { + case TLARecordConstructorField(name, value) => + TLAValueString(name.id) -> interpret(value) + }.toMap) + case TLARecordSet(fields) => + def impl(fields: List[(String,TLAValue)], acc: Map[TLAValue, TLAValue]): Iterator[TLAValue] = + fields match { + case Nil => Iterator.single(TLAValueFunction(acc)) + case (name, TLAValueSet(set)) :: restFields => + set.iterator.flatMap { v => + impl(restFields, acc.updated(TLAValueString(name), v)) } - } - } + } - TLAValueSet(impl(fields, Map.empty).toSet) + TLAValueSet(impl(fields.map { + case TLARecordSetField(name, set) => + (name.id, interpret(set)) + }, Map.empty).toSet) + } + } catch { + case err: IllegalArgumentException => + throw TypeError().initCause(err) + case err: MatchError => + throw TypeError().initCause(err) } + } } diff --git a/test/files/general/dqueue.tla.expectpcal b/test/files/general/dqueue.tla.expectpcal index 1dbd9bff5..0c054da45 100644 --- a/test/files/general/dqueue.tla.expectpcal +++ b/test/files/general/dqueue.tla.expectpcal @@ -89,6 +89,8 @@ CONSTANTS BUFFER_SIZE, NUM_CONSUMERS, PRODUCER c: if(TRUE) { goto c1; + } else { + goto Done; }; c1: with (value1 = self) { @@ -113,6 +115,8 @@ CONSTANTS BUFFER_SIZE, NUM_CONSUMERS, PRODUCER p: if(TRUE) { goto p1; + } else { + goto Done; }; p1: await (Len((network)[self])) > (0); diff --git a/test/files/general/dqueue.tla.gotests/dqueue.go b/test/files/general/dqueue.tla.gotests/dqueue.go index e37946c62..bdf950482 100644 --- a/test/files/general/dqueue.tla.gotests/dqueue.go +++ b/test/files/general/dqueue.tla.gotests/dqueue.go @@ -22,6 +22,7 @@ func AConsumer(ctx *distsys.MPCalContext, self distsys.TLAValue, constants Const cLabelTag = iota c1LabelTag c2LabelTag + DoneLabelTag ) programCounter := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.NewTLANumber(cLabelTag)) @@ -50,7 +51,14 @@ func AConsumer(ctx *distsys.MPCalContext, self distsys.TLAValue, constants Const continue } } else { - // no statements + err = ctx.Write(programCounter, []distsys.TLAValue{}, distsys.NewTLANumber(DoneLabelTag)) + if err != nil { + continue + } + err = ctx.Commit() + if err != nil { + continue + } } // no statements case c1LabelTag: @@ -84,6 +92,8 @@ func AConsumer(ctx *distsys.MPCalContext, self distsys.TLAValue, constants Const if err != nil { continue } + case DoneLabelTag: + return nil default: return fmt.Errorf("invalid program counter %v", labelTag) } @@ -97,6 +107,7 @@ func AProducer(ctx *distsys.MPCalContext, self distsys.TLAValue, constants Const pLabelTag = iota p1LabelTag p2LabelTag + DoneLabelTag ) programCounter0 := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.NewTLANumber(pLabelTag)) requester := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.TLAValue{}) @@ -126,7 +137,14 @@ func AProducer(ctx *distsys.MPCalContext, self distsys.TLAValue, constants Const continue } } else { - // no statements + err0 = ctx.Write(programCounter0, []distsys.TLAValue{}, distsys.NewTLANumber(DoneLabelTag)) + if err0 != nil { + continue + } + err0 = ctx.Commit() + if err0 != nil { + continue + } } // no statements case p1LabelTag: @@ -170,6 +188,8 @@ func AProducer(ctx *distsys.MPCalContext, self distsys.TLAValue, constants Const if err0 != nil { continue } + case DoneLabelTag: + return nil default: return fmt.Errorf("invalid program counter %v", labelTag0) } diff --git a/test/files/general/load_balancer.tla.expectpcal b/test/files/general/load_balancer.tla.expectpcal index b75abbb22..c7996504f 100644 --- a/test/files/general/load_balancer.tla.expectpcal +++ b/test/files/general/load_balancer.tla.expectpcal @@ -255,6 +255,8 @@ CONSTANT WEB_PAGE main: if(TRUE) { goto rcvMsg; + } else { + goto Done; }; rcvMsg: await (Len((network)[LoadBalancerId])) > (0); @@ -281,6 +283,8 @@ CONSTANT WEB_PAGE serverLoop: if(TRUE) { goto rcvReq; + } else { + goto Done; }; rcvReq: await (Len((network)[self])) > (0); @@ -307,6 +311,8 @@ CONSTANT WEB_PAGE clientLoop: if(TRUE) { goto clientRequest; + } else { + goto Done; }; clientRequest: req := [message_type |-> GET_PAGE, client_id |-> self, path |-> in]; diff --git a/test/files/general/load_balancer.tla.gotests/load_balancer.go b/test/files/general/load_balancer.tla.gotests/load_balancer.go index 025484587..23d25cefe 100644 --- a/test/files/general/load_balancer.tla.gotests/load_balancer.go +++ b/test/files/general/load_balancer.tla.gotests/load_balancer.go @@ -25,6 +25,7 @@ func ALoadBalancer(ctx *distsys.MPCalContext, self distsys.TLAValue, constants C mainLabelTag = iota rcvMsgLabelTag sendServerLabelTag + DoneLabelTag ) programCounter := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.NewTLANumber(mainLabelTag)) msg := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.TLAValue{}) @@ -55,7 +56,14 @@ func ALoadBalancer(ctx *distsys.MPCalContext, self distsys.TLAValue, constants C continue } } else { - // no statements + err = ctx.Write(programCounter, []distsys.TLAValue{}, distsys.NewTLANumber(DoneLabelTag)) + if err != nil { + continue + } + err = ctx.Commit() + if err != nil { + continue + } } // no statements case rcvMsgLabelTag: @@ -131,6 +139,8 @@ func ALoadBalancer(ctx *distsys.MPCalContext, self distsys.TLAValue, constants C if err != nil { continue } + case DoneLabelTag: + return nil default: return fmt.Errorf("invalid program counter %v", labelTag) } @@ -144,6 +154,7 @@ func AServer(ctx *distsys.MPCalContext, self distsys.TLAValue, constants Constan serverLoopLabelTag = iota rcvReqLabelTag sendPageLabelTag + DoneLabelTag ) programCounter0 := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.NewTLANumber(serverLoopLabelTag)) msg0 := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.TLAValue{}) @@ -173,7 +184,14 @@ func AServer(ctx *distsys.MPCalContext, self distsys.TLAValue, constants Constan continue } } else { - // no statements + err0 = ctx.Write(programCounter0, []distsys.TLAValue{}, distsys.NewTLANumber(DoneLabelTag)) + if err0 != nil { + continue + } + err0 = ctx.Commit() + if err0 != nil { + continue + } } // no statements case rcvReqLabelTag: @@ -222,6 +240,8 @@ func AServer(ctx *distsys.MPCalContext, self distsys.TLAValue, constants Constan if err0 != nil { continue } + case DoneLabelTag: + return nil default: return fmt.Errorf("invalid program counter %v", labelTag0) } @@ -235,6 +255,7 @@ func AClient(ctx *distsys.MPCalContext, self distsys.TLAValue, constants Constan clientLoopLabelTag = iota clientRequestLabelTag clientReceiveLabelTag + DoneLabelTag ) programCounter1 := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.NewTLANumber(clientLoopLabelTag)) req := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.TLAValue{}) @@ -265,7 +286,14 @@ func AClient(ctx *distsys.MPCalContext, self distsys.TLAValue, constants Constan continue } } else { - // no statements + err1 = ctx.Write(programCounter1, []distsys.TLAValue{}, distsys.NewTLANumber(DoneLabelTag)) + if err1 != nil { + continue + } + err1 = ctx.Commit() + if err1 != nil { + continue + } } // no statements case clientRequestLabelTag: @@ -326,6 +354,8 @@ func AClient(ctx *distsys.MPCalContext, self distsys.TLAValue, constants Constan if err1 != nil { continue } + case DoneLabelTag: + return nil default: return fmt.Errorf("invalid program counter %v", labelTag1) } diff --git a/test/files/general/replicated_kv.tla.expectpcal b/test/files/general/replicated_kv.tla.expectpcal index d5dac2693..dc54345c4 100644 --- a/test/files/general/replicated_kv.tla.expectpcal +++ b/test/files/general/replicated_kv.tla.expectpcal @@ -156,7 +156,7 @@ NullSet == (NUM_REPLICAS+3*NUM_CLIENTS)..(NUM_REPLICAS+4*NUM_CLIENTS-1) \* incoming messages. \* - kv: the underlying "database". When 'put' requests become stable, this \* database is updated to include the value being set by the client. - archetype AReplica(ref clients, replicas, ref kv) + archetype AReplica(ref clients[_], ref replicas[_], ref kv[_]) \* Local state in a replica: variables @@ -423,7 +423,7 @@ NullSet == (NUM_REPLICAS+3*NUM_CLIENTS)..(NUM_REPLICAS+4*NUM_CLIENTS-1) \* A Get message sent to the replica is a record in the following format: \* \* [op: GET_MSG, key: key, client: client_id, timestamp: lamport_clock] - archetype Get(clientId, ref replicas, clients, key, ref clock, spin, ref outside) + archetype Get(ref clientId, ref replicas[_], ref clients[_], key, ref clock[_], spin, ref outside) variable continue = TRUE, getReq, getResp; { \* Loop until disconnected @@ -478,7 +478,7 @@ NullSet == (NUM_REPLICAS+3*NUM_CLIENTS)..(NUM_REPLICAS+4*NUM_CLIENTS-1) \* A Put message sent to the replica is a record in the following format: \* \* [op: PUT_MSG, key: key, value: value, client: client_id, timestamp: lamport_clock] - archetype Put(clientId, ref replicas, clients, key, value, ref clock, spin, ref outside) + archetype Put(ref clientId, ref replicas[_], ref clients[_], key, value, ref clock[_], spin, ref outside) variables continue = TRUE, i, j, putReq, putResp; { \* Loops indefinitely until disconnected @@ -531,7 +531,7 @@ NullSet == (NUM_REPLICAS+3*NUM_CLIENTS)..(NUM_REPLICAS+4*NUM_CLIENTS-1) \* A Disconnect message sent to the replica is a record in the following format: \* \* [op: DISCONNECT_MSG, client: client_id] - archetype Disconnect(clientId, ref replicas, ref clock) + archetype Disconnect(ref clientId, ref replicas[_], ref clock[_]) variables msg, j; { sendDisconnectRequest: @@ -555,7 +555,7 @@ NullSet == (NUM_REPLICAS+3*NUM_CLIENTS)..(NUM_REPLICAS+4*NUM_CLIENTS-1) \* A ClockUpdate message sent to the replica is a record in the following format: \* \* [op: NULL_MSG, client: client_id, timestamp: logical_clock] - archetype ClockUpdate(clientId, ref replicas, ref clock, spin) + archetype ClockUpdate(ref clientId, ref replicas[_], ref clock[_], spin) variables continue = TRUE, j, msg; { clockUpdateLoop: @@ -617,34 +617,30 @@ NullSet == (NUM_REPLICAS+3*NUM_CLIENTS)..(NUM_REPLICAS+4*NUM_CLIENTS-1) \* Instantiate replica servers. The network model used is the one defined in \* the FIFOChannel mapping macro. - fair process (Replica \in ReplicaSet) == instance AReplica(ref clientMailboxes, replicasNetwork, [k \in KeySpace |-> NULL]) + fair process (Replica \in ReplicaSet) == instance AReplica(ref clientMailboxes[_], ref replicasNetwork[_], [k \in KeySpace |-> NULL]) mapping @1[_] via FIFOChannel mapping @2[_] via FIFOChannel mapping @3[_] via Identity; \* Instantiate clients: - fair process (GetClient \in GetSet) == instance Get(cid, ref replicasNetwork, clientMailboxes, GET_KEY, ref clocks, TRUE, ref out) + fair process (GetClient \in GetSet) == instance Get(ref cid, ref replicasNetwork[_], ref clientMailboxes[_], GET_KEY, ref clocks[_], TRUE, ref out) mapping cid via GetClientId mapping replicasNetwork[_] via FIFOChannel - mapping clientMailboxes[_] via FIFOChannel - mapping clocks[_] via Identity; + mapping clientMailboxes[_] via FIFOChannel; - fair process (PutClient \in PutSet) == instance Put(cid, ref replicasNetwork, clientMailboxes, PUT_KEY, PUT_VALUE, ref clocks, TRUE, ref out) + fair process (PutClient \in PutSet) == instance Put(ref cid, ref replicasNetwork[_], ref clientMailboxes[_], PUT_KEY, PUT_VALUE, ref clocks[_], TRUE, ref out) mapping cid via PutClientId mapping replicasNetwork[_] via FIFOChannel - mapping clientMailboxes[_] via FIFOChannel - mapping clocks[_] via Identity; + mapping clientMailboxes[_] via FIFOChannel; - fair process (DisconnectClient \in DisconnectSet) == instance Disconnect(cid, ref replicasNetwork, ref clocks) + fair process (DisconnectClient \in DisconnectSet) == instance Disconnect(ref cid, ref replicasNetwork[_], ref clocks[_]) mapping cid via DisconnectClientId - mapping replicasNetwork[_] via FIFOChannel - mapping clocks[_] via Identity; + mapping replicasNetwork[_] via FIFOChannel; - fair process (ClockUpdateClient \in NullSet) == instance ClockUpdate(cid, ref replicasNetwork, ref clocks, TRUE) + fair process (ClockUpdateClient \in NullSet) == instance ClockUpdate(ref cid, ref replicasNetwork[_], ref clocks[_], TRUE) mapping cid via NullClientId - mapping replicasNetwork[_] via FIFOChannel - mapping clocks[_] via Identity; + mapping replicasNetwork[_] via FIFOChannel; } @@ -659,18 +655,20 @@ NullSet == (NUM_REPLICAS+3*NUM_CLIENTS)..(NUM_REPLICAS+4*NUM_CLIENTS-1) } fair process (Replica \in ReplicaSet) - variables liveClients = ClientSet; pendingRequests = [c \in liveClients |-> <<>>]; stableMessages = <<>>; i; firstPending; timestamp; nextClient; lowestPending; chooseMessage; currentClocks = [c \in liveClients |-> 0]; minClock; continue; pendingClients; clientsIter; msg; ok; key; val; replicas = replicasNetwork; kv = [k \in KeySpace |-> NULL]; + variables liveClients = ClientSet; pendingRequests = [c \in liveClients |-> <<>>]; stableMessages = <<>>; i; firstPending; timestamp; nextClient; lowestPending; chooseMessage; currentClocks = [c \in liveClients |-> 0]; minClock; continue; pendingClients; clientsIter; msg; ok; key; val; kv = [k \in KeySpace |-> NULL]; { replicaLoop: if(TRUE) { stableMessages := <<>>; continue := TRUE; goto receiveClientRequest; + } else { + goto Done; }; receiveClientRequest: - await (Len((replicas)[self])) > (0); - with (msg0 = Head((replicas)[self])) { - replicas := [replicas EXCEPT ![self] = Tail((replicas)[self])]; + await (Len((replicasNetwork)[self])) > (0); + with (msg0 = Head((replicasNetwork)[self])) { + replicasNetwork := [replicasNetwork EXCEPT ![self] = Tail((replicasNetwork)[self])]; with (yielded_replicas0 = msg0) { msg := yielded_replicas0; goto clientDisconnected; @@ -797,8 +795,8 @@ NullSet == (NUM_REPLICAS+3*NUM_CLIENTS)..(NUM_REPLICAS+4*NUM_CLIENTS-1) if(((msg).op) = (PUT_MSG)) { key := (msg).key; val := (msg).value; - with (value11 = val) { - kv := [kv EXCEPT ![key] = value11]; + with (value10 = val) { + kv := [kv EXCEPT ![key] = value10]; with (value20 = [type |-> PUT_RESPONSE, result |-> ok]) { await (Len((clientMailboxes)[(msg).reply_to])) < (BUFFER_SIZE); clientMailboxes := [clientMailboxes EXCEPT ![(msg).reply_to] = Append((clientMailboxes)[(msg).reply_to], value20)]; @@ -811,31 +809,31 @@ NullSet == (NUM_REPLICAS+3*NUM_CLIENTS)..(NUM_REPLICAS+4*NUM_CLIENTS-1) } fair process (GetClient \in GetSet) - variables continue = TRUE; getReq; getResp; clientId = cid; clients = clientMailboxes; key = GET_KEY; spin = TRUE; + variables continue = TRUE; getReq; getResp; key = GET_KEY; spin = TRUE; { getLoop: if(continue) { goto getRequest; + } else { + goto Done; }; getRequest: - with (yielded_clock1 = (clocks)[clientId]) { - if((yielded_clock1) = (- (1))) { + with (yielded_clientId3 = (self) - ((NUM_CLIENTS) * (GET_ORDER))) { + if(((clocks)[yielded_clientId3]) = (- (1))) { continue := FALSE; goto getCheckSpin; } else { - with (yielded_clientId7 = (self) - ((NUM_CLIENTS) * (GET_ORDER))) { - with (yielded_clock12 = (clocks)[clientId]) { - with (value30 = (yielded_clock12) + (1)) { - clocks := [clocks EXCEPT ![yielded_clientId7] = value30]; - with (yielded_clientId00 = (self) - ((NUM_CLIENTS) * (GET_ORDER))) { - with (yielded_clock00 = (clocks)[clientId]) { - getReq := [op |-> GET_MSG, key |-> key, client |-> yielded_clientId00, timestamp |-> yielded_clock00, reply_to |-> self]; - with (dst \in ReplicaSet) { - with (value40 = getReq) { - await (Len((replicasNetwork)[dst])) < (BUFFER_SIZE); - replicasNetwork := [replicasNetwork EXCEPT ![dst] = Append((replicasNetwork)[dst], value40)]; - goto getReply; - }; + with (yielded_clientId00 = (self) - ((NUM_CLIENTS) * (GET_ORDER))) { + with (yielded_clientId20 = (self) - ((NUM_CLIENTS) * (GET_ORDER))) { + clock := [clock EXCEPT ![yielded_clientId00] = ((clocks)[yielded_clientId20]) + (1)]; + with (yielded_clientId21 = (self) - ((NUM_CLIENTS) * (GET_ORDER))) { + with (yielded_clientId110 = (self) - ((NUM_CLIENTS) * (GET_ORDER))) { + getReq := [op |-> GET_MSG, key |-> key, client |-> yielded_clientId21, timestamp |-> (clocks)[yielded_clientId110], reply_to |-> self]; + with (dst \in ReplicaSet) { + with (value30 = getReq) { + await (Len((replicasNetwork)[dst])) < (BUFFER_SIZE); + replicasNetwork := [replicasNetwork EXCEPT ![dst] = Append((replicasNetwork)[dst], value30)]; + goto getReply; }; }; }; @@ -845,14 +843,14 @@ NullSet == (NUM_REPLICAS+3*NUM_CLIENTS)..(NUM_REPLICAS+4*NUM_CLIENTS-1) }; }; getReply: - with (yielded_clock2 = (clocks)[clientId]) { - if((yielded_clock2) = (- (1))) { + with (yielded_clientId4 = (self) - ((NUM_CLIENTS) * (GET_ORDER))) { + if(((clocks)[yielded_clientId4]) = (- (1))) { continue := FALSE; goto getCheckSpin; } else { - await (Len((clients)[self])) > (0); - with (msg1 = Head((clients)[self])) { - clients := [clients EXCEPT ![self] = Tail((clients)[self])]; + await (Len((clientMailboxes)[self])) > (0); + with (msg1 = Head((clientMailboxes)[self])) { + clientMailboxes := [clientMailboxes EXCEPT ![self] = Tail((clientMailboxes)[self])]; with (yielded_clients1 = msg1) { getResp := yielded_clients1; assert ((getResp).type) = (GET_RESPONSE); @@ -872,29 +870,29 @@ NullSet == (NUM_REPLICAS+3*NUM_CLIENTS)..(NUM_REPLICAS+4*NUM_CLIENTS-1) } fair process (PutClient \in PutSet) - variables continue = TRUE; i; j; putReq; putResp; clientId = cid; clients = clientMailboxes; key = PUT_KEY; value = PUT_VALUE; spin = TRUE; + variables continue = TRUE; i; j; putReq; putResp; key = PUT_KEY; value = PUT_VALUE; spin = TRUE; { putLoop: if(continue) { goto putRequest; + } else { + goto Done; }; putRequest: - with (yielded_clock5 = (clocks)[clientId]) { - if((yielded_clock5) = (- (1))) { + with (yielded_clientId9 = (self) - ((NUM_CLIENTS) * (PUT_ORDER))) { + if(((clocks)[yielded_clientId9]) = (- (1))) { continue := FALSE; goto putCheckSpin; } else { - with (yielded_clientId10 = (self) - ((NUM_CLIENTS) * (PUT_ORDER))) { - with (yielded_clock30 = (clocks)[clientId]) { - with (value50 = (yielded_clock30) + (1)) { - clocks := [clocks EXCEPT ![yielded_clientId10] = value50]; - with (yielded_clientId20 = (self) - ((NUM_CLIENTS) * (PUT_ORDER))) { - with (yielded_clock40 = (clocks)[clientId]) { - putReq := [op |-> PUT_MSG, key |-> key, value |-> value, client |-> yielded_clientId20, timestamp |-> yielded_clock40, reply_to |-> self]; - i := 0; - j := 0; - goto putBroadcast; - }; + with (yielded_clientId60 = (self) - ((NUM_CLIENTS) * (PUT_ORDER))) { + with (yielded_clientId50 = (self) - ((NUM_CLIENTS) * (PUT_ORDER))) { + clock := [clock EXCEPT ![yielded_clientId60] = ((clocks)[yielded_clientId50]) + (1)]; + with (yielded_clientId80 = (self) - ((NUM_CLIENTS) * (PUT_ORDER))) { + with (yielded_clientId70 = (self) - ((NUM_CLIENTS) * (PUT_ORDER))) { + putReq := [op |-> PUT_MSG, key |-> key, value |-> value, client |-> yielded_clientId80, timestamp |-> (clocks)[yielded_clientId70], reply_to |-> self]; + i := 0; + j := 0; + goto putBroadcast; }; }; }; @@ -902,11 +900,11 @@ NullSet == (NUM_REPLICAS+3*NUM_CLIENTS)..(NUM_REPLICAS+4*NUM_CLIENTS-1) }; }; putBroadcast: - with (yielded_clock6 = (clocks)[clientId]) { - if(((j) <= ((NUM_REPLICAS) - (1))) /\ ((yielded_clock6) # (- (1)))) { - with (value60 = putReq) { + with (yielded_clientId10 = (self) - ((NUM_CLIENTS) * (PUT_ORDER))) { + if(((j) <= ((NUM_REPLICAS) - (1))) /\ (((clocks)[yielded_clientId10]) # (- (1)))) { + with (value40 = putReq) { await (Len((replicasNetwork)[j])) < (BUFFER_SIZE); - replicasNetwork := [replicasNetwork EXCEPT ![j] = Append((replicasNetwork)[j], value60)]; + replicasNetwork := [replicasNetwork EXCEPT ![j] = Append((replicasNetwork)[j], value40)]; j := (j) + (1); goto putBroadcast; }; @@ -916,14 +914,14 @@ NullSet == (NUM_REPLICAS+3*NUM_CLIENTS)..(NUM_REPLICAS+4*NUM_CLIENTS-1) }; putResponse: if((i) < (Cardinality(ReplicaSet))) { - with (yielded_clock7 = (clocks)[clientId]) { - if((yielded_clock7) = (- (1))) { + with (yielded_clientId11 = (self) - ((NUM_CLIENTS) * (PUT_ORDER))) { + if(((clocks)[yielded_clientId11]) = (- (1))) { continue := FALSE; goto putLoop; } else { - await (Len((clients)[self])) > (0); - with (msg2 = Head((clients)[self])) { - clients := [clients EXCEPT ![self] = Tail((clients)[self])]; + await (Len((clientMailboxes)[self])) > (0); + with (msg2 = Head((clientMailboxes)[self])) { + clientMailboxes := [clientMailboxes EXCEPT ![self] = Tail((clientMailboxes)[self])]; with (yielded_clients00 = msg2) { putResp := yielded_clients00; assert ((putResp).type) = (PUT_RESPONSE); @@ -949,63 +947,63 @@ NullSet == (NUM_REPLICAS+3*NUM_CLIENTS)..(NUM_REPLICAS+4*NUM_CLIENTS-1) } fair process (DisconnectClient \in DisconnectSet) - variables msg; j; clientId = cid; + variables msg; j; { sendDisconnectRequest: - with (yielded_clientId30 = (self) - ((NUM_CLIENTS) * (DISCONNECT_ORDER))) { - msg := [op |-> DISCONNECT_MSG, client |-> yielded_clientId30]; - with (yielded_clientId40 = (self) - ((NUM_CLIENTS) * (DISCONNECT_ORDER))) { - with (value70 = - (1)) { - clocks := [clocks EXCEPT ![yielded_clientId40] = value70]; - j := 0; - goto disconnectBroadcast; - }; + with (yielded_clientId120 = (self) - ((NUM_CLIENTS) * (DISCONNECT_ORDER))) { + msg := [op |-> DISCONNECT_MSG, client |-> yielded_clientId120]; + with (yielded_clientId130 = (self) - ((NUM_CLIENTS) * (DISCONNECT_ORDER))) { + clock := [clock EXCEPT ![yielded_clientId130] = - (1)]; + j := 0; + goto disconnectBroadcast; }; }; disconnectBroadcast: if(((j) <= ((NUM_REPLICAS) - (1))) /\ ((0) # (- (1)))) { - with (value80 = msg) { + with (value50 = msg) { await (Len((replicasNetwork)[j])) < (BUFFER_SIZE); - replicasNetwork := [replicasNetwork EXCEPT ![j] = Append((replicasNetwork)[j], value80)]; + replicasNetwork := [replicasNetwork EXCEPT ![j] = Append((replicasNetwork)[j], value50)]; j := (j) + (1); goto disconnectBroadcast; }; + } else { + goto Done; }; } fair process (ClockUpdateClient \in NullSet) - variables continue = TRUE; j; msg; clientId = cid; spin = TRUE; + variables continue = TRUE; j; msg; spin = TRUE; { clockUpdateLoop: if(continue) { - with (yielded_clock10 = (clocks)[clientId]) { - if((yielded_clock10) = (- (1))) { + with (yielded_clientId18 = (self) - ((NUM_CLIENTS) * (NULL_ORDER))) { + if(((clocks)[yielded_clientId18]) = (- (1))) { continue := FALSE; goto nullCheckSpin; } else { - with (yielded_clientId50 = (self) - ((NUM_CLIENTS) * (NULL_ORDER))) { - with (yielded_clock80 = (clocks)[clientId]) { - with (value90 = (yielded_clock80) + (1)) { - clocks := [clocks EXCEPT ![yielded_clientId50] = value90]; - with (yielded_clientId60 = (self) - ((NUM_CLIENTS) * (NULL_ORDER))) { - with (yielded_clock90 = (clocks)[clientId]) { - msg := [op |-> NULL_MSG, client |-> yielded_clientId60, timestamp |-> yielded_clock90]; - j := 0; - goto nullBroadcast; - }; + with (yielded_clientId150 = (self) - ((NUM_CLIENTS) * (NULL_ORDER))) { + with (yielded_clientId140 = (self) - ((NUM_CLIENTS) * (NULL_ORDER))) { + clock := [clock EXCEPT ![yielded_clientId150] = ((clocks)[yielded_clientId140]) + (1)]; + with (yielded_clientId170 = (self) - ((NUM_CLIENTS) * (NULL_ORDER))) { + with (yielded_clientId160 = (self) - ((NUM_CLIENTS) * (NULL_ORDER))) { + msg := [op |-> NULL_MSG, client |-> yielded_clientId170, timestamp |-> (clocks)[yielded_clientId160]]; + j := 0; + goto nullBroadcast; }; }; }; }; }; }; + } else { + goto Done; }; nullBroadcast: - with (yielded_clock11 = (clocks)[clientId]) { - if(((j) <= ((NUM_REPLICAS) - (1))) /\ ((yielded_clock11) # (- (1)))) { - with (value100 = msg) { + with (yielded_clientId19 = (self) - ((NUM_CLIENTS) * (NULL_ORDER))) { + if(((j) <= ((NUM_REPLICAS) - (1))) /\ (((clocks)[yielded_clientId19]) # (- (1)))) { + with (value60 = msg) { await (Len((replicasNetwork)[j])) < (BUFFER_SIZE); - replicasNetwork := [replicasNetwork EXCEPT ![j] = Append((replicasNetwork)[j], value100)]; + replicasNetwork := [replicasNetwork EXCEPT ![j] = Append((replicasNetwork)[j], value60)]; j := (j) + (1); goto nullBroadcast; }; diff --git a/test/pgo/TLAExpressionFuzzTests.scala b/test/pgo/TLAExpressionFuzzTests.scala new file mode 100644 index 000000000..2f0369d46 --- /dev/null +++ b/test/pgo/TLAExpressionFuzzTests.scala @@ -0,0 +1,224 @@ +package pgo + +import org.scalacheck.{Arbitrary, Gen, Prop} +import org.scalatest.funsuite.AnyFunSuite +import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks +import pgo.model.Definition.ScopeIdentifierName +import pgo.model.tla._ +import pgo.trans.PCalRenderPass +import pgo.util.Description._ +import pgo.util.TLAExprInterpreter + +import scala.collection.mutable + +class TLAExpressionFuzzTests extends AnyFunSuite with ScalaCheckPropertyChecks { + implicit override val generatorDrivenConfig: PropertyCheckConfiguration = + PropertyCheckConfiguration(workers = 1, minSuccessful = 100, maxDiscardedFactor = 10) + + test("TLA+ compiled to Go code behaves like the built-in interpreter (true random ASTs)") { + val workDir = os.temp.dir() + val testFile = workDir / "TestBed.tla" + val outFile = workDir / "testbed.go" + var degenerateCases = 0 + var cases = 0 + + val modFile = workDir / "go.mod" + os.write(modFile, + s"""module example.org/testbed + | + |go 1.14 + | + |replace github.com/UBC-NSS/pgo/distsys => ${os.pwd / "distsys"} + | + |require github.com/UBC-NSS/pgo/distsys v0.0.0-00010101000000-000000000000 + |""".stripMargin) + + val mainFile = workDir / "main" / "main.go" + os.makeDir(workDir / "main") + os.write(mainFile, + s"""package main + | + |import "github.com/UBC-NSS/pgo/distsys" + |import "example.org/testbed" + | + |type dummyDurableStorage struct{} + | + |var _ distsys.MPCalDurableStorage = &dummyDurableStorage{} + | + |func (d dummyDurableStorage) RecoverResources() (rec *distsys.MPCalDurableStorageRecord, err error) { + | return nil, nil + |} + | + |func (d dummyDurableStorage) SnapshotResources(rec *distsys.MPCalDurableStorageRecord) { + | // pass + |} + | + |func main() { + | ctx, err := distsys.NewMPCalContext(&dummyDurableStorage{}) + | if err != nil { + | panic(err) + | } + | err = testbed.TestBed(ctx, distsys.NewTLAString("self"), testbed.Constants{}) + | if err != nil { + | panic(err) + | } + |}""".stripMargin) + + try { + forAll(trueRandomExprGen) { (expr: TLAExpression) => + val mpcalSetup = + d"----MODULE TestBed----\n" + + d"EXTENDS Integers, Sequences, TLC, FiniteSets\n" + + d"(* --mpcal TestBed {\n" + + d"archetype TestBed() {\n" + + d"lbl: print ${PCalRenderPass.describeExpr(expr)};\n".indented + + d"} } *)\n" + + d"\\* BEGIN TRANSLATION\n" + + d"====" + + val (shouldSkip, expectedBehaviour) = try { + (false, Right(TLAExprInterpreter.interpret(expr)(env = Map.empty))) + } catch { + case err@TLAExprInterpreter.Unsupported() => + (true, Left(err)) + case err@TLAExprInterpreter.TypeError() => + (false, Left(err)) + } + whenever(!shouldSkip) { + cases += 1 + Prop.classify(expectedBehaviour match { + case Left(_) => degenerateCases += 1; true + case Right(_) => false + }, "degenerate", "correct") { + os.write.over(testFile, data = mpcalSetup.linesIterator.map(line => s"$line\n")) + + val errs = PGo.run(Seq("gogen", "-s", testFile.toString(), "-o", outFile.toString())) + assert(errs == Nil) + + def somethingBadHappened(): Unit = { + os.makeDir.all(os.pwd / "fuzz_output") + val testOut = os.temp.dir(dir = os.pwd / "fuzz_output", deleteOnExit = false) + println(s"something bad happened. saving test to $testOut") + os.copy.over(from = workDir, to = testOut) + } + + os.proc("go", "mod", "download").call(cwd = workDir) + + try { + os.proc("go", "run", "./main").call(cwd = workDir, mergeErrIntoOut = true, timeout = 15000) + Prop.passed + } catch { + case err: os.SubprocessException => + expectedBehaviour match { + case Left(_) => + if (err.result.out.text().startsWith("panic: TLA+ type error")) { + // that's ok then + Prop.passed + } else { + somethingBadHappened() + throw err + } + case Right(_) => + somethingBadHappened() + throw err + } + } + } + } + } + } finally { + println(s"degenerate cases: $degenerateCases/$cases; ${degenerateCases.toDouble / cases.toDouble * 100}%") + } + } + + lazy val trueRandomExprGen: Gen[TLAExpression] = locally { + val cache = mutable.WeakHashMap[Int,Gen[TLAExpression]]() + + val zeroSizePrimitiveSyntax: List[Gen[TLAExpression]] = + List( + Gen.posNum[Int].map(i => TLANumber(TLANumber.IntValue(i), TLANumber.DecimalSyntax)), + Gen.identifier.map(TLAString), + ) + + def sizedVariadics(sz: Int): List[Gen[TLAExpression]] = { + val maxWidth = Integer.max(sz - 1, 0) + def subArity(opWidth: Int): Int = + if(opWidth == 0) maxWidth else maxWidth / opWidth + + (for { + ident <- Gen.identifier + sub <- sizedAST(maxWidth) + } yield TLADot(sub, TLAIdentifier(ident))) :: + (if(maxWidth >= 3) { + List(Gen.listOfN(3, sizedAST(subArity(3))).map { + case List(cond, tval, fval) => + TLAIf(cond, tval, fval) + }) + } else Nil) ::: // TODO: TLACase on + (Gen.oneOf(0 to maxWidth).flatMap { elemCount => + Gen.listOfN(elemCount, sizedAST(subArity(elemCount))) + .map(TLASetConstructor) + }) :: // TODO: TLASetRefinement on + (Gen.oneOf(0 to maxWidth).flatMap { elemCount => + Gen.listOfN(elemCount, sizedAST(subArity(elemCount))) + .map(TLATuple) + }) :: + (if(maxWidth >= 1) { + List(Gen.oneOf(1 to maxWidth).flatMap { elemCount => + for { + elems <- Gen.listOfN(elemCount, sizedAST(subArity(elemCount))) + names <- Gen.listOfN(elemCount, Gen.identifier) + } yield TLARecordConstructor((names zip elems).map { + case (name, elem) => TLARecordConstructorField(TLAIdentifier(name), elem) + }) + }) + } else Nil) ::: + (if(maxWidth >= 1) { + List(Gen.oneOf(1 to maxWidth).flatMap { elemCount => + for { + elems <- Gen.listOfN(elemCount, sizedAST(subArity(elemCount))) + names <- Gen.listOfN(elemCount, Gen.identifier) + } yield TLARecordSet((names zip elems).map { + case (name, elem) => TLARecordSetField(TLAIdentifier(name), elem) + }) + }) + } else Nil) ::: + BuiltinModules.builtinModules.values.view + .filter { mod => + (mod ne BuiltinModules.Reals) && + (mod ne BuiltinModules.Bags) && + (mod ne BuiltinModules.TLC) && + (mod ne BuiltinModules.Peano) && + (mod ne BuiltinModules.ProtoReals) + } + .flatMap(_.members) + .filter(_.arity <= maxWidth) + .map { op => + Gen.listOfN(op.arity, sizedAST(subArity(op.arity))).map { exprs => + if(op.arity == 0) { + TLAGeneralIdentifier(op.identifier.asInstanceOf[ScopeIdentifierName].name, Nil) + .setRefersTo(op) + } else { + TLAOperatorCall(op.identifier, Nil, exprs) + .setRefersTo(op) + } + } + }.toList + } + + def sizedAST(sz: Int): Gen[TLAExpression] = { + Gen.lzy { + cache.getOrElseUpdate(if (sz <= 0) 0 else sz, { + val elems: List[Gen[TLAExpression]] = + (if (sz <= 0) zeroSizePrimitiveSyntax else Nil) ::: + sizedVariadics(sz) + + Gen.oneOf(elems.head, elems.tail.head, elems.tail.tail: _*) + }) + } + } + + Gen.sized(sizedAST) + } + +} From 48014b4d996ee81d742500b41200effb655b03ce Mon Sep 17 00:00:00 2001 From: fhackett Date: Fri, 9 Jul 2021 11:24:43 -0700 Subject: [PATCH 13/27] WIP: reworking fuzz testing process --- distsys/tlaplus.go | 53 +++++- src/pgo/model/tla/AST.scala | 4 +- src/pgo/parser/TLAParser.scala | 5 +- src/pgo/trans/MPCalGoCodegenPass.scala | 4 +- src/pgo/trans/PCalRenderPass.scala | 2 + src/pgo/util/TLAExprInterpreter.scala | 11 +- test/pgo/TLAExpressionFuzzTests.scala | 234 ++++++++++++++++--------- 7 files changed, 214 insertions(+), 99 deletions(-) diff --git a/distsys/tlaplus.go b/distsys/tlaplus.go index e1d238403..8903fd740 100644 --- a/distsys/tlaplus.go +++ b/distsys/tlaplus.go @@ -663,7 +663,44 @@ func (v *tlaValueTuple) GobDecode(input []byte) error { } func TLA_Seq(v TLAValue) TLAValue { - panic("implement me") + set := v.AsSet() + // move all the elements onto a slice for easier handling + var elems []TLAValue + it := set.Iterator() + for !it.Done() { + elem, _ := it.Next() + elems = append(elems, elem.(TLAValue)) + } + + // prepare to build a set of tuples + builder := immutable.NewMapBuilder(TLAValueHasher{}) + + // skip for k = 0, which is not handles but also needs no work + if len(elems) != 0 { + // generate permutations using Heap's algorithm + var generatePermutations func(k int) + generatePermutations = func(k int) { + if k == 1 { + // store a new tuple in the set + builder.Set(NewTLATuple(elems...), true) + } else { + generatePermutations(k - 1) + + for i := 0; i < k-1; i += 1 { + if k%2 == 0 { + elems[i], elems[k-1] = elems[k-1], elems[i] + } else { + elems[0], elems[k-1] = elems[k-1], elems[0] + } + generatePermutations(k - 1) + } + } + } + + generatePermutations(len(elems)) + } + + return TLAValue{&tlaValueSet{builder.Map()}} } func TLA_Len(v TLAValue) TLAValue { @@ -762,6 +799,20 @@ func NewTLARecordSet(pairs []TLARecordField) TLAValue { return TLAValue{&tlaValueSet{recordSet}} } +func NewTLAFunctionSet(from, to TLAValue) TLAValue { + fromSet, _ := from.AsSet(), to.AsSet() + var pairs []TLARecordField + it := fromSet.Iterator() + for !it.Done() { + key, _ := it.Next() + pairs = append(pairs, TLARecordField{ + Key: key.(TLAValue), + Value: to, + }) + } + return NewTLARecordSet(pairs) +} + func (v *tlaValueFunction) Hash() uint32 { var hash uint32 it := v.Iterator() diff --git a/src/pgo/model/tla/AST.scala b/src/pgo/model/tla/AST.scala index e0a7c32c9..e072d65f5 100644 --- a/src/pgo/model/tla/AST.scala +++ b/src/pgo/model/tla/AST.scala @@ -360,7 +360,9 @@ final case class TLAIf(cond: TLAExpression, tval: TLAExpression, fval: TLAExpres final case class TLALet(defs: List[TLAUnit], body: TLAExpression) extends TLAExpression -final case class TLACase(arms: List[TLACaseArm], other: Option[TLAExpression]) extends TLAExpression +final case class TLACase(arms: List[TLACaseArm], other: Option[TLAExpression]) extends TLAExpression { + require(arms.nonEmpty) +} final case class TLACaseArm(cond: TLAExpression, result: TLAExpression) extends TLANode diff --git a/src/pgo/parser/TLAParser.scala b/src/pgo/parser/TLAParser.scala index 98021c954..d579d2048 100644 --- a/src/pgo/parser/TLAParser.scala +++ b/src/pgo/parser/TLAParser.scala @@ -78,8 +78,9 @@ trait TLAParser extends RegexParsers { val tlaString : Parser[String] = elem('\"') ~> (rep[Char] { (elem('\\') ~>! { - elem('\"') | elem('\\') | ("t" ^^^ '\t') | ("n" ^^^ '\n') | ("f" ^^^ '\f') | ("r" ^^^ '\r') - }.withFailureMessage("expected valid string escape: one of \\\", \\t, \\n, \\f, or \\r")) | + elem('\"') | elem('\\') | ("t" ^^^ '\t') | ("n" ^^^ '\n') | ("f" ^^^ '\f') | ("r" ^^^ '\r') | + elem(')') | elem('*') + }.withFailureMessage("expected valid string escape: one of \\\", \\t, \\n, \\f, \\r, \\*, or \\)")) | acceptMatch("string contents", { case c if c != '\"' => c }) } ^^ { parts => parts.mkString("") }) <~ elem('\"') diff --git a/src/pgo/trans/MPCalGoCodegenPass.scala b/src/pgo/trans/MPCalGoCodegenPass.scala index 3a5e77dc4..a9189ea91 100644 --- a/src/pgo/trans/MPCalGoCodegenPass.scala +++ b/src/pgo/trans/MPCalGoCodegenPass.scala @@ -538,13 +538,13 @@ object MPCalGoCodegenPass { case (TLAQuantifierBound(TLAQuantifierBound.TupleType, elements, _), idx) => elements.view.zipWithIndex.map { case (element, elemIdx) => - d"\nvar ${argIds(element)} $TLAValue = $argsName[$idx].FunctionApply(distsys.NewTLANumber($elemIdx))" + d"\nvar ${argIds(element)} $TLAValue = $argsName[$idx].ApplyFunction(distsys.NewTLANumber($elemIdx))" } }.flattenDescriptions + d"\nreturn ${translateExpr(body)}").indented }\n})" } case TLAFunctionCall(function, params) => - d"${translateExpr(function)}.FunctionApply(${ + d"${translateExpr(function)}.ApplyFunction(${ if(params.size == 1) { translateExpr(params.head) } else { diff --git a/src/pgo/trans/PCalRenderPass.scala b/src/pgo/trans/PCalRenderPass.scala index d6ff5eda4..4cb6f0d91 100644 --- a/src/pgo/trans/PCalRenderPass.scala +++ b/src/pgo/trans/PCalRenderPass.scala @@ -39,6 +39,8 @@ object PCalRenderPass { case '\n' => "\\n" case '\f' => "\\f" case '\r' => "\\r" + case ')' => "\\)" // these last two are extras, to allow writing (* and *) in MPCal comments + case '*' => "\\*" case ch => ch.toString } }"""" diff --git a/src/pgo/util/TLAExprInterpreter.scala b/src/pgo/util/TLAExprInterpreter.scala index 1ef39a556..2b80efac8 100644 --- a/src/pgo/util/TLAExprInterpreter.scala +++ b/src/pgo/util/TLAExprInterpreter.scala @@ -107,7 +107,10 @@ object TLAExprInterpreter { BuiltinModules.TLC.memberAlpha("Permutations") -> { _ => throw Unsupported() }, BuiltinModules.TLC.memberAlpha("SortSeq") -> { _ => throw Unsupported() }, - BuiltinModules.Sequences.memberAlpha("Seq") -> { _ => throw Unsupported() }, + BuiltinModules.Sequences.memberAlpha("Seq") -> { + case List(TLAValueSet(elems)) => + TLAValueSet(elems.toVector.permutations.map(TLAValueTuple).toSet) + }, BuiltinModules.Sequences.memberAlpha("Len") -> { case List(TLAValueTuple(elems)) => TLAValueNumber(elems.size) }, @@ -134,11 +137,7 @@ object TLAExprInterpreter { BuiltinModules.Sequences.memberAlpha("SelectSeq") -> { _ => throw Unsupported() }, BuiltinModules.FiniteSets.memberAlpha("IsFiniteSet") -> { - case List(candidate) => - candidate match { - case TLAValueSet(_) => TLAValueBool(true) - case _ => TLAValueBool(false) - } + case List(TLAValueSet(_)) => TLAValueBool(true) }, BuiltinModules.FiniteSets.memberAlpha("Cardinality") -> { case List(TLAValueSet(set)) => TLAValueNumber(set.size) diff --git a/test/pgo/TLAExpressionFuzzTests.scala b/test/pgo/TLAExpressionFuzzTests.scala index 2f0369d46..f1d6db64d 100644 --- a/test/pgo/TLAExpressionFuzzTests.scala +++ b/test/pgo/TLAExpressionFuzzTests.scala @@ -4,12 +4,16 @@ import org.scalacheck.{Arbitrary, Gen, Prop} import org.scalatest.funsuite.AnyFunSuite import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks import pgo.model.Definition.ScopeIdentifierName +import pgo.model.DefinitionOne import pgo.model.tla._ import pgo.trans.PCalRenderPass import pgo.util.Description._ -import pgo.util.TLAExprInterpreter +import pgo.util.{IdMap, IdSet, TLAExprInterpreter} +import pgo.util.TLAExprInterpreter.{TLAValue, TLAValueBool, TLAValueFunction, TLAValueNumber, TLAValueSet, TLAValueString, TLAValueTuple, builtinOperators} +import scala.annotation.tailrec import scala.collection.mutable +import scala.util.control.NonFatal class TLAExpressionFuzzTests extends AnyFunSuite with ScalaCheckPropertyChecks { implicit override val generatorDrivenConfig: PropertyCheckConfiguration = @@ -92,9 +96,6 @@ class TLAExpressionFuzzTests extends AnyFunSuite with ScalaCheckPropertyChecks { }, "degenerate", "correct") { os.write.over(testFile, data = mpcalSetup.linesIterator.map(line => s"$line\n")) - val errs = PGo.run(Seq("gogen", "-s", testFile.toString(), "-o", outFile.toString())) - assert(errs == Nil) - def somethingBadHappened(): Unit = { os.makeDir.all(os.pwd / "fuzz_output") val testOut = os.temp.dir(dir = os.pwd / "fuzz_output", deleteOnExit = false) @@ -102,6 +103,15 @@ class TLAExpressionFuzzTests extends AnyFunSuite with ScalaCheckPropertyChecks { os.copy.over(from = workDir, to = testOut) } + try { + val errs = PGo.run(Seq("gogen", "-s", testFile.toString(), "-o", outFile.toString())) + assert(errs == Nil) + } catch { + case NonFatal(err) => + somethingBadHappened() + throw err + } + os.proc("go", "mod", "download").call(cwd = workDir) try { @@ -131,94 +141,144 @@ class TLAExpressionFuzzTests extends AnyFunSuite with ScalaCheckPropertyChecks { } } - lazy val trueRandomExprGen: Gen[TLAExpression] = locally { - val cache = mutable.WeakHashMap[Int,Gen[TLAExpression]]() - - val zeroSizePrimitiveSyntax: List[Gen[TLAExpression]] = - List( - Gen.posNum[Int].map(i => TLANumber(TLANumber.IntValue(i), TLANumber.DecimalSyntax)), - Gen.identifier.map(TLAString), - ) - - def sizedVariadics(sz: Int): List[Gen[TLAExpression]] = { - val maxWidth = Integer.max(sz - 1, 0) - def subArity(opWidth: Int): Int = - if(opWidth == 0) maxWidth else maxWidth / opWidth - - (for { - ident <- Gen.identifier - sub <- sizedAST(maxWidth) - } yield TLADot(sub, TLAIdentifier(ident))) :: - (if(maxWidth >= 3) { - List(Gen.listOfN(3, sizedAST(subArity(3))).map { - case List(cond, tval, fval) => - TLAIf(cond, tval, fval) - }) - } else Nil) ::: // TODO: TLACase on - (Gen.oneOf(0 to maxWidth).flatMap { elemCount => - Gen.listOfN(elemCount, sizedAST(subArity(elemCount))) - .map(TLASetConstructor) - }) :: // TODO: TLASetRefinement on - (Gen.oneOf(0 to maxWidth).flatMap { elemCount => - Gen.listOfN(elemCount, sizedAST(subArity(elemCount))) - .map(TLATuple) - }) :: - (if(maxWidth >= 1) { - List(Gen.oneOf(1 to maxWidth).flatMap { elemCount => - for { - elems <- Gen.listOfN(elemCount, sizedAST(subArity(elemCount))) - names <- Gen.listOfN(elemCount, Gen.identifier) - } yield TLARecordConstructor((names zip elems).map { - case (name, elem) => TLARecordConstructorField(TLAIdentifier(name), elem) - }) - }) - } else Nil) ::: - (if(maxWidth >= 1) { - List(Gen.oneOf(1 to maxWidth).flatMap { elemCount => - for { - elems <- Gen.listOfN(elemCount, sizedAST(subArity(elemCount))) - names <- Gen.listOfN(elemCount, Gen.identifier) - } yield TLARecordSet((names zip elems).map { - case (name, elem) => TLARecordSetField(TLAIdentifier(name), elem) - }) - }) - } else Nil) ::: - BuiltinModules.builtinModules.values.view - .filter { mod => - (mod ne BuiltinModules.Reals) && - (mod ne BuiltinModules.Bags) && - (mod ne BuiltinModules.TLC) && - (mod ne BuiltinModules.Peano) && - (mod ne BuiltinModules.ProtoReals) - } - .flatMap(_.members) - .filter(_.arity <= maxWidth) - .map { op => - Gen.listOfN(op.arity, sizedAST(subArity(op.arity))).map { exprs => - if(op.arity == 0) { - TLAGeneralIdentifier(op.identifier.asInstanceOf[ScopeIdentifierName].name, Nil) - .setRefersTo(op) - } else { - TLAOperatorCall(op.identifier, Nil, exprs) - .setRefersTo(op) - } - } - }.toList + private def genCombinedASTNodePossibilities(subExprs: List[TLAExpression])(implicit env: IdSet[DefinitionOne], anchorOpt: Option[TLAFunctionSubstitutionPairAnchor]): List[Gen[TLAExpression]] = { + sealed abstract class GenProvider { + def genIterator: Iterator[Gen[TLAExpression]] + } + + implicit class PartialFnGenProvider(iterable: Iterable[Gen[TLAExpression]]) extends GenProvider { + override def genIterator: Iterator[Gen[TLAExpression]] = iterable.iterator } - def sizedAST(sz: Int): Gen[TLAExpression] = { - Gen.lzy { - cache.getOrElseUpdate(if (sz <= 0) 0 else sz, { - val elems: List[Gen[TLAExpression]] = - (if (sz <= 0) zeroSizePrimitiveSyntax else Nil) ::: - sizedVariadics(sz) + implicit class PartialFnIterableGenProvider(gen: Gen[TLAExpression]) extends GenProvider { + override def genIterator: Iterator[Gen[TLAExpression]] = Iterator.single(gen) + } - Gen.oneOf(elems.head, elems.tail.head, elems.tail.tail: _*) - }) - } + val builtinModules = BuiltinModules.builtinModules.values.filter { mod => + (mod ne BuiltinModules.Reals) && + (mod ne BuiltinModules.Bags) && + (mod ne BuiltinModules.TLC) && + (mod ne BuiltinModules.Peano) && + (mod ne BuiltinModules.ProtoReals) } - Gen.sized(sizedAST) + val cases: Iterator[PartialFunction[List[TLAExpression],GenProvider]] = Iterator( + { case Nil => for { + num <- Gen.posNum[Int] + } yield TLANumber(TLANumber.IntValue(num), TLANumber.DecimalSyntax) + }, + { case Nil => Gen.asciiPrintableStr.map(TLAString) }, // TODO: consider nonsense w/ unprintable ASCII + { case Nil if env.exists(_.arity == 0) => + env.view + .filter(_.arity == 0) + .map { defn => + TLAGeneralIdentifier(defn.identifier.asInstanceOf[ScopeIdentifierName].name, Nil) + .setRefersTo(defn) + } : Iterable[Gen[TLAExpression]] + }, + { case Nil => + builtinModules.view + .flatMap(_.members) + .filter(_.arity == 0) + .map { defn => + TLAGeneralIdentifier(defn.identifier.asInstanceOf[ScopeIdentifierName].name, Nil) + .setRefersTo(defn) + } : Iterable[Gen[TLAExpression]] + }, + { case List(expr: TLAExpression) => + for { + ident <- Gen.identifier + } yield TLADot(expr, TLAIdentifier(ident)) + }, + { case subExprs: List[TLAExpression] if subExprs.nonEmpty && env.exists(_.arity == subExprs.size) => + env.view.filter(_.arity == subExprs.size).map { defn => + Gen.const(TLAOperatorCall(defn.identifier, Nil, subExprs).setRefersTo(defn)) + } + }, + { case subExprs: List[TLAExpression] if subExprs.nonEmpty => + builtinModules.view + .flatMap(_.members) + .filter(_.arity == subExprs.size) + .map { defn => + TLAOperatorCall(defn.identifier, Nil, subExprs) + .setRefersTo(defn) + } : Iterable[Gen[TLAExpression]] + }, + { case List(cond: TLAExpression, yes: TLAExpression, no: TLAExpression) => + Gen.const(TLAIf(cond, yes, no)) + }, + // LET exprs skipped on purpose; we need to understand scoping to get those right, so we leave it to other routines + { case subExprs: List[TLAExpression] if subExprs.size >= 2 => // require at least one whole case arm's worth + @tailrec + def impl(subExprs: List[TLAExpression], armsAcc: List[TLACaseArm]): TLACase = + subExprs match { + case Nil => TLACase(armsAcc, None) + case other :: Nil => TLACase(armsAcc, Some(other)) + case cond :: result :: restArms => + impl(restArms, TLACaseArm(cond, result) :: armsAcc) + } + + Gen.const(impl(subExprs, Nil)) + }, + // skipping function defn for same reason as LET + { case subExprs: List[TLAExpression] if subExprs.size >= 2 => + Gen.const(TLAFunctionCall(subExprs.head, subExprs.tail)) + }, + { case List(from: TLAExpression, to: TLAExpression) => + Gen.const(TLAFunctionSet(from, to)) + }, + // TODO: skipping function substitution because complicated + { case Nil if anchorOpt.nonEmpty => + Gen.const(TLAFunctionSubstitutionAt() + .setRefersTo(anchorOpt.get)) + }, + // skipping quantifiers, again due to scoping + { case subExprs: List[TLAExpression] => + Gen.const(TLASetConstructor(subExprs)) + }, + // skipping set refinement, comprehension due to scoping + { case subExprs: List[TLAExpression] => + Gen.const(TLATuple(subExprs)) + }, + { case subExprs: List[TLAExpression] if subExprs.nonEmpty => + for { + idents <- Gen.listOfN(subExprs.size, Gen.identifier) + } yield TLARecordConstructor((idents.view zip subExprs).map { + case ident -> expr => TLARecordConstructorField(TLAIdentifier(ident), expr) + }.toList) + }, + { case subExprs: List[TLAExpression] if subExprs.nonEmpty => + for { + idents <- Gen.listOfN(subExprs.size, Gen.identifier) + } yield TLARecordSet((idents.view zip subExprs).map { + case ident -> expr => TLARecordSetField(TLAIdentifier(ident), expr) + }.toList) + }, + ) + + cases.flatMap { fn => + fn.unapply(subExprs) + .map(_.genIterator) + } + .flatten + .toList + } + + private def forceOneOf[T](gens: List[Gen[T]]): Gen[T] = { + require(gens.nonEmpty) + Gen.choose(min = 0, max = gens.size - 1) + .flatMap(gens) + } + + lazy val trueRandomExprGen: Gen[TLAExpression] = { + def impl(size: Int)(implicit env: IdSet[DefinitionOne], anchorOpt: Option[TLAFunctionSubstitutionPairAnchor]): Gen[TLAExpression] = + for { + breadth <- Gen.oneOf(0 to size) + subExprs <- Gen.listOfN(breadth, impl(size / (breadth + 1))) + expr <- forceOneOf(genCombinedASTNodePossibilities(subExprs)) + } yield expr + + Gen.sized(size => impl(size)(IdSet.empty, None)) } } From 57167a13bb77f58872b5adc62fc579c84f99c268 Mon Sep 17 00:00:00 2001 From: fhackett Date: Sat, 10 Jul 2021 01:49:26 -0700 Subject: [PATCH 14/27] WIP: AST coverage almost complete for fuzz testing; more bugs fixed --- distsys/tlaplus.go | 141 ++++++++++- distsys/tlaplus_test.go | 40 +++ src/pgo/model/tla/BuiltinModules.scala | 4 +- src/pgo/parser/TLAParser.scala | 6 +- src/pgo/trans/MPCalGoCodegenPass.scala | 230 ++++++++++++------ src/pgo/util/TLAExprInterpreter.scala | 193 +++++++-------- .../general/dqueue.tla.gotests/dqueue.go | 2 +- .../load_balancer.go | 7 +- test/pgo/TLAExpressionFuzzTests.scala | 104 +++++++- 9 files changed, 536 insertions(+), 191 deletions(-) create mode 100644 distsys/tlaplus_test.go diff --git a/distsys/tlaplus.go b/distsys/tlaplus.go index 8903fd740..bd58507b1 100644 --- a/distsys/tlaplus.go +++ b/distsys/tlaplus.go @@ -461,6 +461,102 @@ func (v *tlaValueSet) GobDecode(input []byte) error { } } +func TLAQuantifiedUniversal(setVals []TLAValue, pred func([]TLAValue) bool) TLAValue { + var sets []*immutable.Map + for _, val := range setVals { + sets = append(sets, val.AsSet()) + } + + predArgs := make([]TLAValue, len(sets)) + + var helper func(idx int) bool + helper = func(idx int) bool { + if idx == len(sets) { + return pred(predArgs) + } + + it := sets[idx].Iterator() + for !it.Done() { + elem, _ := it.Next() + predArgs[idx] = elem.(TLAValue) + if !helper(idx + 1) { + return false + } + } + return true + } + + return NewTLABool(helper(0)) +} + +func TLAQuantifiedExistential(setVals []TLAValue, pred func([]TLAValue) bool) TLAValue { + var sets []*immutable.Map + for _, val := range setVals { + sets = append(sets, val.AsSet()) + } + + predArgs := make([]TLAValue, len(sets)) + + var helper func(idx int) bool + helper = func(idx int) bool { + if idx == len(sets) { + return pred(predArgs) + } + + it := sets[idx].Iterator() + for !it.Done() { + elem, _ := it.Next() + predArgs[idx] = elem.(TLAValue) + if helper(idx + 1) { + return true + } + } + return false + } + + return NewTLABool(helper(0)) +} + +func TLASetRefinement(setVal TLAValue, pred func(TLAValue) bool) TLAValue { + set := setVal.AsSet() + builder := immutable.NewMapBuilder(TLAValueHasher{}) + it := set.Iterator() + for !it.Done() { + elem, _ := it.Next() + if pred(elem.(TLAValue)) { + builder.Set(elem, true) + } + } + return TLAValue{&tlaValueSet{builder.Map()}} +} + +func TLASetComprehension(setVals []TLAValue, body func([]TLAValue) TLAValue) TLAValue { + var sets []*immutable.Map + for _, val := range setVals { + sets = append(sets, val.AsSet()) + } + + builder := immutable.NewMapBuilder(TLAValueHasher{}) + bodyArgs := make([]TLAValue, len(sets)) + + var helper func(idx int) + helper = func(idx int) { + if idx == len(sets) { + builder.Set(body(bodyArgs), true) + } else { + it := sets[idx].Iterator() + for !it.Done() { + elem, _ := it.Next() + bodyArgs[idx] = elem.(TLAValue) + helper(idx + 1) + } + } + } + + helper(0) + return TLAValue{&tlaValueSet{builder.Map()}} +} + func TLA_InSymbol(lhs, rhs TLAValue) TLAValue { set := rhs.AsSet() _, ok := set.Get(lhs) @@ -675,8 +771,10 @@ func TLA_Seq(v TLAValue) TLAValue { // prepare to build a set of tuples builder := immutable.NewMapBuilder(TLAValueHasher{}) - // skip for k = 0, which is not handles but also needs no work - if len(elems) != 0 { + // special-case the empty set, as the main process doesn't handle it + if len(elems) == 0 { + builder.Set(NewTLATuple(), true) + } else { // generate permutations using Heap's algorithm var generatePermutations func(k int) generatePermutations = func(k int) { @@ -768,6 +866,35 @@ func (field TLARecordField) Hash() uint32 { var _ tlaValueImpl = &tlaValueFunction{} +func NewTLAFunction(setVals []TLAValue, body func([]TLAValue) TLAValue) TLAValue { + require(len(setVals) > 0, "the domain of a TLA+ function cannot be the product of no sets") + builder := immutable.NewMapBuilder(TLAValueHasher{}) + + var sets []*immutable.Map + for _, val := range setVals { + sets = append(sets, val.AsSet()) + } + + bodyArgs := make([]TLAValue, len(sets)) + + var helper func(idx int) + helper = func(idx int) { + if idx == len(bodyArgs) { + builder.Set(NewTLATuple(bodyArgs...), body(bodyArgs)) + } else { + it := sets[idx].Iterator() + for !it.Done() { + elem, _ := it.Next() + bodyArgs[idx] = elem.(TLAValue) + helper(idx + 1) + } + } + } + helper(0) + + return TLAValue{&tlaValueFunction{builder.Map()}} +} + func NewTLARecord(pairs []TLARecordField) TLAValue { builder := immutable.NewMapBuilder(TLAValueHasher{}) for _, pair := range pairs { @@ -846,7 +973,7 @@ func (v *tlaValueFunction) Equal(other TLAValue) bool { func (v *tlaValueFunction) String() string { builder := strings.Builder{} - builder.WriteString("[") + builder.WriteString("(") first := true it := v.Iterator() for !it.Done() { @@ -854,13 +981,15 @@ func (v *tlaValueFunction) String() string { if first { first = false } else { - builder.WriteString(", ") + builder.WriteString(" @@ ") } + builder.WriteString("(") builder.WriteString(key.(TLAValue).String()) - builder.WriteString(" |-> ") + builder.WriteString(") :> (") builder.WriteString(value.(TLAValue).String()) + builder.WriteString(")") } - builder.WriteString("]") + builder.WriteString(")") return builder.String() } diff --git a/distsys/tlaplus_test.go b/distsys/tlaplus_test.go new file mode 100644 index 000000000..e3571e86a --- /dev/null +++ b/distsys/tlaplus_test.go @@ -0,0 +1,40 @@ +package distsys + +import "testing" + +func TestTLAModel(t *testing.T) { + type Record struct { + Name string + Operation func() TLAValue + ExpectedResult string + } + + tests := []Record{ + { + Name: "Seq({})", + Operation: func() TLAValue { + return TLA_Seq(NewTLASet()) + }, + ExpectedResult: "{<<>>}", + }, + { + Name: "\\E foo \\in {} : TRUE", + Operation: func() TLAValue { + return TLAQuantifiedExistential([]TLAValue{NewTLASet()}, func([]TLAValue) bool { + return true + }) + }, + ExpectedResult: "FALSE", + }, + } + + for _, test := range tests { + t.Run(test.Name, func(t *testing.T) { + actualValue := test.Operation() + actualStr := actualValue.String() + if actualStr != test.ExpectedResult { + t.Errorf("result %s did not equal expected value %s", actualStr, test.ExpectedResult) + } + }) + } +} diff --git a/src/pgo/model/tla/BuiltinModules.scala b/src/pgo/model/tla/BuiltinModules.scala index cc4c83686..d9c926f74 100644 --- a/src/pgo/model/tla/BuiltinModules.scala +++ b/src/pgo/model/tla/BuiltinModules.scala @@ -97,8 +97,8 @@ object BuiltinModules { alphaOp("PrintT", 1) alphaOp("Assert", 2) alphaOp("JavaTime", 0) - alphaOp(":>", 2) - alphaOp("@@", 2) + symOp(TLASymbol.ColonGreaterThanSymbol) + symOp(TLASymbol.DoubleAtSignSymbol) alphaOp("Permutations", 1) alphaOp("SortSeq", 2) } diff --git a/src/pgo/parser/TLAParser.scala b/src/pgo/parser/TLAParser.scala index d579d2048..ea6206688 100644 --- a/src/pgo/parser/TLAParser.scala +++ b/src/pgo/parser/TLAParser.scala @@ -197,7 +197,9 @@ trait TLAParser extends RegexParsers { lateBindings.getOrElseUpdate(id, mutable.ArrayBuffer()) += ref.setRefersTo success(ref) case _ => - throw DefinitionLookupError(pfx, Definition.ScopeIdentifierName(id)) + // don't fail hard; it's possible that the prefix is empty and the identifier is an ambiguous + // prefix of some other piece of syntax; perhaps an OpDecl + failure(s"lookup failed for identifier ${pfx.map(_.id.id).mkString("!")}!$id") } case Some(defn) => if( defn.arity > 0 ) { @@ -354,7 +356,7 @@ trait TLAParser extends RegexParsers { }) }.flatMap { path => val anchor = TLAFunctionSubstitutionPairAnchor() // definition for the @ expression - implicit val ctx = origCtx.withFunctionSubstitutionPairAnchor(anchor) + implicit val ctx: TLAParserContext = origCtx.withFunctionSubstitutionPairAnchor(anchor) (wsChk ~> "=" ~> wsChk ~> tlaExpression) ^^ { value => TLAFunctionSubstitutionPair(anchor, path, value) } diff --git a/src/pgo/trans/MPCalGoCodegenPass.scala b/src/pgo/trans/MPCalGoCodegenPass.scala index a9189ea91..fbcd7547d 100644 --- a/src/pgo/trans/MPCalGoCodegenPass.scala +++ b/src/pgo/trans/MPCalGoCodegenPass.scala @@ -315,7 +315,7 @@ object MPCalGoCodegenPass { def ensureLocalResource(value: Description): Description = d"distsys.EnsureLocalArchetypeResource(${ctx.ctxName}.ResourceEnsurerPositional(), $value)" - d"\nfunc $callableName(${ctx.ctxName} *distsys.MPCalContext, ${ctx.selfName} $TLAValue, ${ctx.constantsName} ${ctx.constantsTypeName}${ + d"""\nfunc $callableName(${ctx.ctxName} *distsys.MPCalContext, ${ctx.selfName} $TLAValue, ${ctx.constantsName} ${ctx.constantsTypeName}${ params.view.map { case param@MPCalRefParam(_, _) => d", ${paramNames(param)} $ArchetypeResourceHandle" case param@MPCalValParam(_) => d", ${paramNames(param)} $TLAValue" @@ -331,21 +331,25 @@ object MPCalGoCodegenPass { }.flattenDescriptions + d"\nDoneLabelTag").indented }\n)" + - d"\n$programCounterResourceName := ${ensureLocalResource { - val firstLabel = labelBinds(body.head.asInstanceOf[PCalLabeledStatements].label.name) - d"distsys.NewTLANumber($firstLabel)" - }}" + + d"\n$programCounterResourceName := ${ + ensureLocalResource { + val firstLabel = labelBinds(body.head.asInstanceOf[PCalLabeledStatements].label.name) + d"distsys.NewTLANumber($firstLabel)" + } + }" + params.view.collect { case param: MPCalValParam => d"\n${paramLocalNames(param)} := ${ensureLocalResource(paramNames(param).toDescription)}" }.flattenDescriptions + - variables.view.map { - case decl@PCalVariableDeclarationEmpty(_) => - d"\n${varNames(decl)} := ${ensureLocalResource(d"$TLAValue{}")}" - case decl@PCalVariableDeclarationSet(_, set) => - d"\n${varNames(decl)} := ${ensureLocalResource(d"${translateExpr(set)}.SelectElement()")}" - case decl@PCalVariableDeclarationValue(_, value) => - d"\n${varNames(decl)} := ${ensureLocalResource(translateExpr(value))}" + variables.view.map { decl => + (decl match { + case PCalVariableDeclarationEmpty(_) => + d"\n${varNames(decl)} := ${ensureLocalResource(d"$TLAValue{}")}" + case PCalVariableDeclarationSet(_, set) => + d"\n${varNames(decl)} := ${ensureLocalResource(d"${translateExpr(set)}.SelectElement()")}" + case PCalVariableDeclarationValue(_, value) => + d"\n${varNames(decl)} := ${ensureLocalResource(translateExpr(value))}" + }) + d"\n_ = ${varNames(decl)}" // avoid any chance of the unused vars error }.flattenDescriptions + pcalEithers.map { either => d"\nvar ${fairnessCounterNames(either)} int = 0" @@ -379,7 +383,7 @@ object MPCalGoCodegenPass { }\n}" }).indented }\n}").indented - }\n}\n" + }\n}""" } } @@ -394,6 +398,59 @@ object MPCalGoCodegenPass { case ch => ch.toString } + def translateQuantifierBound(bound: TLAQuantifierBound, setExpr: Description)(implicit ctx: GoCodegenContext): (IdMap[RefersTo.HasReferences,String],Description) = + bound match { + case TLAQuantifierBound(TLAQuantifierBound.IdsType, List(id), _) => + val boundIds: IdMap[RefersTo.HasReferences,String] = IdMap(id -> ctx.nameCleaner.cleanName(id.id.id)) + val bindings = d"\nvar ${boundIds(id)} $TLAValue = $setExpr" + + d"\n_ = ${boundIds(id)}" // stop the Go compiler from throwing errors on unused vars + (boundIds, bindings) + case TLAQuantifierBound(TLAQuantifierBound.TupleType, elements, _) => + val boundIds: IdMap[RefersTo.HasReferences,String] = elements.view.map(id => id -> ctx.nameCleaner.cleanName(id.id.id)).to(IdMap) + val bindings = elements.view.zipWithIndex.map { + case (element, elemIdx) => + d"\nvar ${boundIds(element)} $TLAValue = $setExpr.ApplyFunction(distsys.NewTLANumber($elemIdx))" + + d"\n_ = ${boundIds(element)}" + }.flattenDescriptions + (boundIds, bindings) + } + + def translateQuantifierBounds(bounds: List[TLAQuantifierBound], setsTupleName: String)(body: GoCodegenContext=>Description)(implicit ctx: GoCodegenContext): Description = { + val bindingInfos = bounds.view.zipWithIndex.map { + case (bound, idx) => translateQuantifierBound(bound, d"$setsTupleName[$idx]") + }.toList + val boundIds: IdMap[RefersTo.HasReferences, String] = bindingInfos.view.map(_._1).reduce(_ ++ _) + + val innerCtx: GoCodegenContext = ctx.copy(bindings = ctx.bindings ++ boundIds.map { + case id -> name => id -> FixedValueBinding(name) + }) + bindingInfos.view.map(_._2).flattenDescriptions + body(innerCtx) + + /*val boundIds = bounds.view.flatMap { + case TLAQuantifierBound(TLAQuantifierBound.IdsType, List(id), _) => + Some(id -> ctx.nameCleaner.cleanName(id.id.id)) + case TLAQuantifierBound(TLAQuantifierBound.TupleType, elements, _) => + elements.view.map(id => id -> ctx.nameCleaner.cleanName(id.id.id)) + }.to(IdMap) + val innerCtx: GoCodegenContext = ctx.copy(bindings = ctx.bindings ++ boundIds.map { + case id -> name => id -> FixedValueBinding(name) + }) + + bounds.view.zipWithIndex.flatMap { + case (TLAQuantifierBound(TLAQuantifierBound.IdsType, List(id), _), idx) => + List { + d"\nvar ${boundIds(id)} $TLAValue = $setsTupleName[$idx]" + + d"\n_ = ${boundIds(id)}" // stop the Go compiler from catching unused vars + } + case (TLAQuantifierBound(TLAQuantifierBound.TupleType, elements, _), idx) => + elements.view.zipWithIndex.map { + case (element, elemIdx) => + d"\nvar ${boundIds(element)} $TLAValue = $setsTupleName[$idx].ApplyFunction(distsys.NewTLANumber($elemIdx))" + + d"\n_ = ${boundIds(element)}" + } + }.flattenDescriptions + body(innerCtx)*/ + } + def translateExpr(expression: TLAExpression)(implicit ctx: GoCodegenContext): Description = expression match { case TLAString(value) => @@ -472,35 +529,39 @@ object MPCalGoCodegenPass { case defn@TLAOperatorDefinition(_, _, _, _) => defn -> IndependentCallableBinding(defnNames(defn)) }) val origCtx2 = ctx - (defs.view.map { - case defn@TLAOperatorDefinition(_, Nil, body, _) => - d"\nvar ${defnNames(defn)} $TLAValue = ${translateExpr(body)}" - case defn@TLAOperatorDefinition(_, args, body, _) => - val opDeclNames = args.view.map { - case decl@TLAOpDecl(variant) => - variant match { - case TLAOpDecl.NamedVariant(ident, _) => decl -> origCtx2.nameCleaner.cleanName(ident.id) - case TLAOpDecl.SymbolVariant(sym) => decl -> origCtx2.nameCleaner.cleanName(sym.symbol.productPrefix) - } - }.to(IdMap) - implicit val ctx: GoCodegenContext = origCtx2.copy(bindings = origCtx2.bindings ++ args.view.map { - case decl@TLAOpDecl(variant) => - variant match { - case TLAOpDecl.NamedVariant(_, 0) => decl -> FixedValueBinding(opDeclNames(decl)) - case TLAOpDecl.NamedVariant(_, _) => decl -> IndependentCallableBinding(opDeclNames(decl)) - case TLAOpDecl.SymbolVariant(_) => decl -> IndependentCallableBinding(opDeclNames(decl)) - } - }) - d"\n${defnNames(defn)} := func(${args.view.map { opDecl => - if(opDecl.arity == 0) { - d"${opDeclNames(opDecl)} $TLAValue" - } else { - d"${opDeclNames(opDecl)} func(${View.fill(opDecl.arity)(TLAValue.toDescription).flattenDescriptions}) $TLAValue" - } - }.separateBy(d", ")}) $TLAValue {${ - d"\nreturn ${translateExpr(body)}".indented - }\n}" - case _ => !!! + (defs.view.map { defn => + (defn match { + case defn@TLAOperatorDefinition(_, Nil, body, _) => + d"\nvar ${defnNames(defn)} $TLAValue = ${translateExpr(body)}" + case defn@TLAOperatorDefinition(_, args, body, _) => + val opDeclNames = args.view.map { + case decl@TLAOpDecl(variant) => + variant match { + case TLAOpDecl.NamedVariant(ident, _) => decl -> origCtx2.nameCleaner.cleanName(ident.id) + case TLAOpDecl.SymbolVariant(sym) => decl -> origCtx2.nameCleaner.cleanName(sym.symbol.productPrefix) + } + }.to(IdMap) + implicit val ctx: GoCodegenContext = origCtx2.copy(bindings = origCtx2.bindings ++ args.view.map { + case decl@TLAOpDecl(variant) => + variant match { + case TLAOpDecl.NamedVariant(_, 0) => decl -> FixedValueBinding(opDeclNames(decl)) + case TLAOpDecl.NamedVariant(_, _) => decl -> IndependentCallableBinding(opDeclNames(decl)) + case TLAOpDecl.SymbolVariant(_) => decl -> IndependentCallableBinding(opDeclNames(decl)) + } + }) + d"\n${defnNames(defn)} := func(${ + args.view.map { opDecl => + if (opDecl.arity == 0) { + d"${opDeclNames(opDecl)} $TLAValue" + } else { + d"${opDeclNames(opDecl)} func(${View.fill(opDecl.arity)(TLAValue.toDescription).flattenDescriptions}) $TLAValue" + } + }.separateBy(d", ") + }) $TLAValue {${ + d"\nreturn ${translateExpr(body)}".indented + }\n}" + case _ => !!! + }) + d"\n_ = ${defnNames(defn.asInstanceOf[TLAOperatorDefinition])}" }.flattenDescriptions + d"\nreturn ${translateExpr(body)}").indented }\n}()" case TLACase(arms, other) => @@ -521,52 +582,79 @@ object MPCalGoCodegenPass { case TLAFairness(_, _, _) => !!! case TLAFunction(args, body) => ctx.cleanName("args") { argsName => - val origCtx = ctx - d"distsys.NewTLAFunction([]$TLAValue{${args.view.map(_.set).map(translateExpr).separateBy(d", ")}}, func($argsName []$TLAValue) $TLAValue {${ - val argIds = args.view.flatMap { - case TLAQuantifierBound(TLAQuantifierBound.IdsType, List(id), _) => - Some(id -> origCtx.nameCleaner.cleanName(id.id.id)) - case TLAQuantifierBound(TLAQuantifierBound.TupleType, elements, _) => - elements.view.map(id => id -> origCtx.nameCleaner.cleanName(id.id.id)) - }.to(IdMap) - implicit val ctx: GoCodegenContext = origCtx.copy(bindings = origCtx.bindings ++ argIds.map { - case id -> name => id -> FixedValueBinding(name) - }) - (args.view.zipWithIndex.flatMap { - case (TLAQuantifierBound(TLAQuantifierBound.IdsType, List(id), _), idx) => - List(d"\nvar ${argIds(id)} $TLAValue = $argsName[$idx]") - case (TLAQuantifierBound(TLAQuantifierBound.TupleType, elements, _), idx) => - elements.view.zipWithIndex.map { - case (element, elemIdx) => - d"\nvar ${argIds(element)} $TLAValue = $argsName[$idx].ApplyFunction(distsys.NewTLANumber($elemIdx))" - } - }.flattenDescriptions + d"\nreturn ${translateExpr(body)}").indented - }\n})" + d"""distsys.NewTLAFunction([]$TLAValue{${args.view.map(_.set).map(translateExpr).separateBy(d", ")}}, func($argsName []$TLAValue) $TLAValue {${ + translateQuantifierBounds(args, argsName) { innerCtx => + implicit val ctx: GoCodegenContext = innerCtx + d"\nreturn ${translateExpr(body)}" + }.indented + }\n})""" } case TLAFunctionCall(function, params) => - d"${translateExpr(function)}.ApplyFunction(${ + d"""${translateExpr(function)}.ApplyFunction(${ if(params.size == 1) { translateExpr(params.head) } else { - d"distsys.NewTLATuple(${ + d"""distsys.NewTLATuple(${ params.view.map(translateExpr).separateBy(d", ") - })" + })""" } - })" + })""" case TLAFunctionSet(from, to) => d"distsys.NewTLAFunctionSet(${translateExpr(from)}, ${translateExpr(to)})" case TLAFunctionSubstitution(source, substitutions) => ??? case at@TLAFunctionSubstitutionAt() => val FixedValueBinding(name) = ctx.bindings(at.refersTo) name.toDescription - case TLAQuantifiedExistential(bounds, body) => ??? - case TLAQuantifiedUniversal(bounds, body) => ??? + case TLAQuantifiedExistential(bounds, body) => + ctx.cleanName("args") { argsName => + d"""distsys.TLAQuantifiedExistential([]$TLAValue{${ + bounds.view.map(_.set).map(translateExpr).separateBy(d", ") + }}, func($argsName []$TLAValue) bool {${ + translateQuantifierBounds(bounds, argsName) { innerCtx => + implicit val ctx: GoCodegenContext = innerCtx + d"\nreturn ${translateExpr(body)}.AsBool()" + }.indented + }\n})""" + } + case TLAQuantifiedUniversal(bounds, body) => + ctx.cleanName("args") { argsName => + d"""distsys.TLAQuantifiedUniversal([]$TLAValue{${ + bounds.view.map(_.set).map(translateExpr).separateBy(d", ") + }}, func($argsName []$TLAValue) bool {${ + translateQuantifierBounds(bounds, argsName) { innerCtx => + implicit val ctx: GoCodegenContext = innerCtx + d"\nreturn ${translateExpr(body)}.AsBool()" + }.indented + }\n})""" + } case TLAExistential(_, _) => !!! case TLAUniversal(_, _) => !!! case TLASetConstructor(contents) => d"distsys.NewTLASet(${contents.view.map(translateExpr).separateBy(d", ")})" - case TLASetRefinement(binding, when) => ??? - case TLASetComprehension(body, bounds) => ??? + case TLASetRefinement(binding, when) => + val origCtx = ctx + ctx.cleanName("elem") { elemName => + d"""distsys.TLASetRefinement(${translateExpr(binding.set)}, func($elemName $TLAValue) bool {${ + val (bindings, bindingCode) = translateQuantifierBound(binding, elemName.toDescription) + locally { + implicit val ctx: GoCodegenContext = origCtx.copy(bindings = origCtx.bindings ++ bindings.view.map { + case id -> name => id -> FixedValueBinding(name) + }) + (bindingCode + d"\nreturn ${translateExpr(when)}.AsBool()").indented + } + }\n})""" + } + case TLASetComprehension(body, bounds) => + ctx.cleanName("args") { argsName => + d"""distsys.TLASetComprehension([]$TLAValue{${ + bounds.view.map(_.set).map(translateExpr).separateBy(d", ") + }}, func($argsName []$TLAValue) $TLAValue {${ + translateQuantifierBounds(bounds, argsName) { innerCtx => + implicit val ctx: GoCodegenContext = innerCtx + d"\nreturn ${translateExpr(body)}" + }.indented + }\n})""" + } case TLATuple(elements) => d"distsys.NewTLATuple(${elements.view.map(translateExpr).separateBy(d", ")})" case TLARecordConstructor(fields) => diff --git a/src/pgo/util/TLAExprInterpreter.scala b/src/pgo/util/TLAExprInterpreter.scala index 2b80efac8..d047895f2 100644 --- a/src/pgo/util/TLAExprInterpreter.scala +++ b/src/pgo/util/TLAExprInterpreter.scala @@ -1,7 +1,9 @@ package pgo.util -import pgo.model.{Definition, DefinitionOne} +import pgo.model.{Definition, DefinitionOne, SourceLocation} import pgo.model.tla._ +import pgo.parser.TLAParser +import pgo.util.Unreachable.!!! import scala.annotation.tailrec @@ -10,6 +12,17 @@ object TLAExprInterpreter { final case class TypeError() extends RuntimeException("TLA+ type error") sealed abstract class TLAValue + object TLAValue { + def parseFromString(str: String): TLAValue = { + val expr = TLAParser.readExpression( + new SourceLocation.UnderlyingString(str), + str, + // Integers needed for prefix `-`, and TLC needed for `:>` and `@@` + definitions = BuiltinModules.Integers.members ::: BuiltinModules.TLC.members) + interpret(expr)(Map.empty) + } + } + final case class TLAValueBool(value: Boolean) extends TLAValue final case class TLAValueNumber(value: Int) extends TLAValue final case class TLAValueString(value: String) extends TLAValue @@ -102,8 +115,12 @@ object TLAExprInterpreter { TLAValueBool(true) }, BuiltinModules.TLC.memberAlpha("JavaTime") -> { case Nil => throw Unsupported() }, - BuiltinModules.TLC.memberAlpha(":>") -> { _ => throw Unsupported() }, - BuiltinModules.TLC.memberAlpha("@@") -> { _ => throw Unsupported() }, + BuiltinModules.TLC.memberSym(TLASymbol.ColonGreaterThanSymbol) -> { + case List(lhs, rhs) => TLAValueFunction(Map(lhs -> rhs)) + }, + BuiltinModules.TLC.memberSym(TLASymbol.DoubleAtSignSymbol) -> { + case List(TLAValueFunction(lhs), TLAValueFunction(rhs)) => TLAValueFunction(lhs ++ rhs) + }, BuiltinModules.TLC.memberAlpha("Permutations") -> { _ => throw Unsupported() }, BuiltinModules.TLC.memberAlpha("SortSeq") -> { _ => throw Unsupported() }, @@ -294,29 +311,30 @@ object TLAExprInterpreter { armEval(arms) case TLAFunction(args, body) => - def impl(args: List[TLAQuantifierBound], acc: Vector[TLAValue])(implicit env: Map[String, TLAValue]): Iterator[(TLAValue, TLAValue)] = - args match { - case Nil => Iterator.single(TLAValueTuple(acc) -> interpret(body)) - case TLAQuantifierBound(tpe, ids, set) :: restArgs => - interpret(set) match { - case TLAValueSet(setValue) => - tpe match { - case TLAQuantifierBound.IdsType => - val List(id) = ids - setValue.iterator.flatMap { v => - impl(restArgs, acc :+ v)(env = env.updated(id.id.id, v)) - } - case TLAQuantifierBound.TupleType => - setValue.iterator.flatMap { - case v@TLAValueTuple(elems) => - assert(elems.size == ids.size) - impl(restArgs, acc :+ v)(env = env ++ (ids.view.map(_.id.id) zip elems)) - } - } - } + val argSets = args.view.map(_.set).map(interpret).map { + case TLAValueSet(set) => set + }.toList + + def impl(args: List[TLAQuantifierBound], argSets: List[Set[TLAValue]], acc: Vector[TLAValue])(implicit env: Map[String, TLAValue]): Iterator[(TLAValue, TLAValue)] = + (args, argSets) match { + case (Nil, Nil) => Iterator.single(TLAValueTuple(acc) -> interpret(body)) + case (TLAQuantifierBound(tpe, ids, _) :: restArgs, argSet :: restArgSets) => + tpe match { + case TLAQuantifierBound.IdsType => + val List(id) = ids + argSet.iterator.flatMap { v => + impl(restArgs, restArgSets, acc :+ v)(env = env.updated(id.id.id, v)) + } + case TLAQuantifierBound.TupleType => + argSet.iterator.flatMap { + case v@TLAValueTuple(elems) => + require(elems.size == ids.size) + impl(restArgs, restArgSets, acc :+ v)(env = env ++ (ids.view.map(_.id.id) zip elems)) + } + } } - TLAValueFunction(impl(args, Vector.empty).toMap) + TLAValueFunction(impl(args, argSets, Vector.empty).toMap) case TLAFunctionCall(function, params) => val paramValue = params match { case List(singleParam) => interpret(singleParam) @@ -362,70 +380,46 @@ object TLAExprInterpreter { subKeys(keys, fnValue) } case TLAFunctionSubstitutionAt() => env("@") - case TLAQuantifiedExistential(bounds, body) => - def impl(bounds: List[TLAQuantifierBound])(implicit env: Map[String, TLAValue]): TLAValue = - bounds match { - case Nil => interpret(body) - case TLAQuantifierBound(tpe, ids, set) :: restBounds => - val setValue = interpret(set) - tpe match { - case TLAQuantifierBound.IdsType => - val List(id) = ids - setValue match { - case TLAValueSet(setValue) => - TLAValueBool(setValue.exists { v => - impl(restBounds)(env = env.updated(id.id.id, v)) match { - case TLAValueBool(value) => value - } - }) - } - case TLAQuantifierBound.TupleType => - setValue match { - case TLAValueSet(setValue) => - TLAValueBool(setValue.exists { - case TLAValueTuple(elems) => - require(elems.size == ids.size) - impl(restBounds)(env = env ++ (ids.view.map(_.id.id) zip elems)) match { - case TLAValueBool(value) => value - } - }) - } - } - } + case expr@(TLAQuantifiedExistential(_, _) | TLAQuantifiedUniversal(_, _)) => + // merge universal and existential code paths, because they are so similar + val (bounds, body) = expr match { + case TLAQuantifiedUniversal(bounds, body) => (bounds, body) + case TLAQuantifiedExistential(bounds, body) => (bounds, body) + } - impl(bounds) - case TLAQuantifiedUniversal(bounds, body) => - def impl(bounds: List[TLAQuantifierBound])(implicit env: Map[String, TLAValue]): TLAValue = - bounds match { - case Nil => interpret(body) - case TLAQuantifierBound(tpe, ids, set) :: restBounds => - val setValue = interpret(set) + val boundValues = bounds.view.map(_.set).map(interpret).map { + case TLAValueSet(set) => set // require all sets to be actual sets + }.toList + + // a function that slots in at the decision point, choosing exists or forall aggregation + val fn: (Set[TLAValue],TLAValue=>Boolean)=>Boolean = expr match { + case TLAQuantifiedUniversal(_, _) => _.forall(_) + case TLAQuantifiedExistential(_, _) => _.exists(_) + } + + def impl(bounds: List[TLAQuantifierBound], boundValues: List[Set[TLAValue]], envAcc: Map[String,TLAValue]): Boolean = + (bounds, boundValues) match { + case (Nil, Nil) => + implicit val env: Map[String,TLAValue] = envAcc + interpret(body) match { + case TLAValueBool(value) => value + } + case (TLAQuantifierBound(tpe, ids, _) :: restBounds, set :: restBoundValues) => tpe match { case TLAQuantifierBound.IdsType => val List(id) = ids - setValue match { - case TLAValueSet(setValue) => - TLAValueBool(setValue.forall { v => - impl(restBounds)(env = env.updated(id.id.id, v)) match { - case TLAValueBool(value) => value - } - }) - } + fn(set, v => impl(restBounds, restBoundValues, envAcc.updated(id.id.id, v))) case TLAQuantifierBound.TupleType => - setValue match { - case TLAValueSet(setValue) => - TLAValueBool(setValue.forall { - case TLAValueTuple(elems) => - require(elems.size == ids.size) - impl(restBounds)(env = env ++ (ids.view.map(_.id.id) zip elems)) match { - case TLAValueBool(value) => value - } - }) - } + fn(set, { + case TLAValueTuple(elems) => + require(ids.size == elems.size) + impl(restBounds, restBoundValues, envAcc ++ (ids.view.map(_.id.id) zip elems)) + }) } + case _ => !!! } - impl(bounds) + TLAValueBool(impl(bounds, boundValues, env)) case TLASetConstructor(contents) => TLAValueSet(contents.view.map(interpret).toSet) case TLASetRefinement(TLAQuantifierBound(tpe, ids, set), when) => @@ -450,29 +444,30 @@ object TLAExprInterpreter { } } case TLASetComprehension(body, bounds) => - def impl(bounds: List[TLAQuantifierBound])(implicit env: Map[String, TLAValue]): Iterator[TLAValue] = - bounds match { - case Nil => Iterator.single(interpret(body)) - case TLAQuantifierBound(tpe, ids, set) :: restBounds => - interpret(set) match { - case TLAValueSet(setValue) => - tpe match { - case TLAQuantifierBound.IdsType => - val List(id) = ids - setValue.iterator.flatMap { v => - impl(restBounds)(env = env.updated(id.id.id, v)) - } - case TLAQuantifierBound.TupleType => - setValue.iterator.flatMap { - case TLAValueTuple(elems) => - require(ids.size == elems.size) - impl(restBounds)(env = env ++ (ids.view.map(_.id.id) zip elems)) - } + val boundValues = bounds.view.map(_.set).map(interpret).map { + case TLAValueSet(set) => set // require all sets are actual sets + }.toList + def impl(bounds: List[TLAQuantifierBound], boundValues: List[Set[TLAValue]])(implicit env: Map[String, TLAValue]): Iterator[TLAValue] = + (bounds, boundValues) match { + case (Nil, Nil) => Iterator.single(interpret(body)) + case (TLAQuantifierBound(tpe, ids, _) :: restBounds, setValue :: restSetValues) => + tpe match { + case TLAQuantifierBound.IdsType => + val List(id) = ids + setValue.iterator.flatMap { v => + impl(restBounds, restSetValues)(env = env.updated(id.id.id, v)) + } + case TLAQuantifierBound.TupleType => + setValue.iterator.flatMap { + case TLAValueTuple(elems) => + require(ids.size == elems.size) + impl(restBounds, restSetValues)(env = env ++ (ids.view.map(_.id.id) zip elems)) } } + case _ => !!! } - TLAValueSet(impl(bounds).toSet) + TLAValueSet(impl(bounds, boundValues).toSet) case TLATuple(elements) => TLAValueTuple(elements.view.map(interpret).toVector) case TLARecordConstructor(fields) => diff --git a/test/files/general/dqueue.tla.gotests/dqueue.go b/test/files/general/dqueue.tla.gotests/dqueue.go index bdf950482..f628eb43d 100644 --- a/test/files/general/dqueue.tla.gotests/dqueue.go +++ b/test/files/general/dqueue.tla.gotests/dqueue.go @@ -99,7 +99,6 @@ func AConsumer(ctx *distsys.MPCalContext, self distsys.TLAValue, constants Const } } } - func AProducer(ctx *distsys.MPCalContext, self distsys.TLAValue, constants Constants, net0 distsys.ArchetypeResourceHandle, s distsys.ArchetypeResourceHandle) error { var err0 error // label tags @@ -111,6 +110,7 @@ func AProducer(ctx *distsys.MPCalContext, self distsys.TLAValue, constants Const ) programCounter0 := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.NewTLANumber(pLabelTag)) requester := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.TLAValue{}) + _ = requester for { if err0 != nil { diff --git a/test/files/general/load_balancer.tla.gotests/load_balancer.go b/test/files/general/load_balancer.tla.gotests/load_balancer.go index 23d25cefe..8e35bb25f 100644 --- a/test/files/general/load_balancer.tla.gotests/load_balancer.go +++ b/test/files/general/load_balancer.tla.gotests/load_balancer.go @@ -29,7 +29,9 @@ func ALoadBalancer(ctx *distsys.MPCalContext, self distsys.TLAValue, constants C ) programCounter := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.NewTLANumber(mainLabelTag)) msg := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.TLAValue{}) + _ = msg next := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.NewTLANumber(0)) + _ = next for { if err != nil { @@ -146,7 +148,6 @@ func ALoadBalancer(ctx *distsys.MPCalContext, self distsys.TLAValue, constants C } } } - func AServer(ctx *distsys.MPCalContext, self distsys.TLAValue, constants Constants, mailboxes0 distsys.ArchetypeResourceHandle, file_system distsys.ArchetypeResourceHandle) error { var err0 error // label tags @@ -158,6 +159,7 @@ func AServer(ctx *distsys.MPCalContext, self distsys.TLAValue, constants Constan ) programCounter0 := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.NewTLANumber(serverLoopLabelTag)) msg0 := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.TLAValue{}) + _ = msg0 for { if err0 != nil { @@ -247,7 +249,6 @@ func AServer(ctx *distsys.MPCalContext, self distsys.TLAValue, constants Constan } } } - func AClient(ctx *distsys.MPCalContext, self distsys.TLAValue, constants Constants, mailboxes1 distsys.ArchetypeResourceHandle, instream distsys.ArchetypeResourceHandle, outstream distsys.ArchetypeResourceHandle) error { var err1 error // label tags @@ -259,7 +260,9 @@ func AClient(ctx *distsys.MPCalContext, self distsys.TLAValue, constants Constan ) programCounter1 := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.NewTLANumber(clientLoopLabelTag)) req := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.TLAValue{}) + _ = req resp := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.TLAValue{}) + _ = resp for { if err1 != nil { diff --git a/test/pgo/TLAExpressionFuzzTests.scala b/test/pgo/TLAExpressionFuzzTests.scala index f1d6db64d..2d9d13740 100644 --- a/test/pgo/TLAExpressionFuzzTests.scala +++ b/test/pgo/TLAExpressionFuzzTests.scala @@ -8,8 +8,8 @@ import pgo.model.DefinitionOne import pgo.model.tla._ import pgo.trans.PCalRenderPass import pgo.util.Description._ -import pgo.util.{IdMap, IdSet, TLAExprInterpreter} -import pgo.util.TLAExprInterpreter.{TLAValue, TLAValueBool, TLAValueFunction, TLAValueNumber, TLAValueSet, TLAValueString, TLAValueTuple, builtinOperators} +import pgo.util.TLAExprInterpreter.TLAValue +import pgo.util.{IdSet, TLAExprInterpreter} import scala.annotation.tailrec import scala.collection.mutable @@ -115,7 +115,14 @@ class TLAExpressionFuzzTests extends AnyFunSuite with ScalaCheckPropertyChecks { os.proc("go", "mod", "download").call(cwd = workDir) try { - os.proc("go", "run", "./main").call(cwd = workDir, mergeErrIntoOut = true, timeout = 15000) + val result = os.proc("go", "run", "./main").call(cwd = workDir, mergeErrIntoOut = true, timeout = 30000) + val valueFromGo = TLAValue.parseFromString(result.out.text()) + expectedBehaviour match { + case Left(err) => + fail(s"expected an error, because Scala-based interpreter threw one", err) + case Right(valueFromScala) => + assert(valueFromGo == valueFromScala) + } Prop.passed } catch { case err: os.SubprocessException => @@ -132,6 +139,9 @@ class TLAExpressionFuzzTests extends AnyFunSuite with ScalaCheckPropertyChecks { somethingBadHappened() throw err } + case NonFatal(err) => + somethingBadHappened() + throw err } } } @@ -141,7 +151,7 @@ class TLAExpressionFuzzTests extends AnyFunSuite with ScalaCheckPropertyChecks { } } - private def genCombinedASTNodePossibilities(subExprs: List[TLAExpression])(implicit env: IdSet[DefinitionOne], anchorOpt: Option[TLAFunctionSubstitutionPairAnchor]): List[Gen[TLAExpression]] = { + private def genFlatASTOptions(subExprs: List[TLAExpression])(implicit env: IdSet[DefinitionOne], anchorOpt: Option[TLAFunctionSubstitutionPairAnchor]): List[Gen[TLAExpression]] = { sealed abstract class GenProvider { def genIterator: Iterator[Gen[TLAExpression]] } @@ -264,18 +274,96 @@ class TLAExpressionFuzzTests extends AnyFunSuite with ScalaCheckPropertyChecks { .toList } + def genNamedASTOptions(breadth: Int, makeExpr: (IdSet[DefinitionOne],Option[TLAFunctionSubstitutionPairAnchor])=>Gen[TLAExpression])(implicit env: IdSet[DefinitionOne], anchorOpt: Option[TLAFunctionSubstitutionPairAnchor]): List[Gen[TLAExpression]] = { + val options = mutable.ListBuffer[Gen[TLAExpression]]() + + lazy val genQuantifierBound: Gen[TLAQuantifierBound] = for { + tpe <- Gen.oneOf(TLAQuantifierBound.IdsType, TLAQuantifierBound.TupleType) + ids <- tpe match { + case TLAQuantifierBound.IdsType => Gen.identifier.map(id => List(TLAIdentifier(id).toDefiningIdentifier)) + case TLAQuantifierBound.TupleType => Gen.nonEmptyListOf(Gen.identifier.map(id => TLAIdentifier(id).toDefiningIdentifier)) + } + set <- makeExpr(env, anchorOpt) + } yield TLAQuantifierBound(tpe, ids, set) + + if(breadth >= 2) { + def impl(count: Int, acc: List[TLAUnit])(implicit env: IdSet[DefinitionOne], anchorOpt: Option[TLAFunctionSubstitutionPairAnchor]): Gen[TLAExpression] = { + assert(count >= 1) + if(count == 1) { + makeExpr(env, anchorOpt).map { body => + TLALet(acc.reverse, body) + } + } else { + for { + name <- Gen.identifier.map(TLAIdentifier) + // TODO: consider more complex argument shapes? this is just plain single names, for now + idents <- Gen.listOf(Gen.identifier.map(name => TLAOpDecl(TLAOpDecl.NamedVariant(TLAIdentifier(name), 0)))) + body <- makeExpr(env ++ idents, anchorOpt) + defn = TLAOperatorDefinition(ScopeIdentifierName(name), idents, body, isLocal = false) + result <- impl(count - 1, defn :: acc)(env = env ++ defn.singleDefinitions, anchorOpt = anchorOpt) + } yield result + } + } + + options += impl(breadth, Nil) + + options += (for { + qbs <- Gen.listOfN(breadth - 1, genQuantifierBound) + body <- makeExpr(env ++ qbs.view.flatMap(_.singleDefinitions), anchorOpt) + } yield TLAFunction(qbs, body)) + + options += (for { + constructor <- Gen.oneOf(TLAQuantifiedExistential, TLAQuantifiedUniversal) + bounds <- Gen.listOfN(breadth - 1, genQuantifierBound) + body <- makeExpr(env ++ bounds.view.flatMap(_.singleDefinitions), anchorOpt) + } yield constructor(bounds, body)) + } + + if(breadth == 2) { + options += (for { + binding <- genQuantifierBound + when <- makeExpr(env ++ binding.singleDefinitions, anchorOpt) + } yield TLASetRefinement(binding, when)) + } + + if(breadth >= 2) { + options += (for { + bounds <- Gen.listOfN(breadth - 1, genQuantifierBound) + body <- makeExpr(env ++ bounds.view.flatMap(_.singleDefinitions), anchorOpt) + } yield TLASetComprehension(body, bounds)) + } + + options.result() + } + private def forceOneOf[T](gens: List[Gen[T]]): Gen[T] = { require(gens.nonEmpty) - Gen.choose(min = 0, max = gens.size - 1) - .flatMap(gens) + if(gens.size == 1) { + gens.head + } else { + Gen.choose(min = 0, max = gens.size - 1) + .flatMap(gens) + } } lazy val trueRandomExprGen: Gen[TLAExpression] = { def impl(size: Int)(implicit env: IdSet[DefinitionOne], anchorOpt: Option[TLAFunctionSubstitutionPairAnchor]): Gen[TLAExpression] = for { breadth <- Gen.oneOf(0 to size) - subExprs <- Gen.listOfN(breadth, impl(size / (breadth + 1))) - expr <- forceOneOf(genCombinedASTNodePossibilities(subExprs)) + expr <- locally { + val namedOptions = genNamedASTOptions(breadth, impl(size / (breadth + 1))(_, _)) + val unnamedCase = + for { + subExprs <- Gen.listOfN(breadth, impl(size / (breadth + 1))) + expr <- forceOneOf(genFlatASTOptions(subExprs)) + } yield expr + + if(namedOptions.nonEmpty) { + Gen.oneOf(forceOneOf(namedOptions), unnamedCase) + } else { + unnamedCase // if there are no named options for this breadth, avoid choice-of-none error + } + } } yield expr Gen.sized(size => impl(size)(IdSet.empty, None)) From 6ece9afa98eabd82ced8d3a1776c6306d52263fc Mon Sep 17 00:00:00 2001 From: fhackett Date: Wed, 14 Jul 2021 00:57:40 -0700 Subject: [PATCH 15/27] almost done fuzz testing; missing one node type --- src/pgo/PGo.scala | 10 +- src/pgo/model/RefersTo.scala | 1 + src/pgo/model/tla/AST.scala | 18 +- src/pgo/parser/MPCalParser.scala | 22 +- src/pgo/parser/PCalParser.scala | 25 +- src/pgo/parser/TLAParser.scala | 71 +- src/pgo/parser/TLAParserContext.scala | 4 +- src/pgo/trans/MPCalGoCodegenPass.scala | 6 +- src/pgo/util/TLAExprInterpreter.scala | 58 +- test/files/general/ExprTests.tla | 29 + test/files/general/ExprTests.tla.expectpcal | 34 + .../ExprTests.tla.gotests/ExprTests.go | 2269 +++++++++++++++++ .../ExprTests.tla.gotests/ExprTests_test.go | 14 + .../general/ExprTests.tla.gotests/go.mod | 7 + test/files/general/dqueue.tla | 5 +- test/files/general/dqueue.tla.expectpcal | 5 +- .../general/dqueue.tla.gotests/dqueue.go | 3 + .../load_balancer.go | 3 + test/pgo/GoGenFileTests.scala | 2 - test/pgo/TLAExpressionFuzzTests.scala | 98 +- 20 files changed, 2532 insertions(+), 152 deletions(-) create mode 100644 test/files/general/ExprTests.tla create mode 100644 test/files/general/ExprTests.tla.expectpcal create mode 100644 test/files/general/ExprTests.tla.gotests/ExprTests.go create mode 100644 test/files/general/ExprTests.tla.gotests/ExprTests_test.go create mode 100644 test/files/general/ExprTests.tla.gotests/go.mod diff --git a/src/pgo/PGo.scala b/src/pgo/PGo.scala index 252be07cf..946e3e642 100644 --- a/src/pgo/PGo.scala +++ b/src/pgo/PGo.scala @@ -94,8 +94,8 @@ object PGo { val tempOutput = os.temp(dir = os.pwd) locally { - val PCalBeginTranslation = raw"""\s*\\\*\s+BEGIN\s+PLUSCAL\s+TRANSLATION""".r - val PCalEndTranslation = raw"""\s*\\\*\s+END\s+PLUSCAL\s+TRANSLATION""".r + val PCalBeginTranslation = raw"""\s*\\\*\s+BEGIN\s+PLUSCAL\s+TRANSLATION\s*""".r + val PCalEndTranslation = raw"""\s*\\\*\s+END\s+PLUSCAL\s+TRANSLATION\s*""".r val renderedPCalIterator = Iterator("", "", "\\* BEGIN PLUSCAL TRANSLATION") ++ renderedPCal.linesIterator ++ @@ -106,11 +106,11 @@ object PGo { os.write.over(tempOutput, os.read.lines.stream(config.PCalGenCmd.specFile()).zipWithIndex.flatMap { case (PCalBeginTranslation(), lineIdx) if !pcalBeginFound => - assert(!pcalEndFound, s"at line ${lineIdx+1}, found PLUSCAL END TRANSLATION comment before PLUSCAL BEGIN TRANSLATION") + assert(!pcalEndFound, s"at line ${lineIdx+1}, found `\\* END PLUSCAL TRANSLATION` comment before `\\* BEGIN PLUSCAL TRANSLATION`") pcalBeginFound = true Generator.from(renderedPCalIterator) case (PCalEndTranslation(), lineIdx) => - assert(!pcalEndFound, s"at line ${lineIdx+1}, found PLUSCAL END TRANSLATION without corresponding previous PLUSCAL BEGIN TRANSLATION") + assert(!pcalEndFound, s"at line ${lineIdx+1}, found `\\* END PLUSCAL TRANSLATION` without corresponding previous `\\* BEGIN PLUSCAL TRANSLATION`") pcalEndFound = true Generator() case _ if pcalBeginFound && !pcalEndFound => @@ -120,7 +120,7 @@ object PGo { }.map(line => s"$line\n")) assert(pcalBeginFound && pcalEndFound, - s"""one or both of "\\* PLUSCAL BEGIN TRANSLATION" and "\\* PLUSCAL END TRANSLATION" not found; + s"""one or both of `\\* BEGIN PLUSCAL TRANSLATION` and `\\* END PLUSCAL TRANSLATION` not found; |add these tags so that PGo knows where to put its generated PlusCal""".stripMargin) } // move the rendered output over the spec file, replacing it diff --git a/src/pgo/model/RefersTo.scala b/src/pgo/model/RefersTo.scala index e6c23eafe..6dccd8767 100644 --- a/src/pgo/model/RefersTo.scala +++ b/src/pgo/model/RefersTo.scala @@ -9,6 +9,7 @@ trait RefersTo[T <: RefersTo.HasReferences] extends Rewritable { refersTo_ = Some(refersTo) this } + def hasRefersTo: Boolean = refersTo_.nonEmpty override def decorateLike(succ: this.type): this.type = super.decorateLike(succ.setRefersTo(refersTo)) diff --git a/src/pgo/model/tla/AST.scala b/src/pgo/model/tla/AST.scala index e072d65f5..4dafd6f84 100644 --- a/src/pgo/model/tla/AST.scala +++ b/src/pgo/model/tla/AST.scala @@ -1,5 +1,6 @@ package pgo.model.tla +import pgo.model.Definition.ScopeIdentifierName import pgo.model.{Definition, DefinitionComposite, DefinitionOne, RefersTo, Rewritable, SourceLocatable, Visitable} import scala.collection.View @@ -350,11 +351,24 @@ object TLANumber { case object HexadecimalSyntax extends Syntax } -final case class TLAGeneralIdentifier(name: TLAIdentifier, prefix: List[TLAGeneralIdentifierPart]) extends TLAExpression with RefersTo[DefinitionOne] +final case class TLAGeneralIdentifier(name: TLAIdentifier, prefix: List[TLAGeneralIdentifierPart]) extends TLAExpression with RefersTo[DefinitionOne] { + override def setRefersTo(refersTo: DefinitionOne): TLAGeneralIdentifier.this.type = { + // TODO: why is this sometimes not true, but things seem fine? + // assert(refersTo.identifier.isInstanceOf[ScopeIdentifierName] && name == refersTo.identifier.asInstanceOf[ScopeIdentifierName].name, + // s"it is probably a bug that an identifier with lexical name $name actually refers to ${refersTo.identifier}") + super.setRefersTo(refersTo) + } +} final case class TLADot(lhs: TLAExpression, identifier: TLAIdentifier) extends TLAExpression -final case class TLAOperatorCall(name: Definition.ScopeIdentifier, prefix: List[TLAGeneralIdentifierPart], arguments: List[TLAExpression]) extends TLAExpression with RefersTo[DefinitionOne] +final case class TLAOperatorCall(name: Definition.ScopeIdentifier, prefix: List[TLAGeneralIdentifierPart], arguments: List[TLAExpression]) extends TLAExpression with RefersTo[DefinitionOne] { + override def setRefersTo(refersTo: DefinitionOne): TLAOperatorCall.this.type = { + // TODO: why is this sometimes not true, but things seem fine? + // assert(refersTo.identifier == name, s"it is probably a bug that an operator call with lexical name $name actually refers to ${refersTo.identifier}") + super.setRefersTo(refersTo) + } +} final case class TLAIf(cond: TLAExpression, tval: TLAExpression, fval: TLAExpression) extends TLAExpression diff --git a/src/pgo/parser/MPCalParser.scala b/src/pgo/parser/MPCalParser.scala index 8d4a00516..7d950dee3 100644 --- a/src/pgo/parser/MPCalParser.scala +++ b/src/pgo/parser/MPCalParser.scala @@ -138,11 +138,23 @@ trait MPCalParser extends PCalParser { implicit val ctx: MPCalParserContext = origCtx.withLateBinding (ws ~> "{" ~> ws ~> "read" ~> ws ~> cast(mpcalMappingMacroBody.pcalCSyntax.pcalCompoundStmt)) ~ (ws ~> "write" ~> ws ~> cast(mpcalMappingMacroBody.pcalCSyntax.pcalCompoundStmt) <~ ws <~ "}") ^^ - ((name, _, ctx.ctx.ctx.lateBindingStack.head)) + ((name, _)) } ^^ { - case (name, readBlock ~ writeBlock, lateBindings) => + case (name, readBlock ~ writeBlock) => + val lateBindings = locally { + val lateBindingsAcc = mutable.HashMap[TLAIdentifier,mutable.ListBuffer[TLAGeneralIdentifier]]() + val visitor: PartialFunction[Visitable,Unit] = { + case ident@TLAGeneralIdentifier(name, Nil) if !ident.hasRefersTo => + lateBindingsAcc.getOrElseUpdate(name, mutable.ListBuffer()) += ident + } + readBlock.foreach(_.visit(Visitable.TopDownFirstStrategy)(visitor)) + writeBlock.foreach(_.visit(Visitable.TopDownFirstStrategy)(visitor)) + + lateBindingsAcc.toMap + } + val freeVars = lateBindings.keysIterator.map(_.toDefiningIdentifier).toList.sortBy(_.id.id) - freeVars.foreach { v => lateBindings(v.id).foreach(_(v)) } + freeVars.foreach { v => lateBindings(v.id).foreach(_.setRefersTo(v)) } MPCalMappingMacro(name, readBlock, writeBlock, freeVars) } } @@ -176,8 +188,8 @@ trait MPCalParser extends PCalParser { ref.setSourceLocation(loc) ctx.ctx.lookupDefinition(List(Definition.ScopeIdentifierName(id))) match { case None => - if(ctx.ctx.lateBindingStack.nonEmpty) { - ctx.ctx.lateBindingStack.head.getOrElseUpdate(id, mutable.ArrayBuffer()) += ref.setRefersTo + if(ctx.ctx.lateBindingStack > 0) { + // pass; expect whoever incremented late bindings to set the reference later } else { throw DefinitionLookupError(Nil, Definition.ScopeIdentifierName(id)) } diff --git a/src/pgo/parser/PCalParser.scala b/src/pgo/parser/PCalParser.scala index 65e6223f1..6d0a35dcc 100644 --- a/src/pgo/parser/PCalParser.scala +++ b/src/pgo/parser/PCalParser.scala @@ -1,6 +1,6 @@ package pgo.parser -import pgo.model.{Definition, SourceLocation} +import pgo.model.{Definition, DefinitionOne, SourceLocation, Visitable} import pgo.model.pcal._ import pgo.model.tla._ @@ -72,11 +72,10 @@ trait PCalParser extends TLAParser { val result = PCalAssignmentLhsIdentifier(id) result.setRefersTo(defn) result - case None if ctx.ctx.lateBindingStack.nonEmpty => - val lateBindings = ctx.ctx.lateBindingStack.head - val result = PCalAssignmentLhsIdentifier(id) - lateBindings.getOrElseUpdate(id, mutable.ArrayBuffer.empty) += result.setRefersTo - result + case None if ctx.ctx.lateBindingStack > 0 => + // let whoever incremented lateBindingStack set the reference later + // this should be the parser for PCalMacro + PCalAssignmentLhsIdentifier(id) case None => throw DefinitionLookupError(Nil, Definition.ScopeIdentifierName(id)) } @@ -179,9 +178,19 @@ trait PCalParser extends TLAParser { "macro" ~> ws ~> tlaIdentifierExpr ~ (ws ~> "(" ~> ws ~> repsep(tlaIdentifierExpr, ws ~> "," ~> ws)).flatMap { params => val definingParams = params.map(_.toDefiningIdentifier) implicit val ctx: PCalParserContext = definingParams.foldLeft(origCtx)(_.withDefinition(_)).withLateBinding - (ws ~> ")" ~> ws ~> pcalBody("macro") <~ opt(ws ~> ";")) ^^ ((definingParams, _, ctx.ctx.lateBindingStack.head)) + (ws ~> ")" ~> ws ~> pcalBody("macro") <~ opt(ws ~> ";")) ^^ ((definingParams, _)) } ^^ { - case id ~ ((params, body, freeVars)) => + case id ~ ((params, body)) => + val freeVars = locally { + val freeVarsAcc = mutable.HashMap[TLAIdentifier,mutable.ListBuffer[DefinitionOne=>Unit]]() + body.foreach(_.visit(Visitable.TopDownFirstStrategy) { + case ident@TLAGeneralIdentifier(name, Nil) if !ident.hasRefersTo => + freeVarsAcc.getOrElseUpdate(name, mutable.ListBuffer()) += ident.setRefersTo + case lhs@PCalAssignmentLhsIdentifier(name) if !lhs.hasRefersTo => + freeVarsAcc.getOrElseUpdate(name, mutable.ListBuffer()) += lhs.setRefersTo + }) + freeVarsAcc.toMap + } val freeVarsList = freeVars.keysIterator.toArray.sortInPlaceBy(_.id).iterator.map(_.toDefiningIdentifier).toList freeVarsList.foreach { ident => freeVars(ident.id).foreach(_(ident)) diff --git a/src/pgo/parser/TLAParser.scala b/src/pgo/parser/TLAParser.scala index ea6206688..adbed6148 100644 --- a/src/pgo/parser/TLAParser.scala +++ b/src/pgo/parser/TLAParser.scala @@ -1,9 +1,10 @@ package pgo.parser -import pgo.model.{Definition, DefinitionOne, SourceLocatable, SourceLocation, SourceLocationWithUnderlying} +import pgo.model.{Definition, DefinitionOne, SourceLocatable, SourceLocation, SourceLocationWithUnderlying, Visitable} import pgo.model.tla._ import pgo.util.Description import Description._ +import pgo.model.Definition.ScopeIdentifierName import scala.collection.mutable import scala.util.parsing.combinator.RegexParsers @@ -143,7 +144,7 @@ trait TLAParser extends RegexParsers { tlaIdentifierExpr.flatMap { id => ctx.lookupDefinition(pfx.map(id => Definition.ScopeIdentifierName(id.id)) :+ Definition.ScopeIdentifierName(id)) match { case None => - failure(s"lookup failed for identifier ${pfx.map(_.id.id).mkString("!")}!$id") + failure(s"lookup failed for identifier ${pfx.map(_.id.id).mkString("!")}!${id.id}") case Some(defn) => if (defn.arity == 0) { wsChk ~> "!" ^^^ PrefixPart(TLAGeneralIdentifierPart(id, Nil), defn) @@ -189,17 +190,15 @@ trait TLAParser extends RegexParsers { val name = Definition.ScopeIdentifierName(id) ctx.lookupDefinition(pfx.map(id => Definition.ScopeIdentifierName(id.id)) :+ name) match { case None => - ctx.lateBindingStack match { - case lateBindings :: _ if pfx.isEmpty => - // if the context allows late bindings (i.e names bound to the right) - // then assume arity == 0 and defer setRefersTo below - val ref = TLAGeneralIdentifier(id, Nil) - lateBindings.getOrElseUpdate(id, mutable.ArrayBuffer()) += ref.setRefersTo - success(ref) - case _ => - // don't fail hard; it's possible that the prefix is empty and the identifier is an ambiguous - // prefix of some other piece of syntax; perhaps an OpDecl - failure(s"lookup failed for identifier ${pfx.map(_.id.id).mkString("!")}!$id") + if(ctx.lateBindingStack > 0 && pfx.isEmpty) { + // if the context allows late bindings (i.e names bound to the right) + // then assume arity == 0 and expect whoever incremented lateBindingStack to gather and handle + // the unbound identifier + success(TLAGeneralIdentifier(id, Nil)) + } else { + // don't fail hard; it's possible that the prefix is empty and the identifier is an ambiguous + // prefix of some other piece of syntax; perhaps an OpDecl + failure(s"lookup failed for identifier ${pfx.map(_.id.id).mkString("!")}!${id.id}") } case Some(defn) => if( defn.arity > 0 ) { @@ -436,38 +435,34 @@ trait TLAParser extends RegexParsers { withSourceLocation { ("{" ~> wsChk ~> { implicit val ctx: TLAParserContext = origCtx.withLateBinding - (tlaExpression <~ wsChk <~ ":") ^^ ((_, ctx.lateBindingStack.head)) + tlaExpression <~ wsChk <~ ":" }) ~ (wsChk ~> tlaComma1Sep(tlaQuantifierBound) <~ wsChk <~ "}") ^^ { - case (expr, lateBindings) ~ bounds => + case expr ~ bounds => // extract all late bindings from bounds, and match them up with any relevant elements // of lateBindings, removing them in the process val defns: List[DefinitionOne] = bounds.flatMap(bind => bind.singleDefinitions) - defns.foreach { defn => - val defnName = defn.identifier.asInstanceOf[Definition.ScopeIdentifierName].name - lateBindings.get(defnName) match { - case Some(lateBind) => - lateBind.foreach(_(defn)) - lateBindings -= defnName - case None => - } + val defnMap = defns.view.map(defn => defn.identifier.asInstanceOf[ScopeIdentifierName].name -> defn).toMap + + // gather all nested unbound names + // (yes, this could end up being really slow, but last time I tried to be smart w/ mutable state or something, a fuzz tester exposed a really weird bug) + val idents = mutable.ListBuffer[TLAGeneralIdentifier]() + expr.visit(Visitable.TopDownFirstStrategy) { + case ident@TLAGeneralIdentifier(_, Nil) if !ident.hasRefersTo => idents += ident } - // if lateBindings is not empty after this (i.e we didn't match all the contained bindings) - // then either these should be bound even later (add to the next late bindings map in the stack) - // or we're out of possible late bindings, in which case raise an error indicating the location - // of one of the remaining identifiers (alphabetically least, for consistency) - if(lateBindings.nonEmpty) { - ctx.lateBindingStack match { - case Nil => - val id = lateBindings.keysIterator.minBy(_.id) - throw DefinitionLookupError(Nil, Definition.ScopeIdentifierName(id)) - case outerBindings :: _ => - lateBindings.foreach { - case (key, bindings) => - outerBindings.getOrElseUpdate(key, mutable.ArrayBuffer.empty) ++= bindings + + idents.foreach { ident => + defnMap.get(ident.name) match { + case Some(defn) => ident.setRefersTo(defn) + case None => + // if the late bindings count is 0 after this, we should check that no idents remain unbound. + // if so, raise the [AST traversal-wise, probably lexically] "earliest" one as an error. + // otherwise, unbound idents may still be bound via currently unknown context, so don't do anything + if(ctx.lateBindingStack == 0) { + throw DefinitionLookupError(Nil, Definition.ScopeIdentifierName(ident.name)) } - lateBindings.clear() } } + TLASetComprehension(expr, bounds) } } @@ -827,7 +822,7 @@ trait TLAParser extends RegexParsers { def tlaModuleBeforeTranslation(implicit ctx: TLAParserContext): Parser[TLAModule] = withSourceLocation { - val translationTag = ("\\*" <~ rep("*") <~ rep(" ") <~ "BEGIN" <~ rep(" ") <~ "TRANSLATION") + val translationTag = ("\\*" <~ rep("*") <~ rep1(" ") <~ "BEGIN" <~ rep1(" ") <~ "TRANSLATION") .withFailureMessage("\\* expected: for scoping reasons, an MPCal-compilable TLA+ module must contain a `\\* BEGIN TRANSLATION` tag") val wsWithoutTranslationTag = rep(regex("""\s+""".r) | tlaMultilineComment | not(translationTag) ~> tlaLineComment) diff --git a/src/pgo/parser/TLAParserContext.scala b/src/pgo/parser/TLAParserContext.scala index 68714eca4..c821ffe62 100644 --- a/src/pgo/parser/TLAParserContext.scala +++ b/src/pgo/parser/TLAParserContext.scala @@ -7,7 +7,7 @@ import scala.annotation.tailrec import scala.collection.mutable final case class TLAParserContext(minColumn: Int = -1, - lateBindingStack: List[mutable.Map[TLAIdentifier,mutable.Buffer[DefinitionOne=>Unit]]] = Nil, + lateBindingStack: Int = 0, currentScope: Map[Definition.ScopeIdentifier,DefinitionOne] = Map.empty, functionSubstitutionPairAnchor: Option[TLAFunctionSubstitutionPairAnchor] = None) { def withMinColumn(minColumn: Int): TLAParserContext = @@ -24,7 +24,7 @@ final case class TLAParserContext(minColumn: Int = -1, copy(functionSubstitutionPairAnchor = Some(anchor)) def withLateBinding: TLAParserContext = - copy(lateBindingStack=mutable.Map.empty[TLAIdentifier,mutable.Buffer[DefinitionOne=>Unit]] :: lateBindingStack) + copy(lateBindingStack = lateBindingStack + 1) def lookupModuleExtends(id: Definition.ScopeIdentifierName): TLAModuleRef = currentScope.get(id) match { diff --git a/src/pgo/trans/MPCalGoCodegenPass.scala b/src/pgo/trans/MPCalGoCodegenPass.scala index fbcd7547d..547e1232d 100644 --- a/src/pgo/trans/MPCalGoCodegenPass.scala +++ b/src/pgo/trans/MPCalGoCodegenPass.scala @@ -754,7 +754,11 @@ object MPCalGoCodegenPass { d"\nimport (${ (d"""\n"github.com/UBC-NSS/pgo/distsys"""" + d"""\n"fmt"""").indented - })\n" + + }\n)" + + d"\n" + + d"\nvar _ = new(fmt.Stringer) // unconditionally prevent go compiler from reporting unused fmt import" + + d"\nvar _ = distsys.TLAValue{} // same, for distsys" + + d"\n" + d"\ntype $Constants struct {${ constantDecls.map { case decl@TLAOpDecl(variant) => diff --git a/src/pgo/util/TLAExprInterpreter.scala b/src/pgo/util/TLAExprInterpreter.scala index d047895f2..d68c2db87 100644 --- a/src/pgo/util/TLAExprInterpreter.scala +++ b/src/pgo/util/TLAExprInterpreter.scala @@ -1,6 +1,6 @@ package pgo.util -import pgo.model.{Definition, DefinitionOne, SourceLocation} +import pgo.model.{Definition, DefinitionOne, RefersTo, SourceLocation} import pgo.model.tla._ import pgo.parser.TLAParser import pgo.util.Unreachable.!!! @@ -236,7 +236,7 @@ object TLAExprInterpreter { BuiltinModules.Reals.memberAlpha("Infinity") -> { _ => throw Unsupported() }, ) - def interpret(expr: TLAExpression)(implicit env: Map[String,TLAValue]): TLAValue = { + def interpret(expr: TLAExpression)(implicit env: Map[RefersTo.HasReferences,TLAValue]): TLAValue = { try { expr match { case TLAString(value) => TLAValueString(value) @@ -246,25 +246,25 @@ object TLAExprInterpreter { } case ident@TLAGeneralIdentifier(name, prefix) => assert(prefix.isEmpty) - env.getOrElse(name.id, { + env.getOrElse(ident.refersTo, { builtinOperators(ident.refersTo)(Nil) }) case TLADot(lhs, identifier) => interpret(lhs) match { case TLAValueFunction(value) => - require(value.contains(identifier.id)) - value(identifier.id) + val idx = TLAValueString(identifier.id) + require(value.contains(idx)) + value(idx) } case opcall@TLAOperatorCall(_, _, arguments) => opcall.refersTo match { case builtin: BuiltinModules.TLABuiltinOperator => builtinOperators(builtin)(arguments.map(interpret)) case TLAOperatorDefinition(_, args, body, _) => - assert(args.size == arguments.size) - assert(args.forall(_.variant.isInstanceOf[TLAOpDecl.NamedVariant])) - val argNames = args.view.map(_.variant.asInstanceOf[TLAOpDecl.NamedVariant].ident.id) + require(args.size == arguments.size) + require(args.forall(_.variant.isInstanceOf[TLAOpDecl.NamedVariant])) val argValues = arguments.map(interpret) - interpret(body)(env = env ++ (argNames zip argValues)) + interpret(body)(env = env ++ (args zip argValues)) } case TLAIf(cond, tval, fval) => interpret(cond) match { @@ -273,17 +273,13 @@ object TLAExprInterpreter { } case TLALet(defs, body) => @tailrec - def impl(defs: List[TLAUnit])(implicit env: Map[String, TLAValue]): TLAValue = + def impl(defs: List[TLAUnit])(implicit env: Map[RefersTo.HasReferences, TLAValue]): TLAValue = defs match { case Nil => interpret(body) case unit :: restUnits => unit match { - case TLAOperatorDefinition(name, args, body, _) if args.isEmpty => - val strName = name match { - case Definition.ScopeIdentifierName(name) => name.id - case Definition.ScopeIdentifierSymbol(symbol) => symbol.symbol.stringReprDefn - } - impl(restUnits)(env = env.updated(strName, interpret(body))) + case defn@TLAOperatorDefinition(name, args, body, _) if args.isEmpty => + impl(restUnits)(env = env.updated(defn, interpret(body))) case _: TLAOperatorDefinition => // for definitions with args, they will be called by TLAOperatorCall, and scoping is done already impl(restUnits) @@ -315,7 +311,7 @@ object TLAExprInterpreter { case TLAValueSet(set) => set }.toList - def impl(args: List[TLAQuantifierBound], argSets: List[Set[TLAValue]], acc: Vector[TLAValue])(implicit env: Map[String, TLAValue]): Iterator[(TLAValue, TLAValue)] = + def impl(args: List[TLAQuantifierBound], argSets: List[Set[TLAValue]], acc: Vector[TLAValue])(implicit env: Map[RefersTo.HasReferences, TLAValue]): Iterator[(TLAValue, TLAValue)] = (args, argSets) match { case (Nil, Nil) => Iterator.single(TLAValueTuple(acc) -> interpret(body)) case (TLAQuantifierBound(tpe, ids, _) :: restArgs, argSet :: restArgSets) => @@ -323,13 +319,13 @@ object TLAExprInterpreter { case TLAQuantifierBound.IdsType => val List(id) = ids argSet.iterator.flatMap { v => - impl(restArgs, restArgSets, acc :+ v)(env = env.updated(id.id.id, v)) + impl(restArgs, restArgSets, acc :+ v)(env = env.updated(id, v)) } case TLAQuantifierBound.TupleType => argSet.iterator.flatMap { case v@TLAValueTuple(elems) => require(elems.size == ids.size) - impl(restArgs, restArgSets, acc :+ v)(env = env ++ (ids.view.map(_.id.id) zip elems)) + impl(restArgs, restArgSets, acc :+ v)(env = env ++ (ids.view zip elems)) } } } @@ -361,11 +357,11 @@ object TLAExprInterpreter { } case TLAFunctionSubstitution(source, substitutions) => substitutions.foldLeft(interpret(source)) { (fnValue, sub) => - val TLAFunctionSubstitutionPair(_, keys, value) = sub + val TLAFunctionSubstitutionPair(anchor, keys, value) = sub def subKeys(keys: List[TLAFunctionSubstitutionKey], origValue: TLAValue): TLAValue = keys match { - case Nil => interpret(value)(env = env.updated("@", origValue)) + case Nil => interpret(value)(env = env.updated(anchor, origValue)) case TLAFunctionSubstitutionKey(indices) :: restKeys => val indexValue = indices match { case List(index) => interpret(index) @@ -379,7 +375,7 @@ object TLAExprInterpreter { subKeys(keys, fnValue) } - case TLAFunctionSubstitutionAt() => env("@") + case at@TLAFunctionSubstitutionAt() => env(at.refersTo) case expr@(TLAQuantifiedExistential(_, _) | TLAQuantifiedUniversal(_, _)) => // merge universal and existential code paths, because they are so similar val (bounds, body) = expr match { @@ -397,10 +393,10 @@ object TLAExprInterpreter { case TLAQuantifiedExistential(_, _) => _.exists(_) } - def impl(bounds: List[TLAQuantifierBound], boundValues: List[Set[TLAValue]], envAcc: Map[String,TLAValue]): Boolean = + def impl(bounds: List[TLAQuantifierBound], boundValues: List[Set[TLAValue]], envAcc: Map[RefersTo.HasReferences,TLAValue]): Boolean = (bounds, boundValues) match { case (Nil, Nil) => - implicit val env: Map[String,TLAValue] = envAcc + implicit val env: Map[RefersTo.HasReferences,TLAValue] = envAcc interpret(body) match { case TLAValueBool(value) => value } @@ -408,12 +404,12 @@ object TLAExprInterpreter { tpe match { case TLAQuantifierBound.IdsType => val List(id) = ids - fn(set, v => impl(restBounds, restBoundValues, envAcc.updated(id.id.id, v))) + fn(set, v => impl(restBounds, restBoundValues, envAcc.updated(id, v))) case TLAQuantifierBound.TupleType => fn(set, { case TLAValueTuple(elems) => require(ids.size == elems.size) - impl(restBounds, restBoundValues, envAcc ++ (ids.view.map(_.id.id) zip elems)) + impl(restBounds, restBoundValues, envAcc ++ (ids.view zip elems)) }) } case _ => !!! @@ -429,7 +425,7 @@ object TLAExprInterpreter { case TLAQuantifierBound.IdsType => val List(id) = ids TLAValueSet(setValue.filter { v => - interpret(when)(env = env.updated(id.id.id, v)) match { + interpret(when)(env = env.updated(id, v)) match { case TLAValueBool(value) => value } }) @@ -437,7 +433,7 @@ object TLAExprInterpreter { TLAValueSet(setValue.filter { case TLAValueTuple(elems) => require(elems.size == ids.size) - interpret(when)(env = env ++ (ids.view.map(_.id.id) zip elems)) match { + interpret(when)(env = env ++ (ids.view zip elems)) match { case TLAValueBool(value) => value } }) @@ -447,7 +443,7 @@ object TLAExprInterpreter { val boundValues = bounds.view.map(_.set).map(interpret).map { case TLAValueSet(set) => set // require all sets are actual sets }.toList - def impl(bounds: List[TLAQuantifierBound], boundValues: List[Set[TLAValue]])(implicit env: Map[String, TLAValue]): Iterator[TLAValue] = + def impl(bounds: List[TLAQuantifierBound], boundValues: List[Set[TLAValue]])(implicit env: Map[RefersTo.HasReferences, TLAValue]): Iterator[TLAValue] = (bounds, boundValues) match { case (Nil, Nil) => Iterator.single(interpret(body)) case (TLAQuantifierBound(tpe, ids, _) :: restBounds, setValue :: restSetValues) => @@ -455,13 +451,13 @@ object TLAExprInterpreter { case TLAQuantifierBound.IdsType => val List(id) = ids setValue.iterator.flatMap { v => - impl(restBounds, restSetValues)(env = env.updated(id.id.id, v)) + impl(restBounds, restSetValues)(env = env.updated(id, v)) } case TLAQuantifierBound.TupleType => setValue.iterator.flatMap { case TLAValueTuple(elems) => require(ids.size == elems.size) - impl(restBounds, restSetValues)(env = env ++ (ids.view.map(_.id.id) zip elems)) + impl(restBounds, restSetValues)(env = env ++ (ids.view zip elems)) } } case _ => !!! diff --git a/test/files/general/ExprTests.tla b/test/files/general/ExprTests.tla new file mode 100644 index 000000000..091e79a75 --- /dev/null +++ b/test/files/general/ExprTests.tla @@ -0,0 +1,29 @@ +---- MODULE ExprTests ---- +EXTENDS Integers, Sequences, TLC, FiniteSets + +Test1 == { x : x \in { y : y \in { 1, 2, 3} } } + +\* this test is not expected to run; it should compile, however, and it should not cause any scoping errors. +\* at one point, this would cause an obscure mutability bug in the TLA+ parser, due to a rare backtracking scenario. +Test2 == \A <> \in "W\"!> \in [rjg96CqaSMuCjtyr450h6DL1e02XHUTSveCKybqCudAztsOjRmkIEFEkhaCX9AEfDDCOqmuEg0Xtb5AWWeMNM2fXfObxeWMG7AcDR5KDDHmtkGN8Xd |-> Nat, cSOk29itvxzRN2lPY |-> <<>>, cfZGl3Wdyxt6gGxpst0G2YzBErEDXQwzSSWERs9MLYB4BpT7ne6vVOh8FuGMFN9KLaHIP7vJe7ItfvqjAIKw8K8LdrCZt |-> "nybf\*j`.#ogke@%3kx7zwaX;~nx68X6qVB=\"Dj__7mkIq=25>YVw#\\#]8?t=]ndqUQnWNDhr([Q2Zd6;", fHeAZdw1vCnj3xfH9h22hrUcMclAc21eFx |-> <<>>, kPKP6DMtdXB26DOcOq |-> Int, kOufhkQQBNihpnqM5EG2ave4gvDLXzM4eM3AF0s1vozipbR3jl8f25jIZF2l1DrHNVNGzYyh |-> Nat, pes31jiQYk7kh9MbAqDybYqzToYtXL24 |-> 105], <> \in {dVpTt5jrKlWu0I6Hq6H80zTmUxwUAJYO4dKwf6DQfbTQWe9fGr8TtnynL58wFnRcfuVdaQJ6yRM : nocBmpMYH5HkfAmS1Hxov1sNAmNpre32Go2PPwiq2V \in 66, j8KL43er \in 99, uOnSBu75CcElcoR2ZLguWLx24i2 \in Nat, ciyA3piCZqGxtypqDZ7yUA6ZigMVm0gahHBAmufYN8QSkFcoxD5mhB0H1o5fgF4J0oOpzQgazH89oz \in Int, n4vC1IUc6EoStkodAFXDtaZxD3jWmDWSa177v15UbOG2B0yKlCWueKjkDEczLz2NF3SdvY \in Nat, <> \in Nat}, ydWAMLx2MOT5MVTV4DoLy4m630MxBh8OzY27IXNa1UwzilN9ABwtkToLjGTMbiFUNXwOxBlp3LCAIzc3syTXB \in {{zWSbRBDcKvPAzjLcOPdpDMdxHB07sO7kEq9Sk9MydQzf7b5IguRfwHTQeQwDS8uwsPPE77kph4VdYlWi6GlfISwJgzUF5mDwt} : nMDLcmFYG6N5X5qUG4Q4ELPxCZRP1ByOFD8cIbWHPjvMaPtf5Q7BBDw71oHBnalYi6KgmUCNtO0j7r3nAkq7Wn3ClMSz44nnJXpgNIZZydK \in 68, vvmBdcUQcmzi3aF14n2S3Oie2iBRkC6Pq5dh91BNivvWOU8pQ8lX0buK5SxjDEHFi \in Len(Nat), <> \in Tail(<<>>)}, <> \in Nat, g540XiUzWuW \in (Len(Nat))[Int, Head(Nat), Cardinality(<<>>)], aYGs4t9TNazIlSTuMV2UZJE2Su42dELDJebUslriCHsCdePddP6kT4herkEEZkaBrLcr19VzcoQUqUxLDj7aM9GlCyqIWhrn1gQ12Wcafcg \in {{jFSnew60k9UkNMbOwRMQkAjaDOsCVlPPzNCyFhfU0fyWovez0zXZDVqaX3EHHxW8P9RjGDPX8z8k8OPG6zvn : bJdvTIPKLRX2S7AzBaJhHn6qzYpgdcuCSHMXowo \in {}} : jFSnew60k9UkNMbOwRMQkAjaDOsCVlPPzNCyFhfU0fyWovez0zXZDVqaX3EHHxW8P9RjGDPX8z8k8OPG6zvn \in <<>>}, qvEBcszWN2nDUY1XVCrYsYFk8gOLE76XaPswHtQNF9Wf5L5hSOy7zlHGM8C85CJb \in CASE <<"|AP8[H3v] 0TXS4l;{MD>jLmGb~(,$M3&I+03G/|yp\\lCm\"gW{Y,|Jp`i$ICm_%\"\).WjP_Q/lA5">> -> Nat + [] "~ l" -> 34 + [] (Int).tpFXgtDC996txdhqxvc6uTZ7LGguVCIqPWhb4GPq0vrjsU6VJ36ivYQrBcr6eLu6EeizwwVG4duDRq6 -> Cardinality(Nat), <> \in {103, <<{}>>, Tail("ao>Q^45R\*\)&S.P;@h>(g&QFHhB2]CIa,O\)R}&icu\)|> \in [eSmDnVka2T5vfCr2D6NAeJaHIIDOlNw2EtW2rEOQXQPKS5kkyWOloH5TdOSGJ8Bz44giGFHo7gIWf8OEXbvNC4Tf8ygMzR3dqbcqv |-> 69, izEEDYZa31aMoAX0ZZSPtnzZiSJasTS5zXqdJAympTsARWZkLDJD |-> 113, dyEu1EeADkIvzDaPjLTdpJIcifTMU16PgoOR7843Gu7mpKqkARv0JE2u1zPr2eQ4vy0VjJul5uqeh7XlPAPV9enWRCf8t0B0xY0IzPaYhk71Y |-> <<>>, ihxh4hux8hT1KYXTuUzKlwPYkKAA |-> {}, ztbbVgCSX1bb5RMzZV4BCFgYkbdQlRyqG57NRyYuAN37oz96UHjVkC7HEElI4leshq4qEfyyLaNoJgFjFiy1Ucxd5jJpteH1vEaWkHa6yFo0Zzk |-> Int, zjWP4mQbVQ2lc9Ah2qo2sENITxJ9Fk |-> {}, v4uawbLQboCq5rPaF4O4P9LhHxvqZlwWboXHoHD4oeoKTh3DhpLroR9zLte1WE3VZl5QuYZf71I5yofGfhfrcAeWZq4MopRwyEv |-> <<>>], <> \in LET dMBYoW4IrtFxgIWrYPBUK7U82G2P3eAqe8GTlNeOFFlAJ6oEJT(nxVAq5SHVzmvyyLtL6KTp81XDMb1M5gm1tUZ5X3tO6tVeixPGbirwW0b3WSixN9B00CFRj5, a6O9WgcDePw3so7SKk8CrZcBbOAQw21QJa3wAo83WKEVOM0q1MxaUg1, iYzkTIpshRIClbgtt7PCsvhU1p9zHHuWkDkQVQpZYHwqetUCJHB9hzSspxoSd4tazL2qGLqiGljQPkkk1abCepxIxQJMsHHegjnI3ORMkzNW, eibKgFT2bFMHNqSkBKHeq6rDs6QWjrBuaUppNNFWfxfGm6ybgx1y6SRQgPWrTaWtoh8IWCJ7CpHI3sl, ybPgPsNbI2tuE2K1iA1LrW4eXPRY05LyWpBCpRHC8q8iS62OXS5add7In, uqDvk2oF1CmjHdAze6afrN9c6Y0V9mZmsAdaeSgayd15MXEfOsru6LNlEsfLBwtgaQfH3CL18EoRux3NHDZ, vdIscEuUCezJghNA3FcZvKPOuwXLU77vygCZ0btzt4EZt90EMW9p0Alq3rISBmthV7NJiWDtasETDIaFyY4fTyJcrbJZ4nnLLL6hlo1r546GIlFHKhA4mf, yVo6R1IjAptaDLwUA1gBn7YfjaF7ZaAf96NxQxdB0z, pnoaUybvqpbFApkcV39Z6t35wHInxdO1geVF30nzdltg4tzSpvt8eq4z3MMOfMBaiyhRg5ybcnhTyA9zEopw3yI4Z5EjlABh9vADzC8, eTfg0HxBkXQFsmHMM7tzNzFG, sIwkrxLi5Ntu7Cp9N0qYRzetOgu5Q3WJkgiou6rcWtw1FCa0K204YXW7c2cc5QJ8eQlYmRQEB9ZX0D30PR6hrduOxltushIle85WUU7bhAWVR1, cIAnUzlzJJKbDePXcOGU5EHKL9nSXf1, cOK, sf3IfXkK2Ol7Y64A7mgUGWM8S3ccH2, jJb4v29omLKKv5It5RN2x2IFq8HV6Z9HseNGKEWmGMBIkmnDEwUI7QvAxfRH, rsLln4MGBLeC81BgBMGSXX, rZCJJMsv1jAxmyQjMLhsdmH8WMPJ3uctBaF0WdMTLBDSW3HlmBe1n1q9jZVLtpkSRwAnc42l8lLGMKZLQKRY5QAdfUsrDlVIM4JAPdiPsAHxXggP21tB, nUPa2waBp3rkfbbmB0YennfJw33fwZ6nPJ3cdH26J12SZZcOYyVvYjbZi5XORCxTdbP9yCAqwA07HjhaHboBNu, aOXhTn, iJAYyXf8zHNTmbKp3UW5K4B0ALrIWjnZwPYa5eQUPDWP9X0EN1xRAeEW1QltgZANH9Y8cl93VWXWPx1B1CeGtJ0Zc0ra3XJcB4a5dGaEEHoVCB9Bsbp, vZAUwcaw94oKZdAS6NhOEpQjadeImLnBdLABlHcxct1G36MLDBMPzbh, zDJhnifz1, pTnQLAuZpwUaqY55cJuvHq1t330FccrKxkEcnudLOjKgqVjJXw9oj, hRZGwOfVOqCN3NjIwRUIKyhwawc4xTc9ckcVLWqL, itF2FYh99DkOnXp5ZOxbXJhYWRf6Kt5TcbKiMnt8KtN0xPcFwqVhWorFOK1ZkGuUpVvLDl8CtcCzOCJ2ScITCo8tB13EOI8dzwR, t2u9, dsXbyTPuEzKcBmNO3vUoDy8byFgyYwP6vmR8ScQVJvNNE7etXukR97tdfJm, xIqUs2QwtR7b7gzlFAiA0nPagsRcXRIrzd4XwPuSc4iY4gcFOBkk6HhYPbXpD82i6wZA0qPxSDujwkgD5UgOb79C8n327qYeZB3B, jrQMqgDsjm6qLHAjB5pC7RfvvjGzAKPtxxyypA, sjl7d9GZhoCh5nEdbcXF44yFcu9W2BJsCvdIUruGMwUpUfXl6IhhRcqUlNPlX4ZSMmhnM9puS, iFSImI2CjxTF, kDb0r3tV81qr6H4SmFFabkD8DHWDz912PeZxQ7YRh9FjBCwY6eXETGHk1Flvk8zD5JpOPfpDTIezK8Q7uUrfbbKuW4GDDiAI24DnKiJeX6hYL, dBtIva3EV4kBUnhWYYKtDcY68OOM3, gU6JaM23335s9fdd71Iu23H6letgfaEm7RMjPRIJV0EjNOrROJCV6juQ1ZutwHbIHmuiU9JKTbyNlwGrxSgvwbIcctrzzvyj6MagRIpvB4Ue, pf1ouwjozkq46dVUev9IMmjvOCNeQSlMXvY, lEwUC4BNAyX, mu2pHEkSxMpJG4IFjyzfSg0FLj42MK5bnIGesapT8TI2cKhWicQcedPAjtR, c1, d4J4XlhEfuUcKHbFjd0I2EiqomIciQBQ1oCZtXOsXYMexyBzM, mb6VcvGiNqAddoL1U27vHSbT15kiRVI0Ccg8bjGYk4N, v32tgD43e2RMYs3l17XRA0oqcqjgppgbGCXy6kpz2DX9B4SZJWFDSafw28keLFVVr8gz85aSukay, od8zAG, agI3fF6yeEgwn4mHyIS6BzL8ZmZYxIycJlZbOrdWs0PuDp6EIp3OEJ4AZeMwbAaWG8C478nr96ufy32O5B9ya3RNgsiRol8, u5OX7jli7pUvdFlQ5GIWp8Y2V4w1Qq6JuSZNXFX58tCXaGAXNw5yAnpgjN7YI9OxgsMaqOal0gviOTsLnltWWVtP8, mzoT46CbhESG2XuO97YqjAIOTKzWRFV13URZM9bhApen3u, euHzTurEOVp5ibMG93Z5n5QIz6Vvd3yxatMiXyCUL1TpOljdnVUascnrfOSIM1d1kkwCN7PsN2She47ixp, cy1SKKvhNyXaU0a7ucbPfvQvwiWIfyoRR9dniXhyujpGiHWwnxpzVNviq2UbpGMSS6qtMtcfp2Ydfred22sowNl9R, b7awbjj0YYXhTT9cfZAlagT4rkOR4UTbkJ9XcvpT, wFylCz1pj9BXgQIj0iRfz9hzLaZdnzFFwvDUjuuRJZt0dPDMtEUWaLUWP2S0cIPjJLSEm4JW5esqfCFrhOSnlVK, woGgx9rhmhU3Fv5V7YfItdR6Ya4Nn61TZXuHgxRKhWraD82DjSckWU9eh8uVG, van0P1WdGWs0Y4xmIgEo62SjbzMz3KqKj1gaz1Oz2DuZk4Vh0WfhQxUV8lFTdzweshJusd3Wq0pdzmopk5HZtj, fJYgdSPVe8ZGrsDsj5URkQ4Po, dN6swQflYr2n, q2ca764vfjW3dsAunTwWLjNJMOzvDa15EUsScuh0pgXRFYGB7n5KHqLPRYU6Uv5zW2kM9xyB8Uc7tT7Dz5QlGBGW4wE6UkiSZ6DUFQ0KkXgv76x, bphFSsnrvrUTp20JF0EW16OkghBZ4yipad2qK, cSC2XESOcKEYMXaT6Sz2BvHjMCxzJELA1Q9abTKT4LjQSclaxwgn9ZbdD8i3HYBCkwAmLbIcuzbmYEzJT, fiW9J4QVDbOOCcDiC, cV3KndmxEb2jiUtpTbOCzpd, yCLJWfpVGdOnNkUQOtJNxI) == cy1SKKvhNyXaU0a7ucbPfvQvwiWIfyoRR9dniXhyujpGiHWwnxpzVNviq2UbpGMSS6qtMtcfp2Ydfred22sowNl9R + pfutib02oMBk9NA(yqdAEKdWrmQatJbiBbNJGV4dVZvwou9CawoI5, yPLRs5NZFyGM19iZaybEfKGN67EhwEQyCPbjWQZILFN65PjILdMxRcd0OltdhEVSjutjg8uBghJUNRlO0yI1Bb5Z9DPoT1d, npOQdK86ZvrzGID2IYr9pY0illf8rz4MjpchsjYnmGgRoVtWEnCFA0iMo4T3eHtNvMgUd1aAAinQIInp3ZISWlizOHEv, f0TtYSKuVdTGPYsQOEMteXQvyJhifPDPjTBlQj46U5H2jUt9wvVR1dp3aRTPqwG8CA0zLuaDxMtKjiD2dV800Geyu2gVkNBzZrmTgYXHPX1kqM, soLhGyWKqbO7txR4jRH4eAHZyygs9FY2pZ8wGb1MGhe7TrfMxiGbZvexCSQGBkx5HrrpzJYxPfJOnx1qCXj4FP9tYNu, yrgcu41SkT7K, vZ1UpiwtSAw, jQjIvW31GnROQeexcXJQ80yp6ZNlyjfCAXkIVdoUFz5m6hQTJ2YDopUO4ExrulFicvg1qiTTZ09zztaAatIuKEwoZx1Rhl2SAZXgbmbNFDQwc, aTnI591CPvPFMtGM0DSFosqwH19JgWkw6TOAnlLrnzVTvA6GXl6Z7YZslowQ4ggbwiOdmsrbQoA7y26EGj5UThwFCuYClOa1Qk9YBSUgCj, petq1FnADEuTu9jd7L0cRMEQEGA, sCsvwtZfuozhXImI2Qe5nOtioKFhV0toIhWugF1FTkDnOM628v6BcsqgbNgPgwTms, om8AZLqChj5QWTzzuE3Klnu54DYow7CaOgsksEWJbx6rIIn5QIYNfyv0Cg0yqI, sKddX6S4cSfFmEkAfQQ4pnGOsrWyTVp6ohov2ZjNh0m8ddQ3kkuT3V73L9J8pwjLbBaOTclW1sqbCaLOD94UqlQwqfqB1ybAPNidBHJLVtCXV7RtZunR, dTB55b5g2ndHTltMFu8sA6wQO3olGlC763PxW62YsF7SGSfQPrGZtsPsR3d8p9W0rfg0rNre7Vrz, k, pspwuKWUAQfUbXxngJ3Pp7oqrvCJGZdA6ZpbX95Gt4R31sDeMmOmkzXDF5Om6aeyBaIIU8Sd0nAgUQnf3970QQNJcAwx, zROWKKR57TTf4dEuXEAJiX6SQ9ErYYVNfKBpRYozrqAUueR, dlqWvq30vbvbYfBQdWCStgeHLJOk5YktXyAFKEZNlH3zJkk1XXnxG0RgieZPspBK3qDYIkYlGRNetdU, vEUiw8Q3wDBUhfkwu85oGaomRgGEeA8L66dibMQUAP1vLgR, bex3Qs4BmJHBRbUmBOpCNiyEbmD2Odz4XFWO7dHoJpLtrpyX5y06A9aj1if4pGtp3ypR, ov8Dx4HxQI4OGfCgF64Za0TLvm7uUySHtxTY74GOmmpGXQekidK, akX5jEznhGZAVgX6PHCPhJGk2nhgVTgZifC2RIOSbGepu0x0F8ObstfajuRj6wqK67xm67txh1iRpy4GI8pDU5heY7yhBxAofExnVVQjD, wXqzibnzdeZGlKOUZ0nB1vk2EtFdhBkkQmVxIu7m2eCZGV3UVICCsV8lvEDr9APBsdu4mfEw9VDdR) == dTB55b5g2ndHTltMFu8sA6wQO3olGlC763PxW62YsF7SGSfQPrGZtsPsR3d8p9W0rfg0rNre7Vrz + neUJpNvUgPe72LyeUCuIqvKpwvWW1RsckR7JbhK36dduupC2UXn9Dp4xa5ss4jbuOM6aN0ioEhvOnCNNczcf2892nd1lXr6zxe3kQaCDGgnLfiCb1A54f(dD5ZfhEn9lMy6hIQ63MgxLX9SLe9RPt, rpJZqPgaJka0TP8CucacnCDjYjWCP0rv2zonLwMNfdKtHZISwCaY1o6x, tV9nuf6o6CC9hCTmATorYSzU1AbJCuMlAfHT1TtwQkoQba, eMUJ35P0rwLqvjo3peYH3jph3OaRaojx4omEFt, p1TaO7BYWoE1lwn, lNU4xQWfgivqKFBroYAcgsUDRhut81WjH4ZXtuvBmD7xEQiX, b9y9qBsXFMo9tcgGgK52Max3oVCkIXf1Wi, xzlnQAIh2CxHeGGccHITKBdh9YGLfskDJYoruY6mniorWiSEdLYGe9kprlD7TvBvTN1wqC0dI1dV4oej07XJwNFUM, zQojcf8mAmjhlsYNQtRSHEQDGBXEJFemNFJi4MqP0vu1ODY5uUx8jNhHcgxSwGxJXELWxcsZ445R8l4U07gHrPYWMwy33rmKfLShWylo3iAqqDIps5y9Og, fulq67nBveb8AL3sI1xlgkvDS6UDy5HV91Y4t0DytPjc3QbppAtizrmflLJk6CN2l144OGC4k9l6A1zbqTVuKSJKYtoyCIFfmw4be6E, cFt8tyq89IFSpGebi2NJEKCmJyLKWNgjsy5rnlASUvkODy9ydSmXjxfXdJdPTJHqii0FccvBuNizbJpW0bdoOKr7QaRCHXxCu2yBsm1EZncCMroRI7d, nk, b, lgE0x0q5EJR5ZrQ, hk4QcmCfEaV7ynEE65eh8PBEFod3VdG3uc5edimMzdMTf1AAVYSv6cCLWTWqEfEzhixBsZTS0xAlcB3OsLEdMnbLDd2bd2agL4zuItrKeGYj, vWQ6gw57aLsFDgPWbcKGHbg83, srpy4ICi5ffG54wava8hMsJmTP3kNX9KFGjYCO1hGWXP2HNRVqmR78ngBhn6i47E4v5Xe7rxhLcgj3S1sMCK7uktoCJNJX, eiaL4Y4ITF6mZcyoGdIJRgv5brQpLVigkwsbF7ZqIcX0xjHGN1B32KyslDg8FF12SNdc6P64W, yAKiq3OZKALyVMM7u8q172vb3R3cpnLSpOkdyyHW2rAQxwT8BQltZSEzjw4CaqNFQYXbgFkJeWyvdMYyHNNEXwH34ARqUD2GWkOzVDfr4eS6vL, g243CGvyoC3q8ne0IiEs8GZ2kTu6qiksuXKAjiP8aDhLWVWXFyJ, uviiueAso6qFDAKcAO8wS685lBm2vlFpKlQ7kWrSBdmjXsFN4UuYNkpHWdGuGyMTOpd8, qAhiscJ9mgAzK44ja, hG5VnplX93p3NIizc4VLAAFMoQOtyDhjrPfYgjJ, gBMWmxaRYzda9R3DadTlBxtDqtc2oly8G8tmXDQ8feYccWakExMKXFx22vnSDX5zxIsNmIX1OzK1sR1kjiVRDA7zycVR9l3p4, ldiKoihUaHjqHQEKVnAnq5q2C0Rd4U2sABLtL48KvTGG6NOISIfbxVputvRiRkHLnaNQHnH5pBiQ2Mr, vmc7p9sqDSLNNroyrQlIP, diFkx6gTeKJkXFhVWtZ0zWYA6CTm0iXSsoaOcOcg8UjK0Hw0RbkwufGYq9EhYig4iAvHQtRqRiCo7IgPFVOoFlxuHydgkAV, xsrJ0hs1Ke, aP9UfZ2zZEj9UUSK4oxi1LmbJ6PXE8gvU6q3GS04q5VelSnO4TAVpH3Dka8Vj9224XWyXX9dhJyJKVcAQF1, mRAkfC3RBXzPnSa8ZujLPQPTW37kfUKnemy7IZuYpAKByr0gKio9SM8CNRaIvZOJ63ohlyBO6Dj3whzWEDV1DNoHksJwK4lUq1PwWPQEkSkH, v29hQOP4auFwWKQtcJmnxZRzGJwyhHnUS0a4vZ30gR1lPUeG0ZH1t0wfNAYNVN41y2qV5aSCQvY8vFi7S3TEsTCklGLhTGWNqHt0O4cYQYOX, p83nDSVkXu1cQDig5M5QVP4unsNheBIMSGNu, sAeZUPte26396OpJlBpmI0LQE21lOtx5s3t8nCC0YvHHB0CNqCxi0lJiwoEVaN, g4aq2R, ns25X4CXQFuglOEPP, zO6zdF15imNgx8fxuwZNG3p22LNMQWWjBfGMcDPKLQb9tCCs1DKDDbNjqAgipqmZJwqPve0NlsmvCQepmhtZroKqO, ccrlQKb9dTYwhvJmvl4uWJH2I70XwyocP1l3tkGTHX0Y28gm4UZgj7xJGFYs3XMD9AxWEUV66SVsHK, yrortUPsQPz3, vrgY2fCsfzc0y, atADMjtPdHVP, opNmvwtrSNJ4RuT6uRHRSinguWgbzqkMsqQ5PW4k61HUy8toxpm3yo7OmM6FD5gRVIEUwGvz9wgCqgLy6ZPMmVyRP7XRUNP4D9CIFRtHe, gRV96fKPGEWe6yKFHxpuaPq, xDJiZCAbwMbVfbl7WcbMeruamFMGo6B2HMhB8N3KRrvic7qc49iGJb0bt5jCL062D1DLivTmY5TbCyP9Wb29pn7VOb8xdbKjXTY, dXXEkdWvl2, gNOgqr8aJX4zP9l0UaPS6VagarrGqLU6i4JYxxjrzHs7mYmgJF2UuNcsLXJywdPURIQ2xCQnH9wy6Y9VSq1gC0J50pAn04v, pchYX3ZcpKwp, gHzB, wOFfsItrf6nLp7zy7bU7ADoa02aW3yFektlj8rpn8a4CRo9BFMXI5nnjixsR2S1, qmpBaDd0wwAwM26ojdOhI7b2Ue5SUX7IuWhpDaEyxk4vAZTjdUv7jAipAEZd41SjSjvlL5TUt9DlST6ASlDN3ObplY2rp0F3, vPA9, dXNBv1xjF8ZdpX9C5ZY59h, hXQEKzRGitGm2rkfhPfIdX7NNi8fC9eUKHbhKQc0bCYivC0xaHYo4yW9Z2yoPdwib39HnBYNhBDRJTDRTaCCmHUEDffrdt0hDlxNOVQ, m0XmdKuUpvl1bxpzt3eNaLIlYDGcVkOcEU, zgiCcx0Ii2UjTDawJHXK8ztW9TxnEs4BqGMIL0KGRQaZG25eHlZnVVD, oGOiwYg4Ni0FnbwxphNIY, cwECL7xY8iScG2ySRm0ti8l2SM98hhZH6aJ3n0PQlTb6CrOU12M, lx8mkvXnvNTddobS7yISY81hUkWXF2snOu4LxOpUVQdxNdAZWzaTZidvQ4UBQRrrRjcg2, ptUB2ALkx6BCK, cUmKmyddS6PXGo2GUNkzZTN7T8aUYA0TyjV6gg8oQ8km8N, rvcG9Wifo9QGqWkQA5WvYZTzYufmDdQBlhPBoANWGrgHdzdN2lO0phAeCeu8SZdsOzaR968R37lkJpZsbmUgtb4i7FPQtIFgLwfKlSeWx358mVm, rwovOOJgVwMF19p, a7S0yryJFshXqvdklI0kKojQNDdCjzZ8njL6OTEEJoDUELF3hXybX2H2j34fqApjlTLas7RndLmWeG6qHlGhOyzCgtsiZ0Ac47CQHla, zMYCpG8uLegaVSIotRhQZx9PUKAk9VScJbUaj3SIoQmgSdtj9V2ZCbZwo1VcBwjscjYOE, cTVZ9beGFz5WuA0xss0ZcVMok7s3r15KQjkTmwkdfiHoYBzsQm, vKR, hvGdY7ny33CZqb970HPMtRgqxyb38sWpNP3mqaFM3CQIF0MzGSbmSEHFblwNDXjlMjbmd6oojyTEkWwbG8ev426SvUvPZ9A, m3pIRkjqdB9DhTQmsqsPA9jjo9dtLe5mvTUlTIQQYTPzRraJUf3LhrMwlEr4tDz2kKvxYyzWUPJ8EjiiHKNKCXEwEZoxVeJf772cnNx3WWuCx, r51OBn836H4CGwaJbpKGSPoz2Po91zoZIvhLGK3o9k9cC7nDxL65U0g1z1ZH6SRsJ, sidyALRX9OvYQ64hbL3cEsPe0uJU54P, ga, pb7Hf9j3EU0fbPaQCJQBMELlAYwXQxoYkOWXxaA9r4NGEO6SWvJyMkzPaibJ7IdF2SoiamwTX23EVkG7LbBVAM4VhhrTULwtCWWSSLFVgKl, rdW5Fk2Xx9e69ZaE5r2a5LVVkO28ktahTi37iiNWVfM7OmTwDZXnoapZ2zZ23rbUFfBgi5Ci858X10XQUAsdKLQS9Rhb0D46jH, u0umaKghoGC1G6mnpX9aEDFLa9OyEPh1KfTJ2XtKcmX2gKfcN1yMKgAiPgrX5Y97NLxnkI50K7fh4yh, tTmkofWz52M2axQpt6G4OMLgBcYOQdI3KBdWdFrGq4Yda58ua, uphJqGX9ZtsAfGdpAd4mdG0SrI6BNfG39y4KCNb1pJugfMZaOEzfodJY, alki5J0u0ZkgrMwbrPRnhcNyFwEkMNzj1pZdybyIUA9DwZtyEtDMem5uM7NxfYZroUPGAxgjDAditFdK8Kcw6TBPwZ3dQQmsU, naXIPTVHPd9, uyqvkdRlrbdXkbb1ABUeKJrZpArqCmDs3O3oPlX, jj8GIOzvZwvVFjltDA5TlBEtc0thYFrEsT6AYhuTR1DCfRjSYsVExVFXH3kludlk, ieZaTIVxTgxp4XntAsQOYQiSvSiSzvhtep7YT7aG3eKqH3MfzAo4WcjBx65PerpVd, whwF81Q8dhsvJdCQotqTLGbBiGuprfUBKRivefPWwIc1Xv8qA8HKIjqNcwarJ2ywKAXiPeFuF1fGcby1Ur, k, moKtttvRNzgiambEv0ElsCn6SOnGFRtwdcwAG29VbIQADaZAhM037grEV80IiS9NXggAW1g6VMQ0omx9XrAvJ7PcqBFkKi188lEes6kJq3cx1rdArLgM, jM0j1vnW9Ph4mrAgkNml08uYIFLEOMyaTss5EIhHKPvtaTTtrkI, gSSsoo0WfLIj4c4pSfB7SH7FnRPf5BbXG3Mc6P6keRNHhbSQgnV9k7fqiumr11djFHVEAudmOEZ2l8D8hwZVsgHpXKH8CmUp09rXlTnZegeJ2yJiGg, cEgq0WGJ4n9DXPcG1DQITQYPNFnmefNHJ0gdAnOehKZ2p6GyG6dQg, xGBke, fFZ3jGvpoJ6qs0TpDOjWxZ6mt4OEwL85kU5gEJqg5PFLEcgUZ, bwhE3, vNawQMPnoqjbFKmoVzXFFj4MwASHGDlEsKnciZSThPfc6iBHAuT6Q2YrKatxfj, lJ3A33n8Mq8N1x8r2aN10aY5KsOvYQ3zHasBY7b8E7MeEBZdKNOrAKHFoEXfv8VsRcmUOjUq, g33CYBTGPqF92hNZUIGRp6UD5aECTMSEJd6FpHJQxOY7CtKloNalX6iyEznlLIfKye109jwqbAtkEYzgh4ocEtcY6NhlUUgdK7sVR8ywttsjkKYWnxXId, xgfnyJIytCnNTK, ocEx4eG5KiMIDuAKa3dejESCdVvgKPoXAmkyA5hbCRXMuX7rENyPIo, q6MTUPxEAeyXKMifVbWAq5yiwxg0WcPqJPO92LkmCdDHggelkCkd9dNLT9aFBaZ3YONXBk9EWDNlzIlMGTojmRcGiV6RYIwJ6NAGeVNFTgs4WBf3Wl, eYaJ0EQqIPYRLHBvqxhVnw5MCrO2yFLWx51zWw5Of9y, qC0lAOIYQE3zbfIiluDtQbX9kAzSxirqj9YNSH8C1JHkAErAIy1H4XSevvZAiDD8PELJG7VHi, eP5qEMgP2Xnk30GtLMzD5LEEp8xhqXaLKSqNIhCtj8mQINTnYfrdZIBiIiu, q2lslxSqzKtgsPRsGzKgsKKJtrcbcVRgCCy, pPVCCskU8t4Fbz6INc3sZRwlTvGTC6zWoY5tU2DcNbdF2Ici93tTq3JATIBcPCuHtvaBsdXUaJz, yUzmfhluvJPwrDp1VLRCY5ie1uvw9DGG7E0fYsp3r3cQOGc03HgWouEucwYBQ08HaXYsn, fqEDJDLNtlexAS4PhM6sKqSqS1YZOMhojD9DFqH8Us6zkaEBVKv3ohCj5AHpC54qu5Yzi0604JQRIY8, iDA6ycv5MPxc3hgQ16SRcpMd8GrKYzB6WxeGF9k, y4DZIxYVUiiATh6NltzAHxY0VsH6M3MCkL3n3eon1lxXVFUqYDky0qGGaL1ksz5XBUXbD6d79dcxf2aVIOiZuQiC6Aru3KsXRLwaBH, qAPu, u, bOIsQ8d8GVM) == aP9UfZ2zZEj9UUSK4oxi1LmbJ6PXE8gvU6q3GS04q5VelSnO4TAVpH3Dka8Vj9224XWyXX9dhJyJKVcAQF1 + ukBmRCtcxU4Z3Yksh0YjLv37MqG99dzPRYxTVv8OCeIwGKh9SwfPSVAXDxWm4T(nyb2Il2gW8dHLUWW4p0IPl7lRCwDCI, q71PuuOLcWFWM12bsnpvqgv4m7uQpM5SbNYxFzyUcheNfOrOdgOv7ZC8TSURQVM4CxsuHzya3uFEVJ65Rne6lO, jGueCxB, jDsrI935UaJyVhce, m8pHde1ec1gY, iotRSKGrRcs4opYC21UM9ERt4bwPjxjwD18a9TYB4EJsQtpFPuybb8xGLgWJDg5Z0eNeGMNC, rsBUK9zYElS2cQsqX2vNWgNm1qAloPP4RPtciMXDX45EhzTPMNp6RZhLlzFovaVdHdO0EViwTttInwqNRjPa1Q3CyeY0ZD5GVAGgHorv7n6AT6, aCbVK4bc44RJSB12Mbba4KhlNUd2AoJSGb2vUKIp1S29aIRGhxh02jYga, dR0tnBY9KUovDwO19VKuTnmSIBpDGgC7u721Hv, x1lnZT49wU1tTxyMcVQYceJ5gmsIwMromJTw8YiWNjDZn1is8psWwz7nvSZrFz50dHVgwJXdAemzpgMZzAsmt, ehKs6sNuZhfo60rG2sg3R1QE5CVTcWG2N7K5WtJBizlRZLVtd, sR7JVAjAVdvlxD456IJ3NvuT0CmjliP, kdUl2CTj, y7TkhjqDzL6ubH, o6thVMlWBmtwYbrcrEiBB8WQfeKvMhyAeCv1P87Aya, u5J9mWoWXYLh5wmdR6YjKcUJtt9qCeQZDAl, jDJPvWrhjydEEYKuKlywSj3ULE10h2dDfhGpjTlGPj7ImhAEMVwXqE24JKmYSzZ7Mp2ftKU5KWoVhxRRGFDKETVR9k0Eavmp, natnlvtTyMOYXqw5u7fHGg0iELBvSL70dxn6PDm8j3SbDjWSkggBG4DFQvO0yCEXBBfAe3bzn0PIem1NIWvi1, lRXB1iqx08OAZGcFwFyuApGbCzQM8qvAq4SC7nOST4awVvYYChJKet, zlm90l5Tu12iJlCg5vGwjGfieiFxrqp27XXNJsCaWlwnrl4wMWIrzdD4u8oJ6i5lXO9e) == lRXB1iqx08OAZGcFwFyuApGbCzQM8qvAq4SC7nOST4awVvYYChJKet + bxqRuwNj67l1Tw0tG4FnJoCpbcwAITjSRFP1I7Gz9BYYEOtYCbQNVLKoEIx0CSFwIyMkChMguq0JB4zT4HXTZdyPn0hn6D4EmtYKzcNEuKBXWJ(uQKOCatlf16egTz9aQedQmOycWBubYLr0FK6oPRqXKV3dbBmO08OiqIS6fYMbg3da7N42C7TZsObO5CaU1CA9051loKrLv4lqizxYz7XN8s8, aSBKtbpBn3rK2oORAyA6MoTROaa77w7IwzLtDcsgLax5OF1Og6b17CUWWGPW8Rg2wBSQDrrkqQqZbqgQbmnNB3icV1KjqtR6XXRZDe, cvWtM6M0aZ9GrzoKN4gllrlyIjtOUWUKBQiGXYT7DFyFzcRB0, lHiIHLn7Dmi2N0yX06JfZlhPboAMDmDkX6nKXZSHwvuzdAwMzrRjjaaIGcNZoDr, q3GxRQPGNOiCkdTjH3XOLCIEHSCR4qK593q75ytYrCnibjD, aC6bZpF0eo7Nc40PnIq9BnapFYjDthyAe7T8V9XI7ePR3VIuihpwqEJuWO7Sga1Ar2EtAYmgzOekIDFnWGhAIDMCh66OYflzfGtwLkUFuvw, aIThXsUSsufSEXBuWRynAC1amycmWnjFNzk2YZoQdw, azy3TQcyTDxmalOQ8hQ1R, x2vzC1BV0ccqEb0JQH4JNj1lxdAJqAS5JqYM3n6MfsAgoxBuMeWfVivojVbSebpV2Isyle3x7bQSiIBLdehUUpT7WcRtrxwTbeBM, dycm4g, e6fp7MZDbcL40Dzxi19tsqc0NOFOMptZXKok3cNaw39jz1Y5olxY, fvpGUtlF4jbJlaEYIEf0KKErG9yMSULSamF3p6uX0ekan7FkYJ1GfGY38FnvaI1xCmJ8, tJZWvhtv5t3w4YOudUqIqxcButdvxdk7QrSkfXrRqxVm0PDDbkDGjxXusW1zEUOz8vtC33GLKmLiaHqvodkyGwzNQqMDN9G7YlWvHFkqz, d9CiJ67ihdcsq1zGpto, l, kfrmqCShcCimYColT2QdFsygTpY1UvNUpV1F0OowzVmgYWEGVThFFpDzf2kmV2bkY7iGzh3wjpLozJIKcFM8I7jjzR6xT65S2N8DLzSvyNlfmE3fgRF04, kiEBQpQU1jo6xyK8efcGcW0jAoRCr5r4wnEavbUsAdlxFvgolAab8QdiIp1Gn992bqEFPvfvm34BvkOQO6, iKFAEtFY7hy4ljNTleW62hcjlpteNLqZpH5UB3uQ5AYqimTymiXDGyjxbjepAcESn8IHZ6bUyxrMKTlGHw8vtAMSzjCVEk7, xgAmcY408twaQxSDXaB8ExSZhkDoIOUqrEDbuUPW6KriB9WX4oItCZGLuCw7zRBWKv6auaHR, hk4VkY4ZiUu63GVigOsSjHmYOyH7djLQNJH, o5IzQoYsUrfVa4i30vvpTktVYGMTG03IMKqD2O8tzsSPuBM3f, q08mHqx7dfTfgggiLK2aNOcXIE2Qu1aXdk0xNvjGzhAfytfEqhn7PI8dZbzgmKhCTuLHcZsTNglm1ZRGzkYO, aJ6DcsWlrdtzTbSTp2pOl1Hbhlato7S9I4f6veppCSYWAiGQuamaV2aG5nVfKUHl3wyOpJZqGTgP7wJJVtvg1a3N, qGugRgMtXAsyiug2, jfMuGqGfx3uqKFk5SD2sEJ275K88pOCqxvsQhMMO891qzSPrX, jtY6HpnYNk6doqATtd, iN7xhv1MzuzYOiCT4Sh7VEShwfS6sa2FuSTedejWWSnBGSArKrArNYfPvncTWyAvaLlVSyF1QuOnxdjlfimPKqXVCidOfv, fsovO0g0buqgPfCT0iUyGA9qkdqp0xiHMAIG49G55vlE09nKWbLyZtvKsrDMVdanfzutwMxLqAmTYzcrqnEllcQqBl4BvccoSuTAO8, yNtOMcEdkEmNHxHRNr4rjaNgiwfw1GDkwQD6XPeqiRyGlBjcQL7YYe4S5Zio834Tr5wv3WEroBdFzeiBT3q5qvcwkjZS80CYMh0GYdA1, eUKe2HagRA189MJo06zexEUWOxxG42bmGx6udVAj5e9DmDbWOWIR99Gy9cksjYRqdTDipT87p7Xg1O0422N2qKqmcIGLqn, b8ddK4eqk8erPJfE3PuBCt6R1nR8z7NaX3af8RpBE8BmAREE4Dm5TkAjRAok0lqrmVEt31Z2eIU, jlw8fsBEtqRnuqaouK2iwD, u0HfGRjE5jId7Jhdx9DjpuZyYrWocemqVPN2AduRPIFnNOINUlVrveUoHJYa2BwoL9qWNMkvPO00sIMUJNP, zZrD2GEI3btaWmmFMhTWt6njd56i9O2AhKTWC8sBzgZYFJjbN8JG8qvCWGfOx8sHyBtJVWKg11uGBZxp, rJANcC7QzWMHjQUaXUF2mXXhnc16yDhM1fHMS9ySiXRK3R0AnaDWDuff, a4kMZiT0UviUzwO7ZTaBAipAVX3NmEFSECOZuvdMwni2OUgKP0tjPxcLFcMVpe3GxGsUwIRp04H9GPhywpx, d1ZxaiQ7KROXHTKbugNHaWJwzfqFqpnZvqF0uVRvL6qe4NDOlicOjmSIRG3aCAQNDVjqA8T7hcKt6L748YJjXpsT, dkh9dftAKQCsEu, uBHkN6sQPuvNQ2R4SxtqVtCWabcO6Cw9u9, tSr2ZDgbgVIWcGa, sfH8ZI89OKbTq2, r, dW1tf5x24MAFXIZwyZL14oxKVN28EhJkpIYSmr64ETHGdMn0GSx7udq2c, t1Vj1Y9RtOoB93Ckt6kan7wmWcLVaxgOOyiX5N6USZkFreiIb9ZabpDGYMtLJwTStnXx24GHIU15QqTnsAOaqSeOoV7Trv6sk2L, n2LQazbNy71xCM5yt9hndpmiEGboqRJ15GZ29b2B, ynKpefQii8aRVNTmUfBP9dP9B2QRq1pU5SyFa7Ypq7CfIV7ZrouSG2JWHiA0c7BAy, ocsxTpiMPrCwBoKLmnJnVTDAIygjTtQq3HK4ZLnetcZVv6Ego8thDXL6MGaWRUdlSzqMeTjId4DsWdnomE26RGdNObdgArTJTMu64ewiS, xHPS0KAxYP4ARqQi6DAEH58yXjI5cyycLKcsZyxy4Kj2IWjcTDW0cA, wxIfXMQKmfhuwZ1AkGH2joSj8Js4E, mXLeZojiw7j0DmWYcbEzGgKD3XxcD3bElIEzpvo2zc124j7eNKJm35WBANvQfL, aw4BXjBAl0R2ui, ou9g1IqqeQfEnYj, k4WP6HSX60Pe7oJUbyiD, hXBgjNmFO64gshs3, dBesg6m9CJunJHw5V9DVeTONVdkh6zQ4qDLYyMIV94vYM85zh4ykeswLKbyj0YSa, raR1ezEVYkGNdZ8dfrwfWa9s6WF, erPhH0uA9ar74awWPit8BRDHHVvWm9PAN5YQ2r, zXgx1ZIcnmfAt8eeR6AoYrUZxMN3PDKsBFjHRPMCUM4kSQHAPzNFMwHA7kulY5mmd1IqmmZrbtgqJ1go9, wX4DbY5Cjz74DH2EBMTqEEmAgPmORwLzyzvrgzK61cM1FkFWNOuXRRjxGvySbh47uekGKC51CZH0K6PnSYnf, pHQbaz8L2o4vtwfkHITGp3hLmBsEzUfnnREIVVb7w0QPiLtnO5wQOvOCUsnefuaS92hqEfEovByLvfZSALyW53iZ0B, vN0oAukCuH1tidxYDNv3tpho9bGH3dSN73iLyPT4LBhKLcweYencnOhr0IVE2WqOLpNqmSXM9e9EmuyntNAvXX1zAXw8, zwwrnscjMRSo4ybtRdBfaCWo5p, u9NLz8UiJfrpRokx6Klej3lJwzxIXELFLovaChsZCbaF7sRLeAjVOdqXk6wPOqM0b2hsfLzYigVIw2IeHxumWrhdxz30Db7itIInwdLJENUAR4, onQcOt48AFx2g3vcKr7JeP16DTWGKYuPbOPe0fPztj1pyHS5P4VKSrUkX9DuGqNISiGnqoDfMWtPqJ695WBCVZuqsy87ZWLKreaaiJJlL2mQEvTKGcq, nzSv46djtF8jRAb0x1tkPL0pJAgZeGMg8mjp0HfO79wuKKHL17c4Qouz528vcFr7U7U7qSK2EHn41dubI, haqvardC6HFV9aBiVpOkhAZOCsnl0AdN7O5jSmdwo4FOHk8GRwsYhBL8Vojo2YZubGmtsEVBuL8OgqDX7go36puITdRih4, tdDITA9zAIMITHRr8Tu7k1MKQvapl1SjqGBfkNpAq7C4WPXgALuD22gJlCQEkDwFLZDM3B, gtcDnKpcoxXxmgSEaDbvuU0S3JFm) == xgAmcY408twaQxSDXaB8ExSZhkDoIOUqrEDbuUPW6KriB9WX4oItCZGLuCw7zRBWKv6auaHR + oGNcam7no50VFS9bNVSLFrVV9tFOTIhTwd9VlrW1xT(am8bWyy6KnGD7pbjuRLHR01nW, i0s8KBm44MBD7jP973D5Eu4zNKCiXaPohAQsXTb4CMmE4z7uccxlcgtrtLf6tVytqIhsXxkf, kwC5NvLfjhrgra7nBauJjJdcPCGZMVFBHk9of51zPNdpV0LNTaraqDEhs9qKYY8Gngi5uy9gknn, ehW25vry3ut0fMujKtUZrmrmPZ7SGzViNd7FExfqWnXySATsZ0eFyWdwwbSx5a8XFouh1UrVdF3otRcwQsbBWkjICbhdFUD0zy6VKEfDFJ4qJ8rlBpk, vcYhmXYbqt6NOh, fjjQWlZST5w8UQJSGYmMExwrE4KiHMs2vva86I7hMGFIXjZMt6Pr6inLcbQaI2fDvv3wzAj, iGP7JEUvz0e5rYJkVm4vSagOFQ98H9ywKRqYsAca8p4yX5XVkKKphJUGP4n, cStGYyv8V, l1CWGSnDAFA9JP69nGrlo2f5ohVH7g6O4yTqWxznzWqFPNBGhTDvk1nDQDU398teHkao4sK2n38qz7zl, aiV1iGsofLK7qe1lQxjSZe55J51Q0s4z, mb2f4sCh9wj7JdY2V3cEmrIv99amnXuMutObxCvZ5aqlj72, p05MeTxF9stYUJ2JXqTIioRDLc4, cZHjp2fGGJxnXXb2t9XjqSQprA5WQtkCwSETFbkGseDOjuuZRbJo6VRiLEn, zyaZUPLlnqpNKeTj3tokZX4dDrnkdjnPvHdgCamm8YLu0WH8IWxsYZnE7tsnbXfHudC7VRYjNvOinB9oyHyaIRlCVKAF2M7dkDCbYxQKSKTU1q9SGZ, uJh6jOSh5uGYgEEzpgdPGVh4TXRlrRvsDzgqdchE5JJdHJTfqOLbxIlSoJf, vXSvT2saRKtTIpFQ9Lb15wveUQM82wTqNV7k2ilR3nd0leLNv8KIm3nmq51aDmkfPmTHRBaNAbZLxFouVAd4ywUHeHEA3tA8mYYCCDpcJNhzIsPo, koSPqSVrdMCYlCkJixR4xlBZmf47UdD0qwxD36fauTxnkYeonmYd3VgUmL695pjXrOsE5puEJtJn, toHkXVSgsIWfecbbl4rfUKKsNhId3D, vLzSLfHX7fGw3l) == l1CWGSnDAFA9JP69nGrlo2f5ohVH7g6O4yTqWxznzWqFPNBGhTDvk1nDQDU398teHkao4sK2n38qz7zl + IN <<>>, gSapU9sycL2vu74K0nFmmgiTgxxxtWq92c0ho \in [bV2U08WxrbJW4YyisaWLdDTlnnQZN48YPIYI1 \in Seq({}), <> \in ";nT!E/a\"~A'^[uvN51;+TePI5&t$^^Daj.]7eDe:_41h;{8(jzvkM`TLwt8" |-> Head({})], <> \in {qxbM0ySqkdzWhn6gaROcgBgxFwsaY7adHaF3zhWU3qvyZMiXDYvhlbWBjZSc6nCHr8DLrsWqkB1ZScZHg8LjT4uJqajwOdLZpq4pEzU6a6Gc : <> \in "Or4uYZ'{+a\*`I/tHTU'@Fw=}G/B/d%h\):%R.FE[0}o-\\ -8'jRgIskN&SKdu\\,\"\)9%r;op>bex\)&O5eqhS/xtaJG,nV#QWjd-c_f:\)d", oyarDkIO1XeNWlRTWPoDsk1rDzx2KhOGK4xnI3CjESXu \in Nat, lAPrrMqrU4ntxPtOdkQigX04o9A1UhGZEbuFmCpVZXsEtPOamE6NNhWjuNSx4u9QGUQi1eGldztPwD9aM6xX3 \in 55, <> \in ">&cXJ\)Blo@-}ot<1`,WaQ4UI%BWVB\)psW,;X", <> \in <<>>, <> \in 68}, nrk37ZYFObeGv0nT \in {"w5:3;Z'1> \in f8FerpPpvVx9MMkWzCPTDTuHTYdIgpO2mcb8SJJFRoo6DrVmr9MPdwFWO4DUFYF6L2lp7vY3RgJuBCEHbcRwltB2NSEmn0RsHtvn4Dchoua9Zh, <> \in uTBOegzf41xwPV9PP4Jyej8A4q8GFeUm044NwlkPT5BL3eI1AIfiH8e |-> kKa0FOAnjnOrXmqpw5mzjiGjspYPvCI3puDlt1jTnz0hhp6eg73Xe9igS9tmIDWBiLcPUA9cZz9cSSqKDCG5DRShCWvfozxKiwTRbTHl93hm] + +\* this being empty is also a test; can PGo compile 0 archetypes? +(* --mpcal ExprTests { + +} + +\* BEGIN PLUSCAL TRANSLATION + +\* END PLUSCAL TRANSLATION +*) + +\* BEGIN TRANSLATION +==== \ No newline at end of file diff --git a/test/files/general/ExprTests.tla.expectpcal b/test/files/general/ExprTests.tla.expectpcal new file mode 100644 index 000000000..66fd8c190 --- /dev/null +++ b/test/files/general/ExprTests.tla.expectpcal @@ -0,0 +1,34 @@ +---- MODULE ExprTests ---- +EXTENDS Integers, Sequences, TLC, FiniteSets + +Test1 == { x : x \in { y : y \in { 1, 2, 3} } } + +\* this test is not expected to run; it should compile, however, and it should not cause any scoping errors. +\* at one point, this would cause an obscure mutability bug in the TLA+ parser, due to a rare backtracking scenario. +Test2 == \A <> \in "W\"!> \in [rjg96CqaSMuCjtyr450h6DL1e02XHUTSveCKybqCudAztsOjRmkIEFEkhaCX9AEfDDCOqmuEg0Xtb5AWWeMNM2fXfObxeWMG7AcDR5KDDHmtkGN8Xd |-> Nat, cSOk29itvxzRN2lPY |-> <<>>, cfZGl3Wdyxt6gGxpst0G2YzBErEDXQwzSSWERs9MLYB4BpT7ne6vVOh8FuGMFN9KLaHIP7vJe7ItfvqjAIKw8K8LdrCZt |-> "nybf\*j`.#ogke@%3kx7zwaX;~nx68X6qVB=\"Dj__7mkIq=25>YVw#\\#]8?t=]ndqUQnWNDhr([Q2Zd6;", fHeAZdw1vCnj3xfH9h22hrUcMclAc21eFx |-> <<>>, kPKP6DMtdXB26DOcOq |-> Int, kOufhkQQBNihpnqM5EG2ave4gvDLXzM4eM3AF0s1vozipbR3jl8f25jIZF2l1DrHNVNGzYyh |-> Nat, pes31jiQYk7kh9MbAqDybYqzToYtXL24 |-> 105], <> \in {dVpTt5jrKlWu0I6Hq6H80zTmUxwUAJYO4dKwf6DQfbTQWe9fGr8TtnynL58wFnRcfuVdaQJ6yRM : nocBmpMYH5HkfAmS1Hxov1sNAmNpre32Go2PPwiq2V \in 66, j8KL43er \in 99, uOnSBu75CcElcoR2ZLguWLx24i2 \in Nat, ciyA3piCZqGxtypqDZ7yUA6ZigMVm0gahHBAmufYN8QSkFcoxD5mhB0H1o5fgF4J0oOpzQgazH89oz \in Int, n4vC1IUc6EoStkodAFXDtaZxD3jWmDWSa177v15UbOG2B0yKlCWueKjkDEczLz2NF3SdvY \in Nat, <> \in Nat}, ydWAMLx2MOT5MVTV4DoLy4m630MxBh8OzY27IXNa1UwzilN9ABwtkToLjGTMbiFUNXwOxBlp3LCAIzc3syTXB \in {{zWSbRBDcKvPAzjLcOPdpDMdxHB07sO7kEq9Sk9MydQzf7b5IguRfwHTQeQwDS8uwsPPE77kph4VdYlWi6GlfISwJgzUF5mDwt} : nMDLcmFYG6N5X5qUG4Q4ELPxCZRP1ByOFD8cIbWHPjvMaPtf5Q7BBDw71oHBnalYi6KgmUCNtO0j7r3nAkq7Wn3ClMSz44nnJXpgNIZZydK \in 68, vvmBdcUQcmzi3aF14n2S3Oie2iBRkC6Pq5dh91BNivvWOU8pQ8lX0buK5SxjDEHFi \in Len(Nat), <> \in Tail(<<>>)}, <> \in Nat, g540XiUzWuW \in (Len(Nat))[Int, Head(Nat), Cardinality(<<>>)], aYGs4t9TNazIlSTuMV2UZJE2Su42dELDJebUslriCHsCdePddP6kT4herkEEZkaBrLcr19VzcoQUqUxLDj7aM9GlCyqIWhrn1gQ12Wcafcg \in {{jFSnew60k9UkNMbOwRMQkAjaDOsCVlPPzNCyFhfU0fyWovez0zXZDVqaX3EHHxW8P9RjGDPX8z8k8OPG6zvn : bJdvTIPKLRX2S7AzBaJhHn6qzYpgdcuCSHMXowo \in {}} : jFSnew60k9UkNMbOwRMQkAjaDOsCVlPPzNCyFhfU0fyWovez0zXZDVqaX3EHHxW8P9RjGDPX8z8k8OPG6zvn \in <<>>}, qvEBcszWN2nDUY1XVCrYsYFk8gOLE76XaPswHtQNF9Wf5L5hSOy7zlHGM8C85CJb \in CASE <<"|AP8[H3v] 0TXS4l;{MD>jLmGb~(,$M3&I+03G/|yp\\lCm\"gW{Y,|Jp`i$ICm_%\"\).WjP_Q/lA5">> -> Nat + [] "~ l" -> 34 + [] (Int).tpFXgtDC996txdhqxvc6uTZ7LGguVCIqPWhb4GPq0vrjsU6VJ36ivYQrBcr6eLu6EeizwwVG4duDRq6 -> Cardinality(Nat), <> \in {103, <<{}>>, Tail("ao>Q^45R\*\)&S.P;@h>(g&QFHhB2]CIa,O\)R}&icu\)|> \in [eSmDnVka2T5vfCr2D6NAeJaHIIDOlNw2EtW2rEOQXQPKS5kkyWOloH5TdOSGJ8Bz44giGFHo7gIWf8OEXbvNC4Tf8ygMzR3dqbcqv |-> 69, izEEDYZa31aMoAX0ZZSPtnzZiSJasTS5zXqdJAympTsARWZkLDJD |-> 113, dyEu1EeADkIvzDaPjLTdpJIcifTMU16PgoOR7843Gu7mpKqkARv0JE2u1zPr2eQ4vy0VjJul5uqeh7XlPAPV9enWRCf8t0B0xY0IzPaYhk71Y |-> <<>>, ihxh4hux8hT1KYXTuUzKlwPYkKAA |-> {}, ztbbVgCSX1bb5RMzZV4BCFgYkbdQlRyqG57NRyYuAN37oz96UHjVkC7HEElI4leshq4qEfyyLaNoJgFjFiy1Ucxd5jJpteH1vEaWkHa6yFo0Zzk |-> Int, zjWP4mQbVQ2lc9Ah2qo2sENITxJ9Fk |-> {}, v4uawbLQboCq5rPaF4O4P9LhHxvqZlwWboXHoHD4oeoKTh3DhpLroR9zLte1WE3VZl5QuYZf71I5yofGfhfrcAeWZq4MopRwyEv |-> <<>>], <> \in LET dMBYoW4IrtFxgIWrYPBUK7U82G2P3eAqe8GTlNeOFFlAJ6oEJT(nxVAq5SHVzmvyyLtL6KTp81XDMb1M5gm1tUZ5X3tO6tVeixPGbirwW0b3WSixN9B00CFRj5, a6O9WgcDePw3so7SKk8CrZcBbOAQw21QJa3wAo83WKEVOM0q1MxaUg1, iYzkTIpshRIClbgtt7PCsvhU1p9zHHuWkDkQVQpZYHwqetUCJHB9hzSspxoSd4tazL2qGLqiGljQPkkk1abCepxIxQJMsHHegjnI3ORMkzNW, eibKgFT2bFMHNqSkBKHeq6rDs6QWjrBuaUppNNFWfxfGm6ybgx1y6SRQgPWrTaWtoh8IWCJ7CpHI3sl, ybPgPsNbI2tuE2K1iA1LrW4eXPRY05LyWpBCpRHC8q8iS62OXS5add7In, uqDvk2oF1CmjHdAze6afrN9c6Y0V9mZmsAdaeSgayd15MXEfOsru6LNlEsfLBwtgaQfH3CL18EoRux3NHDZ, vdIscEuUCezJghNA3FcZvKPOuwXLU77vygCZ0btzt4EZt90EMW9p0Alq3rISBmthV7NJiWDtasETDIaFyY4fTyJcrbJZ4nnLLL6hlo1r546GIlFHKhA4mf, yVo6R1IjAptaDLwUA1gBn7YfjaF7ZaAf96NxQxdB0z, pnoaUybvqpbFApkcV39Z6t35wHInxdO1geVF30nzdltg4tzSpvt8eq4z3MMOfMBaiyhRg5ybcnhTyA9zEopw3yI4Z5EjlABh9vADzC8, eTfg0HxBkXQFsmHMM7tzNzFG, sIwkrxLi5Ntu7Cp9N0qYRzetOgu5Q3WJkgiou6rcWtw1FCa0K204YXW7c2cc5QJ8eQlYmRQEB9ZX0D30PR6hrduOxltushIle85WUU7bhAWVR1, cIAnUzlzJJKbDePXcOGU5EHKL9nSXf1, cOK, sf3IfXkK2Ol7Y64A7mgUGWM8S3ccH2, jJb4v29omLKKv5It5RN2x2IFq8HV6Z9HseNGKEWmGMBIkmnDEwUI7QvAxfRH, rsLln4MGBLeC81BgBMGSXX, rZCJJMsv1jAxmyQjMLhsdmH8WMPJ3uctBaF0WdMTLBDSW3HlmBe1n1q9jZVLtpkSRwAnc42l8lLGMKZLQKRY5QAdfUsrDlVIM4JAPdiPsAHxXggP21tB, nUPa2waBp3rkfbbmB0YennfJw33fwZ6nPJ3cdH26J12SZZcOYyVvYjbZi5XORCxTdbP9yCAqwA07HjhaHboBNu, aOXhTn, iJAYyXf8zHNTmbKp3UW5K4B0ALrIWjnZwPYa5eQUPDWP9X0EN1xRAeEW1QltgZANH9Y8cl93VWXWPx1B1CeGtJ0Zc0ra3XJcB4a5dGaEEHoVCB9Bsbp, vZAUwcaw94oKZdAS6NhOEpQjadeImLnBdLABlHcxct1G36MLDBMPzbh, zDJhnifz1, pTnQLAuZpwUaqY55cJuvHq1t330FccrKxkEcnudLOjKgqVjJXw9oj, hRZGwOfVOqCN3NjIwRUIKyhwawc4xTc9ckcVLWqL, itF2FYh99DkOnXp5ZOxbXJhYWRf6Kt5TcbKiMnt8KtN0xPcFwqVhWorFOK1ZkGuUpVvLDl8CtcCzOCJ2ScITCo8tB13EOI8dzwR, t2u9, dsXbyTPuEzKcBmNO3vUoDy8byFgyYwP6vmR8ScQVJvNNE7etXukR97tdfJm, xIqUs2QwtR7b7gzlFAiA0nPagsRcXRIrzd4XwPuSc4iY4gcFOBkk6HhYPbXpD82i6wZA0qPxSDujwkgD5UgOb79C8n327qYeZB3B, jrQMqgDsjm6qLHAjB5pC7RfvvjGzAKPtxxyypA, sjl7d9GZhoCh5nEdbcXF44yFcu9W2BJsCvdIUruGMwUpUfXl6IhhRcqUlNPlX4ZSMmhnM9puS, iFSImI2CjxTF, kDb0r3tV81qr6H4SmFFabkD8DHWDz912PeZxQ7YRh9FjBCwY6eXETGHk1Flvk8zD5JpOPfpDTIezK8Q7uUrfbbKuW4GDDiAI24DnKiJeX6hYL, dBtIva3EV4kBUnhWYYKtDcY68OOM3, gU6JaM23335s9fdd71Iu23H6letgfaEm7RMjPRIJV0EjNOrROJCV6juQ1ZutwHbIHmuiU9JKTbyNlwGrxSgvwbIcctrzzvyj6MagRIpvB4Ue, pf1ouwjozkq46dVUev9IMmjvOCNeQSlMXvY, lEwUC4BNAyX, mu2pHEkSxMpJG4IFjyzfSg0FLj42MK5bnIGesapT8TI2cKhWicQcedPAjtR, c1, d4J4XlhEfuUcKHbFjd0I2EiqomIciQBQ1oCZtXOsXYMexyBzM, mb6VcvGiNqAddoL1U27vHSbT15kiRVI0Ccg8bjGYk4N, v32tgD43e2RMYs3l17XRA0oqcqjgppgbGCXy6kpz2DX9B4SZJWFDSafw28keLFVVr8gz85aSukay, od8zAG, agI3fF6yeEgwn4mHyIS6BzL8ZmZYxIycJlZbOrdWs0PuDp6EIp3OEJ4AZeMwbAaWG8C478nr96ufy32O5B9ya3RNgsiRol8, u5OX7jli7pUvdFlQ5GIWp8Y2V4w1Qq6JuSZNXFX58tCXaGAXNw5yAnpgjN7YI9OxgsMaqOal0gviOTsLnltWWVtP8, mzoT46CbhESG2XuO97YqjAIOTKzWRFV13URZM9bhApen3u, euHzTurEOVp5ibMG93Z5n5QIz6Vvd3yxatMiXyCUL1TpOljdnVUascnrfOSIM1d1kkwCN7PsN2She47ixp, cy1SKKvhNyXaU0a7ucbPfvQvwiWIfyoRR9dniXhyujpGiHWwnxpzVNviq2UbpGMSS6qtMtcfp2Ydfred22sowNl9R, b7awbjj0YYXhTT9cfZAlagT4rkOR4UTbkJ9XcvpT, wFylCz1pj9BXgQIj0iRfz9hzLaZdnzFFwvDUjuuRJZt0dPDMtEUWaLUWP2S0cIPjJLSEm4JW5esqfCFrhOSnlVK, woGgx9rhmhU3Fv5V7YfItdR6Ya4Nn61TZXuHgxRKhWraD82DjSckWU9eh8uVG, van0P1WdGWs0Y4xmIgEo62SjbzMz3KqKj1gaz1Oz2DuZk4Vh0WfhQxUV8lFTdzweshJusd3Wq0pdzmopk5HZtj, fJYgdSPVe8ZGrsDsj5URkQ4Po, dN6swQflYr2n, q2ca764vfjW3dsAunTwWLjNJMOzvDa15EUsScuh0pgXRFYGB7n5KHqLPRYU6Uv5zW2kM9xyB8Uc7tT7Dz5QlGBGW4wE6UkiSZ6DUFQ0KkXgv76x, bphFSsnrvrUTp20JF0EW16OkghBZ4yipad2qK, cSC2XESOcKEYMXaT6Sz2BvHjMCxzJELA1Q9abTKT4LjQSclaxwgn9ZbdD8i3HYBCkwAmLbIcuzbmYEzJT, fiW9J4QVDbOOCcDiC, cV3KndmxEb2jiUtpTbOCzpd, yCLJWfpVGdOnNkUQOtJNxI) == cy1SKKvhNyXaU0a7ucbPfvQvwiWIfyoRR9dniXhyujpGiHWwnxpzVNviq2UbpGMSS6qtMtcfp2Ydfred22sowNl9R + pfutib02oMBk9NA(yqdAEKdWrmQatJbiBbNJGV4dVZvwou9CawoI5, yPLRs5NZFyGM19iZaybEfKGN67EhwEQyCPbjWQZILFN65PjILdMxRcd0OltdhEVSjutjg8uBghJUNRlO0yI1Bb5Z9DPoT1d, npOQdK86ZvrzGID2IYr9pY0illf8rz4MjpchsjYnmGgRoVtWEnCFA0iMo4T3eHtNvMgUd1aAAinQIInp3ZISWlizOHEv, f0TtYSKuVdTGPYsQOEMteXQvyJhifPDPjTBlQj46U5H2jUt9wvVR1dp3aRTPqwG8CA0zLuaDxMtKjiD2dV800Geyu2gVkNBzZrmTgYXHPX1kqM, soLhGyWKqbO7txR4jRH4eAHZyygs9FY2pZ8wGb1MGhe7TrfMxiGbZvexCSQGBkx5HrrpzJYxPfJOnx1qCXj4FP9tYNu, yrgcu41SkT7K, vZ1UpiwtSAw, jQjIvW31GnROQeexcXJQ80yp6ZNlyjfCAXkIVdoUFz5m6hQTJ2YDopUO4ExrulFicvg1qiTTZ09zztaAatIuKEwoZx1Rhl2SAZXgbmbNFDQwc, aTnI591CPvPFMtGM0DSFosqwH19JgWkw6TOAnlLrnzVTvA6GXl6Z7YZslowQ4ggbwiOdmsrbQoA7y26EGj5UThwFCuYClOa1Qk9YBSUgCj, petq1FnADEuTu9jd7L0cRMEQEGA, sCsvwtZfuozhXImI2Qe5nOtioKFhV0toIhWugF1FTkDnOM628v6BcsqgbNgPgwTms, om8AZLqChj5QWTzzuE3Klnu54DYow7CaOgsksEWJbx6rIIn5QIYNfyv0Cg0yqI, sKddX6S4cSfFmEkAfQQ4pnGOsrWyTVp6ohov2ZjNh0m8ddQ3kkuT3V73L9J8pwjLbBaOTclW1sqbCaLOD94UqlQwqfqB1ybAPNidBHJLVtCXV7RtZunR, dTB55b5g2ndHTltMFu8sA6wQO3olGlC763PxW62YsF7SGSfQPrGZtsPsR3d8p9W0rfg0rNre7Vrz, k, pspwuKWUAQfUbXxngJ3Pp7oqrvCJGZdA6ZpbX95Gt4R31sDeMmOmkzXDF5Om6aeyBaIIU8Sd0nAgUQnf3970QQNJcAwx, zROWKKR57TTf4dEuXEAJiX6SQ9ErYYVNfKBpRYozrqAUueR, dlqWvq30vbvbYfBQdWCStgeHLJOk5YktXyAFKEZNlH3zJkk1XXnxG0RgieZPspBK3qDYIkYlGRNetdU, vEUiw8Q3wDBUhfkwu85oGaomRgGEeA8L66dibMQUAP1vLgR, bex3Qs4BmJHBRbUmBOpCNiyEbmD2Odz4XFWO7dHoJpLtrpyX5y06A9aj1if4pGtp3ypR, ov8Dx4HxQI4OGfCgF64Za0TLvm7uUySHtxTY74GOmmpGXQekidK, akX5jEznhGZAVgX6PHCPhJGk2nhgVTgZifC2RIOSbGepu0x0F8ObstfajuRj6wqK67xm67txh1iRpy4GI8pDU5heY7yhBxAofExnVVQjD, wXqzibnzdeZGlKOUZ0nB1vk2EtFdhBkkQmVxIu7m2eCZGV3UVICCsV8lvEDr9APBsdu4mfEw9VDdR) == dTB55b5g2ndHTltMFu8sA6wQO3olGlC763PxW62YsF7SGSfQPrGZtsPsR3d8p9W0rfg0rNre7Vrz + neUJpNvUgPe72LyeUCuIqvKpwvWW1RsckR7JbhK36dduupC2UXn9Dp4xa5ss4jbuOM6aN0ioEhvOnCNNczcf2892nd1lXr6zxe3kQaCDGgnLfiCb1A54f(dD5ZfhEn9lMy6hIQ63MgxLX9SLe9RPt, rpJZqPgaJka0TP8CucacnCDjYjWCP0rv2zonLwMNfdKtHZISwCaY1o6x, tV9nuf6o6CC9hCTmATorYSzU1AbJCuMlAfHT1TtwQkoQba, eMUJ35P0rwLqvjo3peYH3jph3OaRaojx4omEFt, p1TaO7BYWoE1lwn, lNU4xQWfgivqKFBroYAcgsUDRhut81WjH4ZXtuvBmD7xEQiX, b9y9qBsXFMo9tcgGgK52Max3oVCkIXf1Wi, xzlnQAIh2CxHeGGccHITKBdh9YGLfskDJYoruY6mniorWiSEdLYGe9kprlD7TvBvTN1wqC0dI1dV4oej07XJwNFUM, zQojcf8mAmjhlsYNQtRSHEQDGBXEJFemNFJi4MqP0vu1ODY5uUx8jNhHcgxSwGxJXELWxcsZ445R8l4U07gHrPYWMwy33rmKfLShWylo3iAqqDIps5y9Og, fulq67nBveb8AL3sI1xlgkvDS6UDy5HV91Y4t0DytPjc3QbppAtizrmflLJk6CN2l144OGC4k9l6A1zbqTVuKSJKYtoyCIFfmw4be6E, cFt8tyq89IFSpGebi2NJEKCmJyLKWNgjsy5rnlASUvkODy9ydSmXjxfXdJdPTJHqii0FccvBuNizbJpW0bdoOKr7QaRCHXxCu2yBsm1EZncCMroRI7d, nk, b, lgE0x0q5EJR5ZrQ, hk4QcmCfEaV7ynEE65eh8PBEFod3VdG3uc5edimMzdMTf1AAVYSv6cCLWTWqEfEzhixBsZTS0xAlcB3OsLEdMnbLDd2bd2agL4zuItrKeGYj, vWQ6gw57aLsFDgPWbcKGHbg83, srpy4ICi5ffG54wava8hMsJmTP3kNX9KFGjYCO1hGWXP2HNRVqmR78ngBhn6i47E4v5Xe7rxhLcgj3S1sMCK7uktoCJNJX, eiaL4Y4ITF6mZcyoGdIJRgv5brQpLVigkwsbF7ZqIcX0xjHGN1B32KyslDg8FF12SNdc6P64W, yAKiq3OZKALyVMM7u8q172vb3R3cpnLSpOkdyyHW2rAQxwT8BQltZSEzjw4CaqNFQYXbgFkJeWyvdMYyHNNEXwH34ARqUD2GWkOzVDfr4eS6vL, g243CGvyoC3q8ne0IiEs8GZ2kTu6qiksuXKAjiP8aDhLWVWXFyJ, uviiueAso6qFDAKcAO8wS685lBm2vlFpKlQ7kWrSBdmjXsFN4UuYNkpHWdGuGyMTOpd8, qAhiscJ9mgAzK44ja, hG5VnplX93p3NIizc4VLAAFMoQOtyDhjrPfYgjJ, gBMWmxaRYzda9R3DadTlBxtDqtc2oly8G8tmXDQ8feYccWakExMKXFx22vnSDX5zxIsNmIX1OzK1sR1kjiVRDA7zycVR9l3p4, ldiKoihUaHjqHQEKVnAnq5q2C0Rd4U2sABLtL48KvTGG6NOISIfbxVputvRiRkHLnaNQHnH5pBiQ2Mr, vmc7p9sqDSLNNroyrQlIP, diFkx6gTeKJkXFhVWtZ0zWYA6CTm0iXSsoaOcOcg8UjK0Hw0RbkwufGYq9EhYig4iAvHQtRqRiCo7IgPFVOoFlxuHydgkAV, xsrJ0hs1Ke, aP9UfZ2zZEj9UUSK4oxi1LmbJ6PXE8gvU6q3GS04q5VelSnO4TAVpH3Dka8Vj9224XWyXX9dhJyJKVcAQF1, mRAkfC3RBXzPnSa8ZujLPQPTW37kfUKnemy7IZuYpAKByr0gKio9SM8CNRaIvZOJ63ohlyBO6Dj3whzWEDV1DNoHksJwK4lUq1PwWPQEkSkH, v29hQOP4auFwWKQtcJmnxZRzGJwyhHnUS0a4vZ30gR1lPUeG0ZH1t0wfNAYNVN41y2qV5aSCQvY8vFi7S3TEsTCklGLhTGWNqHt0O4cYQYOX, p83nDSVkXu1cQDig5M5QVP4unsNheBIMSGNu, sAeZUPte26396OpJlBpmI0LQE21lOtx5s3t8nCC0YvHHB0CNqCxi0lJiwoEVaN, g4aq2R, ns25X4CXQFuglOEPP, zO6zdF15imNgx8fxuwZNG3p22LNMQWWjBfGMcDPKLQb9tCCs1DKDDbNjqAgipqmZJwqPve0NlsmvCQepmhtZroKqO, ccrlQKb9dTYwhvJmvl4uWJH2I70XwyocP1l3tkGTHX0Y28gm4UZgj7xJGFYs3XMD9AxWEUV66SVsHK, yrortUPsQPz3, vrgY2fCsfzc0y, atADMjtPdHVP, opNmvwtrSNJ4RuT6uRHRSinguWgbzqkMsqQ5PW4k61HUy8toxpm3yo7OmM6FD5gRVIEUwGvz9wgCqgLy6ZPMmVyRP7XRUNP4D9CIFRtHe, gRV96fKPGEWe6yKFHxpuaPq, xDJiZCAbwMbVfbl7WcbMeruamFMGo6B2HMhB8N3KRrvic7qc49iGJb0bt5jCL062D1DLivTmY5TbCyP9Wb29pn7VOb8xdbKjXTY, dXXEkdWvl2, gNOgqr8aJX4zP9l0UaPS6VagarrGqLU6i4JYxxjrzHs7mYmgJF2UuNcsLXJywdPURIQ2xCQnH9wy6Y9VSq1gC0J50pAn04v, pchYX3ZcpKwp, gHzB, wOFfsItrf6nLp7zy7bU7ADoa02aW3yFektlj8rpn8a4CRo9BFMXI5nnjixsR2S1, qmpBaDd0wwAwM26ojdOhI7b2Ue5SUX7IuWhpDaEyxk4vAZTjdUv7jAipAEZd41SjSjvlL5TUt9DlST6ASlDN3ObplY2rp0F3, vPA9, dXNBv1xjF8ZdpX9C5ZY59h, hXQEKzRGitGm2rkfhPfIdX7NNi8fC9eUKHbhKQc0bCYivC0xaHYo4yW9Z2yoPdwib39HnBYNhBDRJTDRTaCCmHUEDffrdt0hDlxNOVQ, m0XmdKuUpvl1bxpzt3eNaLIlYDGcVkOcEU, zgiCcx0Ii2UjTDawJHXK8ztW9TxnEs4BqGMIL0KGRQaZG25eHlZnVVD, oGOiwYg4Ni0FnbwxphNIY, cwECL7xY8iScG2ySRm0ti8l2SM98hhZH6aJ3n0PQlTb6CrOU12M, lx8mkvXnvNTddobS7yISY81hUkWXF2snOu4LxOpUVQdxNdAZWzaTZidvQ4UBQRrrRjcg2, ptUB2ALkx6BCK, cUmKmyddS6PXGo2GUNkzZTN7T8aUYA0TyjV6gg8oQ8km8N, rvcG9Wifo9QGqWkQA5WvYZTzYufmDdQBlhPBoANWGrgHdzdN2lO0phAeCeu8SZdsOzaR968R37lkJpZsbmUgtb4i7FPQtIFgLwfKlSeWx358mVm, rwovOOJgVwMF19p, a7S0yryJFshXqvdklI0kKojQNDdCjzZ8njL6OTEEJoDUELF3hXybX2H2j34fqApjlTLas7RndLmWeG6qHlGhOyzCgtsiZ0Ac47CQHla, zMYCpG8uLegaVSIotRhQZx9PUKAk9VScJbUaj3SIoQmgSdtj9V2ZCbZwo1VcBwjscjYOE, cTVZ9beGFz5WuA0xss0ZcVMok7s3r15KQjkTmwkdfiHoYBzsQm, vKR, hvGdY7ny33CZqb970HPMtRgqxyb38sWpNP3mqaFM3CQIF0MzGSbmSEHFblwNDXjlMjbmd6oojyTEkWwbG8ev426SvUvPZ9A, m3pIRkjqdB9DhTQmsqsPA9jjo9dtLe5mvTUlTIQQYTPzRraJUf3LhrMwlEr4tDz2kKvxYyzWUPJ8EjiiHKNKCXEwEZoxVeJf772cnNx3WWuCx, r51OBn836H4CGwaJbpKGSPoz2Po91zoZIvhLGK3o9k9cC7nDxL65U0g1z1ZH6SRsJ, sidyALRX9OvYQ64hbL3cEsPe0uJU54P, ga, pb7Hf9j3EU0fbPaQCJQBMELlAYwXQxoYkOWXxaA9r4NGEO6SWvJyMkzPaibJ7IdF2SoiamwTX23EVkG7LbBVAM4VhhrTULwtCWWSSLFVgKl, rdW5Fk2Xx9e69ZaE5r2a5LVVkO28ktahTi37iiNWVfM7OmTwDZXnoapZ2zZ23rbUFfBgi5Ci858X10XQUAsdKLQS9Rhb0D46jH, u0umaKghoGC1G6mnpX9aEDFLa9OyEPh1KfTJ2XtKcmX2gKfcN1yMKgAiPgrX5Y97NLxnkI50K7fh4yh, tTmkofWz52M2axQpt6G4OMLgBcYOQdI3KBdWdFrGq4Yda58ua, uphJqGX9ZtsAfGdpAd4mdG0SrI6BNfG39y4KCNb1pJugfMZaOEzfodJY, alki5J0u0ZkgrMwbrPRnhcNyFwEkMNzj1pZdybyIUA9DwZtyEtDMem5uM7NxfYZroUPGAxgjDAditFdK8Kcw6TBPwZ3dQQmsU, naXIPTVHPd9, uyqvkdRlrbdXkbb1ABUeKJrZpArqCmDs3O3oPlX, jj8GIOzvZwvVFjltDA5TlBEtc0thYFrEsT6AYhuTR1DCfRjSYsVExVFXH3kludlk, ieZaTIVxTgxp4XntAsQOYQiSvSiSzvhtep7YT7aG3eKqH3MfzAo4WcjBx65PerpVd, whwF81Q8dhsvJdCQotqTLGbBiGuprfUBKRivefPWwIc1Xv8qA8HKIjqNcwarJ2ywKAXiPeFuF1fGcby1Ur, k, moKtttvRNzgiambEv0ElsCn6SOnGFRtwdcwAG29VbIQADaZAhM037grEV80IiS9NXggAW1g6VMQ0omx9XrAvJ7PcqBFkKi188lEes6kJq3cx1rdArLgM, jM0j1vnW9Ph4mrAgkNml08uYIFLEOMyaTss5EIhHKPvtaTTtrkI, gSSsoo0WfLIj4c4pSfB7SH7FnRPf5BbXG3Mc6P6keRNHhbSQgnV9k7fqiumr11djFHVEAudmOEZ2l8D8hwZVsgHpXKH8CmUp09rXlTnZegeJ2yJiGg, cEgq0WGJ4n9DXPcG1DQITQYPNFnmefNHJ0gdAnOehKZ2p6GyG6dQg, xGBke, fFZ3jGvpoJ6qs0TpDOjWxZ6mt4OEwL85kU5gEJqg5PFLEcgUZ, bwhE3, vNawQMPnoqjbFKmoVzXFFj4MwASHGDlEsKnciZSThPfc6iBHAuT6Q2YrKatxfj, lJ3A33n8Mq8N1x8r2aN10aY5KsOvYQ3zHasBY7b8E7MeEBZdKNOrAKHFoEXfv8VsRcmUOjUq, g33CYBTGPqF92hNZUIGRp6UD5aECTMSEJd6FpHJQxOY7CtKloNalX6iyEznlLIfKye109jwqbAtkEYzgh4ocEtcY6NhlUUgdK7sVR8ywttsjkKYWnxXId, xgfnyJIytCnNTK, ocEx4eG5KiMIDuAKa3dejESCdVvgKPoXAmkyA5hbCRXMuX7rENyPIo, q6MTUPxEAeyXKMifVbWAq5yiwxg0WcPqJPO92LkmCdDHggelkCkd9dNLT9aFBaZ3YONXBk9EWDNlzIlMGTojmRcGiV6RYIwJ6NAGeVNFTgs4WBf3Wl, eYaJ0EQqIPYRLHBvqxhVnw5MCrO2yFLWx51zWw5Of9y, qC0lAOIYQE3zbfIiluDtQbX9kAzSxirqj9YNSH8C1JHkAErAIy1H4XSevvZAiDD8PELJG7VHi, eP5qEMgP2Xnk30GtLMzD5LEEp8xhqXaLKSqNIhCtj8mQINTnYfrdZIBiIiu, q2lslxSqzKtgsPRsGzKgsKKJtrcbcVRgCCy, pPVCCskU8t4Fbz6INc3sZRwlTvGTC6zWoY5tU2DcNbdF2Ici93tTq3JATIBcPCuHtvaBsdXUaJz, yUzmfhluvJPwrDp1VLRCY5ie1uvw9DGG7E0fYsp3r3cQOGc03HgWouEucwYBQ08HaXYsn, fqEDJDLNtlexAS4PhM6sKqSqS1YZOMhojD9DFqH8Us6zkaEBVKv3ohCj5AHpC54qu5Yzi0604JQRIY8, iDA6ycv5MPxc3hgQ16SRcpMd8GrKYzB6WxeGF9k, y4DZIxYVUiiATh6NltzAHxY0VsH6M3MCkL3n3eon1lxXVFUqYDky0qGGaL1ksz5XBUXbD6d79dcxf2aVIOiZuQiC6Aru3KsXRLwaBH, qAPu, u, bOIsQ8d8GVM) == aP9UfZ2zZEj9UUSK4oxi1LmbJ6PXE8gvU6q3GS04q5VelSnO4TAVpH3Dka8Vj9224XWyXX9dhJyJKVcAQF1 + ukBmRCtcxU4Z3Yksh0YjLv37MqG99dzPRYxTVv8OCeIwGKh9SwfPSVAXDxWm4T(nyb2Il2gW8dHLUWW4p0IPl7lRCwDCI, q71PuuOLcWFWM12bsnpvqgv4m7uQpM5SbNYxFzyUcheNfOrOdgOv7ZC8TSURQVM4CxsuHzya3uFEVJ65Rne6lO, jGueCxB, jDsrI935UaJyVhce, m8pHde1ec1gY, iotRSKGrRcs4opYC21UM9ERt4bwPjxjwD18a9TYB4EJsQtpFPuybb8xGLgWJDg5Z0eNeGMNC, rsBUK9zYElS2cQsqX2vNWgNm1qAloPP4RPtciMXDX45EhzTPMNp6RZhLlzFovaVdHdO0EViwTttInwqNRjPa1Q3CyeY0ZD5GVAGgHorv7n6AT6, aCbVK4bc44RJSB12Mbba4KhlNUd2AoJSGb2vUKIp1S29aIRGhxh02jYga, dR0tnBY9KUovDwO19VKuTnmSIBpDGgC7u721Hv, x1lnZT49wU1tTxyMcVQYceJ5gmsIwMromJTw8YiWNjDZn1is8psWwz7nvSZrFz50dHVgwJXdAemzpgMZzAsmt, ehKs6sNuZhfo60rG2sg3R1QE5CVTcWG2N7K5WtJBizlRZLVtd, sR7JVAjAVdvlxD456IJ3NvuT0CmjliP, kdUl2CTj, y7TkhjqDzL6ubH, o6thVMlWBmtwYbrcrEiBB8WQfeKvMhyAeCv1P87Aya, u5J9mWoWXYLh5wmdR6YjKcUJtt9qCeQZDAl, jDJPvWrhjydEEYKuKlywSj3ULE10h2dDfhGpjTlGPj7ImhAEMVwXqE24JKmYSzZ7Mp2ftKU5KWoVhxRRGFDKETVR9k0Eavmp, natnlvtTyMOYXqw5u7fHGg0iELBvSL70dxn6PDm8j3SbDjWSkggBG4DFQvO0yCEXBBfAe3bzn0PIem1NIWvi1, lRXB1iqx08OAZGcFwFyuApGbCzQM8qvAq4SC7nOST4awVvYYChJKet, zlm90l5Tu12iJlCg5vGwjGfieiFxrqp27XXNJsCaWlwnrl4wMWIrzdD4u8oJ6i5lXO9e) == lRXB1iqx08OAZGcFwFyuApGbCzQM8qvAq4SC7nOST4awVvYYChJKet + bxqRuwNj67l1Tw0tG4FnJoCpbcwAITjSRFP1I7Gz9BYYEOtYCbQNVLKoEIx0CSFwIyMkChMguq0JB4zT4HXTZdyPn0hn6D4EmtYKzcNEuKBXWJ(uQKOCatlf16egTz9aQedQmOycWBubYLr0FK6oPRqXKV3dbBmO08OiqIS6fYMbg3da7N42C7TZsObO5CaU1CA9051loKrLv4lqizxYz7XN8s8, aSBKtbpBn3rK2oORAyA6MoTROaa77w7IwzLtDcsgLax5OF1Og6b17CUWWGPW8Rg2wBSQDrrkqQqZbqgQbmnNB3icV1KjqtR6XXRZDe, cvWtM6M0aZ9GrzoKN4gllrlyIjtOUWUKBQiGXYT7DFyFzcRB0, lHiIHLn7Dmi2N0yX06JfZlhPboAMDmDkX6nKXZSHwvuzdAwMzrRjjaaIGcNZoDr, q3GxRQPGNOiCkdTjH3XOLCIEHSCR4qK593q75ytYrCnibjD, aC6bZpF0eo7Nc40PnIq9BnapFYjDthyAe7T8V9XI7ePR3VIuihpwqEJuWO7Sga1Ar2EtAYmgzOekIDFnWGhAIDMCh66OYflzfGtwLkUFuvw, aIThXsUSsufSEXBuWRynAC1amycmWnjFNzk2YZoQdw, azy3TQcyTDxmalOQ8hQ1R, x2vzC1BV0ccqEb0JQH4JNj1lxdAJqAS5JqYM3n6MfsAgoxBuMeWfVivojVbSebpV2Isyle3x7bQSiIBLdehUUpT7WcRtrxwTbeBM, dycm4g, e6fp7MZDbcL40Dzxi19tsqc0NOFOMptZXKok3cNaw39jz1Y5olxY, fvpGUtlF4jbJlaEYIEf0KKErG9yMSULSamF3p6uX0ekan7FkYJ1GfGY38FnvaI1xCmJ8, tJZWvhtv5t3w4YOudUqIqxcButdvxdk7QrSkfXrRqxVm0PDDbkDGjxXusW1zEUOz8vtC33GLKmLiaHqvodkyGwzNQqMDN9G7YlWvHFkqz, d9CiJ67ihdcsq1zGpto, l, kfrmqCShcCimYColT2QdFsygTpY1UvNUpV1F0OowzVmgYWEGVThFFpDzf2kmV2bkY7iGzh3wjpLozJIKcFM8I7jjzR6xT65S2N8DLzSvyNlfmE3fgRF04, kiEBQpQU1jo6xyK8efcGcW0jAoRCr5r4wnEavbUsAdlxFvgolAab8QdiIp1Gn992bqEFPvfvm34BvkOQO6, iKFAEtFY7hy4ljNTleW62hcjlpteNLqZpH5UB3uQ5AYqimTymiXDGyjxbjepAcESn8IHZ6bUyxrMKTlGHw8vtAMSzjCVEk7, xgAmcY408twaQxSDXaB8ExSZhkDoIOUqrEDbuUPW6KriB9WX4oItCZGLuCw7zRBWKv6auaHR, hk4VkY4ZiUu63GVigOsSjHmYOyH7djLQNJH, o5IzQoYsUrfVa4i30vvpTktVYGMTG03IMKqD2O8tzsSPuBM3f, q08mHqx7dfTfgggiLK2aNOcXIE2Qu1aXdk0xNvjGzhAfytfEqhn7PI8dZbzgmKhCTuLHcZsTNglm1ZRGzkYO, aJ6DcsWlrdtzTbSTp2pOl1Hbhlato7S9I4f6veppCSYWAiGQuamaV2aG5nVfKUHl3wyOpJZqGTgP7wJJVtvg1a3N, qGugRgMtXAsyiug2, jfMuGqGfx3uqKFk5SD2sEJ275K88pOCqxvsQhMMO891qzSPrX, jtY6HpnYNk6doqATtd, iN7xhv1MzuzYOiCT4Sh7VEShwfS6sa2FuSTedejWWSnBGSArKrArNYfPvncTWyAvaLlVSyF1QuOnxdjlfimPKqXVCidOfv, fsovO0g0buqgPfCT0iUyGA9qkdqp0xiHMAIG49G55vlE09nKWbLyZtvKsrDMVdanfzutwMxLqAmTYzcrqnEllcQqBl4BvccoSuTAO8, yNtOMcEdkEmNHxHRNr4rjaNgiwfw1GDkwQD6XPeqiRyGlBjcQL7YYe4S5Zio834Tr5wv3WEroBdFzeiBT3q5qvcwkjZS80CYMh0GYdA1, eUKe2HagRA189MJo06zexEUWOxxG42bmGx6udVAj5e9DmDbWOWIR99Gy9cksjYRqdTDipT87p7Xg1O0422N2qKqmcIGLqn, b8ddK4eqk8erPJfE3PuBCt6R1nR8z7NaX3af8RpBE8BmAREE4Dm5TkAjRAok0lqrmVEt31Z2eIU, jlw8fsBEtqRnuqaouK2iwD, u0HfGRjE5jId7Jhdx9DjpuZyYrWocemqVPN2AduRPIFnNOINUlVrveUoHJYa2BwoL9qWNMkvPO00sIMUJNP, zZrD2GEI3btaWmmFMhTWt6njd56i9O2AhKTWC8sBzgZYFJjbN8JG8qvCWGfOx8sHyBtJVWKg11uGBZxp, rJANcC7QzWMHjQUaXUF2mXXhnc16yDhM1fHMS9ySiXRK3R0AnaDWDuff, a4kMZiT0UviUzwO7ZTaBAipAVX3NmEFSECOZuvdMwni2OUgKP0tjPxcLFcMVpe3GxGsUwIRp04H9GPhywpx, d1ZxaiQ7KROXHTKbugNHaWJwzfqFqpnZvqF0uVRvL6qe4NDOlicOjmSIRG3aCAQNDVjqA8T7hcKt6L748YJjXpsT, dkh9dftAKQCsEu, uBHkN6sQPuvNQ2R4SxtqVtCWabcO6Cw9u9, tSr2ZDgbgVIWcGa, sfH8ZI89OKbTq2, r, dW1tf5x24MAFXIZwyZL14oxKVN28EhJkpIYSmr64ETHGdMn0GSx7udq2c, t1Vj1Y9RtOoB93Ckt6kan7wmWcLVaxgOOyiX5N6USZkFreiIb9ZabpDGYMtLJwTStnXx24GHIU15QqTnsAOaqSeOoV7Trv6sk2L, n2LQazbNy71xCM5yt9hndpmiEGboqRJ15GZ29b2B, ynKpefQii8aRVNTmUfBP9dP9B2QRq1pU5SyFa7Ypq7CfIV7ZrouSG2JWHiA0c7BAy, ocsxTpiMPrCwBoKLmnJnVTDAIygjTtQq3HK4ZLnetcZVv6Ego8thDXL6MGaWRUdlSzqMeTjId4DsWdnomE26RGdNObdgArTJTMu64ewiS, xHPS0KAxYP4ARqQi6DAEH58yXjI5cyycLKcsZyxy4Kj2IWjcTDW0cA, wxIfXMQKmfhuwZ1AkGH2joSj8Js4E, mXLeZojiw7j0DmWYcbEzGgKD3XxcD3bElIEzpvo2zc124j7eNKJm35WBANvQfL, aw4BXjBAl0R2ui, ou9g1IqqeQfEnYj, k4WP6HSX60Pe7oJUbyiD, hXBgjNmFO64gshs3, dBesg6m9CJunJHw5V9DVeTONVdkh6zQ4qDLYyMIV94vYM85zh4ykeswLKbyj0YSa, raR1ezEVYkGNdZ8dfrwfWa9s6WF, erPhH0uA9ar74awWPit8BRDHHVvWm9PAN5YQ2r, zXgx1ZIcnmfAt8eeR6AoYrUZxMN3PDKsBFjHRPMCUM4kSQHAPzNFMwHA7kulY5mmd1IqmmZrbtgqJ1go9, wX4DbY5Cjz74DH2EBMTqEEmAgPmORwLzyzvrgzK61cM1FkFWNOuXRRjxGvySbh47uekGKC51CZH0K6PnSYnf, pHQbaz8L2o4vtwfkHITGp3hLmBsEzUfnnREIVVb7w0QPiLtnO5wQOvOCUsnefuaS92hqEfEovByLvfZSALyW53iZ0B, vN0oAukCuH1tidxYDNv3tpho9bGH3dSN73iLyPT4LBhKLcweYencnOhr0IVE2WqOLpNqmSXM9e9EmuyntNAvXX1zAXw8, zwwrnscjMRSo4ybtRdBfaCWo5p, u9NLz8UiJfrpRokx6Klej3lJwzxIXELFLovaChsZCbaF7sRLeAjVOdqXk6wPOqM0b2hsfLzYigVIw2IeHxumWrhdxz30Db7itIInwdLJENUAR4, onQcOt48AFx2g3vcKr7JeP16DTWGKYuPbOPe0fPztj1pyHS5P4VKSrUkX9DuGqNISiGnqoDfMWtPqJ695WBCVZuqsy87ZWLKreaaiJJlL2mQEvTKGcq, nzSv46djtF8jRAb0x1tkPL0pJAgZeGMg8mjp0HfO79wuKKHL17c4Qouz528vcFr7U7U7qSK2EHn41dubI, haqvardC6HFV9aBiVpOkhAZOCsnl0AdN7O5jSmdwo4FOHk8GRwsYhBL8Vojo2YZubGmtsEVBuL8OgqDX7go36puITdRih4, tdDITA9zAIMITHRr8Tu7k1MKQvapl1SjqGBfkNpAq7C4WPXgALuD22gJlCQEkDwFLZDM3B, gtcDnKpcoxXxmgSEaDbvuU0S3JFm) == xgAmcY408twaQxSDXaB8ExSZhkDoIOUqrEDbuUPW6KriB9WX4oItCZGLuCw7zRBWKv6auaHR + oGNcam7no50VFS9bNVSLFrVV9tFOTIhTwd9VlrW1xT(am8bWyy6KnGD7pbjuRLHR01nW, i0s8KBm44MBD7jP973D5Eu4zNKCiXaPohAQsXTb4CMmE4z7uccxlcgtrtLf6tVytqIhsXxkf, kwC5NvLfjhrgra7nBauJjJdcPCGZMVFBHk9of51zPNdpV0LNTaraqDEhs9qKYY8Gngi5uy9gknn, ehW25vry3ut0fMujKtUZrmrmPZ7SGzViNd7FExfqWnXySATsZ0eFyWdwwbSx5a8XFouh1UrVdF3otRcwQsbBWkjICbhdFUD0zy6VKEfDFJ4qJ8rlBpk, vcYhmXYbqt6NOh, fjjQWlZST5w8UQJSGYmMExwrE4KiHMs2vva86I7hMGFIXjZMt6Pr6inLcbQaI2fDvv3wzAj, iGP7JEUvz0e5rYJkVm4vSagOFQ98H9ywKRqYsAca8p4yX5XVkKKphJUGP4n, cStGYyv8V, l1CWGSnDAFA9JP69nGrlo2f5ohVH7g6O4yTqWxznzWqFPNBGhTDvk1nDQDU398teHkao4sK2n38qz7zl, aiV1iGsofLK7qe1lQxjSZe55J51Q0s4z, mb2f4sCh9wj7JdY2V3cEmrIv99amnXuMutObxCvZ5aqlj72, p05MeTxF9stYUJ2JXqTIioRDLc4, cZHjp2fGGJxnXXb2t9XjqSQprA5WQtkCwSETFbkGseDOjuuZRbJo6VRiLEn, zyaZUPLlnqpNKeTj3tokZX4dDrnkdjnPvHdgCamm8YLu0WH8IWxsYZnE7tsnbXfHudC7VRYjNvOinB9oyHyaIRlCVKAF2M7dkDCbYxQKSKTU1q9SGZ, uJh6jOSh5uGYgEEzpgdPGVh4TXRlrRvsDzgqdchE5JJdHJTfqOLbxIlSoJf, vXSvT2saRKtTIpFQ9Lb15wveUQM82wTqNV7k2ilR3nd0leLNv8KIm3nmq51aDmkfPmTHRBaNAbZLxFouVAd4ywUHeHEA3tA8mYYCCDpcJNhzIsPo, koSPqSVrdMCYlCkJixR4xlBZmf47UdD0qwxD36fauTxnkYeonmYd3VgUmL695pjXrOsE5puEJtJn, toHkXVSgsIWfecbbl4rfUKKsNhId3D, vLzSLfHX7fGw3l) == l1CWGSnDAFA9JP69nGrlo2f5ohVH7g6O4yTqWxznzWqFPNBGhTDvk1nDQDU398teHkao4sK2n38qz7zl + IN <<>>, gSapU9sycL2vu74K0nFmmgiTgxxxtWq92c0ho \in [bV2U08WxrbJW4YyisaWLdDTlnnQZN48YPIYI1 \in Seq({}), <> \in ";nT!E/a\"~A'^[uvN51;+TePI5&t$^^Daj.]7eDe:_41h;{8(jzvkM`TLwt8" |-> Head({})], <> \in {qxbM0ySqkdzWhn6gaROcgBgxFwsaY7adHaF3zhWU3qvyZMiXDYvhlbWBjZSc6nCHr8DLrsWqkB1ZScZHg8LjT4uJqajwOdLZpq4pEzU6a6Gc : <> \in "Or4uYZ'{+a\*`I/tHTU'@Fw=}G/B/d%h\):%R.FE[0}o-\\ -8'jRgIskN&SKdu\\,\"\)9%r;op>bex\)&O5eqhS/xtaJG,nV#QWjd-c_f:\)d", oyarDkIO1XeNWlRTWPoDsk1rDzx2KhOGK4xnI3CjESXu \in Nat, lAPrrMqrU4ntxPtOdkQigX04o9A1UhGZEbuFmCpVZXsEtPOamE6NNhWjuNSx4u9QGUQi1eGldztPwD9aM6xX3 \in 55, <> \in ">&cXJ\)Blo@-}ot<1`,WaQ4UI%BWVB\)psW,;X", <> \in <<>>, <> \in 68}, nrk37ZYFObeGv0nT \in {"w5:3;Z'1> \in f8FerpPpvVx9MMkWzCPTDTuHTYdIgpO2mcb8SJJFRoo6DrVmr9MPdwFWO4DUFYF6L2lp7vY3RgJuBCEHbcRwltB2NSEmn0RsHtvn4Dchoua9Zh, <> \in uTBOegzf41xwPV9PP4Jyej8A4q8GFeUm044NwlkPT5BL3eI1AIfiH8e |-> kKa0FOAnjnOrXmqpw5mzjiGjspYPvCI3puDlt1jTnz0hhp6eg73Xe9igS9tmIDWBiLcPUA9cZz9cSSqKDCG5DRShCWvfozxKiwTRbTHl93hm] + +\* this being empty is also a test; can PGo compile 0 archetypes? +(* --mpcal ExprTests { + +} + + + +\* BEGIN PLUSCAL TRANSLATION +--algorithm ExprTests { +} + +\* END PLUSCAL TRANSLATION + +*) + +\* BEGIN TRANSLATION +==== diff --git a/test/files/general/ExprTests.tla.gotests/ExprTests.go b/test/files/general/ExprTests.tla.gotests/ExprTests.go new file mode 100644 index 000000000..6da2bd270 --- /dev/null +++ b/test/files/general/ExprTests.tla.gotests/ExprTests.go @@ -0,0 +1,2269 @@ +package exprtests + +import ( + "fmt" + "github.com/UBC-NSS/pgo/distsys" +) + +var _ = new(fmt.Stringer) // unconditionally prevent go compiler from reporting unused fmt import +var _ = distsys.TLAValue{} // same, for distsys + +type Constants struct { +} + +func Test1(constants Constants) distsys.TLAValue { + return distsys.TLASetComprehension([]distsys.TLAValue{distsys.TLASetComprehension([]distsys.TLAValue{distsys.NewTLASet(distsys.NewTLANumber(1), distsys.NewTLANumber(2), distsys.NewTLANumber(3))}, func(args0 []distsys.TLAValue) distsys.TLAValue { + var y distsys.TLAValue = args0[0] + _ = y + return y + })}, func(args []distsys.TLAValue) distsys.TLAValue { + var x distsys.TLAValue = args[0] + _ = x + return x + }) +} + +func Test2(constants Constants) distsys.TLAValue { + return distsys.TLAQuantifiedUniversal([]distsys.TLAValue{distsys.NewTLAString("W\"!YVw#\\#]8?t=]ndqUQnWNDhr([Q2Zd6;")}, + {distsys.NewTLAString("fHeAZdw1vCnj3xfH9h22hrUcMclAc21eFx"), distsys.NewTLATuple()}, + {distsys.NewTLAString("kPKP6DMtdXB26DOcOq"), distsys.TLA_Int}, + {distsys.NewTLAString("kOufhkQQBNihpnqM5EG2ave4gvDLXzM4eM3AF0s1vozipbR3jl8f25jIZF2l1DrHNVNGzYyh"), distsys.TLA_Nat}, + {distsys.NewTLAString("pes31jiQYk7kh9MbAqDybYqzToYtXL24"), distsys.NewTLANumber(105)}, + }), distsys.TLASetComprehension([]distsys.TLAValue{distsys.NewTLANumber(66), distsys.NewTLANumber(99), distsys.TLA_Nat, distsys.TLA_Int, distsys.TLA_Nat, distsys.TLA_Nat}, func(args3 []distsys.TLAValue) distsys.TLAValue { + var nocBmpMYH5HkfAmS1Hxov1sNAmNpre32Go2PPwiq2V distsys.TLAValue = args3[0] + _ = nocBmpMYH5HkfAmS1Hxov1sNAmNpre32Go2PPwiq2V + var j8KL43er distsys.TLAValue = args3[1] + _ = j8KL43er + var uOnSBu75CcElcoR2ZLguWLx24i2 distsys.TLAValue = args3[2] + _ = uOnSBu75CcElcoR2ZLguWLx24i2 + var ciyA3piCZqGxtypqDZ7yUA6ZigMVm0gahHBAmufYN8QSkFcoxD5mhB0H1o5fgF4J0oOpzQgazH89oz distsys.TLAValue = args3[3] + _ = ciyA3piCZqGxtypqDZ7yUA6ZigMVm0gahHBAmufYN8QSkFcoxD5mhB0H1o5fgF4J0oOpzQgazH89oz + var n4vC1IUc6EoStkodAFXDtaZxD3jWmDWSa177v15UbOG2B0yKlCWueKjkDEczLz2NF3SdvY distsys.TLAValue = args3[4] + _ = n4vC1IUc6EoStkodAFXDtaZxD3jWmDWSa177v15UbOG2B0yKlCWueKjkDEczLz2NF3SdvY + var nG28Jo6ZPmaioDORB3rtTQC3MA6TXOlrBAGlocmnn91fd4VcPEWpWFRO7JUXcTbk3FQn3dCQcqJ distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(0)) + _ = nG28Jo6ZPmaioDORB3rtTQC3MA6TXOlrBAGlocmnn91fd4VcPEWpWFRO7JUXcTbk3FQn3dCQcqJ + var xBKLJo9UXTx2yGO87kKwLZp3EJKjMt8xOS9vvpwT1NdMzGj1EGCi0KqLedT1CH81ojtIhh3obPGrPxeWEY1EHqhj distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(1)) + _ = xBKLJo9UXTx2yGO87kKwLZp3EJKjMt8xOS9vvpwT1NdMzGj1EGCi0KqLedT1CH81ojtIhh3obPGrPxeWEY1EHqhj + var i6RrPVsaJZp34W9RKfsUL6y8a2YLkAZH1n1ZGwEfiLNAHirEv distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(2)) + _ = i6RrPVsaJZp34W9RKfsUL6y8a2YLkAZH1n1ZGwEfiLNAHirEv + var dVlDesP9YxJFSIssi1mU9dRmbKMn6bTfAnumnKi9ajEgz1NuxRdxwryFIHa3OfUo1MrozlD4uSviullnZ08ri859pa4F5KfNb8gR6fdhjtBoWJlWNkW distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(3)) + _ = dVlDesP9YxJFSIssi1mU9dRmbKMn6bTfAnumnKi9ajEgz1NuxRdxwryFIHa3OfUo1MrozlD4uSviullnZ08ri859pa4F5KfNb8gR6fdhjtBoWJlWNkW + var vL5YlZ5RucAAv5PRhEbOI9VZskTUrKJ4CBKFD375A24fBQ9Zkar3kcIAP2Zi3nG9Wc9lk distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(4)) + _ = vL5YlZ5RucAAv5PRhEbOI9VZskTUrKJ4CBKFD375A24fBQ9Zkar3kcIAP2Zi3nG9Wc9lk + var jDdLltQvIaww86GJ9RLit4bbP2TJjZwCFi distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(5)) + _ = jDdLltQvIaww86GJ9RLit4bbP2TJjZwCFi + var c1 distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(6)) + _ = c1 + var gu9EXjPotxXhvLLIhjtCDzeQCP1lCJ7RzjSKWwESuD27E2vhrcreT1bWQAr8Gy01cR2R0amcoUxJHjGzo2AyzZCmi2T9SwC37Nf distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(7)) + _ = gu9EXjPotxXhvLLIhjtCDzeQCP1lCJ7RzjSKWwESuD27E2vhrcreT1bWQAr8Gy01cR2R0amcoUxJHjGzo2AyzZCmi2T9SwC37Nf + var m3xijwGkSO5cbxLH25trtyfWt6DqP1Z4BzoZ3WcgSqIYyn2dDt7ZVs78ZxwY1FsqNxLwi3dMbpfEmt5q8OTZWvi distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(8)) + _ = m3xijwGkSO5cbxLH25trtyfWt6DqP1Z4BzoZ3WcgSqIYyn2dDt7ZVs78ZxwY1FsqNxLwi3dMbpfEmt5q8OTZWvi + var w0Dnh9ChXjWb8kwo2yccyYqOEY3g4xUC1BVGmq9Ef4wToN distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(9)) + _ = w0Dnh9ChXjWb8kwo2yccyYqOEY3g4xUC1BVGmq9Ef4wToN + var arHtAVg7ZC84ZQTk37sxLduCtyW4EZdFarK2NgVFYjUAqYK4Lg5svlEuubqZupNbMxg4CxlsMsRbPbx1Zgn7hI distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(10)) + _ = arHtAVg7ZC84ZQTk37sxLduCtyW4EZdFarK2NgVFYjUAqYK4Lg5svlEuubqZupNbMxg4CxlsMsRbPbx1Zgn7hI + var v32wFKoCXnEHyXEvNj3vCN2HDlHtHTKsZuHvKK6M5Lj4lGKAAAoNIgshzYHaNJcaEIuIKA3tJxbzdSO9HLdt4OBdiVyEYgtoO0Pdt490mNtbsZXLS distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(11)) + _ = v32wFKoCXnEHyXEvNj3vCN2HDlHtHTKsZuHvKK6M5Lj4lGKAAAoNIgshzYHaNJcaEIuIKA3tJxbzdSO9HLdt4OBdiVyEYgtoO0Pdt490mNtbsZXLS + var ymOlbwXnWTvlyPZhi5hXUr1Q8F distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(12)) + _ = ymOlbwXnWTvlyPZhi5hXUr1Q8F + var pzJGbF7qPxCbwDH distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(13)) + _ = pzJGbF7qPxCbwDH + var u1LIxPKqyyXmP7KEdyFd6fh1U9IPW1yfA1BXLBIBaS distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(14)) + _ = u1LIxPKqyyXmP7KEdyFd6fh1U9IPW1yfA1BXLBIBaS + var b distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(15)) + _ = b + var w distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(16)) + _ = w + var uHBr distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(17)) + _ = uHBr + var tKBu3irs5Z1iD0osrHAlL3DC3SaZYsftheu01mEju6FMuMA2SDLe5Bgv6Ftk2yTPvsyryXT6PUwuY3JbA787nHWzK5oFEho6Dru distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(18)) + _ = tKBu3irs5Z1iD0osrHAlL3DC3SaZYsftheu01mEju6FMuMA2SDLe5Bgv6Ftk2yTPvsyryXT6PUwuY3JbA787nHWzK5oFEho6Dru + var wEe1wi4JAYXEZw9A distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(19)) + _ = wEe1wi4JAYXEZw9A + var fSc09GVpEzR3NEnv9gDKuWbvxZk1DhFPpgcR5wrelxE52YmuI distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(20)) + _ = fSc09GVpEzR3NEnv9gDKuWbvxZk1DhFPpgcR5wrelxE52YmuI + var cKJMd4bNQHvk0LNOuxxosJkDpCUCGdPlGken4VkXbbW10XvjagfiuFvUxUSh9GOO7HQqtbKQm50ttSxJroiEPqeAvsqTc7GmJARuTcGAJuP0OQ5S9vlasi distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(21)) + _ = cKJMd4bNQHvk0LNOuxxosJkDpCUCGdPlGken4VkXbbW10XvjagfiuFvUxUSh9GOO7HQqtbKQm50ttSxJroiEPqeAvsqTc7GmJARuTcGAJuP0OQ5S9vlasi + var dabbf4pW9iZ4o9PNEHXEwJVICgUUWGH1di distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(22)) + _ = dabbf4pW9iZ4o9PNEHXEwJVICgUUWGH1di + var oCLDsZ0pCbYzH1WtiKo3Q25bzO6AFfzEWU4V5nmcCR7Wg7H3tz0mIUYN distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(23)) + _ = oCLDsZ0pCbYzH1WtiKo3Q25bzO6AFfzEWU4V5nmcCR7Wg7H3tz0mIUYN + var vQRcHh7prXCSmo7645kktQGhhzw5sU0EKA0dPj6IGYmm1gcJKZCF1C59jwIEMYkjknYtrcnzmdZRdNzEKQjYkWaXARfqTuQhN3UvuZPsDf064 distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(24)) + _ = vQRcHh7prXCSmo7645kktQGhhzw5sU0EKA0dPj6IGYmm1gcJKZCF1C59jwIEMYkjknYtrcnzmdZRdNzEKQjYkWaXARfqTuQhN3UvuZPsDf064 + var v5NBESJZR67FQzEdXo distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(25)) + _ = v5NBESJZR67FQzEdXo + var mPmT0xvvir9qcuagEB1FjKePcHSzFin3eSyj5pskFDh8gkwgQ4UNSpwZObSgan7dvaHmmEhuf1W9XqBzVuG3WDZ6umhIzsp3uquqfx distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(26)) + _ = mPmT0xvvir9qcuagEB1FjKePcHSzFin3eSyj5pskFDh8gkwgQ4UNSpwZObSgan7dvaHmmEhuf1W9XqBzVuG3WDZ6umhIzsp3uquqfx + var gajCKIRYCfEvkywyxqQtnZN2X1KUCvA2hToDYPpNc5pOusuzLZIxRhqjeBINPqE3dMhjleIMHi8twhfLrgy distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(27)) + _ = gajCKIRYCfEvkywyxqQtnZN2X1KUCvA2hToDYPpNc5pOusuzLZIxRhqjeBINPqE3dMhjleIMHi8twhfLrgy + var tVrPMl8sA8IosBJShd8LqkdVuCeGLSWg5PgHkDbSq6SCUnbg5DMAv9oLfb76sTvo7PR2G7McNtJjTgJ3QinYDOXGuZIe8tcMho distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(28)) + _ = tVrPMl8sA8IosBJShd8LqkdVuCeGLSWg5PgHkDbSq6SCUnbg5DMAv9oLfb76sTvo7PR2G7McNtJjTgJ3QinYDOXGuZIe8tcMho + var cUrxulKuQoIhZ9NgsDb5TH2eR4aZh452ydMqQerlucMtphQVZHq9LT7jOiaLSHGKuSrLekPafmxhi1tq02Bc2YVYzl0IswOZJPWee0yy1TF6XujIvnOUH distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(29)) + _ = cUrxulKuQoIhZ9NgsDb5TH2eR4aZh452ydMqQerlucMtphQVZHq9LT7jOiaLSHGKuSrLekPafmxhi1tq02Bc2YVYzl0IswOZJPWee0yy1TF6XujIvnOUH + var oY7kvPVenvblJViuFV4oOckuE2PHkOElURKpg3pV9wzdakL8wyGR5ppr16f8W7jvvKcK2obG9OZNg8FxPqpT distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(30)) + _ = oY7kvPVenvblJViuFV4oOckuE2PHkOElURKpg3pV9wzdakL8wyGR5ppr16f8W7jvvKcK2obG9OZNg8FxPqpT + var kygf0KxSTLZM0WIYsStdDMhVWjBOEc distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(31)) + _ = kygf0KxSTLZM0WIYsStdDMhVWjBOEc + var dVpTt5jrKlWu0I6Hq6H80zTmUxwUAJYO4dKwf6DQfbTQWe9fGr8TtnynL58wFnRcfuVdaQJ6yRM distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(32)) + _ = dVpTt5jrKlWu0I6Hq6H80zTmUxwUAJYO4dKwf6DQfbTQWe9fGr8TtnynL58wFnRcfuVdaQJ6yRM + var dAod1 distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(33)) + _ = dAod1 + var kgoXTBI4KqvOyUWXaIwWyd6yIIPp5SQe51pyZdLfvIe2MkKoI5OE1McSiYFuc4hHjnn2UREQjPE distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(34)) + _ = kgoXTBI4KqvOyUWXaIwWyd6yIIPp5SQe51pyZdLfvIe2MkKoI5OE1McSiYFuc4hHjnn2UREQjPE + var jEKHjJEhnyPrT0ICMbND4ZDuST7YpZmchzVcdgZTsbRuoLUO distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(35)) + _ = jEKHjJEhnyPrT0ICMbND4ZDuST7YpZmchzVcdgZTsbRuoLUO + var fCYu6JnCdhV5dcnEHZqdxqxb1NvkWaW3a7CSwZOVuwwMP7xaxWQFTXVO5JA distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(36)) + _ = fCYu6JnCdhV5dcnEHZqdxqxb1NvkWaW3a7CSwZOVuwwMP7xaxWQFTXVO5JA + var eLgDSIT360uKHiKfIXuvvt80krKy3E9CB distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(37)) + _ = eLgDSIT360uKHiKfIXuvvt80krKy3E9CB + var rRne27EVaaUYkyaACWgTLRzkUZBHz27jIJAAr9fWGycUhL7GkbDNTCGmZk7c8cH8TMH4BRU56iZVykwQNYvVYzJyl5W8Rq85Lo0X0sThIZ894Z5 distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(38)) + _ = rRne27EVaaUYkyaACWgTLRzkUZBHz27jIJAAr9fWGycUhL7GkbDNTCGmZk7c8cH8TMH4BRU56iZVykwQNYvVYzJyl5W8Rq85Lo0X0sThIZ894Z5 + var z767kHpudwA927klR1QW86dnn2HLK0WnSJ8xeBYvEGIUKdIekF82nkMXwlSNbA392CEmc0OIO0150CDQjUSCPkSsVTFyu6zVcjToo distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(39)) + _ = z767kHpudwA927klR1QW86dnn2HLK0WnSJ8xeBYvEGIUKdIekF82nkMXwlSNbA392CEmc0OIO0150CDQjUSCPkSsVTFyu6zVcjToo + var w7jnhD4IjE4lXlmTNY7h8QxxKuCCUVcC72vq1ZebZBFcyhXMEC2tL2jBHvMg7FsGMf0DqWQ distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(40)) + _ = w7jnhD4IjE4lXlmTNY7h8QxxKuCCUVcC72vq1ZebZBFcyhXMEC2tL2jBHvMg7FsGMf0DqWQ + var rIGa13FV0ZR5AdCTnWlDOXjT distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(41)) + _ = rIGa13FV0ZR5AdCTnWlDOXjT + var bo8LMTlo6KHZQuTJpU00AHCVdVHTzdSQ2F3iC0QJX6wbHs0iZc4bcQwsw4ltSneeHqFPQA5sPrxwp2P distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(42)) + _ = bo8LMTlo6KHZQuTJpU00AHCVdVHTzdSQ2F3iC0QJX6wbHs0iZc4bcQwsw4ltSneeHqFPQA5sPrxwp2P + var tu44YUABDodKj1b40ebx0tUcGO29nOdXBAh69zcrHWXduPkyHnvXqWvorVJ1N87iPojCHUYJ5ik2FZh63NDp6sEcI6RZeZeHEBKjzWoUtEIbOBPJa6v distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(43)) + _ = tu44YUABDodKj1b40ebx0tUcGO29nOdXBAh69zcrHWXduPkyHnvXqWvorVJ1N87iPojCHUYJ5ik2FZh63NDp6sEcI6RZeZeHEBKjzWoUtEIbOBPJa6v + var s1oqnYwqyEn1UiHJIR2wPc2ujLz58hTDNQR2b1re6AhBWW5kzH9z7s distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(44)) + _ = s1oqnYwqyEn1UiHJIR2wPc2ujLz58hTDNQR2b1re6AhBWW5kzH9z7s + var wZliaUx98doRU7rNu6fbT2mk815GbGmEYSQuuUjk35kZlZJATuI3xyfQWguOR6q1sImmNRfrXp2FGh01LINAXJ3cPV3rXDLjZobznGHUdPAQhzj6RyLYVp distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(45)) + _ = wZliaUx98doRU7rNu6fbT2mk815GbGmEYSQuuUjk35kZlZJATuI3xyfQWguOR6q1sImmNRfrXp2FGh01LINAXJ3cPV3rXDLjZobznGHUdPAQhzj6RyLYVp + var iX8k4PuCzNziDOGiuwRX7fX9z6BEXhkCke2svL5oljwqETLc3Rvyao7TAi3LKF6MtxUq37S42lfGOcrwYNCcUpVINAu077PqQh distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(46)) + _ = iX8k4PuCzNziDOGiuwRX7fX9z6BEXhkCke2svL5oljwqETLc3Rvyao7TAi3LKF6MtxUq37S42lfGOcrwYNCcUpVINAu077PqQh + var sD9Xav0QEOwlydXcltrIAOUOIBhVXVjDFmIlxe5HfxJuw7a3NJDjnnuHAO9VHmkR2wzKvX8aBDrVmcFl distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(47)) + _ = sD9Xav0QEOwlydXcltrIAOUOIBhVXVjDFmIlxe5HfxJuw7a3NJDjnnuHAO9VHmkR2wzKvX8aBDrVmcFl + var w9EjUpyHHRBcb31bvL2gDTM6aN6ENy2r distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(48)) + _ = w9EjUpyHHRBcb31bvL2gDTM6aN6ENy2r + var pZ51Eey23PSGICwafccEh3nv8a7UIK2iNS1RfoaCrJ distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(49)) + _ = pZ51Eey23PSGICwafccEh3nv8a7UIK2iNS1RfoaCrJ + var cb8FIw3u7G8UiFsOGqB2r8X0E distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(50)) + _ = cb8FIw3u7G8UiFsOGqB2r8X0E + var cqnsx3vgQ5yUZiT0NfGWch99Sz2t0fwcKrJoMmph1ptrJjfIqLsFQfSlkcJ7JFt0Fls0zLEkgETuOjE62kZOyWOHfXEaViXGtktc3WcE distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(51)) + _ = cqnsx3vgQ5yUZiT0NfGWch99Sz2t0fwcKrJoMmph1ptrJjfIqLsFQfSlkcJ7JFt0Fls0zLEkgETuOjE62kZOyWOHfXEaViXGtktc3WcE + var cjQHmCGaCBlQwj86IWfLZT4S8TV9 distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(52)) + _ = cjQHmCGaCBlQwj86IWfLZT4S8TV9 + var kmKS4wSYkuaPVwT7gQvCnrlUq3Aq86a3fJFLhCwyumZiBSCTbDw5eC0Gbxnu2W9lTfK2EPrd3rJppEskL4LWq8ChHO3ZRI1XMh4z5ibLx distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(53)) + _ = kmKS4wSYkuaPVwT7gQvCnrlUq3Aq86a3fJFLhCwyumZiBSCTbDw5eC0Gbxnu2W9lTfK2EPrd3rJppEskL4LWq8ChHO3ZRI1XMh4z5ibLx + var q1w6LUdsyk2L6Xj4Zu1pXbqTWJ28bOS65 distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(54)) + _ = q1w6LUdsyk2L6Xj4Zu1pXbqTWJ28bOS65 + var j0HejTVIA0AU8kGoqhD3ujGPiKNTT7ez9mA10vbjezgwcCFOTI67WopqH3JWjPjB2vgnp2hnwoD5UKmEmEb58OvRP6ikVoNuYBR distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(55)) + _ = j0HejTVIA0AU8kGoqhD3ujGPiKNTT7ez9mA10vbjezgwcCFOTI67WopqH3JWjPjB2vgnp2hnwoD5UKmEmEb58OvRP6ikVoNuYBR + var b1vQTWqj8hvGIg4NNe9K46MWC2R7O8YKVMKFGWCX1GWgGfBD26aGpxmuUU6RJrUHHvVfcOfUHZi2IJvTBmJsQpjgUldOHnhaRTfPp80VP0gNHb9gaX2n5 distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(56)) + _ = b1vQTWqj8hvGIg4NNe9K46MWC2R7O8YKVMKFGWCX1GWgGfBD26aGpxmuUU6RJrUHHvVfcOfUHZi2IJvTBmJsQpjgUldOHnhaRTfPp80VP0gNHb9gaX2n5 + var eojcqQlbou3xtqcgn67uUd0vFebHtwD53Ko508UycnBiq5lbw6Fg4jcvv37F5uEi7KoxubM4irzxKq distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(57)) + _ = eojcqQlbou3xtqcgn67uUd0vFebHtwD53Ko508UycnBiq5lbw6Fg4jcvv37F5uEi7KoxubM4irzxKq + var zH distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(58)) + _ = zH + var yXTIbTDjWUn6gCVk2lQGSZr3TCdqbtiHw4edqxs6DLzkJMdFyeYs1jl7Ls6yXVKXlKM7bbGw1v7022fiJIzpF6Rf distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(59)) + _ = yXTIbTDjWUn6gCVk2lQGSZr3TCdqbtiHw4edqxs6DLzkJMdFyeYs1jl7Ls6yXVKXlKM7bbGw1v7022fiJIzpF6Rf + return dVpTt5jrKlWu0I6Hq6H80zTmUxwUAJYO4dKwf6DQfbTQWe9fGr8TtnynL58wFnRcfuVdaQJ6yRM + }), distsys.TLASetComprehension([]distsys.TLAValue{distsys.NewTLANumber(68), distsys.TLA_Len(distsys.TLA_Nat), distsys.TLA_Tail(distsys.NewTLATuple())}, func(args4 []distsys.TLAValue) distsys.TLAValue { + var nMDLcmFYG6N5X5qUG4Q4ELPxCZRP1ByOFD8cIbWHPjvMaPtf5Q7BBDw71oHBnalYi6KgmUCNtO0j7r3nAkq7Wn3ClMSz44nnJXpgNIZZydK distsys.TLAValue = args4[0] + _ = nMDLcmFYG6N5X5qUG4Q4ELPxCZRP1ByOFD8cIbWHPjvMaPtf5Q7BBDw71oHBnalYi6KgmUCNtO0j7r3nAkq7Wn3ClMSz44nnJXpgNIZZydK + var vvmBdcUQcmzi3aF14n2S3Oie2iBRkC6Pq5dh91BNivvWOU8pQ8lX0buK5SxjDEHFi distsys.TLAValue = args4[1] + _ = vvmBdcUQcmzi3aF14n2S3Oie2iBRkC6Pq5dh91BNivvWOU8pQ8lX0buK5SxjDEHFi + var zWSbRBDcKvPAzjLcOPdpDMdxHB07sO7kEq9Sk9MydQzf7b5IguRfwHTQeQwDS8uwsPPE77kph4VdYlWi6GlfISwJgzUF5mDwt distsys.TLAValue = args4[2].ApplyFunction(distsys.NewTLANumber(0)) + _ = zWSbRBDcKvPAzjLcOPdpDMdxHB07sO7kEq9Sk9MydQzf7b5IguRfwHTQeQwDS8uwsPPE77kph4VdYlWi6GlfISwJgzUF5mDwt + var tM4biPtMAZBAnwcHTRZchOiUQbHTr5KKiEMSYGuaTRcR2D7H7gRNHU1jtt7MufPg0LIhai5q4fS4 distsys.TLAValue = args4[2].ApplyFunction(distsys.NewTLANumber(1)) + _ = tM4biPtMAZBAnwcHTRZchOiUQbHTr5KKiEMSYGuaTRcR2D7H7gRNHU1jtt7MufPg0LIhai5q4fS4 + var wcjXTUfGXsyPRN2pceinloBdDEEHrHSn1maNU4p0sXLC7L8XZVx23CVShjmVQFhJGTdbd1S4Yez3THebEY41dE9hSjqL distsys.TLAValue = args4[2].ApplyFunction(distsys.NewTLANumber(2)) + _ = wcjXTUfGXsyPRN2pceinloBdDEEHrHSn1maNU4p0sXLC7L8XZVx23CVShjmVQFhJGTdbd1S4Yez3THebEY41dE9hSjqL + var av02TZ distsys.TLAValue = args4[2].ApplyFunction(distsys.NewTLANumber(3)) + _ = av02TZ + var wT99Pz2tTM7YcBTcUsZXIkd6iERmCmjIeM6olKGr1W2o3qbpooN80wnA37x2Yu03QomrJCPixVKWEQ8CCTkNXiBEu8hYnGcporfbymNh distsys.TLAValue = args4[2].ApplyFunction(distsys.NewTLANumber(4)) + _ = wT99Pz2tTM7YcBTcUsZXIkd6iERmCmjIeM6olKGr1W2o3qbpooN80wnA37x2Yu03QomrJCPixVKWEQ8CCTkNXiBEu8hYnGcporfbymNh + var dmUGiLMfUfbLQetiOQLGDsJfywJllYN9HZWT0mRxzdB6Oi2PH5mLqQQkSgh7K distsys.TLAValue = args4[2].ApplyFunction(distsys.NewTLANumber(5)) + _ = dmUGiLMfUfbLQetiOQLGDsJfywJllYN9HZWT0mRxzdB6Oi2PH5mLqQQkSgh7K + var xXGfSvXoSeT9bS distsys.TLAValue = args4[2].ApplyFunction(distsys.NewTLANumber(6)) + _ = xXGfSvXoSeT9bS + var sWJBRBh7HLygHJkCRastp distsys.TLAValue = args4[2].ApplyFunction(distsys.NewTLANumber(7)) + _ = sWJBRBh7HLygHJkCRastp + var jA5vUa3xHA distsys.TLAValue = args4[2].ApplyFunction(distsys.NewTLANumber(8)) + _ = jA5vUa3xHA + var aq distsys.TLAValue = args4[2].ApplyFunction(distsys.NewTLANumber(9)) + _ = aq + var f distsys.TLAValue = args4[2].ApplyFunction(distsys.NewTLANumber(10)) + _ = f + var prStzVZ7XpWWbKe distsys.TLAValue = args4[2].ApplyFunction(distsys.NewTLANumber(11)) + _ = prStzVZ7XpWWbKe + var eIRzlCgxVKnkew9eZcLbvOl9EuW5fcCfFhRQHoXFluPH6xZWIYMDKcLFXNsb9JrHulGXYSJnGaTC20T7ONoHzHyyrf6uS distsys.TLAValue = args4[2].ApplyFunction(distsys.NewTLANumber(12)) + _ = eIRzlCgxVKnkew9eZcLbvOl9EuW5fcCfFhRQHoXFluPH6xZWIYMDKcLFXNsb9JrHulGXYSJnGaTC20T7ONoHzHyyrf6uS + var nVjmRIA1A0qvjMvMcWtEazsaHzES6Y6avOavkfPu9vivjs3nLb1xNhDASadHLLwDOpirr distsys.TLAValue = args4[2].ApplyFunction(distsys.NewTLANumber(13)) + _ = nVjmRIA1A0qvjMvMcWtEazsaHzES6Y6avOavkfPu9vivjs3nLb1xNhDASadHLLwDOpirr + var i8VaAM97sRQIskPqOb8F9qgrC2xbfIFajVEpFV1swyX4HY4itr8dqiu7CtOm4mkLHGYpfcINUDEo distsys.TLAValue = args4[2].ApplyFunction(distsys.NewTLANumber(14)) + _ = i8VaAM97sRQIskPqOb8F9qgrC2xbfIFajVEpFV1swyX4HY4itr8dqiu7CtOm4mkLHGYpfcINUDEo + var hRv4iQGc1JVFMKCTUQzsbwHCqzQQBxhBenCzVtigvQEu53lXN6VbVCZjnphAv5ivPE0eQkvDLvE9UG085C7FGFX3Az5rx0L5jw4WYA distsys.TLAValue = args4[2].ApplyFunction(distsys.NewTLANumber(15)) + _ = hRv4iQGc1JVFMKCTUQzsbwHCqzQQBxhBenCzVtigvQEu53lXN6VbVCZjnphAv5ivPE0eQkvDLvE9UG085C7FGFX3Az5rx0L5jw4WYA + var twOadTdWqFwx7Njr0GZjFFKPMe distsys.TLAValue = args4[2].ApplyFunction(distsys.NewTLANumber(16)) + _ = twOadTdWqFwx7Njr0GZjFFKPMe + var d2jxAQesE8O168 distsys.TLAValue = args4[2].ApplyFunction(distsys.NewTLANumber(17)) + _ = d2jxAQesE8O168 + var lkwXOmWqOIJ6Ql8OIq3bTcbIQskJSBVZDSFBlgPVo2bsCFMTna3KlDhloRIADgpYDkhsH1eVxsLeomYGENKO2tPvZ885GYMGU4ySwDAW671GD7XWkHH1z0 distsys.TLAValue = args4[2].ApplyFunction(distsys.NewTLANumber(18)) + _ = lkwXOmWqOIJ6Ql8OIq3bTcbIQskJSBVZDSFBlgPVo2bsCFMTna3KlDhloRIADgpYDkhsH1eVxsLeomYGENKO2tPvZ885GYMGU4ySwDAW671GD7XWkHH1z0 + var vtzcOt0qehTOCbja7hiqi9V4Hs2tIvgee distsys.TLAValue = args4[2].ApplyFunction(distsys.NewTLANumber(19)) + _ = vtzcOt0qehTOCbja7hiqi9V4Hs2tIvgee + var sck5QnM1QBAJZiiQTl1cWPDvK6T924jcFs0W0rCUSPvBJpzWw6dKuw9GSx7qYhOMktuyxHMl7cQ2WOCzwdAfmapTHCN8ULAWdHYB3RhcDMwT distsys.TLAValue = args4[2].ApplyFunction(distsys.NewTLANumber(20)) + _ = sck5QnM1QBAJZiiQTl1cWPDvK6T924jcFs0W0rCUSPvBJpzWw6dKuw9GSx7qYhOMktuyxHMl7cQ2WOCzwdAfmapTHCN8ULAWdHYB3RhcDMwT + var cBDTNj2CdkpUB6FQj6Eh4f0y25yUZZz6nyHTD0HKxV distsys.TLAValue = args4[2].ApplyFunction(distsys.NewTLANumber(21)) + _ = cBDTNj2CdkpUB6FQj6Eh4f0y25yUZZz6nyHTD0HKxV + var abkEO30MYO2pVxZCTm distsys.TLAValue = args4[2].ApplyFunction(distsys.NewTLANumber(22)) + _ = abkEO30MYO2pVxZCTm + var hXmoGfFLEVzH440IsaAa distsys.TLAValue = args4[2].ApplyFunction(distsys.NewTLANumber(23)) + _ = hXmoGfFLEVzH440IsaAa + var tLJy44X8hgEaFaijSMIP0cBZHKwCTwNFcfKVbc3KOspZa47YLjw7whIRfeRgcbF9VVbOt0B6eFiLfmErFSGKkc distsys.TLAValue = args4[2].ApplyFunction(distsys.NewTLANumber(24)) + _ = tLJy44X8hgEaFaijSMIP0cBZHKwCTwNFcfKVbc3KOspZa47YLjw7whIRfeRgcbF9VVbOt0B6eFiLfmErFSGKkc + var ffsgS88PJbkGRGRPyvshSsbCSuCvdKmCzWvj5jjtec70RMylBnbam3raHiWhiBRwHpznDps6UZ4ToyM distsys.TLAValue = args4[2].ApplyFunction(distsys.NewTLANumber(25)) + _ = ffsgS88PJbkGRGRPyvshSsbCSuCvdKmCzWvj5jjtec70RMylBnbam3raHiWhiBRwHpznDps6UZ4ToyM + var kp5z5odj84ZCfq8YO8EddxCGN6Cdd9Fy4vFsTNHEfb4uzqFO0t1KFdX6jC2rPZrw7iWCXC0I7WopTbDMpDJ distsys.TLAValue = args4[2].ApplyFunction(distsys.NewTLANumber(26)) + _ = kp5z5odj84ZCfq8YO8EddxCGN6Cdd9Fy4vFsTNHEfb4uzqFO0t1KFdX6jC2rPZrw7iWCXC0I7WopTbDMpDJ + var fW3AJLNnZhCFZobuhEplMFQJBJyFWuvxdVgPRqGF7XSSyhcElsQAe84TIlEJ0YsI99KvebNeRKfwyZYkghsxWRZMkbimKER distsys.TLAValue = args4[2].ApplyFunction(distsys.NewTLANumber(27)) + _ = fW3AJLNnZhCFZobuhEplMFQJBJyFWuvxdVgPRqGF7XSSyhcElsQAe84TIlEJ0YsI99KvebNeRKfwyZYkghsxWRZMkbimKER + var safYYZEZdjiPMwpqGelf0JtCZ3gxbKWgp7gROzmTkMMI3S26yi7jtplo1700qqjKIn distsys.TLAValue = args4[2].ApplyFunction(distsys.NewTLANumber(28)) + _ = safYYZEZdjiPMwpqGelf0JtCZ3gxbKWgp7gROzmTkMMI3S26yi7jtplo1700qqjKIn + var iPZqmoYuMPJZgulzB8meSpcZb4bnsiiOATvyn0pWKol2pHA29qCvVLVa0ANtPDr0Su0MMv403 distsys.TLAValue = args4[2].ApplyFunction(distsys.NewTLANumber(29)) + _ = iPZqmoYuMPJZgulzB8meSpcZb4bnsiiOATvyn0pWKol2pHA29qCvVLVa0ANtPDr0Su0MMv403 + var d5zv5RIsAzs2ahTNTGSgUqEWeRuUBQn8rnA4zCPPNJHaOr2qnst0RBA1EVhNnqmAhBpVn0TgFfAMGzRwQYM5McLHK54fGQKKXHrlV0NYbeFClB2r7hj distsys.TLAValue = args4[2].ApplyFunction(distsys.NewTLANumber(30)) + _ = d5zv5RIsAzs2ahTNTGSgUqEWeRuUBQn8rnA4zCPPNJHaOr2qnst0RBA1EVhNnqmAhBpVn0TgFfAMGzRwQYM5McLHK54fGQKKXHrlV0NYbeFClB2r7hj + var idl0BkyjmqQR2ogEUbauQslCMUFgmpkeB9fK7BGsFYgj88jn9Yk8fFmyiigqq8XYPsvLIfmyfKINd2fEt7qli5qKMzymBZ47bMn distsys.TLAValue = args4[2].ApplyFunction(distsys.NewTLANumber(31)) + _ = idl0BkyjmqQR2ogEUbauQslCMUFgmpkeB9fK7BGsFYgj88jn9Yk8fFmyiigqq8XYPsvLIfmyfKINd2fEt7qli5qKMzymBZ47bMn + var zwHA6J50eAqpOn4Fbddd4o1jJh0epr1YLcR0CiYxo6SdhySdmqPWuPvwLlJP3hRDl84EWzZs6J distsys.TLAValue = args4[2].ApplyFunction(distsys.NewTLANumber(32)) + _ = zwHA6J50eAqpOn4Fbddd4o1jJh0epr1YLcR0CiYxo6SdhySdmqPWuPvwLlJP3hRDl84EWzZs6J + var v7vKCElgaxOtASA7f2MQ6nwPhPF3U319cVK1ptI4xk7zi5pqyYHeZW860mWbRNQbIyjs1VioacJv01D3NGeFZg distsys.TLAValue = args4[2].ApplyFunction(distsys.NewTLANumber(33)) + _ = v7vKCElgaxOtASA7f2MQ6nwPhPF3U319cVK1ptI4xk7zi5pqyYHeZW860mWbRNQbIyjs1VioacJv01D3NGeFZg + var fRwBpdsAaVfacRTkB9lOL8vQnYPZf8xbyuI66WTf1UzHB9uL5NNEyFCgHcUu7q7bdxShZV454X5Wr7EILJU2RDqiNsMdHpN distsys.TLAValue = args4[2].ApplyFunction(distsys.NewTLANumber(34)) + _ = fRwBpdsAaVfacRTkB9lOL8vQnYPZf8xbyuI66WTf1UzHB9uL5NNEyFCgHcUu7q7bdxShZV454X5Wr7EILJU2RDqiNsMdHpN + var asB9JRbcFvI1JMj7JMqkM0cZFcKmLjCaPsMz8pCrMyhWHev65Gp0dkWdxf87hDN7rfYo9xvLhcvmC6RxVdfFCI1GPDewEJ02VqOnnGCvKUBVJImZY distsys.TLAValue = args4[2].ApplyFunction(distsys.NewTLANumber(35)) + _ = asB9JRbcFvI1JMj7JMqkM0cZFcKmLjCaPsMz8pCrMyhWHev65Gp0dkWdxf87hDN7rfYo9xvLhcvmC6RxVdfFCI1GPDewEJ02VqOnnGCvKUBVJImZY + var k4uPFdT09BGyWRWYEu7pX distsys.TLAValue = args4[2].ApplyFunction(distsys.NewTLANumber(36)) + _ = k4uPFdT09BGyWRWYEu7pX + var h5pW5RegOA0yWovd7W4YjksfYlGpW4I0U4RyJpQ7U698zO5JaejMotDyOkAHYxSKdDylSDT2vX3v4TQ8vmi3WztCuxArTodhQIvcL distsys.TLAValue = args4[2].ApplyFunction(distsys.NewTLANumber(37)) + _ = h5pW5RegOA0yWovd7W4YjksfYlGpW4I0U4RyJpQ7U698zO5JaejMotDyOkAHYxSKdDylSDT2vX3v4TQ8vmi3WztCuxArTodhQIvcL + var up0Vdghc938Mr6hIH3j0VGUmvFxGw4sm9f2Dq distsys.TLAValue = args4[2].ApplyFunction(distsys.NewTLANumber(38)) + _ = up0Vdghc938Mr6hIH3j0VGUmvFxGw4sm9f2Dq + var kKrE0nlxzpu1lHtP7uXyLbghdH3rmMWbOEAY7Cqkn4xchUmVC distsys.TLAValue = args4[2].ApplyFunction(distsys.NewTLANumber(39)) + _ = kKrE0nlxzpu1lHtP7uXyLbghdH3rmMWbOEAY7Cqkn4xchUmVC + return distsys.NewTLASet(zWSbRBDcKvPAzjLcOPdpDMdxHB07sO7kEq9Sk9MydQzf7b5IguRfwHTQeQwDS8uwsPPE77kph4VdYlWi6GlfISwJgzUF5mDwt) + }), distsys.TLA_Nat, distsys.TLA_Len(distsys.TLA_Nat).ApplyFunction(distsys.NewTLATuple(distsys.TLA_Int, distsys.TLA_Head(distsys.TLA_Nat), distsys.TLA_Cardinality(distsys.NewTLATuple()))), distsys.TLASetComprehension([]distsys.TLAValue{distsys.NewTLATuple()}, func(args5 []distsys.TLAValue) distsys.TLAValue { + var jFSnew60k9UkNMbOwRMQkAjaDOsCVlPPzNCyFhfU0fyWovez0zXZDVqaX3EHHxW8P9RjGDPX8z8k8OPG6zvn distsys.TLAValue = args5[0] + _ = jFSnew60k9UkNMbOwRMQkAjaDOsCVlPPzNCyFhfU0fyWovez0zXZDVqaX3EHHxW8P9RjGDPX8z8k8OPG6zvn + return distsys.TLASetComprehension([]distsys.TLAValue{distsys.NewTLASet()}, func(args6 []distsys.TLAValue) distsys.TLAValue { + var bJdvTIPKLRX2S7AzBaJhHn6qzYpgdcuCSHMXowo distsys.TLAValue = args6[0] + _ = bJdvTIPKLRX2S7AzBaJhHn6qzYpgdcuCSHMXowo + return jFSnew60k9UkNMbOwRMQkAjaDOsCVlPPzNCyFhfU0fyWovez0zXZDVqaX3EHHxW8P9RjGDPX8z8k8OPG6zvn + }) + }), func() distsys.TLAValue { + switch { + case distsys.NewTLATuple(distsys.NewTLAString("|AP8[H3v] 0TXS4l;{MD>jLmGb~(,$M3&I+03G/|yp\\lCm\"gW{Y,|Jp`i$ICm_%\").WjP_Q/lA5")).AsBool(): + return distsys.TLA_Nat + case distsys.NewTLAString("~ l").AsBool(): + return distsys.NewTLANumber(34) + case distsys.TLA_Int.ApplyFunction(distsys.NewTLAString("tpFXgtDC996txdhqxvc6uTZ7LGguVCIqPWhb4GPq0vrjsU6VJ36ivYQrBcr6eLu6EeizwwVG4duDRq6")).AsBool(): + return distsys.TLA_Cardinality(distsys.TLA_Nat) + default: + panic("no cases matched for TLA+ case expression!") + } + }(), distsys.NewTLASet(distsys.NewTLANumber(103), distsys.NewTLATuple(distsys.NewTLASet()), distsys.TLA_Tail(distsys.NewTLAString("ao>Q^45R*)&S.P;@h>(g&QFHhB2]CIa,O)R}&icu)|bex)&O5eqhS/xtaJG,nV#QWjd-c_f:)d"), distsys.TLA_Nat, distsys.NewTLANumber(55), distsys.NewTLAString(">&cXJ)Blo@-}ot<1`,WaQ4UI%BWVB)psW,;X"), distsys.NewTLATuple(), distsys.NewTLANumber(68)}, func(args8 []distsys.TLAValue) distsys.TLAValue { + var kO0o8ujUrtEZSKXpafhXQv9EHVxF45b4MkRvqWCB76Ex6z1DdtwByAbWNZyQ6UfhvyVKTxjOmES5Jlx2nCIGaQB7KsdUw00Ozvmm7CtuhSt4GEGL1Hvf distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(0)) + _ = kO0o8ujUrtEZSKXpafhXQv9EHVxF45b4MkRvqWCB76Ex6z1DdtwByAbWNZyQ6UfhvyVKTxjOmES5Jlx2nCIGaQB7KsdUw00Ozvmm7CtuhSt4GEGL1Hvf + var ldBDvTLTWC5zA7k distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(1)) + _ = ldBDvTLTWC5zA7k + var pIjp2lddQViuziUJ5PzpXdPBwEdaMP3AszU3BjFhemaQDBE8gbMv7jwixPTpChTqWqpLiQkwJIpjVWg0uYQco8dGQ66ukUDtw2usxlCN distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(2)) + _ = pIjp2lddQViuziUJ5PzpXdPBwEdaMP3AszU3BjFhemaQDBE8gbMv7jwixPTpChTqWqpLiQkwJIpjVWg0uYQco8dGQ66ukUDtw2usxlCN + var b3UtW0rVZtZyhgTLrtyDEsKDHKBXcplhnMNq3Nb1rDEzEvD14GQ4xrCpHbtMYYxQ1Ls5FLheAaQQA4SUmAULszAeG03r4PK6CQjDJCg3DFtNo8od2pNJ distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(3)) + _ = b3UtW0rVZtZyhgTLrtyDEsKDHKBXcplhnMNq3Nb1rDEzEvD14GQ4xrCpHbtMYYxQ1Ls5FLheAaQQA4SUmAULszAeG03r4PK6CQjDJCg3DFtNo8od2pNJ + var vMEv8m7FSuBnidiaNz8mtxx8tdtU8b4F202sYMtG7 distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(4)) + _ = vMEv8m7FSuBnidiaNz8mtxx8tdtU8b4F202sYMtG7 + var iQZO0T24G3qnDyj6vVBLHvMjgcaZOitVbHtyt8AL22DS1mkpWey2XwbBX0m4gXJAFsgTGNKYMaSYvPCyoqjXWZarUEJGvR642x2FUMJ7Fhw7FZE distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(5)) + _ = iQZO0T24G3qnDyj6vVBLHvMjgcaZOitVbHtyt8AL22DS1mkpWey2XwbBX0m4gXJAFsgTGNKYMaSYvPCyoqjXWZarUEJGvR642x2FUMJ7Fhw7FZE + var yjoZf3KwI7SqmHeLeKhvHU2gxANVgfse8azWiGYPxfpsacwcrxnmKoofmI4CPGNsUieyRGYAl40afhPAIU0RnOMHMJGEU5I57NclzPbplZgtzUQMENaJM distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(6)) + _ = yjoZf3KwI7SqmHeLeKhvHU2gxANVgfse8azWiGYPxfpsacwcrxnmKoofmI4CPGNsUieyRGYAl40afhPAIU0RnOMHMJGEU5I57NclzPbplZgtzUQMENaJM + var eNvWBf98yGDwLOTxgh0hmlAS8J133kVrL3yTs3jQRUSBgiEVgFQTBe1CpaoJcFQrUtfWssk21W8DheW distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(7)) + _ = eNvWBf98yGDwLOTxgh0hmlAS8J133kVrL3yTs3jQRUSBgiEVgFQTBe1CpaoJcFQrUtfWssk21W8DheW + var iksItfTdWlf91wMH1QVzekiPxgtyt6iMonMoOdWHikwWzrfV44cfCCkkhKGDNWrBG7Evu1EXKXzZ8him06EYYXs34IrJhQBWRav62X distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(8)) + _ = iksItfTdWlf91wMH1QVzekiPxgtyt6iMonMoOdWHikwWzrfV44cfCCkkhKGDNWrBG7Evu1EXKXzZ8him06EYYXs34IrJhQBWRav62X + var tAnobkLMVODeyXE3dJMbTOex55Rh9KfBmbCPIDIWqOYlIXBGwW3ca3CcdndqOXK6sY1spZMtel0Gbb8u3rlTnvMkXYTxpFaRWoSgRtb8QUxf distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(9)) + _ = tAnobkLMVODeyXE3dJMbTOex55Rh9KfBmbCPIDIWqOYlIXBGwW3ca3CcdndqOXK6sY1spZMtel0Gbb8u3rlTnvMkXYTxpFaRWoSgRtb8QUxf + var jOEN2cA1B9hSAANKYwLKzvrXDS3cKD8RG8U7NqXf0tx6RmGrEw distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(10)) + _ = jOEN2cA1B9hSAANKYwLKzvrXDS3cKD8RG8U7NqXf0tx6RmGrEw + var pRguamU3idbV23h2ampbT0nXDhmJsIb0aAKe distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(11)) + _ = pRguamU3idbV23h2ampbT0nXDhmJsIb0aAKe + var uxBIVI2d1IQe4i2tn1vBKtj1KH5nJ21S8EvSaDMTuc69EAf66jFR9 distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(12)) + _ = uxBIVI2d1IQe4i2tn1vBKtj1KH5nJ21S8EvSaDMTuc69EAf66jFR9 + var jQHDNDhlLsdZ6J49JzRNaf0SEGWYTT5E distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(13)) + _ = jQHDNDhlLsdZ6J49JzRNaf0SEGWYTT5E + var k1 distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(14)) + _ = k1 + var elsvkEBOPBXA4p1xJhWv8mancOIbcsb6KDz23GUGjYXc0PAfRmRrwrDtvL0N8nfvOsPpkpVcbhLxUTm0MtNzxM87VN distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(15)) + _ = elsvkEBOPBXA4p1xJhWv8mancOIbcsb6KDz23GUGjYXc0PAfRmRrwrDtvL0N8nfvOsPpkpVcbhLxUTm0MtNzxM87VN + var v4Q4ZQRr9aVm04y0FsPupkMfhtT24dxkdpm2adALoTcNijFUX8nVYifww4oNk2N6HWmQvM1DQ6Q8w8YdlPVAu7ZHZggGbgeZiER6KWeo distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(16)) + _ = v4Q4ZQRr9aVm04y0FsPupkMfhtT24dxkdpm2adALoTcNijFUX8nVYifww4oNk2N6HWmQvM1DQ6Q8w8YdlPVAu7ZHZggGbgeZiER6KWeo + var btDGdQbYfLXDkiFZWKaWJrq2srlGJyXOycVmwj8HSe5sCDaiKoyl2GsCCP0z distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(17)) + _ = btDGdQbYfLXDkiFZWKaWJrq2srlGJyXOycVmwj8HSe5sCDaiKoyl2GsCCP0z + var bdff distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(18)) + _ = bdff + var gr1BdNF8dvif2l04cmJpyn0JuhNixTANCDazjty8OlIIV6vnMiGaNaJVDzOOK2R8 distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(19)) + _ = gr1BdNF8dvif2l04cmJpyn0JuhNixTANCDazjty8OlIIV6vnMiGaNaJVDzOOK2R8 + var oocQSJVdSzSSWgyLvYdc8A8zXnByxCQoGPGTgVZ9XfJ208eAeVRtBHRGZZsmi54FFnbIZjDgQT1ZVoC0WeqP103CHQCJc61uTMix6zomMp8U3imFU distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(20)) + _ = oocQSJVdSzSSWgyLvYdc8A8zXnByxCQoGPGTgVZ9XfJ208eAeVRtBHRGZZsmi54FFnbIZjDgQT1ZVoC0WeqP103CHQCJc61uTMix6zomMp8U3imFU + var c2 distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(21)) + _ = c2 + var qrr distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(22)) + _ = qrr + var m7PmBz36K8FT7NEoRfbVJafSPHcGUUTEugg2KG5cShS0PKCfSV3TeELEM6HXSPw26OFWBUxcruG6bBXGB0DVHJ8mxhSHjmfwjqlm5OCrHZeHowM distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(23)) + _ = m7PmBz36K8FT7NEoRfbVJafSPHcGUUTEugg2KG5cShS0PKCfSV3TeELEM6HXSPw26OFWBUxcruG6bBXGB0DVHJ8mxhSHjmfwjqlm5OCrHZeHowM + var kuxw1iiItainvT7Q73 distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(24)) + _ = kuxw1iiItainvT7Q73 + var zP4rMlAi020Bus8HM9BUQtojksqW3RB9KbvZDeYyZfV8m1Loxk4vHoO8heE10i3J6p5dvwHVkieGsRobkIZFAgP60APg2qlt distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(25)) + _ = zP4rMlAi020Bus8HM9BUQtojksqW3RB9KbvZDeYyZfV8m1Loxk4vHoO8heE10i3J6p5dvwHVkieGsRobkIZFAgP60APg2qlt + var zI1VBWlKdoAGmVgFskli6szD28WnwtXeokxMYN4dzS0HpVolIzAi3nahgzxc4fAiE3XlJHoAL6BlxVtAg3jJxUTs028QDByWr distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(26)) + _ = zI1VBWlKdoAGmVgFskli6szD28WnwtXeokxMYN4dzS0HpVolIzAi3nahgzxc4fAiE3XlJHoAL6BlxVtAg3jJxUTs028QDByWr + var rt0AnnGwvsNCWKPxj83FjDQ6CDywAE1wyhckI3zMq distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(27)) + _ = rt0AnnGwvsNCWKPxj83FjDQ6CDywAE1wyhckI3zMq + var i15aBySROLrwkWWU2MBe12EPcBazmfwa7z0lC6GoTcV2nWp0gjshpwxa0 distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(28)) + _ = i15aBySROLrwkWWU2MBe12EPcBazmfwa7z0lC6GoTcV2nWp0gjshpwxa0 + var gTJBp8b6o2 distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(29)) + _ = gTJBp8b6o2 + var ouDjMggVqFIWA2mvO7XDYWpSgjfmm6egFAyIhBciUKWA7k5NzBHA08G44Q2ebH2MdisKeQF3rLX9sT4 distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(30)) + _ = ouDjMggVqFIWA2mvO7XDYWpSgjfmm6egFAyIhBciUKWA7k5NzBHA08G44Q2ebH2MdisKeQF3rLX9sT4 + var fCXNrvL7LQsetTuC8NDnP7AvN9zUT2meIa6oAFmMKymeRuXz1z distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(31)) + _ = fCXNrvL7LQsetTuC8NDnP7AvN9zUT2meIa6oAFmMKymeRuXz1z + var cB75zWu4bFfZ7bReB2tz6nChMeLrnshf8iSo distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(32)) + _ = cB75zWu4bFfZ7bReB2tz6nChMeLrnshf8iSo + var mJBsPwrfnDYQEtcf6aIJ75CLMgUUAWQ distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(33)) + _ = mJBsPwrfnDYQEtcf6aIJ75CLMgUUAWQ + var tThaic86zb50xcaa9En6nMcgKmsQOVAlGlg6NODp9aD3HK7LgYtusnmagu8LeD8Gdtjk5X2liu1YhZj63oUZgXvWao distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(34)) + _ = tThaic86zb50xcaa9En6nMcgKmsQOVAlGlg6NODp9aD3HK7LgYtusnmagu8LeD8Gdtjk5X2liu1YhZj63oUZgXvWao + var vxQgtx9LyM78cX4eJ3 distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(35)) + _ = vxQgtx9LyM78cX4eJ3 + var uUgriaeOjiNpG distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(36)) + _ = uUgriaeOjiNpG + var dIJkiFIHC distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(37)) + _ = dIJkiFIHC + var hUUqU1AJ5jhhGNR distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(38)) + _ = hUUqU1AJ5jhhGNR + var mWDgHVMnBakuYYQpYbmsPhvA78t9CbU9L6mcbTVbPAmSaS distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(39)) + _ = mWDgHVMnBakuYYQpYbmsPhvA78t9CbU9L6mcbTVbPAmSaS + var ckDkPibv4YdeL3NlpUQAmKVhrZJ9s0jgha3Gzk8rge1zGSJdoSE5RYrUxELp9qWkZAskRba7F90zdC distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(40)) + _ = ckDkPibv4YdeL3NlpUQAmKVhrZJ9s0jgha3Gzk8rge1zGSJdoSE5RYrUxELp9qWkZAskRba7F90zdC + var vXNPVUvU0frMbkTYztO2jUV distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(41)) + _ = vXNPVUvU0frMbkTYztO2jUV + var gna2KuPcjDqObxBhR2WLN9TIc0H2vkV8zdLGHOkP98CevOd8RUIzS59NNGs11VrIhfOBND3EWryGW6cJmamT3AsZtI6SXiyPICIMPZEgh8iT3ILToFc2R distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(42)) + _ = gna2KuPcjDqObxBhR2WLN9TIc0H2vkV8zdLGHOkP98CevOd8RUIzS59NNGs11VrIhfOBND3EWryGW6cJmamT3AsZtI6SXiyPICIMPZEgh8iT3ILToFc2R + var unimZH distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(43)) + _ = unimZH + var cCp4BttUPhWK7Y4eFkMJkHi7ebwI0dVqHB0aEZ6EwFeBFsRgCRrlG8rVOBRLfN392YMDxVtoav distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(44)) + _ = cCp4BttUPhWK7Y4eFkMJkHi7ebwI0dVqHB0aEZ6EwFeBFsRgCRrlG8rVOBRLfN392YMDxVtoav + var nzhSngOM1p0V7P47VNCDGCeAwrp distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(45)) + _ = nzhSngOM1p0V7P47VNCDGCeAwrp + var jul4HViEqCSVrXKX9IixqvO85FGc0peEExAYlte1Ak61bXri0i17VO555DOkZFdYSBncchZ8aaHW distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(46)) + _ = jul4HViEqCSVrXKX9IixqvO85FGc0peEExAYlte1Ak61bXri0i17VO555DOkZFdYSBncchZ8aaHW + var fdzTFEcXfD0QPG5oHRsxZcbMEcZwzmypXVZmXXlTtNnzolk3zrorAQjLAuXN6lK1siSP6LJ5tbKGTnKH8LZfyNVns8m26B9OivjaOXlqxBrtUcZMnx5XD distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(47)) + _ = fdzTFEcXfD0QPG5oHRsxZcbMEcZwzmypXVZmXXlTtNnzolk3zrorAQjLAuXN6lK1siSP6LJ5tbKGTnKH8LZfyNVns8m26B9OivjaOXlqxBrtUcZMnx5XD + var ypfYTnFuWzTzgSoEOSURZGzFGjn2mcMVDH distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(48)) + _ = ypfYTnFuWzTzgSoEOSURZGzFGjn2mcMVDH + var vfuiSoDYtUOHweqrpS3nlpZSq5xP1bqaxgqyzw8uDFafP6hiv7RrhtPaltrGQSiBgSpHYCCel91N0Vbqdny distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(49)) + _ = vfuiSoDYtUOHweqrpS3nlpZSq5xP1bqaxgqyzw8uDFafP6hiv7RrhtPaltrGQSiBgSpHYCCel91N0Vbqdny + var nFl7jZeuLq3f2wNnL695EXG1ibiivJ5REpy distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(50)) + _ = nFl7jZeuLq3f2wNnL695EXG1ibiivJ5REpy + var bTz3sME7uzvqvSRG4aVh05UtyP9SnTDt5TNHyCFBLMzDrWPGhK0lY9B3O71YXk9bYFSyxAahbMqXdgBaHyW45H1B6AnCUpVkBYfOh4YmgW6uSfKl2nI distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(51)) + _ = bTz3sME7uzvqvSRG4aVh05UtyP9SnTDt5TNHyCFBLMzDrWPGhK0lY9B3O71YXk9bYFSyxAahbMqXdgBaHyW45H1B6AnCUpVkBYfOh4YmgW6uSfKl2nI + var egZacxcdnwHTXFjQv0mKAT distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(52)) + _ = egZacxcdnwHTXFjQv0mKAT + var fXDIsjR2eM0AUQjupHODeoOzPmWHg80fnpFfrREZdPnevlz distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(53)) + _ = fXDIsjR2eM0AUQjupHODeoOzPmWHg80fnpFfrREZdPnevlz + var f9ve6VS9Y8lFGuQkUIYyc3cG6E1o9w0sJANSJ8QqAhT1X1Tm5CBglXjLrbQZOWJpazH3hdj distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(54)) + _ = f9ve6VS9Y8lFGuQkUIYyc3cG6E1o9w0sJANSJ8QqAhT1X1Tm5CBglXjLrbQZOWJpazH3hdj + var jQgnsNXmg8WQzWTP7 distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(55)) + _ = jQgnsNXmg8WQzWTP7 + var yI1M54USa0JkoDwEuhrLKJfohgstZnMek58ONSDqVAVuq5MHjasjmDg0vLjnAJsiXgV8kr4b39CXdYQ4CUBxsgJoDALhshwje9EfJh37rH1rHnFp distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(56)) + _ = yI1M54USa0JkoDwEuhrLKJfohgstZnMek58ONSDqVAVuq5MHjasjmDg0vLjnAJsiXgV8kr4b39CXdYQ4CUBxsgJoDALhshwje9EfJh37rH1rHnFp + var femfYGpvUQxUXPaBbAc4V7BkEd71Z distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(57)) + _ = femfYGpvUQxUXPaBbAc4V7BkEd71Z + var slG1TW9kzeXjOFmw5mP9JRRXZx6 distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(58)) + _ = slG1TW9kzeXjOFmw5mP9JRRXZx6 + var ikwVTkV4ft7K53XiRwWiMyTlFIiRJlObVi0cCN9HPPy distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(59)) + _ = ikwVTkV4ft7K53XiRwWiMyTlFIiRJlObVi0cCN9HPPy + var nRJa6VIjG0iSk3umJGlA0YKb5LeDRF3S4LYCAromZgLDtfOd6BYVOrV3WpQ5XxAiP4ahlc1fqZ6kbnkdR5hvNUdkqVgF9hTK3 distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(60)) + _ = nRJa6VIjG0iSk3umJGlA0YKb5LeDRF3S4LYCAromZgLDtfOd6BYVOrV3WpQ5XxAiP4ahlc1fqZ6kbnkdR5hvNUdkqVgF9hTK3 + var rS01pIEqFI4nECM distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(61)) + _ = rS01pIEqFI4nECM + var x9lTCQJ46gsItDkq3s7puzIT3dhl396BxvZevpJZqgL distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(62)) + _ = x9lTCQJ46gsItDkq3s7puzIT3dhl396BxvZevpJZqgL + var wX2of distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(63)) + _ = wX2of + var yVZ2kwpKr8WTnHQBA0Zajs0WhlTLCpWvL8jieQwi2LAfioPwt1ttRZNWO41mGYeyQyRFUMN0bSCLrr6 distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(64)) + _ = yVZ2kwpKr8WTnHQBA0Zajs0WhlTLCpWvL8jieQwi2LAfioPwt1ttRZNWO41mGYeyQyRFUMN0bSCLrr6 + var dqByoNgSuCNNKVW1jvrrpBMbogTZ2G32Mtl1ns88U2c6Se0OyI3l distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(65)) + _ = dqByoNgSuCNNKVW1jvrrpBMbogTZ2G32Mtl1ns88U2c6Se0OyI3l + var eilbyb6SsTvkG distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(66)) + _ = eilbyb6SsTvkG + var aqiWNd2h0ebqXWYuCMYoRZOdpi15kQGjEX7S4rY0xceblCGZyFjmJzynrHa86dQRT9cyBQTYetu8Mp92ZkSwI3HdD6Tfuv distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(67)) + _ = aqiWNd2h0ebqXWYuCMYoRZOdpi15kQGjEX7S4rY0xceblCGZyFjmJzynrHa86dQRT9cyBQTYetu8Mp92ZkSwI3HdD6Tfuv + var t70LxjlzZS2MKJk9NaKo7LXgYuOqnCVTquv4UhRMbVY3z distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(68)) + _ = t70LxjlzZS2MKJk9NaKo7LXgYuOqnCVTquv4UhRMbVY3z + var oNhdMH1vNIChcsmWBwhaM distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(69)) + _ = oNhdMH1vNIChcsmWBwhaM + var hzEGhhnRYrI7mGjXnj51FB8Jxqy0Rpl3fxYLk3XGF0BTUYCZGbRldmelbE5csc7GplMminJV4dGAX4O6N03p distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(70)) + _ = hzEGhhnRYrI7mGjXnj51FB8Jxqy0Rpl3fxYLk3XGF0BTUYCZGbRldmelbE5csc7GplMminJV4dGAX4O6N03p + var t5eghclsFuE6CjDCubUJpc14DcmhxPhy distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(71)) + _ = t5eghclsFuE6CjDCubUJpc14DcmhxPhy + var hmTiNkMN3KJVoMdbGecjOzv3bShhuKI5QhIIS62cEzsDWirN1PSygSoaQIZczHnKFKZLGiGZ6YQvBzSGitDGyltQuaI4EEh4CnobOUQ9g distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(72)) + _ = hmTiNkMN3KJVoMdbGecjOzv3bShhuKI5QhIIS62cEzsDWirN1PSygSoaQIZczHnKFKZLGiGZ6YQvBzSGitDGyltQuaI4EEh4CnobOUQ9g + var iXCyDBBJHfbBYbpLCyPfYjcYRehMfJPPCcMiCrrQQhy1fvRnuevlgz0YN3AIhu distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(73)) + _ = iXCyDBBJHfbBYbpLCyPfYjcYRehMfJPPCcMiCrrQQhy1fvRnuevlgz0YN3AIhu + var qYQ8rPoy84TlMSkhJzrStSm5z22vyJ25BPF6JGByWzyJlglMlohLRxls distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(74)) + _ = qYQ8rPoy84TlMSkhJzrStSm5z22vyJ25BPF6JGByWzyJlglMlohLRxls + var zUOc5RkBnUYKK5U3B1CACgrYf4uavpr distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(75)) + _ = zUOc5RkBnUYKK5U3B1CACgrYf4uavpr + var rqSr9elqVrUOXVzYwnxEhEaR048QEo2cn5m1tvf1uyG4grj53R6MRC6XomMZw9AibztCglmgiAAZe5EDkL1AO distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(76)) + _ = rqSr9elqVrUOXVzYwnxEhEaR048QEo2cn5m1tvf1uyG4grj53R6MRC6XomMZw9AibztCglmgiAAZe5EDkL1AO + var a distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(77)) + _ = a + var ddpP8QrFBXM75EHZBxbFDOM distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(78)) + _ = ddpP8QrFBXM75EHZBxbFDOM + var mpHjrXsJUThOqZGyvuClPaOnRU4OKremovq3UxqEVPkw4Zsd80mymZzx8TJBzan1KzXRrmjebKj9pJ distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(79)) + _ = mpHjrXsJUThOqZGyvuClPaOnRU4OKremovq3UxqEVPkw4Zsd80mymZzx8TJBzan1KzXRrmjebKj9pJ + var b4UmPxr40v6HFQr6bG7iY4YKjRuqWAwIA33XYKGpuGZEsJ8reAk9RWKjg0Y7dxA2v6uf6zgHSoehRwYJ1j4jQ distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(80)) + _ = b4UmPxr40v6HFQr6bG7iY4YKjRuqWAwIA33XYKGpuGZEsJ8reAk9RWKjg0Y7dxA2v6uf6zgHSoehRwYJ1j4jQ + var j3hi4BuSA72oSUC9zYnE9kKzFBZvBS7WJOi8raRB3b7xG9BxkfhuXwTMhLQd distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(81)) + _ = j3hi4BuSA72oSUC9zYnE9kKzFBZvBS7WJOi8raRB3b7xG9BxkfhuXwTMhLQd + var gauJumtCTW4D3DKeaTcvTeLkrIddKZnghAuq2hknmysixjmTpQSmSGPoyKwaDLKjGfAF4wMV0JlYOMxGqdNo6GIwt8LRY1omSVXiBA8hNWbkA distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(82)) + _ = gauJumtCTW4D3DKeaTcvTeLkrIddKZnghAuq2hknmysixjmTpQSmSGPoyKwaDLKjGfAF4wMV0JlYOMxGqdNo6GIwt8LRY1omSVXiBA8hNWbkA + var qWNNS2K1xhyu5oyFyGU5kWdP2gK8Z2PA9gJN1hQwSn7zkqYFQ8J8 distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(83)) + _ = qWNNS2K1xhyu5oyFyGU5kWdP2gK8Z2PA9gJN1hQwSn7zkqYFQ8J8 + var mlKKyFJSUsJhVVh3xOMqRAapsOk4IjX9oRlORM7M9J1NeuKlkvsunu48fQHmlau61pRMeBYcUJgozKjWpbkG3dQ distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(84)) + _ = mlKKyFJSUsJhVVh3xOMqRAapsOk4IjX9oRlORM7M9J1NeuKlkvsunu48fQHmlau61pRMeBYcUJgozKjWpbkG3dQ + var kcArELuTjGw0bL9h9XLmLPqW7Teo6le9eYBLzUraYVYvJg0 distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(85)) + _ = kcArELuTjGw0bL9h9XLmLPqW7Teo6le9eYBLzUraYVYvJg0 + var djgwfpKUIraZ7Ix2wm3vMZnGhkqrve07n6P79DEpuFvGSXQ255jNVFYNSynFrWgr3jAjIIT distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(86)) + _ = djgwfpKUIraZ7Ix2wm3vMZnGhkqrve07n6P79DEpuFvGSXQ255jNVFYNSynFrWgr3jAjIIT + var p2s2nyv7cNCYbijxHjEsWoJn01g92V263GLCOuZHFEZyj6aKO7DJypSazbnJ3yiLYNrr3ZQOQdq6pCMNvG84ljHizSvdfqt3s8cxBft9QAeuJMNS6w1UU distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(87)) + _ = p2s2nyv7cNCYbijxHjEsWoJn01g92V263GLCOuZHFEZyj6aKO7DJypSazbnJ3yiLYNrr3ZQOQdq6pCMNvG84ljHizSvdfqt3s8cxBft9QAeuJMNS6w1UU + var jQZqVEZPh14ngahWR6bJ distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(88)) + _ = jQZqVEZPh14ngahWR6bJ + var vU54xC5FxTB6cG1Nag5lsTPaeGIUhhqDShwkO8fHer4iNCwJ7na8 distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(89)) + _ = vU54xC5FxTB6cG1Nag5lsTPaeGIUhhqDShwkO8fHer4iNCwJ7na8 + var gbXqnnPs1dudzBCWUFdVAlN70yKS50OZayTTtMOf30cfYsUJBppwvOEyzetOp9NFzR6H27sPufjk8R distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(90)) + _ = gbXqnnPs1dudzBCWUFdVAlN70yKS50OZayTTtMOf30cfYsUJBppwvOEyzetOp9NFzR6H27sPufjk8R + var pa9fCpVXPR8wRMoPrpentu7s7fs distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(91)) + _ = pa9fCpVXPR8wRMoPrpentu7s7fs + var tNWcHI4ukF8QG5xNRvFm distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(92)) + _ = tNWcHI4ukF8QG5xNRvFm + var dhInHXJhVwccgOdwTXVLGIIljRDyP7eGziKx2DOC2dMNBwVCw6Etdho8SEdV3lNHpBcVWt3zrVB distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(93)) + _ = dhInHXJhVwccgOdwTXVLGIIljRDyP7eGziKx2DOC2dMNBwVCw6Etdho8SEdV3lNHpBcVWt3zrVB + var bHg9fmrcSY1un4rNZHEi4i4IQq5V5Quxcm0QOUlIojlDDJvRX4QN8FBBcxrPBzUME6A1JJsjahpPanCqHP9KxTtZDiLFZAUUrYDguy8M4m3YcwQkO8Yj8 distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(94)) + _ = bHg9fmrcSY1un4rNZHEi4i4IQq5V5Quxcm0QOUlIojlDDJvRX4QN8FBBcxrPBzUME6A1JJsjahpPanCqHP9KxTtZDiLFZAUUrYDguy8M4m3YcwQkO8Yj8 + var sHxuNtsEoXD9ldJSqGWa5J9x414RoC0CERcKyQTobMr2PO3WS2V0WLKHn7YL distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(95)) + _ = sHxuNtsEoXD9ldJSqGWa5J9x414RoC0CERcKyQTobMr2PO3WS2V0WLKHn7YL + var qs7zFQE2EK3XeQjsriWsExAGrC18p0XX6bMbKNFbMgMqP distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(96)) + _ = qs7zFQE2EK3XeQjsriWsExAGrC18p0XX6bMbKNFbMgMqP + var uzR6cdmOMb3oKB332RJmoMAbkJT8W5dBkq83FQif64Zx distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(97)) + _ = uzR6cdmOMb3oKB332RJmoMAbkJT8W5dBkq83FQif64Zx + var wanyIzeRPINssefDuxC6oZSqTXdtlAVQ63f1VOK4KIgEDlnT68IuB5hJS7fyCoc7HkaRKhkaPYv7heY1pxdWZin8jMp distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(98)) + _ = wanyIzeRPINssefDuxC6oZSqTXdtlAVQ63f1VOK4KIgEDlnT68IuB5hJS7fyCoc7HkaRKhkaPYv7heY1pxdWZin8jMp + var bhPhVYyD9iBbZ3SjuZEA7XAnmQGgru2Y8mqSqbhgcf2yZIiqTN3vikA4FZOEU7mAe5SVp0cZH distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(99)) + _ = bhPhVYyD9iBbZ3SjuZEA7XAnmQGgru2Y8mqSqbhgcf2yZIiqTN3vikA4FZOEU7mAe5SVp0cZH + var n4UO2hD40hwjB1i5TQ6NvpSbv99v4ZfeSJLM5ajG5cbUfewjv9Jzse7ssXXf9fbOJmZ5m4Z distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(100)) + _ = n4UO2hD40hwjB1i5TQ6NvpSbv99v4ZfeSJLM5ajG5cbUfewjv9Jzse7ssXXf9fbOJmZ5m4Z + var n38jwcbXgULpJV21mZUYWedX8DxT4x distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(101)) + _ = n38jwcbXgULpJV21mZUYWedX8DxT4x + var e52VdhC9irySRc6baYWJWqctknfa2SocXH6s3WXD68yxyDsthJl3OxCJd8JM9ZumFjsjwOG3Kdy distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(102)) + _ = e52VdhC9irySRc6baYWJWqctknfa2SocXH6s3WXD68yxyDsthJl3OxCJd8JM9ZumFjsjwOG3Kdy + var nllszb9hx7o2DpH9VgtKXbbbConb6qZkVE51FT distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(103)) + _ = nllszb9hx7o2DpH9VgtKXbbbConb6qZkVE51FT + var oyarDkIO1XeNWlRTWPoDsk1rDzx2KhOGK4xnI3CjESXu distsys.TLAValue = args8[1] + _ = oyarDkIO1XeNWlRTWPoDsk1rDzx2KhOGK4xnI3CjESXu + var lAPrrMqrU4ntxPtOdkQigX04o9A1UhGZEbuFmCpVZXsEtPOamE6NNhWjuNSx4u9QGUQi1eGldztPwD9aM6xX3 distsys.TLAValue = args8[2] + _ = lAPrrMqrU4ntxPtOdkQigX04o9A1UhGZEbuFmCpVZXsEtPOamE6NNhWjuNSx4u9QGUQi1eGldztPwD9aM6xX3 + var au1cdpoEAC9qpKhX95muLa7UHtd7Tc5ClX8RPdqrx1VnwB73UWLmobCcRUJ00MykuKUNvxqaBeCpgLJazYJJbWr distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(0)) + _ = au1cdpoEAC9qpKhX95muLa7UHtd7Tc5ClX8RPdqrx1VnwB73UWLmobCcRUJ00MykuKUNvxqaBeCpgLJazYJJbWr + var hzLz47gO3PXjsufbylWIR4mTHq6vCNacxkbhBUoa0nuwsT5E0n5U6PWFkkZirl8ZEixM99Ewdj05HvHwxslZDN8t585781qX3z4hXVOiRp8FFp distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(1)) + _ = hzLz47gO3PXjsufbylWIR4mTHq6vCNacxkbhBUoa0nuwsT5E0n5U6PWFkkZirl8ZEixM99Ewdj05HvHwxslZDN8t585781qX3z4hXVOiRp8FFp + var aU4LYhjGn4d5XsRLPIvK1FIAX8qwM7MFxxS0GcitvGAqZBZLoYBvMXuuBG42WI6pmGhYUiIlr4i24KUBKY5jTmtsWblOCQiDYpqoN9FGwB1RqHEi27 distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(2)) + _ = aU4LYhjGn4d5XsRLPIvK1FIAX8qwM7MFxxS0GcitvGAqZBZLoYBvMXuuBG42WI6pmGhYUiIlr4i24KUBKY5jTmtsWblOCQiDYpqoN9FGwB1RqHEi27 + var uHl2tqdxD22AMbjUnwvSeSNc9Nv9tmlqWYHct9ZAB51iJCSOrr4FTfoAjoxk0y9uqsv distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(3)) + _ = uHl2tqdxD22AMbjUnwvSeSNc9Nv9tmlqWYHct9ZAB51iJCSOrr4FTfoAjoxk0y9uqsv + var oguxOV5fEaapPZjnfKLbtbeZv1eTdeiMpNhIJvQHkSZCLsLXSHoWa4DY2cwSpkVCXRO7qzQNz9f distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(4)) + _ = oguxOV5fEaapPZjnfKLbtbeZv1eTdeiMpNhIJvQHkSZCLsLXSHoWa4DY2cwSpkVCXRO7qzQNz9f + var hbUt0AZXXz6LYtOO distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(5)) + _ = hbUt0AZXXz6LYtOO + var lgSJuN1uQn6SwALwXUaWvaa8Zy9DNKHfl3HuugQfYRp distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(6)) + _ = lgSJuN1uQn6SwALwXUaWvaa8Zy9DNKHfl3HuugQfYRp + var bd303Ubr6ck750RJxkGKLfD0mIyg6lNIErBRyc4gPUKk8QHXPlFz5gEAcDERgyVwPGAb0tfNnIQkLRLK3ZQJYhdIPnAPeCT5b2L distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(7)) + _ = bd303Ubr6ck750RJxkGKLfD0mIyg6lNIErBRyc4gPUKk8QHXPlFz5gEAcDERgyVwPGAb0tfNnIQkLRLK3ZQJYhdIPnAPeCT5b2L + var ex6IHT0FvHtvyWDlLMD2sMcgH2S7HkcG7tRQEwoUhHUqNALJkiy8mT3M4zLKrTYPYtAGp0UpNuHzbt9SvmywcdGad0u109AEuZVMiEDvFdAZ3elZI distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(8)) + _ = ex6IHT0FvHtvyWDlLMD2sMcgH2S7HkcG7tRQEwoUhHUqNALJkiy8mT3M4zLKrTYPYtAGp0UpNuHzbt9SvmywcdGad0u109AEuZVMiEDvFdAZ3elZI + var mpQxvepo9RZldQx6ztwSteOnGnkDpRRYxuUcT22pJpoj2URIhiYoxFhHdMb667D3OlpFad00IUo7YnDZ2ksaKtDSjBxVkWyx9w5yUs0fr distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(9)) + _ = mpQxvepo9RZldQx6ztwSteOnGnkDpRRYxuUcT22pJpoj2URIhiYoxFhHdMb667D3OlpFad00IUo7YnDZ2ksaKtDSjBxVkWyx9w5yUs0fr + var pN0k58Og1pFVER11g9ZjuYo6GM distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(10)) + _ = pN0k58Og1pFVER11g9ZjuYo6GM + var c5Xdkp5vWkWtDWMFi8S2JRBrztq8TuLtRJ7HFYf5c9jKH4kphxkGnf6LjIoSii24syOzTl8Or2WiXQBOsGSqlQzIuodyPW22KBNDNR2IO7u distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(11)) + _ = c5Xdkp5vWkWtDWMFi8S2JRBrztq8TuLtRJ7HFYf5c9jKH4kphxkGnf6LjIoSii24syOzTl8Or2WiXQBOsGSqlQzIuodyPW22KBNDNR2IO7u + var a5q0T6qoZGsD distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(12)) + _ = a5q0T6qoZGsD + var x5agC7yGKNdin6gg9mjdKORWIMAtNVUPA2McZGoND7O0c3bvExJ distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(13)) + _ = x5agC7yGKNdin6gg9mjdKORWIMAtNVUPA2McZGoND7O0c3bvExJ + var qa5L9ldSLlxfhlJUykYTQwrtgjc5e3qNd0iYIzEbJLm1Z4eSpNmWr0OI8oYNJ distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(14)) + _ = qa5L9ldSLlxfhlJUykYTQwrtgjc5e3qNd0iYIzEbJLm1Z4eSpNmWr0OI8oYNJ + var pvNAMZqvzbiLS05Iv1yiNpYlOLbDjkk0pdXHdIP distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(15)) + _ = pvNAMZqvzbiLS05Iv1yiNpYlOLbDjkk0pdXHdIP + var qxbM0ySqkdzWhn6gaROcgBgxFwsaY7adHaF3zhWU3qvyZMiXDYvhlbWBjZSc6nCHr8DLrsWqkB1ZScZHg8LjT4uJqajwOdLZpq4pEzU6a6Gc distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(16)) + _ = qxbM0ySqkdzWhn6gaROcgBgxFwsaY7adHaF3zhWU3qvyZMiXDYvhlbWBjZSc6nCHr8DLrsWqkB1ZScZHg8LjT4uJqajwOdLZpq4pEzU6a6Gc + var jbOiq5HMFD8cif9XiUh6hnhIT8YiZRNR5GZw9OypWmdXVYJepnHvBmXomux8psyO3wxhnQIbsScWDSENdLfGEnqt4FFPG distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(17)) + _ = jbOiq5HMFD8cif9XiUh6hnhIT8YiZRNR5GZw9OypWmdXVYJepnHvBmXomux8psyO3wxhnQIbsScWDSENdLfGEnqt4FFPG + var t9NNl distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(18)) + _ = t9NNl + var fVzrKexwJierBG3hrZ23gwGhpFJayfb9AVRY9yctyCs1v0eevdU0Tf9sr4PWtDNzC0ShzgWJIAnkD7doIj8WWJIJjln54rx8ePxMH distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(19)) + _ = fVzrKexwJierBG3hrZ23gwGhpFJayfb9AVRY9yctyCs1v0eevdU0Tf9sr4PWtDNzC0ShzgWJIAnkD7doIj8WWJIJjln54rx8ePxMH + var rbYYWIdW8cBhrHYa8Sh4a7WZBIVYLMEMbwictyRa2N44lrijZvcB6 distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(20)) + _ = rbYYWIdW8cBhrHYa8Sh4a7WZBIVYLMEMbwictyRa2N44lrijZvcB6 + var szsIaKkIkQks2UP6nNmno2w4LjWVnEbO8g1E0Lftg2JPAvdruTprjbguf2bty distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(21)) + _ = szsIaKkIkQks2UP6nNmno2w4LjWVnEbO8g1E0Lftg2JPAvdruTprjbguf2bty + var nfpgB7M0Rilxy58mrAFWru6fZsVLMuymfeOYonnLiXiYVZnwAlK1ciofegFm5M60pk2v6APjYkVibb1tF0 distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(22)) + _ = nfpgB7M0Rilxy58mrAFWru6fZsVLMuymfeOYonnLiXiYVZnwAlK1ciofegFm5M60pk2v6APjYkVibb1tF0 + var fmfnfeJBnNeOfhWLWmzlliBBK distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(23)) + _ = fmfnfeJBnNeOfhWLWmzlliBBK + var hd00g2nvPGSTW5Mz999GjUaURy2EkwkQ6xvPfWX1W3UNEfmgWOmg3lgpEmVCQi5CzR3asdf9QossCtYY distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(24)) + _ = hd00g2nvPGSTW5Mz999GjUaURy2EkwkQ6xvPfWX1W3UNEfmgWOmg3lgpEmVCQi5CzR3asdf9QossCtYY + var euxA2lDDj2qWZiYTlc1W9QmDMx1g5vx7LxD8h4c8yccTuQb9HAHbgny0QFA88870OURf0URMPbf distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(25)) + _ = euxA2lDDj2qWZiYTlc1W9QmDMx1g5vx7LxD8h4c8yccTuQb9HAHbgny0QFA88870OURf0URMPbf + var xN9TPhSUmZPSl4KWKLpK9QkP6LSFcM9dGokhZrkB32B99q065eQuCNs distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(26)) + _ = xN9TPhSUmZPSl4KWKLpK9QkP6LSFcM9dGokhZrkB32B99q065eQuCNs + var hmNUnDWYdh70I8cTr distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(27)) + _ = hmNUnDWYdh70I8cTr + var oeIqhndp6tenU6QiiB8CUyJSPXjZjQ7Iyg0UKN9OarWDDfdFHKmETPfeVvwvouBxX distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(28)) + _ = oeIqhndp6tenU6QiiB8CUyJSPXjZjQ7Iyg0UKN9OarWDDfdFHKmETPfeVvwvouBxX + var vzc6KpuDfomthXJ2IhgCi distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(29)) + _ = vzc6KpuDfomthXJ2IhgCi + var dWU7d2r0QU74gm7LRVanCRdMemPqnHnO4dI06kxq3sVNkgjp distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(30)) + _ = dWU7d2r0QU74gm7LRVanCRdMemPqnHnO4dI06kxq3sVNkgjp + var b95EGSgn8LhXHgWBXEjm7l2S0lz8uFa2Tz5wEdR4GlXgxiklVgi5pJ7zOxpIRfgrbaPIWGNjjM9e5i7Ddi5sYrUi8iZGlleLgqBEGvYyNCYhD distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(31)) + _ = b95EGSgn8LhXHgWBXEjm7l2S0lz8uFa2Tz5wEdR4GlXgxiklVgi5pJ7zOxpIRfgrbaPIWGNjjM9e5i7Ddi5sYrUi8iZGlleLgqBEGvYyNCYhD + var aoNi5aMtn1gZFOQydE8PHVHEUL16pLenad3darEb4fkWCx7ullptyfy8luXS3RmT3fQu distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(32)) + _ = aoNi5aMtn1gZFOQydE8PHVHEUL16pLenad3darEb4fkWCx7ullptyfy8luXS3RmT3fQu + var pFCOBMSUVeGJ2jEAb0rOPnAC9cJMtkPFuFgef8yyN5sGXeM1BhKXjlvYCBpJYYeGwHbsnK3PSXQn4nlO74xoGSw1Oh distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(33)) + _ = pFCOBMSUVeGJ2jEAb0rOPnAC9cJMtkPFuFgef8yyN5sGXeM1BhKXjlvYCBpJYYeGwHbsnK3PSXQn4nlO74xoGSw1Oh + var cXhaD65hxsJtJPq5qlZElRs96ZAjMkhy9YmiNA2zXg1F9FYTcVccJPRuNhN0VDQcQ9ziyK21RtjEan0MSPAuRX9eZEGau1GSQyo3nJjsllxE distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(34)) + _ = cXhaD65hxsJtJPq5qlZElRs96ZAjMkhy9YmiNA2zXg1F9FYTcVccJPRuNhN0VDQcQ9ziyK21RtjEan0MSPAuRX9eZEGau1GSQyo3nJjsllxE + var bW2468OtxPktGLK4MVXJzYaPqN0OLpxcOkCOsA8X2mL1jfOjgFei7h0ULoVFzxyUV3W5IyY6mvsmTGkjZPQlV15N4Wp613fGA3ZYtbEoH1j2M distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(35)) + _ = bW2468OtxPktGLK4MVXJzYaPqN0OLpxcOkCOsA8X2mL1jfOjgFei7h0ULoVFzxyUV3W5IyY6mvsmTGkjZPQlV15N4Wp613fGA3ZYtbEoH1j2M + var wQVnYM9Z8c4CweQoHvFBVAggPszqqY4XQrgiIt6vstYAaLO6KVlIZY5xBWvI2GRs3YKCuYZ4u6B7k9MIXO4TcvYJh3qYXd324LZT9BRXCcmHMWlh distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(36)) + _ = wQVnYM9Z8c4CweQoHvFBVAggPszqqY4XQrgiIt6vstYAaLO6KVlIZY5xBWvI2GRs3YKCuYZ4u6B7k9MIXO4TcvYJh3qYXd324LZT9BRXCcmHMWlh + var tYV6nVFRhrhf5fAA1M21yImOpdfAqFtobbpJJAUA0AJrAGv90DU7j87Up68NxVL2F2jisMWFfdgBKRzemF9Hl7HEpEXyrpsvp6khqV0NGayJ5QpmpykI distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(37)) + _ = tYV6nVFRhrhf5fAA1M21yImOpdfAqFtobbpJJAUA0AJrAGv90DU7j87Up68NxVL2F2jisMWFfdgBKRzemF9Hl7HEpEXyrpsvp6khqV0NGayJ5QpmpykI + var ruhYsMuvLQfrnoa0mltlCEArVUQXeeKJA26ixaF9QoTfXuwC7ISPYThs8GpoIM5cL0Sy8M9klWTYbZ8SbGyFjM distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(38)) + _ = ruhYsMuvLQfrnoa0mltlCEArVUQXeeKJA26ixaF9QoTfXuwC7ISPYThs8GpoIM5cL0Sy8M9klWTYbZ8SbGyFjM + var x3RlxtzukPGmwZJPSUlaAi distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(39)) + _ = x3RlxtzukPGmwZJPSUlaAi + var oHlbHqPxYDpIj5g distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(40)) + _ = oHlbHqPxYDpIj5g + var hTThjtHRV95wozaOIvq4tthTyiw9kMpSv27JBcvfy8AYIOiOVj83x08xCuq5FSm distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(41)) + _ = hTThjtHRV95wozaOIvq4tthTyiw9kMpSv27JBcvfy8AYIOiOVj83x08xCuq5FSm + var xpb9kfTJuMJbPksb9kT3XvDlzNA16f063WS96oU1SA6UY8I9V21gDGW7ErDpecGIxIqTjKAlRPZJ2b6B5sLfm9iDyjYUA9HAJXzmwnZa2e4Uu distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(42)) + _ = xpb9kfTJuMJbPksb9kT3XvDlzNA16f063WS96oU1SA6UY8I9V21gDGW7ErDpecGIxIqTjKAlRPZJ2b6B5sLfm9iDyjYUA9HAJXzmwnZa2e4Uu + var tqUcmTzXE3Fz7dBRQ9NGCSSle85yvc0bt7fbiKLkEI5iY6iQ0 distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(43)) + _ = tqUcmTzXE3Fz7dBRQ9NGCSSle85yvc0bt7fbiKLkEI5iY6iQ0 + var iO2zm2YrS6dQSq5auWwaMgTUICDYC4QpF7L89l3NI9MNDej4SfAHgbsoN0YbxMGd2nqo2xuWReMIhXU3DWseoO6R distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(44)) + _ = iO2zm2YrS6dQSq5auWwaMgTUICDYC4QpF7L89l3NI9MNDej4SfAHgbsoN0YbxMGd2nqo2xuWReMIhXU3DWseoO6R + var xuOYHgPWe3HahKfxUK1AgvlT0P31iNMf4c1ljBJ27MCl3lcy7POJ2 distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(45)) + _ = xuOYHgPWe3HahKfxUK1AgvlT0P31iNMf4c1ljBJ27MCl3lcy7POJ2 + var mTi4I31HoXGf0jefw3zQmQY01GpYftoHZnDN distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(46)) + _ = mTi4I31HoXGf0jefw3zQmQY01GpYftoHZnDN + var l6n46iVh1ybtF5TgV1N1Tds distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(47)) + _ = l6n46iVh1ybtF5TgV1N1Tds + var gvHMDcRUkO0hrJ9xA29NHUz7DxdxTpWMc3aN8zkFziGh77Zn2EPNulzkvaayt2EAtLBnVHyLMxqxGzkvhI4b4q50EVcN distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(48)) + _ = gvHMDcRUkO0hrJ9xA29NHUz7DxdxTpWMc3aN8zkFziGh77Zn2EPNulzkvaayt2EAtLBnVHyLMxqxGzkvhI4b4q50EVcN + var aRypQCmRaaZJwspACFjZEfGvhNPPmdgKBpxPeZ8w7QnaguWpL distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(49)) + _ = aRypQCmRaaZJwspACFjZEfGvhNPPmdgKBpxPeZ8w7QnaguWpL + var c3 distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(50)) + _ = c3 + var zV5AYeIhWyXMVf7atiSDikFU2ExF1GMMVnyofEuOaHsVTlfAD distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(51)) + _ = zV5AYeIhWyXMVf7atiSDikFU2ExF1GMMVnyofEuOaHsVTlfAD + var coB5hQkxVjx57nec1adAag4F64VJm4SUg6aG5WvGPF1glkmeSCA8H6BiIkDSbrSz7PyDDDjMGItuLXnQASXzDbfj8fXcRd8uWKkoQD distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(52)) + _ = coB5hQkxVjx57nec1adAag4F64VJm4SUg6aG5WvGPF1glkmeSCA8H6BiIkDSbrSz7PyDDDjMGItuLXnQASXzDbfj8fXcRd8uWKkoQD + var oPYzOm2t0FUGe9PmrVWcS7yfQyQNad4sC2SkfPRecH distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(53)) + _ = oPYzOm2t0FUGe9PmrVWcS7yfQyQNad4sC2SkfPRecH + var ssV3KBNB2gZWZJYcmG5HDN1zz8du54zyIRSncFti1rT6jaDzT distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(54)) + _ = ssV3KBNB2gZWZJYcmG5HDN1zz8du54zyIRSncFti1rT6jaDzT + var u6huSF0Ic9nxwLrUuk7M distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(55)) + _ = u6huSF0Ic9nxwLrUuk7M + var zzxYCGcM1GxKfVkCPJTRTFnRpesl6SHRdErcTuXrPbjuzef7OYOkvgN distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(56)) + _ = zzxYCGcM1GxKfVkCPJTRTFnRpesl6SHRdErcTuXrPbjuzef7OYOkvgN + var wArDmuwkH5AI6uMKHTYD2UTkSWvnMed distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(57)) + _ = wArDmuwkH5AI6uMKHTYD2UTkSWvnMed + var oZqiIRaDJ6he5iya2HKw8Z0biC5qyr0TOOrpDP29mTi8OCK6ah9UoN0TpYYrxveSYTzOf0QQr5br7mTOmqDikHfIo7Bb6rDDV distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(58)) + _ = oZqiIRaDJ6he5iya2HKw8Z0biC5qyr0TOOrpDP29mTi8OCK6ah9UoN0TpYYrxveSYTzOf0QQr5br7mTOmqDikHfIo7Bb6rDDV + var fwwceNk1mOejco6Xz85jHol7NovhmD2wy7fZchBoB6KWyQuNYV8n7rqs85GWqPQ9SrGwI distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(59)) + _ = fwwceNk1mOejco6Xz85jHol7NovhmD2wy7fZchBoB6KWyQuNYV8n7rqs85GWqPQ9SrGwI + var g4htEEA2wh2U9wJoiLA5DATskRAbuj6Gb05gM4voIUqN1nOTr68ay8RzNEHuZUGVFnTKa0Nxw9YI9SeoQylB distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(60)) + _ = g4htEEA2wh2U9wJoiLA5DATskRAbuj6Gb05gM4voIUqN1nOTr68ay8RzNEHuZUGVFnTKa0Nxw9YI9SeoQylB + var csAir1tWqElRZGz7r5STeer distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(61)) + _ = csAir1tWqElRZGz7r5STeer + var kBzGPNkjLRYoCtggPUYD1yG2GhP3MO distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(62)) + _ = kBzGPNkjLRYoCtggPUYD1yG2GhP3MO + var pptW9yQU7hmSA9JC8GGDfvwaLWG5I8IYP9PFf2jOY7H7EyEdY1Nlt6E distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(63)) + _ = pptW9yQU7hmSA9JC8GGDfvwaLWG5I8IYP9PFf2jOY7H7EyEdY1Nlt6E + var ynbXCelNrwTY65CpQJIlgq1A2XDtiALVD6TrWR1VlsvUMcPQb5e924lQ3 distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(64)) + _ = ynbXCelNrwTY65CpQJIlgq1A2XDtiALVD6TrWR1VlsvUMcPQb5e924lQ3 + var iEPaaa63QPMjE1NIlGTtN1GqgSR4Hu365kqi6omVfUPMoojXkmiP1YwGAfTHK70V4IQRrfxHf3UZy6jmmeart2irbIIaPgHPZBK distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(65)) + _ = iEPaaa63QPMjE1NIlGTtN1GqgSR4Hu365kqi6omVfUPMoojXkmiP1YwGAfTHK70V4IQRrfxHf3UZy6jmmeart2irbIIaPgHPZBK + var bOZqBs0VirPBezxCopGvk73IvlxVrzHII4YYSK5RZpmY distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(66)) + _ = bOZqBs0VirPBezxCopGvk73IvlxVrzHII4YYSK5RZpmY + var thlGZFI9F7D8alAGPYfelIjpHjP distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(67)) + _ = thlGZFI9F7D8alAGPYfelIjpHjP + var uFVon832WvRB612oHBxrqdG1xJSE7e9oMIK0OPHSbkEWzZSOqCg8WbMpG9ta7iOSaHs1z1cmM03rSqbqUjMjNDpIaA4vO7UcA5UsJFJ6Gn26FaHLYBVlmA distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(68)) + _ = uFVon832WvRB612oHBxrqdG1xJSE7e9oMIK0OPHSbkEWzZSOqCg8WbMpG9ta7iOSaHs1z1cmM03rSqbqUjMjNDpIaA4vO7UcA5UsJFJ6Gn26FaHLYBVlmA + var pL25wa2HlFiZjpUjv00 distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(69)) + _ = pL25wa2HlFiZjpUjv00 + var jxT5r6zS8pIPHkWM1qcSje distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(70)) + _ = jxT5r6zS8pIPHkWM1qcSje + var mz4NalYEJpSDSylMyMWsA4KMiAT6NxI4GqTk8KqhAuBqx4MfDyVEw1j2l9JfB7WDeC9Tt7w2AKXsaTRG15uoaoF3Nsk distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(71)) + _ = mz4NalYEJpSDSylMyMWsA4KMiAT6NxI4GqTk8KqhAuBqx4MfDyVEw1j2l9JfB7WDeC9Tt7w2AKXsaTRG15uoaoF3Nsk + var hhjpozL5792SYbOhatWEA7wbfMHgq07cBpgeq2Uv5cuz8lL4nJ2MmfNosM4dPvO distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(72)) + _ = hhjpozL5792SYbOhatWEA7wbfMHgq07cBpgeq2Uv5cuz8lL4nJ2MmfNosM4dPvO + var tX1XLTTnft460ppN distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(73)) + _ = tX1XLTTnft460ppN + var e distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(74)) + _ = e + var t9aMaFibK1tlkCbGxyUcSIQ8ur2fcdGXCVQlUZ3ByHRtNJMusam5kFGTu distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(75)) + _ = t9aMaFibK1tlkCbGxyUcSIQ8ur2fcdGXCVQlUZ3ByHRtNJMusam5kFGTu + var sHHNQe8qgrlR7B9uRDru3D distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(76)) + _ = sHHNQe8qgrlR7B9uRDru3D + var noBLCLFjLNfYpNVney3NI5ELR9NiCoG1NC95WUgXNql2C3uf3nm3AfjrtRd3EzJCnTMF6CazWMhrT1VEAGa0ZjrkZU9hnKeP distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(77)) + _ = noBLCLFjLNfYpNVney3NI5ELR9NiCoG1NC95WUgXNql2C3uf3nm3AfjrtRd3EzJCnTMF6CazWMhrT1VEAGa0ZjrkZU9hnKeP + var i0yLReUUPcRXM2nHgrFWdb3tu4tbfNF9utSUn5urbOKktRgAIGfisfy9wni3V2QVpDGlrSwDqK73XPOhYZuLEJ distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(78)) + _ = i0yLReUUPcRXM2nHgrFWdb3tu4tbfNF9utSUn5urbOKktRgAIGfisfy9wni3V2QVpDGlrSwDqK73XPOhYZuLEJ + var v7WDS7D0Asy4gggWVjoDCg1TYfKZZ6xPTLV6tbKMhBOhxq5qqoBlDhRQLTcLDYdNlk distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(79)) + _ = v7WDS7D0Asy4gggWVjoDCg1TYfKZZ6xPTLV6tbKMhBOhxq5qqoBlDhRQLTcLDYdNlk + var oR3RvtjYHGIlTqE5iuwri3poF5QMU9uv5oAnF6bp7tafQJyvCC4kOkjTjvil1iPS distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(80)) + _ = oR3RvtjYHGIlTqE5iuwri3poF5QMU9uv5oAnF6bp7tafQJyvCC4kOkjTjvil1iPS + var pHcnP0YYWa0i5MobPSWsGCPZKqMaCQV0sGoRMpXRqdTJgzMoYVYm5yqcTi0H0lFjo0Ny7OzlBWDtBmM7oX distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(81)) + _ = pHcnP0YYWa0i5MobPSWsGCPZKqMaCQV0sGoRMpXRqdTJgzMoYVYm5yqcTi0H0lFjo0Ny7OzlBWDtBmM7oX + var tM6lLFnDkCLrBYxLRIcH9nFLmErv5pxlvFlSWOE4I3zDK5OIWIxs1DOp4JP6i64WwdL6uU5gTgfSIHK0Yty8MsfmOK4k58J8ViVB4yvkh320FGkYDojT distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(82)) + _ = tM6lLFnDkCLrBYxLRIcH9nFLmErv5pxlvFlSWOE4I3zDK5OIWIxs1DOp4JP6i64WwdL6uU5gTgfSIHK0Yty8MsfmOK4k58J8ViVB4yvkh320FGkYDojT + var lP52N22FlaSMD8t5esKZIHHkp5rUgjqwL7DR59zBIF5uUklPD2dhpTRhanQa1Vm8MHQRlrmnXsUn2oAb1mPLQLjeMRYZwy distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(83)) + _ = lP52N22FlaSMD8t5esKZIHHkp5rUgjqwL7DR59zBIF5uUklPD2dhpTRhanQa1Vm8MHQRlrmnXsUn2oAb1mPLQLjeMRYZwy + var xDvXYYCkOwNg57 distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(84)) + _ = xDvXYYCkOwNg57 + var akl5Dks3ctrKj3h7YukzwDX0SLOTZrW distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(85)) + _ = akl5Dks3ctrKj3h7YukzwDX0SLOTZrW + var d4wNzZGpOMK distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(86)) + _ = d4wNzZGpOMK + var ha8qMdi8HkZFnIaCdfkKX7Inj distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(87)) + _ = ha8qMdi8HkZFnIaCdfkKX7Inj + var sN1WU5MRkGQnF9tdlSqVAxs6LmVvtPK7RvwZ2O6CIwFNYCJqipTcqtl3dl2JRw8Y distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(88)) + _ = sN1WU5MRkGQnF9tdlSqVAxs6LmVvtPK7RvwZ2O6CIwFNYCJqipTcqtl3dl2JRw8Y + var hekB4NOymzpTl2en8ijXe2QGIcwTYOaY8IVWGjrOCVj6Gt0mEmA62waj3GEg distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(89)) + _ = hekB4NOymzpTl2en8ijXe2QGIcwTYOaY8IVWGjrOCVj6Gt0mEmA62waj3GEg + var cAfltU1qEbnZT7VGxOO8J4N5EK4gbe0FtHzg37bfquF8RByYx4Wp1z0W8yVtUEMhFmEXYBKFjMDnnmt8ScsdU3iJrxQ distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(90)) + _ = cAfltU1qEbnZT7VGxOO8J4N5EK4gbe0FtHzg37bfquF8RByYx4Wp1z0W8yVtUEMhFmEXYBKFjMDnnmt8ScsdU3iJrxQ + var hY4W2ZRqgGUZ6xKw28xYEC3HEdVpc2eSL2klMfmWD34CujHUvNSTKd2 distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(91)) + _ = hY4W2ZRqgGUZ6xKw28xYEC3HEdVpc2eSL2klMfmWD34CujHUvNSTKd2 + var t6HUBcO1CSZiUjI distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(92)) + _ = t6HUBcO1CSZiUjI + var vw4CkbUUyRtxOdyh2QRI792vnv2XjqooFRcxMiOh4Y5luzfz9c3621vC5whx3hALYBU distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(93)) + _ = vw4CkbUUyRtxOdyh2QRI792vnv2XjqooFRcxMiOh4Y5luzfz9c3621vC5whx3hALYBU + var acwEWlB2MhKTsdnEGevebAQdgPgWIlVkuQO0oCv3pavCT4jFYN9FuR530Id5EQqfjJEtkYvjFf32Ac74jbNdz3PgYnzQw81kd53CmPcgCemsg3yil distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(94)) + _ = acwEWlB2MhKTsdnEGevebAQdgPgWIlVkuQO0oCv3pavCT4jFYN9FuR530Id5EQqfjJEtkYvjFf32Ac74jbNdz3PgYnzQw81kd53CmPcgCemsg3yil + var gzIkXtbo3H7JgHPYIJKdNE58lMdJhIgROEDfur3rnH1Xpqtqtr7xZiwgkX9dMR7hmL4e5UAKKLHX4198TWEICTdjSEFRaGVVuhzMb5qvNF9eE distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(95)) + _ = gzIkXtbo3H7JgHPYIJKdNE58lMdJhIgROEDfur3rnH1Xpqtqtr7xZiwgkX9dMR7hmL4e5UAKKLHX4198TWEICTdjSEFRaGVVuhzMb5qvNF9eE + var jhVt4A4uYHqLSfA0jfJZegQEqo20wgvNOU9IEFjoAtBmVVf5ghevcVqSdCP5alx distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(96)) + _ = jhVt4A4uYHqLSfA0jfJZegQEqo20wgvNOU9IEFjoAtBmVVf5ghevcVqSdCP5alx + var oN4oa21whYFm80wv7FqqllOleE60lWjJQuvuqeZeBaIUeOfnRQD3BsSEC6PJhQEKgZmcA39r5r0hyJl2V distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(97)) + _ = oN4oa21whYFm80wv7FqqllOleE60lWjJQuvuqeZeBaIUeOfnRQD3BsSEC6PJhQEKgZmcA39r5r0hyJl2V + var m distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(98)) + _ = m + var mVuGApmAkeqeaONPjiYXjYwIHpliIoz0ngSmGKsBicgoX4ZNYacxVj distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(99)) + _ = mVuGApmAkeqeaONPjiYXjYwIHpliIoz0ngSmGKsBicgoX4ZNYacxVj + var t1l8xFbevbYDYD7b3msZzmGqC76gb0ciBRtssFZDCDHRytV distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(100)) + _ = t1l8xFbevbYDYD7b3msZzmGqC76gb0ciBRtssFZDCDHRytV + var aKOuhdDAK0wxIER distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(101)) + _ = aKOuhdDAK0wxIER + var fgz19tsiZKI2BwG4G08tVrys9iVigGhAdXkeE distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(102)) + _ = fgz19tsiZKI2BwG4G08tVrys9iVigGhAdXkeE + var u42m6 distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(103)) + _ = u42m6 + var bnJICnFGUBv7h distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(104)) + _ = bnJICnFGUBv7h + var te6GUSAlDbXqoxNqQC6N8F2OOCMQAbJcW2zpzWyKEFyJo3ekpopBWn0TNOcBm7xKrpF3UPXqeff74t8Y6bScZYwqzHWRyS4qE distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(105)) + _ = te6GUSAlDbXqoxNqQC6N8F2OOCMQAbJcW2zpzWyKEFyJo3ekpopBWn0TNOcBm7xKrpF3UPXqeff74t8Y6bScZYwqzHWRyS4qE + var yhxjl4qcuu7hXEyhva4blPVE3QtwsY2r1uhR3lpdO5UAhgqVxbQUhkPGDtbqcb0qip7kEArJP6V95ckFVPmQYMzxcgbFs distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(106)) + _ = yhxjl4qcuu7hXEyhva4blPVE3QtwsY2r1uhR3lpdO5UAhgqVxbQUhkPGDtbqcb0qip7kEArJP6V95ckFVPmQYMzxcgbFs + var pY1D4u6EHqfl970yXrE3DKXnEN9xxtLBuPqVQnl distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(107)) + _ = pY1D4u6EHqfl970yXrE3DKXnEN9xxtLBuPqVQnl + var ekAU4zDRWUqnzAOKcRLmN6tDgXaBtXffZjrc7lqmI82QgSygqhMYjaHGDN8TZ21bIMJzZuPSTEd55MVHCLId5czQGBr distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(108)) + _ = ekAU4zDRWUqnzAOKcRLmN6tDgXaBtXffZjrc7lqmI82QgSygqhMYjaHGDN8TZ21bIMJzZuPSTEd55MVHCLId5czQGBr + var lhHqXinEAJ7m6zgTdg4xjBLTz448zkE3IUwdlz9LCLoqBomJlPU5rE1KKncXigFmHWm6TsGYzqgpcemODayBxJp8UmsyirHrP distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(109)) + _ = lhHqXinEAJ7m6zgTdg4xjBLTz448zkE3IUwdlz9LCLoqBomJlPU5rE1KKncXigFmHWm6TsGYzqgpcemODayBxJp8UmsyirHrP + var sTP979YCAaiYZ0X8hHYXziqQg0fG7ufxcWoQX3PvhZiQJTRrj34T distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(110)) + _ = sTP979YCAaiYZ0X8hHYXziqQg0fG7ufxcWoQX3PvhZiQJTRrj34T + var iVr distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(111)) + _ = iVr + var fGuFtW5imhaTKaFAoHHnoAjGPd3cd distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(112)) + _ = fGuFtW5imhaTKaFAoHHnoAjGPd3cd + var iQAoyH7xQTmTyvutz99yiDkdW17wy0p0UkM9tClnyfCwFVfXyZ8ykSxTJyny6sHOQdSQHtGspLE8w0AbGXnkMjf8Qs9YrtR86vFr8tDcyB distsys.TLAValue = args8[3].ApplyFunction(distsys.NewTLANumber(113)) + _ = iQAoyH7xQTmTyvutz99yiDkdW17wy0p0UkM9tClnyfCwFVfXyZ8ykSxTJyny6sHOQdSQHtGspLE8w0AbGXnkMjf8Qs9YrtR86vFr8tDcyB + var nghbg6dp54IHdkATnyFDqhyD7RkJD3VsvpJ0RvZdxkgbTwxHcyPyNtsoVo3bWvBNhPnfi76ZDX5EYF8tSPhNL distsys.TLAValue = args8[4].ApplyFunction(distsys.NewTLANumber(0)) + _ = nghbg6dp54IHdkATnyFDqhyD7RkJD3VsvpJ0RvZdxkgbTwxHcyPyNtsoVo3bWvBNhPnfi76ZDX5EYF8tSPhNL + var uYElYRh8Us7CWxUYIHrj1Bsv39GpxaB7ZSlyjII5LYSBN3yk distsys.TLAValue = args8[4].ApplyFunction(distsys.NewTLANumber(1)) + _ = uYElYRh8Us7CWxUYIHrj1Bsv39GpxaB7ZSlyjII5LYSBN3yk + var p0J2xoHWWuEMwzXyG4rHW3cggeKWUGxwOd4mfF9HWLPo5RJSD1tpgNOKVnyCCQwxiGpZvx54iJOHwIKPqjDPRLhooUyzX distsys.TLAValue = args8[4].ApplyFunction(distsys.NewTLANumber(2)) + _ = p0J2xoHWWuEMwzXyG4rHW3cggeKWUGxwOd4mfF9HWLPo5RJSD1tpgNOKVnyCCQwxiGpZvx54iJOHwIKPqjDPRLhooUyzX + var rIL3VaKXsqSYTq8wMjaYx9oUSwGAuRio3Jt15eHc distsys.TLAValue = args8[4].ApplyFunction(distsys.NewTLANumber(3)) + _ = rIL3VaKXsqSYTq8wMjaYx9oUSwGAuRio3Jt15eHc + var eLeKq8B2Z8zMAmAdahUhPNJXC16ETOprUXBA5uUJBD distsys.TLAValue = args8[4].ApplyFunction(distsys.NewTLANumber(4)) + _ = eLeKq8B2Z8zMAmAdahUhPNJXC16ETOprUXBA5uUJBD + var maZXYK2ecLSflBdcV8v1ORf57gXHtyTY0E4JtRbR65zvF7eplLC distsys.TLAValue = args8[4].ApplyFunction(distsys.NewTLANumber(5)) + _ = maZXYK2ecLSflBdcV8v1ORf57gXHtyTY0E4JtRbR65zvF7eplLC + var jZ471eWPzrlu0iwqFDduMfnr9874RZ90MSKI6qxTbRdMw1sTkEk1yk0eKQ3iW0PywyQ0 distsys.TLAValue = args8[4].ApplyFunction(distsys.NewTLANumber(6)) + _ = jZ471eWPzrlu0iwqFDduMfnr9874RZ90MSKI6qxTbRdMw1sTkEk1yk0eKQ3iW0PywyQ0 + var cNQBsEl4sxU77NuhXKQQqzyC4aude0OMooGjgmABdhhEHO2s9zOXjoQygLdhGtJOkP8mpfx92fOZuHdDauujOh9A distsys.TLAValue = args8[4].ApplyFunction(distsys.NewTLANumber(7)) + _ = cNQBsEl4sxU77NuhXKQQqzyC4aude0OMooGjgmABdhhEHO2s9zOXjoQygLdhGtJOkP8mpfx92fOZuHdDauujOh9A + var pTlz1MQxM41mkVXq8hVhRGsjXHYZUpFJRmMKhuGhP5Cm5EwJaYWSxWd8GggE6hPheTo9VZr2vR9uNd8PO8 distsys.TLAValue = args8[4].ApplyFunction(distsys.NewTLANumber(8)) + _ = pTlz1MQxM41mkVXq8hVhRGsjXHYZUpFJRmMKhuGhP5Cm5EwJaYWSxWd8GggE6hPheTo9VZr2vR9uNd8PO8 + var opiETaFb5nJEva1Yh9gC4ZdcROtY2kzZp distsys.TLAValue = args8[4].ApplyFunction(distsys.NewTLANumber(9)) + _ = opiETaFb5nJEva1Yh9gC4ZdcROtY2kzZp + var b1 distsys.TLAValue = args8[4].ApplyFunction(distsys.NewTLANumber(10)) + _ = b1 + var jx0S0Lc5eCgFyUjhMEqQLPwxJ9lGatpMKa1tYXgXylcpzDTg1NMZOKNBnz95dluZSZbCgP9VsANj5OJPEb12daTeTDBWr0 distsys.TLAValue = args8[4].ApplyFunction(distsys.NewTLANumber(11)) + _ = jx0S0Lc5eCgFyUjhMEqQLPwxJ9lGatpMKa1tYXgXylcpzDTg1NMZOKNBnz95dluZSZbCgP9VsANj5OJPEb12daTeTDBWr0 + var eRDj66Urr0kHo5IUL07zojWbwmh7yHQuLAdvBMRi7ckUr4R8Dd9x74qw9aMgZ4RY distsys.TLAValue = args8[4].ApplyFunction(distsys.NewTLANumber(12)) + _ = eRDj66Urr0kHo5IUL07zojWbwmh7yHQuLAdvBMRi7ckUr4R8Dd9x74qw9aMgZ4RY + var jHCJuRpvLlP2XWPna4KJXtBUDmBLPBPI distsys.TLAValue = args8[5].ApplyFunction(distsys.NewTLANumber(0)) + _ = jHCJuRpvLlP2XWPna4KJXtBUDmBLPBPI + var sjkow0o6ArFQDmkpwTbgsZG6ygpdxi8akbjEZeHPpnRHHBDrFjUH9sajamY4KI0hnh8Kk6k distsys.TLAValue = args8[5].ApplyFunction(distsys.NewTLANumber(1)) + _ = sjkow0o6ArFQDmkpwTbgsZG6ygpdxi8akbjEZeHPpnRHHBDrFjUH9sajamY4KI0hnh8Kk6k + var rIDP2bqRc3A0xjwpbq13TNCKutRyb2MGl9c8oi3I2GZ8ybNDXI8zyCibj9Z8lTZG1bWMEVLJoyU4a13mYuU9Ho4Nhb1Ld5WB distsys.TLAValue = args8[5].ApplyFunction(distsys.NewTLANumber(2)) + _ = rIDP2bqRc3A0xjwpbq13TNCKutRyb2MGl9c8oi3I2GZ8ybNDXI8zyCibj9Z8lTZG1bWMEVLJoyU4a13mYuU9Ho4Nhb1Ld5WB + var ifzK1T19yxR8Q2OkB8w5TS distsys.TLAValue = args8[5].ApplyFunction(distsys.NewTLANumber(3)) + _ = ifzK1T19yxR8Q2OkB8w5TS + var xfdqXpiAaoeiKF1z1WD5CBPhPZT374WFKWTAf distsys.TLAValue = args8[5].ApplyFunction(distsys.NewTLANumber(4)) + _ = xfdqXpiAaoeiKF1z1WD5CBPhPZT374WFKWTAf + var dEuIljNP2b4VhbQMKlrCL distsys.TLAValue = args8[5].ApplyFunction(distsys.NewTLANumber(5)) + _ = dEuIljNP2b4VhbQMKlrCL + var lGa5ZpUL70V1rZklDRIwA3UoMV7Lpm6Il0lPJDav2SPN4MBds4cXXkJlkhVLWciMup4Kq5aiz4gwVV19aHgT7XCDFTsG3tNOy3wd4Sl distsys.TLAValue = args8[5].ApplyFunction(distsys.NewTLANumber(6)) + _ = lGa5ZpUL70V1rZklDRIwA3UoMV7Lpm6Il0lPJDav2SPN4MBds4cXXkJlkhVLWciMup4Kq5aiz4gwVV19aHgT7XCDFTsG3tNOy3wd4Sl + var l0xNLcyud4OX0CzdQdeSkCfYrzprRjch9IbHun9QZ6pHFRT distsys.TLAValue = args8[5].ApplyFunction(distsys.NewTLANumber(7)) + _ = l0xNLcyud4OX0CzdQdeSkCfYrzprRjch9IbHun9QZ6pHFRT + var sjnc9Z57XD1wlcG0o29WZyY3abg26rZqRS2nQ2LhiKAr1vEejFmzEmHnvFVjDFUm6q distsys.TLAValue = args8[5].ApplyFunction(distsys.NewTLANumber(8)) + _ = sjnc9Z57XD1wlcG0o29WZyY3abg26rZqRS2nQ2LhiKAr1vEejFmzEmHnvFVjDFUm6q + var m7kWa1xpnuL7GChtKEKpvUXwU8X93EAPnzZQKtzshJWzjaF2yfhbrmNF6lrixclpc6ySm5XTKBc92pFj34nCtyYKB3jxFUJOpbq51YKEPM6lz distsys.TLAValue = args8[5].ApplyFunction(distsys.NewTLANumber(9)) + _ = m7kWa1xpnuL7GChtKEKpvUXwU8X93EAPnzZQKtzshJWzjaF2yfhbrmNF6lrixclpc6ySm5XTKBc92pFj34nCtyYKB3jxFUJOpbq51YKEPM6lz + var i0vZZrp0EHBoUP7xCqepbg8Tef0wEjk2XZYqVlZgRE9SRI4rw8AHDolApbenP distsys.TLAValue = args8[5].ApplyFunction(distsys.NewTLANumber(10)) + _ = i0vZZrp0EHBoUP7xCqepbg8Tef0wEjk2XZYqVlZgRE9SRI4rw8AHDolApbenP + var mZRCbbqhph8PV9bp6GWiXIOzMUBagM distsys.TLAValue = args8[5].ApplyFunction(distsys.NewTLANumber(11)) + _ = mZRCbbqhph8PV9bp6GWiXIOzMUBagM + var d35vqopBq91c9r4k4vVn3zN distsys.TLAValue = args8[5].ApplyFunction(distsys.NewTLANumber(12)) + _ = d35vqopBq91c9r4k4vVn3zN + var nsCGq7i4LGAIn9CqSEvJbUaVg6mDAoIBY4ENvkL4tjnkp6QUXe3fDd8oMGSczvoC6U2tsQP7ubGmCNHFOJcfF9HF distsys.TLAValue = args8[5].ApplyFunction(distsys.NewTLANumber(13)) + _ = nsCGq7i4LGAIn9CqSEvJbUaVg6mDAoIBY4ENvkL4tjnkp6QUXe3fDd8oMGSczvoC6U2tsQP7ubGmCNHFOJcfF9HF + var pCby2iPey6XbkoZNW38ml5P96K9z64cRxnsqBUUbh9Yt6rq09u3O8fLlPdLkSi5owlAEfaYOjyeaM2kZsfRwLUIiixCMEYBXv distsys.TLAValue = args8[5].ApplyFunction(distsys.NewTLANumber(14)) + _ = pCby2iPey6XbkoZNW38ml5P96K9z64cRxnsqBUUbh9Yt6rq09u3O8fLlPdLkSi5owlAEfaYOjyeaM2kZsfRwLUIiixCMEYBXv + var eWwzs4iwMxN8g0XVp7y3m62L4KAWyMcJlixJhb2kp07Y61TpGwzCUTr4466jnFC4Fakg12ysTq3vt8L7O3OE1kl8gi7Mjm distsys.TLAValue = args8[5].ApplyFunction(distsys.NewTLANumber(15)) + _ = eWwzs4iwMxN8g0XVp7y3m62L4KAWyMcJlixJhb2kp07Y61TpGwzCUTr4466jnFC4Fakg12ysTq3vt8L7O3OE1kl8gi7Mjm + var uYVxpXjcFvXHEeObGcHL0NhWchmpTzQI05TvoTIwGoxPNozlxZvfW4cd5IAhVpSJKy distsys.TLAValue = args8[5].ApplyFunction(distsys.NewTLANumber(16)) + _ = uYVxpXjcFvXHEeObGcHL0NhWchmpTzQI05TvoTIwGoxPNozlxZvfW4cd5IAhVpSJKy + var pAfpgBx4lPajChoPENrTCbSk9scUZiEp2kDupsoiZdsBcB94rwvfRZOFMA distsys.TLAValue = args8[5].ApplyFunction(distsys.NewTLANumber(17)) + _ = pAfpgBx4lPajChoPENrTCbSk9scUZiEp2kDupsoiZdsBcB94rwvfRZOFMA + var xCo2eUJXSgqC1q2zYnJYZ6KwpLYi7uTKdxDBR941JgQDcXjfeZl distsys.TLAValue = args8[5].ApplyFunction(distsys.NewTLANumber(18)) + _ = xCo2eUJXSgqC1q2zYnJYZ6KwpLYi7uTKdxDBR941JgQDcXjfeZl + var vDL1OiV distsys.TLAValue = args8[5].ApplyFunction(distsys.NewTLANumber(19)) + _ = vDL1OiV + var mbhhmiDsTEHMLWvv93GyovUTmnPoPlIy2s56iHib8Dn9QlqJiWrdmCmkaIXcBsJQwOIm2ThUX4tPOzqeJCxdwmmkVajC9v3T distsys.TLAValue = args8[5].ApplyFunction(distsys.NewTLANumber(20)) + _ = mbhhmiDsTEHMLWvv93GyovUTmnPoPlIy2s56iHib8Dn9QlqJiWrdmCmkaIXcBsJQwOIm2ThUX4tPOzqeJCxdwmmkVajC9v3T + var jFY2R54QeauyHVWpnemZ1CN9G2pILgeY2sxuFxqdBigN9UQCmkjeczbFKkMJSU3Tdq6m011oQW distsys.TLAValue = args8[5].ApplyFunction(distsys.NewTLANumber(21)) + _ = jFY2R54QeauyHVWpnemZ1CN9G2pILgeY2sxuFxqdBigN9UQCmkjeczbFKkMJSU3Tdq6m011oQW + var zoGRR00PrajULFuD72JL8ZgKHO0aJWlJfMtlY distsys.TLAValue = args8[5].ApplyFunction(distsys.NewTLANumber(22)) + _ = zoGRR00PrajULFuD72JL8ZgKHO0aJWlJfMtlY + var yy5du8I9blKTUxSxhPPqufIzKW7OxC9kf59ETSd distsys.TLAValue = args8[5].ApplyFunction(distsys.NewTLANumber(23)) + _ = yy5du8I9blKTUxSxhPPqufIzKW7OxC9kf59ETSd + var s7LwiU06 distsys.TLAValue = args8[5].ApplyFunction(distsys.NewTLANumber(24)) + _ = s7LwiU06 + var dm distsys.TLAValue = args8[5].ApplyFunction(distsys.NewTLANumber(25)) + _ = dm + var q7G7iIUDhARKfIyeRtXTQpySmg8vuzfkhzGEcWAuE32eSQIV5GZKwSLODQTw3p1Iz0vnwltb2gXQmIWk5upw distsys.TLAValue = args8[5].ApplyFunction(distsys.NewTLANumber(26)) + _ = q7G7iIUDhARKfIyeRtXTQpySmg8vuzfkhzGEcWAuE32eSQIV5GZKwSLODQTw3p1Iz0vnwltb2gXQmIWk5upw + var b7woXaQt5UKYKw3M2anyqRJwHpB2Rw8jB1tBiLvDG5bqajEMPhihdYh2KxFkmBNI distsys.TLAValue = args8[5].ApplyFunction(distsys.NewTLANumber(27)) + _ = b7woXaQt5UKYKw3M2anyqRJwHpB2Rw8jB1tBiLvDG5bqajEMPhihdYh2KxFkmBNI + var qGMfQzAU2fN6vCyQs18zRjX1pxjPiLksC distsys.TLAValue = args8[5].ApplyFunction(distsys.NewTLANumber(28)) + _ = qGMfQzAU2fN6vCyQs18zRjX1pxjPiLksC + var udHap4MoGBwMbWe3wfkwHtySrtHxLY7fUmyjYtOczUnO4wn09ksrx distsys.TLAValue = args8[5].ApplyFunction(distsys.NewTLANumber(29)) + _ = udHap4MoGBwMbWe3wfkwHtySrtHxLY7fUmyjYtOczUnO4wn09ksrx + return qxbM0ySqkdzWhn6gaROcgBgxFwsaY7adHaF3zhWU3qvyZMiXDYvhlbWBjZSc6nCHr8DLrsWqkB1ZScZHg8LjT4uJqajwOdLZpq4pEzU6a6Gc + }), distsys.NewTLASet(distsys.NewTLAString("w5:3;Z'1 ../../../../distsys + +require github.com/UBC-NSS/pgo/distsys v0.0.0-00010101000000-000000000000 diff --git a/test/files/general/dqueue.tla b/test/files/general/dqueue.tla index 398c7d38f..952157611 100644 --- a/test/files/general/dqueue.tla +++ b/test/files/general/dqueue.tla @@ -142,11 +142,8 @@ CONSTANTS BUFFER_SIZE, NUM_CONSUMERS, PRODUCER } } \* END PLUSCAL TRANSLATION +*) - - - -***************************************************************************) \* BEGIN TRANSLATION PCal-e64ab9284c1a4c5172f564abb6f099c4 CONSTANT defaultInitValue VARIABLES network, processor, stream, netWrite, netRead, procWrite, netWrite0, diff --git a/test/files/general/dqueue.tla.expectpcal b/test/files/general/dqueue.tla.expectpcal index 0c054da45..6af6e1168 100644 --- a/test/files/general/dqueue.tla.expectpcal +++ b/test/files/general/dqueue.tla.expectpcal @@ -141,11 +141,8 @@ CONSTANTS BUFFER_SIZE, NUM_CONSUMERS, PRODUCER \* END PLUSCAL TRANSLATION +*) - - - -***************************************************************************) \* BEGIN TRANSLATION PCal-e64ab9284c1a4c5172f564abb6f099c4 CONSTANT defaultInitValue VARIABLES network, processor, stream, netWrite, netRead, procWrite, netWrite0, diff --git a/test/files/general/dqueue.tla.gotests/dqueue.go b/test/files/general/dqueue.tla.gotests/dqueue.go index f628eb43d..35f67d33a 100644 --- a/test/files/general/dqueue.tla.gotests/dqueue.go +++ b/test/files/general/dqueue.tla.gotests/dqueue.go @@ -5,6 +5,9 @@ import ( "github.com/UBC-NSS/pgo/distsys" ) +var _ = new(fmt.Stringer) // unconditionally prevent go compiler from reporting unused fmt import +var _ = distsys.TLAValue{} // same, for distsys + type Constants struct { BUFFER_SIZE distsys.TLAValue NUM_CONSUMERS distsys.TLAValue diff --git a/test/files/general/load_balancer.tla.gotests/load_balancer.go b/test/files/general/load_balancer.tla.gotests/load_balancer.go index 8e35bb25f..3c999a68b 100644 --- a/test/files/general/load_balancer.tla.gotests/load_balancer.go +++ b/test/files/general/load_balancer.tla.gotests/load_balancer.go @@ -5,6 +5,9 @@ import ( "github.com/UBC-NSS/pgo/distsys" ) +var _ = new(fmt.Stringer) // unconditionally prevent go compiler from reporting unused fmt import +var _ = distsys.TLAValue{} // same, for distsys + type Constants struct { BUFFER_SIZE distsys.TLAValue LoadBalancerId distsys.TLAValue diff --git a/test/pgo/GoGenFileTests.scala b/test/pgo/GoGenFileTests.scala index 80d4a11bc..44dffda2c 100644 --- a/test/pgo/GoGenFileTests.scala +++ b/test/pgo/GoGenFileTests.scala @@ -1,7 +1,5 @@ package pgo -import scala.util.control.NonFatal - class GoGenFileTests extends FileTestSuite { lazy val goExe: String = sys.env.getOrElse("GO_EXE", "go") diff --git a/test/pgo/TLAExpressionFuzzTests.scala b/test/pgo/TLAExpressionFuzzTests.scala index 2d9d13740..635aefafa 100644 --- a/test/pgo/TLAExpressionFuzzTests.scala +++ b/test/pgo/TLAExpressionFuzzTests.scala @@ -1,6 +1,6 @@ package pgo -import org.scalacheck.{Arbitrary, Gen, Prop} +import org.scalacheck.Gen import org.scalatest.funsuite.AnyFunSuite import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks import pgo.model.Definition.ScopeIdentifierName @@ -19,7 +19,7 @@ class TLAExpressionFuzzTests extends AnyFunSuite with ScalaCheckPropertyChecks { implicit override val generatorDrivenConfig: PropertyCheckConfiguration = PropertyCheckConfiguration(workers = 1, minSuccessful = 100, maxDiscardedFactor = 10) - test("TLA+ compiled to Go code behaves like the built-in interpreter (true random ASTs)") { + test("TLA+ expr eval (true random ASTs)") { val workDir = os.temp.dir() val testFile = workDir / "TestBed.tla" val outFile = workDir / "testbed.go" @@ -90,59 +90,57 @@ class TLAExpressionFuzzTests extends AnyFunSuite with ScalaCheckPropertyChecks { } whenever(!shouldSkip) { cases += 1 - Prop.classify(expectedBehaviour match { - case Left(_) => degenerateCases += 1; true - case Right(_) => false - }, "degenerate", "correct") { - os.write.over(testFile, data = mpcalSetup.linesIterator.map(line => s"$line\n")) - - def somethingBadHappened(): Unit = { - os.makeDir.all(os.pwd / "fuzz_output") - val testOut = os.temp.dir(dir = os.pwd / "fuzz_output", deleteOnExit = false) - println(s"something bad happened. saving test to $testOut") - os.copy.over(from = workDir, to = testOut) - } + expectedBehaviour match { + case Left(_) => degenerateCases += 1 + case Right(_) => + } + os.remove.all(outFile) + os.write.over(testFile, data = mpcalSetup.linesIterator.map(line => s"$line\n")) + + def somethingBadHappened(): Unit = { + os.makeDir.all(os.pwd / "fuzz_output") + val testOut = os.temp.dir(dir = os.pwd / "fuzz_output", deleteOnExit = false) + println(s"something bad happened. saving test to $testOut") + os.copy.over(from = workDir, to = testOut) + } - try { - val errs = PGo.run(Seq("gogen", "-s", testFile.toString(), "-o", outFile.toString())) - assert(errs == Nil) - } catch { - case NonFatal(err) => - somethingBadHappened() - throw err - } + try { + val errs = PGo.run(Seq("gogen", "-s", testFile.toString(), "-o", outFile.toString())) + assert(errs == Nil) + } catch { + case NonFatal(err) => + somethingBadHappened() + throw err + } - os.proc("go", "mod", "download").call(cwd = workDir) + os.proc("go", "mod", "download").call(cwd = workDir) - try { - val result = os.proc("go", "run", "./main").call(cwd = workDir, mergeErrIntoOut = true, timeout = 30000) - val valueFromGo = TLAValue.parseFromString(result.out.text()) + try { + val result = os.proc("go", "run", "./main").call(cwd = workDir, mergeErrIntoOut = true, timeout = 30000) + val valueFromGo = TLAValue.parseFromString(result.out.text()) + expectedBehaviour match { + case Left(err) => + fail(s"expected an error, because Scala-based interpreter threw one", err) + case Right(valueFromScala) => + assert(valueFromGo == valueFromScala) + } + } catch { + case err: os.SubprocessException => expectedBehaviour match { - case Left(err) => - fail(s"expected an error, because Scala-based interpreter threw one", err) - case Right(valueFromScala) => - assert(valueFromGo == valueFromScala) - } - Prop.passed - } catch { - case err: os.SubprocessException => - expectedBehaviour match { - case Left(_) => - if (err.result.out.text().startsWith("panic: TLA+ type error")) { - // that's ok then - Prop.passed - } else { - somethingBadHappened() - throw err - } - case Right(_) => + case Left(_) => + if (err.result.out.text().startsWith("panic: TLA+ type error")) { + // that's ok then + } else { somethingBadHappened() throw err - } - case NonFatal(err) => - somethingBadHappened() - throw err - } + } + case Right(_) => + somethingBadHappened() + throw err + } + case NonFatal(err) => + somethingBadHappened() + throw err } } } @@ -277,7 +275,7 @@ class TLAExpressionFuzzTests extends AnyFunSuite with ScalaCheckPropertyChecks { def genNamedASTOptions(breadth: Int, makeExpr: (IdSet[DefinitionOne],Option[TLAFunctionSubstitutionPairAnchor])=>Gen[TLAExpression])(implicit env: IdSet[DefinitionOne], anchorOpt: Option[TLAFunctionSubstitutionPairAnchor]): List[Gen[TLAExpression]] = { val options = mutable.ListBuffer[Gen[TLAExpression]]() - lazy val genQuantifierBound: Gen[TLAQuantifierBound] = for { + def genQuantifierBound(implicit env: IdSet[DefinitionOne], anchorOpt: Option[TLAFunctionSubstitutionPairAnchor]): Gen[TLAQuantifierBound] = for { tpe <- Gen.oneOf(TLAQuantifierBound.IdsType, TLAQuantifierBound.TupleType) ids <- tpe match { case TLAQuantifierBound.IdsType => Gen.identifier.map(id => List(TLAIdentifier(id).toDefiningIdentifier)) From df91ea8c70695b321dbb32ba89fffd741788fdd6 Mon Sep 17 00:00:00 2001 From: fhackett Date: Wed, 14 Jul 2021 05:50:18 -0700 Subject: [PATCH 16/27] add fuzz testing for EXCEPT expression; fix related bugs --- distsys/tlaplus.go | 32 ++++++++++++++++++++++---- src/pgo/model/tla/AST.scala | 8 +++++-- src/pgo/parser/TLAParser.scala | 12 ++++++---- src/pgo/trans/MPCalGoCodegenPass.scala | 20 ++++++++++++++-- src/pgo/trans/PCalRenderPass.scala | 2 +- src/pgo/util/TLAExprInterpreter.scala | 1 + test/pgo/TLAExpressionFuzzTests.scala | 28 +++++++++++++++++++--- 7 files changed, 87 insertions(+), 16 deletions(-) diff --git a/distsys/tlaplus.go b/distsys/tlaplus.go index bd58507b1..aa9a35315 100644 --- a/distsys/tlaplus.go +++ b/distsys/tlaplus.go @@ -120,10 +120,10 @@ func (v TLAValue) AsTuple() *immutable.List { } } -func (v TLAValue) AsFunction() *tlaValueFunction { +func (v TLAValue) AsFunction() *immutable.Map { switch data := v.data.(type) { case *tlaValueFunction: - return data + return data.Map default: panic(fmt.Errorf("%w: %v is not a function", TLATypeError, v)) } @@ -136,7 +136,7 @@ func (v TLAValue) SelectElement() TLAValue { key, _ := it.Next() return key.(TLAValue) } else { - panic(fmt.Errorf("tried to select an element of %v, which was an empty set", v)) + panic(fmt.Errorf("%w: tried to select an element of %v, which was an empty set", TLATypeError, v)) } } @@ -147,7 +147,7 @@ func (v TLAValue) ApplyFunction(argument TLAValue) TLAValue { case *tlaValueFunction: value, ok := data.Get(argument) if !ok { - panic(fmt.Errorf("function %v's domain does not contain index %v", v, argument)) + panic(fmt.Errorf("%w: function %v's domain does not contain index %v", TLATypeError, v, argument)) } return value.(TLAValue) default: @@ -1029,6 +1029,30 @@ func (v *tlaValueFunction) GobDecode(input []byte) error { } } +type TLAFunctionSubstitutionRecord struct { + Keys []TLAValue + Value func(anchor TLAValue) TLAValue +} + +func TLAFunctionSubstitution(source TLAValue, substitutions []TLAFunctionSubstitutionRecord) TLAValue { + var keysHelper func(source TLAValue, keys []TLAValue, value func(anchor TLAValue) TLAValue) TLAValue + keysHelper = func(source TLAValue, keys []TLAValue, value func(anchor TLAValue) TLAValue) TLAValue { + if len(keys) == 0 { + return value(source) + } else { + sourceFn := source.AsFunction() + val, keyOk := sourceFn.Get(keys[0]) + require(keyOk, "invalid key during function substitution") + sourceFn = sourceFn.Set(keys[0], keysHelper(val.(TLAValue), keys[1:], value)) + return TLAValue{&tlaValueFunction{sourceFn}} + } + } + for _, substitution := range substitutions { + source = keysHelper(source, substitution.Keys, substitution.Value) + } + return source +} + func TLA_DomainSymbol(v TLAValue) TLAValue { fn := v.AsFunction() builder := immutable.NewMapBuilder(TLAValueHasher{}) diff --git a/src/pgo/model/tla/AST.scala b/src/pgo/model/tla/AST.scala index 4dafd6f84..2552aa9fe 100644 --- a/src/pgo/model/tla/AST.scala +++ b/src/pgo/model/tla/AST.scala @@ -400,9 +400,13 @@ final case class TLAFunctionSet(from: TLAExpression, to: TLAExpression) extends final case class TLAFunctionSubstitution(source: TLAExpression, substitutions: List[TLAFunctionSubstitutionPair]) extends TLAExpression -final case class TLAFunctionSubstitutionPair(anchor: TLAFunctionSubstitutionPairAnchor, keys: List[TLAFunctionSubstitutionKey], value: TLAExpression) extends TLANode +final case class TLAFunctionSubstitutionPair(anchor: TLAFunctionSubstitutionPairAnchor, keys: List[TLAFunctionSubstitutionKey], value: TLAExpression) extends TLANode { + require(keys.nonEmpty) +} -final case class TLAFunctionSubstitutionKey(indices: List[TLAExpression]) extends TLANode +final case class TLAFunctionSubstitutionKey(indices: List[TLAExpression]) extends TLANode { + require(indices.nonEmpty) +} final case class TLAFunctionSubstitutionPairAnchor() extends TLANode with RefersTo.HasReferences diff --git a/src/pgo/parser/TLAParser.scala b/src/pgo/parser/TLAParser.scala index adbed6148..c205849cf 100644 --- a/src/pgo/parser/TLAParser.scala +++ b/src/pgo/parser/TLAParser.scala @@ -3,8 +3,8 @@ package pgo.parser import pgo.model.{Definition, DefinitionOne, SourceLocatable, SourceLocation, SourceLocationWithUnderlying, Visitable} import pgo.model.tla._ import pgo.util.Description -import Description._ import pgo.model.Definition.ScopeIdentifierName +import pgo.util.Description.DescriptionHelper import scala.collection.mutable import scala.util.parsing.combinator.RegexParsers @@ -147,9 +147,10 @@ trait TLAParser extends RegexParsers { failure(s"lookup failed for identifier ${pfx.map(_.id.id).mkString("!")}!${id.id}") case Some(defn) => if (defn.arity == 0) { - wsChk ~> "!" ^^^ PrefixPart(TLAGeneralIdentifierPart(id, Nil), defn) + // the extra negation is to avoid matching parts of an EXCEPT expression, where an id might be followed by ! + wsChk ~> "!" ~> not(wsChk ~> "[" ~> tlaWhitespace) ^^^ PrefixPart(TLAGeneralIdentifierPart(id, Nil), defn) } else { - wsChk ~> "(" ~> wsChk ~> tlaComma1Sep(tlaExpression) <~ wsChk <~ ")" <~ wsChk <~ "!" ^^ { args => + wsChk ~> "(" ~> wsChk ~> tlaComma1Sep(tlaExpression) <~ wsChk <~ ")" <~ wsChk <~ "!" <~ not(wsChk ~> "[" ~> tlaWhitespace) ^^ { args => PrefixPart(TLAGeneralIdentifierPart(id, args), defn) } } @@ -159,9 +160,11 @@ trait TLAParser extends RegexParsers { case PrefixPart(idPart, defn) => if(!defn.isModuleInstance) { throw KindMismatchError(idPart.sourceLocation, d"expected module instance, found operator or variable") + //failure(s"kind mismatch: expected module instance, found operator or variable `${defn.identifier.asInstanceOf[ScopeIdentifierName].name.id}`") } if(idPart.parameters.length != defn.arity) { throw ArityMismatchError(idPart.sourceLocation, defn, idPart.parameters.length) + //failure(s"arity mismatch: definition has arity ${defn.arity}, mismatched with ${idPart.parameters.length}") } val path = pfx :+ idPart opt(wsChk ~> impl(path)) ^^ (_.getOrElse(path)) @@ -185,7 +188,7 @@ trait TLAParser extends RegexParsers { def tlaOperatorCallOrGeneralIdentifier(implicit ctx: TLAParserContext): Parser[TLAExpression] = withSourceLocation { - (tlaInstancePrefix ~ (wsChk ~> tlaIdentifierExpr)).flatMap { + (tlaInstancePrefix ~ (not(wsChk ~> "[") ~> wsChk ~> tlaIdentifierExpr)).flatMap { case pfx ~ id => val name = Definition.ScopeIdentifierName(id) ctx.lookupDefinition(pfx.map(id => Definition.ScopeIdentifierName(id.id)) :+ name) match { @@ -355,6 +358,7 @@ trait TLAParser extends RegexParsers { }) }.flatMap { path => val anchor = TLAFunctionSubstitutionPairAnchor() // definition for the @ expression + .setSourceLocation(path.view.map(_.sourceLocation).reduce(_ ++ _)) implicit val ctx: TLAParserContext = origCtx.withFunctionSubstitutionPairAnchor(anchor) (wsChk ~> "=" ~> wsChk ~> tlaExpression) ^^ { value => TLAFunctionSubstitutionPair(anchor, path, value) diff --git a/src/pgo/trans/MPCalGoCodegenPass.scala b/src/pgo/trans/MPCalGoCodegenPass.scala index 547e1232d..3f4f00c31 100644 --- a/src/pgo/trans/MPCalGoCodegenPass.scala +++ b/src/pgo/trans/MPCalGoCodegenPass.scala @@ -24,7 +24,7 @@ object MPCalGoCodegenPass { |chan else goto package switch |const fallthrough if range type |continue for import return var - |""".stripMargin.split(' ').view.filter(_.nonEmpty).toList + |""".stripMargin.split(Array(' ', '\n')).view.filter(_.nonEmpty).toList sealed abstract class Binding { val bind: String @@ -601,7 +601,23 @@ object MPCalGoCodegenPass { })""" case TLAFunctionSet(from, to) => d"distsys.NewTLAFunctionSet(${translateExpr(from)}, ${translateExpr(to)})" - case TLAFunctionSubstitution(source, substitutions) => ??? + case TLAFunctionSubstitution(source, substitutions) => + d"distsys.TLAFunctionSubstitution(${translateExpr(source)}, []distsys.TLAFunctionSubstitutionRecord{${ + substitutions.view.map { + case TLAFunctionSubstitutionPair(anchor, keys, value) => + ctx.cleanName("anchor") { anchorName => + d"\n{[]$TLAValue{${ + keys.view.map { + case TLAFunctionSubstitutionKey(List(index)) => translateExpr(index) + case TLAFunctionSubstitutionKey(indices) => + d"distsys.NewTLATuple(${indices.view.map(translateExpr).separateBy(d", ")})" + }.separateBy(d", ") + }}, func($anchorName $TLAValue) $TLAValue {${ + d"return ${translateExpr(value)(ctx = ctx.copy(bindings = ctx.bindings.updated(anchor, FixedValueBinding(anchorName))))}" + }\n}}," + } + }.flattenDescriptions.indented + }\n})" case at@TLAFunctionSubstitutionAt() => val FixedValueBinding(name) = ctx.bindings(at.refersTo) name.toDescription diff --git a/src/pgo/trans/PCalRenderPass.scala b/src/pgo/trans/PCalRenderPass.scala index 4cb6f0d91..cd87f6149 100644 --- a/src/pgo/trans/PCalRenderPass.scala +++ b/src/pgo/trans/PCalRenderPass.scala @@ -121,7 +121,7 @@ object PCalRenderPass { d"[${indices.view.map(describeExpr).separateBy(d", ")}]" }.flattenDescriptions } = ${describeExpr(value)}" - }.separateBy(d" ") + }.separateBy(d", ") }]" case TLAFunctionSubstitutionAt() => d"@" case TLAQuantifiedExistential(bounds, body) => diff --git a/src/pgo/util/TLAExprInterpreter.scala b/src/pgo/util/TLAExprInterpreter.scala index d68c2db87..88a465ee7 100644 --- a/src/pgo/util/TLAExprInterpreter.scala +++ b/src/pgo/util/TLAExprInterpreter.scala @@ -369,6 +369,7 @@ object TLAExprInterpreter { } origValue match { case TLAValueFunction(origFn) => + require(origFn.contains(indexValue)) TLAValueFunction(origFn.updated(indexValue, subKeys(restKeys, origFn(indexValue)))) } } diff --git a/test/pgo/TLAExpressionFuzzTests.scala b/test/pgo/TLAExpressionFuzzTests.scala index 635aefafa..aa31882dc 100644 --- a/test/pgo/TLAExpressionFuzzTests.scala +++ b/test/pgo/TLAExpressionFuzzTests.scala @@ -13,6 +13,7 @@ import pgo.util.{IdSet, TLAExprInterpreter} import scala.annotation.tailrec import scala.collection.mutable +import scala.math import scala.util.control.NonFatal class TLAExpressionFuzzTests extends AnyFunSuite with ScalaCheckPropertyChecks { @@ -116,7 +117,7 @@ class TLAExpressionFuzzTests extends AnyFunSuite with ScalaCheckPropertyChecks { os.proc("go", "mod", "download").call(cwd = workDir) try { - val result = os.proc("go", "run", "./main").call(cwd = workDir, mergeErrIntoOut = true, timeout = 30000) + val result = os.proc("go", "run", "./main").call(cwd = workDir, mergeErrIntoOut = true, timeout = 60000) val valueFromGo = TLAValue.parseFromString(result.out.text()) expectedBehaviour match { case Left(err) => @@ -235,7 +236,7 @@ class TLAExpressionFuzzTests extends AnyFunSuite with ScalaCheckPropertyChecks { { case List(from: TLAExpression, to: TLAExpression) => Gen.const(TLAFunctionSet(from, to)) }, - // TODO: skipping function substitution because complicated + // skipping function substitution; requires scoping { case Nil if anchorOpt.nonEmpty => Gen.const(TLAFunctionSubstitutionAt() .setRefersTo(anchorOpt.get)) @@ -287,7 +288,7 @@ class TLAExpressionFuzzTests extends AnyFunSuite with ScalaCheckPropertyChecks { if(breadth >= 2) { def impl(count: Int, acc: List[TLAUnit])(implicit env: IdSet[DefinitionOne], anchorOpt: Option[TLAFunctionSubstitutionPairAnchor]): Gen[TLAExpression] = { assert(count >= 1) - if(count == 1) { + if (count == 1) { makeExpr(env, anchorOpt).map { body => TLALet(acc.reverse, body) } @@ -309,7 +310,28 @@ class TLAExpressionFuzzTests extends AnyFunSuite with ScalaCheckPropertyChecks { qbs <- Gen.listOfN(breadth - 1, genQuantifierBound) body <- makeExpr(env ++ qbs.view.flatMap(_.singleDefinitions), anchorOpt) } yield TLAFunction(qbs, body)) + } + + if(breadth >= 3) { + // some of these might end up being quite "wide", but it's simpler than trying to accurately + // count sub-expressions + val genSubstitutionPair: Gen[TLAFunctionSubstitutionPair] = for { + anchor <- Gen.delay(Gen.const(TLAFunctionSubstitutionPairAnchor())) + keyCount <- Gen.chooseNum(1, (breadth - 1) / 2) + keys <- Gen.listOfN(keyCount, for { + indexCount <- Gen.chooseNum(1, math.max(((breadth - 1) / 2) / keyCount, 0)) + indices <- Gen.listOfN(indexCount, makeExpr(env, anchorOpt)) + } yield TLAFunctionSubstitutionKey(indices)) + value <- makeExpr(env, Some(anchor)) + } yield TLAFunctionSubstitutionPair(anchor, keys, value) + + options += (for { + source <- makeExpr(env, anchorOpt) + pairs <- Gen.listOfN((breadth - 1) / 2, genSubstitutionPair) + } yield TLAFunctionSubstitution(source, pairs)) + } + if(breadth >= 2) { options += (for { constructor <- Gen.oneOf(TLAQuantifiedExistential, TLAQuantifiedUniversal) bounds <- Gen.listOfN(breadth - 1, genQuantifierBound) From 032de5e2befd826a7d2658274ccc0d8c5d007378 Mon Sep 17 00:00:00 2001 From: fhackett Date: Thu, 15 Jul 2021 06:52:11 -0700 Subject: [PATCH 17/27] add a couple of explanatory comments --- src/pgo/trans/MPCalGoCodegenPass.scala | 52 ++++++++++++++------------ 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/src/pgo/trans/MPCalGoCodegenPass.scala b/src/pgo/trans/MPCalGoCodegenPass.scala index 3f4f00c31..fa3cb81ad 100644 --- a/src/pgo/trans/MPCalGoCodegenPass.scala +++ b/src/pgo/trans/MPCalGoCodegenPass.scala @@ -70,6 +70,18 @@ object MPCalGoCodegenPass { label.name -> s"${ctx.nameCleaner.cleanName(label.name)}LabelTag" } ++ List("Done" -> "DoneLabelTag")).toMap + /** + * Ensures that any archetype resource reads embedded within expr are lifted out and performed ahead of time. + * Pure expressions will be unaffected. + * + * e.g: + * `print x + 1` + * becomes something like + * ` + * tmp := ctx.Read(...) + * (tmp + 1).PCalPrint() + * ` + */ def readExpr(expr: TLAExpression, hint: String = "resourceRead")(fn: Description=>Description)(implicit ctx: GoCodegenContext): Description = { val resourceReads = mutable.ListBuffer[(DefinitionOne,PCalVariableDeclarationEmpty,List[TLAExpression])]() lazy val readReplacer: PartialFunction[Rewritable,Rewritable] = { @@ -124,6 +136,14 @@ object MPCalGoCodegenPass { } } + /** + * The plural of readExpr. + * + * @param exprs multiple expressions to read + * @param fn the "body", mapping from a list of bound expression values to a sequence of Go statements + * @param ctx the context + * @return the entire sequence of (1) perform expression reads and bindings (2) insert the result of fn(...) + */ def readExprs(exprs: List[(TLAExpression,String)])(fn: List[Description]=>Description)(implicit ctx: GoCodegenContext): Description = { def impl(exprs: List[(TLAExpression,String)], acc: mutable.ListBuffer[Description]): Description = exprs match { @@ -425,32 +445,16 @@ object MPCalGoCodegenPass { case id -> name => id -> FixedValueBinding(name) }) bindingInfos.view.map(_._2).flattenDescriptions + body(innerCtx) - - /*val boundIds = bounds.view.flatMap { - case TLAQuantifierBound(TLAQuantifierBound.IdsType, List(id), _) => - Some(id -> ctx.nameCleaner.cleanName(id.id.id)) - case TLAQuantifierBound(TLAQuantifierBound.TupleType, elements, _) => - elements.view.map(id => id -> ctx.nameCleaner.cleanName(id.id.id)) - }.to(IdMap) - val innerCtx: GoCodegenContext = ctx.copy(bindings = ctx.bindings ++ boundIds.map { - case id -> name => id -> FixedValueBinding(name) - }) - - bounds.view.zipWithIndex.flatMap { - case (TLAQuantifierBound(TLAQuantifierBound.IdsType, List(id), _), idx) => - List { - d"\nvar ${boundIds(id)} $TLAValue = $setsTupleName[$idx]" + - d"\n_ = ${boundIds(id)}" // stop the Go compiler from catching unused vars - } - case (TLAQuantifierBound(TLAQuantifierBound.TupleType, elements, _), idx) => - elements.view.zipWithIndex.map { - case (element, elemIdx) => - d"\nvar ${boundIds(element)} $TLAValue = $setsTupleName[$idx].ApplyFunction(distsys.NewTLANumber($elemIdx))" + - d"\n_ = ${boundIds(element)}" - } - }.flattenDescriptions + body(innerCtx)*/ } + /** + * Given ctx, translates the expression into Go code. + * + * The output type is Description, which can be thought of as a lazy String which is optimized for + * concatenation, embedding, and other generative operations. + * + * Note: this function relies on readExpr, defined above, for the handling of archetype resource reads. + */ def translateExpr(expression: TLAExpression)(implicit ctx: GoCodegenContext): Description = expression match { case TLAString(value) => From 876d0041a81a90c379d35c5456f0bbc87e3726b5 Mon Sep 17 00:00:00 2001 From: fhackett Date: Thu, 15 Jul 2021 07:05:42 -0700 Subject: [PATCH 18/27] Remove test reliance on empty paths that do not end up in the git repo. --- test/pgo/GoGenFileTests.scala | 8 ++++---- test/pgo/PCalGenFileTests.scala | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/test/pgo/GoGenFileTests.scala b/test/pgo/GoGenFileTests.scala index 44dffda2c..af37d7e23 100644 --- a/test/pgo/GoGenFileTests.scala +++ b/test/pgo/GoGenFileTests.scala @@ -3,10 +3,10 @@ package pgo class GoGenFileTests extends FileTestSuite { lazy val goExe: String = sys.env.getOrElse("GO_EXE", "go") - override val testFiles: List[os.Path] = (os.list.stream(os.pwd / "test" / "files" / "gogen") ++ - os.list.stream(os.pwd / "test" / "files" / "general")) - .filter(_.last.endsWith(".tla")) - .toList + override val testFiles: List[os.Path] = + os.list.stream(os.pwd / "test" / "files" / "general") + .filter(_.last.endsWith(".tla")) + .toList testFiles.foreach { testFile => test(s"gogen ${testFile.relativeTo(os.pwd)}") { diff --git a/test/pgo/PCalGenFileTests.scala b/test/pgo/PCalGenFileTests.scala index 60993870e..3d4006688 100644 --- a/test/pgo/PCalGenFileTests.scala +++ b/test/pgo/PCalGenFileTests.scala @@ -5,10 +5,10 @@ import com.github.difflib.{DiffUtils, UnifiedDiffUtils} import scala.jdk.CollectionConverters._ class PCalGenFileTests extends FileTestSuite { - override val testFiles: List[os.Path] = (os.list.stream(os.pwd / "test" / "files" / "pcalgen") ++ - os.list.stream(os.pwd / "test" / "files" / "general")) - .filter(_.last.endsWith(".tla")) - .toList + override val testFiles: List[os.Path] = + os.list.stream(os.pwd / "test" / "files" / "general") + .filter(_.last.endsWith(".tla")) + .toList testFiles.foreach { testFile => test(s"pcalgen ${testFile.relativeTo(os.pwd)}") { From a138d0eb7f387d2f0d2af49b78c8d966900db776 Mon Sep 17 00:00:00 2001 From: fhackett Date: Sat, 17 Jul 2021 15:24:11 -0700 Subject: [PATCH 19/27] Add multiple mapping macro error; make minor Go style changes. --- distsys/archetypes.go | 119 +++++++----------- distsys/mpcal.go | 2 +- src/pgo/trans/MPCalGoCodegenPass.scala | 6 +- src/pgo/trans/MPCalSemanticCheckPass.scala | 20 +++ src/pgo/util/Description.scala | 3 +- test/files/general/MappingMacroRules.tla | 59 +++++++++ .../general/dqueue.tla.gotests/dqueue.go | 4 +- .../load_balancer.go | 8 +- 8 files changed, 134 insertions(+), 87 deletions(-) create mode 100644 test/files/general/MappingMacroRules.tla diff --git a/distsys/archetypes.go b/distsys/archetypes.go index 9d8b13d6f..ce4331a9f 100644 --- a/distsys/archetypes.go +++ b/distsys/archetypes.go @@ -7,18 +7,15 @@ import ( "errors" "fmt" "github.com/benbjohnson/immutable" - "io" "log" "net" "sync" "time" ) -var CriticalSectionAborted = errors.New("MPCal critical section aborted") +var ErrCriticalSectionAborted = errors.New("MPCal critical section aborted") type ArchetypeResource interface { - gob.GobDecoder - gob.GobEncoder Abort() chan struct{} PreCommit() chan error Commit() chan struct{} @@ -29,22 +26,22 @@ type ArchetypeResource interface { type ArchetypeResourceLeafMixin struct{} -var ArchetypeResourceLeafIndexedError = errors.New("internal error: attempted to index a leaf archetype resource") +var ErrArchetypeResourceLeafIndexed = errors.New("internal error: attempted to index a leaf archetype resource") func (ArchetypeResourceLeafMixin) Index(TLAValue) (ArchetypeResource, error) { - return nil, ArchetypeResourceLeafIndexedError + return nil, ErrArchetypeResourceLeafIndexed } type ArchetypeResourceMapMixin struct{} -var ArchetypeResourceMapReadWriteError = errors.New("internal error: attempted to read/write a map archetype resource") +var ErrArchetypeResourceMapReadWrite = errors.New("internal error: attempted to read/write a map archetype resource") func (ArchetypeResourceMapMixin) ReadValue() (TLAValue, error) { - return TLAValue{}, ArchetypeResourceMapReadWriteError + return TLAValue{}, ErrArchetypeResourceMapReadWrite } func (ArchetypeResourceMapMixin) WriteValue(TLAValue) error { - return ArchetypeResourceMapReadWriteError + return ErrArchetypeResourceMapReadWrite } //////////////////////////////////////////////// @@ -170,7 +167,7 @@ func (res *InputChannelResource) ReadValue() (TLAValue, error) { res.buffer = append(res.buffer, value) return value, nil case <-time.After(time.Millisecond * 20): - return TLAValue{}, CriticalSectionAborted + return TLAValue{}, ErrCriticalSectionAborted } } @@ -178,14 +175,6 @@ func (res *InputChannelResource) WriteValue(value TLAValue) error { panic(fmt.Errorf("attempted to write %v to an input channel resource", value)) } -func (res *InputChannelResource) GobDecode(input []byte) error { - panic("implement me") -} - -func (res *InputChannelResource) GobEncode() ([]byte, error) { - panic("implement me") -} - // Output channel resource: a write-only resource backed by an externally-readable Go channel // ------------------------------------------------------------------------------------------ @@ -234,14 +223,6 @@ func (res *OutputChannelResource) WriteValue(value TLAValue) error { return nil } -func (res *OutputChannelResource) GobDecode(i []byte) error { - panic("implement me") -} - -func (res *OutputChannelResource) GobEncode() ([]byte, error) { - panic("implement me") -} - // A generic map resource, with hooks to programmatically and serializably realize child resources during execution // ---------------------------------------------------------------------------------------------------------------- @@ -372,42 +353,6 @@ func (res *IncrementalArchetypeMapResource) Abort() chan struct{} { return outCh } -func (res *IncrementalArchetypeMapResource) GobDecode(input []byte) error { - buf := bytes.NewBuffer(input) - decoder := gob.NewDecoder(buf) - builder := immutable.NewMapBuilder(TLAValueHasher{}) - for { - var record incrementalArchetypeMapResourceRecord - err := decoder.Decode(&record) - if err != nil { - if errors.Is(err, io.EOF) { - res.realizedMap = builder.Map() - return nil - } else { - return err - } - } - builder.Set(record.Key, record.Value) - } -} - -func (res *IncrementalArchetypeMapResource) GobEncode() ([]byte, error) { - var buf bytes.Buffer - encoder := gob.NewEncoder(&buf) - it := res.realizedMap.Iterator() - for !it.Done() { - key, value := it.Next() - err := encoder.Encode(incrementalArchetypeMapResourceRecord{ - Key: key.(TLAValue), - Value: value.(ArchetypeResource), - }) - if err != nil { - return nil, err - } - } - return buf.Bytes(), nil -} - // Global State as Archetype Resource // ---------------------------------- @@ -636,7 +581,7 @@ func (res *TCPMailboxLocalArchetypeResource) ReadValue() (TLAValue, error) { res.readsInProgress = append(res.readsInProgress, poppedValue) return poppedValue, nil case <-time.After(20 * time.Millisecond): - return TLAValue{}, CriticalSectionAborted + return TLAValue{}, ErrCriticalSectionAborted } } @@ -644,14 +589,6 @@ func (res *TCPMailboxLocalArchetypeResource) WriteValue(value TLAValue) error { panic(fmt.Errorf("attempted to write value %v to a local mailbox archetype resource", value)) } -func (res *TCPMailboxLocalArchetypeResource) GobDecode(i []byte) error { - panic("implement me") -} - -func (res *TCPMailboxLocalArchetypeResource) GobEncode() ([]byte, error) { - panic("implement me") -} - type TCPMailboxRemoteArchetypeResource struct { ArchetypeResourceLeafMixin dialAddr string @@ -676,7 +613,7 @@ func (res *TCPMailboxRemoteArchetypeResource) ensureConnection() error { if err != nil { log.Printf("failed to dial %s, aborting after 50ms: %v", res.dialAddr, err) time.Sleep(time.Millisecond * 50) - return CriticalSectionAborted + return ErrCriticalSectionAborted } res.connEncoder = gob.NewEncoder(res.conn) res.connDecoder = gob.NewDecoder(res.conn) @@ -710,7 +647,7 @@ func (res *TCPMailboxRemoteArchetypeResource) PreCommit() chan error { handleError: log.Printf("network error while performing pre-commit handshake, aborting: %v", err) res.conn = nil - ch <- CriticalSectionAborted + ch <- ErrCriticalSectionAborted }() return ch } @@ -790,13 +727,43 @@ func (res *TCPMailboxRemoteArchetypeResource) WriteValue(value TLAValue) error { handleError: log.Printf("network error during remote value write, aborting: %v", err) res.conn = nil - return CriticalSectionAborted + return ErrCriticalSectionAborted +} + +// Filesystem archetype resource +// ----------------------------- + +type FilesystemArchetypeResource struct { + ArchetypeResourceLeafMixin + workingDirectory string + writesPending map[string]TLAValue +} + +var _ ArchetypeResource = &FilesystemArchetypeResource{} + +func NewFilesystemArchetypeResource(ensurer MPCalContextResourceEnsurer, workingDirectory string) ArchetypeResourceHandle { + return ensurer(&FilesystemArchetypeResource{}, func(resource ArchetypeResource) { + res := resource.(*FilesystemArchetypeResource) + _ = res + }) +} + +func (res *FilesystemArchetypeResource) Abort() chan struct{} { + panic("implement me") +} + +func (res *FilesystemArchetypeResource) PreCommit() chan error { + panic("implement me") +} + +func (res *FilesystemArchetypeResource) Commit() chan struct{} { + panic("implement me") } -func (res *TCPMailboxRemoteArchetypeResource) GobDecode(i []byte) error { +func (res *FilesystemArchetypeResource) ReadValue() (TLAValue, error) { panic("implement me") } -func (res *TCPMailboxRemoteArchetypeResource) GobEncode() ([]byte, error) { +func (res *FilesystemArchetypeResource) WriteValue(value TLAValue) error { panic("implement me") } diff --git a/distsys/mpcal.go b/distsys/mpcal.go index aa2d17bda..2f04a1116 100644 --- a/distsys/mpcal.go +++ b/distsys/mpcal.go @@ -5,7 +5,7 @@ import ( "fmt" ) -var AssertionFailed = errors.New("assertion failed") +var ErrAssertionFailed = errors.New("assertion failed") type ArchetypeResourceHandle struct { Tag int diff --git a/src/pgo/trans/MPCalGoCodegenPass.scala b/src/pgo/trans/MPCalGoCodegenPass.scala index fa3cb81ad..de4b76b4f 100644 --- a/src/pgo/trans/MPCalGoCodegenPass.scala +++ b/src/pgo/trans/MPCalGoCodegenPass.scala @@ -213,7 +213,7 @@ object MPCalGoCodegenPass { d"\nif !$condition.AsBool() {${ (d"""\n${ctx.err} = fmt.Errorf("%w: ${ escapeStringToGo(PCalRenderPass.describeExpr(conditionExpr).linesIterator.mkString("\n")) - }", distsys.AssertionFailed)""" + + }", distsys.ErrAssertionFailed)""" + d"\ncontinue").indented }\n}" } @@ -249,7 +249,7 @@ object MPCalGoCodegenPass { case PCalAwait(condition) => readExpr(condition, hint = "condition") { condition => d"\nif !$condition.AsBool() {${ - (d"\n${ctx.err} = distsys.CriticalSectionAborted" + + (d"\n${ctx.err} = distsys.ErrCriticalSectionAborted" + d"\ncontinue").indented }\n}" } @@ -377,7 +377,7 @@ object MPCalGoCodegenPass { d"\n" + d"\nfor {${ (d"\nif $err != nil {${ - (d"\nif $err == distsys.CriticalSectionAborted {${ + (d"\nif $err == distsys.ErrCriticalSectionAborted {${ (d"\nctx.Abort()" + d"\n$err = nil").indented }\n} else {${ diff --git a/src/pgo/trans/MPCalSemanticCheckPass.scala b/src/pgo/trans/MPCalSemanticCheckPass.scala index 5f8166896..efc7cf074 100644 --- a/src/pgo/trans/MPCalSemanticCheckPass.scala +++ b/src/pgo/trans/MPCalSemanticCheckPass.scala @@ -46,6 +46,11 @@ object MPCalSemanticCheckPass { usage.sourceLocation, d"call arity at ${ defn.sourceLocation.longDescription }\n does not match") + + final case class MPCalMultipleMapping(firstMapping: SourceLocatable, secondMapping: SourceLocatable) extends Error( + secondMapping.sourceLocation, d"instance parameter mapped at ${ + firstMapping.sourceLocation.longDescription + }\n is mapped again") } @throws[PGoError] @@ -416,6 +421,21 @@ object MPCalSemanticCheckPass { } } + // check that mapping macros are not many-to-one + // i.e that the same instance parameter is not mapped more than one way + block.visit(Visitable.TopDownFirstStrategy) { + case MPCalInstance(_, _, _, _, mappings) => + val visitedPositions = mutable.HashMap[Int,MPCalMapping]() + mappings.foreach { + case mapping@MPCalMapping(target, _) => + if(!visitedPositions.contains(target.position)) { + visitedPositions.update(target.position, mapping) + } else { + errors += SemanticError.MPCalMultipleMapping(visitedPositions(target.position), mapping) + } + } + } + if(errors.nonEmpty) { throw SemanticError(errors.result()) } diff --git a/src/pgo/util/Description.scala b/src/pgo/util/Description.scala index e02210a82..3f078084a 100644 --- a/src/pgo/util/Description.scala +++ b/src/pgo/util/Description.scala @@ -1,5 +1,6 @@ package pgo.util +import pgo.util.Unreachable.!!! import scala.collection.{AbstractIterator, View, mutable} private sealed abstract class DescriptionPart @@ -65,7 +66,7 @@ final class Description private (private val parts: View[DescriptionPart]) exten (0 until indent).foreach(_ => lineBuilder += ' ') } lineBuilder.addAll(str) - case DescriptionEmbedPart(_) => ??? // should be unreachable + case DescriptionEmbedPart(_) => !!! // should be unreachable } } // lineBuilder.nonEmpty ==> make sure to output trailing strings without a new line following them diff --git a/test/files/general/MappingMacroRules.tla b/test/files/general/MappingMacroRules.tla new file mode 100644 index 000000000..1494f0a8a --- /dev/null +++ b/test/files/general/MappingMacroRules.tla @@ -0,0 +1,59 @@ +---- MODULE MappingMacroRules ---- +EXTENDS Sequences, FiniteSets, Integers + +CONSTANTS NODE_SET, SERVER_SET + +(* +--mpcal MappingMacroRules { +mapping macro TCPChannel { + read { + await Len($variable.queue) > 0 /\ $variable.enabled; + with (msg = Head($variable.queue)) { + $variable.queue := Tail($variable.queue); + yield msg; + }; + } + + write { + await Len($variable.queue) < BUFFER_SIZE /\ $variable.enabled; + yield [queue |-> Append($variable.queue, $value), enabled |-> $variable.enabled]; + } +} + +mapping macro NetworkToggle { + read { + yield $variable.enabled; + } + + write { + yield [queue |-> $variable.queue, enabled |-> $value]; + } +} + +archetype AServer(ref net[_], ref netToggle[_]) { + lbl: skip; +} + +variables + network = [id \in NODE_SET |-> [queue |-> <<>>, enabled |-> TRUE]]; + +fair process (Server \in SERVER_SET) == instance AServer(ref network[_], ref network[_]) + mapping network[_] via TCPChannel + (*:: expectedError: MPCalMultipleMapping *) mapping network[_] via NetworkToggle; + +fair process (Server2 \in SERVER_SET) == instance AServer(ref network[_], ref network[_]) + mapping @1[_] via TCPChannel + (*:: expectedError: MPCalMultipleMapping *) mapping @1[_] via NetworkToggle; + +fair process (Server3 \in SERVER_SET) == instance AServer(ref network[_], ref network[_]) + mapping @2[_] via TCPChannel + (*:: expectedError: MPCalMultipleMapping *) mapping @2[_] via NetworkToggle; + +fair process (Server3 \in SERVER_SET) == instance AServer(ref network[_], ref network[_]) + mapping @1[_] via TCPChannel + mapping @2[_] via NetworkToggle; +} +*) + +\* BEGIN TRANSLATION +==== \ No newline at end of file diff --git a/test/files/general/dqueue.tla.gotests/dqueue.go b/test/files/general/dqueue.tla.gotests/dqueue.go index 35f67d33a..ea8833304 100644 --- a/test/files/general/dqueue.tla.gotests/dqueue.go +++ b/test/files/general/dqueue.tla.gotests/dqueue.go @@ -31,7 +31,7 @@ func AConsumer(ctx *distsys.MPCalContext, self distsys.TLAValue, constants Const for { if err != nil { - if err == distsys.CriticalSectionAborted { + if err == distsys.ErrCriticalSectionAborted { ctx.Abort() err = nil } else { @@ -117,7 +117,7 @@ func AProducer(ctx *distsys.MPCalContext, self distsys.TLAValue, constants Const for { if err0 != nil { - if err0 == distsys.CriticalSectionAborted { + if err0 == distsys.ErrCriticalSectionAborted { ctx.Abort() err0 = nil } else { diff --git a/test/files/general/load_balancer.tla.gotests/load_balancer.go b/test/files/general/load_balancer.tla.gotests/load_balancer.go index 3c999a68b..c67f01732 100644 --- a/test/files/general/load_balancer.tla.gotests/load_balancer.go +++ b/test/files/general/load_balancer.tla.gotests/load_balancer.go @@ -38,7 +38,7 @@ func ALoadBalancer(ctx *distsys.MPCalContext, self distsys.TLAValue, constants C for { if err != nil { - if err == distsys.CriticalSectionAborted { + if err == distsys.ErrCriticalSectionAborted { ctx.Abort() err = nil } else { @@ -87,7 +87,7 @@ func ALoadBalancer(ctx *distsys.MPCalContext, self distsys.TLAValue, constants C continue } if !distsys.TLA_EqualsSymbol(condition.ApplyFunction(distsys.NewTLAString("message_type")), constants.GET_PAGE).AsBool() { - err = fmt.Errorf("%w: ((msg).message_type) = (GET_PAGE)", distsys.AssertionFailed) + err = fmt.Errorf("%w: ((msg).message_type) = (GET_PAGE)", distsys.ErrAssertionFailed) continue } err = ctx.Write(programCounter, []distsys.TLAValue{}, distsys.NewTLANumber(sendServerLabelTag)) @@ -166,7 +166,7 @@ func AServer(ctx *distsys.MPCalContext, self distsys.TLAValue, constants Constan for { if err0 != nil { - if err0 == distsys.CriticalSectionAborted { + if err0 == distsys.ErrCriticalSectionAborted { ctx.Abort() err0 = nil } else { @@ -269,7 +269,7 @@ func AClient(ctx *distsys.MPCalContext, self distsys.TLAValue, constants Constan for { if err1 != nil { - if err1 == distsys.CriticalSectionAborted { + if err1 == distsys.ErrCriticalSectionAborted { ctx.Abort() err1 = nil } else { From 2ce5330dcf355b9bc0c76f64d26e45b26cc5cf87 Mon Sep 17 00:00:00 2001 From: fhackett Date: Fri, 23 Jul 2021 11:26:00 -0700 Subject: [PATCH 20/27] Comment and clean up Go lib; add load_balancer test --- distsys/archetype_resource.go | 116 + distsys/archetype_resources/channels.go | 113 + distsys/archetype_resources/filesystem.go | 85 + .../archetype_resources/incremental_map.go | 124 + distsys/archetype_resources/tcp_mailboxes.go | 331 +++ distsys/archetypes.go | 769 ------- distsys/barrier.go | 169 -- distsys/client.go | 135 -- distsys/connections.go | 120 - distsys/data_store.go | 105 - distsys/data_store_test.go | 123 - distsys/distsys.go | 612 ----- distsys/distsys_test.go | 325 --- distsys/etcd.go | 189 -- distsys/go.mod | 8 +- distsys/go.sum | 196 -- distsys/mpcal.go | 231 -- distsys/mpcal_context.go | 217 ++ distsys/processutil.go | 25 - distsys/processutil_test.go | 23 - distsys/state_ownership.go | 219 -- distsys/state_ownership_test.go | 164 -- distsys/state_server.go | 57 - distsys/tlaplus.go | 83 +- src/pgo/model/Rewritable.scala | 5 + src/pgo/trans/MPCalGoCodegenPass.scala | 88 +- .../general/ExprTests.tla.gotests/go.sum | 2 + .../general/dqueue.tla.gotests/dqueue.go | 35 +- .../general/dqueue.tla.gotests/dqueue_test.go | 48 +- test/files/general/dqueue.tla.gotests/go.sum | 2 + .../general/load_balancer.tla.gotests/go.sum | 2 + .../load_balancer.go | 67 +- .../load_balancer_test.go | 133 +- .../general/replicated_kv.tla.gotests/go.mod | 7 + .../general/replicated_kv.tla.gotests/go.sum | 2 + .../replicated_kv.go | 2048 +++++++++++++++++ .../replicated_kv_test.go | 7 + test/pgo/TLAExpressionFuzzTests.scala | 18 +- 38 files changed, 3416 insertions(+), 3587 deletions(-) create mode 100644 distsys/archetype_resource.go create mode 100644 distsys/archetype_resources/channels.go create mode 100644 distsys/archetype_resources/filesystem.go create mode 100644 distsys/archetype_resources/incremental_map.go create mode 100644 distsys/archetype_resources/tcp_mailboxes.go delete mode 100644 distsys/archetypes.go delete mode 100644 distsys/barrier.go delete mode 100644 distsys/client.go delete mode 100644 distsys/connections.go delete mode 100644 distsys/data_store.go delete mode 100644 distsys/data_store_test.go delete mode 100644 distsys/distsys.go delete mode 100644 distsys/distsys_test.go delete mode 100644 distsys/etcd.go delete mode 100644 distsys/mpcal.go create mode 100644 distsys/mpcal_context.go delete mode 100644 distsys/processutil.go delete mode 100644 distsys/processutil_test.go delete mode 100644 distsys/state_ownership.go delete mode 100644 distsys/state_ownership_test.go delete mode 100644 distsys/state_server.go create mode 100644 test/files/general/ExprTests.tla.gotests/go.sum create mode 100644 test/files/general/dqueue.tla.gotests/go.sum create mode 100644 test/files/general/load_balancer.tla.gotests/go.sum create mode 100644 test/files/general/replicated_kv.tla.gotests/go.mod create mode 100644 test/files/general/replicated_kv.tla.gotests/go.sum create mode 100644 test/files/general/replicated_kv.tla.gotests/replicated_kv.go create mode 100644 test/files/general/replicated_kv.tla.gotests/replicated_kv_test.go diff --git a/distsys/archetype_resource.go b/distsys/archetype_resource.go new file mode 100644 index 000000000..a65151e0b --- /dev/null +++ b/distsys/archetype_resource.go @@ -0,0 +1,116 @@ +package distsys + +import ( + "errors" +) + +// ArchetypeResource represents an interface between an MPCal model and some external environment. +// Such a resource should be instantiated under the control of MPCalContext.EnsureArchetypeResourceByName or +// MPCalContext.EnsureArchetypeResourceByPosition. Typically, the former would be clearer. +// Many implementations are available under ./archetype_resources. +// This API describes what is expected of those implementations, and any others. +type ArchetypeResource interface { + // Abort will be called when the resource should be reset to a state similar to the last Commit. + // May return nil. If it doesn't return nil, the channel should notify one time, when the operation is complete. + // If it returns nil, the operation is considered complete immediately. + Abort() chan struct{} + // PreCommit will be called after any number of ReadValue, WriteValue, or Index operations. + // It signals if it is reasonable to go ahead with a Commit. + // If the resource might need to back out, it should do it here. + // May return nil. If it doesn't return nil, the channel should yield one error value. If the error is nil, + // Commit may go ahead. Otherwise, it may not. + // Returning nil is considered a short-cut to immediately yielding a nil error. + PreCommit() chan error + // Commit will be called if no sibling PreCommit calls raised any errors. + // It must unconditionally commit current resource state. By necessity, this is the only resource operation that + // may block indefinitely. + // May return nil. If it doesn't return nil, the channel should notify once the commit is complete. + // Returning nil is considered as an immediately successful commit. + Commit() chan struct{} + // ReadValue must return the resource's current value. + // If the resource is not ready, ErrCriticalSectionAborted may be returned alongside a default TLAValue. + // This operation should not block indefinitely. + // This makes no sense for a map-like resource, and should be blocked off with ArchetypeResourceMapMixin in that case. + ReadValue() (TLAValue, error) + // WriteValue must update the resource's current value. + // It follows the same conventions as ReadValue. + WriteValue(value TLAValue) error + // Index must return the resource's sub-resource at the given index. + // It's unclear when this would be needed, but, if the resource is not ready, then this operation may return + // ErrCriticalSectionAborted. + // This makes no sense for a value-like resource, and should be blocked off with ArchetypeResourceLeafMixin in that case. + Index(index TLAValue) (ArchetypeResource, error) +} + +type ArchetypeResourceLeafMixin struct{} + +var ErrArchetypeResourceLeafIndexed = errors.New("internal error: attempted to index a leaf archetype resource") + +func (ArchetypeResourceLeafMixin) Index(TLAValue) (ArchetypeResource, error) { + return nil, ErrArchetypeResourceLeafIndexed +} + +type ArchetypeResourceMapMixin struct{} + +var ErrArchetypeResourceMapReadWrite = errors.New("internal error: attempted to read/write a map archetype resource") + +func (ArchetypeResourceMapMixin) ReadValue() (TLAValue, error) { + return TLAValue{}, ErrArchetypeResourceMapReadWrite +} + +func (ArchetypeResourceMapMixin) WriteValue(TLAValue) error { + return ErrArchetypeResourceMapReadWrite +} + +// A bare-bones resource: just holds and buffers a TLAValue +// -------------------------------------------------------- + +type LocalArchetypeResource struct { + ArchetypeResourceLeafMixin + hasOldValue bool // if true, this resource has already been written in this critical section + // if this resource is already written in this critical section, oldValue contains prev value + // value always contains the "current" value + value, oldValue TLAValue +} + +var _ ArchetypeResource = &LocalArchetypeResource{} + +func LocalArchetypeResourceMaker(value TLAValue) ArchetypeResourceMaker { + return ArchetypeResourceMakerFn(func() ArchetypeResource { + return &LocalArchetypeResource{ + value: value, + } + }) +} + +func (res *LocalArchetypeResource) Abort() chan struct{} { + if res.hasOldValue { + res.value = res.oldValue + res.hasOldValue = false + res.oldValue = TLAValue{} + } + return nil +} + +func (res *LocalArchetypeResource) PreCommit() chan error { + return nil +} + +func (res *LocalArchetypeResource) Commit() chan struct{} { + res.hasOldValue = false + res.oldValue = TLAValue{} + return nil +} + +func (res *LocalArchetypeResource) ReadValue() (TLAValue, error) { + return res.value, nil +} + +func (res *LocalArchetypeResource) WriteValue(value TLAValue) error { + if !res.hasOldValue { + res.oldValue = res.value + res.hasOldValue = true + } + res.value = value + return nil +} diff --git a/distsys/archetype_resources/channels.go b/distsys/archetype_resources/channels.go new file mode 100644 index 000000000..4c3a8c9a4 --- /dev/null +++ b/distsys/archetype_resources/channels.go @@ -0,0 +1,113 @@ +package archetype_resources + +import ( + "fmt" + "github.com/UBC-NSS/pgo/distsys" + "time" +) + +// InputChannelResource wraps a native Go channel, such that an MPCal model might read what is written +// to the channel. +type InputChannelResource struct { + distsys.ArchetypeResourceLeafMixin + channel <-chan distsys.TLAValue + buffer []distsys.TLAValue +} + +var _ distsys.ArchetypeResource = &InputChannelResource{} + +func InputChannelResourceMaker(channel <-chan distsys.TLAValue) distsys.ArchetypeResourceMaker { + return distsys.ArchetypeResourceMakerStruct{ + MakeFn: func() distsys.ArchetypeResource { + return &InputChannelResource{} + }, + ConfigureFn: func(res distsys.ArchetypeResource) { + r := res.(*InputChannelResource) + r.channel = channel + }, + } +} + +func (res *InputChannelResource) Abort() chan struct{} { + return nil +} + +func (res *InputChannelResource) PreCommit() chan error { + return nil +} + +func (res *InputChannelResource) Commit() chan struct{} { + res.buffer = nil + return nil +} + +func (res *InputChannelResource) ReadValue() (distsys.TLAValue, error) { + if len(res.buffer) > 0 { + value := res.buffer[0] + res.buffer = res.buffer[1:] + return value, nil + } + + select { + case value := <-res.channel: + res.buffer = append(res.buffer, value) + return value, nil + case <-time.After(time.Millisecond * 20): + return distsys.TLAValue{}, distsys.ErrCriticalSectionAborted + } +} + +func (res *InputChannelResource) WriteValue(value distsys.TLAValue) error { + panic(fmt.Errorf("attempted to write %v to an input channel resource", value)) +} + +// OutputChannelResource wraps a native Go channel, such that an MPCal model may write to that channel. +type OutputChannelResource struct { + distsys.ArchetypeResourceLeafMixin + channel chan<- distsys.TLAValue + buffer []distsys.TLAValue +} + +var _ distsys.ArchetypeResource = &OutputChannelResource{} + +func OutputChannelResourceMaker(channel chan<- distsys.TLAValue) distsys.ArchetypeResourceMaker { + return distsys.ArchetypeResourceMakerStruct{ + MakeFn: func() distsys.ArchetypeResource { + return &OutputChannelResource{} + }, + ConfigureFn: func(res distsys.ArchetypeResource) { + r := res.(*OutputChannelResource) + r.channel = channel + }, + } +} + +func (res *OutputChannelResource) Abort() chan struct{} { + res.buffer = nil + return nil +} + +func (res *OutputChannelResource) PreCommit() chan error { + return nil +} + +func (res *OutputChannelResource) Commit() chan struct{} { + ch := make(chan struct{}) + go func() { + for _, value := range res.buffer { + res.channel <- value + } + res.buffer = nil + ch <- struct{}{} + }() + return ch +} + +func (res *OutputChannelResource) ReadValue() (distsys.TLAValue, error) { + panic(fmt.Errorf("attempted to read from an input channel resource")) +} + +func (res *OutputChannelResource) WriteValue(value distsys.TLAValue) error { + res.buffer = append(res.buffer, value) + return nil +} diff --git a/distsys/archetype_resources/filesystem.go b/distsys/archetype_resources/filesystem.go new file mode 100644 index 000000000..a5fd38508 --- /dev/null +++ b/distsys/archetype_resources/filesystem.go @@ -0,0 +1,85 @@ +package archetype_resources + +import ( + "fmt" + "github.com/UBC-NSS/pgo/distsys" + "io/ioutil" + "path" +) + +// FilesystemArchetypeResourceMaker produces a distsys.ArchetypeResourceMaker for a filesystem-backed +// map-like resource. Each element of the map will refer to a file, with keys and values being required +// to be string-typed, and keys being required to refer to valid paths (or create-able paths, if a +// key is written to before it is read). +func FilesystemArchetypeResourceMaker(workingDirectory string) distsys.ArchetypeResourceMaker { + return IncrementalArchetypeMapResourceMaker(func(index distsys.TLAValue) distsys.ArchetypeResourceMaker { + return distsys.ArchetypeResourceMakerFn(func() distsys.ArchetypeResource { + return &fileArchetypeResource{ + workingDirectory: workingDirectory, + subPath: index.AsString(), + } + }) + }) +} + +type fileArchetypeResource struct { + distsys.ArchetypeResourceLeafMixin + + workingDirectory string + subPath string + + writePending *string + cachedRead *string +} + +var _ distsys.ArchetypeResource = &fileArchetypeResource{} + +func (res *fileArchetypeResource) Abort() chan struct{} { + res.writePending = nil + res.cachedRead = nil + return nil +} + +func (res *fileArchetypeResource) PreCommit() chan error { + return nil +} + +func (res *fileArchetypeResource) Commit() chan struct{} { + if res.writePending != nil { + doneCh := make(chan struct{}) + go func() { + err := ioutil.WriteFile(path.Join(res.workingDirectory, res.subPath), []byte(*res.writePending), 0777) + if err != nil { + panic(fmt.Errorf("could not write file %s: %w", path.Join(res.workingDirectory, res.subPath), err)) + } + res.writePending = nil + doneCh <- struct{}{} + }() + return doneCh + } + res.cachedRead = nil + return nil +} + +func (res *fileArchetypeResource) ReadValue() (distsys.TLAValue, error) { + if res.writePending != nil { + return distsys.NewTLAString(*res.writePending), nil + } else if res.cachedRead != nil { + return distsys.NewTLAString(*res.cachedRead), nil + } else { + contents, err := ioutil.ReadFile(path.Join(res.workingDirectory, res.subPath)) + if err != nil { + panic(fmt.Errorf("could not read file %s: %w", path.Join(res.workingDirectory, res.subPath), err)) + } + contentsStr := string(contents) + res.cachedRead = &contentsStr + return distsys.NewTLAString(*res.cachedRead), nil + } +} + +func (res *fileArchetypeResource) WriteValue(value distsys.TLAValue) error { + res.cachedRead = nil + strToWrite := value.AsString() + res.writePending = &strToWrite + return nil +} diff --git a/distsys/archetype_resources/incremental_map.go b/distsys/archetype_resources/incremental_map.go new file mode 100644 index 000000000..b2ceaa9ac --- /dev/null +++ b/distsys/archetype_resources/incremental_map.go @@ -0,0 +1,124 @@ +package archetype_resources + +import ( + "github.com/UBC-NSS/pgo/distsys" + "github.com/benbjohnson/immutable" +) + +// A generic map resource, with hooks to programmatically realize child resources during execution +// ---------------------------------------------------------------------------------------------------------------- + +type IncrementalArchetypeMapResource struct { + distsys.ArchetypeResourceMapMixin + realizedMap *immutable.Map + fillFunction func(index distsys.TLAValue) distsys.ArchetypeResourceMaker +} + +var _ distsys.ArchetypeResource = &IncrementalArchetypeMapResource{} + +func IncrementalArchetypeMapResourceMaker(fillFunction func(index distsys.TLAValue) distsys.ArchetypeResourceMaker) distsys.ArchetypeResourceMaker { + return distsys.ArchetypeResourceMakerStruct{ + MakeFn: func() distsys.ArchetypeResource { + return &IncrementalArchetypeMapResource{ + realizedMap: immutable.NewMap(distsys.TLAValueHasher{}), + } + }, + ConfigureFn: func(res distsys.ArchetypeResource) { + r := res.(*IncrementalArchetypeMapResource) + r.fillFunction = fillFunction + }, + } +} + +func (res *IncrementalArchetypeMapResource) Index(index distsys.TLAValue) (distsys.ArchetypeResource, error) { + maker := res.fillFunction(index) + if subRes, ok := res.realizedMap.Get(index); ok { + r := subRes.(distsys.ArchetypeResource) + maker.Configure(r) + return subRes.(distsys.ArchetypeResource), nil + } + + subRes := maker.Make() + maker.Configure(subRes) + res.realizedMap = res.realizedMap.Set(index, subRes) + return subRes, nil +} + +func (res *IncrementalArchetypeMapResource) PreCommit() chan error { + var nonTrivialOps []chan error + it := res.realizedMap.Iterator() + for !it.Done() { + _, r := it.Next() + ch := r.(distsys.ArchetypeResource).PreCommit() + if ch != nil { + nonTrivialOps = append(nonTrivialOps, ch) + } + } + + if len(nonTrivialOps) != 0 { + doneCh := make(chan error) + go func() { + var err error + for _, ch := range nonTrivialOps { + err = <-ch + if err != nil { + break + } + } + doneCh <- err + }() + return doneCh + } + + return nil +} + +func (res *IncrementalArchetypeMapResource) Commit() chan struct{} { + var nonTrivialOps []chan struct{} + it := res.realizedMap.Iterator() + for !it.Done() { + _, r := it.Next() + ch := r.(distsys.ArchetypeResource).Commit() + if ch != nil { + nonTrivialOps = append(nonTrivialOps, ch) + } + } + + if len(nonTrivialOps) != 0 { + doneCh := make(chan struct{}) + go func() { + for _, ch := range nonTrivialOps { + <-ch + } + doneCh <- struct{}{} + }() + return doneCh + } + + return nil +} + +func (res *IncrementalArchetypeMapResource) Abort() chan struct{} { + var nonTrivialOps []chan struct{} + it := res.realizedMap.Iterator() + for !it.Done() { + _, r := it.Next() + ch := r.(distsys.ArchetypeResource).Abort() + if ch != nil { + nonTrivialOps = append(nonTrivialOps, ch) + } + } + + if len(nonTrivialOps) != 0 { + doneCh := make(chan struct{}) + go func() { + for _, ch := range nonTrivialOps { + <-ch + } + doneCh <- struct{}{} + }() + return doneCh + } + + return nil +} diff --git a/distsys/archetype_resources/tcp_mailboxes.go b/distsys/archetype_resources/tcp_mailboxes.go new file mode 100644 index 000000000..713ff9ce2 --- /dev/null +++ b/distsys/archetype_resources/tcp_mailboxes.go @@ -0,0 +1,331 @@ +package archetype_resources + +import ( + "encoding/gob" + "fmt" + "github.com/UBC-NSS/pgo/distsys" + "log" + "net" + "time" +) + +// Mailboxes as Archetype Resource +// ------------------------------- + +const ( + tcpNetworkBegin = iota + tcpNetworkValue + tcpNetworkPreCommit + tcpNetworkCommit +) + +type TCPMailboxKind int + +const ( + TCPMailboxesLocal = iota + TCPMailboxesRemote +) + +func TCPMailboxesArchetypeResourceMaker(addressMappingFn func(distsys.TLAValue) (TCPMailboxKind, string)) distsys.ArchetypeResourceMaker { + return IncrementalArchetypeMapResourceMaker(func(index distsys.TLAValue) distsys.ArchetypeResourceMaker { + tpe, addr := addressMappingFn(index) + switch tpe { + case TCPMailboxesLocal: + return tcpMailboxesLocalArchetypeResourceMaker(addr) + case TCPMailboxesRemote: + return tcpMailboxesRemoteArchetypeResourceMaker(addr) + default: + panic(fmt.Errorf("invalid TCP mailbox type %d for address %s: expected local or remote, which are %d or %d", tpe, addr, TCPMailboxesLocal, TCPMailboxesRemote)) + } + }) +} + +type tcpMailboxesLocalArchetypeResource struct { + distsys.ArchetypeResourceLeafMixin + msgChannel chan distsys.TLAValue + + readBacklog []distsys.TLAValue + readsInProgress []distsys.TLAValue +} + +var _ distsys.ArchetypeResource = &tcpMailboxesLocalArchetypeResource{} + +func tcpMailboxesLocalArchetypeResourceMaker(listenAddr string) distsys.ArchetypeResourceMaker { + return distsys.ArchetypeResourceMakerFn(func() distsys.ArchetypeResource { + msgChannel := make(chan distsys.TLAValue, 100) + listener, err := net.Listen("tcp", listenAddr) + if err != nil { + log.Fatalf("could not listen on address %s", listenAddr) + } + go func() { + for { + conn, err := listener.Accept() + if err != nil { + log.Fatalf("error listening on %s", listenAddr) + } + go func() { + var err error + encoder := gob.NewEncoder(conn) + decoder := gob.NewDecoder(conn) + var localBuffer []distsys.TLAValue + hasBegun := false + for { + if err != nil { + log.Printf("network error: %s", err.Error()) + break + } + var tag int + err = decoder.Decode(&tag) + if err != nil { + continue + } + switch tag { + case tcpNetworkBegin: + if localBuffer != nil { + localBuffer = nil + } + hasBegun = true + case tcpNetworkValue: + var value distsys.TLAValue + err = decoder.Decode(&value) + if err != nil { + continue + } + localBuffer = append(localBuffer, value) + case tcpNetworkPreCommit: + err = encoder.Encode(struct{}{}) + if err != nil { + continue + } + case tcpNetworkCommit: + // when crash-proofing, we need a way to identify repeat commits + // _when an old commit was successful but didn't persist due to crash_ + // could be done by: + // - send a unique incrementing counter on pre-commit + // - commit-er sends this id on commit, and we store this commit attempt in a persistent set + // alongside the buffer itself + // - receiving two commits for the same id can be detected by looking in the set, in which + // case do nothing and reply that the thing is done. + // - starting a new critical section sends the id of the remote's last commit, which + // indicates that commit was successful, and that the id can be removed from the set + if !hasBegun { + err = encoder.Encode(true) + if err != nil { + continue + } + } else { + // FIXME: this is weak to restarts, but fixing that without proper context is really hard + // at least, in this case the msgChannel will function as a rate limiter, so + // crash-free operation shouldn't do anything weird + for _, elem := range localBuffer { + msgChannel <- elem + } + err = encoder.Encode(false) + if err != nil { + continue + } + hasBegun = false + } + } + } + err = conn.Close() + if err != nil { + log.Printf("error closing connection: %s", err.Error()) + } + }() + } + }() + + return &tcpMailboxesLocalArchetypeResource{ + msgChannel: msgChannel, + } + }) +} + +func (res *tcpMailboxesLocalArchetypeResource) Abort() chan struct{} { + res.readBacklog = append(res.readBacklog, res.readsInProgress...) + res.readsInProgress = nil + return nil +} + +func (res *tcpMailboxesLocalArchetypeResource) PreCommit() chan error { + return nil +} + +func (res *tcpMailboxesLocalArchetypeResource) Commit() chan struct{} { + res.readsInProgress = nil + return nil +} + +func (res *tcpMailboxesLocalArchetypeResource) ReadValue() (distsys.TLAValue, error) { + // if a critical section previously aborted, already-read values will be here + if len(res.readBacklog) > 0 { + value := res.readBacklog[0] + res.readBacklog[0] = distsys.TLAValue{} + res.readBacklog = res.readBacklog[1:] + return value, nil + } + + // otherwise, either pull a notification + atomically read a value from the buffer, or time out + select { + case msg := <-res.msgChannel: + res.readsInProgress = append(res.readsInProgress, msg) + return msg, nil + case <-time.After(20 * time.Millisecond): + return distsys.TLAValue{}, distsys.ErrCriticalSectionAborted + } +} + +func (res *tcpMailboxesLocalArchetypeResource) WriteValue(value distsys.TLAValue) error { + panic(fmt.Errorf("attempted to write value %v to a local mailbox archetype resource", value)) +} + +type tcpMailboxesRemoteArchetypeResource struct { + distsys.ArchetypeResourceLeafMixin + dialAddr string + + inCriticalSection bool + conn net.Conn + connEncoder *gob.Encoder + connDecoder *gob.Decoder + sendBuffer []distsys.TLAValue +} + +var _ distsys.ArchetypeResource = &tcpMailboxesRemoteArchetypeResource{} + +func tcpMailboxesRemoteArchetypeResourceMaker(dialAddr string) distsys.ArchetypeResourceMaker { + return distsys.ArchetypeResourceMakerFn(func() distsys.ArchetypeResource { + return &tcpMailboxesRemoteArchetypeResource{ + dialAddr: dialAddr, + } + }) +} + +func (res *tcpMailboxesRemoteArchetypeResource) ensureConnection() error { + if res.conn == nil { + var err error + res.conn, err = net.Dial("tcp", res.dialAddr) + if err != nil { + log.Printf("failed to dial %s, aborting after 50ms: %v", res.dialAddr, err) + time.Sleep(time.Millisecond * 50) + return distsys.ErrCriticalSectionAborted + } + res.connEncoder = gob.NewEncoder(res.conn) + res.connDecoder = gob.NewDecoder(res.conn) + } + return nil +} + +func (res *tcpMailboxesRemoteArchetypeResource) Abort() chan struct{} { + res.sendBuffer = nil + // nothing to do; the remote end tolerates just starting over with no explanation + return nil +} + +func (res *tcpMailboxesRemoteArchetypeResource) PreCommit() chan error { + ch := make(chan error, 1) + go func() { + var err error + { + err = res.connEncoder.Encode(tcpNetworkPreCommit) + if err != nil { + goto handleError + } + var ack struct{} + err = res.connDecoder.Decode(&ack) + if err != nil { + goto handleError + } + ch <- nil + return + } + handleError: + log.Printf("network error while performing pre-commit handshake, aborting: %v", err) + res.conn = nil + ch <- distsys.ErrCriticalSectionAborted + }() + return ch +} + +func (res *tcpMailboxesRemoteArchetypeResource) Commit() chan struct{} { + ch := make(chan struct{}, 1) + go func() { + var err error + outerLoop: + for { + if err != nil { + log.Printf("network error during commit, resetting: %v", err) + res.conn = nil + } + err = res.ensureConnection() + if err != nil { + continue outerLoop + } + err = res.connEncoder.Encode(tcpNetworkCommit) + if err != nil { + continue outerLoop + } + var shouldResend bool + err = res.connDecoder.Decode(&shouldResend) + if err != nil { + continue outerLoop + } + if shouldResend { + err = res.connEncoder.Encode(tcpNetworkBegin) + if err != nil { + continue outerLoop + } + for _, value := range res.sendBuffer { + err = res.connEncoder.Encode(tcpNetworkValue) + if err != nil { + continue outerLoop + } + err = res.connEncoder.Encode(&value) + if err != nil { + continue outerLoop + } + } + continue outerLoop + } + res.sendBuffer = nil + ch <- struct{}{} + return + } + }() + return ch +} + +func (res *tcpMailboxesRemoteArchetypeResource) ReadValue() (distsys.TLAValue, error) { + panic(fmt.Errorf("attempted to read from a remote mailbox archetype resource")) +} + +func (res *tcpMailboxesRemoteArchetypeResource) WriteValue(value distsys.TLAValue) error { + var err error + handleError := func() error { + log.Printf("network error during remote value write, aborting: %v", err) + res.conn = nil + return distsys.ErrCriticalSectionAborted + } + + err = res.ensureConnection() + if err != nil { + return err + } + if !res.inCriticalSection { + err = res.connEncoder.Encode(tcpNetworkBegin) + if err != nil { + return handleError() + } + } + err = res.connEncoder.Encode(tcpNetworkValue) + if err != nil { + return handleError() + } + addressableValue := new(distsys.TLAValue) + *addressableValue = value + err = res.connEncoder.Encode(addressableValue) + if err != nil { + return handleError() + } + return nil +} diff --git a/distsys/archetypes.go b/distsys/archetypes.go deleted file mode 100644 index ce4331a9f..000000000 --- a/distsys/archetypes.go +++ /dev/null @@ -1,769 +0,0 @@ -package distsys - -import ( - "bytes" - "container/list" - "encoding/gob" - "errors" - "fmt" - "github.com/benbjohnson/immutable" - "log" - "net" - "sync" - "time" -) - -var ErrCriticalSectionAborted = errors.New("MPCal critical section aborted") - -type ArchetypeResource interface { - Abort() chan struct{} - PreCommit() chan error - Commit() chan struct{} - ReadValue() (TLAValue, error) - WriteValue(value TLAValue) error - Index(index TLAValue) (ArchetypeResource, error) -} - -type ArchetypeResourceLeafMixin struct{} - -var ErrArchetypeResourceLeafIndexed = errors.New("internal error: attempted to index a leaf archetype resource") - -func (ArchetypeResourceLeafMixin) Index(TLAValue) (ArchetypeResource, error) { - return nil, ErrArchetypeResourceLeafIndexed -} - -type ArchetypeResourceMapMixin struct{} - -var ErrArchetypeResourceMapReadWrite = errors.New("internal error: attempted to read/write a map archetype resource") - -func (ArchetypeResourceMapMixin) ReadValue() (TLAValue, error) { - return TLAValue{}, ErrArchetypeResourceMapReadWrite -} - -func (ArchetypeResourceMapMixin) WriteValue(TLAValue) error { - return ErrArchetypeResourceMapReadWrite -} - -//////////////////////////////////////////////// -//// ARCHETYPE RESOURCES //// -//////////////////////////////////////////////// - -// A bare-bones resource: just holds and buffers a TLAValue -// -------------------------------------------------------- - -type LocalArchetypeResource struct { - ArchetypeResourceLeafMixin - record localArchetypeResourceRecord -} - -type localArchetypeResourceRecord struct { - IsInitialized bool // start-up flag, to avoid setting up state again when reloading from disk - HasOldValue bool // if true, this resource has already been written in this critical section - // if this resource is already written in this critical section, OldValue contains prev value - // Value always contains the "current" value - Value, OldValue TLAValue -} - -var _ ArchetypeResource = &LocalArchetypeResource{} - -func EnsureLocalArchetypeResource(ensurer MPCalContextResourceEnsurer, value TLAValue) ArchetypeResourceHandle { - return ensurer(&LocalArchetypeResource{}, func(resource ArchetypeResource) { - res := resource.(*LocalArchetypeResource) - if !res.record.IsInitialized { - res.record.IsInitialized = true - res.record.Value = value - } - }) -} - -func (res *LocalArchetypeResource) Abort() chan struct{} { - if res.record.HasOldValue { - res.record.Value = res.record.OldValue - res.record.HasOldValue = false - res.record.OldValue = TLAValue{} - } - return nil -} - -func (res *LocalArchetypeResource) PreCommit() chan error { - return nil -} - -func (res *LocalArchetypeResource) Commit() chan struct{} { - res.record.HasOldValue = false - res.record.OldValue = TLAValue{} - return nil -} - -func (res *LocalArchetypeResource) ReadValue() (TLAValue, error) { - return res.record.Value, nil -} - -func (res *LocalArchetypeResource) WriteValue(value TLAValue) error { - if !res.record.HasOldValue { - res.record.OldValue = res.record.Value - res.record.HasOldValue = true - } - res.record.Value = value - return nil -} - -func (res *LocalArchetypeResource) GobDecode(input []byte) error { - buf := bytes.NewBuffer(input) - decoder := gob.NewDecoder(buf) - return decoder.Decode(&res.record) -} - -func (res *LocalArchetypeResource) GobEncode() ([]byte, error) { - var buf bytes.Buffer - encoder := gob.NewEncoder(&buf) - err := encoder.Encode(&res.record) - if err != nil { - return nil, err - } - return buf.Bytes(), nil -} - -// Input channel resource: a read-only data source backed by an externally-controlled Go channel -// --------------------------------------------------------------------------------------------- - -type InputChannelResource struct { - ArchetypeResourceLeafMixin - channel <-chan TLAValue - buffer []TLAValue -} - -var _ ArchetypeResource = &InputChannelResource{} - -func EnsureInputChannelResource(ensurer MPCalContextResourceEnsurer, channel <-chan TLAValue) ArchetypeResourceHandle { - return ensurer(&InputChannelResource{}, func(resource ArchetypeResource) { - res := resource.(*InputChannelResource) - res.channel = channel - }) -} - -func (res *InputChannelResource) Abort() chan struct{} { - return nil -} - -func (res *InputChannelResource) PreCommit() chan error { - return nil -} - -func (res *InputChannelResource) Commit() chan struct{} { - res.buffer = nil - return nil -} - -func (res *InputChannelResource) ReadValue() (TLAValue, error) { - if len(res.buffer) > 0 { - value := res.buffer[0] - res.buffer = res.buffer[1:] - return value, nil - } - - select { - case value := <-res.channel: - res.buffer = append(res.buffer, value) - return value, nil - case <-time.After(time.Millisecond * 20): - return TLAValue{}, ErrCriticalSectionAborted - } -} - -func (res *InputChannelResource) WriteValue(value TLAValue) error { - panic(fmt.Errorf("attempted to write %v to an input channel resource", value)) -} - -// Output channel resource: a write-only resource backed by an externally-readable Go channel -// ------------------------------------------------------------------------------------------ - -type OutputChannelResource struct { - ArchetypeResourceLeafMixin - channel chan<- TLAValue - buffer []TLAValue -} - -var _ ArchetypeResource = &OutputChannelResource{} - -func EnsureOutputChannelResource(ensurer MPCalContextResourceEnsurer, channel chan<- TLAValue) ArchetypeResourceHandle { - return ensurer(&OutputChannelResource{}, func(resource ArchetypeResource) { - res := resource.(*OutputChannelResource) - res.channel = channel - }) -} - -func (res *OutputChannelResource) Abort() chan struct{} { - res.buffer = nil - return nil -} - -func (res *OutputChannelResource) PreCommit() chan error { - return nil -} - -func (res *OutputChannelResource) Commit() chan struct{} { - ch := make(chan struct{}) - go func() { - for _, value := range res.buffer { - res.channel <- value - } - res.buffer = nil - ch <- struct{}{} - }() - return ch -} - -func (res *OutputChannelResource) ReadValue() (TLAValue, error) { - panic(fmt.Errorf("attempted to read from an input channel resource")) -} - -func (res *OutputChannelResource) WriteValue(value TLAValue) error { - res.buffer = append(res.buffer, value) - return nil -} - -// A generic map resource, with hooks to programmatically and serializably realize child resources during execution -// ---------------------------------------------------------------------------------------------------------------- - -type IncrementalArchetypeMapResource struct { - ArchetypeResourceMapMixin - realizedMap *immutable.Map - FillFunction func(IncrementalArchetypeMapResourceEnsurer, TLAValue) -} - -type incrementalArchetypeMapResourceRecord struct { - Key TLAValue - Value ArchetypeResource -} - -type IncrementalArchetypeMapResourceEnsurer func(blank ArchetypeResource, configFn func(ArchetypeResource)) - -var _ ArchetypeResource = &IncrementalArchetypeMapResource{} - -func EnsureIncrementalArchetypeMapResource(ensurer MPCalContextResourceEnsurer, fillFunction func(IncrementalArchetypeMapResourceEnsurer, TLAValue)) ArchetypeResourceHandle { - return ensurer(&IncrementalArchetypeMapResource{}, func(resource ArchetypeResource) { - resource.(*IncrementalArchetypeMapResource).EnsureConfig(fillFunction) - }) -} - -func (res *IncrementalArchetypeMapResource) EnsureConfig(fillFunction func(IncrementalArchetypeMapResourceEnsurer, TLAValue)) { - if res.realizedMap == nil { - res.realizedMap = immutable.NewMap(TLAValueHasher{}) - } - // this should only happen once, because, once it happens, FillFunction will be set. - // this structure allows sub-resources to set up any static non-serializable information, if they have just - // previously been deserialized. - if res.FillFunction == nil { - res.FillFunction = fillFunction - it := res.realizedMap.Iterator() - for !it.Done() { - key, value := it.Next() - fillFunction(func(_ ArchetypeResource, configFn func(ArchetypeResource)) { - configFn(value.(ArchetypeResource)) - }, key.(TLAValue)) - } - } -} - -func (res *IncrementalArchetypeMapResource) Index(index TLAValue) (ArchetypeResource, error) { - var resource ArchetypeResource - res.FillFunction(func(blank ArchetypeResource, configFn func(ArchetypeResource)) { - if subRes, ok := res.realizedMap.Get(index); ok { - resource = subRes.(ArchetypeResource) - } else { - configFn(blank) - res.realizedMap = res.realizedMap.Set(index, blank) - resource = blank - } - }, index) - return resource, nil -} - -func (res *IncrementalArchetypeMapResource) PreCommit() chan error { - var nonTrivialPreCommits []chan error - it := res.realizedMap.Iterator() - for !it.Done() { - _, subRes := it.Next() - ch := subRes.(ArchetypeResource).PreCommit() - if ch != nil { - nonTrivialPreCommits = append(nonTrivialPreCommits, ch) - } - } - if len(nonTrivialPreCommits) == 0 { - return nil - } - outCh := make(chan error) - go func() { - var err error - for _, ch := range nonTrivialPreCommits { - err = <-ch - if err != nil { - break - } - } - outCh <- err - }() - return outCh -} - -func (res *IncrementalArchetypeMapResource) Commit() chan struct{} { - var nonTrivialCommits []chan struct{} - it := res.realizedMap.Iterator() - for !it.Done() { - _, subRes := it.Next() - ch := subRes.(ArchetypeResource).Commit() - if ch != nil { - nonTrivialCommits = append(nonTrivialCommits, ch) - } - } - if len(nonTrivialCommits) == 0 { - return nil - } - outCh := make(chan struct{}) - go func() { - for _, ch := range nonTrivialCommits { - <-ch - } - outCh <- struct{}{} - }() - return outCh -} - -func (res *IncrementalArchetypeMapResource) Abort() chan struct{} { - var nonTrivialAborts []chan struct{} - it := res.realizedMap.Iterator() - for !it.Done() { - _, subRes := it.Next() - ch := subRes.(ArchetypeResource).Abort() - if ch != nil { - nonTrivialAborts = append(nonTrivialAborts, ch) - } - } - if len(nonTrivialAborts) == 0 { - return nil - } - outCh := make(chan struct{}) - go func() { - for _, ch := range nonTrivialAborts { - <-ch - } - outCh <- struct{}{} - }() - return outCh -} - -// Global State as Archetype Resource -// ---------------------------------- - -// TODO: recreate - -// Mailboxes as Archetype Resource -// ------------------------------- - -type TCPMailboxesArchetypeResource struct { - IncrementalArchetypeMapResource -} - -const ( - tcpNetworkBegin = iota - tcpNetworkValue - tcpNetworkPreCommit - tcpNetworkPreCommitAck - tcpNetworkCommit -) - -var _ ArchetypeResource = &TCPMailboxesArchetypeResource{} - -type TCPMailboxKind int - -const ( - TCPMailboxesLocal = iota - TCPMailboxesRemote -) - -func EnsureTCPMailboxesArchetypeResource(ensurer MPCalContextResourceEnsurer, addressMappingFn func(TLAValue) (TCPMailboxKind, string)) ArchetypeResourceHandle { - return ensurer(&TCPMailboxesArchetypeResource{}, func(resource ArchetypeResource) { - res := resource.(*TCPMailboxesArchetypeResource) - res.EnsureConfig(func(ensurer IncrementalArchetypeMapResourceEnsurer, index TLAValue) { - tpe, addr := addressMappingFn(index) - switch tpe { - case TCPMailboxesLocal: - ensurer(&TCPMailboxLocalArchetypeResource{}, func(resource ArchetypeResource) { - r := resource.(*TCPMailboxLocalArchetypeResource) - r.EnsureConfig(addr) - }) - case TCPMailboxesRemote: - ensurer(&TCPMailboxRemoteArchetypeResource{}, func(resource ArchetypeResource) { - r := resource.(*TCPMailboxRemoteArchetypeResource) - r.EnsureConfig(addr) - }) - default: - panic(fmt.Errorf("invalid TCP mailbox type %d for address %s: expected local or remote, which are %d or %d", tpe, addr, TCPMailboxesLocal, TCPMailboxesRemote)) - } - }) - }) -} - -type TCPMailboxLocalArchetypeResource struct { - ArchetypeResourceLeafMixin - listenAddr string - - listener net.Listener - buffer *list.List - bufferFillNotify chan struct{} - bufferLock sync.Mutex - - bufferSize int - - readBacklog []TLAValue - readsInProgress []TLAValue -} - -var _ ArchetypeResource = &TCPMailboxLocalArchetypeResource{} - -func (res *TCPMailboxLocalArchetypeResource) ensureSetup() { - res.bufferLock.Lock() - defer res.bufferLock.Unlock() - - if res.buffer == nil { - res.buffer = list.New() - } - - if res.bufferFillNotify == nil { - // ideally, the notification count should be equal to buffer size, but, for reliability, we sometimes - // store an oversize buffer. in this case, surreptitiously bump the channel size to avoid deadlock - notifyCount := res.bufferSize - if res.buffer.Len() > notifyCount { - notifyCount = res.buffer.Len() - } - res.bufferFillNotify = make(chan struct{}, notifyCount) - for i := 0; i < notifyCount; i++ { - res.bufferFillNotify <- struct{}{} - } - } - - if res.listener == nil { - var err error - res.listener, err = net.Listen("tcp", res.listenAddr) - if err != nil { - log.Fatalf("could not listen on address %s", res.listenAddr) - } - go func() { - for { - conn, err := res.listener.Accept() - if err != nil { - log.Fatalf("error listening on %s", res.listenAddr) - } - go func() { - var err error - encoder := gob.NewEncoder(conn) - decoder := gob.NewDecoder(conn) - var localBuffer []TLAValue - hasBegun := false - for { - if err != nil { - log.Printf("network error: %s", err.Error()) - break - } - var tag int - err = decoder.Decode(&tag) - if err != nil { - continue - } - switch tag { - case tcpNetworkBegin: - if localBuffer != nil { - localBuffer = nil - } - hasBegun = true - case tcpNetworkValue: - var value TLAValue - err = decoder.Decode(&value) - if err != nil { - continue - } - localBuffer = append(localBuffer, value) - case tcpNetworkPreCommit: - err = encoder.Encode(struct{}{}) - if err != nil { - continue - } - case tcpNetworkCommit: - // when crash-proofing, we need a way to identify repeat commits - // _when an old commit was successful but didn't persist due to crash_ - // could be done by: - // - send a unique incrementing counter on pre-commit - // - commit-er sends this id on commit, and we store this commit attempt in a persistent set - // alongside the buffer itself - // - receiving two commits for the same id can be detected by looking in the set, in which - // case do nothing and reply that the thing is done. - // - starting a new critical section sends the id of the remote's last commit, which - // indicates that commit was successful, and that the id can be removed from the set - if !hasBegun { - err = encoder.Encode(true) - if err != nil { - continue - } - } else { - func() { - res.bufferLock.Lock() - defer res.bufferLock.Unlock() - // TODO: store buffer durably - for _, val := range localBuffer { - res.buffer.PushBack(val) - } - // store buffer as a locked structure, use channels to notify when important change happen - // - when the channel becomes not-full, notify any potential writers - // - when the channel becomes not-empty, notify the reader - }() - err = encoder.Encode(false) - if err != nil { - continue - } - hasBegun = false // TODO: also store durably? - // push notifications _after_ the buffer has been filled, so we guarantee that - // a filled version of the buffer has been atomically saved, while allowing - // us to block for a long time without the complication of holding a lock on the buffer - for range localBuffer { - res.bufferFillNotify <- struct{}{} - } - } - } - } - err = conn.Close() - if err != nil { - log.Printf("error closing connection: %s", err.Error()) - } - }() - } - }() - } -} - -func (res *TCPMailboxLocalArchetypeResource) EnsureConfig(addr string) { - res.listenAddr = addr - res.ensureSetup() -} - -func (res *TCPMailboxLocalArchetypeResource) Abort() chan struct{} { - res.readBacklog = append(res.readBacklog, res.readsInProgress...) - res.readsInProgress = nil - return nil -} - -func (res *TCPMailboxLocalArchetypeResource) PreCommit() chan error { - return nil -} - -func (res *TCPMailboxLocalArchetypeResource) Commit() chan struct{} { - res.readsInProgress = nil - return nil -} - -func (res *TCPMailboxLocalArchetypeResource) ReadValue() (TLAValue, error) { - // if a critical section previously aborted, already-read values will be here - if len(res.readBacklog) > 0 { - value := res.readBacklog[0] - res.readBacklog[0] = TLAValue{} - res.readBacklog = res.readBacklog[1:] - return value, nil - } - - // otherwise, either pull a notification + atomically read a value from the buffer, or time out - select { - case <-res.bufferFillNotify: - res.bufferLock.Lock() - defer res.bufferLock.Unlock() - frontElem := res.buffer.Front() - poppedValue := frontElem.Value.(TLAValue) - res.buffer.Remove(frontElem) - res.readsInProgress = append(res.readsInProgress, poppedValue) - return poppedValue, nil - case <-time.After(20 * time.Millisecond): - return TLAValue{}, ErrCriticalSectionAborted - } -} - -func (res *TCPMailboxLocalArchetypeResource) WriteValue(value TLAValue) error { - panic(fmt.Errorf("attempted to write value %v to a local mailbox archetype resource", value)) -} - -type TCPMailboxRemoteArchetypeResource struct { - ArchetypeResourceLeafMixin - dialAddr string - - inCriticalSection bool - conn net.Conn - connEncoder *gob.Encoder - connDecoder *gob.Decoder - sendBuffer []TLAValue -} - -var _ ArchetypeResource = &TCPMailboxRemoteArchetypeResource{} - -func (res *TCPMailboxRemoteArchetypeResource) EnsureConfig(addr string) { - res.dialAddr = addr -} - -func (res *TCPMailboxRemoteArchetypeResource) ensureConnection() error { - if res.conn == nil { - var err error - res.conn, err = net.Dial("tcp", res.dialAddr) - if err != nil { - log.Printf("failed to dial %s, aborting after 50ms: %v", res.dialAddr, err) - time.Sleep(time.Millisecond * 50) - return ErrCriticalSectionAborted - } - res.connEncoder = gob.NewEncoder(res.conn) - res.connDecoder = gob.NewDecoder(res.conn) - } - return nil -} - -func (res *TCPMailboxRemoteArchetypeResource) Abort() chan struct{} { - res.sendBuffer = nil - // nothing to do; the remote end tolerates just starting over with no explanation - return nil -} - -func (res *TCPMailboxRemoteArchetypeResource) PreCommit() chan error { - ch := make(chan error, 1) - go func() { - var err error - { - err = res.connEncoder.Encode(tcpNetworkPreCommit) - if err != nil { - goto handleError - } - var ack struct{} - err = res.connDecoder.Decode(&ack) - if err != nil { - goto handleError - } - ch <- nil - return - } - handleError: - log.Printf("network error while performing pre-commit handshake, aborting: %v", err) - res.conn = nil - ch <- ErrCriticalSectionAborted - }() - return ch -} - -func (res *TCPMailboxRemoteArchetypeResource) Commit() chan struct{} { - ch := make(chan struct{}, 1) - go func() { - var err error - outerLoop: - for { - if err != nil { - log.Printf("network error during commit, resetting: %v", err) - res.conn = nil - } - err = res.ensureConnection() - if err != nil { - continue outerLoop - } - err = res.connEncoder.Encode(tcpNetworkCommit) - if err != nil { - continue outerLoop - } - var shouldResend bool - err = res.connDecoder.Decode(&shouldResend) - if err != nil { - continue outerLoop - } - if shouldResend { - err = res.connEncoder.Encode(tcpNetworkBegin) - if err != nil { - continue outerLoop - } - for _, value := range res.sendBuffer { - err = res.connEncoder.Encode(tcpNetworkValue) - if err != nil { - continue outerLoop - } - err = res.connEncoder.Encode(&value) - if err != nil { - continue outerLoop - } - } - continue outerLoop - } - res.sendBuffer = nil - ch <- struct{}{} - return - } - }() - return ch -} - -func (res *TCPMailboxRemoteArchetypeResource) ReadValue() (TLAValue, error) { - panic(fmt.Errorf("attempted to read from a remote mailbox archetype resource")) -} - -func (res *TCPMailboxRemoteArchetypeResource) WriteValue(value TLAValue) error { - err := res.ensureConnection() - if err != nil { - return err - } - if !res.inCriticalSection { - err = res.connEncoder.Encode(tcpNetworkBegin) - if err != nil { - goto handleError - } - } - err = res.connEncoder.Encode(tcpNetworkValue) - if err != nil { - goto handleError - } - err = res.connEncoder.Encode(&value) - if err != nil { - goto handleError - } - return nil -handleError: - log.Printf("network error during remote value write, aborting: %v", err) - res.conn = nil - return ErrCriticalSectionAborted -} - -// Filesystem archetype resource -// ----------------------------- - -type FilesystemArchetypeResource struct { - ArchetypeResourceLeafMixin - workingDirectory string - writesPending map[string]TLAValue -} - -var _ ArchetypeResource = &FilesystemArchetypeResource{} - -func NewFilesystemArchetypeResource(ensurer MPCalContextResourceEnsurer, workingDirectory string) ArchetypeResourceHandle { - return ensurer(&FilesystemArchetypeResource{}, func(resource ArchetypeResource) { - res := resource.(*FilesystemArchetypeResource) - _ = res - }) -} - -func (res *FilesystemArchetypeResource) Abort() chan struct{} { - panic("implement me") -} - -func (res *FilesystemArchetypeResource) PreCommit() chan error { - panic("implement me") -} - -func (res *FilesystemArchetypeResource) Commit() chan struct{} { - panic("implement me") -} - -func (res *FilesystemArchetypeResource) ReadValue() (TLAValue, error) { - panic("implement me") -} - -func (res *FilesystemArchetypeResource) WriteValue(value TLAValue) error { - panic("implement me") -} diff --git a/distsys/barrier.go b/distsys/barrier.go deleted file mode 100644 index 4585b7746..000000000 --- a/distsys/barrier.go +++ /dev/null @@ -1,169 +0,0 @@ -package distsys - -// This implements the a barrier protocol across all PlusCal processes. -// When a PlusCal specification is compiled to TLA+, the TLC model checker -// starts every "process" defined in PlusCal at the same time. -// -// The synchronization barrier implemented here makes sure that a processes -// only starts running once all other processes declared to be ready to -// continue executing as well. -// -// For more information, see: https://github.com/UBC-NSS/pgo/wiki/Synchronization-Barrier-Protocol - -import ( - "sync/atomic" - "time" -) - -const ( - RPC_ID = "PlusCalProcess" -) - -// SyncBarrierRPC provides RPC methods that are used to synchronize all PlusCal processes -// in the system. -type SyncBarrierRPC struct { - MyAddress string // the address of the current process (IP:port) - Coordinator string // which host is the coordinator (IP:port) - processesReady int32 // how many processes are ready currently (used only by the coordinator) - readyChan chan bool // underlying channel used to coordinate start - connections *Connections // connections to other peers - process string // the name of running process, as defined in the original PlusCal specification - configuration map[string]string // maps deployed IP addresses to PlusCal names (used by the coordinator) - setup bool // whether the RPC configuration has been performed -} - -// SyncBarrier wraps the underlying RPC object (SyncBarrierRPC) and provides functions that -// callers can use when a new barrier is required. -type SyncBarrier struct { - *SyncBarrierRPC -} - -// NewSyncBarrier creates a new SyncBarrier struct that can be used to create synchronization -// barriers across all processes in the PlusCal spec. -func NewSyncBarrier(configuration map[string]string, connections *Connections, address, coordinator string) *SyncBarrier { - barrier := &SyncBarrierRPC{ - MyAddress: address, - Coordinator: coordinator, - processesReady: 0, - readyChan: make(chan bool, 1), - connections: connections, - configuration: configuration, - setup: false, - } - - return &SyncBarrier{barrier} -} - -func (barrier *SyncBarrier) isCoordinator() bool { - return barrier.MyAddress == barrier.Coordinator -} - -func (barrier *SyncBarrier) PeerConnections() *Connections { - return barrier.connections -} - -// WaitPeers is the method to be used when the caller wants the process to block -// until all processes reach the same barrier. -func (barrier *SyncBarrier) WaitPeers() error { - if !barrier.setup { - barrier.init() - } - - // the process itself is ready. Incremented when other processes indicate they are - // ready via the `ProcessReady` RPC call - atomic.AddInt32(&barrier.processesReady, 1) - - if barrier.isCoordinator() { - // if this is the coordinator process and every other process already "checked-in", - // we are ready to move on - if err := barrier.check(); err != nil { - return err - } - - } else { - barrier.helloCoordinator() - } - - // wait for all processes to be ready - <-barrier.readyChan - - return nil -} - -// exposes the RPC methods required for the processes to communicate -func (barrier *SyncBarrier) init() error { - barrier.setup = true - return barrier.connections.ExposeImplementation(RPC_ID, barrier.SyncBarrierRPC) -} - -// check checks whether all processes have "checked-in". Only called -// by the coordinator process. If the number of "ProcessReady" calls -// the coordinator has received indicate that all nodes in the system -// are ready, the coordinator will send a message to all nodes -// indicating that they can resume their operation, and the -// coordinator itself will return from its call to WaitPeers(). -func (barrier *SyncBarrierRPC) check() error { - if int(atomic.LoadInt32(&barrier.processesReady))%len(barrier.configuration) == 0 { - for _, ip := range barrier.configuration { - if ip == barrier.MyAddress { - continue - } - - if err := barrier.connections.ConnectTo(ip); err != nil { - return err - } - - client := barrier.connections.GetConnection(ip) - var ok bool - if err := client.Call(RPC_ID+".Start", true, &ok); err != nil { - return err - } - } - - barrier.readyChan <- true - } - - return nil -} - -func (barrier *SyncBarrier) helloCoordinator() { - // try to reach the coordinator until it finally succeeds. - // Connection errors are interpreted to mean the coordinator is not up yet, - // so we wait (indefinitely) for it to be. - for { - if err := barrier.connections.ConnectTo(barrier.Coordinator); err != nil { - time.Sleep(1 * time.Second) - continue - } - - client := barrier.connections.GetConnection(barrier.Coordinator) - var ok bool - if err := client.Call(RPC_ID+".ProcessReady", true, &ok); err != nil { - continue - } - - return - } -} - -// ProcessReady is an RPC method used by processes to indicate they -// are ready to run. The coordinator keeps a counter of how many -// processes are ready, and when the counter is equal to the (static) -// number of peers, it means all processes are up and ready to run. It -// then sends a message to each of them indicating that they may start -// running their algorithms -func (barrier *SyncBarrierRPC) ProcessReady(_, ok *bool) error { - atomic.AddInt32(&barrier.processesReady, 1) - *ok = true - - return barrier.check() -} - -// Start is an RPC method that is sent to every process when the -// coordinator detects that every process in the system is ready. -func (barrier *SyncBarrierRPC) Start(_, ok *bool) error { - barrier.readyChan <- true - *ok = true - - return nil -} diff --git a/distsys/client.go b/distsys/client.go deleted file mode 100644 index 705069c71..000000000 --- a/distsys/client.go +++ /dev/null @@ -1,135 +0,0 @@ -package distsys - -// stateHandler defines the interface of a state handler. Apart from the definitions -// of localStateHandler, which manipulate state located within the running node's -// local store, there is also the possibility that state lives in another node -// in the system, and a similar interface is required -type stateHandler interface { - GetState() (VarReferences, error) - ReleaseState(VarReferences) error -} - -// remoteHandler implements stateHandler for the case where state lives in a different -// node in the network -type remoteHandler struct { - group *VarReq - stateServer *StateServer -} - -// GetState retrieves state that lives in another node in the system. The ownership table -// needs to be locked before this function is called since the variable may have -// moved. -func (remote remoteHandler) GetState() (VarReferences, error) { - conn := remote.stateServer.connections.GetConnection(remote.group.Peer) - remote.group.Requester = remote.stateServer.self - refs := VarReferences(map[string]*Reference{}) - - // unlock local references before we request remote state - for _, borrowVar := range remote.group.Names { - remote.stateServer.store.Unlock(borrowVar.Name) - } - - if err := conn.Call("StateServer.GetState", remote.group, &refs); err != nil { - return nil, err - } - - return refs, nil -} - -// ReleaseState releases state that lives in another system. This function needs to be -// called once a counterpart GetState call has succeeded. -func (remote remoteHandler) ReleaseState(refs VarReferences) error { - var ok bool - conn := remote.stateServer.connections.GetConnection(remote.group.Peer) - - // include only references for variables included in the group - // being released - releaseNames := []string{} - for _, borrowVar := range remote.group.Names { - releaseNames = append(releaseNames, borrowVar.Name) - } - - refSlice := VarReferences(map[string]*Reference{}) - for name, ref := range refs { - for _, releaseName := range releaseNames { - if releaseName == name { - refSlice[name] = ref - break - } - } - } - - if err := conn.Call("StateServer.ReleaseState", &refSlice, &ok); err != nil { - return err - } - - return nil -} - -// stateBuilder returns a stateHandler that either manipulates state in the running node's -// local store, or sends messages to the node that currently owns the state contained -// in the VarReq struct. -func stateBuilder(group *VarReq, ss *StateServer) stateHandler { - if group.Peer == ss.self { - return localStateHandler{ - group: group, - store: ss.store, - self: ss.self, - } - } - - return remoteHandler{group, ss} -} - -// Acquire receives a BorrowSpec and returns a populated VarReferences struct containing -// the values of the variables in the spec given, with the requested permissions (i.e., -// exclusive or non-exclusive (read-only) access). -func (ss *StateServer) Acquire(spec *BorrowSpec) (VarReferences, error) { - op := NewGlobalStateOperation(spec, ss.store, ss.self, ss.connections) - allRefs := VarReferences(map[string]*Reference{}) - - // lock every variable that is being requested to avoid migrations - // while we determine request groups - op.Lock() - - for op.HasNext() { - group := op.Next() - op.UnlockExcept(group) - - refs, err := stateBuilder(group, ss).GetState() - if err != nil { - return nil, err - } - - holds := op.UpdateRefs(refs) - op.AckMigrations() - allRefs = allRefs.Merge(holds) - - op.Lock() - } - - return allRefs, nil -} - -// Release receives a set of references to variables, potentially manipulated by -// the application (after a call to Acquire), and releases any locks that were -// held, either locally or remotely on a different node in the system. -func (ss *StateServer) Release(refs VarReferences) error { - op := NewGlobalStateOperation(refs.ToBorrowSpec(), ss.store, ss.self, ss.connections) - - for _, group := range op.Groups() { - if err := stateBuilder(group, ss).ReleaseState(refs); err != nil { - return err - } - } - - // unlock local entries after releasing our locks remotely - op.Unlock() - - return nil -} - -// func (net *Network) Close() error { -// net.connections.Close() -// return nil -// } diff --git a/distsys/connections.go b/distsys/connections.go deleted file mode 100644 index 666d214a6..000000000 --- a/distsys/connections.go +++ /dev/null @@ -1,120 +0,0 @@ -package distsys - -// This implements a unified way to connect to other proceses and expose an implementation -// that other processes can call. -// -// It uses Go's RPC library under the hood. Extensions to this abstraction could involve -// the definition of a interface that could be implemented by multiple communication methods -// (i.e., not only RPC but other types of protocols, if needed). - -import ( - "fmt" - "net" - "net/rpc" - "sync" -) - -// Connections maintain the state of the connections across the processes in the network. -type Connections struct { - address string // the IP:port combination that identifies the current process - listener *net.TCPListener // where the server is listening to, if at all - server *rpc.Server // RPC server instance, if this process exposes methods to the network - network map[string]*rpc.Client // existing connections to other processes - lock sync.Mutex // exclusive access to the metadata -} - -// NewConnections returns an empty connection map. -func NewConnections(addr string) *Connections { - return &Connections{ - address: addr, - server: nil, - network: map[string]*rpc.Client{}, - } -} - -// binds to the address given on initialization. Does nothing if this method was -// already invoked before -func (c *Connections) prepareRPCServer() error { - // server already exists, nothing to do here - if c.server != nil { - return nil - } - - // bind to this process's address - tcpaddr, err := net.ResolveTCPAddr("tcp", c.address) - if err != nil { - return err - } - - listener, err := net.ListenTCP("tcp", tcpaddr) - if err != nil { - return err - } - - c.listener = listener - c.server = rpc.NewServer() - go c.server.Accept(listener) - - return nil -} - -// ExposeImplementation associates a name with an implementation -// Other processes may then connect to this node and invoke the -// exposed methods under the name given. -func (c *Connections) ExposeImplementation(name string, impl interface{}) error { - if err := c.prepareRPCServer(); err != nil { - return err - } - - return c.server.RegisterName(name, impl) -} - -// ConnectTo builds a TCP connection to a given node in the address given. -func (c *Connections) ConnectTo(addr string) error { - c.lock.Lock() - defer c.lock.Unlock() - - // if the connection already exists, nothing to do here - if _, connected := c.network[addr]; connected { - return nil - } - - client, err := rpc.Dial("tcp", addr) - if err != nil { - return err - } - - c.network[addr] = client - return nil -} - -// GetConnection returns a connection to the node with the given address. If a -// connection to that node already exists, it is returned; otherwise, a new -// connection is established. -func (c *Connections) GetConnection(addr string) *rpc.Client { - conn, ok := c.network[addr] - if ok { - return conn - } - - // an error here should only occur if the initialization protocol was not - // used. To properly handle failures, this connection management implementation - // could be specialized to deal with scenarios where the node is not reachable - if err := c.ConnectTo(addr); err != nil { - panic(fmt.Sprintf("Node at %s is not ready to receive connections (error: %v)", addr, err)) - } - - return c.network[addr] -} - -// Close terminates all connections to other nodes and stops accepting remote -// connections from other peers. -func (c *Connections) Close() { - if c.listener != nil { - c.listener.Close() - } - - for _, conn := range c.network { - conn.Close() - } -} diff --git a/distsys/data_store.go b/distsys/data_store.go deleted file mode 100644 index ba875c2ac..000000000 --- a/distsys/data_store.go +++ /dev/null @@ -1,105 +0,0 @@ -package distsys - -import ( - "bytes" - "fmt" - "log" - "sync" -) - -// NameNotFoundError occurs when a lookup for an unknown name in the store is made -type NameNotFoundError string - -func (e NameNotFoundError) Error() string { - return fmt.Sprintf("Local store: name not found: %s", string(e)) -} - -// DataEntry represents a single piece of global state that is -// contained in this node. Entries are protected by a read-write lock -// in order to make sure that two different nodes trying to read -// from/write to the same piece of global state concurrently will not -// lead to inconsistencies in program execution (race conditions) -type DataEntry struct { - sync.RWMutex // protects access this entry - Value interface{} // value, which can be of any type - Owner string // address of the node that currently owns this entry -} - -// DataStore implements a volatile store that can be used to keep -// track of global state of applications compiled by PGo. State is -// modeled as a table that maps names (such as variable names) to -// values of any type, encapsulated as `DataEntry` structs. -type DataStore map[string]*DataEntry - -// NewDataStore creates a new `DataStore` struct. An initial state can -// be given in the `initValues` parameter, which makes sure the state -// local to this node will contain the data passed to this function. -func NewDataStore(initValues map[string]*DataEntry) DataStore { - return DataStore(initValues) -} - -// Lock gives the caller exclusive access to the entry associated with -// the given `name`. Blocks if another thread currently holds the -// lock. -func (store DataStore) Lock(name string) { - store.findOrPanic(name).Lock() -} - -// Unlock releases exclusive access previously held by `Lock()`. It is -// an error to call this function without a previous call to Lock(). -func (store DataStore) Unlock(name string) { - store.findOrPanic(name).Unlock() -} - -// GetVal returns the value associated with the name in the underlying -// store. Panics if the name does not exist. -func (store DataStore) GetVal(name string) interface{} { - return store.findOrPanic(name).Value -} - -// SetVal updates the value associated with a given `name` in the -// underlying store. Invoking this function is only safe if the -// caller has previously called Lock() on the same name. Panics if the -// name does not exist in the store. -func (store DataStore) SetVal(name string, val interface{}) { - store.findOrPanic(name).Value = val -} - -// OwnerOf returns the address of the node that is believed to own the -// given `name`. Panics if the name does not exist. -func (store DataStore) OwnerOf(name string) string { - return store.findOrPanic(name).Owner -} - -// UpdateOwner updates the address of the node that is believed to own -// the `name` given. Invoking this function is only safe if the caller -// has previously called Lock() on the same name. Panics if the name -// does not exist in the store. -func (store DataStore) UpdateOwner(name, owner string) { - store.findOrPanic(name).Owner = owner -} - -func (store DataStore) findOrPanic(name string) *DataEntry { - entry, inStore := store[name] - if !inStore { - log.Panic(NameNotFoundError(name)) - } - - return entry -} - -func (data DataStore) String() string { - var buf bytes.Buffer - var i int - - for name, entry := range data { - if i > 0 { - buf.WriteString(", ") - } - - buf.WriteString(fmt.Sprintf("%s => %v [%s]", name, entry.Value, entry.Owner)) - i++ - } - - return fmt.Sprintf("Store(%s)", buf.String()) -} diff --git a/distsys/data_store_test.go b/distsys/data_store_test.go deleted file mode 100644 index 59b19478a..000000000 --- a/distsys/data_store_test.go +++ /dev/null @@ -1,123 +0,0 @@ -package distsys - -import ( - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" - - "testing" -) - -var _ = Describe("DataStore", func() { - var ( - store DataStore - ) - - BeforeEach(func() { - store = NewDataStore(map[string]*DataEntry{ - "a": &DataEntry{Value: 10, Owner: "10.10.10.10"}, - "b": &DataEntry{Value: 20, Owner: "10.10.10.20"}, - "c": &DataEntry{Value: 30, Owner: "10.10.10.30"}, - }) - }) - - var _ = Describe("Lock", func() { - It("panics if the name given is not known", func() { - unknownName := func() { - store.Lock("unknown") - } - - Expect(unknownName).To(Panic()) - }) - - It("locks the entry with the name given", func() { - // name exists -- does not panic - store.Lock("a") - - // locks successfully -- now able to unlock - store.Unlock("a") - }) - }) - - var _ = Describe("Unlock", func() { - It("panics if the name given is not known", func() { - unknownName := func() { - store.Unlock("unknown") - } - - Expect(unknownName).To(Panic()) - }) - }) - - var _ = Describe("GetVal", func() { - It("panics if the name given is not known", func() { - unknownName := func() { - store.GetVal("unknown") - } - - Expect(unknownName).To(Panic()) - }) - - It("returns the value associated with an existing name", func() { - Expect(store.GetVal("a")).To(Equal(10)) - Expect(store.GetVal("b")).To(Equal(20)) - Expect(store.GetVal("c")).To(Equal(30)) - }) - }) - - var _ = Describe("SetVal", func() { - It("panics if the name given is not known", func() { - unknownName := func() { - store.SetVal("unknown", 40) - } - - Expect(unknownName).To(Panic()) - }) - - It("updates the value associated with an existing name", func() { - store.SetVal("a", 40) - - Expect(store.GetVal("a")).To(Equal(40)) - Expect(store.GetVal("b")).To(Equal(20)) - Expect(store.GetVal("c")).To(Equal(30)) - }) - }) - - var _ = Describe("OwnerOf", func() { - It("panics if the name given is not known", func() { - unknownName := func() { - store.OwnerOf("unknown") - } - - Expect(unknownName).To(Panic()) - }) - - It("returns the address of the owner of an existing name", func() { - Expect(store.OwnerOf("a")).To(Equal("10.10.10.10")) - Expect(store.OwnerOf("b")).To(Equal("10.10.10.20")) - Expect(store.OwnerOf("c")).To(Equal("10.10.10.30")) - }) - }) - - var _ = Describe("UpdateOwner", func() { - It("panics if the name given is not known", func() { - unknownName := func() { - store.UpdateOwner("unknown", "10.10.10.40") - } - - Expect(unknownName).To(Panic()) - }) - - It("updates the address of the owner of an existing name", func() { - store.UpdateOwner("a", "10.10.10.40") - - Expect(store.OwnerOf("a")).To(Equal("10.10.10.40")) - Expect(store.OwnerOf("b")).To(Equal("10.10.10.20")) - Expect(store.OwnerOf("c")).To(Equal("10.10.10.30")) - }) - }) -}) - -func TestDataStore(t *testing.T) { - RegisterFailHandler(Fail) - RunSpecs(t, "DataStore") -} diff --git a/distsys/distsys.go b/distsys/distsys.go deleted file mode 100644 index 22c4067bf..000000000 --- a/distsys/distsys.go +++ /dev/null @@ -1,612 +0,0 @@ -package distsys - -import ( - "github.com/mitchellh/hashstructure/v2" - - "bytes" - "encoding/gob" - "fmt" - "log" - "sort" - "strings" -) - -// UnknownOwnerError happens when a lookup for a certain piece of global -// state on the ownership table does not yield any result -type UnknownOwnerError struct { - name string -} - -func (e *UnknownOwnerError) Error() string { - return fmt.Sprintf("Ownership table lookup failed: no owner for variable %s", e.name) -} - -// BorrowSpec specifies a borrow request from a node to another. It includes a list -// of variables names for which exclusive access is required, as well as a list of -// names for which non-exclusive access is sufficient -type BorrowSpec struct { - ReadNames []string // which variables we are reading (non-exclusive access) - WriteNames []string // which variables we are writing (exclusive access) -} - -// BorrowSpecVariable represents a the borrowing requirements of a single variable -// within a `BorrowSpec` -type BorrowSpecVariable struct { - Name string - Exclusive bool -} - -func (specv *BorrowSpecVariable) String() string { - var exclusive string - if specv.Exclusive { - exclusive = " [exclusive]" - } - - return fmt.Sprintf("BorrowSpecVariable(%s%s)", specv.Name, exclusive) -} - -type SortedBorrowSpec []*BorrowSpecVariable - -func (sbs SortedBorrowSpec) String() string { - var buf bytes.Buffer - var i int - - for _, specv := range sbs { - if i > 0 { - buf.WriteString(", ") - } - - buf.WriteString(fmt.Sprintf("%v", specv)) - i++ - } - - return fmt.Sprintf("[%s]", buf.String()) -} - -func (spec SortedBorrowSpec) Len() int { - return len(spec) -} - -func (spec SortedBorrowSpec) Swap(i, j int) { - spec[i], spec[j] = spec[j], spec[i] -} - -func (spec SortedBorrowSpec) Less(i, j int) bool { - return strings.Compare(spec[i].Name, spec[j].Name) < 0 -} - -// Sorted returns a list of requested names in the borrow spec in alphabetical order. -func (spec *BorrowSpec) Sorted() SortedBorrowSpec { - // remove duplicates across read and write names - namesSet := map[string]bool{} - - for _, readVar := range spec.ReadNames { - namesSet[readVar] = true - } - - for _, writeVar := range spec.WriteNames { - namesSet[writeVar] = true - } - - names := []*BorrowSpecVariable{} - for name, _ := range namesSet { - writeVariable := false - - // if the current variable is a write-variable, access to - // it must be declared exclusive - for _, writeVar := range spec.WriteNames { - if writeVar == name { - writeVariable = true - break - } - } - - names = append(names, &BorrowSpecVariable{ - Name: name, - Exclusive: writeVariable, - }) - } - - sort.Sort(SortedBorrowSpec(names)) - return SortedBorrowSpec(names) -} - -func (spec *BorrowSpec) String() string { - return fmt.Sprintf("BorrowSpec[ReadNames=(%s) | WriteNames=(%s)]", - strings.Join(spec.ReadNames, ","), strings.Join(spec.WriteNames, ",")) -} - -// Reference represents a variable reference. It indicates the current variable -// value and whether the reference is exclusive (no other node has access to -// it, and allows the node to mutate the value). -type Reference struct { - Type int // the type of reference: REF_VAL or REF_MOVED - - // Used when Type == REF_VAL - Value interface{} // the value of a variable reference - Exclusive bool // whether access to this value is exclusive - Ownership bool // whether the ownership of the state is being moved with the reference - - // Used when Type == REF_MOVED - Peer string -} - -func (ref Reference) String() string { - var owns, exclusive, typeDesc string - if ref.Ownership { - owns = " [owns]" - } - - if ref.Exclusive { - exclusive = "*" - } - - if ref.Type == REF_VAL { - typeDesc = "VAL" - } else if ref.Type == REF_MOVED { - typeDesc = fmt.Sprintf("MOVED:%s", ref.Peer) - } else { - typeDesc = "SKIP" - } - - return fmt.Sprintf("Ref(%v%s%s (%s))", ref.Value, exclusive, owns, typeDesc) -} - -// VarReferences maps variable names to references. Can be used when a node is -// transferring state it knows about to another node in the system -type VarReferences map[string]*Reference - -// insert populates a VarReferences struct with a (potentially new) name -func (self VarReferences) insert(name string, ref *Reference) { - self[name] = ref -} - -// Set is used by clients when updating global state locally (once ownership of -// the global state has been acquired). Panics if the name given does not -// exist in the VarReferences struct (a situtation that could only happen if -// the developer makes changes to the generated source code) -func (self VarReferences) Set(name string, val interface{}) { - ref, found := self[name] - if !found { - log.Panicf("Attempt to set unknown variable: %s", name) - } - - ref.Value = val -} - -// Get is used by clients reading global state locally (once the running node -// has successfully borrowed or owns the given name). Panics if the name given -// does not exist in the VarReferences struct. -func (self VarReferences) Get(name string) interface{} { - if _, found := self[name]; !found { - log.Panicf("Attempt to get unknown variable: %s", name) - } - - return self[name].Value -} - -// Merge takes another VarReferences object and merges it with the receiver. -// Returns a new VarReferences struct that includes references from both objects -func (self VarReferences) Merge(other VarReferences) VarReferences { - // optimization: if the VarReferences passed as argument to this function - // does not contain any reference, just return the target unmodified - if len(other) == 0 { - return self - } - - newrefs := map[string]*Reference{} - - for name, ref := range self { - newrefs[name] = ref - } - - for name, ref := range other { - newrefs[name] = ref - } - - return VarReferences(newrefs) -} - -// ToBorrowSpec transforms a VarReferences struct into a corresponding BorrowSpec -// struct. The BorrowSpec struct returned contains the same names as the original -// VarReferences, with the same exclusive access rights. However, the translation -// is lossy -- values stored in VarReferences are not present in BorrowSpec. -func (self VarReferences) ToBorrowSpec() *BorrowSpec { - spec := BorrowSpec{ - ReadNames: []string{}, - WriteNames: []string{}, - } - - for name, ref := range self { - if ref.Exclusive { - spec.WriteNames = append(spec.WriteNames, name) - } else { - spec.ReadNames = append(spec.ReadNames, name) - } - } - - sort.Strings(spec.ReadNames) - sort.Strings(spec.WriteNames) - return &spec -} - -func (self VarReferences) String() string { - var buf bytes.Buffer - var i int - - for name, ref := range self { - if i > 0 { - buf.WriteString(", ") - } - - buf.WriteString(fmt.Sprintf("%s => %v", name, ref)) - i++ - } - - return fmt.Sprintf("VarReferences(%s)", buf.String()) -} - -// GlobalStateOperation represents an attempt to get access to a set of variables -// from the system's global state. Depending on which variables are requested and -// who owns each part of it, this struct is able to group variables together -// in order to minimize the number of requests necessary to get access to the -// state requested -type GlobalStateOperation struct { - spec *BorrowSpec - store DataStore - self string - connections *Connections - - ownerships []string - ackMigrationTo string -} - -// NewGlobalStateOperation returns a new instance of GlobalStateOperation for -// the borrow specification passed as argument. -func NewGlobalStateOperation(spec *BorrowSpec, store DataStore, self string, connections *Connections) *GlobalStateOperation { - readNames := make([]string, len(spec.ReadNames)) - writeNames := make([]string, len(spec.WriteNames)) - - // create an internal copy of the borrow spec being used since it is modified internally - // on calls to `UpdateRefs` - copy(readNames, spec.ReadNames) - copy(writeNames, spec.WriteNames) - specCopy := &BorrowSpec{ - ReadNames: readNames, - WriteNames: writeNames, - } - - return &GlobalStateOperation{ - spec: specCopy, - store: store, - self: self, - connections: connections, - - ownerships: []string{}, - } -} - -// Lock acquires exclusive access to all variables contained in the -// BorrowSpec -func (global *GlobalStateOperation) Lock() { - for _, borrowVar := range global.spec.Sorted() { - global.store.Lock(borrowVar.Name) - } -} - -// Unlock releases exclusive access, previously held with Lock(), to -// the variables in this BorrowSpec -func (global *GlobalStateOperation) Unlock() { - for _, borrowVar := range global.spec.Sorted() { - global.store.Unlock(borrowVar.Name) - } -} - -// UnlockExcept unlocks every variable in the BorrowSpec of the receiver -// except for the ones contained in the VarReq struct given as -// parameters. This is used when the caller wants to process a group -// of variables (owned by the same node) at a time. -func (global *GlobalStateOperation) UnlockExcept(req *VarReq) { - for _, borrowVar := range global.spec.Sorted() { - // if variable is in the group, skip - skip := false - for _, reqVar := range req.Names { - if reqVar.Name == borrowVar.Name { - skip = true - break - } - } - - if skip { - continue - } - - // if variable is not in the group, unlock it - global.store.Unlock(borrowVar.Name) - } -} - -// HasNext returns true when there are more variables to be processed -// (i.e., get a `REF_VALUE`) in the BorrowSpec passed on initialization -func (global *GlobalStateOperation) HasNext() bool { - return len(global.spec.ReadNames) > 0 || len(global.spec.WriteNames) > 0 -} - -// Next returns the next group of variables to be processed by -// the caller. Should be used before a call to `Next` is made. -func (global *GlobalStateOperation) Next() *VarReq { - return global.Groups()[0] -} - -// UpdateRefs updates the global state operation with a set of references -// obtained either from the local state handler, or from a remote node -// in the system. -func (global *GlobalStateOperation) UpdateRefs(refs VarReferences) VarReferences { - holds := VarReferences(map[string]*Reference{}) - - // Updating references for a new group -- clean any previously held - // data about past ownership moves. - global.ownerships = []string{} - global.ackMigrationTo = "" - - for name, ref := range refs { - switch ref.Type { - case REF_VAL: - if ref.Peer != global.self { - global.store.Lock(name) - } - - holds[name] = ref - - // if the ownership of this piece of state was transmitted with the - // reference itself, update our state accordingly - if ref.Ownership { - global.owns(name, ref) - } - - global.deleteFromSpec(name) - - case REF_MOVED: - // update ownership table - global.store.UpdateOwner(name, ref.Peer) - - case REF_SKIP: - // skip - } - } - - return holds -} - -// updates internal data structures when the reference given includes ownership -// of the state it contains -func (global *GlobalStateOperation) owns(name string, ref *Reference) { - global.store.UpdateOwner(name, global.self) - global.store.SetVal(name, ref.Value) - - // collect all ownerships gained - global.ownerships = append(global.ownerships, name) - global.ackMigrationTo = ref.Peer -} - -func (global *GlobalStateOperation) AckMigrations() { - if len(global.ownerships) == 0 { - return - } - - req := VarReq{Peer: global.self, Names: []*BorrowSpecVariable{}} - for _, name := range global.ownerships { - req.Names = append(req.Names, &BorrowSpecVariable{ - Name: name, - }) - } - - var ok bool - conn := global.connections.GetConnection(global.ackMigrationTo) - - if err := conn.Call("StateServer.OwnershipMoved", &req, &ok); err != nil { - log.Panic(err) - } -} - -func (global *GlobalStateOperation) deleteFromSpec(name string) { - deleted := global.deleteFromCollection(name, &global.spec.ReadNames) - deleted += global.deleteFromCollection(name, &global.spec.WriteNames) - - if deleted == 0 { - log.Panicf("Expected to find '%s' in borrow spec, but couldn't", name) - } -} - -// deleteFromCollection looks for the given `name` in the `collection` given, -// and removes it from the slice. Returns the number of elements deleted from -// the collection (i.e., 1 when the name is in the collection, 0 otherwise) -func (global *GlobalStateOperation) deleteFromCollection(name string, collection *[]string) int { - nameIndex := -1 - - for i, rname := range *collection { - if name == rname { - nameIndex = i - break - } - } - - if nameIndex == -1 { - return 0 - } - - (*collection)[nameIndex] = (*collection)[len(*collection)-1] - *collection = (*collection)[:len(*collection)-1] - - return 1 -} - -// Groups places the variables contained in a `BorrowSpec` in groupings that minimize -// the number of network calls necessary to get access to the global state required. -// Given the state of the ownership table at the time of call, this function will -// group variables based on ownership. -// -// Examples: -// ownershipTable := NewOwnershipTable(map[string]string{ -// "a": "10.10.10.1", -// "b": "10.10.10.1", -// "c": "10.10.10.3", -// }) -// -// borrowSpec := BorrowSpec{ -// ReadNames: []string{"a", "b", "c"}, -// WriteNames: []string{"b"}, -// } -// -// op := GlobalStateOperation(spec: &spec, ownership: ownershipTable) -// op.Groups() // => -// []*VarReq{ -// *VarReq{Peer: "10.10.10.1", Names: []*BorrowSpecVariable{{Name: "a", Exclusive: false}, ... }, -// *VarReq{Peer: "10.10.10.3", Names: []*BorrowSpecVariable{{Name: "c", Exclusive: false}, ...} -// } -func (global *GlobalStateOperation) Groups() []*VarReq { - reqs := []*VarReq{} - sorted := global.spec.Sorted() - - // if borrow spec is empty, return early - if len(sorted) == 0 { - return reqs - } - - var currentPeer string - var currVarReq *VarReq - for _, borrowVar := range sorted { - owner := global.store.OwnerOf(borrowVar.Name) - - // if this is the first iteration, the current peer is the owner - // of the current variable - if len(currentPeer) == 0 { - currentPeer = owner - currVarReq = &VarReq{ - Peer: currentPeer, - Names: []*BorrowSpecVariable{}, - } - } - - if owner == currentPeer { - currVarReq.Names = append(currVarReq.Names, borrowVar) - } else { - reqs = append(reqs, currVarReq) - - currentPeer = owner - currVarReq = &VarReq{ - Peer: currentPeer, - Names: []*BorrowSpecVariable{borrowVar}, - } - } - } - - // add last group to the list of requests - reqs = append(reqs, currVarReq) - - return reqs -} - -// VarReq represents a request to be sent to another peer in the system. It encapsulates -// the address of the peer as well as the pieces of state required from it -type VarReq struct { - Peer string // the node to which this request should be sent - Requester string // the node sending the request - Names []*BorrowSpecVariable // maps state names to whether exclusive access is required or not -} - -func (req *VarReq) String() string { - return fmt.Sprintf("VarReq(Peer=%s, Names=%s)", req.Peer, SortedBorrowSpec(req.Names).String()) -} - -// StateServer represents the current state of the global state at a given time, including -// all the information the running node currently stores, as well as ownership information -// for all pieces of global state -type StateServer struct { - *SyncBarrier - - self string // the address of the running node - configuration map[string]string // a map from processes to addresses of all peers in the system - store DataStore // the underlying state store - - migrationStrategy MigrationStrategy // determines when to migrate data from a node to another -} - -// StateServerRPC wraps the StateServer struct so that only a few methods are -// exposed as RPC methods to other peers in the network -type StateServerRPC struct { - server *StateServer -} - -// NewStateServer creates a new instance of the StateServer struct and sets up algorithm start -// across all peers in the system. This function can only be invoked once the addresses of all -// nodes in the system is known, as well as the initial values for every piece of global state -// in the system. This function will block until all other nodes in the system are also started -// and invoke their corresponding NewStateServer function on their ends. -func NewStateServer(configuration map[string]string, address, coordinator string, initValues map[string]interface{}, migration MigrationStrategy) (*StateServer, error) { - barrier := NewSyncBarrier(configuration, NewConnections(address), address, coordinator) - - foundAddress := false - foundCoordinator := false - for _, addr := range configuration { - if addr == address { - foundAddress = true - } - - if addr == coordinator { - foundCoordinator = true - } - } - // Make sure `address` and `coordinator` are in the list of peers - if !foundAddress { - panic("given address is not in system configuration") - } - if !foundCoordinator { - panic("coodinator is not in system configuration") - } - - entries := map[string]*DataEntry{} - - // at first, all state is owned by the coordinator node - for name, _ := range initValues { - var val interface{} - if barrier.isCoordinator() { - val = initValues[name] - } - - entries[name] = &DataEntry{Value: val, Owner: coordinator} - } - - stateServer := &StateServer{ - SyncBarrier: barrier, - - self: address, - configuration: configuration, - store: NewDataStore(entries), - - migrationStrategy: migration, - } - - if err := stateServer.connections.ExposeImplementation("StateServer", &StateServerRPC{stateServer}); err != nil { - return nil, err - } - - return stateServer, nil -} - -// DefineCustomType allows the appplication to use user-defined types -// (e.g., Go structs) when communicating with other processes compiled -// by PGo. -func DefineCustomType(value interface{}) { - gob.Register(value) -} - -// Hash returns a uint64 representation for arbitrary data types. -func Hash(value interface{}) uint64 { - result, err := hashstructure.Hash(value, hashstructure.FormatV2, nil) - if err != nil { - panic(fmt.Sprintf("Cannot hash value: %v", value)) - } - - return result -} diff --git a/distsys/distsys_test.go b/distsys/distsys_test.go deleted file mode 100644 index 1a9b88498..000000000 --- a/distsys/distsys_test.go +++ /dev/null @@ -1,325 +0,0 @@ -package distsys - -import ( - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" - - "testing" -) - -var _ = Describe("Distsys package", func() { - var ( - store DataStore - self = "10.10.10.1" - ) - - BeforeEach(func() { - store = NewDataStore(map[string]*DataEntry{ - "a": &DataEntry{Owner: "10.10.10.10"}, - "b": &DataEntry{Owner: "10.10.10.20"}, - "c": &DataEntry{Owner: "10.10.10.30"}, - }) - }) - - var _ = Describe("BorrowSpec", func() { - Context("Sorting entries", func() { - It("Sorts an empty spec", func() { - spec := BorrowSpec{ - ReadNames: []string{}, - WriteNames: []string{}, - } - - sorted := spec.Sorted() - Expect(len(sorted)).To(Equal(0)) - }) - - It("Sorts disjoint read and write names", func() { - spec := BorrowSpec{ - ReadNames: []string{"a", "c"}, - WriteNames: []string{"d", "b"}, - } - - sorted := spec.Sorted() - Expect(len(sorted)).To(Equal(4)) - - Expect(sorted[0].Name).To(Equal("a")) - Expect(sorted[0].Exclusive).To(Equal(false)) - - Expect(sorted[1].Name).To(Equal("b")) - Expect(sorted[1].Exclusive).To(Equal(true)) - - Expect(sorted[2].Name).To(Equal("c")) - Expect(sorted[2].Exclusive).To(Equal(false)) - - Expect(sorted[3].Name).To(Equal("d")) - Expect(sorted[3].Exclusive).To(Equal(true)) - }) - - It("Sorts read and write names with non-empty intersections", func() { - spec := BorrowSpec{ - ReadNames: []string{"b", "a"}, - WriteNames: []string{"c", "b"}, - } - - sorted := spec.Sorted() - Expect(len(sorted)).To(Equal(3)) - - Expect(sorted[0].Name).To(Equal("a")) - Expect(sorted[0].Exclusive).To(Equal(false)) - - Expect(sorted[1].Name).To(Equal("b")) - Expect(sorted[1].Exclusive).To(Equal(true)) - - Expect(sorted[2].Name).To(Equal("c")) - Expect(sorted[2].Exclusive).To(Equal(true)) - }) - }) - }) - - var _ = Describe("GlobalStateOperation", func() { - Context("Grouping variables", func() { - It("panics if Next() is called on an empty spec", func() { - op := NewGlobalStateOperation(&BorrowSpec{}, store, self, nil) - - getNext := func() { - op.Next() - } - - Expect(op.HasNext()).To(Equal(false)) - Expect(getNext).To(Panic()) - }) - - It("Groups a spec where no grouping is possible", func() { - spec := &BorrowSpec{ReadNames: []string{"a", "b", "c"}, WriteNames: []string{"b"}} - op := NewGlobalStateOperation(spec, store, self, nil) - - groups := op.Groups() - Expect(len(groups)).To(Equal(3)) - - Expect(groups[0].Peer).To(Equal("10.10.10.10")) - Expect(len(groups[0].Names)).To(Equal(1)) - Expect(groups[0].Names[0].Name).To(Equal("a")) - Expect(groups[0].Names[0].Exclusive).To(Equal(false)) - - Expect(groups[1].Peer).To(Equal("10.10.10.20")) - Expect(len(groups[1].Names)).To(Equal(1)) - Expect(groups[1].Names[0].Name).To(Equal("b")) - Expect(groups[1].Names[0].Exclusive).To(Equal(true)) - - Expect(groups[2].Peer).To(Equal("10.10.10.30")) - Expect(len(groups[2].Names)).To(Equal(1)) - Expect(groups[2].Names[0].Name).To(Equal("c")) - Expect(groups[2].Names[0].Exclusive).To(Equal(false)) - }) - - It("Groups a spec where some grouping of variables is possible", func() { - spec := &BorrowSpec{ReadNames: []string{"a", "b", "c"}, WriteNames: []string{"b"}} - op := NewGlobalStateOperation(spec, store, self, nil) - - // co-locate variables 'a' and 'b' - store.UpdateOwner("b", store.OwnerOf("a")) - - groups := op.Groups() - Expect(len(groups)).To(Equal(2)) - - // group 1: 'a' (non-exclusive) and 'b' (exclusive) - Expect(groups[0].Peer).To(Equal("10.10.10.10")) - Expect(len(groups[0].Names)).To(Equal(2)) - Expect(groups[0].Names[0].Name).To(Equal("a")) - Expect(groups[0].Names[0].Exclusive).To(Equal(false)) - Expect(groups[0].Names[1].Name).To(Equal("b")) - Expect(groups[0].Names[1].Exclusive).To(Equal(true)) - - // group 2: 'c' (non-exclusive) - Expect(groups[1].Peer).To(Equal("10.10.10.30")) - Expect(len(groups[1].Names)).To(Equal(1)) - Expect(groups[1].Names[0].Name).To(Equal("c")) - Expect(groups[1].Names[0].Exclusive).To(Equal(false)) - }) - - It("Groups a spec where every variable is owned by the same peer", func() { - spec := &BorrowSpec{ReadNames: []string{"a", "b", "c"}, WriteNames: []string{"b"}} - op := NewGlobalStateOperation(spec, store, self, nil) - - // co-locate variables 'a', 'b' and 'c' - store.UpdateOwner("b", store.OwnerOf("a")) - store.UpdateOwner("c", store.OwnerOf("a")) - - groups := op.Groups() - Expect(len(groups)).To(Equal(1)) - - Expect(groups[0].Peer).To(Equal("10.10.10.10")) - Expect(len(groups[0].Names)).To(Equal(3)) - - Expect(groups[0].Names[0].Name).To(Equal("a")) - Expect(groups[0].Names[0].Exclusive).To(Equal(false)) - - Expect(groups[0].Names[1].Name).To(Equal("b")) - Expect(groups[0].Names[1].Exclusive).To(Equal(true)) - - Expect(groups[0].Names[2].Name).To(Equal("c")) - Expect(groups[0].Names[2].Exclusive).To(Equal(false)) - }) - }) - - var _ = Describe("UpdateRefs", func() { - It("Detects no more variables are left if all references are present", func() { - spec := &BorrowSpec{ReadNames: []string{"a", "b", "c"}, WriteNames: []string{"b"}} - op := NewGlobalStateOperation(spec, store, self, nil) - - refs := VarReferences(map[string]*Reference{ - "a": &Reference{Type: REF_VAL, Value: 10}, - "b": &Reference{Type: REF_VAL, Value: 20}, - "c": &Reference{Type: REF_VAL, Value: 30}, - }) - - holds := op.UpdateRefs(refs) - Expect(holds).To(Equal(refs)) - - Expect(op.HasNext()).To(Equal(false)) - }) - - It("Updates the ownership table when a moved references are received", func() { - spec := &BorrowSpec{ReadNames: []string{"a", "b", "c"}, WriteNames: []string{"b"}} - op := NewGlobalStateOperation(spec, store, self, nil) - - refs := VarReferences(map[string]*Reference{ - "a": &Reference{Type: REF_VAL, Value: 10}, - "b": &Reference{Type: REF_MOVED, Peer: "10.10.10.10"}, - "c": &Reference{Type: REF_MOVED, Peer: "10.10.10.10"}, - }) - - holds := op.UpdateRefs(refs) - Expect(len(holds)).To(Equal(1)) - - Expect(holds).To(Equal(VarReferences(map[string]*Reference{ - "a": &Reference{Type: REF_VAL, Value: 10}, - }))) - - Expect(op.HasNext()).To(Equal(true)) - Expect(op.Next()).To(Equal(&VarReq{ - Peer: "10.10.10.10", - Names: []*BorrowSpecVariable{ - &BorrowSpecVariable{Name: "b", Exclusive: true}, - &BorrowSpecVariable{Name: "c", Exclusive: false}, - }, - })) - }) - - It("updates the ownership table and local store when ownership is received", func() { - spec := &BorrowSpec{ReadNames: []string{"a", "b", "c"}, WriteNames: []string{"b"}} - op := NewGlobalStateOperation(spec, store, self, nil) - - refs := VarReferences(map[string]*Reference{ - "a": &Reference{Type: REF_VAL, Value: 10, Ownership: true, Peer: "10.10.10.40"}, - "b": &Reference{Type: REF_MOVED, Peer: "10.10.10.10"}, - "c": &Reference{Type: REF_SKIP}, - }) - - holds := op.UpdateRefs(refs) - Expect(len(holds)).To(Equal(1)) - - Expect(holds).To(Equal(VarReferences(map[string]*Reference{ - "a": &Reference{Type: REF_VAL, Value: 10, Ownership: true, Peer: "10.10.10.40"}, - }))) - - Expect(op.HasNext()).To(Equal(true)) - Expect(op.Next()).To(Equal(&VarReq{ - Peer: "10.10.10.10", - Names: []*BorrowSpecVariable{ - &BorrowSpecVariable{Name: "b", Exclusive: true}, - }, - })) - - // updates the ownership table to indicate that the current node - // now owns variable 'a' - Expect(store.OwnerOf("a")).To(Equal(self)) - - // updates the local store with the value received - Expect(store.GetVal("a")).To(Equal(10)) - - // has a list of variables to acknowledge ownership about - Expect(op.ownerships).To(Equal([]string{"a"})) - }) - }) - }) - - var _ = Describe("VarReferences", func() { - It("updates its contents", func() { - refs := VarReferences(map[string]*Reference{ - "a": &Reference{Value: "old", Exclusive: true}, - }) - - refs.Set("a", "new") - - Expect(refs).To(Equal(VarReferences(map[string]*Reference{ - "a": &Reference{Value: "new", Exclusive: true}, - }))) - }) - - It("gets the correct content", func() { - refs := VarReferences(map[string]*Reference{ - "a": &Reference{Value: "old", Exclusive: true}, - }) - - s := refs.Get("a").(string) - - Expect(refs).To(Equal(VarReferences(map[string]*Reference{ - "a": &Reference{Value: "old", Exclusive: true}, - }))) - - Expect(s).To(Equal("old")) - }) - - var _ = Describe("Merge", func() { - var target VarReferences - - BeforeEach(func() { - target = VarReferences(map[string]*Reference{ - "a": &Reference{Value: "refs1:a", Exclusive: true}, - "b": &Reference{Value: "refs1:b", Exclusive: false}, - }) - }) - - It("Merges with an empty VarReferences", func() { - other := VarReferences(map[string]*Reference{}) - - Expect(target.Merge(other)).To(Equal(target)) - }) - - It("is able to merge with another VarReferences", func() { - other := VarReferences(map[string]*Reference{ - "b": &Reference{Value: "refs2:b", Exclusive: true}, - }) - - Expect(target.Merge(other)).To(Equal(VarReferences(map[string]*Reference{ - "a": &Reference{Value: "refs1:a", Exclusive: true}, - "b": &Reference{Value: "refs2:b", Exclusive: true}, - }))) - }) - }) - - It("is able to generate a corresponding BorrowSpec", func() { - refs := VarReferences(map[string]*Reference{ - "c": &Reference{Value: []int{1, 2, 3}, Exclusive: true}, - "a": &Reference{Value: 10, Exclusive: false}, - "b": &Reference{Value: "PGo", Exclusive: true}, - }) - - spec := refs.ToBorrowSpec() - - Expect(len(spec.ReadNames)).To(Equal(1)) - Expect(spec.ReadNames[0]).To(Equal("a")) - - Expect(len(spec.WriteNames)).To(Equal(2)) - Expect(spec.WriteNames[0]).To(Equal("b")) - Expect(spec.WriteNames[1]).To(Equal("c")) - }) - }) - -}) - -func TestDistsys(t *testing.T) { - RegisterFailHandler(Fail) - RunSpecs(t, "Distsys") -} diff --git a/distsys/etcd.go b/distsys/etcd.go deleted file mode 100644 index cbbef9aef..000000000 --- a/distsys/etcd.go +++ /dev/null @@ -1,189 +0,0 @@ -package distsys - -// Implements the etcd global state management API. -// -// Currently, PGo manages global state in a distributed environment by using the -// `etcd' key-value store. The functions defined here wrap that behaviour by providing -// a get/set interface so that if ever the way that we store global variables change, -// our API (and the code generated by the compiler) may hopefully stay the same. -// -// Usage: -// -// import ( -// "fmt" -// "pgo/distsys" -// ) -// -// config := &Config{ -// Endpoints: []string{"10.0.0.1:1234", "10.0.0.2:1234"}, -// Timeout: 3, -// } -// state, err := distsys.InitEtcdState(config) -// if err != nil { -// // handle error -// } -// -// state.Set("project", "PGo") -// val := state.GetString("project") -// fmt.Printf("project value has value: %s\n", val) // project has value: PGo -// -// // Integers are also supported -// state.Set("count", 42) -// count := state.Get("count") -// fmt.Printf("count has value: %d\n", count) // count has value: 42 -// -// // so are collections -// col := []string{"1", "2", "3"} -// state.Set("collection", col) -// col = state.GetStringCollection("collection") - -// Implementation Details -// -// Global variables are stored in `etcd' as name => hex-encoded string of a gob. -// -// This representation is internal and applications need not know about it. - -import ( - "bytes" - "context" - "encoding/gob" - "encoding/hex" - "fmt" - "time" - - etcd "go.etcd.io/etcd/client/v2" -) - -// declares the types of global variables supported by PGo at the moment. -const ( - LOCK_NAMESPACE = "/locks/" -) - -// A reference to our global state, created via +InitEtcdState+. Used in the -// generated Go code to set and get the values of global variables. -type EtcdState struct { - *SyncBarrier - c etcd.Client - kv etcd.KeysAPI -} - -// Initializes centralized global state management. -// -// The 'centralized' global state strategy uses the etcd server (or -// collection of servers). It uses the etcd key-value store. -// -// Returns a reference to `distsys.EtcdState' on success. Fails if we -// cannot establish a connection to the etcd cluster. -func NewEtcdState(endpoints []string, timeout int, configuration map[string]string, address, coordinator string, initValues map[string]interface{}) (*EtcdState, error) { - c, err := etcd.New(etcd.Config{ - Endpoints: endpoints, - HeaderTimeoutPerRequest: time.Duration(timeout) * time.Second, - }) - if err != nil { - return nil, err - } - - ret := &EtcdState{ - NewSyncBarrier(configuration, NewConnections(address), address, coordinator), - c, - etcd.NewKeysAPI(c), - } - - if ret.isCoordinator() && len(initValues) > 0 { - for name, val := range initValues { - ret.Set(name, val) - } - } - - return ret, nil -} - -// Sets variable `name' to a given `value'. Contacts the global variable server -// *synchronously* -func (self *EtcdState) Set(name string, value interface{}) { - buffer := bytes.Buffer{} - encoder := gob.NewEncoder(&buffer) - err := encoder.Encode(value) - if err != nil { - panic(fmt.Sprintf("Unable to GobEncode %v, err = %s", value, err.Error())) - } - s := hex.EncodeToString(buffer.Bytes()) - key := prepareKey(name) - _, err = self.kv.Set(context.Background(), key, s, nil) - if err != nil { - panic(fmt.Sprintf("Unable to set %s to %s, err = %s", key, s, err)) - } -} - -// indicates whether a variable with the given name was previously set. -// Caller must hold a lock before invoking this function if behavior following -// its return lies within a critical section -func (self *EtcdState) Exists(name string) bool { - _, err := self.kv.Get(context.Background(), prepareKey(name), nil) - if err != nil { - etcdErr := err.(etcd.Error) - if etcdErr.Code == etcd.ErrorCodeKeyNotFound { - return false - } - - panic(err) - } - - return true -} - -// Gets the value associated with a variable with the given `name'. Contacts -// the global variable server *synchronously*. -func (self *EtcdState) Get(name string, variable interface{}) interface{} { - key := prepareKey(name) - response, err := self.kv.Get(context.Background(), key, nil) - if err != nil { - panic(fmt.Sprintf("Unable to get %s, err = %s", key, err.Error())) - } - - buffer, err := hex.DecodeString(response.Node.Value) - if err != nil { - panic(fmt.Sprintf("Unable to hex.Decode %s, err = %s", response.Node.Value, err.Error())) - } - - decoder := gob.NewDecoder(bytes.NewReader(buffer)) - err = decoder.Decode(variable) - if err != nil { - panic(fmt.Sprintf("Unable to GobDecode %v, err = %s", buffer, err.Error())) - } - - return variable -} - -func (self *EtcdState) Lock(who, which string) { - key := prepareLock(which) - for { - _, err := self.kv.Create(context.Background(), key, who) - etcdErr, ok := err.(etcd.Error) - if err == nil { - return - } - if !ok || etcdErr.Code != etcd.ErrorCodeNodeExist { - panic(err) - } - } -} - -func (self *EtcdState) Unlock(who, which string) { - _, err := self.kv.Delete(context.Background(), prepareLock(which), &etcd.DeleteOptions{ - PrevValue: who, - }) - if err != nil { - panic(err) - } -} - -// given a key k, this method transforms it to the format expected by `etcd' -func prepareKey(k string) string { - return "/" + k -} - -// given a lock k, this method transforms it to the format expected by `etcd' -func prepareLock(k string) string { - return LOCK_NAMESPACE + k -} diff --git a/distsys/go.mod b/distsys/go.mod index 3ac273bd9..ae17345ab 100644 --- a/distsys/go.mod +++ b/distsys/go.mod @@ -2,10 +2,4 @@ module github.com/UBC-NSS/pgo/distsys go 1.14 -require ( - github.com/benbjohnson/immutable v0.3.0 - github.com/mitchellh/hashstructure/v2 v2.0.1 - github.com/onsi/ginkgo v1.16.2 - github.com/onsi/gomega v1.12.0 - go.etcd.io/etcd/client/v2 v2.305.0-beta.3 -) +require github.com/benbjohnson/immutable v0.3.0 diff --git a/distsys/go.sum b/distsys/go.sum index b1c34bccb..d8fec35cd 100644 --- a/distsys/go.sum +++ b/distsys/go.sum @@ -1,198 +1,2 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/benbjohnson/immutable v0.3.0 h1:TVRhuZx2wG9SZ0LRdqlbs9S5BZ6Y24hJEHTCgWHZEIw= github.com/benbjohnson/immutable v0.3.0/go.mod h1:uc6OHo6PN2++n98KHLxW8ef4W42ylHiQSENghE1ezxI= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= -github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd/v22 v22.3.1/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= -github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= -github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68= -github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/mitchellh/hashstructure/v2 v2.0.1 h1:L60q1+q7cXE4JeEJJKMnh2brFIe3rZxCihYAB61ypAY= -github.com/mitchellh/hashstructure/v2 v2.0.1/go.mod h1:MG3aRVU/N29oo/V/IhBX8GR/zz4kQkprJgF2EVszyDE= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= -github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.16.2 h1:HFB2fbVIlhIfCfOW81bZFbiC/RvnpXSdhbF2/DJr134= -github.com/onsi/ginkgo v1.16.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E= -github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.12.0 h1:p4oGGk2M2UJc0wWN4lHFvIB71lxsh0T/UiKCCgFADY8= -github.com/onsi/gomega v1.12.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.etcd.io/etcd/api/v3 v3.5.0-beta.3 h1:FdNjTxZpH98oWWTtOjhz0EU7sILw9giVIW+M3dzZFOg= -go.etcd.io/etcd/api/v3 v3.5.0-beta.3/go.mod h1:yF0YUmBghT48aC0/eTFrhULo+uKQAr5spQQ6sRhPauE= -go.etcd.io/etcd/client/pkg/v3 v3.5.0-beta.3 h1:fh2cSzLD4OeGVy164WtilS9hAQYmQ2BC6Fh/akRR1b0= -go.etcd.io/etcd/client/pkg/v3 v3.5.0-beta.3/go.mod h1:a+pbz+UrcOpvve1Qxf6tGovi15PjgtRhi0QTO2Nlc4U= -go.etcd.io/etcd/client/v2 v2.305.0-beta.3 h1:tYAN7hKzGE6dDjdgZqRCwXLMwaSliWJ/CZmxhYz73Yc= -go.etcd.io/etcd/client/v2 v2.305.0-beta.3/go.mod h1:sWZG9/Oa2nspIl/4MBllUgm25QoQYNiuek6xCXTdEj8= -go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/zap v1.16.1-0.20210329175301-c23abee72d19/go.mod h1:aMfIlz3TDBfB0BwTCKFU1XbEmj9zevr5S5LcBr85MXw= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 h1:DzZ89McO9/gWPsQXS/FVKAlG02ZjaQ6AlZRBimEYOd0= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da h1:b3NXsE2LusjYGGjL5bxEVZZORm/YEFFrWFjR8eFrw/c= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= -google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/distsys/mpcal.go b/distsys/mpcal.go deleted file mode 100644 index 2f04a1116..000000000 --- a/distsys/mpcal.go +++ /dev/null @@ -1,231 +0,0 @@ -package distsys - -import ( - "errors" - "fmt" -) - -var ErrAssertionFailed = errors.New("assertion failed") - -type ArchetypeResourceHandle struct { - Tag int - Index int - Name string -} - -const ( - ArchetypeResourceNamedTag = iota - ArchetypeResourceIndexedTag -) - -type MPCalDurableStorageRecord struct { - Resources []ArchetypeResource - Frame int - FrameStack []int - ResourcesByName map[string]ArchetypeResource - CommitPending map[ArchetypeResourceHandle]bool -} - -func (record *MPCalDurableStorageRecord) getResourceByHandle(handle ArchetypeResourceHandle) ArchetypeResource { - switch handle.Tag { - case ArchetypeResourceNamedTag: - return record.ResourcesByName[handle.Name] - case ArchetypeResourceIndexedTag: - return record.Resources[handle.Index] - default: - panic(fmt.Errorf("could not find archetype resource by handle %v", handle)) - } -} - -type MPCalDurableStorage interface { - RecoverResources() (rec *MPCalDurableStorageRecord, err error) - SnapshotResources(rec *MPCalDurableStorageRecord) -} - -type MPCalContext struct { - durableStorage MPCalDurableStorage - record MPCalDurableStorageRecord -} - -func NewMPCalContext(durableStorage MPCalDurableStorage) (*MPCalContext, error) { - record, err := durableStorage.RecoverResources() - if err != nil { - return nil, err - } - if record == nil { - record = &MPCalDurableStorageRecord{ - ResourcesByName: make(map[string]ArchetypeResource), - } - } - if record.CommitPending != nil { - var nonTrivialOutstandingCommits []chan struct{} - for resHandle := range record.CommitPending { - ch := record.getResourceByHandle(resHandle).Commit() - if ch != nil { - nonTrivialOutstandingCommits = append(nonTrivialOutstandingCommits, ch) - } - } - for _, ch := range nonTrivialOutstandingCommits { - <-ch - } - for resHandle := range record.CommitPending { - delete(record.CommitPending, resHandle) - } - durableStorage.SnapshotResources(record) - } - return &MPCalContext{ - durableStorage: durableStorage, - record: *record, - }, nil -} - -type MPCalContextArchetypeConfigFn func(durability MPCalDurableStorage, resource ArchetypeResource) - -type MPCalContextResourceEnsurer func(blank ArchetypeResource, configFn func(resource ArchetypeResource)) ArchetypeResourceHandle - -func (ctx *MPCalContext) ResourceEnsurerByName(name string) MPCalContextResourceEnsurer { - return func(blank ArchetypeResource, configFn func(ArchetypeResource)) ArchetypeResourceHandle { - resource, ok := ctx.record.ResourcesByName[name] - if !ok { - ctx.record.ResourcesByName[name] = blank - resource = blank - } - configFn(resource) - return ArchetypeResourceHandle{ - Tag: ArchetypeResourceNamedTag, - Name: name, - } - } -} - -func (ctx *MPCalContext) ResourceEnsurerPositional() MPCalContextResourceEnsurer { - return func(blank ArchetypeResource, configFn func(ArchetypeResource)) ArchetypeResourceHandle { - var resource ArchetypeResource - if ctx.record.Frame == len(ctx.record.Resources) { - resource = blank - ctx.record.Resources = append(ctx.record.Resources, blank) - } else { - resource = ctx.record.Resources[ctx.record.Frame] - } - configFn(resource) - resourcePosition := ctx.record.Frame - ctx.record.Frame += 1 - return ArchetypeResourceHandle{ - Tag: ArchetypeResourceIndexedTag, - Index: resourcePosition, - } - } -} - -func (ctx *MPCalContext) PositionalResourceStackPush() { - ctx.record.FrameStack = append(ctx.record.FrameStack, ctx.record.Frame) -} - -func (ctx *MPCalContext) PositionalResourceStackPop() { - ctx.record.Frame = ctx.record.FrameStack[len(ctx.record.FrameStack)-1] - ctx.record.FrameStack = ctx.record.FrameStack[:len(ctx.record.FrameStack)-1] - ctx.record.Resources = ctx.record.Resources[:ctx.record.Frame] -} - -func (ctx *MPCalContext) Abort() { - if ctx.record.CommitPending == nil { - return - } - var nonTrivialAborts []chan struct{} - for resHandle := range ctx.record.CommitPending { - ch := ctx.record.getResourceByHandle(resHandle).Abort() - if ch != nil { - nonTrivialAborts = append(nonTrivialAborts, ch) - } - } - for _, ch := range nonTrivialAborts { - <-ch - } - - // clear any touched resources (compiler will optimise this, see https://golang.org/doc/go1.11#performance-compiler) - for resHandle := range ctx.record.CommitPending { - delete(ctx.record.CommitPending, resHandle) - } -} - -func (ctx *MPCalContext) Commit() (err error) { - if ctx.record.CommitPending == nil { - return // in the unlikely event this is reachable, skip it - } - - // dispatch all parts of the pre-commit phase asynchronously, so we only wait as long as the slowest resource - var nonTrivialPreCommits []chan error - for resHandle := range ctx.record.CommitPending { - ch := ctx.record.getResourceByHandle(resHandle).PreCommit() - if ch != nil { - nonTrivialPreCommits = append(nonTrivialPreCommits, ch) - } - } - for _, ch := range nonTrivialPreCommits { - localErr := <-ch - if localErr != nil { - err = localErr - } - } - - // if there was an error, stop now, and expect either (1) total crash of (2) Abort to be called - if err != nil { - return - } - - // we commit to committing, so apply any durable persistence here, so we recover to this point if we crash - ctx.durableStorage.SnapshotResources(&ctx.record) - - // same as above, run all the commit processes async - var nonTrivialCommits []chan struct{} - for resHandle := range ctx.record.CommitPending { - ch := ctx.record.getResourceByHandle(resHandle).Commit() - if ch != nil { - nonTrivialCommits = append(nonTrivialCommits, ch) - } - } - for _, ch := range nonTrivialCommits { - <-ch - } - - // if we have not crashed, we successfully committed everything, so snapshot state again, but without - // the in-progress commit, as we are done. - for resHandle := range ctx.record.CommitPending { - delete(ctx.record.CommitPending, resHandle) - } - ctx.durableStorage.SnapshotResources(&ctx.record) - return -} - -func (ctx *MPCalContext) ensureCriticalSectionWith(handle ArchetypeResourceHandle) { - if ctx.record.CommitPending == nil { - ctx.record.CommitPending = make(map[ArchetypeResourceHandle]bool) - } - ctx.record.CommitPending[handle] = true -} - -func (ctx *MPCalContext) Write(handle ArchetypeResourceHandle, indices []TLAValue, value TLAValue) (err error) { - ctx.ensureCriticalSectionWith(handle) - res := ctx.record.getResourceByHandle(handle) - for _, index := range indices { - res, err = res.Index(index) - if err != nil { - return - } - } - err = res.WriteValue(value) - return -} - -func (ctx *MPCalContext) Read(handle ArchetypeResourceHandle, indices []TLAValue) (value TLAValue, err error) { - ctx.ensureCriticalSectionWith(handle) - res := ctx.record.getResourceByHandle(handle) - for _, index := range indices { - res, err = res.Index(index) - if err != nil { - return - } - } - value, err = res.ReadValue() - return -} diff --git a/distsys/mpcal_context.go b/distsys/mpcal_context.go new file mode 100644 index 000000000..364d29c64 --- /dev/null +++ b/distsys/mpcal_context.go @@ -0,0 +1,217 @@ +package distsys + +import ( + "errors" + "fmt" + "github.com/benbjohnson/immutable" +) + +var ErrAssertionFailed = errors.New("assertion failed") + +var ErrCriticalSectionAborted = errors.New("MPCal critical section aborted") + +// ArchetypeResourceHandle encapsulates a reference to an ArchetypeResource. +// These handles insulate the end-user from worrying about the specifics of resource lifetimes, logging, and +// crash recovery scenarios. +type ArchetypeResourceHandle struct { + path TLAValue +} + +// ArchetypeResourceMaker encapsulates how a specific kind of ArchetypeResource is created. +// At its simplest, Make() should produce a fresh instance, and Configure will then be called on that instance +// in order to do any further configuration to it. +// This two-step process anticipates situations where the ArchetypeResource has been e.g reloaded from disk +// during crash recovery, but might still need some configuration (setting up any function objects, user-provided Go channels). +type ArchetypeResourceMaker interface { + Make() ArchetypeResource + Configure(res ArchetypeResource) +} + +// ArchetypeResourceMakerFn short-cuts the common case where there is no Configure step. +// It implements that step as a no-op, while wrapping an ArchetypeResource-creating function. +type ArchetypeResourceMakerFn func() ArchetypeResource + +var _ ArchetypeResourceMaker = new(ArchetypeResourceMakerFn) + +func (mkFunc ArchetypeResourceMakerFn) Make() ArchetypeResource { + return mkFunc() +} + +func (mkFunc ArchetypeResourceMakerFn) Configure(ArchetypeResource) { + // pass +} + +// ArchetypeResourceMakerStruct aims to handle anything ArchetypeResourceMakerFn can't. +// It provides full customisation of both steps. +type ArchetypeResourceMakerStruct struct { + MakeFn func() ArchetypeResource + ConfigureFn func(res ArchetypeResource) +} + +var _ ArchetypeResourceMaker = ArchetypeResourceMakerStruct{} + +func (mkStruct ArchetypeResourceMakerStruct) Make() ArchetypeResource { + return mkStruct.MakeFn() +} + +func (mkStruct ArchetypeResourceMakerStruct) Configure(res ArchetypeResource) { + mkStruct.ConfigureFn(res) +} + +// MPCalContext manages the internal lifecycle of a compiled MPCal model's execution. +// This includes: +// - currently stub-level stack frame management +// - critical section semantics +// - resource lifecycle management, which may eventually include logging and crash recovery +type MPCalContext struct { + resources *immutable.Map + + // stack-related fields + pathBase TLAValue + frameIdx int + frameStack [][]ArchetypeResourceHandle + + dirtyResourceHandles []ArchetypeResourceHandle +} + +func NewMPCalContext() *MPCalContext { + return &MPCalContext{ + resources: immutable.NewMap(TLAValueHasher{}), + + pathBase: NewTLATuple(), + frameIdx: 0, + frameStack: [][]ArchetypeResourceHandle{{}}, + } +} + +func (ctx *MPCalContext) EnsureArchetypeResourceByName(name string, maker ArchetypeResourceMaker) ArchetypeResourceHandle { + handle := ArchetypeResourceHandle{ + path: NewTLAString(name), + } + // this (currently unreachable) case accounts for a recovery situation, where the desired resource already exists + if res, ok := ctx.resources.Get(handle.path); ok { + maker.Configure(res.(ArchetypeResource)) + return handle + } + res := maker.Make() + maker.Configure(res) + ctx.resources = ctx.resources.Set(handle.path, res) + return handle +} + +func (ctx *MPCalContext) EnsureArchetypeResourceByPosition(maker ArchetypeResourceMaker) ArchetypeResourceHandle { + frame := ctx.frameStack[len(ctx.frameStack)-1] + handle := ArchetypeResourceHandle{ + path: TLA_Append(ctx.pathBase, NewTLATuple(NewTLANumber(int32(ctx.frameIdx)))), + } + + // this (currently unreachable) case accounts for a recovery situation, where the desired resource is already in place + if ctx.frameIdx < len(frame) { + maker.Configure(ctx.getResourceByHandle(frame[ctx.frameIdx])) + ctx.frameIdx += 1 + return handle + } + + // without recovery, we push + setup a fresh resource + ctx.frameIdx += 1 + ctx.frameStack[len(ctx.frameStack)-1] = append(frame, handle) + res := maker.Make() + maker.Configure(res) + ctx.resources = ctx.resources.Set(handle.path, res) + return handle +} + +func (ctx *MPCalContext) getResourceByHandle(handle ArchetypeResourceHandle) ArchetypeResource { + res, ok := ctx.resources.Get(handle.path) + if !ok { + panic(fmt.Errorf("could not find resource with path %s", handle.path.String())) + } + return res.(ArchetypeResource) +} + +func (ctx *MPCalContext) Abort() { + var nonTrivialAborts []chan struct{} + for _, resHandle := range ctx.dirtyResourceHandles { + ch := ctx.getResourceByHandle(resHandle).Abort() + if ch != nil { + nonTrivialAborts = append(nonTrivialAborts, ch) + } + } + for _, ch := range nonTrivialAborts { + <-ch + } + + ctx.dirtyResourceHandles = nil +} + +func (ctx *MPCalContext) Commit() (err error) { + // dispatch all parts of the pre-commit phase asynchronously, so we only wait as long as the slowest resource + var nonTrivialPreCommits []chan error + for _, resHandle := range ctx.dirtyResourceHandles { + ch := ctx.getResourceByHandle(resHandle).PreCommit() + if ch != nil { + nonTrivialPreCommits = append(nonTrivialPreCommits, ch) + } + } + for _, ch := range nonTrivialPreCommits { + localErr := <-ch + if localErr != nil { + err = localErr + } + } + + // if there was an error, stop now, and expect either (1) total crash, or (2) Abort to be called + if err != nil { + return + } + + // same as above, run all the commit processes async + var nonTrivialCommits []chan struct{} + for _, resHandle := range ctx.dirtyResourceHandles { + ch := ctx.getResourceByHandle(resHandle).Commit() + if ch != nil { + nonTrivialCommits = append(nonTrivialCommits, ch) + } + } + for _, ch := range nonTrivialCommits { + <-ch + } + + ctx.dirtyResourceHandles = nil + return +} + +func (ctx *MPCalContext) ensureCriticalSectionWith(handle ArchetypeResourceHandle) { + for _, candidateHandle := range ctx.dirtyResourceHandles { + if candidateHandle.path.Equal(handle.path) { + return + } + } + ctx.dirtyResourceHandles = append(ctx.dirtyResourceHandles, handle) +} + +func (ctx *MPCalContext) Write(handle ArchetypeResourceHandle, indices []TLAValue, value TLAValue) (err error) { + ctx.ensureCriticalSectionWith(handle) + res := ctx.getResourceByHandle(handle) + for _, index := range indices { + res, err = res.Index(index) + if err != nil { + return + } + } + err = res.WriteValue(value) + return +} + +func (ctx *MPCalContext) Read(handle ArchetypeResourceHandle, indices []TLAValue) (value TLAValue, err error) { + ctx.ensureCriticalSectionWith(handle) + res := ctx.getResourceByHandle(handle) + for _, index := range indices { + res, err = res.Index(index) + if err != nil { + return + } + } + value, err = res.ReadValue() + return +} diff --git a/distsys/processutil.go b/distsys/processutil.go deleted file mode 100644 index 9ed285aa2..000000000 --- a/distsys/processutil.go +++ /dev/null @@ -1,25 +0,0 @@ -package distsys - -import ( - "strings" -) - -func ParseProcessId(processId string) (string, string) { - leftParens := strings.Index(processId, "(") - if leftParens < 0 { - panic("Missing left parenthesis for process ID " + processId) - } - processName := processId[:leftParens] - if processName == "" { - panic("Missing process name for process ID " + processId) - } - rightParens := strings.LastIndex(processId, ")") - if rightParens < 0 { - panic("Missing right parenthesis for process ID " + processId) - } - argument := processId[leftParens+1 : rightParens] - if argument == "" { - panic("Missing processs argument for process ID " + processId) - } - return processName, argument -} diff --git a/distsys/processutil_test.go b/distsys/processutil_test.go deleted file mode 100644 index 5c4a42feb..000000000 --- a/distsys/processutil_test.go +++ /dev/null @@ -1,23 +0,0 @@ -package distsys - -import "testing" - -func TestIntArgument(t *testing.T) { - processName, argument := ParseProcessId("P(1)") - if processName != "P" { - t.Errorf("Expected P, found %s", processName) - } - if argument != "1" { - t.Errorf("Expected 1, found %v", argument) - } -} - -func TestStringArgument(t *testing.T) { - processName, argument := ParseProcessId("P(str)") - if processName != "P" { - t.Errorf("Expected P, found %s", processName) - } - if argument != "str" { - t.Errorf("Expected str, found %v", argument) - } -} diff --git a/distsys/state_ownership.go b/distsys/state_ownership.go deleted file mode 100644 index 86166f083..000000000 --- a/distsys/state_ownership.go +++ /dev/null @@ -1,219 +0,0 @@ -package distsys - -import ( - "math/rand" - "time" -) - -const ( - REF_VAL = iota - REF_MOVED - REF_SKIP -) - -type MigrationStrategy interface { - ShouldMigrate(name, requester string) bool -} - -type NeverMigrate string - -func (never NeverMigrate) ShouldMigrate(_, _ string) bool { - return false -} - -type AlwaysMigrate string - -func (always AlwaysMigrate) ShouldMigrate(_, _ string) bool { - return true -} - -type RandomMigrate string - -func NewRandomMigrate(self string) RandomMigrate { - rand.Seed(time.Now().UTC().UnixNano()) - return RandomMigrate(self) -} - -func (random RandomMigrate) ShouldMigrate(_, _ string) bool { - return rand.Float64() > 0.5 -} - -type RefHandler interface { - GetRef() *Reference -} - -func refBuilder(handler *requestStateHandler, variable *BorrowSpecVariable) RefHandler { - owner := handler.store.OwnerOf(variable.Name) - - if owner == handler.self { - if handler.ownershipMiss { - return RefSkipHandler{variable.Name, handler.store} - } - - return RefValHandler{ - name: variable.Name, - self: handler.self, - requester: handler.requester, - exclusive: variable.Exclusive, - store: handler.store, - migrationStrategy: handler.migrationStrategy, - } - } - - handler.ownershipMiss = true - return RefMovedHandler{variable.Name, owner, handler.store} -} - -type RefValHandler struct { - name string - self string - requester string - exclusive bool - store DataStore - - migrationStrategy MigrationStrategy -} - -func (refhandler RefValHandler) GetRef() *Reference { - var peer string - val := refhandler.store.GetVal(refhandler.name) - moveOwnership := refhandler.migrationStrategy.ShouldMigrate(refhandler.name, refhandler.requester) - - if moveOwnership { - // update our ownership table to reflect the migration - refhandler.store.UpdateOwner(refhandler.name, refhandler.requester) - - // since we are no longer the owners of this variable, free - // any memory being taken by it - refhandler.store.SetVal(refhandler.name, nil) - } - - // indicate the source of the variable ownership so that an - // ACK can be sent back - peer = refhandler.self - - return &Reference{ - Type: REF_VAL, - - Value: val, - Exclusive: refhandler.exclusive, - Ownership: moveOwnership, - Peer: peer, - } -} - -type RefMovedHandler struct { - name string - peer string - store DataStore -} - -func (refhandler RefMovedHandler) GetRef() *Reference { - refhandler.store.Unlock(refhandler.name) - - return &Reference{ - Type: REF_MOVED, - Peer: refhandler.peer, - } -} - -type RefSkipHandler struct { - name string - store DataStore -} - -func (refhandler RefSkipHandler) GetRef() *Reference { - refhandler.store.Unlock(refhandler.name) - - return &Reference{ - Type: REF_SKIP, - } -} - -// localStateHandler is responsible for manipulating requests for global state that is -// to be present in this node's local store. -type localStateHandler struct { - group *VarReq // the variables to be manipulated, including their permissions - store DataStore // the underlying data store - self string // address of the running node -} - -// GetState returns a list of REF_VAL references for the variables contained -// in the VarReq struct within the localStateHandler (receiver). This function -// can only be safely called if the caller holds the lock for all variables -// involved. -func (handler localStateHandler) GetState() (VarReferences, error) { - refs := VarReferences(map[string]*Reference{}) - - for _, borrowVar := range handler.group.Names { - handler := RefValHandler{ - name: borrowVar.Name, - exclusive: borrowVar.Exclusive, - self: handler.self, - store: handler.store, - - // no migrations since this is a local request - migrationStrategy: NeverMigrate(handler.self), - } - - refs.insert(borrowVar.Name, handler.GetRef()) - } - - return refs, nil -} - -// ReleaseState updates the underlying data store with potentially updated -// values in the VarReferences struct given. -func (handler localStateHandler) ReleaseState(refs VarReferences) error { - for name, ref := range refs { - if ref.Exclusive { - handler.store.SetVal(name, ref.Value) - } - } - - return nil -} - -type requestStateHandler struct { - group *VarReq // the variables to be manipulated, including their permissions - requester string // the address of the node making the request - store DataStore // the underlying data store - self string // address of the running node - ownershipMiss bool // whether some variable in `group` is not owned by this node - - migrationStrategy MigrationStrategy -} - -func (handler requestStateHandler) GetState() (VarReferences, error) { - refs := VarReferences(map[string]*Reference{}) - - for _, borrowVar := range handler.group.Names { - handler.store.Lock(borrowVar.Name) - - ref := refBuilder(&handler, borrowVar).GetRef() - refs.insert(borrowVar.Name, ref) - } - - return refs, nil -} - -func (handler requestStateHandler) ReleaseState(refs VarReferences) error { - for name, ref := range refs { - if ref.Exclusive { - handler.store.SetVal(name, ref.Value) - } - - handler.store.Unlock(name) - } - - return nil -} - -// StateMoveComplete is called when a name's ownership is sent to another node -// in the system, and the receiving node acknowledges that it has updates its -// local store to reflect the fact that it now owns that state. -func (handler requestStateHandler) StateMoveComplete() { - for _, borrowVar := range handler.group.Names { - handler.store.Unlock(borrowVar.Name) - } -} diff --git a/distsys/state_ownership_test.go b/distsys/state_ownership_test.go deleted file mode 100644 index 991f077a6..000000000 --- a/distsys/state_ownership_test.go +++ /dev/null @@ -1,164 +0,0 @@ -package distsys - -import ( - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" - - "testing" -) - -var _ = Describe("State Ownership", func() { - var ( - stateHandler requestStateHandler - store DataStore - group *VarReq - self = "10.10.10.1" - ) - - BeforeEach(func() { - store = NewDataStore(map[string]*DataEntry{ - "a": &DataEntry{Owner: "10.10.10.10"}, - "b": &DataEntry{Owner: "10.10.10.20"}, - "c": &DataEntry{Owner: "10.10.10.30"}, - }) - }) - - var _ = Describe("localStateHandler", func() { - BeforeEach(func() { - // current state of the underlying global state store in the running node - store.SetVal("a", 10) - store.SetVal("b", 20) - store.SetVal("c", 30) - - // which group of variables is being requested - group = &VarReq{ - Peer: self, - Names: []*BorrowSpecVariable{ - &BorrowSpecVariable{Name: "a", Exclusive: true}, - &BorrowSpecVariable{Name: "c", Exclusive: false}, - }, - } - - stateHandler = requestStateHandler{ - self: self, - group: group, - store: store, - - migrationStrategy: NeverMigrate(self), - } - }) - - var _ = Describe("GetState", func() { - It("returns a series of values when all of the state is owned by that peer", func() { - store.UpdateOwner("a", self) - store.UpdateOwner("b", self) - store.UpdateOwner("c", self) - - refs, _ := stateHandler.GetState() - Expect(len(refs)).To(Equal(2)) - - Expect(refs["a"]).To(Equal(&Reference{ - Type: REF_VAL, - - Peer: self, - Value: 10, - Exclusive: true, - Ownership: false, - })) - Expect(refs["c"]).To(Equal(&Reference{ - Type: REF_VAL, - - Peer: self, - Value: 30, - Exclusive: false, - Ownership: false, - })) - }) - - It("returns a moved value when the running node no longer owns a variable", func() { - // current node owns variable 'a', but not 'c' - store.UpdateOwner("a", self) - - refs, _ := stateHandler.GetState() - Expect(len(refs)).To(Equal(2)) - - Expect(refs["a"]).To(Equal(&Reference{ - Type: REF_VAL, - Peer: self, - Value: 10, - Exclusive: true, - Ownership: false, - })) - Expect(refs["c"]).To(Equal(&Reference{ - Type: REF_MOVED, - Peer: "10.10.10.30", - })) - }) - - It("skips values that it owns if previous variables moved", func() { - // request for variables 'a', 'b' and 'c' - group.Names = append(group.Names, group.Names[1]) - group.Names[1] = &BorrowSpecVariable{Name: "b", Exclusive: true} - - // running node owns 'a' and 'c', but not 'b' - store.UpdateOwner("a", self) - store.UpdateOwner("c", self) - - refs, _ := stateHandler.GetState() - Expect(len(refs)).To(Equal(3)) - - Expect(refs["a"]).To(Equal(&Reference{ - Type: REF_VAL, - Peer: self, - Value: 10, - Exclusive: true, - Ownership: false, - })) - - Expect(refs["b"]).To(Equal(&Reference{ - Type: REF_MOVED, - Peer: "10.10.10.20", - })) - - Expect(refs["c"]).To(Equal(&Reference{ - Type: REF_SKIP, - })) - }) - - It("indicates all variables that have moved", func() { - // request for variables 'a', 'b' and 'c' - group.Names = append(group.Names, group.Names[1]) - group.Names[1] = &BorrowSpecVariable{Name: "b", Exclusive: true} - - // running node owns 'a', but not 'b' and 'c' - store.UpdateOwner("a", self) - - refs, _ := stateHandler.GetState() - Expect(len(refs)).To(Equal(3)) - - Expect(refs["a"]).To(Equal(&Reference{ - Type: REF_VAL, - Peer: self, - Value: 10, - Exclusive: true, - Ownership: false, - })) - - Expect(refs["b"]).To(Equal(&Reference{ - Type: REF_MOVED, - Peer: "10.10.10.20", - })) - - Expect(refs["c"]).To(Equal(&Reference{ - Type: REF_MOVED, - Peer: "10.10.10.30", - })) - }) - }) - }) -}) - -func TestStateOwnership(t *testing.T) { - RegisterFailHandler(Fail) - RunSpecs(t, "StateOwnership") -} diff --git a/distsys/state_server.go b/distsys/state_server.go deleted file mode 100644 index cf34aa0c1..000000000 --- a/distsys/state_server.go +++ /dev/null @@ -1,57 +0,0 @@ -package distsys - -///////////////////////////////////////////////////////////////////////////////////// -// Details on distributed global state and how the underlying protocol works can // -// be found at https://github.com/UBC-NSS/pgo/wiki/Distributed-Global-State // -////////////////////////////////////////////////////////////////////////////////// - -// GetState is an RPC call used by nodes in the system to request parts -// of the global state that are believed to be owned by the running node. -// Not all variables contained in the VarReq struct passed as argument -// to this function could be owned by this function (the caller may have -// out of date ownership information), in which case this function will -// include references pointing to the actual owner of the state. -func (iface *StateServerRPC) GetState(req *VarReq, refs *VarReferences) error { - handler := requestStateHandler{ - group: req, - requester: req.Requester, - store: iface.server.store, - self: iface.server.self, - - migrationStrategy: iface.server.migrationStrategy, - } - - state, err := handler.GetState() - if err != nil { - return err - } - - *refs = state - return nil -} - -// ReleaseState is an RPC call used by nodes in the system in order to release -// state previously held with a counterpart GetState() call. The references passed -// to this function *must* be owned by the current node. -func (iface *StateServerRPC) ReleaseState(refs VarReferences, ok *bool) error { - handler := requestStateHandler{store: iface.server.store, self: iface.server.self} - - if err := handler.ReleaseState(refs); err != nil { - return err - } - - *ok = true - return nil -} - -// OwnershipMoved is an RPC call used by nodes to indicate that a previous -// move of ownership of a piece of state is acknowledged by the receiving -// end. The local entry for the variables that were moved can, therefore, -// be unlocked. -func (iface *StateServerRPC) OwnershipMoved(req *VarReq, ok *bool) error { - handler := requestStateHandler{store: iface.server.store, group: req} - handler.StateMoveComplete() - - *ok = true - return nil -} diff --git a/distsys/tlaplus.go b/distsys/tlaplus.go index aa9a35315..da4d16b48 100644 --- a/distsys/tlaplus.go +++ b/distsys/tlaplus.go @@ -22,6 +22,7 @@ func init() { gob.Register(tlaValueString("")) gob.Register(&tlaValueSet{}) gob.Register(&tlaValueTuple{}) + gob.Register(&tlaValueFunction{}) } type TLAValue struct { @@ -29,6 +30,8 @@ type TLAValue struct { } var _ fmt.Stringer = TLAValue{} +var _ gob.GobDecoder = &TLAValue{} +var _ gob.GobEncoder = &TLAValue{} func (v TLAValue) Hash() uint32 { if v.data == nil { @@ -75,6 +78,60 @@ func require(req bool, msg string) { } } +func (v TLAValue) IsBool() bool { + switch v.data.(type) { + case tlaValueBool: + return true + default: + return false + } +} + +func (v TLAValue) IsNumber() bool { + switch v.data.(type) { + case tlaValueNumber: + return true + default: + return false + } +} + +func (v TLAValue) IsString() bool { + switch v.data.(type) { + case tlaValueString: + return true + default: + return false + } +} + +func (v TLAValue) IsSet() bool { + switch v.data.(type) { + case *tlaValueSet: + return true + default: + return false + } +} + +func (v TLAValue) IsTuple() bool { + switch v.data.(type) { + case *tlaValueTuple: + return true + default: + return false + } +} + +func (v TLAValue) IsFunction() bool { + switch v.data.(type) { + case *tlaValueFunction: + return true + default: + return false + } +} + func (v TLAValue) AsBool() bool { switch data := v.data.(type) { case tlaValueBool: @@ -264,7 +321,7 @@ func (v tlaValueNumber) Hash() uint32 { } func (v tlaValueNumber) Equal(other TLAValue) bool { - return int32(v) == other.AsNumber() + return other.IsNumber() && int32(v) == other.AsNumber() } func (v tlaValueNumber) String() string { @@ -347,7 +404,7 @@ func (v tlaValueString) Hash() uint32 { } func (v tlaValueString) Equal(other TLAValue) bool { - return string(v) == other.AsString() + return other.IsString() && string(v) == other.AsString() } func (v tlaValueString) String() string { @@ -386,6 +443,9 @@ func (v *tlaValueSet) Hash() uint32 { } func (v *tlaValueSet) Equal(other TLAValue) bool { + if !other.IsSet() { + return false + } oC := other.AsSet() if v.Len() != oC.Len() { return false @@ -434,7 +494,8 @@ func (v *tlaValueSet) GobEncode() ([]byte, error) { it := v.Iterator() for !it.Done() { elem, _ := it.Next() - err := encoder.Encode(elem.(TLAValue)) + elemV := elem.(TLAValue) + err := encoder.Encode(&elemV) // make sure encoded thing is addressable if err != nil { return nil, err } @@ -692,6 +753,10 @@ func (v *tlaValueTuple) Hash() uint32 { } func (v *tlaValueTuple) Equal(other TLAValue) bool { + if !other.IsTuple() { + return false + } + otherTuple := other.AsTuple() if v.Len() != otherTuple.Len() { return false @@ -731,7 +796,8 @@ func (v *tlaValueTuple) GobEncode() ([]byte, error) { it := v.Iterator() for !it.Done() { _, elem := it.Next() - err := encoder.Encode(elem) + elemV := elem.(TLAValue) + err := encoder.Encode(&elemV) if err != nil { return nil, err } @@ -956,6 +1022,10 @@ func (v *tlaValueFunction) Hash() uint32 { } func (v *tlaValueFunction) Equal(other TLAValue) bool { + if !other.IsFunction() { + return false + } + otherFunction := other.AsFunction() if v.Len() != otherFunction.Len() { return false @@ -999,10 +1069,11 @@ func (v *tlaValueFunction) GobEncode() ([]byte, error) { it := v.Iterator() for !it.Done() { key, value := it.Next() - err := encoder.Encode(TLARecordField{ + field := TLARecordField{ Key: key.(TLAValue), Value: value.(TLAValue), - }) + } + err := encoder.Encode(&field) if err != nil { return nil, err } diff --git a/src/pgo/model/Rewritable.scala b/src/pgo/model/Rewritable.scala index 22eb871d7..ec982c46e 100644 --- a/src/pgo/model/Rewritable.scala +++ b/src/pgo/model/Rewritable.scala @@ -5,6 +5,11 @@ import pgo.util.IdMap import java.lang.reflect.Constructor import scala.annotation.tailrec +/** + * This transformation mechanism is heavily inspired by the Viper project's similar, but more general, mechanism. + * + * See https://github.com/viperproject/silver. + */ trait Rewritable extends Visitable { import Rewritable._ diff --git a/src/pgo/trans/MPCalGoCodegenPass.scala b/src/pgo/trans/MPCalGoCodegenPass.scala index de4b76b4f..062a816fb 100644 --- a/src/pgo/trans/MPCalGoCodegenPass.scala +++ b/src/pgo/trans/MPCalGoCodegenPass.scala @@ -65,10 +65,14 @@ object MPCalGoCodegenPass { .map(either => either -> ctx.nameCleaner.cleanName("fairnessCounter")) .to(IdMap) + val InitLabelTag = ctx.nameCleaner.cleanName("InitLabelTag") + val DoneLabelTag = ctx.nameCleaner.cleanName("DoneLabelTag") val labelBinds = (body.view.map { - case PCalLabeledStatements(label, statements) => + case PCalLabeledStatements(label, _) => label.name -> s"${ctx.nameCleaner.cleanName(label.name)}LabelTag" - } ++ List("Done" -> "DoneLabelTag")).toMap + } ++ List("Done" -> DoneLabelTag)).toMap + + val FirstLabel = labelBinds(body.head.asInstanceOf[PCalLabeledStatements].label.name) /** * Ensures that any archetype resource reads embedded within expr are lifted out and performed ahead of time. @@ -166,7 +170,7 @@ object MPCalGoCodegenPass { body def goto(label: String)(implicit ctx: GoCodegenContext): Description = - d"\n${ctx.err} = ${ctx.ctxName}.Write($programCounterResourceName, []$TLAValue{}, distsys.NewTLANumber(${labelBinds(label)}))" + + d"\n${ctx.err} = ${ctx.ctxName}.Write($programCounterResourceName, []$TLAValue{}, distsys.NewTLANumber($label))" + d"\nif ${ctx.err} != nil {${ d"\ncontinue".indented }\n}" @@ -176,7 +180,7 @@ object MPCalGoCodegenPass { case Nil => d"$pfxDesc\n// no statements" case PCalGoto(target) :: Nil => - pfxDesc + goto(target) + commit(d"") + pfxDesc + goto(labelBinds(target)) + commit(d"") case PCalReturn() :: Nil => pfxDesc + commit(d"\nreturn nil") case PCalExtensionStatement(call@MPCalCall(_, arguments)) :: restStmts => @@ -333,9 +337,9 @@ object MPCalGoCodegenPass { ) def ensureLocalResource(value: Description): Description = - d"distsys.EnsureLocalArchetypeResource(${ctx.ctxName}.ResourceEnsurerPositional(), $value)" + d"${ctx.ctxName}.EnsureArchetypeResourceByPosition(distsys.LocalArchetypeResourceMaker($value))" - d"""\nfunc $callableName(${ctx.ctxName} *distsys.MPCalContext, ${ctx.selfName} $TLAValue, ${ctx.constantsName} ${ctx.constantsTypeName}${ + d"""\n\nfunc $callableName(${ctx.ctxName} *distsys.MPCalContext, ${ctx.selfName} $TLAValue, ${ctx.constantsName} ${ctx.constantsTypeName}${ params.view.map { case param@MPCalRefParam(_, _) => d", ${paramNames(param)} $ArchetypeResourceHandle" case param@MPCalValParam(_) => d", ${paramNames(param)} $TLAValue" @@ -344,17 +348,16 @@ object MPCalGoCodegenPass { (d"\nvar ${ctx.err} error" + d"\n// label tags" + d"\nconst (${ - (d"\n${labelBinds(body.head.asInstanceOf[PCalLabeledStatements].label.name)} = iota" + - body.view.tail.map { + (d"\n$InitLabelTag = iota" + + body.view.map { case PCalLabeledStatements(label, _) => d"\n${labelBinds(label.name)}" }.flattenDescriptions + - d"\nDoneLabelTag").indented + d"\n$DoneLabelTag").indented }\n)" + d"\n$programCounterResourceName := ${ ensureLocalResource { - val firstLabel = labelBinds(body.head.asInstanceOf[PCalLabeledStatements].label.name) - d"distsys.NewTLANumber($firstLabel)" + d"distsys.NewTLANumber($InitLabelTag)" } }" + params.view.collect { @@ -362,14 +365,8 @@ object MPCalGoCodegenPass { d"\n${paramLocalNames(param)} := ${ensureLocalResource(paramNames(param).toDescription)}" }.flattenDescriptions + variables.view.map { decl => - (decl match { - case PCalVariableDeclarationEmpty(_) => - d"\n${varNames(decl)} := ${ensureLocalResource(d"$TLAValue{}")}" - case PCalVariableDeclarationSet(_, set) => - d"\n${varNames(decl)} := ${ensureLocalResource(d"${translateExpr(set)}.SelectElement()")}" - case PCalVariableDeclarationValue(_, value) => - d"\n${varNames(decl)} := ${ensureLocalResource(translateExpr(value))}" - }) + d"\n_ = ${varNames(decl)}" // avoid any chance of the unused vars error + d"\n${varNames(decl)} := ${ensureLocalResource(d"$TLAValue{}")}" + + d"\n_ = ${varNames(decl)}" // avoid any chance of the unused vars error }.flattenDescriptions + pcalEithers.map { either => d"\nvar ${fairnessCounterNames(either)} int = 0" @@ -385,18 +382,39 @@ object MPCalGoCodegenPass { }\n}").indented }\n}" + ctx.cleanName("labelTag") { labelTag => - d"\n$labelTag, ${ctx.err} := ${ctx.ctxName}.Read($programCounterResourceName, []$TLAValue{})" + + d"\nvar $labelTag $TLAValue" + + d"\n$labelTag, ${ctx.err} = ${ctx.ctxName}.Read($programCounterResourceName, []$TLAValue{})" + d"\nif ${ctx.err} != nil {${ d"\nreturn ${ctx.err}".indented }\n}" + d"\nswitch $labelTag.AsNumber() {${ - body.map { - case PCalLabeledStatements(label, statements) => - d"\ncase ${labelBinds(label.name)}:${ - impl(statements).indented - }" - }.flattenDescriptions + - d"\ncase DoneLabelTag:" + + // perform any initial commits + d"\ncase $InitLabelTag:" + + variables.map { + case PCalVariableDeclarationEmpty(_) => d"" + case decl@PCalVariableDeclarationSet(_, set) => + readExpr(set) { setRead => + d"\n${ctx.err} = ${ctx.ctxName}.Write(${varNames(decl)}, nil, ${setRead}.SelectElement())" + + d"\nif ${ctx.err} != nil {${ + d"\ncontinue".indented + }\n}" + } + case decl@PCalVariableDeclarationValue(_, value) => + readExpr(value) { valueRead => + d"\n${ctx.err} = ${ctx.ctxName}.Write(${varNames(decl)}, nil, $valueRead)" + + d"\nif ${ctx.err} != nil {${ + d"\ncontinue".indented + }\n}" + } + }.flattenDescriptions.indented + + goto(FirstLabel).indented + + body.map { + case PCalLabeledStatements(label, statements) => + d"\ncase ${labelBinds(label.name)}:${ + impl(statements).indented + }" + }.flattenDescriptions + + d"\ncase $DoneLabelTag:" + d"\nreturn nil".indented }\ndefault:${ d"""\nreturn fmt.Errorf("invalid program counter %v", $labelTag)""".indented @@ -491,10 +509,20 @@ object MPCalGoCodegenPass { // - reading an arity 0 built-in (which is basically like a constant) bind.toDescription case DependentCallableBinding(bind) => + // only makes sense when: + // - reading a locally-defined operator with arity 0 + // - passing an (arity >=1) operator to an operator val cleanArgs = View.fill(ident.refersTo.arity)(ctx.nameCleaner.cleanName("arg")).toList - d"func(${cleanArgs.view.map(arg => d"$arg $TLAValue").separateBy(d", ")}) $TLAValue {${ - d"\nreturn $bind(${ctx.constantsName}${cleanArgs.view.map(arg => d", $arg").flattenDescriptions})" - }\n}" + val wrappedFunc = + d"func(${cleanArgs.view.map(arg => d"$arg $TLAValue").separateBy(d", ")}) $TLAValue {${ + d"\nreturn $bind(${ctx.constantsName}${cleanArgs.view.map(arg => d", $arg").flattenDescriptions})".indented + }\n}" + + if(ident.refersTo.arity == 0) { + wrappedFunc + d"()" // if arity 0, pass by value + } else { + wrappedFunc + } case FixedValueBinding(bind) => bind.toDescription case ResourceBinding(_) => !!! } diff --git a/test/files/general/ExprTests.tla.gotests/go.sum b/test/files/general/ExprTests.tla.gotests/go.sum new file mode 100644 index 000000000..d8fec35cd --- /dev/null +++ b/test/files/general/ExprTests.tla.gotests/go.sum @@ -0,0 +1,2 @@ +github.com/benbjohnson/immutable v0.3.0 h1:TVRhuZx2wG9SZ0LRdqlbs9S5BZ6Y24hJEHTCgWHZEIw= +github.com/benbjohnson/immutable v0.3.0/go.mod h1:uc6OHo6PN2++n98KHLxW8ef4W42ylHiQSENghE1ezxI= diff --git a/test/files/general/dqueue.tla.gotests/dqueue.go b/test/files/general/dqueue.tla.gotests/dqueue.go index ea8833304..b4b7bd732 100644 --- a/test/files/general/dqueue.tla.gotests/dqueue.go +++ b/test/files/general/dqueue.tla.gotests/dqueue.go @@ -22,12 +22,13 @@ func AConsumer(ctx *distsys.MPCalContext, self distsys.TLAValue, constants Const var err error // label tags const ( - cLabelTag = iota + InitLabelTag = iota + cLabelTag c1LabelTag c2LabelTag DoneLabelTag ) - programCounter := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.NewTLANumber(cLabelTag)) + programCounter := ctx.EnsureArchetypeResourceByPosition(distsys.LocalArchetypeResourceMaker(distsys.NewTLANumber(InitLabelTag))) for { if err != nil { @@ -38,11 +39,17 @@ func AConsumer(ctx *distsys.MPCalContext, self distsys.TLAValue, constants Const return err } } - labelTag, err := ctx.Read(programCounter, []distsys.TLAValue{}) + var labelTag distsys.TLAValue + labelTag, err = ctx.Read(programCounter, []distsys.TLAValue{}) if err != nil { return err } switch labelTag.AsNumber() { + case InitLabelTag: + err = ctx.Write(programCounter, []distsys.TLAValue{}, distsys.NewTLANumber(cLabelTag)) + if err != nil { + continue + } case cLabelTag: if distsys.TLA_TRUE.AsBool() { err = ctx.Write(programCounter, []distsys.TLAValue{}, distsys.NewTLANumber(c1LabelTag)) @@ -102,17 +109,19 @@ func AConsumer(ctx *distsys.MPCalContext, self distsys.TLAValue, constants Const } } } + func AProducer(ctx *distsys.MPCalContext, self distsys.TLAValue, constants Constants, net0 distsys.ArchetypeResourceHandle, s distsys.ArchetypeResourceHandle) error { var err0 error // label tags const ( - pLabelTag = iota + InitLabelTag0 = iota + pLabelTag p1LabelTag p2LabelTag - DoneLabelTag + DoneLabelTag0 ) - programCounter0 := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.NewTLANumber(pLabelTag)) - requester := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.TLAValue{}) + programCounter0 := ctx.EnsureArchetypeResourceByPosition(distsys.LocalArchetypeResourceMaker(distsys.NewTLANumber(InitLabelTag0))) + requester := ctx.EnsureArchetypeResourceByPosition(distsys.LocalArchetypeResourceMaker(distsys.TLAValue{})) _ = requester for { @@ -124,11 +133,17 @@ func AProducer(ctx *distsys.MPCalContext, self distsys.TLAValue, constants Const return err0 } } - labelTag0, err0 := ctx.Read(programCounter0, []distsys.TLAValue{}) + var labelTag0 distsys.TLAValue + labelTag0, err0 = ctx.Read(programCounter0, []distsys.TLAValue{}) if err0 != nil { return err0 } switch labelTag0.AsNumber() { + case InitLabelTag0: + err0 = ctx.Write(programCounter0, []distsys.TLAValue{}, distsys.NewTLANumber(pLabelTag)) + if err0 != nil { + continue + } case pLabelTag: if distsys.TLA_TRUE.AsBool() { err0 = ctx.Write(programCounter0, []distsys.TLAValue{}, distsys.NewTLANumber(p1LabelTag)) @@ -140,7 +155,7 @@ func AProducer(ctx *distsys.MPCalContext, self distsys.TLAValue, constants Const continue } } else { - err0 = ctx.Write(programCounter0, []distsys.TLAValue{}, distsys.NewTLANumber(DoneLabelTag)) + err0 = ctx.Write(programCounter0, []distsys.TLAValue{}, distsys.NewTLANumber(DoneLabelTag0)) if err0 != nil { continue } @@ -191,7 +206,7 @@ func AProducer(ctx *distsys.MPCalContext, self distsys.TLAValue, constants Const if err0 != nil { continue } - case DoneLabelTag: + case DoneLabelTag0: return nil default: return fmt.Errorf("invalid program counter %v", labelTag0) diff --git a/test/files/general/dqueue.tla.gotests/dqueue_test.go b/test/files/general/dqueue.tla.gotests/dqueue_test.go index dbc83ad42..067693d66 100644 --- a/test/files/general/dqueue.tla.gotests/dqueue_test.go +++ b/test/files/general/dqueue.tla.gotests/dqueue_test.go @@ -1,7 +1,9 @@ package dqueue import ( + "fmt" "github.com/UBC-NSS/pgo/distsys" + "github.com/UBC-NSS/pgo/distsys/archetype_resources" "testing" ) @@ -12,30 +14,12 @@ func TestNUM_NODES(t *testing.T) { } } -type dummyDurableStorage struct{} - -var _ distsys.MPCalDurableStorage = &dummyDurableStorage{} - -func (d dummyDurableStorage) RecoverResources() (rec *distsys.MPCalDurableStorageRecord, err error) { - return nil, nil -} - -func (d dummyDurableStorage) SnapshotResources(rec *distsys.MPCalDurableStorageRecord) { - // pass -} - func TestProducerConsumer(t *testing.T) { - producerCtx, err := distsys.NewMPCalContext(&dummyDurableStorage{}) - if err != nil { - panic(err) - } + producerCtx := distsys.NewMPCalContext() producerSelf := distsys.NewTLANumber(1) producerInputChannel := make(chan distsys.TLAValue, 3) - consumerCtx, err := distsys.NewMPCalContext(&dummyDurableStorage{}) - if err != nil { - panic(err) - } + consumerCtx := distsys.NewMPCalContext() consumerSelf := distsys.NewTLANumber(2) consumerOutputChannel := make(chan distsys.TLAValue, 3) @@ -44,17 +28,17 @@ func TestProducerConsumer(t *testing.T) { } go func() { - network := distsys.EnsureTCPMailboxesArchetypeResource(producerCtx.ResourceEnsurerByName("network"), func(index distsys.TLAValue) (distsys.TCPMailboxKind, string) { + network := producerCtx.EnsureArchetypeResourceByName("network", archetype_resources.TCPMailboxesArchetypeResourceMaker(func(index distsys.TLAValue) (archetype_resources.TCPMailboxKind, string) { switch index.AsNumber() { case 1: - return distsys.TCPMailboxesLocal, "localhost:8001" + return archetype_resources.TCPMailboxesLocal, "localhost:8001" case 2: - return distsys.TCPMailboxesRemote, "localhost:8002" + return archetype_resources.TCPMailboxesRemote, "localhost:8002" default: - panic("TODO") + panic(fmt.Errorf("unknown mailbox index %v", index)) } - }) - s := distsys.EnsureInputChannelResource(producerCtx.ResourceEnsurerByName("s"), producerInputChannel) + })) + s := producerCtx.EnsureArchetypeResourceByName("s", archetype_resources.InputChannelResourceMaker(producerInputChannel)) err := AProducer(producerCtx, producerSelf, constants, network, s) if err != nil { panic(err) @@ -62,17 +46,17 @@ func TestProducerConsumer(t *testing.T) { }() go func() { - network := distsys.EnsureTCPMailboxesArchetypeResource(consumerCtx.ResourceEnsurerByName("network"), func(index distsys.TLAValue) (distsys.TCPMailboxKind, string) { + network := consumerCtx.EnsureArchetypeResourceByName("network", archetype_resources.TCPMailboxesArchetypeResourceMaker(func(index distsys.TLAValue) (archetype_resources.TCPMailboxKind, string) { switch index.AsNumber() { case 1: - return distsys.TCPMailboxesRemote, "localhost:8001" + return archetype_resources.TCPMailboxesRemote, "localhost:8001" case 2: - return distsys.TCPMailboxesLocal, "localhost:8002" + return archetype_resources.TCPMailboxesLocal, "localhost:8002" default: - panic("TODO") + panic(fmt.Errorf("unknown mailbox index %v", index)) } - }) - proc := distsys.EnsureOutputChannelResource(consumerCtx.ResourceEnsurerByName("proc"), consumerOutputChannel) + })) + proc := consumerCtx.EnsureArchetypeResourceByName("proc", archetype_resources.OutputChannelResourceMaker(consumerOutputChannel)) err := AConsumer(consumerCtx, consumerSelf, constants, network, proc) if err != nil { panic(err) diff --git a/test/files/general/dqueue.tla.gotests/go.sum b/test/files/general/dqueue.tla.gotests/go.sum new file mode 100644 index 000000000..d8fec35cd --- /dev/null +++ b/test/files/general/dqueue.tla.gotests/go.sum @@ -0,0 +1,2 @@ +github.com/benbjohnson/immutable v0.3.0 h1:TVRhuZx2wG9SZ0LRdqlbs9S5BZ6Y24hJEHTCgWHZEIw= +github.com/benbjohnson/immutable v0.3.0/go.mod h1:uc6OHo6PN2++n98KHLxW8ef4W42ylHiQSENghE1ezxI= diff --git a/test/files/general/load_balancer.tla.gotests/go.sum b/test/files/general/load_balancer.tla.gotests/go.sum new file mode 100644 index 000000000..d8fec35cd --- /dev/null +++ b/test/files/general/load_balancer.tla.gotests/go.sum @@ -0,0 +1,2 @@ +github.com/benbjohnson/immutable v0.3.0 h1:TVRhuZx2wG9SZ0LRdqlbs9S5BZ6Y24hJEHTCgWHZEIw= +github.com/benbjohnson/immutable v0.3.0/go.mod h1:uc6OHo6PN2++n98KHLxW8ef4W42ylHiQSENghE1ezxI= diff --git a/test/files/general/load_balancer.tla.gotests/load_balancer.go b/test/files/general/load_balancer.tla.gotests/load_balancer.go index c67f01732..15b96089a 100644 --- a/test/files/general/load_balancer.tla.gotests/load_balancer.go +++ b/test/files/general/load_balancer.tla.gotests/load_balancer.go @@ -25,15 +25,16 @@ func ALoadBalancer(ctx *distsys.MPCalContext, self distsys.TLAValue, constants C var err error // label tags const ( - mainLabelTag = iota + InitLabelTag = iota + mainLabelTag rcvMsgLabelTag sendServerLabelTag DoneLabelTag ) - programCounter := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.NewTLANumber(mainLabelTag)) - msg := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.TLAValue{}) + programCounter := ctx.EnsureArchetypeResourceByPosition(distsys.LocalArchetypeResourceMaker(distsys.NewTLANumber(InitLabelTag))) + msg := ctx.EnsureArchetypeResourceByPosition(distsys.LocalArchetypeResourceMaker(distsys.TLAValue{})) _ = msg - next := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.NewTLANumber(0)) + next := ctx.EnsureArchetypeResourceByPosition(distsys.LocalArchetypeResourceMaker(distsys.TLAValue{})) _ = next for { @@ -45,11 +46,21 @@ func ALoadBalancer(ctx *distsys.MPCalContext, self distsys.TLAValue, constants C return err } } - labelTag, err := ctx.Read(programCounter, []distsys.TLAValue{}) + var labelTag distsys.TLAValue + labelTag, err = ctx.Read(programCounter, []distsys.TLAValue{}) if err != nil { return err } switch labelTag.AsNumber() { + case InitLabelTag: + err = ctx.Write(next, nil, distsys.NewTLANumber(0)) + if err != nil { + continue + } + err = ctx.Write(programCounter, []distsys.TLAValue{}, distsys.NewTLANumber(mainLabelTag)) + if err != nil { + continue + } case mainLabelTag: if distsys.TLA_TRUE.AsBool() { err = ctx.Write(programCounter, []distsys.TLAValue{}, distsys.NewTLANumber(rcvMsgLabelTag)) @@ -151,17 +162,19 @@ func ALoadBalancer(ctx *distsys.MPCalContext, self distsys.TLAValue, constants C } } } + func AServer(ctx *distsys.MPCalContext, self distsys.TLAValue, constants Constants, mailboxes0 distsys.ArchetypeResourceHandle, file_system distsys.ArchetypeResourceHandle) error { var err0 error // label tags const ( - serverLoopLabelTag = iota + InitLabelTag0 = iota + serverLoopLabelTag rcvReqLabelTag sendPageLabelTag - DoneLabelTag + DoneLabelTag0 ) - programCounter0 := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.NewTLANumber(serverLoopLabelTag)) - msg0 := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.TLAValue{}) + programCounter0 := ctx.EnsureArchetypeResourceByPosition(distsys.LocalArchetypeResourceMaker(distsys.NewTLANumber(InitLabelTag0))) + msg0 := ctx.EnsureArchetypeResourceByPosition(distsys.LocalArchetypeResourceMaker(distsys.TLAValue{})) _ = msg0 for { @@ -173,11 +186,17 @@ func AServer(ctx *distsys.MPCalContext, self distsys.TLAValue, constants Constan return err0 } } - labelTag0, err0 := ctx.Read(programCounter0, []distsys.TLAValue{}) + var labelTag0 distsys.TLAValue + labelTag0, err0 = ctx.Read(programCounter0, []distsys.TLAValue{}) if err0 != nil { return err0 } switch labelTag0.AsNumber() { + case InitLabelTag0: + err0 = ctx.Write(programCounter0, []distsys.TLAValue{}, distsys.NewTLANumber(serverLoopLabelTag)) + if err0 != nil { + continue + } case serverLoopLabelTag: if distsys.TLA_TRUE.AsBool() { err0 = ctx.Write(programCounter0, []distsys.TLAValue{}, distsys.NewTLANumber(rcvReqLabelTag)) @@ -189,7 +208,7 @@ func AServer(ctx *distsys.MPCalContext, self distsys.TLAValue, constants Constan continue } } else { - err0 = ctx.Write(programCounter0, []distsys.TLAValue{}, distsys.NewTLANumber(DoneLabelTag)) + err0 = ctx.Write(programCounter0, []distsys.TLAValue{}, distsys.NewTLANumber(DoneLabelTag0)) if err0 != nil { continue } @@ -245,26 +264,28 @@ func AServer(ctx *distsys.MPCalContext, self distsys.TLAValue, constants Constan if err0 != nil { continue } - case DoneLabelTag: + case DoneLabelTag0: return nil default: return fmt.Errorf("invalid program counter %v", labelTag0) } } } + func AClient(ctx *distsys.MPCalContext, self distsys.TLAValue, constants Constants, mailboxes1 distsys.ArchetypeResourceHandle, instream distsys.ArchetypeResourceHandle, outstream distsys.ArchetypeResourceHandle) error { var err1 error // label tags const ( - clientLoopLabelTag = iota + InitLabelTag1 = iota + clientLoopLabelTag clientRequestLabelTag clientReceiveLabelTag - DoneLabelTag + DoneLabelTag1 ) - programCounter1 := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.NewTLANumber(clientLoopLabelTag)) - req := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.TLAValue{}) + programCounter1 := ctx.EnsureArchetypeResourceByPosition(distsys.LocalArchetypeResourceMaker(distsys.NewTLANumber(InitLabelTag1))) + req := ctx.EnsureArchetypeResourceByPosition(distsys.LocalArchetypeResourceMaker(distsys.TLAValue{})) _ = req - resp := distsys.EnsureLocalArchetypeResource(ctx.ResourceEnsurerPositional(), distsys.TLAValue{}) + resp := ctx.EnsureArchetypeResourceByPosition(distsys.LocalArchetypeResourceMaker(distsys.TLAValue{})) _ = resp for { @@ -276,11 +297,17 @@ func AClient(ctx *distsys.MPCalContext, self distsys.TLAValue, constants Constan return err1 } } - labelTag1, err1 := ctx.Read(programCounter1, []distsys.TLAValue{}) + var labelTag1 distsys.TLAValue + labelTag1, err1 = ctx.Read(programCounter1, []distsys.TLAValue{}) if err1 != nil { return err1 } switch labelTag1.AsNumber() { + case InitLabelTag1: + err1 = ctx.Write(programCounter1, []distsys.TLAValue{}, distsys.NewTLANumber(clientLoopLabelTag)) + if err1 != nil { + continue + } case clientLoopLabelTag: if distsys.TLA_TRUE.AsBool() { err1 = ctx.Write(programCounter1, []distsys.TLAValue{}, distsys.NewTLANumber(clientRequestLabelTag)) @@ -292,7 +319,7 @@ func AClient(ctx *distsys.MPCalContext, self distsys.TLAValue, constants Constan continue } } else { - err1 = ctx.Write(programCounter1, []distsys.TLAValue{}, distsys.NewTLANumber(DoneLabelTag)) + err1 = ctx.Write(programCounter1, []distsys.TLAValue{}, distsys.NewTLANumber(DoneLabelTag1)) if err1 != nil { continue } @@ -360,7 +387,7 @@ func AClient(ctx *distsys.MPCalContext, self distsys.TLAValue, constants Constan if err1 != nil { continue } - case DoneLabelTag: + case DoneLabelTag1: return nil default: return fmt.Errorf("invalid program counter %v", labelTag1) diff --git a/test/files/general/load_balancer.tla.gotests/load_balancer_test.go b/test/files/general/load_balancer.tla.gotests/load_balancer_test.go index 53f85b7f6..7f5bc0433 100644 --- a/test/files/general/load_balancer.tla.gotests/load_balancer_test.go +++ b/test/files/general/load_balancer.tla.gotests/load_balancer_test.go @@ -1,8 +1,133 @@ package loadbalancer -import "testing" +import ( + "fmt" + "github.com/UBC-NSS/pgo/distsys" + "github.com/UBC-NSS/pgo/distsys/archetype_resources" + "io/ioutil" + "math/rand" + "os" + "path" + "testing" + "time" +) -func TestOneServer(t *testing.T) { - // TODO: test 1 client, 1 server scenario - t.Fail() +func TestOneServerOneClient(t *testing.T) { + constants := Constants{ + LoadBalancerId: distsys.NewTLANumber(0), + NUM_SERVERS: distsys.NewTLANumber(1), + NUM_CLIENTS: distsys.NewTLANumber(1), + GET_PAGE: distsys.NewTLAString("GET_PAGE"), + } + + tempDir, err := ioutil.TempDir("", "") + if err != nil { + panic(err) + } + defer func() { + err := os.RemoveAll(tempDir) + if err != nil { + panic(err) + } + }() + err = ioutil.WriteFile(path.Join(tempDir, "test1.txt"), []byte("test 1"), 0777) + if err != nil { + panic(err) + } + err = ioutil.WriteFile(path.Join(tempDir, "test2.txt"), []byte("test 2"), 0777) + if err != nil { + panic(err) + } + + go func() { + ctx := distsys.NewMPCalContext() + self := distsys.NewTLANumber(0) + mailboxes := ctx.EnsureArchetypeResourceByName("mailboxes", archetype_resources.TCPMailboxesArchetypeResourceMaker(func(index distsys.TLAValue) (archetype_resources.TCPMailboxKind, string) { + switch index.AsNumber() { + case 0: + return archetype_resources.TCPMailboxesLocal, "localhost:8001" + case 1: + return archetype_resources.TCPMailboxesRemote, "localhost:8002" + case 2: + return archetype_resources.TCPMailboxesRemote, "localhost:8003" + default: + panic(fmt.Errorf("unknown mailbox index %v", index)) + } + })) + err := ALoadBalancer(ctx, self, constants, mailboxes) + if err != nil { + panic(err) + } + }() + + go func() { + ctx := distsys.NewMPCalContext() + self := distsys.NewTLANumber(1) + mailboxes := ctx.EnsureArchetypeResourceByName("mailboxes", archetype_resources.TCPMailboxesArchetypeResourceMaker(func(index distsys.TLAValue) (archetype_resources.TCPMailboxKind, string) { + switch index.AsNumber() { + case 0: + return archetype_resources.TCPMailboxesRemote, "localhost:8001" + case 1: + return archetype_resources.TCPMailboxesLocal, "localhost:8002" + case 2: + return archetype_resources.TCPMailboxesRemote, "localhost:8003" + default: + panic(fmt.Errorf("unknown mailbox index %v", index)) + } + })) + filesystem := ctx.EnsureArchetypeResourceByName("filesystem", archetype_resources.FilesystemArchetypeResourceMaker(tempDir)) + err := AServer(ctx, self, constants, mailboxes, filesystem) + if err != nil { + panic(err) + } + }() + + requestChannel := make(chan distsys.TLAValue, 32) + responseChannel := make(chan distsys.TLAValue, 32) + go func() { + ctx := distsys.NewMPCalContext() + self := distsys.NewTLANumber(2) + mailboxes := ctx.EnsureArchetypeResourceByName("mailboxes", archetype_resources.TCPMailboxesArchetypeResourceMaker(func(index distsys.TLAValue) (archetype_resources.TCPMailboxKind, string) { + switch index.AsNumber() { + case 0: + return archetype_resources.TCPMailboxesRemote, "localhost:8001" + case 1: + return archetype_resources.TCPMailboxesRemote, "localhost:8002" + case 2: + return archetype_resources.TCPMailboxesLocal, "localhost:8003" + default: + panic(fmt.Errorf("unknown mailbox index %v", index)) + } + })) + instream := ctx.EnsureArchetypeResourceByName("instream", archetype_resources.InputChannelResourceMaker(requestChannel)) + outstream := ctx.EnsureArchetypeResourceByName("outstream", archetype_resources.OutputChannelResourceMaker(responseChannel)) + err := AClient(ctx, self, constants, mailboxes, instream, outstream) + if err != nil { + panic(err) + } + }() + + type RequestResponse struct { + Request, Response distsys.TLAValue + } + choices := []RequestResponse{ + {Request: distsys.NewTLAString("test1.txt"), Response: distsys.NewTLAString("test 1")}, + {Request: distsys.NewTLAString("test2.txt"), Response: distsys.NewTLAString("test 2")}, + } + + rand.Seed(time.Now().UnixNano()) + requestResponsePairs := make([]RequestResponse, 32) + for i := 0; i < 32; i++ { + requestResponsePairs[i] = choices[rand.Intn(len(choices))] + } + // send requests + for i := range requestResponsePairs { + requestChannel <- requestResponsePairs[i].Request + } + for i := range requestResponsePairs { + response := <-responseChannel + if !response.Equal(requestResponsePairs[i].Response) { + t.Fatalf("actual response %v to request %v did not equal expected response %v", response, requestResponsePairs[i].Request, requestResponsePairs[i].Response) + } + } } diff --git a/test/files/general/replicated_kv.tla.gotests/go.mod b/test/files/general/replicated_kv.tla.gotests/go.mod new file mode 100644 index 000000000..8fe907e2c --- /dev/null +++ b/test/files/general/replicated_kv.tla.gotests/go.mod @@ -0,0 +1,7 @@ +module example.org/replicated_kv + +go 1.14 + +replace github.com/UBC-NSS/pgo/distsys => ../../../../distsys + +require github.com/UBC-NSS/pgo/distsys v0.0.0-00010101000000-000000000000 diff --git a/test/files/general/replicated_kv.tla.gotests/go.sum b/test/files/general/replicated_kv.tla.gotests/go.sum new file mode 100644 index 000000000..d8fec35cd --- /dev/null +++ b/test/files/general/replicated_kv.tla.gotests/go.sum @@ -0,0 +1,2 @@ +github.com/benbjohnson/immutable v0.3.0 h1:TVRhuZx2wG9SZ0LRdqlbs9S5BZ6Y24hJEHTCgWHZEIw= +github.com/benbjohnson/immutable v0.3.0/go.mod h1:uc6OHo6PN2++n98KHLxW8ef4W42ylHiQSENghE1ezxI= diff --git a/test/files/general/replicated_kv.tla.gotests/replicated_kv.go b/test/files/general/replicated_kv.tla.gotests/replicated_kv.go new file mode 100644 index 000000000..fe05b59ae --- /dev/null +++ b/test/files/general/replicated_kv.tla.gotests/replicated_kv.go @@ -0,0 +1,2048 @@ +package replicatedkv + +import ( + "fmt" + "github.com/UBC-NSS/pgo/distsys" +) + +var _ = new(fmt.Stringer) // unconditionally prevent go compiler from reporting unused fmt import +var _ = distsys.TLAValue{} // same, for distsys + +type Constants struct { + BUFFER_SIZE distsys.TLAValue + NUM_REPLICAS distsys.TLAValue + NUM_CLIENTS distsys.TLAValue + DISCONNECT_MSG distsys.TLAValue + GET_MSG distsys.TLAValue + PUT_MSG distsys.TLAValue + NULL_MSG distsys.TLAValue + GET_RESPONSE distsys.TLAValue + PUT_RESPONSE distsys.TLAValue + NULL distsys.TLAValue + GET_KEY distsys.TLAValue + PUT_KEY distsys.TLAValue + PUT_VALUE distsys.TLAValue +} + +func KeySpace(constants Constants) distsys.TLAValue { + return distsys.NewTLASet(constants.GET_KEY, constants.PUT_KEY) +} + +func GET_ORDER(constants Constants) distsys.TLAValue { + return distsys.NewTLANumber(0) +} + +func PUT_ORDER(constants Constants) distsys.TLAValue { + return distsys.NewTLANumber(1) +} + +func DISCONNECT_ORDER(constants Constants) distsys.TLAValue { + return distsys.NewTLANumber(2) +} + +func NULL_ORDER(constants Constants) distsys.TLAValue { + return distsys.NewTLANumber(3) +} + +func GetSet(constants Constants) distsys.TLAValue { + return distsys.TLA_DotDotSymbol(constants.NUM_REPLICAS, distsys.TLA_PlusSymbol(constants.NUM_REPLICAS, distsys.TLA_MinusSymbol(constants.NUM_CLIENTS, distsys.NewTLANumber(1)))) +} + +func PutSet(constants Constants) distsys.TLAValue { + return distsys.TLA_DotDotSymbol(distsys.TLA_PlusSymbol(constants.NUM_REPLICAS, constants.NUM_CLIENTS), distsys.TLA_PlusSymbol(constants.NUM_REPLICAS, distsys.TLA_MinusSymbol(distsys.TLA_AsteriskSymbol(distsys.NewTLANumber(2), constants.NUM_CLIENTS), distsys.NewTLANumber(1)))) +} + +func DisconnectSet(constants Constants) distsys.TLAValue { + return distsys.TLA_DotDotSymbol(distsys.TLA_PlusSymbol(constants.NUM_REPLICAS, distsys.TLA_AsteriskSymbol(distsys.NewTLANumber(2), constants.NUM_CLIENTS)), distsys.TLA_PlusSymbol(constants.NUM_REPLICAS, distsys.TLA_MinusSymbol(distsys.TLA_AsteriskSymbol(distsys.NewTLANumber(3), constants.NUM_CLIENTS), distsys.NewTLANumber(1)))) +} + +func NullSet(constants Constants) distsys.TLAValue { + return distsys.TLA_DotDotSymbol(distsys.TLA_PlusSymbol(constants.NUM_REPLICAS, distsys.TLA_AsteriskSymbol(distsys.NewTLANumber(3), constants.NUM_CLIENTS)), distsys.TLA_PlusSymbol(constants.NUM_REPLICAS, distsys.TLA_MinusSymbol(distsys.TLA_AsteriskSymbol(distsys.NewTLANumber(4), constants.NUM_CLIENTS), distsys.NewTLANumber(1)))) +} + +func NUM_NODES(constants Constants) distsys.TLAValue { + return distsys.TLA_PlusSymbol(constants.NUM_REPLICAS, constants.NUM_CLIENTS) +} + +func ReplicaSet(constants Constants) distsys.TLAValue { + return distsys.TLA_DotDotSymbol(distsys.NewTLANumber(0), distsys.TLA_MinusSymbol(constants.NUM_REPLICAS, distsys.NewTLANumber(1))) +} + +func ClientSet(constants Constants) distsys.TLAValue { + return distsys.TLA_DotDotSymbol(constants.NUM_REPLICAS, distsys.TLA_MinusSymbol(func() distsys.TLAValue { + return NUM_NODES(constants) + }(), distsys.NewTLANumber(1))) +} + +func AReplica(ctx *distsys.MPCalContext, self distsys.TLAValue, constants Constants, clients distsys.ArchetypeResourceHandle, replicas distsys.ArchetypeResourceHandle, kv distsys.ArchetypeResourceHandle) error { + var err error + // label tags + const ( + InitLabelTag = iota + replicaLoopLabelTag + receiveClientRequestLabelTag + clientDisconnectedLabelTag + replicaGetRequestLabelTag + replicaPutRequestLabelTag + replicaNullRequestLabelTag + findStableRequestsLoopLabelTag + findMinClockLabelTag + findMinClientLabelTag + addStableMessageLabelTag + respondPendingRequestsLoopLabelTag + respondStableGetLabelTag + respondStablePutLabelTag + DoneLabelTag + ) + programCounter := ctx.EnsureArchetypeResourceByPosition(distsys.LocalArchetypeResourceMaker(distsys.NewTLANumber(InitLabelTag))) + liveClients := ctx.EnsureArchetypeResourceByPosition(distsys.LocalArchetypeResourceMaker(distsys.TLAValue{})) + _ = liveClients + pendingRequests := ctx.EnsureArchetypeResourceByPosition(distsys.LocalArchetypeResourceMaker(distsys.TLAValue{})) + _ = pendingRequests + stableMessages := ctx.EnsureArchetypeResourceByPosition(distsys.LocalArchetypeResourceMaker(distsys.TLAValue{})) + _ = stableMessages + i := ctx.EnsureArchetypeResourceByPosition(distsys.LocalArchetypeResourceMaker(distsys.TLAValue{})) + _ = i + firstPending := ctx.EnsureArchetypeResourceByPosition(distsys.LocalArchetypeResourceMaker(distsys.TLAValue{})) + _ = firstPending + timestamp := ctx.EnsureArchetypeResourceByPosition(distsys.LocalArchetypeResourceMaker(distsys.TLAValue{})) + _ = timestamp + nextClient := ctx.EnsureArchetypeResourceByPosition(distsys.LocalArchetypeResourceMaker(distsys.TLAValue{})) + _ = nextClient + lowestPending := ctx.EnsureArchetypeResourceByPosition(distsys.LocalArchetypeResourceMaker(distsys.TLAValue{})) + _ = lowestPending + chooseMessage := ctx.EnsureArchetypeResourceByPosition(distsys.LocalArchetypeResourceMaker(distsys.TLAValue{})) + _ = chooseMessage + currentClocks := ctx.EnsureArchetypeResourceByPosition(distsys.LocalArchetypeResourceMaker(distsys.TLAValue{})) + _ = currentClocks + minClock := ctx.EnsureArchetypeResourceByPosition(distsys.LocalArchetypeResourceMaker(distsys.TLAValue{})) + _ = minClock + continue0 := ctx.EnsureArchetypeResourceByPosition(distsys.LocalArchetypeResourceMaker(distsys.TLAValue{})) + _ = continue0 + pendingClients := ctx.EnsureArchetypeResourceByPosition(distsys.LocalArchetypeResourceMaker(distsys.TLAValue{})) + _ = pendingClients + clientsIter := ctx.EnsureArchetypeResourceByPosition(distsys.LocalArchetypeResourceMaker(distsys.TLAValue{})) + _ = clientsIter + msg := ctx.EnsureArchetypeResourceByPosition(distsys.LocalArchetypeResourceMaker(distsys.TLAValue{})) + _ = msg + ok := ctx.EnsureArchetypeResourceByPosition(distsys.LocalArchetypeResourceMaker(distsys.TLAValue{})) + _ = ok + key := ctx.EnsureArchetypeResourceByPosition(distsys.LocalArchetypeResourceMaker(distsys.TLAValue{})) + _ = key + val := ctx.EnsureArchetypeResourceByPosition(distsys.LocalArchetypeResourceMaker(distsys.TLAValue{})) + _ = val + + for { + if err != nil { + if err == distsys.ErrCriticalSectionAborted { + ctx.Abort() + err = nil + } else { + return err + } + } + var labelTag distsys.TLAValue + labelTag, err = ctx.Read(programCounter, []distsys.TLAValue{}) + if err != nil { + return err + } + switch labelTag.AsNumber() { + case InitLabelTag: + err = ctx.Write(liveClients, nil, func() distsys.TLAValue { + return ClientSet(constants) + }()) + if err != nil { + continue + } + var resourceRead distsys.TLAValue + resourceRead, err = ctx.Read(liveClients, []distsys.TLAValue{}) + if err != nil { + continue + } + err = ctx.Write(pendingRequests, nil, distsys.NewTLAFunction([]distsys.TLAValue{resourceRead}, func(args []distsys.TLAValue) distsys.TLAValue { + var c distsys.TLAValue = args[0] + _ = c + return distsys.NewTLATuple() + })) + if err != nil { + continue + } + err = ctx.Write(stableMessages, nil, distsys.NewTLATuple()) + if err != nil { + continue + } + var resourceRead0 distsys.TLAValue + resourceRead0, err = ctx.Read(liveClients, []distsys.TLAValue{}) + if err != nil { + continue + } + err = ctx.Write(currentClocks, nil, distsys.NewTLAFunction([]distsys.TLAValue{resourceRead0}, func(args0 []distsys.TLAValue) distsys.TLAValue { + var c0 distsys.TLAValue = args0[0] + _ = c0 + return distsys.NewTLANumber(0) + })) + if err != nil { + continue + } + err = ctx.Write(programCounter, []distsys.TLAValue{}, distsys.NewTLANumber(replicaLoopLabelTag)) + if err != nil { + continue + } + case replicaLoopLabelTag: + if distsys.TLA_TRUE.AsBool() { + err = ctx.Write(stableMessages, []distsys.TLAValue{}, distsys.NewTLATuple()) + if err != nil { + continue + } + err = ctx.Write(continue0, []distsys.TLAValue{}, distsys.TLA_TRUE) + if err != nil { + continue + } + err = ctx.Write(programCounter, []distsys.TLAValue{}, distsys.NewTLANumber(receiveClientRequestLabelTag)) + if err != nil { + continue + } + err = ctx.Commit() + if err != nil { + continue + } + } else { + err = ctx.Write(programCounter, []distsys.TLAValue{}, distsys.NewTLANumber(DoneLabelTag)) + if err != nil { + continue + } + err = ctx.Commit() + if err != nil { + continue + } + } + // no statements + case receiveClientRequestLabelTag: + var exprRead distsys.TLAValue + exprRead, err = ctx.Read(replicas, []distsys.TLAValue{self}) + if err != nil { + continue + } + err = ctx.Write(msg, []distsys.TLAValue{}, exprRead) + if err != nil { + continue + } + err = ctx.Write(programCounter, []distsys.TLAValue{}, distsys.NewTLANumber(clientDisconnectedLabelTag)) + if err != nil { + continue + } + err = ctx.Commit() + if err != nil { + continue + } + case clientDisconnectedLabelTag: + var condition distsys.TLAValue + condition, err = ctx.Read(msg, []distsys.TLAValue{}) + if err != nil { + continue + } + if distsys.TLA_EqualsSymbol(condition.ApplyFunction(distsys.NewTLAString("op")), constants.DISCONNECT_MSG).AsBool() { + var exprRead0 distsys.TLAValue + exprRead0, err = ctx.Read(liveClients, []distsys.TLAValue{}) + if err != nil { + continue + } + var exprRead1 distsys.TLAValue + exprRead1, err = ctx.Read(msg, []distsys.TLAValue{}) + if err != nil { + continue + } + err = ctx.Write(liveClients, []distsys.TLAValue{}, distsys.TLA_BackslashSymbol(exprRead0, distsys.NewTLASet(exprRead1.ApplyFunction(distsys.NewTLAString("client"))))) + if err != nil { + continue + } + err = ctx.Write(programCounter, []distsys.TLAValue{}, distsys.NewTLANumber(replicaGetRequestLabelTag)) + if err != nil { + continue + } + err = ctx.Commit() + if err != nil { + continue + } + } else { + err = ctx.Write(programCounter, []distsys.TLAValue{}, distsys.NewTLANumber(replicaGetRequestLabelTag)) + if err != nil { + continue + } + err = ctx.Commit() + if err != nil { + continue + } + } + // no statements + case replicaGetRequestLabelTag: + var condition0 distsys.TLAValue + condition0, err = ctx.Read(msg, []distsys.TLAValue{}) + if err != nil { + continue + } + if distsys.TLA_EqualsSymbol(condition0.ApplyFunction(distsys.NewTLAString("op")), constants.GET_MSG).AsBool() { + var condition1 distsys.TLAValue + condition1, err = ctx.Read(msg, []distsys.TLAValue{}) + if err != nil { + continue + } + var condition2 distsys.TLAValue + condition2, err = ctx.Read(liveClients, []distsys.TLAValue{}) + if err != nil { + continue + } + if !distsys.TLA_InSymbol(condition1.ApplyFunction(distsys.NewTLAString("client")), condition2).AsBool() { + err = fmt.Errorf("%w: ((msg).client) \\in (liveClients)", distsys.ErrAssertionFailed) + continue + } + var exprRead2 distsys.TLAValue + exprRead2, err = ctx.Read(msg, []distsys.TLAValue{}) + if err != nil { + continue + } + var indexRead distsys.TLAValue + indexRead, err = ctx.Read(msg, []distsys.TLAValue{}) + if err != nil { + continue + } + err = ctx.Write(currentClocks, []distsys.TLAValue{indexRead.ApplyFunction(distsys.NewTLAString("client"))}, exprRead2.ApplyFunction(distsys.NewTLAString("timestamp"))) + if err != nil { + continue + } + var exprRead3 distsys.TLAValue + exprRead3, err = ctx.Read(pendingRequests, []distsys.TLAValue{}) + if err != nil { + continue + } + var exprRead4 distsys.TLAValue + exprRead4, err = ctx.Read(msg, []distsys.TLAValue{}) + if err != nil { + continue + } + var exprRead5 distsys.TLAValue + exprRead5, err = ctx.Read(msg, []distsys.TLAValue{}) + if err != nil { + continue + } + var indexRead0 distsys.TLAValue + indexRead0, err = ctx.Read(msg, []distsys.TLAValue{}) + if err != nil { + continue + } + err = ctx.Write(pendingRequests, []distsys.TLAValue{indexRead0.ApplyFunction(distsys.NewTLAString("client"))}, distsys.TLA_Append(exprRead3.ApplyFunction(exprRead4.ApplyFunction(distsys.NewTLAString("client"))), exprRead5)) + if err != nil { + continue + } + err = ctx.Write(programCounter, []distsys.TLAValue{}, distsys.NewTLANumber(replicaPutRequestLabelTag)) + if err != nil { + continue + } + err = ctx.Commit() + if err != nil { + continue + } + } else { + err = ctx.Write(programCounter, []distsys.TLAValue{}, distsys.NewTLANumber(replicaPutRequestLabelTag)) + if err != nil { + continue + } + err = ctx.Commit() + if err != nil { + continue + } + } + // no statements + case replicaPutRequestLabelTag: + var condition3 distsys.TLAValue + condition3, err = ctx.Read(msg, []distsys.TLAValue{}) + if err != nil { + continue + } + if distsys.TLA_EqualsSymbol(condition3.ApplyFunction(distsys.NewTLAString("op")), constants.PUT_MSG).AsBool() { + var exprRead6 distsys.TLAValue + exprRead6, err = ctx.Read(msg, []distsys.TLAValue{}) + if err != nil { + continue + } + var indexRead1 distsys.TLAValue + indexRead1, err = ctx.Read(msg, []distsys.TLAValue{}) + if err != nil { + continue + } + err = ctx.Write(currentClocks, []distsys.TLAValue{indexRead1.ApplyFunction(distsys.NewTLAString("client"))}, exprRead6.ApplyFunction(distsys.NewTLAString("timestamp"))) + if err != nil { + continue + } + var exprRead7 distsys.TLAValue + exprRead7, err = ctx.Read(pendingRequests, []distsys.TLAValue{}) + if err != nil { + continue + } + var exprRead8 distsys.TLAValue + exprRead8, err = ctx.Read(msg, []distsys.TLAValue{}) + if err != nil { + continue + } + var exprRead9 distsys.TLAValue + exprRead9, err = ctx.Read(msg, []distsys.TLAValue{}) + if err != nil { + continue + } + var indexRead2 distsys.TLAValue + indexRead2, err = ctx.Read(msg, []distsys.TLAValue{}) + if err != nil { + continue + } + err = ctx.Write(pendingRequests, []distsys.TLAValue{indexRead2.ApplyFunction(distsys.NewTLAString("client"))}, distsys.TLA_Append(exprRead7.ApplyFunction(exprRead8.ApplyFunction(distsys.NewTLAString("client"))), exprRead9)) + if err != nil { + continue + } + err = ctx.Write(programCounter, []distsys.TLAValue{}, distsys.NewTLANumber(replicaNullRequestLabelTag)) + if err != nil { + continue + } + err = ctx.Commit() + if err != nil { + continue + } + } else { + err = ctx.Write(programCounter, []distsys.TLAValue{}, distsys.NewTLANumber(replicaNullRequestLabelTag)) + if err != nil { + continue + } + err = ctx.Commit() + if err != nil { + continue + } + } + // no statements + case replicaNullRequestLabelTag: + var condition4 distsys.TLAValue + condition4, err = ctx.Read(msg, []distsys.TLAValue{}) + if err != nil { + continue + } + if distsys.TLA_EqualsSymbol(condition4.ApplyFunction(distsys.NewTLAString("op")), constants.NULL_MSG).AsBool() { + var exprRead10 distsys.TLAValue + exprRead10, err = ctx.Read(msg, []distsys.TLAValue{}) + if err != nil { + continue + } + var indexRead3 distsys.TLAValue + indexRead3, err = ctx.Read(msg, []distsys.TLAValue{}) + if err != nil { + continue + } + err = ctx.Write(currentClocks, []distsys.TLAValue{indexRead3.ApplyFunction(distsys.NewTLAString("client"))}, exprRead10.ApplyFunction(distsys.NewTLAString("timestamp"))) + if err != nil { + continue + } + err = ctx.Write(programCounter, []distsys.TLAValue{}, distsys.NewTLANumber(findStableRequestsLoopLabelTag)) + if err != nil { + continue + } + err = ctx.Commit() + if err != nil { + continue + } + } else { + err = ctx.Write(programCounter, []distsys.TLAValue{}, distsys.NewTLANumber(findStableRequestsLoopLabelTag)) + if err != nil { + continue + } + err = ctx.Commit() + if err != nil { + continue + } + } + // no statements + case findStableRequestsLoopLabelTag: + var condition5 distsys.TLAValue + condition5, err = ctx.Read(continue0, []distsys.TLAValue{}) + if err != nil { + continue + } + if condition5.AsBool() { + var exprRead11 distsys.TLAValue + exprRead11, err = ctx.Read(liveClients, []distsys.TLAValue{}) + if err != nil { + continue + } + var exprRead12 distsys.TLAValue + exprRead12, err = ctx.Read(pendingRequests, []distsys.TLAValue{}) + if err != nil { + continue + } + err = ctx.Write(pendingClients, []distsys.TLAValue{}, distsys.TLASetRefinement(exprRead11, func(elem distsys.TLAValue) bool { + var c1 distsys.TLAValue = elem + _ = c1 + return distsys.TLA_GreaterThanSymbol(distsys.TLA_Len(exprRead12.ApplyFunction(c1)), distsys.NewTLANumber(0)).AsBool() + })) + if err != nil { + continue + } + err = ctx.Write(nextClient, []distsys.TLAValue{}, distsys.TLA_PlusSymbol(func() distsys.TLAValue { + return NUM_NODES(constants) + }(), distsys.NewTLANumber(1))) + if err != nil { + continue + } + var exprRead13 distsys.TLAValue + exprRead13, err = ctx.Read(liveClients, []distsys.TLAValue{}) + if err != nil { + continue + } + err = ctx.Write(clientsIter, []distsys.TLAValue{}, exprRead13) + if err != nil { + continue + } + err = ctx.Write(i, []distsys.TLAValue{}, distsys.NewTLANumber(0)) + if err != nil { + continue + } + err = ctx.Write(minClock, []distsys.TLAValue{}, distsys.NewTLANumber(0)) + if err != nil { + continue + } + err = ctx.Write(programCounter, []distsys.TLAValue{}, distsys.NewTLANumber(findMinClockLabelTag)) + if err != nil { + continue + } + err = ctx.Commit() + if err != nil { + continue + } + } else { + err = ctx.Write(i, []distsys.TLAValue{}, distsys.NewTLANumber(1)) + if err != nil { + continue + } + err = ctx.Write(programCounter, []distsys.TLAValue{}, distsys.NewTLANumber(respondPendingRequestsLoopLabelTag)) + if err != nil { + continue + } + err = ctx.Commit() + if err != nil { + continue + } + } + // no statements + case findMinClockLabelTag: + var condition6 distsys.TLAValue + condition6, err = ctx.Read(i, []distsys.TLAValue{}) + if err != nil { + continue + } + var condition7 distsys.TLAValue + condition7, err = ctx.Read(clientsIter, []distsys.TLAValue{}) + if err != nil { + continue + } + if distsys.TLA_LessThanSymbol(condition6, distsys.TLA_Cardinality(condition7)).AsBool() { + var clientRead distsys.TLAValue + clientRead, err = ctx.Read(clientsIter, []distsys.TLAValue{}) + if err != nil { + continue + } + var client distsys.TLAValue = clientRead.SelectElement() + var condition8 distsys.TLAValue + condition8, err = ctx.Read(minClock, []distsys.TLAValue{}) + if err != nil { + continue + } + var condition9 distsys.TLAValue + condition9, err = ctx.Read(currentClocks, []distsys.TLAValue{}) + if err != nil { + continue + } + var condition10 distsys.TLAValue + condition10, err = ctx.Read(minClock, []distsys.TLAValue{}) + if err != nil { + continue + } + if distsys.TLA_LogicalOrSymbol(distsys.TLA_EqualsSymbol(condition8, distsys.NewTLANumber(0)), distsys.TLA_LessThanSymbol(condition9.ApplyFunction(client), condition10)).AsBool() { + var exprRead14 distsys.TLAValue + exprRead14, err = ctx.Read(currentClocks, []distsys.TLAValue{}) + if err != nil { + continue + } + err = ctx.Write(minClock, []distsys.TLAValue{}, exprRead14.ApplyFunction(client)) + if err != nil { + continue + } + // no statements + } else { + // no statements + } + var exprRead15 distsys.TLAValue + exprRead15, err = ctx.Read(clientsIter, []distsys.TLAValue{}) + if err != nil { + continue + } + err = ctx.Write(clientsIter, []distsys.TLAValue{}, distsys.TLA_BackslashSymbol(exprRead15, distsys.NewTLASet(client))) + if err != nil { + continue + } + err = ctx.Write(programCounter, []distsys.TLAValue{}, distsys.NewTLANumber(findMinClockLabelTag)) + if err != nil { + continue + } + err = ctx.Commit() + if err != nil { + continue + } + // no statements + } else { + var exprRead16 distsys.TLAValue + exprRead16, err = ctx.Read(minClock, []distsys.TLAValue{}) + if err != nil { + continue + } + err = ctx.Write(lowestPending, []distsys.TLAValue{}, distsys.TLA_PlusSymbol(exprRead16, distsys.NewTLANumber(1))) + if err != nil { + continue + } + err = ctx.Write(i, []distsys.TLAValue{}, distsys.NewTLANumber(0)) + if err != nil { + continue + } + err = ctx.Write(programCounter, []distsys.TLAValue{}, distsys.NewTLANumber(findMinClientLabelTag)) + if err != nil { + continue + } + err = ctx.Commit() + if err != nil { + continue + } + } + // no statements + case findMinClientLabelTag: + var condition11 distsys.TLAValue + condition11, err = ctx.Read(i, []distsys.TLAValue{}) + if err != nil { + continue + } + var condition12 distsys.TLAValue + condition12, err = ctx.Read(pendingClients, []distsys.TLAValue{}) + if err != nil { + continue + } + if distsys.TLA_LessThanSymbol(condition11, distsys.TLA_Cardinality(condition12)).AsBool() { + var clientRead0 distsys.TLAValue + clientRead0, err = ctx.Read(pendingClients, []distsys.TLAValue{}) + if err != nil { + continue + } + var client0 distsys.TLAValue = clientRead0.SelectElement() + var exprRead17 distsys.TLAValue + exprRead17, err = ctx.Read(pendingRequests, []distsys.TLAValue{}) + if err != nil { + continue + } + err = ctx.Write(firstPending, []distsys.TLAValue{}, distsys.TLA_Head(exprRead17.ApplyFunction(client0))) + if err != nil { + continue + } + var condition13 distsys.TLAValue + condition13, err = ctx.Read(firstPending, []distsys.TLAValue{}) + if err != nil { + continue + } + var condition14 distsys.TLAValue + condition14, err = ctx.Read(firstPending, []distsys.TLAValue{}) + if err != nil { + continue + } + if !distsys.TLA_LogicalOrSymbol(distsys.TLA_EqualsSymbol(condition13.ApplyFunction(distsys.NewTLAString("op")), constants.GET_MSG), distsys.TLA_EqualsSymbol(condition14.ApplyFunction(distsys.NewTLAString("op")), constants.PUT_MSG)).AsBool() { + err = fmt.Errorf("%w: (((firstPending).op) = (GET_MSG)) \\/ (((firstPending).op) = (PUT_MSG))", distsys.ErrAssertionFailed) + continue + } + var exprRead18 distsys.TLAValue + exprRead18, err = ctx.Read(firstPending, []distsys.TLAValue{}) + if err != nil { + continue + } + err = ctx.Write(timestamp, []distsys.TLAValue{}, exprRead18.ApplyFunction(distsys.NewTLAString("timestamp"))) + if err != nil { + continue + } + var condition15 distsys.TLAValue + condition15, err = ctx.Read(timestamp, []distsys.TLAValue{}) + if err != nil { + continue + } + var condition16 distsys.TLAValue + condition16, err = ctx.Read(minClock, []distsys.TLAValue{}) + if err != nil { + continue + } + if distsys.TLA_LessThanSymbol(condition15, condition16).AsBool() { + var exprRead19 distsys.TLAValue + exprRead19, err = ctx.Read(timestamp, []distsys.TLAValue{}) + if err != nil { + continue + } + var exprRead20 distsys.TLAValue + exprRead20, err = ctx.Read(lowestPending, []distsys.TLAValue{}) + if err != nil { + continue + } + var exprRead21 distsys.TLAValue + exprRead21, err = ctx.Read(timestamp, []distsys.TLAValue{}) + if err != nil { + continue + } + var exprRead22 distsys.TLAValue + exprRead22, err = ctx.Read(lowestPending, []distsys.TLAValue{}) + if err != nil { + continue + } + var exprRead23 distsys.TLAValue + exprRead23, err = ctx.Read(nextClient, []distsys.TLAValue{}) + if err != nil { + continue + } + err = ctx.Write(chooseMessage, []distsys.TLAValue{}, distsys.TLA_LogicalOrSymbol(distsys.TLA_LessThanSymbol(exprRead19, exprRead20), distsys.TLA_LogicalAndSymbol(distsys.TLA_EqualsSymbol(exprRead21, exprRead22), distsys.TLA_LessThanSymbol(client0, exprRead23)))) + if err != nil { + continue + } + var condition17 distsys.TLAValue + condition17, err = ctx.Read(chooseMessage, []distsys.TLAValue{}) + if err != nil { + continue + } + if condition17.AsBool() { + err = ctx.Write(nextClient, []distsys.TLAValue{}, client0) + if err != nil { + continue + } + var exprRead24 distsys.TLAValue + exprRead24, err = ctx.Read(timestamp, []distsys.TLAValue{}) + if err != nil { + continue + } + err = ctx.Write(lowestPending, []distsys.TLAValue{}, exprRead24) + if err != nil { + continue + } + // no statements + } else { + // no statements + } + // no statements + } else { + // no statements + } + var exprRead25 distsys.TLAValue + exprRead25, err = ctx.Read(pendingClients, []distsys.TLAValue{}) + if err != nil { + continue + } + err = ctx.Write(pendingClients, []distsys.TLAValue{}, distsys.TLA_BackslashSymbol(exprRead25, distsys.NewTLASet(client0))) + if err != nil { + continue + } + err = ctx.Write(programCounter, []distsys.TLAValue{}, distsys.NewTLANumber(findMinClientLabelTag)) + if err != nil { + continue + } + err = ctx.Commit() + if err != nil { + continue + } + // no statements + } else { + err = ctx.Write(programCounter, []distsys.TLAValue{}, distsys.NewTLANumber(addStableMessageLabelTag)) + if err != nil { + continue + } + err = ctx.Commit() + if err != nil { + continue + } + } + // no statements + case addStableMessageLabelTag: + var condition18 distsys.TLAValue + condition18, err = ctx.Read(lowestPending, []distsys.TLAValue{}) + if err != nil { + continue + } + var condition19 distsys.TLAValue + condition19, err = ctx.Read(minClock, []distsys.TLAValue{}) + if err != nil { + continue + } + if distsys.TLA_LessThanSymbol(condition18, condition19).AsBool() { + var exprRead26 distsys.TLAValue + exprRead26, err = ctx.Read(pendingRequests, []distsys.TLAValue{}) + if err != nil { + continue + } + var exprRead27 distsys.TLAValue + exprRead27, err = ctx.Read(nextClient, []distsys.TLAValue{}) + if err != nil { + continue + } + err = ctx.Write(msg, []distsys.TLAValue{}, distsys.TLA_Head(exprRead26.ApplyFunction(exprRead27))) + if err != nil { + continue + } + var exprRead28 distsys.TLAValue + exprRead28, err = ctx.Read(pendingRequests, []distsys.TLAValue{}) + if err != nil { + continue + } + var exprRead29 distsys.TLAValue + exprRead29, err = ctx.Read(nextClient, []distsys.TLAValue{}) + if err != nil { + continue + } + var indexRead4 distsys.TLAValue + indexRead4, err = ctx.Read(nextClient, []distsys.TLAValue{}) + if err != nil { + continue + } + err = ctx.Write(pendingRequests, []distsys.TLAValue{indexRead4}, distsys.TLA_Tail(exprRead28.ApplyFunction(exprRead29))) + if err != nil { + continue + } + var exprRead30 distsys.TLAValue + exprRead30, err = ctx.Read(stableMessages, []distsys.TLAValue{}) + if err != nil { + continue + } + var exprRead31 distsys.TLAValue + exprRead31, err = ctx.Read(msg, []distsys.TLAValue{}) + if err != nil { + continue + } + err = ctx.Write(stableMessages, []distsys.TLAValue{}, distsys.TLA_Append(exprRead30, exprRead31)) + if err != nil { + continue + } + err = ctx.Write(programCounter, []distsys.TLAValue{}, distsys.NewTLANumber(findStableRequestsLoopLabelTag)) + if err != nil { + continue + } + err = ctx.Commit() + if err != nil { + continue + } + } else { + err = ctx.Write(continue0, []distsys.TLAValue{}, distsys.TLA_FALSE) + if err != nil { + continue + } + err = ctx.Write(programCounter, []distsys.TLAValue{}, distsys.NewTLANumber(findStableRequestsLoopLabelTag)) + if err != nil { + continue + } + err = ctx.Commit() + if err != nil { + continue + } + } + // no statements + case respondPendingRequestsLoopLabelTag: + var condition20 distsys.TLAValue + condition20, err = ctx.Read(i, []distsys.TLAValue{}) + if err != nil { + continue + } + var condition21 distsys.TLAValue + condition21, err = ctx.Read(stableMessages, []distsys.TLAValue{}) + if err != nil { + continue + } + if distsys.TLA_LessThanOrEqualSymbol(condition20, distsys.TLA_Len(condition21)).AsBool() { + var exprRead32 distsys.TLAValue + exprRead32, err = ctx.Read(stableMessages, []distsys.TLAValue{}) + if err != nil { + continue + } + var exprRead33 distsys.TLAValue + exprRead33, err = ctx.Read(i, []distsys.TLAValue{}) + if err != nil { + continue + } + err = ctx.Write(msg, []distsys.TLAValue{}, exprRead32.ApplyFunction(exprRead33)) + if err != nil { + continue + } + var exprRead34 distsys.TLAValue + exprRead34, err = ctx.Read(i, []distsys.TLAValue{}) + if err != nil { + continue + } + err = ctx.Write(i, []distsys.TLAValue{}, distsys.TLA_PlusSymbol(exprRead34, distsys.NewTLANumber(1))) + if err != nil { + continue + } + err = ctx.Write(programCounter, []distsys.TLAValue{}, distsys.NewTLANumber(respondStableGetLabelTag)) + if err != nil { + continue + } + err = ctx.Commit() + if err != nil { + continue + } + } else { + err = ctx.Write(programCounter, []distsys.TLAValue{}, distsys.NewTLANumber(replicaLoopLabelTag)) + if err != nil { + continue + } + err = ctx.Commit() + if err != nil { + continue + } + } + // no statements + case respondStableGetLabelTag: + var condition22 distsys.TLAValue + condition22, err = ctx.Read(msg, []distsys.TLAValue{}) + if err != nil { + continue + } + if distsys.TLA_EqualsSymbol(condition22.ApplyFunction(distsys.NewTLAString("op")), constants.GET_MSG).AsBool() { + var exprRead35 distsys.TLAValue + exprRead35, err = ctx.Read(msg, []distsys.TLAValue{}) + if err != nil { + continue + } + err = ctx.Write(key, []distsys.TLAValue{}, exprRead35.ApplyFunction(distsys.NewTLAString("key"))) + if err != nil { + continue + } + var exprRead36 distsys.TLAValue + exprRead36, err = ctx.Read(key, []distsys.TLAValue{}) + if err != nil { + continue + } + var exprRead37 distsys.TLAValue + exprRead37, err = ctx.Read(kv, []distsys.TLAValue{exprRead36}) + if err != nil { + continue + } + err = ctx.Write(val, []distsys.TLAValue{}, exprRead37) + if err != nil { + continue + } + var exprRead38 distsys.TLAValue + exprRead38, err = ctx.Read(val, []distsys.TLAValue{}) + if err != nil { + continue + } + var indexRead5 distsys.TLAValue + indexRead5, err = ctx.Read(msg, []distsys.TLAValue{}) + if err != nil { + continue + } + err = ctx.Write(clients, []distsys.TLAValue{indexRead5.ApplyFunction(distsys.NewTLAString("reply_to"))}, distsys.NewTLARecord([]distsys.TLARecordField{ + {distsys.NewTLAString("type"), constants.GET_RESPONSE}, + {distsys.NewTLAString("result"), exprRead38}, + })) + if err != nil { + continue + } + err = ctx.Write(programCounter, []distsys.TLAValue{}, distsys.NewTLANumber(respondStablePutLabelTag)) + if err != nil { + continue + } + err = ctx.Commit() + if err != nil { + continue + } + } else { + err = ctx.Write(programCounter, []distsys.TLAValue{}, distsys.NewTLANumber(respondStablePutLabelTag)) + if err != nil { + continue + } + err = ctx.Commit() + if err != nil { + continue + } + } + // no statements + case respondStablePutLabelTag: + var condition23 distsys.TLAValue + condition23, err = ctx.Read(msg, []distsys.TLAValue{}) + if err != nil { + continue + } + if distsys.TLA_EqualsSymbol(condition23.ApplyFunction(distsys.NewTLAString("op")), constants.PUT_MSG).AsBool() { + var exprRead39 distsys.TLAValue + exprRead39, err = ctx.Read(msg, []distsys.TLAValue{}) + if err != nil { + continue + } + err = ctx.Write(key, []distsys.TLAValue{}, exprRead39.ApplyFunction(distsys.NewTLAString("key"))) + if err != nil { + continue + } + var exprRead40 distsys.TLAValue + exprRead40, err = ctx.Read(msg, []distsys.TLAValue{}) + if err != nil { + continue + } + err = ctx.Write(val, []distsys.TLAValue{}, exprRead40.ApplyFunction(distsys.NewTLAString("value"))) + if err != nil { + continue + } + var exprRead41 distsys.TLAValue + exprRead41, err = ctx.Read(val, []distsys.TLAValue{}) + if err != nil { + continue + } + var indexRead6 distsys.TLAValue + indexRead6, err = ctx.Read(key, []distsys.TLAValue{}) + if err != nil { + continue + } + err = ctx.Write(kv, []distsys.TLAValue{indexRead6}, exprRead41) + if err != nil { + continue + } + var exprRead42 distsys.TLAValue + exprRead42, err = ctx.Read(ok, []distsys.TLAValue{}) + if err != nil { + continue + } + var indexRead7 distsys.TLAValue + indexRead7, err = ctx.Read(msg, []distsys.TLAValue{}) + if err != nil { + continue + } + err = ctx.Write(clients, []distsys.TLAValue{indexRead7.ApplyFunction(distsys.NewTLAString("reply_to"))}, distsys.NewTLARecord([]distsys.TLARecordField{ + {distsys.NewTLAString("type"), constants.PUT_RESPONSE}, + {distsys.NewTLAString("result"), exprRead42}, + })) + if err != nil { + continue + } + err = ctx.Write(programCounter, []distsys.TLAValue{}, distsys.NewTLANumber(respondPendingRequestsLoopLabelTag)) + if err != nil { + continue + } + err = ctx.Commit() + if err != nil { + continue + } + } else { + err = ctx.Write(programCounter, []distsys.TLAValue{}, distsys.NewTLANumber(respondPendingRequestsLoopLabelTag)) + if err != nil { + continue + } + err = ctx.Commit() + if err != nil { + continue + } + } + // no statements + case DoneLabelTag: + return nil + default: + return fmt.Errorf("invalid program counter %v", labelTag) + } + } +} + +func Get(ctx *distsys.MPCalContext, self distsys.TLAValue, constants Constants, clientId distsys.ArchetypeResourceHandle, replicas0 distsys.ArchetypeResourceHandle, clients0 distsys.ArchetypeResourceHandle, key0 distsys.TLAValue, clock distsys.ArchetypeResourceHandle, spin distsys.TLAValue, outside distsys.ArchetypeResourceHandle) error { + var err0 error + // label tags + const ( + InitLabelTag0 = iota + getLoopLabelTag + getRequestLabelTag + getReplyLabelTag + getCheckSpinLabelTag + DoneLabelTag0 + ) + programCounter0 := ctx.EnsureArchetypeResourceByPosition(distsys.LocalArchetypeResourceMaker(distsys.NewTLANumber(InitLabelTag0))) + key1 := ctx.EnsureArchetypeResourceByPosition(distsys.LocalArchetypeResourceMaker(key0)) + spin0 := ctx.EnsureArchetypeResourceByPosition(distsys.LocalArchetypeResourceMaker(spin)) + continue1 := ctx.EnsureArchetypeResourceByPosition(distsys.LocalArchetypeResourceMaker(distsys.TLAValue{})) + _ = continue1 + getReq := ctx.EnsureArchetypeResourceByPosition(distsys.LocalArchetypeResourceMaker(distsys.TLAValue{})) + _ = getReq + getResp := ctx.EnsureArchetypeResourceByPosition(distsys.LocalArchetypeResourceMaker(distsys.TLAValue{})) + _ = getResp + + for { + if err0 != nil { + if err0 == distsys.ErrCriticalSectionAborted { + ctx.Abort() + err0 = nil + } else { + return err0 + } + } + var labelTag0 distsys.TLAValue + labelTag0, err0 = ctx.Read(programCounter0, []distsys.TLAValue{}) + if err0 != nil { + return err0 + } + switch labelTag0.AsNumber() { + case InitLabelTag0: + err0 = ctx.Write(continue1, nil, distsys.TLA_TRUE) + if err0 != nil { + continue + } + err0 = ctx.Write(programCounter0, []distsys.TLAValue{}, distsys.NewTLANumber(getLoopLabelTag)) + if err0 != nil { + continue + } + case getLoopLabelTag: + var condition24 distsys.TLAValue + condition24, err0 = ctx.Read(continue1, []distsys.TLAValue{}) + if err0 != nil { + continue + } + if condition24.AsBool() { + err0 = ctx.Write(programCounter0, []distsys.TLAValue{}, distsys.NewTLANumber(getRequestLabelTag)) + if err0 != nil { + continue + } + err0 = ctx.Commit() + if err0 != nil { + continue + } + } else { + err0 = ctx.Write(programCounter0, []distsys.TLAValue{}, distsys.NewTLANumber(DoneLabelTag0)) + if err0 != nil { + continue + } + err0 = ctx.Commit() + if err0 != nil { + continue + } + } + // no statements + case getRequestLabelTag: + var condition25 distsys.TLAValue + condition25, err0 = ctx.Read(clientId, []distsys.TLAValue{}) + if err0 != nil { + continue + } + var condition26 distsys.TLAValue + condition26, err0 = ctx.Read(clock, []distsys.TLAValue{condition25}) + if err0 != nil { + continue + } + if distsys.TLA_EqualsSymbol(condition26, distsys.TLA_NegationSymbol(distsys.NewTLANumber(1))).AsBool() { + err0 = ctx.Write(continue1, []distsys.TLAValue{}, distsys.TLA_FALSE) + if err0 != nil { + continue + } + err0 = ctx.Write(programCounter0, []distsys.TLAValue{}, distsys.NewTLANumber(getCheckSpinLabelTag)) + if err0 != nil { + continue + } + err0 = ctx.Commit() + if err0 != nil { + continue + } + } else { + var exprRead43 distsys.TLAValue + exprRead43, err0 = ctx.Read(clientId, []distsys.TLAValue{}) + if err0 != nil { + continue + } + var exprRead44 distsys.TLAValue + exprRead44, err0 = ctx.Read(clock, []distsys.TLAValue{exprRead43}) + if err0 != nil { + continue + } + var indexRead8 distsys.TLAValue + indexRead8, err0 = ctx.Read(clientId, []distsys.TLAValue{}) + if err0 != nil { + continue + } + err0 = ctx.Write(clock, []distsys.TLAValue{indexRead8}, distsys.TLA_PlusSymbol(exprRead44, distsys.NewTLANumber(1))) + if err0 != nil { + continue + } + var exprRead45 distsys.TLAValue + exprRead45, err0 = ctx.Read(key1, []distsys.TLAValue{}) + if err0 != nil { + continue + } + var exprRead46 distsys.TLAValue + exprRead46, err0 = ctx.Read(clientId, []distsys.TLAValue{}) + if err0 != nil { + continue + } + var exprRead47 distsys.TLAValue + exprRead47, err0 = ctx.Read(clientId, []distsys.TLAValue{}) + if err0 != nil { + continue + } + var exprRead48 distsys.TLAValue + exprRead48, err0 = ctx.Read(clock, []distsys.TLAValue{exprRead47}) + if err0 != nil { + continue + } + err0 = ctx.Write(getReq, []distsys.TLAValue{}, distsys.NewTLARecord([]distsys.TLARecordField{ + {distsys.NewTLAString("op"), constants.GET_MSG}, + {distsys.NewTLAString("key"), exprRead45}, + {distsys.NewTLAString("client"), exprRead46}, + {distsys.NewTLAString("timestamp"), exprRead48}, + {distsys.NewTLAString("reply_to"), self}, + })) + if err0 != nil { + continue + } + var dst distsys.TLAValue = func() distsys.TLAValue { + return ReplicaSet(constants) + }().SelectElement() + var exprRead49 distsys.TLAValue + exprRead49, err0 = ctx.Read(getReq, []distsys.TLAValue{}) + if err0 != nil { + continue + } + err0 = ctx.Write(replicas0, []distsys.TLAValue{dst}, exprRead49) + if err0 != nil { + continue + } + err0 = ctx.Write(programCounter0, []distsys.TLAValue{}, distsys.NewTLANumber(getReplyLabelTag)) + if err0 != nil { + continue + } + err0 = ctx.Commit() + if err0 != nil { + continue + } + // no statements + } + // no statements + case getReplyLabelTag: + var condition27 distsys.TLAValue + condition27, err0 = ctx.Read(clientId, []distsys.TLAValue{}) + if err0 != nil { + continue + } + var condition28 distsys.TLAValue + condition28, err0 = ctx.Read(clock, []distsys.TLAValue{condition27}) + if err0 != nil { + continue + } + if distsys.TLA_EqualsSymbol(condition28, distsys.TLA_NegationSymbol(distsys.NewTLANumber(1))).AsBool() { + err0 = ctx.Write(continue1, []distsys.TLAValue{}, distsys.TLA_FALSE) + if err0 != nil { + continue + } + err0 = ctx.Write(programCounter0, []distsys.TLAValue{}, distsys.NewTLANumber(getCheckSpinLabelTag)) + if err0 != nil { + continue + } + err0 = ctx.Commit() + if err0 != nil { + continue + } + } else { + var exprRead50 distsys.TLAValue + exprRead50, err0 = ctx.Read(clients0, []distsys.TLAValue{self}) + if err0 != nil { + continue + } + err0 = ctx.Write(getResp, []distsys.TLAValue{}, exprRead50) + if err0 != nil { + continue + } + var condition29 distsys.TLAValue + condition29, err0 = ctx.Read(getResp, []distsys.TLAValue{}) + if err0 != nil { + continue + } + if !distsys.TLA_EqualsSymbol(condition29.ApplyFunction(distsys.NewTLAString("type")), constants.GET_RESPONSE).AsBool() { + err0 = fmt.Errorf("%w: ((getResp).type) = (GET_RESPONSE)", distsys.ErrAssertionFailed) + continue + } + var exprRead51 distsys.TLAValue + exprRead51, err0 = ctx.Read(getResp, []distsys.TLAValue{}) + if err0 != nil { + continue + } + err0 = ctx.Write(outside, []distsys.TLAValue{}, exprRead51.ApplyFunction(distsys.NewTLAString("result"))) + if err0 != nil { + continue + } + err0 = ctx.Write(programCounter0, []distsys.TLAValue{}, distsys.NewTLANumber(getCheckSpinLabelTag)) + if err0 != nil { + continue + } + err0 = ctx.Commit() + if err0 != nil { + continue + } + } + // no statements + case getCheckSpinLabelTag: + var condition30 distsys.TLAValue + condition30, err0 = ctx.Read(spin0, []distsys.TLAValue{}) + if err0 != nil { + continue + } + if distsys.TLA_LogicalNotSymbol(condition30).AsBool() { + err0 = ctx.Write(continue1, []distsys.TLAValue{}, distsys.TLA_FALSE) + if err0 != nil { + continue + } + err0 = ctx.Write(programCounter0, []distsys.TLAValue{}, distsys.NewTLANumber(getLoopLabelTag)) + if err0 != nil { + continue + } + err0 = ctx.Commit() + if err0 != nil { + continue + } + } else { + err0 = ctx.Write(programCounter0, []distsys.TLAValue{}, distsys.NewTLANumber(getLoopLabelTag)) + if err0 != nil { + continue + } + err0 = ctx.Commit() + if err0 != nil { + continue + } + } + // no statements + case DoneLabelTag0: + return nil + default: + return fmt.Errorf("invalid program counter %v", labelTag0) + } + } +} + +func Put(ctx *distsys.MPCalContext, self distsys.TLAValue, constants Constants, clientId0 distsys.ArchetypeResourceHandle, replicas1 distsys.ArchetypeResourceHandle, clients1 distsys.ArchetypeResourceHandle, key2 distsys.TLAValue, value distsys.TLAValue, clock0 distsys.ArchetypeResourceHandle, spin1 distsys.TLAValue, outside0 distsys.ArchetypeResourceHandle) error { + var err1 error + // label tags + const ( + InitLabelTag1 = iota + putLoopLabelTag + putRequestLabelTag + putBroadcastLabelTag + putResponseLabelTag + putCompleteLabelTag + putCheckSpinLabelTag + DoneLabelTag1 + ) + programCounter1 := ctx.EnsureArchetypeResourceByPosition(distsys.LocalArchetypeResourceMaker(distsys.NewTLANumber(InitLabelTag1))) + key3 := ctx.EnsureArchetypeResourceByPosition(distsys.LocalArchetypeResourceMaker(key2)) + value0 := ctx.EnsureArchetypeResourceByPosition(distsys.LocalArchetypeResourceMaker(value)) + spin2 := ctx.EnsureArchetypeResourceByPosition(distsys.LocalArchetypeResourceMaker(spin1)) + continue2 := ctx.EnsureArchetypeResourceByPosition(distsys.LocalArchetypeResourceMaker(distsys.TLAValue{})) + _ = continue2 + i0 := ctx.EnsureArchetypeResourceByPosition(distsys.LocalArchetypeResourceMaker(distsys.TLAValue{})) + _ = i0 + j := ctx.EnsureArchetypeResourceByPosition(distsys.LocalArchetypeResourceMaker(distsys.TLAValue{})) + _ = j + putReq := ctx.EnsureArchetypeResourceByPosition(distsys.LocalArchetypeResourceMaker(distsys.TLAValue{})) + _ = putReq + putResp := ctx.EnsureArchetypeResourceByPosition(distsys.LocalArchetypeResourceMaker(distsys.TLAValue{})) + _ = putResp + + for { + if err1 != nil { + if err1 == distsys.ErrCriticalSectionAborted { + ctx.Abort() + err1 = nil + } else { + return err1 + } + } + var labelTag1 distsys.TLAValue + labelTag1, err1 = ctx.Read(programCounter1, []distsys.TLAValue{}) + if err1 != nil { + return err1 + } + switch labelTag1.AsNumber() { + case InitLabelTag1: + err1 = ctx.Write(continue2, nil, distsys.TLA_TRUE) + if err1 != nil { + continue + } + err1 = ctx.Write(programCounter1, []distsys.TLAValue{}, distsys.NewTLANumber(putLoopLabelTag)) + if err1 != nil { + continue + } + case putLoopLabelTag: + var condition31 distsys.TLAValue + condition31, err1 = ctx.Read(continue2, []distsys.TLAValue{}) + if err1 != nil { + continue + } + if condition31.AsBool() { + err1 = ctx.Write(programCounter1, []distsys.TLAValue{}, distsys.NewTLANumber(putRequestLabelTag)) + if err1 != nil { + continue + } + err1 = ctx.Commit() + if err1 != nil { + continue + } + } else { + err1 = ctx.Write(programCounter1, []distsys.TLAValue{}, distsys.NewTLANumber(DoneLabelTag1)) + if err1 != nil { + continue + } + err1 = ctx.Commit() + if err1 != nil { + continue + } + } + // no statements + case putRequestLabelTag: + var condition32 distsys.TLAValue + condition32, err1 = ctx.Read(clientId0, []distsys.TLAValue{}) + if err1 != nil { + continue + } + var condition33 distsys.TLAValue + condition33, err1 = ctx.Read(clock0, []distsys.TLAValue{condition32}) + if err1 != nil { + continue + } + if distsys.TLA_EqualsSymbol(condition33, distsys.TLA_NegationSymbol(distsys.NewTLANumber(1))).AsBool() { + err1 = ctx.Write(continue2, []distsys.TLAValue{}, distsys.TLA_FALSE) + if err1 != nil { + continue + } + err1 = ctx.Write(programCounter1, []distsys.TLAValue{}, distsys.NewTLANumber(putCheckSpinLabelTag)) + if err1 != nil { + continue + } + err1 = ctx.Commit() + if err1 != nil { + continue + } + } else { + var exprRead52 distsys.TLAValue + exprRead52, err1 = ctx.Read(clientId0, []distsys.TLAValue{}) + if err1 != nil { + continue + } + var exprRead53 distsys.TLAValue + exprRead53, err1 = ctx.Read(clock0, []distsys.TLAValue{exprRead52}) + if err1 != nil { + continue + } + var indexRead9 distsys.TLAValue + indexRead9, err1 = ctx.Read(clientId0, []distsys.TLAValue{}) + if err1 != nil { + continue + } + err1 = ctx.Write(clock0, []distsys.TLAValue{indexRead9}, distsys.TLA_PlusSymbol(exprRead53, distsys.NewTLANumber(1))) + if err1 != nil { + continue + } + var exprRead54 distsys.TLAValue + exprRead54, err1 = ctx.Read(key3, []distsys.TLAValue{}) + if err1 != nil { + continue + } + var exprRead55 distsys.TLAValue + exprRead55, err1 = ctx.Read(value0, []distsys.TLAValue{}) + if err1 != nil { + continue + } + var exprRead56 distsys.TLAValue + exprRead56, err1 = ctx.Read(clientId0, []distsys.TLAValue{}) + if err1 != nil { + continue + } + var exprRead57 distsys.TLAValue + exprRead57, err1 = ctx.Read(clientId0, []distsys.TLAValue{}) + if err1 != nil { + continue + } + var exprRead58 distsys.TLAValue + exprRead58, err1 = ctx.Read(clock0, []distsys.TLAValue{exprRead57}) + if err1 != nil { + continue + } + err1 = ctx.Write(putReq, []distsys.TLAValue{}, distsys.NewTLARecord([]distsys.TLARecordField{ + {distsys.NewTLAString("op"), constants.PUT_MSG}, + {distsys.NewTLAString("key"), exprRead54}, + {distsys.NewTLAString("value"), exprRead55}, + {distsys.NewTLAString("client"), exprRead56}, + {distsys.NewTLAString("timestamp"), exprRead58}, + {distsys.NewTLAString("reply_to"), self}, + })) + if err1 != nil { + continue + } + err1 = ctx.Write(i0, []distsys.TLAValue{}, distsys.NewTLANumber(0)) + if err1 != nil { + continue + } + err1 = ctx.Write(j, []distsys.TLAValue{}, distsys.NewTLANumber(0)) + if err1 != nil { + continue + } + err1 = ctx.Write(programCounter1, []distsys.TLAValue{}, distsys.NewTLANumber(putBroadcastLabelTag)) + if err1 != nil { + continue + } + err1 = ctx.Commit() + if err1 != nil { + continue + } + } + // no statements + case putBroadcastLabelTag: + var condition34 distsys.TLAValue + condition34, err1 = ctx.Read(j, []distsys.TLAValue{}) + if err1 != nil { + continue + } + var condition35 distsys.TLAValue + condition35, err1 = ctx.Read(clientId0, []distsys.TLAValue{}) + if err1 != nil { + continue + } + var condition36 distsys.TLAValue + condition36, err1 = ctx.Read(clock0, []distsys.TLAValue{condition35}) + if err1 != nil { + continue + } + if distsys.TLA_LogicalAndSymbol(distsys.TLA_LessThanOrEqualSymbol(condition34, distsys.TLA_MinusSymbol(constants.NUM_REPLICAS, distsys.NewTLANumber(1))), distsys.TLA_NotEqualsSymbol(condition36, distsys.TLA_NegationSymbol(distsys.NewTLANumber(1)))).AsBool() { + var exprRead59 distsys.TLAValue + exprRead59, err1 = ctx.Read(putReq, []distsys.TLAValue{}) + if err1 != nil { + continue + } + var indexRead10 distsys.TLAValue + indexRead10, err1 = ctx.Read(j, []distsys.TLAValue{}) + if err1 != nil { + continue + } + err1 = ctx.Write(replicas1, []distsys.TLAValue{indexRead10}, exprRead59) + if err1 != nil { + continue + } + var exprRead60 distsys.TLAValue + exprRead60, err1 = ctx.Read(j, []distsys.TLAValue{}) + if err1 != nil { + continue + } + err1 = ctx.Write(j, []distsys.TLAValue{}, distsys.TLA_PlusSymbol(exprRead60, distsys.NewTLANumber(1))) + if err1 != nil { + continue + } + err1 = ctx.Write(programCounter1, []distsys.TLAValue{}, distsys.NewTLANumber(putBroadcastLabelTag)) + if err1 != nil { + continue + } + err1 = ctx.Commit() + if err1 != nil { + continue + } + } else { + err1 = ctx.Write(programCounter1, []distsys.TLAValue{}, distsys.NewTLANumber(putResponseLabelTag)) + if err1 != nil { + continue + } + err1 = ctx.Commit() + if err1 != nil { + continue + } + } + // no statements + case putResponseLabelTag: + var condition37 distsys.TLAValue + condition37, err1 = ctx.Read(i0, []distsys.TLAValue{}) + if err1 != nil { + continue + } + if distsys.TLA_LessThanSymbol(condition37, distsys.TLA_Cardinality(func() distsys.TLAValue { + return ReplicaSet(constants) + }())).AsBool() { + var condition38 distsys.TLAValue + condition38, err1 = ctx.Read(clientId0, []distsys.TLAValue{}) + if err1 != nil { + continue + } + var condition39 distsys.TLAValue + condition39, err1 = ctx.Read(clock0, []distsys.TLAValue{condition38}) + if err1 != nil { + continue + } + if distsys.TLA_EqualsSymbol(condition39, distsys.TLA_NegationSymbol(distsys.NewTLANumber(1))).AsBool() { + err1 = ctx.Write(continue2, []distsys.TLAValue{}, distsys.TLA_FALSE) + if err1 != nil { + continue + } + err1 = ctx.Write(programCounter1, []distsys.TLAValue{}, distsys.NewTLANumber(putLoopLabelTag)) + if err1 != nil { + continue + } + err1 = ctx.Commit() + if err1 != nil { + continue + } + } else { + var exprRead61 distsys.TLAValue + exprRead61, err1 = ctx.Read(clients1, []distsys.TLAValue{self}) + if err1 != nil { + continue + } + err1 = ctx.Write(putResp, []distsys.TLAValue{}, exprRead61) + if err1 != nil { + continue + } + var condition40 distsys.TLAValue + condition40, err1 = ctx.Read(putResp, []distsys.TLAValue{}) + if err1 != nil { + continue + } + if !distsys.TLA_EqualsSymbol(condition40.ApplyFunction(distsys.NewTLAString("type")), constants.PUT_RESPONSE).AsBool() { + err1 = fmt.Errorf("%w: ((putResp).type) = (PUT_RESPONSE)", distsys.ErrAssertionFailed) + continue + } + var exprRead62 distsys.TLAValue + exprRead62, err1 = ctx.Read(i0, []distsys.TLAValue{}) + if err1 != nil { + continue + } + err1 = ctx.Write(i0, []distsys.TLAValue{}, distsys.TLA_PlusSymbol(exprRead62, distsys.NewTLANumber(1))) + if err1 != nil { + continue + } + err1 = ctx.Write(programCounter1, []distsys.TLAValue{}, distsys.NewTLANumber(putResponseLabelTag)) + if err1 != nil { + continue + } + err1 = ctx.Commit() + if err1 != nil { + continue + } + } + // no statements + } else { + err1 = ctx.Write(programCounter1, []distsys.TLAValue{}, distsys.NewTLANumber(putCompleteLabelTag)) + if err1 != nil { + continue + } + err1 = ctx.Commit() + if err1 != nil { + continue + } + } + // no statements + case putCompleteLabelTag: + err1 = ctx.Write(outside0, []distsys.TLAValue{}, constants.PUT_RESPONSE) + if err1 != nil { + continue + } + err1 = ctx.Write(programCounter1, []distsys.TLAValue{}, distsys.NewTLANumber(putCheckSpinLabelTag)) + if err1 != nil { + continue + } + err1 = ctx.Commit() + if err1 != nil { + continue + } + case putCheckSpinLabelTag: + var condition41 distsys.TLAValue + condition41, err1 = ctx.Read(spin2, []distsys.TLAValue{}) + if err1 != nil { + continue + } + if distsys.TLA_LogicalNotSymbol(condition41).AsBool() { + err1 = ctx.Write(continue2, []distsys.TLAValue{}, distsys.TLA_FALSE) + if err1 != nil { + continue + } + err1 = ctx.Write(programCounter1, []distsys.TLAValue{}, distsys.NewTLANumber(putLoopLabelTag)) + if err1 != nil { + continue + } + err1 = ctx.Commit() + if err1 != nil { + continue + } + } else { + err1 = ctx.Write(programCounter1, []distsys.TLAValue{}, distsys.NewTLANumber(putLoopLabelTag)) + if err1 != nil { + continue + } + err1 = ctx.Commit() + if err1 != nil { + continue + } + } + // no statements + case DoneLabelTag1: + return nil + default: + return fmt.Errorf("invalid program counter %v", labelTag1) + } + } +} + +func Disconnect(ctx *distsys.MPCalContext, self distsys.TLAValue, constants Constants, clientId1 distsys.ArchetypeResourceHandle, replicas2 distsys.ArchetypeResourceHandle, clock1 distsys.ArchetypeResourceHandle) error { + var err2 error + // label tags + const ( + InitLabelTag2 = iota + sendDisconnectRequestLabelTag + disconnectBroadcastLabelTag + DoneLabelTag2 + ) + programCounter2 := ctx.EnsureArchetypeResourceByPosition(distsys.LocalArchetypeResourceMaker(distsys.NewTLANumber(InitLabelTag2))) + msg0 := ctx.EnsureArchetypeResourceByPosition(distsys.LocalArchetypeResourceMaker(distsys.TLAValue{})) + _ = msg0 + j0 := ctx.EnsureArchetypeResourceByPosition(distsys.LocalArchetypeResourceMaker(distsys.TLAValue{})) + _ = j0 + + for { + if err2 != nil { + if err2 == distsys.ErrCriticalSectionAborted { + ctx.Abort() + err2 = nil + } else { + return err2 + } + } + var labelTag2 distsys.TLAValue + labelTag2, err2 = ctx.Read(programCounter2, []distsys.TLAValue{}) + if err2 != nil { + return err2 + } + switch labelTag2.AsNumber() { + case InitLabelTag2: + err2 = ctx.Write(programCounter2, []distsys.TLAValue{}, distsys.NewTLANumber(sendDisconnectRequestLabelTag)) + if err2 != nil { + continue + } + case sendDisconnectRequestLabelTag: + var exprRead63 distsys.TLAValue + exprRead63, err2 = ctx.Read(clientId1, []distsys.TLAValue{}) + if err2 != nil { + continue + } + err2 = ctx.Write(msg0, []distsys.TLAValue{}, distsys.NewTLARecord([]distsys.TLARecordField{ + {distsys.NewTLAString("op"), constants.DISCONNECT_MSG}, + {distsys.NewTLAString("client"), exprRead63}, + })) + if err2 != nil { + continue + } + var indexRead11 distsys.TLAValue + indexRead11, err2 = ctx.Read(clientId1, []distsys.TLAValue{}) + if err2 != nil { + continue + } + err2 = ctx.Write(clock1, []distsys.TLAValue{indexRead11}, distsys.TLA_NegationSymbol(distsys.NewTLANumber(1))) + if err2 != nil { + continue + } + err2 = ctx.Write(j0, []distsys.TLAValue{}, distsys.NewTLANumber(0)) + if err2 != nil { + continue + } + err2 = ctx.Write(programCounter2, []distsys.TLAValue{}, distsys.NewTLANumber(disconnectBroadcastLabelTag)) + if err2 != nil { + continue + } + err2 = ctx.Commit() + if err2 != nil { + continue + } + case disconnectBroadcastLabelTag: + var condition42 distsys.TLAValue + condition42, err2 = ctx.Read(j0, []distsys.TLAValue{}) + if err2 != nil { + continue + } + if distsys.TLA_LogicalAndSymbol(distsys.TLA_LessThanOrEqualSymbol(condition42, distsys.TLA_MinusSymbol(constants.NUM_REPLICAS, distsys.NewTLANumber(1))), distsys.TLA_NotEqualsSymbol(distsys.NewTLANumber(0), distsys.TLA_NegationSymbol(distsys.NewTLANumber(1)))).AsBool() { + var exprRead64 distsys.TLAValue + exprRead64, err2 = ctx.Read(msg0, []distsys.TLAValue{}) + if err2 != nil { + continue + } + var indexRead12 distsys.TLAValue + indexRead12, err2 = ctx.Read(j0, []distsys.TLAValue{}) + if err2 != nil { + continue + } + err2 = ctx.Write(replicas2, []distsys.TLAValue{indexRead12}, exprRead64) + if err2 != nil { + continue + } + var exprRead65 distsys.TLAValue + exprRead65, err2 = ctx.Read(j0, []distsys.TLAValue{}) + if err2 != nil { + continue + } + err2 = ctx.Write(j0, []distsys.TLAValue{}, distsys.TLA_PlusSymbol(exprRead65, distsys.NewTLANumber(1))) + if err2 != nil { + continue + } + err2 = ctx.Write(programCounter2, []distsys.TLAValue{}, distsys.NewTLANumber(disconnectBroadcastLabelTag)) + if err2 != nil { + continue + } + err2 = ctx.Commit() + if err2 != nil { + continue + } + } else { + err2 = ctx.Write(programCounter2, []distsys.TLAValue{}, distsys.NewTLANumber(DoneLabelTag2)) + if err2 != nil { + continue + } + err2 = ctx.Commit() + if err2 != nil { + continue + } + } + // no statements + case DoneLabelTag2: + return nil + default: + return fmt.Errorf("invalid program counter %v", labelTag2) + } + } +} + +func ClockUpdate(ctx *distsys.MPCalContext, self distsys.TLAValue, constants Constants, clientId2 distsys.ArchetypeResourceHandle, replicas3 distsys.ArchetypeResourceHandle, clock2 distsys.ArchetypeResourceHandle, spin3 distsys.TLAValue) error { + var err3 error + // label tags + const ( + InitLabelTag3 = iota + clockUpdateLoopLabelTag + nullBroadcastLabelTag + nullCheckSpinLabelTag + DoneLabelTag3 + ) + programCounter3 := ctx.EnsureArchetypeResourceByPosition(distsys.LocalArchetypeResourceMaker(distsys.NewTLANumber(InitLabelTag3))) + spin4 := ctx.EnsureArchetypeResourceByPosition(distsys.LocalArchetypeResourceMaker(spin3)) + continue3 := ctx.EnsureArchetypeResourceByPosition(distsys.LocalArchetypeResourceMaker(distsys.TLAValue{})) + _ = continue3 + j1 := ctx.EnsureArchetypeResourceByPosition(distsys.LocalArchetypeResourceMaker(distsys.TLAValue{})) + _ = j1 + msg1 := ctx.EnsureArchetypeResourceByPosition(distsys.LocalArchetypeResourceMaker(distsys.TLAValue{})) + _ = msg1 + + for { + if err3 != nil { + if err3 == distsys.ErrCriticalSectionAborted { + ctx.Abort() + err3 = nil + } else { + return err3 + } + } + var labelTag3 distsys.TLAValue + labelTag3, err3 = ctx.Read(programCounter3, []distsys.TLAValue{}) + if err3 != nil { + return err3 + } + switch labelTag3.AsNumber() { + case InitLabelTag3: + err3 = ctx.Write(continue3, nil, distsys.TLA_TRUE) + if err3 != nil { + continue + } + err3 = ctx.Write(programCounter3, []distsys.TLAValue{}, distsys.NewTLANumber(clockUpdateLoopLabelTag)) + if err3 != nil { + continue + } + case clockUpdateLoopLabelTag: + var condition43 distsys.TLAValue + condition43, err3 = ctx.Read(continue3, []distsys.TLAValue{}) + if err3 != nil { + continue + } + if condition43.AsBool() { + var condition44 distsys.TLAValue + condition44, err3 = ctx.Read(clientId2, []distsys.TLAValue{}) + if err3 != nil { + continue + } + var condition45 distsys.TLAValue + condition45, err3 = ctx.Read(clock2, []distsys.TLAValue{condition44}) + if err3 != nil { + continue + } + if distsys.TLA_EqualsSymbol(condition45, distsys.TLA_NegationSymbol(distsys.NewTLANumber(1))).AsBool() { + err3 = ctx.Write(continue3, []distsys.TLAValue{}, distsys.TLA_FALSE) + if err3 != nil { + continue + } + err3 = ctx.Write(programCounter3, []distsys.TLAValue{}, distsys.NewTLANumber(nullCheckSpinLabelTag)) + if err3 != nil { + continue + } + err3 = ctx.Commit() + if err3 != nil { + continue + } + } else { + var exprRead66 distsys.TLAValue + exprRead66, err3 = ctx.Read(clientId2, []distsys.TLAValue{}) + if err3 != nil { + continue + } + var exprRead67 distsys.TLAValue + exprRead67, err3 = ctx.Read(clock2, []distsys.TLAValue{exprRead66}) + if err3 != nil { + continue + } + var indexRead13 distsys.TLAValue + indexRead13, err3 = ctx.Read(clientId2, []distsys.TLAValue{}) + if err3 != nil { + continue + } + err3 = ctx.Write(clock2, []distsys.TLAValue{indexRead13}, distsys.TLA_PlusSymbol(exprRead67, distsys.NewTLANumber(1))) + if err3 != nil { + continue + } + var exprRead68 distsys.TLAValue + exprRead68, err3 = ctx.Read(clientId2, []distsys.TLAValue{}) + if err3 != nil { + continue + } + var exprRead69 distsys.TLAValue + exprRead69, err3 = ctx.Read(clientId2, []distsys.TLAValue{}) + if err3 != nil { + continue + } + var exprRead70 distsys.TLAValue + exprRead70, err3 = ctx.Read(clock2, []distsys.TLAValue{exprRead69}) + if err3 != nil { + continue + } + err3 = ctx.Write(msg1, []distsys.TLAValue{}, distsys.NewTLARecord([]distsys.TLARecordField{ + {distsys.NewTLAString("op"), constants.NULL_MSG}, + {distsys.NewTLAString("client"), exprRead68}, + {distsys.NewTLAString("timestamp"), exprRead70}, + })) + if err3 != nil { + continue + } + err3 = ctx.Write(j1, []distsys.TLAValue{}, distsys.NewTLANumber(0)) + if err3 != nil { + continue + } + err3 = ctx.Write(programCounter3, []distsys.TLAValue{}, distsys.NewTLANumber(nullBroadcastLabelTag)) + if err3 != nil { + continue + } + err3 = ctx.Commit() + if err3 != nil { + continue + } + } + // no statements + } else { + err3 = ctx.Write(programCounter3, []distsys.TLAValue{}, distsys.NewTLANumber(DoneLabelTag3)) + if err3 != nil { + continue + } + err3 = ctx.Commit() + if err3 != nil { + continue + } + } + // no statements + case nullBroadcastLabelTag: + var condition46 distsys.TLAValue + condition46, err3 = ctx.Read(j1, []distsys.TLAValue{}) + if err3 != nil { + continue + } + var condition47 distsys.TLAValue + condition47, err3 = ctx.Read(clientId2, []distsys.TLAValue{}) + if err3 != nil { + continue + } + var condition48 distsys.TLAValue + condition48, err3 = ctx.Read(clock2, []distsys.TLAValue{condition47}) + if err3 != nil { + continue + } + if distsys.TLA_LogicalAndSymbol(distsys.TLA_LessThanOrEqualSymbol(condition46, distsys.TLA_MinusSymbol(constants.NUM_REPLICAS, distsys.NewTLANumber(1))), distsys.TLA_NotEqualsSymbol(condition48, distsys.TLA_NegationSymbol(distsys.NewTLANumber(1)))).AsBool() { + var exprRead71 distsys.TLAValue + exprRead71, err3 = ctx.Read(msg1, []distsys.TLAValue{}) + if err3 != nil { + continue + } + var indexRead14 distsys.TLAValue + indexRead14, err3 = ctx.Read(j1, []distsys.TLAValue{}) + if err3 != nil { + continue + } + err3 = ctx.Write(replicas3, []distsys.TLAValue{indexRead14}, exprRead71) + if err3 != nil { + continue + } + var exprRead72 distsys.TLAValue + exprRead72, err3 = ctx.Read(j1, []distsys.TLAValue{}) + if err3 != nil { + continue + } + err3 = ctx.Write(j1, []distsys.TLAValue{}, distsys.TLA_PlusSymbol(exprRead72, distsys.NewTLANumber(1))) + if err3 != nil { + continue + } + err3 = ctx.Write(programCounter3, []distsys.TLAValue{}, distsys.NewTLANumber(nullBroadcastLabelTag)) + if err3 != nil { + continue + } + err3 = ctx.Commit() + if err3 != nil { + continue + } + } else { + err3 = ctx.Write(programCounter3, []distsys.TLAValue{}, distsys.NewTLANumber(nullCheckSpinLabelTag)) + if err3 != nil { + continue + } + err3 = ctx.Commit() + if err3 != nil { + continue + } + } + // no statements + case nullCheckSpinLabelTag: + var condition49 distsys.TLAValue + condition49, err3 = ctx.Read(spin4, []distsys.TLAValue{}) + if err3 != nil { + continue + } + if distsys.TLA_LogicalNotSymbol(condition49).AsBool() { + err3 = ctx.Write(continue3, []distsys.TLAValue{}, distsys.TLA_FALSE) + if err3 != nil { + continue + } + err3 = ctx.Write(programCounter3, []distsys.TLAValue{}, distsys.NewTLANumber(clockUpdateLoopLabelTag)) + if err3 != nil { + continue + } + err3 = ctx.Commit() + if err3 != nil { + continue + } + } else { + err3 = ctx.Write(programCounter3, []distsys.TLAValue{}, distsys.NewTLANumber(clockUpdateLoopLabelTag)) + if err3 != nil { + continue + } + err3 = ctx.Commit() + if err3 != nil { + continue + } + } + // no statements + case DoneLabelTag3: + return nil + default: + return fmt.Errorf("invalid program counter %v", labelTag3) + } + } +} diff --git a/test/files/general/replicated_kv.tla.gotests/replicated_kv_test.go b/test/files/general/replicated_kv.tla.gotests/replicated_kv_test.go new file mode 100644 index 000000000..7fdca88c4 --- /dev/null +++ b/test/files/general/replicated_kv.tla.gotests/replicated_kv_test.go @@ -0,0 +1,7 @@ +package replicatedkv + +import "testing" + +func TestOneReplica(t *testing.T) { + t.Fail() +} diff --git a/test/pgo/TLAExpressionFuzzTests.scala b/test/pgo/TLAExpressionFuzzTests.scala index aa31882dc..7694edcb2 100644 --- a/test/pgo/TLAExpressionFuzzTests.scala +++ b/test/pgo/TLAExpressionFuzzTests.scala @@ -46,24 +46,10 @@ class TLAExpressionFuzzTests extends AnyFunSuite with ScalaCheckPropertyChecks { |import "github.com/UBC-NSS/pgo/distsys" |import "example.org/testbed" | - |type dummyDurableStorage struct{} - | - |var _ distsys.MPCalDurableStorage = &dummyDurableStorage{} - | - |func (d dummyDurableStorage) RecoverResources() (rec *distsys.MPCalDurableStorageRecord, err error) { - | return nil, nil - |} - | - |func (d dummyDurableStorage) SnapshotResources(rec *distsys.MPCalDurableStorageRecord) { - | // pass - |} | |func main() { - | ctx, err := distsys.NewMPCalContext(&dummyDurableStorage{}) - | if err != nil { - | panic(err) - | } - | err = testbed.TestBed(ctx, distsys.NewTLAString("self"), testbed.Constants{}) + | ctx := distsys.NewMPCalContext() + | err := testbed.TestBed(ctx, distsys.NewTLAString("self"), testbed.Constants{}) | if err != nil { | panic(err) | } From 2715174bd1d33d3ea93a14bca213e29487524837 Mon Sep 17 00:00:00 2001 From: fhackett Date: Fri, 23 Jul 2021 14:24:31 -0700 Subject: [PATCH 21/27] add unsupported ops error; more clean-up --- .gitignore | 5 + .travis.yml | 14 - distsys/tlaplus.go | 27 +- src/pgo/parser/TLAParser.scala | 6 +- src/pgo/trans/MPCalGoCodegenPass.scala | 96 +- src/pgo/util/TLAExprInterpreter.scala | 16 +- test/files/general/ExprTests.tla | 8 +- test/files/general/ExprTests.tla.expectpcal | 8 +- .../ExprTests.tla.gotests/ExprTests.go | 24 +- test/files/gogen/UnsupportedOps.tla | 30 + test/integration/EitherBothBranches.tla | 78 - test/integration/EitherRepeatedExec.tla | 57 - test/integration/Procedures.tla | 149 - test/integration/ProceduresPSyntax.tla | 150 - test/integration/SimpleEither.tla | 62 - test/integration/SingleProcess.tla | 144 - .../concurrent_replicated_kv/client2_in.txt | 100 - .../concurrent_replicated_kv/client3_in.txt | 100 - .../concurrent_replicated_kv/client4_in.txt | 100 - .../mpcal/go/concurrent_replicated_kv/main.go | 386 --- .../concurrent_replicated_kv/replicas_out.txt | 138 - .../go/load_balancer_file_system/main.go | 108 - .../pages/page1.html | 1 - .../pages/page2.html | 1 - .../go/load_balancer_record_payloads/main.go | 108 - .../load_balancer_record_payloads/page1.html | 1 - .../load_balancer_record_payloads/page2.html | 1 - test/mpcal/go/load_balancer_tuples/main.go | 108 - test/mpcal/go/load_balancer_tuples/page1.html | 1 - test/mpcal/go/load_balancer_tuples/page2.html | 1 - test/mpcal/go/replicated_kv/main.go | 327 -- test/mpcal/spec/concurrent_replicated_kv.tla | 2707 --------------- test/mpcal/spec/load_balancer_file_system.tla | 573 ---- .../spec/load_balancer_record_payloads.tla | 563 --- test/mpcal/spec/load_balancer_tuples.tla | 540 --- test/mpcal/spec/replicated_kv.tla | 3019 ----------------- test/pgo/GoGenFileTests.scala | 3 +- test/pgo/TLAExpressionFuzzTests.scala | 22 +- test/pluscal/AltBitProtocol.tla | 148 - test/pluscal/Await.tla | 71 - test/pluscal/Euclid.tla | 59 - test/pluscal/FastMutex.tla | 160 - test/pluscal/QueensPluscal.tla | 124 - test/pluscal/Sum.tla | 155 - test/pluscal/TwoPhaseCommit.tla | 180 - test/pluscal/pgo2pc.tla | 204 -- 46 files changed, 196 insertions(+), 10687 deletions(-) delete mode 100644 .travis.yml create mode 100644 test/files/gogen/UnsupportedOps.tla delete mode 100644 test/integration/EitherBothBranches.tla delete mode 100644 test/integration/EitherRepeatedExec.tla delete mode 100644 test/integration/Procedures.tla delete mode 100644 test/integration/ProceduresPSyntax.tla delete mode 100644 test/integration/SimpleEither.tla delete mode 100644 test/integration/SingleProcess.tla delete mode 100644 test/mpcal/go/concurrent_replicated_kv/client2_in.txt delete mode 100644 test/mpcal/go/concurrent_replicated_kv/client3_in.txt delete mode 100644 test/mpcal/go/concurrent_replicated_kv/client4_in.txt delete mode 100644 test/mpcal/go/concurrent_replicated_kv/main.go delete mode 100644 test/mpcal/go/concurrent_replicated_kv/replicas_out.txt delete mode 100644 test/mpcal/go/load_balancer_file_system/main.go delete mode 100644 test/mpcal/go/load_balancer_file_system/pages/page1.html delete mode 100644 test/mpcal/go/load_balancer_file_system/pages/page2.html delete mode 100644 test/mpcal/go/load_balancer_record_payloads/main.go delete mode 100644 test/mpcal/go/load_balancer_record_payloads/page1.html delete mode 100644 test/mpcal/go/load_balancer_record_payloads/page2.html delete mode 100644 test/mpcal/go/load_balancer_tuples/main.go delete mode 100644 test/mpcal/go/load_balancer_tuples/page1.html delete mode 100644 test/mpcal/go/load_balancer_tuples/page2.html delete mode 100644 test/mpcal/go/replicated_kv/main.go delete mode 100644 test/mpcal/spec/concurrent_replicated_kv.tla delete mode 100644 test/mpcal/spec/load_balancer_file_system.tla delete mode 100644 test/mpcal/spec/load_balancer_record_payloads.tla delete mode 100644 test/mpcal/spec/load_balancer_tuples.tla delete mode 100644 test/mpcal/spec/replicated_kv.tla delete mode 100644 test/pluscal/AltBitProtocol.tla delete mode 100644 test/pluscal/Await.tla delete mode 100644 test/pluscal/Euclid.tla delete mode 100644 test/pluscal/FastMutex.tla delete mode 100644 test/pluscal/QueensPluscal.tla delete mode 100644 test/pluscal/Sum.tla delete mode 100644 test/pluscal/TwoPhaseCommit.tla delete mode 100644 test/pluscal/pgo2pc.tla diff --git a/.gitignore b/.gitignore index 552395289..1c4096055 100644 --- a/.gitignore +++ b/.gitignore @@ -363,4 +363,9 @@ lib/pgo.jar # ignore copied src in example/output/ /examples/output/*/src/ + +# Scala and sbt-related items target/ +project/ +.bloop/ +.bsp/ diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 1ac1b3e48..000000000 --- a/.travis.yml +++ /dev/null @@ -1,14 +0,0 @@ -language: java -jdk: - - openjdk8 - - openjdk9 -env: - - GO_VERSION=1.8 - - GO_VERSION=1.9 - - GO_VERSION=1.10 - - GO_VERSION=1.11 -before_script: - - sudo apt-get install ant-optional -script: - - eval "$(gimme $GO_VERSION)" && go version - - eval "$(gimme $GO_VERSION)" && ant tests diff --git a/distsys/tlaplus.go b/distsys/tlaplus.go index da4d16b48..4238c1554 100644 --- a/distsys/tlaplus.go +++ b/distsys/tlaplus.go @@ -200,7 +200,9 @@ func (v TLAValue) SelectElement() TLAValue { func (v TLAValue) ApplyFunction(argument TLAValue) TLAValue { switch data := v.data.(type) { case *tlaValueTuple: - return data.Get(int(argument.AsNumber())).(TLAValue) + idx := int(argument.AsNumber()) + require(idx >= 1 || idx <= data.Len(), "tuple indices must be in range; note that tuples are 1-indexed in TLA+") + return data.Get(idx - 1).(TLAValue) case *tlaValueFunction: value, ok := data.Get(argument) if !ok { @@ -250,6 +252,11 @@ var TLA_TRUE = TLAValue{tlaValueBool(true)} var TLA_FALSE = TLAValue{tlaValueBool(false)} var TLA_BOOLEAN = NewTLASet(TLA_TRUE, TLA_FALSE) +func TLA_Assert(cond, msg TLAValue) TLAValue { + require(cond.AsBool(), fmt.Sprintf("TLA+ assertion: %s", msg.AsString())) + return TLA_TRUE +} + func NewTLABool(v bool) TLAValue { if v { return TLA_TRUE @@ -307,6 +314,8 @@ func NewTLANumber(num int32) TLAValue { return TLAValue{tlaValueNumber(num)} } +var TLA_Zero = NewTLANumber(0) + // FIXME: better error handling var TLA_Nat = TLAValue{} var TLA_Int = TLAValue{} @@ -1124,6 +1133,22 @@ func TLAFunctionSubstitution(source TLAValue, substitutions []TLAFunctionSubstit return source } +func TLA_ColonGreaterThanSymbol(lhs, rhs TLAValue) TLAValue { + builder := immutable.NewMapBuilder(TLAValueHasher{}) + builder.Set(lhs, rhs) + return TLAValue{&tlaValueFunction{builder.Map()}} +} + +func TLA_DoubleAtSignSymbol(lhs, rhs TLAValue) TLAValue { + lhsFn, rhsFh := lhs.AsFunction(), rhs.AsFunction() + it := rhsFh.Iterator() + for !it.Done() { + key, value := it.Next() + lhsFn = lhsFn.Set(key, value) + } + return TLAValue{&tlaValueFunction{lhsFn}} +} + func TLA_DomainSymbol(v TLAValue) TLAValue { fn := v.AsFunction() builder := immutable.NewMapBuilder(TLAValueHasher{}) diff --git a/src/pgo/parser/TLAParser.scala b/src/pgo/parser/TLAParser.scala index c205849cf..ce5f64d38 100644 --- a/src/pgo/parser/TLAParser.scala +++ b/src/pgo/parser/TLAParser.scala @@ -144,7 +144,7 @@ trait TLAParser extends RegexParsers { tlaIdentifierExpr.flatMap { id => ctx.lookupDefinition(pfx.map(id => Definition.ScopeIdentifierName(id.id)) :+ Definition.ScopeIdentifierName(id)) match { case None => - failure(s"lookup failed for identifier ${pfx.map(_.id.id).mkString("!")}!${id.id}") + failure(s"lookup failed for identifier ${pfx.map(_.id.id).mkString("!")}${if(pfx.nonEmpty) "!" else ""}${id.id}") case Some(defn) => if (defn.arity == 0) { // the extra negation is to avoid matching parts of an EXCEPT expression, where an id might be followed by ! @@ -201,7 +201,7 @@ trait TLAParser extends RegexParsers { } else { // don't fail hard; it's possible that the prefix is empty and the identifier is an ambiguous // prefix of some other piece of syntax; perhaps an OpDecl - failure(s"lookup failed for identifier ${pfx.map(_.id.id).mkString("!")}!${id.id}") + failure(s"lookup failed for identifier ${pfx.map(_.id.id).mkString("!")}${if(pfx.nonEmpty) "!" else ""}${id.id}") } case Some(defn) => if( defn.arity > 0 ) { @@ -655,7 +655,7 @@ trait TLAParser extends RegexParsers { tlaLetExpr | tlaCaseExpr | // starting with [ - tlaFunctionExpr | tlaRecordSetExpr | tlaRecordConstructorExpr | tlaFunctionSetExpr | + tlaFunctionExpr | tlaRecordSetExpr | tlaRecordConstructorExpr | tlaFunctionSetExpr | tlaMaybeActionExpr | tlaFunctionSubstitutionExpr | // starting with \E, EE, \A, \AA tlaQuantifiedExistentialExpr | tlaQuantifiedUniversalExpr | diff --git a/src/pgo/trans/MPCalGoCodegenPass.scala b/src/pgo/trans/MPCalGoCodegenPass.scala index 062a816fb..b434039e0 100644 --- a/src/pgo/trans/MPCalGoCodegenPass.scala +++ b/src/pgo/trans/MPCalGoCodegenPass.scala @@ -1,12 +1,12 @@ package pgo.trans -import pgo.model.{Definition, DefinitionOne, PGoError, RefersTo, Rewritable, Visitable} +import pgo.model.{Definition, DefinitionOne, PGoError, RefersTo, Rewritable, SourceLocation, Visitable} import pgo.model.mpcal._ import pgo.model.pcal._ import pgo.model.tla._ -import pgo.util.{Description, IdMap, NameCleaner} +import pgo.util.{Description, IdMap, IdSet, NameCleaner} import Description._ -import pgo.model.tla.BuiltinModules.TLABuiltinOperator +import pgo.model.tla.BuiltinModules.{TLABuiltinOperator, builtinModules} import pgo.util.MPCalPassUtils.MappedRead import pgo.util.Unreachable.!!! @@ -15,6 +15,66 @@ import scala.annotation.tailrec import scala.collection.{View, mutable} object MPCalGoCodegenPass { + final case class UnsupportedOperationsError(override val errors: List[UnsupportedOperationsError.UnsupportedOperationError]) extends PGoError + + object UnsupportedOperationsError { + final case class UnsupportedOperationError(override val sourceLocation: SourceLocation) extends PGoError.Error { + override val description: Description = d"unsupported built-in operator referenced" + } + } + + lazy val unsupportedOperators: IdSet[TLABuiltinOperator] = IdSet( + BuiltinModules.Intrinsics.memberAlpha("STRING"), + + BuiltinModules.Intrinsics.memberSym(TLASymbol.PrimeSymbol), + BuiltinModules.Intrinsics.memberSym(TLASymbol.EnabledSymbol), + BuiltinModules.Intrinsics.memberSym(TLASymbol.UnchangedSymbol), + BuiltinModules.Intrinsics.memberSym(TLASymbol.CDotSymbol), + + BuiltinModules.Intrinsics.memberSym(TLASymbol.TLAlwaysSymbol), + BuiltinModules.Intrinsics.memberSym(TLASymbol.TLEventuallySymbol), + BuiltinModules.Intrinsics.memberSym(TLASymbol.SequencingSymbol), + BuiltinModules.Intrinsics.memberSym(TLASymbol.PlusArrowSymbol), + + BuiltinModules.TLC.memberAlpha("Print"), + BuiltinModules.TLC.memberAlpha("PrintT"), + BuiltinModules.TLC.memberAlpha("JavaTime"), + BuiltinModules.TLC.memberAlpha("Permutations"), + BuiltinModules.TLC.memberAlpha("SortSeq"), + + BuiltinModules.Sequences.memberAlpha("SelectSeq"), + + BuiltinModules.Bags.memberAlpha("IsABag"), + BuiltinModules.Bags.memberAlpha("BagToSet"), + BuiltinModules.Bags.memberAlpha("SetToBag"), + BuiltinModules.Bags.memberAlpha("BagIn"), + BuiltinModules.Bags.memberAlpha("EmptyBag"), + BuiltinModules.Bags.memberAlpha("CopiesIn"), + BuiltinModules.Bags.memberSym(TLASymbol.OPlusSymbol), + BuiltinModules.Bags.memberSym(TLASymbol.OMinusSymbol), + BuiltinModules.Bags.memberAlpha("BagUnion"), + BuiltinModules.Bags.memberSym(TLASymbol.SquareSupersetOrEqualSymbol), + BuiltinModules.Bags.memberAlpha("SubBag"), + BuiltinModules.Bags.memberAlpha("BagOfAll"), + BuiltinModules.Bags.memberAlpha("BagCardinality"), + + BuiltinModules.Peano.memberAlpha("PeanoAxioms"), + BuiltinModules.Peano.memberAlpha("Succ"), + BuiltinModules.Peano.memberAlpha("Nat"), + + BuiltinModules.ProtoReals.memberAlpha("IsModelOfReals"), + BuiltinModules.ProtoReals.memberAlpha("RM"), + BuiltinModules.ProtoReals.memberAlpha("Real"), + BuiltinModules.ProtoReals.memberAlpha("Infinity"), + BuiltinModules.ProtoReals.memberAlpha("MinusInfinity"), + BuiltinModules.ProtoReals.memberSym(TLASymbol.SlashSymbol), + BuiltinModules.ProtoReals.memberAlpha("Int"), + + BuiltinModules.Reals.memberAlpha("Real"), + BuiltinModules.Reals.memberSym(TLASymbol.SlashSymbol), + BuiltinModules.Reals.memberAlpha("Infinity"), + ) + private val TLAValue = "distsys.TLAValue" private val ArchetypeResourceHandle = "distsys.ArchetypeResourceHandle" val goKeywords: List[String] = @@ -722,6 +782,36 @@ object MPCalGoCodegenPass { @throws[PGoError] def apply(tlaModule: TLAModule, mpcalBlock: MPCalBlock, packageName: Option[String]): Description = { + locally { + val errors = mutable.ListBuffer[UnsupportedOperationsError.UnsupportedOperationError]() + + def checkBuiltin(sourceLocation: SourceLocation, builtin: TLABuiltinOperator): Unit = + if (unsupportedOperators(builtin)) { + errors += UnsupportedOperationsError.UnsupportedOperationError(sourceLocation) + } + + val supportedOpsChecker: PartialFunction[Visitable, Unit] = { + case ident: TLAGeneralIdentifier => + ident.refersTo match { + case builtin: TLABuiltinOperator => checkBuiltin(ident.sourceLocation, builtin) + case _ => + } + case opCall: TLAOperatorCall => + opCall.refersTo match { + case builtin: TLABuiltinOperator => checkBuiltin(opCall.sourceLocation, builtin) + case _ => + } + } + tlaModule.units.foreach(_.visit(Visitable.BottomUpFirstStrategy)(supportedOpsChecker)) + mpcalBlock.units.foreach(_.visit(Visitable.BottomUpFirstStrategy)(supportedOpsChecker)) + mpcalBlock.mpcalProcedures.foreach(_.visit(Visitable.BottomUpFirstStrategy)(supportedOpsChecker)) + mpcalBlock.archetypes.foreach(_.visit(Visitable.BottomUpFirstStrategy)(supportedOpsChecker)) + + if(errors.nonEmpty) { + throw UnsupportedOperationsError(errors.toList) + } + } + val nameCleaner = new NameCleaner goKeywords.foreach(nameCleaner.addKnownName) nameCleaner.addKnownName("distsys") diff --git a/src/pgo/util/TLAExprInterpreter.scala b/src/pgo/util/TLAExprInterpreter.scala index 88a465ee7..947be14ec 100644 --- a/src/pgo/util/TLAExprInterpreter.scala +++ b/src/pgo/util/TLAExprInterpreter.scala @@ -1,6 +1,6 @@ package pgo.util -import pgo.model.{Definition, DefinitionOne, RefersTo, SourceLocation} +import pgo.model.{DefinitionOne, RefersTo, SourceLocation} import pgo.model.tla._ import pgo.parser.TLAParser import pgo.util.Unreachable.!!! @@ -30,7 +30,7 @@ object TLAExprInterpreter { final case class TLAValueTuple(value: Vector[TLAValue]) extends TLAValue final case class TLAValueFunction(value: Map[TLAValue,TLAValue]) extends TLAValue - lazy val builtinOperators: IdMap[DefinitionOne,List[TLAValue]=>TLAValue] = + lazy val builtinOperators: IdMap[DefinitionOne,PartialFunction[List[TLAValue],TLAValue]] = IdMap( BuiltinModules.Intrinsics.memberSym(TLASymbol.LogicalAndSymbol) -> { case List(TLAValueBool(lhs), TLAValueBool(rhs)) => TLAValueBool(lhs && rhs) @@ -111,7 +111,7 @@ object TLAExprInterpreter { BuiltinModules.TLC.memberAlpha("PrintT") -> { case List(_) => throw Unsupported() }, BuiltinModules.TLC.memberAlpha("Assert") -> { case List(TLAValueBool(cond), out) => - assert(cond, out.toString) + require(cond, out.toString) TLAValueBool(true) }, BuiltinModules.TLC.memberAlpha("JavaTime") -> { case Nil => throw Unsupported() }, @@ -244,7 +244,7 @@ object TLAExprInterpreter { value match { case TLANumber.IntValue(value) => TLAValueNumber(value.intValue) } - case ident@TLAGeneralIdentifier(name, prefix) => + case ident@TLAGeneralIdentifier(_, prefix) => assert(prefix.isEmpty) env.getOrElse(ident.refersTo, { builtinOperators(ident.refersTo)(Nil) @@ -278,7 +278,7 @@ object TLAExprInterpreter { case Nil => interpret(body) case unit :: restUnits => unit match { - case defn@TLAOperatorDefinition(name, args, body, _) if args.isEmpty => + case defn@TLAOperatorDefinition(_, args, body, _) if args.isEmpty => impl(restUnits)(env = env.updated(defn, interpret(body))) case _: TLAOperatorDefinition => // for definitions with args, they will be called by TLAOperatorCall, and scoping is done already @@ -339,7 +339,7 @@ object TLAExprInterpreter { interpret(function) match { case TLAValueTuple(value) => paramValue match { - case TLAValueNumber(idx) => value(idx) + case TLAValueNumber(idx) if idx >= 1 && idx <= value.size => value(idx - 1) } case TLAValueFunction(value) => value(paramValue) } @@ -484,7 +484,9 @@ object TLAExprInterpreter { TLAValueSet(impl(fields.map { case TLARecordSetField(name, set) => - (name.id, interpret(set)) + interpret(set) match { + case setVal: TLAValueSet => name.id -> setVal + } }, Map.empty).toSet) } } catch { diff --git a/test/files/general/ExprTests.tla b/test/files/general/ExprTests.tla index 091e79a75..c98b4fdb7 100644 --- a/test/files/general/ExprTests.tla +++ b/test/files/general/ExprTests.tla @@ -1,19 +1,19 @@ ---- MODULE ExprTests ---- -EXTENDS Integers, Sequences, TLC, FiniteSets +EXTENDS Integers, Sequences, TLC, FiniteSets, Peano Test1 == { x : x \in { y : y \in { 1, 2, 3} } } \* this test is not expected to run; it should compile, however, and it should not cause any scoping errors. \* at one point, this would cause an obscure mutability bug in the TLA+ parser, due to a rare backtracking scenario. -Test2 == \A <> \in "W\"!> \in [rjg96CqaSMuCjtyr450h6DL1e02XHUTSveCKybqCudAztsOjRmkIEFEkhaCX9AEfDDCOqmuEg0Xtb5AWWeMNM2fXfObxeWMG7AcDR5KDDHmtkGN8Xd |-> Nat, cSOk29itvxzRN2lPY |-> <<>>, cfZGl3Wdyxt6gGxpst0G2YzBErEDXQwzSSWERs9MLYB4BpT7ne6vVOh8FuGMFN9KLaHIP7vJe7ItfvqjAIKw8K8LdrCZt |-> "nybf\*j`.#ogke@%3kx7zwaX;~nx68X6qVB=\"Dj__7mkIq=25>YVw#\\#]8?t=]ndqUQnWNDhr([Q2Zd6;", fHeAZdw1vCnj3xfH9h22hrUcMclAc21eFx |-> <<>>, kPKP6DMtdXB26DOcOq |-> Int, kOufhkQQBNihpnqM5EG2ave4gvDLXzM4eM3AF0s1vozipbR3jl8f25jIZF2l1DrHNVNGzYyh |-> Nat, pes31jiQYk7kh9MbAqDybYqzToYtXL24 |-> 105], <> \in {dVpTt5jrKlWu0I6Hq6H80zTmUxwUAJYO4dKwf6DQfbTQWe9fGr8TtnynL58wFnRcfuVdaQJ6yRM : nocBmpMYH5HkfAmS1Hxov1sNAmNpre32Go2PPwiq2V \in 66, j8KL43er \in 99, uOnSBu75CcElcoR2ZLguWLx24i2 \in Nat, ciyA3piCZqGxtypqDZ7yUA6ZigMVm0gahHBAmufYN8QSkFcoxD5mhB0H1o5fgF4J0oOpzQgazH89oz \in Int, n4vC1IUc6EoStkodAFXDtaZxD3jWmDWSa177v15UbOG2B0yKlCWueKjkDEczLz2NF3SdvY \in Nat, <> \in Nat}, ydWAMLx2MOT5MVTV4DoLy4m630MxBh8OzY27IXNa1UwzilN9ABwtkToLjGTMbiFUNXwOxBlp3LCAIzc3syTXB \in {{zWSbRBDcKvPAzjLcOPdpDMdxHB07sO7kEq9Sk9MydQzf7b5IguRfwHTQeQwDS8uwsPPE77kph4VdYlWi6GlfISwJgzUF5mDwt} : nMDLcmFYG6N5X5qUG4Q4ELPxCZRP1ByOFD8cIbWHPjvMaPtf5Q7BBDw71oHBnalYi6KgmUCNtO0j7r3nAkq7Wn3ClMSz44nnJXpgNIZZydK \in 68, vvmBdcUQcmzi3aF14n2S3Oie2iBRkC6Pq5dh91BNivvWOU8pQ8lX0buK5SxjDEHFi \in Len(Nat), <> \in Tail(<<>>)}, <> \in Nat, g540XiUzWuW \in (Len(Nat))[Int, Head(Nat), Cardinality(<<>>)], aYGs4t9TNazIlSTuMV2UZJE2Su42dELDJebUslriCHsCdePddP6kT4herkEEZkaBrLcr19VzcoQUqUxLDj7aM9GlCyqIWhrn1gQ12Wcafcg \in {{jFSnew60k9UkNMbOwRMQkAjaDOsCVlPPzNCyFhfU0fyWovez0zXZDVqaX3EHHxW8P9RjGDPX8z8k8OPG6zvn : bJdvTIPKLRX2S7AzBaJhHn6qzYpgdcuCSHMXowo \in {}} : jFSnew60k9UkNMbOwRMQkAjaDOsCVlPPzNCyFhfU0fyWovez0zXZDVqaX3EHHxW8P9RjGDPX8z8k8OPG6zvn \in <<>>}, qvEBcszWN2nDUY1XVCrYsYFk8gOLE76XaPswHtQNF9Wf5L5hSOy7zlHGM8C85CJb \in CASE <<"|AP8[H3v] 0TXS4l;{MD>jLmGb~(,$M3&I+03G/|yp\\lCm\"gW{Y,|Jp`i$ICm_%\"\).WjP_Q/lA5">> -> Nat +Test2 == \A <> \in "W\"!> \in [rjg96CqaSMuCjtyr450h6DL1e02XHUTSveCKybqCudAztsOjRmkIEFEkhaCX9AEfDDCOqmuEg0Xtb5AWWeMNM2fXfObxeWMG7AcDR5KDDHmtkGN8Xd |-> Zero, cSOk29itvxzRN2lPY |-> <<>>, cfZGl3Wdyxt6gGxpst0G2YzBErEDXQwzSSWERs9MLYB4BpT7ne6vVOh8FuGMFN9KLaHIP7vJe7ItfvqjAIKw8K8LdrCZt |-> "nybf\*j`.#ogke@%3kx7zwaX;~nx68X6qVB=\"Dj__7mkIq=25>YVw#\\#]8?t=]ndqUQnWNDhr([Q2Zd6;", fHeAZdw1vCnj3xfH9h22hrUcMclAc21eFx |-> <<>>, kPKP6DMtdXB26DOcOq |-> Zero, kOufhkQQBNihpnqM5EG2ave4gvDLXzM4eM3AF0s1vozipbR3jl8f25jIZF2l1DrHNVNGzYyh |-> Zero, pes31jiQYk7kh9MbAqDybYqzToYtXL24 |-> 105], <> \in {dVpTt5jrKlWu0I6Hq6H80zTmUxwUAJYO4dKwf6DQfbTQWe9fGr8TtnynL58wFnRcfuVdaQJ6yRM : nocBmpMYH5HkfAmS1Hxov1sNAmNpre32Go2PPwiq2V \in 66, j8KL43er \in 99, uOnSBu75CcElcoR2ZLguWLx24i2 \in Zero, ciyA3piCZqGxtypqDZ7yUA6ZigMVm0gahHBAmufYN8QSkFcoxD5mhB0H1o5fgF4J0oOpzQgazH89oz \in Zero, n4vC1IUc6EoStkodAFXDtaZxD3jWmDWSa177v15UbOG2B0yKlCWueKjkDEczLz2NF3SdvY \in Zero, <> \in Zero}, ydWAMLx2MOT5MVTV4DoLy4m630MxBh8OzY27IXNa1UwzilN9ABwtkToLjGTMbiFUNXwOxBlp3LCAIzc3syTXB \in {{zWSbRBDcKvPAzjLcOPdpDMdxHB07sO7kEq9Sk9MydQzf7b5IguRfwHTQeQwDS8uwsPPE77kph4VdYlWi6GlfISwJgzUF5mDwt} : nMDLcmFYG6N5X5qUG4Q4ELPxCZRP1ByOFD8cIbWHPjvMaPtf5Q7BBDw71oHBnalYi6KgmUCNtO0j7r3nAkq7Wn3ClMSz44nnJXpgNIZZydK \in 68, vvmBdcUQcmzi3aF14n2S3Oie2iBRkC6Pq5dh91BNivvWOU8pQ8lX0buK5SxjDEHFi \in Len(Zero), <> \in Tail(<<>>)}, <> \in Zero, g540XiUzWuW \in (Len(Zero))[Zero, Head(Zero), Cardinality(<<>>)], aYGs4t9TNazIlSTuMV2UZJE2Su42dELDJebUslriCHsCdePddP6kT4herkEEZkaBrLcr19VzcoQUqUxLDj7aM9GlCyqIWhrn1gQ12Wcafcg \in {{jFSnew60k9UkNMbOwRMQkAjaDOsCVlPPzNCyFhfU0fyWovez0zXZDVqaX3EHHxW8P9RjGDPX8z8k8OPG6zvn : bJdvTIPKLRX2S7AzBaJhHn6qzYpgdcuCSHMXowo \in {}} : jFSnew60k9UkNMbOwRMQkAjaDOsCVlPPzNCyFhfU0fyWovez0zXZDVqaX3EHHxW8P9RjGDPX8z8k8OPG6zvn \in <<>>}, qvEBcszWN2nDUY1XVCrYsYFk8gOLE76XaPswHtQNF9Wf5L5hSOy7zlHGM8C85CJb \in CASE <<"|AP8[H3v] 0TXS4l;{MD>jLmGb~(,$M3&I+03G/|yp\\lCm\"gW{Y,|Jp`i$ICm_%\"\).WjP_Q/lA5">> -> Zero [] "~ l" -> 34 - [] (Int).tpFXgtDC996txdhqxvc6uTZ7LGguVCIqPWhb4GPq0vrjsU6VJ36ivYQrBcr6eLu6EeizwwVG4duDRq6 -> Cardinality(Nat), <> \in {103, <<{}>>, Tail("ao>Q^45R\*\)&S.P;@h>(g&QFHhB2]CIa,O\)R}&icu\)|> \in [eSmDnVka2T5vfCr2D6NAeJaHIIDOlNw2EtW2rEOQXQPKS5kkyWOloH5TdOSGJ8Bz44giGFHo7gIWf8OEXbvNC4Tf8ygMzR3dqbcqv |-> 69, izEEDYZa31aMoAX0ZZSPtnzZiSJasTS5zXqdJAympTsARWZkLDJD |-> 113, dyEu1EeADkIvzDaPjLTdpJIcifTMU16PgoOR7843Gu7mpKqkARv0JE2u1zPr2eQ4vy0VjJul5uqeh7XlPAPV9enWRCf8t0B0xY0IzPaYhk71Y |-> <<>>, ihxh4hux8hT1KYXTuUzKlwPYkKAA |-> {}, ztbbVgCSX1bb5RMzZV4BCFgYkbdQlRyqG57NRyYuAN37oz96UHjVkC7HEElI4leshq4qEfyyLaNoJgFjFiy1Ucxd5jJpteH1vEaWkHa6yFo0Zzk |-> Int, zjWP4mQbVQ2lc9Ah2qo2sENITxJ9Fk |-> {}, v4uawbLQboCq5rPaF4O4P9LhHxvqZlwWboXHoHD4oeoKTh3DhpLroR9zLte1WE3VZl5QuYZf71I5yofGfhfrcAeWZq4MopRwyEv |-> <<>>], <> \in LET dMBYoW4IrtFxgIWrYPBUK7U82G2P3eAqe8GTlNeOFFlAJ6oEJT(nxVAq5SHVzmvyyLtL6KTp81XDMb1M5gm1tUZ5X3tO6tVeixPGbirwW0b3WSixN9B00CFRj5, a6O9WgcDePw3so7SKk8CrZcBbOAQw21QJa3wAo83WKEVOM0q1MxaUg1, iYzkTIpshRIClbgtt7PCsvhU1p9zHHuWkDkQVQpZYHwqetUCJHB9hzSspxoSd4tazL2qGLqiGljQPkkk1abCepxIxQJMsHHegjnI3ORMkzNW, eibKgFT2bFMHNqSkBKHeq6rDs6QWjrBuaUppNNFWfxfGm6ybgx1y6SRQgPWrTaWtoh8IWCJ7CpHI3sl, ybPgPsNbI2tuE2K1iA1LrW4eXPRY05LyWpBCpRHC8q8iS62OXS5add7In, uqDvk2oF1CmjHdAze6afrN9c6Y0V9mZmsAdaeSgayd15MXEfOsru6LNlEsfLBwtgaQfH3CL18EoRux3NHDZ, vdIscEuUCezJghNA3FcZvKPOuwXLU77vygCZ0btzt4EZt90EMW9p0Alq3rISBmthV7NJiWDtasETDIaFyY4fTyJcrbJZ4nnLLL6hlo1r546GIlFHKhA4mf, yVo6R1IjAptaDLwUA1gBn7YfjaF7ZaAf96NxQxdB0z, pnoaUybvqpbFApkcV39Z6t35wHInxdO1geVF30nzdltg4tzSpvt8eq4z3MMOfMBaiyhRg5ybcnhTyA9zEopw3yI4Z5EjlABh9vADzC8, eTfg0HxBkXQFsmHMM7tzNzFG, sIwkrxLi5Ntu7Cp9N0qYRzetOgu5Q3WJkgiou6rcWtw1FCa0K204YXW7c2cc5QJ8eQlYmRQEB9ZX0D30PR6hrduOxltushIle85WUU7bhAWVR1, cIAnUzlzJJKbDePXcOGU5EHKL9nSXf1, cOK, sf3IfXkK2Ol7Y64A7mgUGWM8S3ccH2, jJb4v29omLKKv5It5RN2x2IFq8HV6Z9HseNGKEWmGMBIkmnDEwUI7QvAxfRH, rsLln4MGBLeC81BgBMGSXX, rZCJJMsv1jAxmyQjMLhsdmH8WMPJ3uctBaF0WdMTLBDSW3HlmBe1n1q9jZVLtpkSRwAnc42l8lLGMKZLQKRY5QAdfUsrDlVIM4JAPdiPsAHxXggP21tB, nUPa2waBp3rkfbbmB0YennfJw33fwZ6nPJ3cdH26J12SZZcOYyVvYjbZi5XORCxTdbP9yCAqwA07HjhaHboBNu, aOXhTn, iJAYyXf8zHNTmbKp3UW5K4B0ALrIWjnZwPYa5eQUPDWP9X0EN1xRAeEW1QltgZANH9Y8cl93VWXWPx1B1CeGtJ0Zc0ra3XJcB4a5dGaEEHoVCB9Bsbp, vZAUwcaw94oKZdAS6NhOEpQjadeImLnBdLABlHcxct1G36MLDBMPzbh, zDJhnifz1, pTnQLAuZpwUaqY55cJuvHq1t330FccrKxkEcnudLOjKgqVjJXw9oj, hRZGwOfVOqCN3NjIwRUIKyhwawc4xTc9ckcVLWqL, itF2FYh99DkOnXp5ZOxbXJhYWRf6Kt5TcbKiMnt8KtN0xPcFwqVhWorFOK1ZkGuUpVvLDl8CtcCzOCJ2ScITCo8tB13EOI8dzwR, t2u9, dsXbyTPuEzKcBmNO3vUoDy8byFgyYwP6vmR8ScQVJvNNE7etXukR97tdfJm, xIqUs2QwtR7b7gzlFAiA0nPagsRcXRIrzd4XwPuSc4iY4gcFOBkk6HhYPbXpD82i6wZA0qPxSDujwkgD5UgOb79C8n327qYeZB3B, jrQMqgDsjm6qLHAjB5pC7RfvvjGzAKPtxxyypA, sjl7d9GZhoCh5nEdbcXF44yFcu9W2BJsCvdIUruGMwUpUfXl6IhhRcqUlNPlX4ZSMmhnM9puS, iFSImI2CjxTF, kDb0r3tV81qr6H4SmFFabkD8DHWDz912PeZxQ7YRh9FjBCwY6eXETGHk1Flvk8zD5JpOPfpDTIezK8Q7uUrfbbKuW4GDDiAI24DnKiJeX6hYL, dBtIva3EV4kBUnhWYYKtDcY68OOM3, gU6JaM23335s9fdd71Iu23H6letgfaEm7RMjPRIJV0EjNOrROJCV6juQ1ZutwHbIHmuiU9JKTbyNlwGrxSgvwbIcctrzzvyj6MagRIpvB4Ue, pf1ouwjozkq46dVUev9IMmjvOCNeQSlMXvY, lEwUC4BNAyX, mu2pHEkSxMpJG4IFjyzfSg0FLj42MK5bnIGesapT8TI2cKhWicQcedPAjtR, c1, d4J4XlhEfuUcKHbFjd0I2EiqomIciQBQ1oCZtXOsXYMexyBzM, mb6VcvGiNqAddoL1U27vHSbT15kiRVI0Ccg8bjGYk4N, v32tgD43e2RMYs3l17XRA0oqcqjgppgbGCXy6kpz2DX9B4SZJWFDSafw28keLFVVr8gz85aSukay, od8zAG, agI3fF6yeEgwn4mHyIS6BzL8ZmZYxIycJlZbOrdWs0PuDp6EIp3OEJ4AZeMwbAaWG8C478nr96ufy32O5B9ya3RNgsiRol8, u5OX7jli7pUvdFlQ5GIWp8Y2V4w1Qq6JuSZNXFX58tCXaGAXNw5yAnpgjN7YI9OxgsMaqOal0gviOTsLnltWWVtP8, mzoT46CbhESG2XuO97YqjAIOTKzWRFV13URZM9bhApen3u, euHzTurEOVp5ibMG93Z5n5QIz6Vvd3yxatMiXyCUL1TpOljdnVUascnrfOSIM1d1kkwCN7PsN2She47ixp, cy1SKKvhNyXaU0a7ucbPfvQvwiWIfyoRR9dniXhyujpGiHWwnxpzVNviq2UbpGMSS6qtMtcfp2Ydfred22sowNl9R, b7awbjj0YYXhTT9cfZAlagT4rkOR4UTbkJ9XcvpT, wFylCz1pj9BXgQIj0iRfz9hzLaZdnzFFwvDUjuuRJZt0dPDMtEUWaLUWP2S0cIPjJLSEm4JW5esqfCFrhOSnlVK, woGgx9rhmhU3Fv5V7YfItdR6Ya4Nn61TZXuHgxRKhWraD82DjSckWU9eh8uVG, van0P1WdGWs0Y4xmIgEo62SjbzMz3KqKj1gaz1Oz2DuZk4Vh0WfhQxUV8lFTdzweshJusd3Wq0pdzmopk5HZtj, fJYgdSPVe8ZGrsDsj5URkQ4Po, dN6swQflYr2n, q2ca764vfjW3dsAunTwWLjNJMOzvDa15EUsScuh0pgXRFYGB7n5KHqLPRYU6Uv5zW2kM9xyB8Uc7tT7Dz5QlGBGW4wE6UkiSZ6DUFQ0KkXgv76x, bphFSsnrvrUTp20JF0EW16OkghBZ4yipad2qK, cSC2XESOcKEYMXaT6Sz2BvHjMCxzJELA1Q9abTKT4LjQSclaxwgn9ZbdD8i3HYBCkwAmLbIcuzbmYEzJT, fiW9J4QVDbOOCcDiC, cV3KndmxEb2jiUtpTbOCzpd, yCLJWfpVGdOnNkUQOtJNxI) == cy1SKKvhNyXaU0a7ucbPfvQvwiWIfyoRR9dniXhyujpGiHWwnxpzVNviq2UbpGMSS6qtMtcfp2Ydfred22sowNl9R + [] (Zero).tpFXgtDC996txdhqxvc6uTZ7LGguVCIqPWhb4GPq0vrjsU6VJ36ivYQrBcr6eLu6EeizwwVG4duDRq6 -> Cardinality(Zero), <> \in {103, <<{}>>, Tail("ao>Q^45R\*\)&S.P;@h>(g&QFHhB2]CIa,O\)R}&icu\)|> \in [eSmDnVka2T5vfCr2D6NAeJaHIIDOlNw2EtW2rEOQXQPKS5kkyWOloH5TdOSGJ8Bz44giGFHo7gIWf8OEXbvNC4Tf8ygMzR3dqbcqv |-> 69, izEEDYZa31aMoAX0ZZSPtnzZiSJasTS5zXqdJAympTsARWZkLDJD |-> 113, dyEu1EeADkIvzDaPjLTdpJIcifTMU16PgoOR7843Gu7mpKqkARv0JE2u1zPr2eQ4vy0VjJul5uqeh7XlPAPV9enWRCf8t0B0xY0IzPaYhk71Y |-> <<>>, ihxh4hux8hT1KYXTuUzKlwPYkKAA |-> {}, ztbbVgCSX1bb5RMzZV4BCFgYkbdQlRyqG57NRyYuAN37oz96UHjVkC7HEElI4leshq4qEfyyLaNoJgFjFiy1Ucxd5jJpteH1vEaWkHa6yFo0Zzk |-> Zero, zjWP4mQbVQ2lc9Ah2qo2sENITxJ9Fk |-> {}, v4uawbLQboCq5rPaF4O4P9LhHxvqZlwWboXHoHD4oeoKTh3DhpLroR9zLte1WE3VZl5QuYZf71I5yofGfhfrcAeWZq4MopRwyEv |-> <<>>], <> \in LET dMBYoW4IrtFxgIWrYPBUK7U82G2P3eAqe8GTlNeOFFlAJ6oEJT(nxVAq5SHVzmvyyLtL6KTp81XDMb1M5gm1tUZ5X3tO6tVeixPGbirwW0b3WSixN9B00CFRj5, a6O9WgcDePw3so7SKk8CrZcBbOAQw21QJa3wAo83WKEVOM0q1MxaUg1, iYzkTIpshRIClbgtt7PCsvhU1p9zHHuWkDkQVQpZYHwqetUCJHB9hzSspxoSd4tazL2qGLqiGljQPkkk1abCepxIxQJMsHHegjnI3ORMkzNW, eibKgFT2bFMHNqSkBKHeq6rDs6QWjrBuaUppNNFWfxfGm6ybgx1y6SRQgPWrTaWtoh8IWCJ7CpHI3sl, ybPgPsNbI2tuE2K1iA1LrW4eXPRY05LyWpBCpRHC8q8iS62OXS5add7In, uqDvk2oF1CmjHdAze6afrN9c6Y0V9mZmsAdaeSgayd15MXEfOsru6LNlEsfLBwtgaQfH3CL18EoRux3NHDZ, vdIscEuUCezJghNA3FcZvKPOuwXLU77vygCZ0btzt4EZt90EMW9p0Alq3rISBmthV7NJiWDtasETDIaFyY4fTyJcrbJZ4nnLLL6hlo1r546GIlFHKhA4mf, yVo6R1IjAptaDLwUA1gBn7YfjaF7ZaAf96NxQxdB0z, pnoaUybvqpbFApkcV39Z6t35wHInxdO1geVF30nzdltg4tzSpvt8eq4z3MMOfMBaiyhRg5ybcnhTyA9zEopw3yI4Z5EjlABh9vADzC8, eTfg0HxBkXQFsmHMM7tzNzFG, sIwkrxLi5Ntu7Cp9N0qYRzetOgu5Q3WJkgiou6rcWtw1FCa0K204YXW7c2cc5QJ8eQlYmRQEB9ZX0D30PR6hrduOxltushIle85WUU7bhAWVR1, cIAnUzlzJJKbDePXcOGU5EHKL9nSXf1, cOK, sf3IfXkK2Ol7Y64A7mgUGWM8S3ccH2, jJb4v29omLKKv5It5RN2x2IFq8HV6Z9HseNGKEWmGMBIkmnDEwUI7QvAxfRH, rsLln4MGBLeC81BgBMGSXX, rZCJJMsv1jAxmyQjMLhsdmH8WMPJ3uctBaF0WdMTLBDSW3HlmBe1n1q9jZVLtpkSRwAnc42l8lLGMKZLQKRY5QAdfUsrDlVIM4JAPdiPsAHxXggP21tB, nUPa2waBp3rkfbbmB0YennfJw33fwZ6nPJ3cdH26J12SZZcOYyVvYjbZi5XORCxTdbP9yCAqwA07HjhaHboBNu, aOXhTn, iJAYyXf8zHNTmbKp3UW5K4B0ALrIWjnZwPYa5eQUPDWP9X0EN1xRAeEW1QltgZANH9Y8cl93VWXWPx1B1CeGtJ0Zc0ra3XJcB4a5dGaEEHoVCB9Bsbp, vZAUwcaw94oKZdAS6NhOEpQjadeImLnBdLABlHcxct1G36MLDBMPzbh, zDJhnifz1, pTnQLAuZpwUaqY55cJuvHq1t330FccrKxkEcnudLOjKgqVjJXw9oj, hRZGwOfVOqCN3NjIwRUIKyhwawc4xTc9ckcVLWqL, itF2FYh99DkOnXp5ZOxbXJhYWRf6Kt5TcbKiMnt8KtN0xPcFwqVhWorFOK1ZkGuUpVvLDl8CtcCzOCJ2ScITCo8tB13EOI8dzwR, t2u9, dsXbyTPuEzKcBmNO3vUoDy8byFgyYwP6vmR8ScQVJvNNE7etXukR97tdfJm, xIqUs2QwtR7b7gzlFAiA0nPagsRcXRIrzd4XwPuSc4iY4gcFOBkk6HhYPbXpD82i6wZA0qPxSDujwkgD5UgOb79C8n327qYeZB3B, jrQMqgDsjm6qLHAjB5pC7RfvvjGzAKPtxxyypA, sjl7d9GZhoCh5nEdbcXF44yFcu9W2BJsCvdIUruGMwUpUfXl6IhhRcqUlNPlX4ZSMmhnM9puS, iFSImI2CjxTF, kDb0r3tV81qr6H4SmFFabkD8DHWDz912PeZxQ7YRh9FjBCwY6eXETGHk1Flvk8zD5JpOPfpDTIezK8Q7uUrfbbKuW4GDDiAI24DnKiJeX6hYL, dBtIva3EV4kBUnhWYYKtDcY68OOM3, gU6JaM23335s9fdd71Iu23H6letgfaEm7RMjPRIJV0EjNOrROJCV6juQ1ZutwHbIHmuiU9JKTbyNlwGrxSgvwbIcctrzzvyj6MagRIpvB4Ue, pf1ouwjozkq46dVUev9IMmjvOCNeQSlMXvY, lEwUC4BNAyX, mu2pHEkSxMpJG4IFjyzfSg0FLj42MK5bnIGesapT8TI2cKhWicQcedPAjtR, c1, d4J4XlhEfuUcKHbFjd0I2EiqomIciQBQ1oCZtXOsXYMexyBzM, mb6VcvGiNqAddoL1U27vHSbT15kiRVI0Ccg8bjGYk4N, v32tgD43e2RMYs3l17XRA0oqcqjgppgbGCXy6kpz2DX9B4SZJWFDSafw28keLFVVr8gz85aSukay, od8zAG, agI3fF6yeEgwn4mHyIS6BzL8ZmZYxIycJlZbOrdWs0PuDp6EIp3OEJ4AZeMwbAaWG8C478nr96ufy32O5B9ya3RNgsiRol8, u5OX7jli7pUvdFlQ5GIWp8Y2V4w1Qq6JuSZNXFX58tCXaGAXNw5yAnpgjN7YI9OxgsMaqOal0gviOTsLnltWWVtP8, mzoT46CbhESG2XuO97YqjAIOTKzWRFV13URZM9bhApen3u, euHzTurEOVp5ibMG93Z5n5QIz6Vvd3yxatMiXyCUL1TpOljdnVUascnrfOSIM1d1kkwCN7PsN2She47ixp, cy1SKKvhNyXaU0a7ucbPfvQvwiWIfyoRR9dniXhyujpGiHWwnxpzVNviq2UbpGMSS6qtMtcfp2Ydfred22sowNl9R, b7awbjj0YYXhTT9cfZAlagT4rkOR4UTbkJ9XcvpT, wFylCz1pj9BXgQIj0iRfz9hzLaZdnzFFwvDUjuuRJZt0dPDMtEUWaLUWP2S0cIPjJLSEm4JW5esqfCFrhOSnlVK, woGgx9rhmhU3Fv5V7YfItdR6Ya4Nn61TZXuHgxRKhWraD82DjSckWU9eh8uVG, van0P1WdGWs0Y4xmIgEo62SjbzMz3KqKj1gaz1Oz2DuZk4Vh0WfhQxUV8lFTdzweshJusd3Wq0pdzmopk5HZtj, fJYgdSPVe8ZGrsDsj5URkQ4Po, dN6swQflYr2n, q2ca764vfjW3dsAunTwWLjNJMOzvDa15EUsScuh0pgXRFYGB7n5KHqLPRYU6Uv5zW2kM9xyB8Uc7tT7Dz5QlGBGW4wE6UkiSZ6DUFQ0KkXgv76x, bphFSsnrvrUTp20JF0EW16OkghBZ4yipad2qK, cSC2XESOcKEYMXaT6Sz2BvHjMCxzJELA1Q9abTKT4LjQSclaxwgn9ZbdD8i3HYBCkwAmLbIcuzbmYEzJT, fiW9J4QVDbOOCcDiC, cV3KndmxEb2jiUtpTbOCzpd, yCLJWfpVGdOnNkUQOtJNxI) == cy1SKKvhNyXaU0a7ucbPfvQvwiWIfyoRR9dniXhyujpGiHWwnxpzVNviq2UbpGMSS6qtMtcfp2Ydfred22sowNl9R pfutib02oMBk9NA(yqdAEKdWrmQatJbiBbNJGV4dVZvwou9CawoI5, yPLRs5NZFyGM19iZaybEfKGN67EhwEQyCPbjWQZILFN65PjILdMxRcd0OltdhEVSjutjg8uBghJUNRlO0yI1Bb5Z9DPoT1d, npOQdK86ZvrzGID2IYr9pY0illf8rz4MjpchsjYnmGgRoVtWEnCFA0iMo4T3eHtNvMgUd1aAAinQIInp3ZISWlizOHEv, f0TtYSKuVdTGPYsQOEMteXQvyJhifPDPjTBlQj46U5H2jUt9wvVR1dp3aRTPqwG8CA0zLuaDxMtKjiD2dV800Geyu2gVkNBzZrmTgYXHPX1kqM, soLhGyWKqbO7txR4jRH4eAHZyygs9FY2pZ8wGb1MGhe7TrfMxiGbZvexCSQGBkx5HrrpzJYxPfJOnx1qCXj4FP9tYNu, yrgcu41SkT7K, vZ1UpiwtSAw, jQjIvW31GnROQeexcXJQ80yp6ZNlyjfCAXkIVdoUFz5m6hQTJ2YDopUO4ExrulFicvg1qiTTZ09zztaAatIuKEwoZx1Rhl2SAZXgbmbNFDQwc, aTnI591CPvPFMtGM0DSFosqwH19JgWkw6TOAnlLrnzVTvA6GXl6Z7YZslowQ4ggbwiOdmsrbQoA7y26EGj5UThwFCuYClOa1Qk9YBSUgCj, petq1FnADEuTu9jd7L0cRMEQEGA, sCsvwtZfuozhXImI2Qe5nOtioKFhV0toIhWugF1FTkDnOM628v6BcsqgbNgPgwTms, om8AZLqChj5QWTzzuE3Klnu54DYow7CaOgsksEWJbx6rIIn5QIYNfyv0Cg0yqI, sKddX6S4cSfFmEkAfQQ4pnGOsrWyTVp6ohov2ZjNh0m8ddQ3kkuT3V73L9J8pwjLbBaOTclW1sqbCaLOD94UqlQwqfqB1ybAPNidBHJLVtCXV7RtZunR, dTB55b5g2ndHTltMFu8sA6wQO3olGlC763PxW62YsF7SGSfQPrGZtsPsR3d8p9W0rfg0rNre7Vrz, k, pspwuKWUAQfUbXxngJ3Pp7oqrvCJGZdA6ZpbX95Gt4R31sDeMmOmkzXDF5Om6aeyBaIIU8Sd0nAgUQnf3970QQNJcAwx, zROWKKR57TTf4dEuXEAJiX6SQ9ErYYVNfKBpRYozrqAUueR, dlqWvq30vbvbYfBQdWCStgeHLJOk5YktXyAFKEZNlH3zJkk1XXnxG0RgieZPspBK3qDYIkYlGRNetdU, vEUiw8Q3wDBUhfkwu85oGaomRgGEeA8L66dibMQUAP1vLgR, bex3Qs4BmJHBRbUmBOpCNiyEbmD2Odz4XFWO7dHoJpLtrpyX5y06A9aj1if4pGtp3ypR, ov8Dx4HxQI4OGfCgF64Za0TLvm7uUySHtxTY74GOmmpGXQekidK, akX5jEznhGZAVgX6PHCPhJGk2nhgVTgZifC2RIOSbGepu0x0F8ObstfajuRj6wqK67xm67txh1iRpy4GI8pDU5heY7yhBxAofExnVVQjD, wXqzibnzdeZGlKOUZ0nB1vk2EtFdhBkkQmVxIu7m2eCZGV3UVICCsV8lvEDr9APBsdu4mfEw9VDdR) == dTB55b5g2ndHTltMFu8sA6wQO3olGlC763PxW62YsF7SGSfQPrGZtsPsR3d8p9W0rfg0rNre7Vrz neUJpNvUgPe72LyeUCuIqvKpwvWW1RsckR7JbhK36dduupC2UXn9Dp4xa5ss4jbuOM6aN0ioEhvOnCNNczcf2892nd1lXr6zxe3kQaCDGgnLfiCb1A54f(dD5ZfhEn9lMy6hIQ63MgxLX9SLe9RPt, rpJZqPgaJka0TP8CucacnCDjYjWCP0rv2zonLwMNfdKtHZISwCaY1o6x, tV9nuf6o6CC9hCTmATorYSzU1AbJCuMlAfHT1TtwQkoQba, eMUJ35P0rwLqvjo3peYH3jph3OaRaojx4omEFt, p1TaO7BYWoE1lwn, lNU4xQWfgivqKFBroYAcgsUDRhut81WjH4ZXtuvBmD7xEQiX, b9y9qBsXFMo9tcgGgK52Max3oVCkIXf1Wi, xzlnQAIh2CxHeGGccHITKBdh9YGLfskDJYoruY6mniorWiSEdLYGe9kprlD7TvBvTN1wqC0dI1dV4oej07XJwNFUM, zQojcf8mAmjhlsYNQtRSHEQDGBXEJFemNFJi4MqP0vu1ODY5uUx8jNhHcgxSwGxJXELWxcsZ445R8l4U07gHrPYWMwy33rmKfLShWylo3iAqqDIps5y9Og, fulq67nBveb8AL3sI1xlgkvDS6UDy5HV91Y4t0DytPjc3QbppAtizrmflLJk6CN2l144OGC4k9l6A1zbqTVuKSJKYtoyCIFfmw4be6E, cFt8tyq89IFSpGebi2NJEKCmJyLKWNgjsy5rnlASUvkODy9ydSmXjxfXdJdPTJHqii0FccvBuNizbJpW0bdoOKr7QaRCHXxCu2yBsm1EZncCMroRI7d, nk, b, lgE0x0q5EJR5ZrQ, hk4QcmCfEaV7ynEE65eh8PBEFod3VdG3uc5edimMzdMTf1AAVYSv6cCLWTWqEfEzhixBsZTS0xAlcB3OsLEdMnbLDd2bd2agL4zuItrKeGYj, vWQ6gw57aLsFDgPWbcKGHbg83, srpy4ICi5ffG54wava8hMsJmTP3kNX9KFGjYCO1hGWXP2HNRVqmR78ngBhn6i47E4v5Xe7rxhLcgj3S1sMCK7uktoCJNJX, eiaL4Y4ITF6mZcyoGdIJRgv5brQpLVigkwsbF7ZqIcX0xjHGN1B32KyslDg8FF12SNdc6P64W, yAKiq3OZKALyVMM7u8q172vb3R3cpnLSpOkdyyHW2rAQxwT8BQltZSEzjw4CaqNFQYXbgFkJeWyvdMYyHNNEXwH34ARqUD2GWkOzVDfr4eS6vL, g243CGvyoC3q8ne0IiEs8GZ2kTu6qiksuXKAjiP8aDhLWVWXFyJ, uviiueAso6qFDAKcAO8wS685lBm2vlFpKlQ7kWrSBdmjXsFN4UuYNkpHWdGuGyMTOpd8, qAhiscJ9mgAzK44ja, hG5VnplX93p3NIizc4VLAAFMoQOtyDhjrPfYgjJ, gBMWmxaRYzda9R3DadTlBxtDqtc2oly8G8tmXDQ8feYccWakExMKXFx22vnSDX5zxIsNmIX1OzK1sR1kjiVRDA7zycVR9l3p4, ldiKoihUaHjqHQEKVnAnq5q2C0Rd4U2sABLtL48KvTGG6NOISIfbxVputvRiRkHLnaNQHnH5pBiQ2Mr, vmc7p9sqDSLNNroyrQlIP, diFkx6gTeKJkXFhVWtZ0zWYA6CTm0iXSsoaOcOcg8UjK0Hw0RbkwufGYq9EhYig4iAvHQtRqRiCo7IgPFVOoFlxuHydgkAV, xsrJ0hs1Ke, aP9UfZ2zZEj9UUSK4oxi1LmbJ6PXE8gvU6q3GS04q5VelSnO4TAVpH3Dka8Vj9224XWyXX9dhJyJKVcAQF1, mRAkfC3RBXzPnSa8ZujLPQPTW37kfUKnemy7IZuYpAKByr0gKio9SM8CNRaIvZOJ63ohlyBO6Dj3whzWEDV1DNoHksJwK4lUq1PwWPQEkSkH, v29hQOP4auFwWKQtcJmnxZRzGJwyhHnUS0a4vZ30gR1lPUeG0ZH1t0wfNAYNVN41y2qV5aSCQvY8vFi7S3TEsTCklGLhTGWNqHt0O4cYQYOX, p83nDSVkXu1cQDig5M5QVP4unsNheBIMSGNu, sAeZUPte26396OpJlBpmI0LQE21lOtx5s3t8nCC0YvHHB0CNqCxi0lJiwoEVaN, g4aq2R, ns25X4CXQFuglOEPP, zO6zdF15imNgx8fxuwZNG3p22LNMQWWjBfGMcDPKLQb9tCCs1DKDDbNjqAgipqmZJwqPve0NlsmvCQepmhtZroKqO, ccrlQKb9dTYwhvJmvl4uWJH2I70XwyocP1l3tkGTHX0Y28gm4UZgj7xJGFYs3XMD9AxWEUV66SVsHK, yrortUPsQPz3, vrgY2fCsfzc0y, atADMjtPdHVP, opNmvwtrSNJ4RuT6uRHRSinguWgbzqkMsqQ5PW4k61HUy8toxpm3yo7OmM6FD5gRVIEUwGvz9wgCqgLy6ZPMmVyRP7XRUNP4D9CIFRtHe, gRV96fKPGEWe6yKFHxpuaPq, xDJiZCAbwMbVfbl7WcbMeruamFMGo6B2HMhB8N3KRrvic7qc49iGJb0bt5jCL062D1DLivTmY5TbCyP9Wb29pn7VOb8xdbKjXTY, dXXEkdWvl2, gNOgqr8aJX4zP9l0UaPS6VagarrGqLU6i4JYxxjrzHs7mYmgJF2UuNcsLXJywdPURIQ2xCQnH9wy6Y9VSq1gC0J50pAn04v, pchYX3ZcpKwp, gHzB, wOFfsItrf6nLp7zy7bU7ADoa02aW3yFektlj8rpn8a4CRo9BFMXI5nnjixsR2S1, qmpBaDd0wwAwM26ojdOhI7b2Ue5SUX7IuWhpDaEyxk4vAZTjdUv7jAipAEZd41SjSjvlL5TUt9DlST6ASlDN3ObplY2rp0F3, vPA9, dXNBv1xjF8ZdpX9C5ZY59h, hXQEKzRGitGm2rkfhPfIdX7NNi8fC9eUKHbhKQc0bCYivC0xaHYo4yW9Z2yoPdwib39HnBYNhBDRJTDRTaCCmHUEDffrdt0hDlxNOVQ, m0XmdKuUpvl1bxpzt3eNaLIlYDGcVkOcEU, zgiCcx0Ii2UjTDawJHXK8ztW9TxnEs4BqGMIL0KGRQaZG25eHlZnVVD, oGOiwYg4Ni0FnbwxphNIY, cwECL7xY8iScG2ySRm0ti8l2SM98hhZH6aJ3n0PQlTb6CrOU12M, lx8mkvXnvNTddobS7yISY81hUkWXF2snOu4LxOpUVQdxNdAZWzaTZidvQ4UBQRrrRjcg2, ptUB2ALkx6BCK, cUmKmyddS6PXGo2GUNkzZTN7T8aUYA0TyjV6gg8oQ8km8N, rvcG9Wifo9QGqWkQA5WvYZTzYufmDdQBlhPBoANWGrgHdzdN2lO0phAeCeu8SZdsOzaR968R37lkJpZsbmUgtb4i7FPQtIFgLwfKlSeWx358mVm, rwovOOJgVwMF19p, a7S0yryJFshXqvdklI0kKojQNDdCjzZ8njL6OTEEJoDUELF3hXybX2H2j34fqApjlTLas7RndLmWeG6qHlGhOyzCgtsiZ0Ac47CQHla, zMYCpG8uLegaVSIotRhQZx9PUKAk9VScJbUaj3SIoQmgSdtj9V2ZCbZwo1VcBwjscjYOE, cTVZ9beGFz5WuA0xss0ZcVMok7s3r15KQjkTmwkdfiHoYBzsQm, vKR, hvGdY7ny33CZqb970HPMtRgqxyb38sWpNP3mqaFM3CQIF0MzGSbmSEHFblwNDXjlMjbmd6oojyTEkWwbG8ev426SvUvPZ9A, m3pIRkjqdB9DhTQmsqsPA9jjo9dtLe5mvTUlTIQQYTPzRraJUf3LhrMwlEr4tDz2kKvxYyzWUPJ8EjiiHKNKCXEwEZoxVeJf772cnNx3WWuCx, r51OBn836H4CGwaJbpKGSPoz2Po91zoZIvhLGK3o9k9cC7nDxL65U0g1z1ZH6SRsJ, sidyALRX9OvYQ64hbL3cEsPe0uJU54P, ga, pb7Hf9j3EU0fbPaQCJQBMELlAYwXQxoYkOWXxaA9r4NGEO6SWvJyMkzPaibJ7IdF2SoiamwTX23EVkG7LbBVAM4VhhrTULwtCWWSSLFVgKl, rdW5Fk2Xx9e69ZaE5r2a5LVVkO28ktahTi37iiNWVfM7OmTwDZXnoapZ2zZ23rbUFfBgi5Ci858X10XQUAsdKLQS9Rhb0D46jH, u0umaKghoGC1G6mnpX9aEDFLa9OyEPh1KfTJ2XtKcmX2gKfcN1yMKgAiPgrX5Y97NLxnkI50K7fh4yh, tTmkofWz52M2axQpt6G4OMLgBcYOQdI3KBdWdFrGq4Yda58ua, uphJqGX9ZtsAfGdpAd4mdG0SrI6BNfG39y4KCNb1pJugfMZaOEzfodJY, alki5J0u0ZkgrMwbrPRnhcNyFwEkMNzj1pZdybyIUA9DwZtyEtDMem5uM7NxfYZroUPGAxgjDAditFdK8Kcw6TBPwZ3dQQmsU, naXIPTVHPd9, uyqvkdRlrbdXkbb1ABUeKJrZpArqCmDs3O3oPlX, jj8GIOzvZwvVFjltDA5TlBEtc0thYFrEsT6AYhuTR1DCfRjSYsVExVFXH3kludlk, ieZaTIVxTgxp4XntAsQOYQiSvSiSzvhtep7YT7aG3eKqH3MfzAo4WcjBx65PerpVd, whwF81Q8dhsvJdCQotqTLGbBiGuprfUBKRivefPWwIc1Xv8qA8HKIjqNcwarJ2ywKAXiPeFuF1fGcby1Ur, k, moKtttvRNzgiambEv0ElsCn6SOnGFRtwdcwAG29VbIQADaZAhM037grEV80IiS9NXggAW1g6VMQ0omx9XrAvJ7PcqBFkKi188lEes6kJq3cx1rdArLgM, jM0j1vnW9Ph4mrAgkNml08uYIFLEOMyaTss5EIhHKPvtaTTtrkI, gSSsoo0WfLIj4c4pSfB7SH7FnRPf5BbXG3Mc6P6keRNHhbSQgnV9k7fqiumr11djFHVEAudmOEZ2l8D8hwZVsgHpXKH8CmUp09rXlTnZegeJ2yJiGg, cEgq0WGJ4n9DXPcG1DQITQYPNFnmefNHJ0gdAnOehKZ2p6GyG6dQg, xGBke, fFZ3jGvpoJ6qs0TpDOjWxZ6mt4OEwL85kU5gEJqg5PFLEcgUZ, bwhE3, vNawQMPnoqjbFKmoVzXFFj4MwASHGDlEsKnciZSThPfc6iBHAuT6Q2YrKatxfj, lJ3A33n8Mq8N1x8r2aN10aY5KsOvYQ3zHasBY7b8E7MeEBZdKNOrAKHFoEXfv8VsRcmUOjUq, g33CYBTGPqF92hNZUIGRp6UD5aECTMSEJd6FpHJQxOY7CtKloNalX6iyEznlLIfKye109jwqbAtkEYzgh4ocEtcY6NhlUUgdK7sVR8ywttsjkKYWnxXId, xgfnyJIytCnNTK, ocEx4eG5KiMIDuAKa3dejESCdVvgKPoXAmkyA5hbCRXMuX7rENyPIo, q6MTUPxEAeyXKMifVbWAq5yiwxg0WcPqJPO92LkmCdDHggelkCkd9dNLT9aFBaZ3YONXBk9EWDNlzIlMGTojmRcGiV6RYIwJ6NAGeVNFTgs4WBf3Wl, eYaJ0EQqIPYRLHBvqxhVnw5MCrO2yFLWx51zWw5Of9y, qC0lAOIYQE3zbfIiluDtQbX9kAzSxirqj9YNSH8C1JHkAErAIy1H4XSevvZAiDD8PELJG7VHi, eP5qEMgP2Xnk30GtLMzD5LEEp8xhqXaLKSqNIhCtj8mQINTnYfrdZIBiIiu, q2lslxSqzKtgsPRsGzKgsKKJtrcbcVRgCCy, pPVCCskU8t4Fbz6INc3sZRwlTvGTC6zWoY5tU2DcNbdF2Ici93tTq3JATIBcPCuHtvaBsdXUaJz, yUzmfhluvJPwrDp1VLRCY5ie1uvw9DGG7E0fYsp3r3cQOGc03HgWouEucwYBQ08HaXYsn, fqEDJDLNtlexAS4PhM6sKqSqS1YZOMhojD9DFqH8Us6zkaEBVKv3ohCj5AHpC54qu5Yzi0604JQRIY8, iDA6ycv5MPxc3hgQ16SRcpMd8GrKYzB6WxeGF9k, y4DZIxYVUiiATh6NltzAHxY0VsH6M3MCkL3n3eon1lxXVFUqYDky0qGGaL1ksz5XBUXbD6d79dcxf2aVIOiZuQiC6Aru3KsXRLwaBH, qAPu, u, bOIsQ8d8GVM) == aP9UfZ2zZEj9UUSK4oxi1LmbJ6PXE8gvU6q3GS04q5VelSnO4TAVpH3Dka8Vj9224XWyXX9dhJyJKVcAQF1 ukBmRCtcxU4Z3Yksh0YjLv37MqG99dzPRYxTVv8OCeIwGKh9SwfPSVAXDxWm4T(nyb2Il2gW8dHLUWW4p0IPl7lRCwDCI, q71PuuOLcWFWM12bsnpvqgv4m7uQpM5SbNYxFzyUcheNfOrOdgOv7ZC8TSURQVM4CxsuHzya3uFEVJ65Rne6lO, jGueCxB, jDsrI935UaJyVhce, m8pHde1ec1gY, iotRSKGrRcs4opYC21UM9ERt4bwPjxjwD18a9TYB4EJsQtpFPuybb8xGLgWJDg5Z0eNeGMNC, rsBUK9zYElS2cQsqX2vNWgNm1qAloPP4RPtciMXDX45EhzTPMNp6RZhLlzFovaVdHdO0EViwTttInwqNRjPa1Q3CyeY0ZD5GVAGgHorv7n6AT6, aCbVK4bc44RJSB12Mbba4KhlNUd2AoJSGb2vUKIp1S29aIRGhxh02jYga, dR0tnBY9KUovDwO19VKuTnmSIBpDGgC7u721Hv, x1lnZT49wU1tTxyMcVQYceJ5gmsIwMromJTw8YiWNjDZn1is8psWwz7nvSZrFz50dHVgwJXdAemzpgMZzAsmt, ehKs6sNuZhfo60rG2sg3R1QE5CVTcWG2N7K5WtJBizlRZLVtd, sR7JVAjAVdvlxD456IJ3NvuT0CmjliP, kdUl2CTj, y7TkhjqDzL6ubH, o6thVMlWBmtwYbrcrEiBB8WQfeKvMhyAeCv1P87Aya, u5J9mWoWXYLh5wmdR6YjKcUJtt9qCeQZDAl, jDJPvWrhjydEEYKuKlywSj3ULE10h2dDfhGpjTlGPj7ImhAEMVwXqE24JKmYSzZ7Mp2ftKU5KWoVhxRRGFDKETVR9k0Eavmp, natnlvtTyMOYXqw5u7fHGg0iELBvSL70dxn6PDm8j3SbDjWSkggBG4DFQvO0yCEXBBfAe3bzn0PIem1NIWvi1, lRXB1iqx08OAZGcFwFyuApGbCzQM8qvAq4SC7nOST4awVvYYChJKet, zlm90l5Tu12iJlCg5vGwjGfieiFxrqp27XXNJsCaWlwnrl4wMWIrzdD4u8oJ6i5lXO9e) == lRXB1iqx08OAZGcFwFyuApGbCzQM8qvAq4SC7nOST4awVvYYChJKet bxqRuwNj67l1Tw0tG4FnJoCpbcwAITjSRFP1I7Gz9BYYEOtYCbQNVLKoEIx0CSFwIyMkChMguq0JB4zT4HXTZdyPn0hn6D4EmtYKzcNEuKBXWJ(uQKOCatlf16egTz9aQedQmOycWBubYLr0FK6oPRqXKV3dbBmO08OiqIS6fYMbg3da7N42C7TZsObO5CaU1CA9051loKrLv4lqizxYz7XN8s8, aSBKtbpBn3rK2oORAyA6MoTROaa77w7IwzLtDcsgLax5OF1Og6b17CUWWGPW8Rg2wBSQDrrkqQqZbqgQbmnNB3icV1KjqtR6XXRZDe, cvWtM6M0aZ9GrzoKN4gllrlyIjtOUWUKBQiGXYT7DFyFzcRB0, lHiIHLn7Dmi2N0yX06JfZlhPboAMDmDkX6nKXZSHwvuzdAwMzrRjjaaIGcNZoDr, q3GxRQPGNOiCkdTjH3XOLCIEHSCR4qK593q75ytYrCnibjD, aC6bZpF0eo7Nc40PnIq9BnapFYjDthyAe7T8V9XI7ePR3VIuihpwqEJuWO7Sga1Ar2EtAYmgzOekIDFnWGhAIDMCh66OYflzfGtwLkUFuvw, aIThXsUSsufSEXBuWRynAC1amycmWnjFNzk2YZoQdw, azy3TQcyTDxmalOQ8hQ1R, x2vzC1BV0ccqEb0JQH4JNj1lxdAJqAS5JqYM3n6MfsAgoxBuMeWfVivojVbSebpV2Isyle3x7bQSiIBLdehUUpT7WcRtrxwTbeBM, dycm4g, e6fp7MZDbcL40Dzxi19tsqc0NOFOMptZXKok3cNaw39jz1Y5olxY, fvpGUtlF4jbJlaEYIEf0KKErG9yMSULSamF3p6uX0ekan7FkYJ1GfGY38FnvaI1xCmJ8, tJZWvhtv5t3w4YOudUqIqxcButdvxdk7QrSkfXrRqxVm0PDDbkDGjxXusW1zEUOz8vtC33GLKmLiaHqvodkyGwzNQqMDN9G7YlWvHFkqz, d9CiJ67ihdcsq1zGpto, l, kfrmqCShcCimYColT2QdFsygTpY1UvNUpV1F0OowzVmgYWEGVThFFpDzf2kmV2bkY7iGzh3wjpLozJIKcFM8I7jjzR6xT65S2N8DLzSvyNlfmE3fgRF04, kiEBQpQU1jo6xyK8efcGcW0jAoRCr5r4wnEavbUsAdlxFvgolAab8QdiIp1Gn992bqEFPvfvm34BvkOQO6, iKFAEtFY7hy4ljNTleW62hcjlpteNLqZpH5UB3uQ5AYqimTymiXDGyjxbjepAcESn8IHZ6bUyxrMKTlGHw8vtAMSzjCVEk7, xgAmcY408twaQxSDXaB8ExSZhkDoIOUqrEDbuUPW6KriB9WX4oItCZGLuCw7zRBWKv6auaHR, hk4VkY4ZiUu63GVigOsSjHmYOyH7djLQNJH, o5IzQoYsUrfVa4i30vvpTktVYGMTG03IMKqD2O8tzsSPuBM3f, q08mHqx7dfTfgggiLK2aNOcXIE2Qu1aXdk0xNvjGzhAfytfEqhn7PI8dZbzgmKhCTuLHcZsTNglm1ZRGzkYO, aJ6DcsWlrdtzTbSTp2pOl1Hbhlato7S9I4f6veppCSYWAiGQuamaV2aG5nVfKUHl3wyOpJZqGTgP7wJJVtvg1a3N, qGugRgMtXAsyiug2, jfMuGqGfx3uqKFk5SD2sEJ275K88pOCqxvsQhMMO891qzSPrX, jtY6HpnYNk6doqATtd, iN7xhv1MzuzYOiCT4Sh7VEShwfS6sa2FuSTedejWWSnBGSArKrArNYfPvncTWyAvaLlVSyF1QuOnxdjlfimPKqXVCidOfv, fsovO0g0buqgPfCT0iUyGA9qkdqp0xiHMAIG49G55vlE09nKWbLyZtvKsrDMVdanfzutwMxLqAmTYzcrqnEllcQqBl4BvccoSuTAO8, yNtOMcEdkEmNHxHRNr4rjaNgiwfw1GDkwQD6XPeqiRyGlBjcQL7YYe4S5Zio834Tr5wv3WEroBdFzeiBT3q5qvcwkjZS80CYMh0GYdA1, eUKe2HagRA189MJo06zexEUWOxxG42bmGx6udVAj5e9DmDbWOWIR99Gy9cksjYRqdTDipT87p7Xg1O0422N2qKqmcIGLqn, b8ddK4eqk8erPJfE3PuBCt6R1nR8z7NaX3af8RpBE8BmAREE4Dm5TkAjRAok0lqrmVEt31Z2eIU, jlw8fsBEtqRnuqaouK2iwD, u0HfGRjE5jId7Jhdx9DjpuZyYrWocemqVPN2AduRPIFnNOINUlVrveUoHJYa2BwoL9qWNMkvPO00sIMUJNP, zZrD2GEI3btaWmmFMhTWt6njd56i9O2AhKTWC8sBzgZYFJjbN8JG8qvCWGfOx8sHyBtJVWKg11uGBZxp, rJANcC7QzWMHjQUaXUF2mXXhnc16yDhM1fHMS9ySiXRK3R0AnaDWDuff, a4kMZiT0UviUzwO7ZTaBAipAVX3NmEFSECOZuvdMwni2OUgKP0tjPxcLFcMVpe3GxGsUwIRp04H9GPhywpx, d1ZxaiQ7KROXHTKbugNHaWJwzfqFqpnZvqF0uVRvL6qe4NDOlicOjmSIRG3aCAQNDVjqA8T7hcKt6L748YJjXpsT, dkh9dftAKQCsEu, uBHkN6sQPuvNQ2R4SxtqVtCWabcO6Cw9u9, tSr2ZDgbgVIWcGa, sfH8ZI89OKbTq2, r, dW1tf5x24MAFXIZwyZL14oxKVN28EhJkpIYSmr64ETHGdMn0GSx7udq2c, t1Vj1Y9RtOoB93Ckt6kan7wmWcLVaxgOOyiX5N6USZkFreiIb9ZabpDGYMtLJwTStnXx24GHIU15QqTnsAOaqSeOoV7Trv6sk2L, n2LQazbNy71xCM5yt9hndpmiEGboqRJ15GZ29b2B, ynKpefQii8aRVNTmUfBP9dP9B2QRq1pU5SyFa7Ypq7CfIV7ZrouSG2JWHiA0c7BAy, ocsxTpiMPrCwBoKLmnJnVTDAIygjTtQq3HK4ZLnetcZVv6Ego8thDXL6MGaWRUdlSzqMeTjId4DsWdnomE26RGdNObdgArTJTMu64ewiS, xHPS0KAxYP4ARqQi6DAEH58yXjI5cyycLKcsZyxy4Kj2IWjcTDW0cA, wxIfXMQKmfhuwZ1AkGH2joSj8Js4E, mXLeZojiw7j0DmWYcbEzGgKD3XxcD3bElIEzpvo2zc124j7eNKJm35WBANvQfL, aw4BXjBAl0R2ui, ou9g1IqqeQfEnYj, k4WP6HSX60Pe7oJUbyiD, hXBgjNmFO64gshs3, dBesg6m9CJunJHw5V9DVeTONVdkh6zQ4qDLYyMIV94vYM85zh4ykeswLKbyj0YSa, raR1ezEVYkGNdZ8dfrwfWa9s6WF, erPhH0uA9ar74awWPit8BRDHHVvWm9PAN5YQ2r, zXgx1ZIcnmfAt8eeR6AoYrUZxMN3PDKsBFjHRPMCUM4kSQHAPzNFMwHA7kulY5mmd1IqmmZrbtgqJ1go9, wX4DbY5Cjz74DH2EBMTqEEmAgPmORwLzyzvrgzK61cM1FkFWNOuXRRjxGvySbh47uekGKC51CZH0K6PnSYnf, pHQbaz8L2o4vtwfkHITGp3hLmBsEzUfnnREIVVb7w0QPiLtnO5wQOvOCUsnefuaS92hqEfEovByLvfZSALyW53iZ0B, vN0oAukCuH1tidxYDNv3tpho9bGH3dSN73iLyPT4LBhKLcweYencnOhr0IVE2WqOLpNqmSXM9e9EmuyntNAvXX1zAXw8, zwwrnscjMRSo4ybtRdBfaCWo5p, u9NLz8UiJfrpRokx6Klej3lJwzxIXELFLovaChsZCbaF7sRLeAjVOdqXk6wPOqM0b2hsfLzYigVIw2IeHxumWrhdxz30Db7itIInwdLJENUAR4, onQcOt48AFx2g3vcKr7JeP16DTWGKYuPbOPe0fPztj1pyHS5P4VKSrUkX9DuGqNISiGnqoDfMWtPqJ695WBCVZuqsy87ZWLKreaaiJJlL2mQEvTKGcq, nzSv46djtF8jRAb0x1tkPL0pJAgZeGMg8mjp0HfO79wuKKHL17c4Qouz528vcFr7U7U7qSK2EHn41dubI, haqvardC6HFV9aBiVpOkhAZOCsnl0AdN7O5jSmdwo4FOHk8GRwsYhBL8Vojo2YZubGmtsEVBuL8OgqDX7go36puITdRih4, tdDITA9zAIMITHRr8Tu7k1MKQvapl1SjqGBfkNpAq7C4WPXgALuD22gJlCQEkDwFLZDM3B, gtcDnKpcoxXxmgSEaDbvuU0S3JFm) == xgAmcY408twaQxSDXaB8ExSZhkDoIOUqrEDbuUPW6KriB9WX4oItCZGLuCw7zRBWKv6auaHR oGNcam7no50VFS9bNVSLFrVV9tFOTIhTwd9VlrW1xT(am8bWyy6KnGD7pbjuRLHR01nW, i0s8KBm44MBD7jP973D5Eu4zNKCiXaPohAQsXTb4CMmE4z7uccxlcgtrtLf6tVytqIhsXxkf, kwC5NvLfjhrgra7nBauJjJdcPCGZMVFBHk9of51zPNdpV0LNTaraqDEhs9qKYY8Gngi5uy9gknn, ehW25vry3ut0fMujKtUZrmrmPZ7SGzViNd7FExfqWnXySATsZ0eFyWdwwbSx5a8XFouh1UrVdF3otRcwQsbBWkjICbhdFUD0zy6VKEfDFJ4qJ8rlBpk, vcYhmXYbqt6NOh, fjjQWlZST5w8UQJSGYmMExwrE4KiHMs2vva86I7hMGFIXjZMt6Pr6inLcbQaI2fDvv3wzAj, iGP7JEUvz0e5rYJkVm4vSagOFQ98H9ywKRqYsAca8p4yX5XVkKKphJUGP4n, cStGYyv8V, l1CWGSnDAFA9JP69nGrlo2f5ohVH7g6O4yTqWxznzWqFPNBGhTDvk1nDQDU398teHkao4sK2n38qz7zl, aiV1iGsofLK7qe1lQxjSZe55J51Q0s4z, mb2f4sCh9wj7JdY2V3cEmrIv99amnXuMutObxCvZ5aqlj72, p05MeTxF9stYUJ2JXqTIioRDLc4, cZHjp2fGGJxnXXb2t9XjqSQprA5WQtkCwSETFbkGseDOjuuZRbJo6VRiLEn, zyaZUPLlnqpNKeTj3tokZX4dDrnkdjnPvHdgCamm8YLu0WH8IWxsYZnE7tsnbXfHudC7VRYjNvOinB9oyHyaIRlCVKAF2M7dkDCbYxQKSKTU1q9SGZ, uJh6jOSh5uGYgEEzpgdPGVh4TXRlrRvsDzgqdchE5JJdHJTfqOLbxIlSoJf, vXSvT2saRKtTIpFQ9Lb15wveUQM82wTqNV7k2ilR3nd0leLNv8KIm3nmq51aDmkfPmTHRBaNAbZLxFouVAd4ywUHeHEA3tA8mYYCCDpcJNhzIsPo, koSPqSVrdMCYlCkJixR4xlBZmf47UdD0qwxD36fauTxnkYeonmYd3VgUmL695pjXrOsE5puEJtJn, toHkXVSgsIWfecbbl4rfUKKsNhId3D, vLzSLfHX7fGw3l) == l1CWGSnDAFA9JP69nGrlo2f5ohVH7g6O4yTqWxznzWqFPNBGhTDvk1nDQDU398teHkao4sK2n38qz7zl - IN <<>>, gSapU9sycL2vu74K0nFmmgiTgxxxtWq92c0ho \in [bV2U08WxrbJW4YyisaWLdDTlnnQZN48YPIYI1 \in Seq({}), <> \in ";nT!E/a\"~A'^[uvN51;+TePI5&t$^^Daj.]7eDe:_41h;{8(jzvkM`TLwt8" |-> Head({})], <> \in {qxbM0ySqkdzWhn6gaROcgBgxFwsaY7adHaF3zhWU3qvyZMiXDYvhlbWBjZSc6nCHr8DLrsWqkB1ZScZHg8LjT4uJqajwOdLZpq4pEzU6a6Gc : <> \in "Or4uYZ'{+a\*`I/tHTU'@Fw=}G/B/d%h\):%R.FE[0}o-\\ -8'jRgIskN&SKdu\\,\"\)9%r;op>bex\)&O5eqhS/xtaJG,nV#QWjd-c_f:\)d", oyarDkIO1XeNWlRTWPoDsk1rDzx2KhOGK4xnI3CjESXu \in Nat, lAPrrMqrU4ntxPtOdkQigX04o9A1UhGZEbuFmCpVZXsEtPOamE6NNhWjuNSx4u9QGUQi1eGldztPwD9aM6xX3 \in 55, <> \in ">&cXJ\)Blo@-}ot<1`,WaQ4UI%BWVB\)psW,;X", <> \in <<>>, <> \in 68}, nrk37ZYFObeGv0nT \in {"w5:3;Z'1> \in f8FerpPpvVx9MMkWzCPTDTuHTYdIgpO2mcb8SJJFRoo6DrVmr9MPdwFWO4DUFYF6L2lp7vY3RgJuBCEHbcRwltB2NSEmn0RsHtvn4Dchoua9Zh, <> \in uTBOegzf41xwPV9PP4Jyej8A4q8GFeUm044NwlkPT5BL3eI1AIfiH8e |-> kKa0FOAnjnOrXmqpw5mzjiGjspYPvCI3puDlt1jTnz0hhp6eg73Xe9igS9tmIDWBiLcPUA9cZz9cSSqKDCG5DRShCWvfozxKiwTRbTHl93hm] + IN <<>>, gSapU9sycL2vu74K0nFmmgiTgxxxtWq92c0ho \in [bV2U08WxrbJW4YyisaWLdDTlnnQZN48YPIYI1 \in Seq({}), <> \in ";nT!E/a\"~A'^[uvN51;+TePI5&t$^^Daj.]7eDe:_41h;{8(jzvkM`TLwt8" |-> Head({})], <> \in {qxbM0ySqkdzWhn6gaROcgBgxFwsaY7adHaF3zhWU3qvyZMiXDYvhlbWBjZSc6nCHr8DLrsWqkB1ZScZHg8LjT4uJqajwOdLZpq4pEzU6a6Gc : <> \in "Or4uYZ'{+a\*`I/tHTU'@Fw=}G/B/d%h\):%R.FE[0}o-\\ -8'jRgIskN&SKdu\\,\"\)9%r;op>bex\)&O5eqhS/xtaJG,nV#QWjd-c_f:\)d", oyarDkIO1XeNWlRTWPoDsk1rDzx2KhOGK4xnI3CjESXu \in Zero, lAPrrMqrU4ntxPtOdkQigX04o9A1UhGZEbuFmCpVZXsEtPOamE6NNhWjuNSx4u9QGUQi1eGldztPwD9aM6xX3 \in 55, <> \in ">&cXJ\)Blo@-}ot<1`,WaQ4UI%BWVB\)psW,;X", <> \in <<>>, <> \in 68}, nrk37ZYFObeGv0nT \in {"w5:3;Z'1> \in f8FerpPpvVx9MMkWzCPTDTuHTYdIgpO2mcb8SJJFRoo6DrVmr9MPdwFWO4DUFYF6L2lp7vY3RgJuBCEHbcRwltB2NSEmn0RsHtvn4Dchoua9Zh, <> \in uTBOegzf41xwPV9PP4Jyej8A4q8GFeUm044NwlkPT5BL3eI1AIfiH8e |-> kKa0FOAnjnOrXmqpw5mzjiGjspYPvCI3puDlt1jTnz0hhp6eg73Xe9igS9tmIDWBiLcPUA9cZz9cSSqKDCG5DRShCWvfozxKiwTRbTHl93hm] \* this being empty is also a test; can PGo compile 0 archetypes? (* --mpcal ExprTests { diff --git a/test/files/general/ExprTests.tla.expectpcal b/test/files/general/ExprTests.tla.expectpcal index 66fd8c190..61c911e20 100644 --- a/test/files/general/ExprTests.tla.expectpcal +++ b/test/files/general/ExprTests.tla.expectpcal @@ -1,19 +1,19 @@ ---- MODULE ExprTests ---- -EXTENDS Integers, Sequences, TLC, FiniteSets +EXTENDS Integers, Sequences, TLC, FiniteSets, Peano Test1 == { x : x \in { y : y \in { 1, 2, 3} } } \* this test is not expected to run; it should compile, however, and it should not cause any scoping errors. \* at one point, this would cause an obscure mutability bug in the TLA+ parser, due to a rare backtracking scenario. -Test2 == \A <> \in "W\"!> \in [rjg96CqaSMuCjtyr450h6DL1e02XHUTSveCKybqCudAztsOjRmkIEFEkhaCX9AEfDDCOqmuEg0Xtb5AWWeMNM2fXfObxeWMG7AcDR5KDDHmtkGN8Xd |-> Nat, cSOk29itvxzRN2lPY |-> <<>>, cfZGl3Wdyxt6gGxpst0G2YzBErEDXQwzSSWERs9MLYB4BpT7ne6vVOh8FuGMFN9KLaHIP7vJe7ItfvqjAIKw8K8LdrCZt |-> "nybf\*j`.#ogke@%3kx7zwaX;~nx68X6qVB=\"Dj__7mkIq=25>YVw#\\#]8?t=]ndqUQnWNDhr([Q2Zd6;", fHeAZdw1vCnj3xfH9h22hrUcMclAc21eFx |-> <<>>, kPKP6DMtdXB26DOcOq |-> Int, kOufhkQQBNihpnqM5EG2ave4gvDLXzM4eM3AF0s1vozipbR3jl8f25jIZF2l1DrHNVNGzYyh |-> Nat, pes31jiQYk7kh9MbAqDybYqzToYtXL24 |-> 105], <> \in {dVpTt5jrKlWu0I6Hq6H80zTmUxwUAJYO4dKwf6DQfbTQWe9fGr8TtnynL58wFnRcfuVdaQJ6yRM : nocBmpMYH5HkfAmS1Hxov1sNAmNpre32Go2PPwiq2V \in 66, j8KL43er \in 99, uOnSBu75CcElcoR2ZLguWLx24i2 \in Nat, ciyA3piCZqGxtypqDZ7yUA6ZigMVm0gahHBAmufYN8QSkFcoxD5mhB0H1o5fgF4J0oOpzQgazH89oz \in Int, n4vC1IUc6EoStkodAFXDtaZxD3jWmDWSa177v15UbOG2B0yKlCWueKjkDEczLz2NF3SdvY \in Nat, <> \in Nat}, ydWAMLx2MOT5MVTV4DoLy4m630MxBh8OzY27IXNa1UwzilN9ABwtkToLjGTMbiFUNXwOxBlp3LCAIzc3syTXB \in {{zWSbRBDcKvPAzjLcOPdpDMdxHB07sO7kEq9Sk9MydQzf7b5IguRfwHTQeQwDS8uwsPPE77kph4VdYlWi6GlfISwJgzUF5mDwt} : nMDLcmFYG6N5X5qUG4Q4ELPxCZRP1ByOFD8cIbWHPjvMaPtf5Q7BBDw71oHBnalYi6KgmUCNtO0j7r3nAkq7Wn3ClMSz44nnJXpgNIZZydK \in 68, vvmBdcUQcmzi3aF14n2S3Oie2iBRkC6Pq5dh91BNivvWOU8pQ8lX0buK5SxjDEHFi \in Len(Nat), <> \in Tail(<<>>)}, <> \in Nat, g540XiUzWuW \in (Len(Nat))[Int, Head(Nat), Cardinality(<<>>)], aYGs4t9TNazIlSTuMV2UZJE2Su42dELDJebUslriCHsCdePddP6kT4herkEEZkaBrLcr19VzcoQUqUxLDj7aM9GlCyqIWhrn1gQ12Wcafcg \in {{jFSnew60k9UkNMbOwRMQkAjaDOsCVlPPzNCyFhfU0fyWovez0zXZDVqaX3EHHxW8P9RjGDPX8z8k8OPG6zvn : bJdvTIPKLRX2S7AzBaJhHn6qzYpgdcuCSHMXowo \in {}} : jFSnew60k9UkNMbOwRMQkAjaDOsCVlPPzNCyFhfU0fyWovez0zXZDVqaX3EHHxW8P9RjGDPX8z8k8OPG6zvn \in <<>>}, qvEBcszWN2nDUY1XVCrYsYFk8gOLE76XaPswHtQNF9Wf5L5hSOy7zlHGM8C85CJb \in CASE <<"|AP8[H3v] 0TXS4l;{MD>jLmGb~(,$M3&I+03G/|yp\\lCm\"gW{Y,|Jp`i$ICm_%\"\).WjP_Q/lA5">> -> Nat +Test2 == \A <> \in "W\"!> \in [rjg96CqaSMuCjtyr450h6DL1e02XHUTSveCKybqCudAztsOjRmkIEFEkhaCX9AEfDDCOqmuEg0Xtb5AWWeMNM2fXfObxeWMG7AcDR5KDDHmtkGN8Xd |-> Zero, cSOk29itvxzRN2lPY |-> <<>>, cfZGl3Wdyxt6gGxpst0G2YzBErEDXQwzSSWERs9MLYB4BpT7ne6vVOh8FuGMFN9KLaHIP7vJe7ItfvqjAIKw8K8LdrCZt |-> "nybf\*j`.#ogke@%3kx7zwaX;~nx68X6qVB=\"Dj__7mkIq=25>YVw#\\#]8?t=]ndqUQnWNDhr([Q2Zd6;", fHeAZdw1vCnj3xfH9h22hrUcMclAc21eFx |-> <<>>, kPKP6DMtdXB26DOcOq |-> Zero, kOufhkQQBNihpnqM5EG2ave4gvDLXzM4eM3AF0s1vozipbR3jl8f25jIZF2l1DrHNVNGzYyh |-> Zero, pes31jiQYk7kh9MbAqDybYqzToYtXL24 |-> 105], <> \in {dVpTt5jrKlWu0I6Hq6H80zTmUxwUAJYO4dKwf6DQfbTQWe9fGr8TtnynL58wFnRcfuVdaQJ6yRM : nocBmpMYH5HkfAmS1Hxov1sNAmNpre32Go2PPwiq2V \in 66, j8KL43er \in 99, uOnSBu75CcElcoR2ZLguWLx24i2 \in Zero, ciyA3piCZqGxtypqDZ7yUA6ZigMVm0gahHBAmufYN8QSkFcoxD5mhB0H1o5fgF4J0oOpzQgazH89oz \in Zero, n4vC1IUc6EoStkodAFXDtaZxD3jWmDWSa177v15UbOG2B0yKlCWueKjkDEczLz2NF3SdvY \in Zero, <> \in Zero}, ydWAMLx2MOT5MVTV4DoLy4m630MxBh8OzY27IXNa1UwzilN9ABwtkToLjGTMbiFUNXwOxBlp3LCAIzc3syTXB \in {{zWSbRBDcKvPAzjLcOPdpDMdxHB07sO7kEq9Sk9MydQzf7b5IguRfwHTQeQwDS8uwsPPE77kph4VdYlWi6GlfISwJgzUF5mDwt} : nMDLcmFYG6N5X5qUG4Q4ELPxCZRP1ByOFD8cIbWHPjvMaPtf5Q7BBDw71oHBnalYi6KgmUCNtO0j7r3nAkq7Wn3ClMSz44nnJXpgNIZZydK \in 68, vvmBdcUQcmzi3aF14n2S3Oie2iBRkC6Pq5dh91BNivvWOU8pQ8lX0buK5SxjDEHFi \in Len(Zero), <> \in Tail(<<>>)}, <> \in Zero, g540XiUzWuW \in (Len(Zero))[Zero, Head(Zero), Cardinality(<<>>)], aYGs4t9TNazIlSTuMV2UZJE2Su42dELDJebUslriCHsCdePddP6kT4herkEEZkaBrLcr19VzcoQUqUxLDj7aM9GlCyqIWhrn1gQ12Wcafcg \in {{jFSnew60k9UkNMbOwRMQkAjaDOsCVlPPzNCyFhfU0fyWovez0zXZDVqaX3EHHxW8P9RjGDPX8z8k8OPG6zvn : bJdvTIPKLRX2S7AzBaJhHn6qzYpgdcuCSHMXowo \in {}} : jFSnew60k9UkNMbOwRMQkAjaDOsCVlPPzNCyFhfU0fyWovez0zXZDVqaX3EHHxW8P9RjGDPX8z8k8OPG6zvn \in <<>>}, qvEBcszWN2nDUY1XVCrYsYFk8gOLE76XaPswHtQNF9Wf5L5hSOy7zlHGM8C85CJb \in CASE <<"|AP8[H3v] 0TXS4l;{MD>jLmGb~(,$M3&I+03G/|yp\\lCm\"gW{Y,|Jp`i$ICm_%\"\).WjP_Q/lA5">> -> Zero [] "~ l" -> 34 - [] (Int).tpFXgtDC996txdhqxvc6uTZ7LGguVCIqPWhb4GPq0vrjsU6VJ36ivYQrBcr6eLu6EeizwwVG4duDRq6 -> Cardinality(Nat), <> \in {103, <<{}>>, Tail("ao>Q^45R\*\)&S.P;@h>(g&QFHhB2]CIa,O\)R}&icu\)|> \in [eSmDnVka2T5vfCr2D6NAeJaHIIDOlNw2EtW2rEOQXQPKS5kkyWOloH5TdOSGJ8Bz44giGFHo7gIWf8OEXbvNC4Tf8ygMzR3dqbcqv |-> 69, izEEDYZa31aMoAX0ZZSPtnzZiSJasTS5zXqdJAympTsARWZkLDJD |-> 113, dyEu1EeADkIvzDaPjLTdpJIcifTMU16PgoOR7843Gu7mpKqkARv0JE2u1zPr2eQ4vy0VjJul5uqeh7XlPAPV9enWRCf8t0B0xY0IzPaYhk71Y |-> <<>>, ihxh4hux8hT1KYXTuUzKlwPYkKAA |-> {}, ztbbVgCSX1bb5RMzZV4BCFgYkbdQlRyqG57NRyYuAN37oz96UHjVkC7HEElI4leshq4qEfyyLaNoJgFjFiy1Ucxd5jJpteH1vEaWkHa6yFo0Zzk |-> Int, zjWP4mQbVQ2lc9Ah2qo2sENITxJ9Fk |-> {}, v4uawbLQboCq5rPaF4O4P9LhHxvqZlwWboXHoHD4oeoKTh3DhpLroR9zLte1WE3VZl5QuYZf71I5yofGfhfrcAeWZq4MopRwyEv |-> <<>>], <> \in LET dMBYoW4IrtFxgIWrYPBUK7U82G2P3eAqe8GTlNeOFFlAJ6oEJT(nxVAq5SHVzmvyyLtL6KTp81XDMb1M5gm1tUZ5X3tO6tVeixPGbirwW0b3WSixN9B00CFRj5, a6O9WgcDePw3so7SKk8CrZcBbOAQw21QJa3wAo83WKEVOM0q1MxaUg1, iYzkTIpshRIClbgtt7PCsvhU1p9zHHuWkDkQVQpZYHwqetUCJHB9hzSspxoSd4tazL2qGLqiGljQPkkk1abCepxIxQJMsHHegjnI3ORMkzNW, eibKgFT2bFMHNqSkBKHeq6rDs6QWjrBuaUppNNFWfxfGm6ybgx1y6SRQgPWrTaWtoh8IWCJ7CpHI3sl, ybPgPsNbI2tuE2K1iA1LrW4eXPRY05LyWpBCpRHC8q8iS62OXS5add7In, uqDvk2oF1CmjHdAze6afrN9c6Y0V9mZmsAdaeSgayd15MXEfOsru6LNlEsfLBwtgaQfH3CL18EoRux3NHDZ, vdIscEuUCezJghNA3FcZvKPOuwXLU77vygCZ0btzt4EZt90EMW9p0Alq3rISBmthV7NJiWDtasETDIaFyY4fTyJcrbJZ4nnLLL6hlo1r546GIlFHKhA4mf, yVo6R1IjAptaDLwUA1gBn7YfjaF7ZaAf96NxQxdB0z, pnoaUybvqpbFApkcV39Z6t35wHInxdO1geVF30nzdltg4tzSpvt8eq4z3MMOfMBaiyhRg5ybcnhTyA9zEopw3yI4Z5EjlABh9vADzC8, eTfg0HxBkXQFsmHMM7tzNzFG, sIwkrxLi5Ntu7Cp9N0qYRzetOgu5Q3WJkgiou6rcWtw1FCa0K204YXW7c2cc5QJ8eQlYmRQEB9ZX0D30PR6hrduOxltushIle85WUU7bhAWVR1, cIAnUzlzJJKbDePXcOGU5EHKL9nSXf1, cOK, sf3IfXkK2Ol7Y64A7mgUGWM8S3ccH2, jJb4v29omLKKv5It5RN2x2IFq8HV6Z9HseNGKEWmGMBIkmnDEwUI7QvAxfRH, rsLln4MGBLeC81BgBMGSXX, rZCJJMsv1jAxmyQjMLhsdmH8WMPJ3uctBaF0WdMTLBDSW3HlmBe1n1q9jZVLtpkSRwAnc42l8lLGMKZLQKRY5QAdfUsrDlVIM4JAPdiPsAHxXggP21tB, nUPa2waBp3rkfbbmB0YennfJw33fwZ6nPJ3cdH26J12SZZcOYyVvYjbZi5XORCxTdbP9yCAqwA07HjhaHboBNu, aOXhTn, iJAYyXf8zHNTmbKp3UW5K4B0ALrIWjnZwPYa5eQUPDWP9X0EN1xRAeEW1QltgZANH9Y8cl93VWXWPx1B1CeGtJ0Zc0ra3XJcB4a5dGaEEHoVCB9Bsbp, vZAUwcaw94oKZdAS6NhOEpQjadeImLnBdLABlHcxct1G36MLDBMPzbh, zDJhnifz1, pTnQLAuZpwUaqY55cJuvHq1t330FccrKxkEcnudLOjKgqVjJXw9oj, hRZGwOfVOqCN3NjIwRUIKyhwawc4xTc9ckcVLWqL, itF2FYh99DkOnXp5ZOxbXJhYWRf6Kt5TcbKiMnt8KtN0xPcFwqVhWorFOK1ZkGuUpVvLDl8CtcCzOCJ2ScITCo8tB13EOI8dzwR, t2u9, dsXbyTPuEzKcBmNO3vUoDy8byFgyYwP6vmR8ScQVJvNNE7etXukR97tdfJm, xIqUs2QwtR7b7gzlFAiA0nPagsRcXRIrzd4XwPuSc4iY4gcFOBkk6HhYPbXpD82i6wZA0qPxSDujwkgD5UgOb79C8n327qYeZB3B, jrQMqgDsjm6qLHAjB5pC7RfvvjGzAKPtxxyypA, sjl7d9GZhoCh5nEdbcXF44yFcu9W2BJsCvdIUruGMwUpUfXl6IhhRcqUlNPlX4ZSMmhnM9puS, iFSImI2CjxTF, kDb0r3tV81qr6H4SmFFabkD8DHWDz912PeZxQ7YRh9FjBCwY6eXETGHk1Flvk8zD5JpOPfpDTIezK8Q7uUrfbbKuW4GDDiAI24DnKiJeX6hYL, dBtIva3EV4kBUnhWYYKtDcY68OOM3, gU6JaM23335s9fdd71Iu23H6letgfaEm7RMjPRIJV0EjNOrROJCV6juQ1ZutwHbIHmuiU9JKTbyNlwGrxSgvwbIcctrzzvyj6MagRIpvB4Ue, pf1ouwjozkq46dVUev9IMmjvOCNeQSlMXvY, lEwUC4BNAyX, mu2pHEkSxMpJG4IFjyzfSg0FLj42MK5bnIGesapT8TI2cKhWicQcedPAjtR, c1, d4J4XlhEfuUcKHbFjd0I2EiqomIciQBQ1oCZtXOsXYMexyBzM, mb6VcvGiNqAddoL1U27vHSbT15kiRVI0Ccg8bjGYk4N, v32tgD43e2RMYs3l17XRA0oqcqjgppgbGCXy6kpz2DX9B4SZJWFDSafw28keLFVVr8gz85aSukay, od8zAG, agI3fF6yeEgwn4mHyIS6BzL8ZmZYxIycJlZbOrdWs0PuDp6EIp3OEJ4AZeMwbAaWG8C478nr96ufy32O5B9ya3RNgsiRol8, u5OX7jli7pUvdFlQ5GIWp8Y2V4w1Qq6JuSZNXFX58tCXaGAXNw5yAnpgjN7YI9OxgsMaqOal0gviOTsLnltWWVtP8, mzoT46CbhESG2XuO97YqjAIOTKzWRFV13URZM9bhApen3u, euHzTurEOVp5ibMG93Z5n5QIz6Vvd3yxatMiXyCUL1TpOljdnVUascnrfOSIM1d1kkwCN7PsN2She47ixp, cy1SKKvhNyXaU0a7ucbPfvQvwiWIfyoRR9dniXhyujpGiHWwnxpzVNviq2UbpGMSS6qtMtcfp2Ydfred22sowNl9R, b7awbjj0YYXhTT9cfZAlagT4rkOR4UTbkJ9XcvpT, wFylCz1pj9BXgQIj0iRfz9hzLaZdnzFFwvDUjuuRJZt0dPDMtEUWaLUWP2S0cIPjJLSEm4JW5esqfCFrhOSnlVK, woGgx9rhmhU3Fv5V7YfItdR6Ya4Nn61TZXuHgxRKhWraD82DjSckWU9eh8uVG, van0P1WdGWs0Y4xmIgEo62SjbzMz3KqKj1gaz1Oz2DuZk4Vh0WfhQxUV8lFTdzweshJusd3Wq0pdzmopk5HZtj, fJYgdSPVe8ZGrsDsj5URkQ4Po, dN6swQflYr2n, q2ca764vfjW3dsAunTwWLjNJMOzvDa15EUsScuh0pgXRFYGB7n5KHqLPRYU6Uv5zW2kM9xyB8Uc7tT7Dz5QlGBGW4wE6UkiSZ6DUFQ0KkXgv76x, bphFSsnrvrUTp20JF0EW16OkghBZ4yipad2qK, cSC2XESOcKEYMXaT6Sz2BvHjMCxzJELA1Q9abTKT4LjQSclaxwgn9ZbdD8i3HYBCkwAmLbIcuzbmYEzJT, fiW9J4QVDbOOCcDiC, cV3KndmxEb2jiUtpTbOCzpd, yCLJWfpVGdOnNkUQOtJNxI) == cy1SKKvhNyXaU0a7ucbPfvQvwiWIfyoRR9dniXhyujpGiHWwnxpzVNviq2UbpGMSS6qtMtcfp2Ydfred22sowNl9R + [] (Zero).tpFXgtDC996txdhqxvc6uTZ7LGguVCIqPWhb4GPq0vrjsU6VJ36ivYQrBcr6eLu6EeizwwVG4duDRq6 -> Cardinality(Zero), <> \in {103, <<{}>>, Tail("ao>Q^45R\*\)&S.P;@h>(g&QFHhB2]CIa,O\)R}&icu\)|> \in [eSmDnVka2T5vfCr2D6NAeJaHIIDOlNw2EtW2rEOQXQPKS5kkyWOloH5TdOSGJ8Bz44giGFHo7gIWf8OEXbvNC4Tf8ygMzR3dqbcqv |-> 69, izEEDYZa31aMoAX0ZZSPtnzZiSJasTS5zXqdJAympTsARWZkLDJD |-> 113, dyEu1EeADkIvzDaPjLTdpJIcifTMU16PgoOR7843Gu7mpKqkARv0JE2u1zPr2eQ4vy0VjJul5uqeh7XlPAPV9enWRCf8t0B0xY0IzPaYhk71Y |-> <<>>, ihxh4hux8hT1KYXTuUzKlwPYkKAA |-> {}, ztbbVgCSX1bb5RMzZV4BCFgYkbdQlRyqG57NRyYuAN37oz96UHjVkC7HEElI4leshq4qEfyyLaNoJgFjFiy1Ucxd5jJpteH1vEaWkHa6yFo0Zzk |-> Zero, zjWP4mQbVQ2lc9Ah2qo2sENITxJ9Fk |-> {}, v4uawbLQboCq5rPaF4O4P9LhHxvqZlwWboXHoHD4oeoKTh3DhpLroR9zLte1WE3VZl5QuYZf71I5yofGfhfrcAeWZq4MopRwyEv |-> <<>>], <> \in LET dMBYoW4IrtFxgIWrYPBUK7U82G2P3eAqe8GTlNeOFFlAJ6oEJT(nxVAq5SHVzmvyyLtL6KTp81XDMb1M5gm1tUZ5X3tO6tVeixPGbirwW0b3WSixN9B00CFRj5, a6O9WgcDePw3so7SKk8CrZcBbOAQw21QJa3wAo83WKEVOM0q1MxaUg1, iYzkTIpshRIClbgtt7PCsvhU1p9zHHuWkDkQVQpZYHwqetUCJHB9hzSspxoSd4tazL2qGLqiGljQPkkk1abCepxIxQJMsHHegjnI3ORMkzNW, eibKgFT2bFMHNqSkBKHeq6rDs6QWjrBuaUppNNFWfxfGm6ybgx1y6SRQgPWrTaWtoh8IWCJ7CpHI3sl, ybPgPsNbI2tuE2K1iA1LrW4eXPRY05LyWpBCpRHC8q8iS62OXS5add7In, uqDvk2oF1CmjHdAze6afrN9c6Y0V9mZmsAdaeSgayd15MXEfOsru6LNlEsfLBwtgaQfH3CL18EoRux3NHDZ, vdIscEuUCezJghNA3FcZvKPOuwXLU77vygCZ0btzt4EZt90EMW9p0Alq3rISBmthV7NJiWDtasETDIaFyY4fTyJcrbJZ4nnLLL6hlo1r546GIlFHKhA4mf, yVo6R1IjAptaDLwUA1gBn7YfjaF7ZaAf96NxQxdB0z, pnoaUybvqpbFApkcV39Z6t35wHInxdO1geVF30nzdltg4tzSpvt8eq4z3MMOfMBaiyhRg5ybcnhTyA9zEopw3yI4Z5EjlABh9vADzC8, eTfg0HxBkXQFsmHMM7tzNzFG, sIwkrxLi5Ntu7Cp9N0qYRzetOgu5Q3WJkgiou6rcWtw1FCa0K204YXW7c2cc5QJ8eQlYmRQEB9ZX0D30PR6hrduOxltushIle85WUU7bhAWVR1, cIAnUzlzJJKbDePXcOGU5EHKL9nSXf1, cOK, sf3IfXkK2Ol7Y64A7mgUGWM8S3ccH2, jJb4v29omLKKv5It5RN2x2IFq8HV6Z9HseNGKEWmGMBIkmnDEwUI7QvAxfRH, rsLln4MGBLeC81BgBMGSXX, rZCJJMsv1jAxmyQjMLhsdmH8WMPJ3uctBaF0WdMTLBDSW3HlmBe1n1q9jZVLtpkSRwAnc42l8lLGMKZLQKRY5QAdfUsrDlVIM4JAPdiPsAHxXggP21tB, nUPa2waBp3rkfbbmB0YennfJw33fwZ6nPJ3cdH26J12SZZcOYyVvYjbZi5XORCxTdbP9yCAqwA07HjhaHboBNu, aOXhTn, iJAYyXf8zHNTmbKp3UW5K4B0ALrIWjnZwPYa5eQUPDWP9X0EN1xRAeEW1QltgZANH9Y8cl93VWXWPx1B1CeGtJ0Zc0ra3XJcB4a5dGaEEHoVCB9Bsbp, vZAUwcaw94oKZdAS6NhOEpQjadeImLnBdLABlHcxct1G36MLDBMPzbh, zDJhnifz1, pTnQLAuZpwUaqY55cJuvHq1t330FccrKxkEcnudLOjKgqVjJXw9oj, hRZGwOfVOqCN3NjIwRUIKyhwawc4xTc9ckcVLWqL, itF2FYh99DkOnXp5ZOxbXJhYWRf6Kt5TcbKiMnt8KtN0xPcFwqVhWorFOK1ZkGuUpVvLDl8CtcCzOCJ2ScITCo8tB13EOI8dzwR, t2u9, dsXbyTPuEzKcBmNO3vUoDy8byFgyYwP6vmR8ScQVJvNNE7etXukR97tdfJm, xIqUs2QwtR7b7gzlFAiA0nPagsRcXRIrzd4XwPuSc4iY4gcFOBkk6HhYPbXpD82i6wZA0qPxSDujwkgD5UgOb79C8n327qYeZB3B, jrQMqgDsjm6qLHAjB5pC7RfvvjGzAKPtxxyypA, sjl7d9GZhoCh5nEdbcXF44yFcu9W2BJsCvdIUruGMwUpUfXl6IhhRcqUlNPlX4ZSMmhnM9puS, iFSImI2CjxTF, kDb0r3tV81qr6H4SmFFabkD8DHWDz912PeZxQ7YRh9FjBCwY6eXETGHk1Flvk8zD5JpOPfpDTIezK8Q7uUrfbbKuW4GDDiAI24DnKiJeX6hYL, dBtIva3EV4kBUnhWYYKtDcY68OOM3, gU6JaM23335s9fdd71Iu23H6letgfaEm7RMjPRIJV0EjNOrROJCV6juQ1ZutwHbIHmuiU9JKTbyNlwGrxSgvwbIcctrzzvyj6MagRIpvB4Ue, pf1ouwjozkq46dVUev9IMmjvOCNeQSlMXvY, lEwUC4BNAyX, mu2pHEkSxMpJG4IFjyzfSg0FLj42MK5bnIGesapT8TI2cKhWicQcedPAjtR, c1, d4J4XlhEfuUcKHbFjd0I2EiqomIciQBQ1oCZtXOsXYMexyBzM, mb6VcvGiNqAddoL1U27vHSbT15kiRVI0Ccg8bjGYk4N, v32tgD43e2RMYs3l17XRA0oqcqjgppgbGCXy6kpz2DX9B4SZJWFDSafw28keLFVVr8gz85aSukay, od8zAG, agI3fF6yeEgwn4mHyIS6BzL8ZmZYxIycJlZbOrdWs0PuDp6EIp3OEJ4AZeMwbAaWG8C478nr96ufy32O5B9ya3RNgsiRol8, u5OX7jli7pUvdFlQ5GIWp8Y2V4w1Qq6JuSZNXFX58tCXaGAXNw5yAnpgjN7YI9OxgsMaqOal0gviOTsLnltWWVtP8, mzoT46CbhESG2XuO97YqjAIOTKzWRFV13URZM9bhApen3u, euHzTurEOVp5ibMG93Z5n5QIz6Vvd3yxatMiXyCUL1TpOljdnVUascnrfOSIM1d1kkwCN7PsN2She47ixp, cy1SKKvhNyXaU0a7ucbPfvQvwiWIfyoRR9dniXhyujpGiHWwnxpzVNviq2UbpGMSS6qtMtcfp2Ydfred22sowNl9R, b7awbjj0YYXhTT9cfZAlagT4rkOR4UTbkJ9XcvpT, wFylCz1pj9BXgQIj0iRfz9hzLaZdnzFFwvDUjuuRJZt0dPDMtEUWaLUWP2S0cIPjJLSEm4JW5esqfCFrhOSnlVK, woGgx9rhmhU3Fv5V7YfItdR6Ya4Nn61TZXuHgxRKhWraD82DjSckWU9eh8uVG, van0P1WdGWs0Y4xmIgEo62SjbzMz3KqKj1gaz1Oz2DuZk4Vh0WfhQxUV8lFTdzweshJusd3Wq0pdzmopk5HZtj, fJYgdSPVe8ZGrsDsj5URkQ4Po, dN6swQflYr2n, q2ca764vfjW3dsAunTwWLjNJMOzvDa15EUsScuh0pgXRFYGB7n5KHqLPRYU6Uv5zW2kM9xyB8Uc7tT7Dz5QlGBGW4wE6UkiSZ6DUFQ0KkXgv76x, bphFSsnrvrUTp20JF0EW16OkghBZ4yipad2qK, cSC2XESOcKEYMXaT6Sz2BvHjMCxzJELA1Q9abTKT4LjQSclaxwgn9ZbdD8i3HYBCkwAmLbIcuzbmYEzJT, fiW9J4QVDbOOCcDiC, cV3KndmxEb2jiUtpTbOCzpd, yCLJWfpVGdOnNkUQOtJNxI) == cy1SKKvhNyXaU0a7ucbPfvQvwiWIfyoRR9dniXhyujpGiHWwnxpzVNviq2UbpGMSS6qtMtcfp2Ydfred22sowNl9R pfutib02oMBk9NA(yqdAEKdWrmQatJbiBbNJGV4dVZvwou9CawoI5, yPLRs5NZFyGM19iZaybEfKGN67EhwEQyCPbjWQZILFN65PjILdMxRcd0OltdhEVSjutjg8uBghJUNRlO0yI1Bb5Z9DPoT1d, npOQdK86ZvrzGID2IYr9pY0illf8rz4MjpchsjYnmGgRoVtWEnCFA0iMo4T3eHtNvMgUd1aAAinQIInp3ZISWlizOHEv, f0TtYSKuVdTGPYsQOEMteXQvyJhifPDPjTBlQj46U5H2jUt9wvVR1dp3aRTPqwG8CA0zLuaDxMtKjiD2dV800Geyu2gVkNBzZrmTgYXHPX1kqM, soLhGyWKqbO7txR4jRH4eAHZyygs9FY2pZ8wGb1MGhe7TrfMxiGbZvexCSQGBkx5HrrpzJYxPfJOnx1qCXj4FP9tYNu, yrgcu41SkT7K, vZ1UpiwtSAw, jQjIvW31GnROQeexcXJQ80yp6ZNlyjfCAXkIVdoUFz5m6hQTJ2YDopUO4ExrulFicvg1qiTTZ09zztaAatIuKEwoZx1Rhl2SAZXgbmbNFDQwc, aTnI591CPvPFMtGM0DSFosqwH19JgWkw6TOAnlLrnzVTvA6GXl6Z7YZslowQ4ggbwiOdmsrbQoA7y26EGj5UThwFCuYClOa1Qk9YBSUgCj, petq1FnADEuTu9jd7L0cRMEQEGA, sCsvwtZfuozhXImI2Qe5nOtioKFhV0toIhWugF1FTkDnOM628v6BcsqgbNgPgwTms, om8AZLqChj5QWTzzuE3Klnu54DYow7CaOgsksEWJbx6rIIn5QIYNfyv0Cg0yqI, sKddX6S4cSfFmEkAfQQ4pnGOsrWyTVp6ohov2ZjNh0m8ddQ3kkuT3V73L9J8pwjLbBaOTclW1sqbCaLOD94UqlQwqfqB1ybAPNidBHJLVtCXV7RtZunR, dTB55b5g2ndHTltMFu8sA6wQO3olGlC763PxW62YsF7SGSfQPrGZtsPsR3d8p9W0rfg0rNre7Vrz, k, pspwuKWUAQfUbXxngJ3Pp7oqrvCJGZdA6ZpbX95Gt4R31sDeMmOmkzXDF5Om6aeyBaIIU8Sd0nAgUQnf3970QQNJcAwx, zROWKKR57TTf4dEuXEAJiX6SQ9ErYYVNfKBpRYozrqAUueR, dlqWvq30vbvbYfBQdWCStgeHLJOk5YktXyAFKEZNlH3zJkk1XXnxG0RgieZPspBK3qDYIkYlGRNetdU, vEUiw8Q3wDBUhfkwu85oGaomRgGEeA8L66dibMQUAP1vLgR, bex3Qs4BmJHBRbUmBOpCNiyEbmD2Odz4XFWO7dHoJpLtrpyX5y06A9aj1if4pGtp3ypR, ov8Dx4HxQI4OGfCgF64Za0TLvm7uUySHtxTY74GOmmpGXQekidK, akX5jEznhGZAVgX6PHCPhJGk2nhgVTgZifC2RIOSbGepu0x0F8ObstfajuRj6wqK67xm67txh1iRpy4GI8pDU5heY7yhBxAofExnVVQjD, wXqzibnzdeZGlKOUZ0nB1vk2EtFdhBkkQmVxIu7m2eCZGV3UVICCsV8lvEDr9APBsdu4mfEw9VDdR) == dTB55b5g2ndHTltMFu8sA6wQO3olGlC763PxW62YsF7SGSfQPrGZtsPsR3d8p9W0rfg0rNre7Vrz neUJpNvUgPe72LyeUCuIqvKpwvWW1RsckR7JbhK36dduupC2UXn9Dp4xa5ss4jbuOM6aN0ioEhvOnCNNczcf2892nd1lXr6zxe3kQaCDGgnLfiCb1A54f(dD5ZfhEn9lMy6hIQ63MgxLX9SLe9RPt, rpJZqPgaJka0TP8CucacnCDjYjWCP0rv2zonLwMNfdKtHZISwCaY1o6x, tV9nuf6o6CC9hCTmATorYSzU1AbJCuMlAfHT1TtwQkoQba, eMUJ35P0rwLqvjo3peYH3jph3OaRaojx4omEFt, p1TaO7BYWoE1lwn, lNU4xQWfgivqKFBroYAcgsUDRhut81WjH4ZXtuvBmD7xEQiX, b9y9qBsXFMo9tcgGgK52Max3oVCkIXf1Wi, xzlnQAIh2CxHeGGccHITKBdh9YGLfskDJYoruY6mniorWiSEdLYGe9kprlD7TvBvTN1wqC0dI1dV4oej07XJwNFUM, zQojcf8mAmjhlsYNQtRSHEQDGBXEJFemNFJi4MqP0vu1ODY5uUx8jNhHcgxSwGxJXELWxcsZ445R8l4U07gHrPYWMwy33rmKfLShWylo3iAqqDIps5y9Og, fulq67nBveb8AL3sI1xlgkvDS6UDy5HV91Y4t0DytPjc3QbppAtizrmflLJk6CN2l144OGC4k9l6A1zbqTVuKSJKYtoyCIFfmw4be6E, cFt8tyq89IFSpGebi2NJEKCmJyLKWNgjsy5rnlASUvkODy9ydSmXjxfXdJdPTJHqii0FccvBuNizbJpW0bdoOKr7QaRCHXxCu2yBsm1EZncCMroRI7d, nk, b, lgE0x0q5EJR5ZrQ, hk4QcmCfEaV7ynEE65eh8PBEFod3VdG3uc5edimMzdMTf1AAVYSv6cCLWTWqEfEzhixBsZTS0xAlcB3OsLEdMnbLDd2bd2agL4zuItrKeGYj, vWQ6gw57aLsFDgPWbcKGHbg83, srpy4ICi5ffG54wava8hMsJmTP3kNX9KFGjYCO1hGWXP2HNRVqmR78ngBhn6i47E4v5Xe7rxhLcgj3S1sMCK7uktoCJNJX, eiaL4Y4ITF6mZcyoGdIJRgv5brQpLVigkwsbF7ZqIcX0xjHGN1B32KyslDg8FF12SNdc6P64W, yAKiq3OZKALyVMM7u8q172vb3R3cpnLSpOkdyyHW2rAQxwT8BQltZSEzjw4CaqNFQYXbgFkJeWyvdMYyHNNEXwH34ARqUD2GWkOzVDfr4eS6vL, g243CGvyoC3q8ne0IiEs8GZ2kTu6qiksuXKAjiP8aDhLWVWXFyJ, uviiueAso6qFDAKcAO8wS685lBm2vlFpKlQ7kWrSBdmjXsFN4UuYNkpHWdGuGyMTOpd8, qAhiscJ9mgAzK44ja, hG5VnplX93p3NIizc4VLAAFMoQOtyDhjrPfYgjJ, gBMWmxaRYzda9R3DadTlBxtDqtc2oly8G8tmXDQ8feYccWakExMKXFx22vnSDX5zxIsNmIX1OzK1sR1kjiVRDA7zycVR9l3p4, ldiKoihUaHjqHQEKVnAnq5q2C0Rd4U2sABLtL48KvTGG6NOISIfbxVputvRiRkHLnaNQHnH5pBiQ2Mr, vmc7p9sqDSLNNroyrQlIP, diFkx6gTeKJkXFhVWtZ0zWYA6CTm0iXSsoaOcOcg8UjK0Hw0RbkwufGYq9EhYig4iAvHQtRqRiCo7IgPFVOoFlxuHydgkAV, xsrJ0hs1Ke, aP9UfZ2zZEj9UUSK4oxi1LmbJ6PXE8gvU6q3GS04q5VelSnO4TAVpH3Dka8Vj9224XWyXX9dhJyJKVcAQF1, mRAkfC3RBXzPnSa8ZujLPQPTW37kfUKnemy7IZuYpAKByr0gKio9SM8CNRaIvZOJ63ohlyBO6Dj3whzWEDV1DNoHksJwK4lUq1PwWPQEkSkH, v29hQOP4auFwWKQtcJmnxZRzGJwyhHnUS0a4vZ30gR1lPUeG0ZH1t0wfNAYNVN41y2qV5aSCQvY8vFi7S3TEsTCklGLhTGWNqHt0O4cYQYOX, p83nDSVkXu1cQDig5M5QVP4unsNheBIMSGNu, sAeZUPte26396OpJlBpmI0LQE21lOtx5s3t8nCC0YvHHB0CNqCxi0lJiwoEVaN, g4aq2R, ns25X4CXQFuglOEPP, zO6zdF15imNgx8fxuwZNG3p22LNMQWWjBfGMcDPKLQb9tCCs1DKDDbNjqAgipqmZJwqPve0NlsmvCQepmhtZroKqO, ccrlQKb9dTYwhvJmvl4uWJH2I70XwyocP1l3tkGTHX0Y28gm4UZgj7xJGFYs3XMD9AxWEUV66SVsHK, yrortUPsQPz3, vrgY2fCsfzc0y, atADMjtPdHVP, opNmvwtrSNJ4RuT6uRHRSinguWgbzqkMsqQ5PW4k61HUy8toxpm3yo7OmM6FD5gRVIEUwGvz9wgCqgLy6ZPMmVyRP7XRUNP4D9CIFRtHe, gRV96fKPGEWe6yKFHxpuaPq, xDJiZCAbwMbVfbl7WcbMeruamFMGo6B2HMhB8N3KRrvic7qc49iGJb0bt5jCL062D1DLivTmY5TbCyP9Wb29pn7VOb8xdbKjXTY, dXXEkdWvl2, gNOgqr8aJX4zP9l0UaPS6VagarrGqLU6i4JYxxjrzHs7mYmgJF2UuNcsLXJywdPURIQ2xCQnH9wy6Y9VSq1gC0J50pAn04v, pchYX3ZcpKwp, gHzB, wOFfsItrf6nLp7zy7bU7ADoa02aW3yFektlj8rpn8a4CRo9BFMXI5nnjixsR2S1, qmpBaDd0wwAwM26ojdOhI7b2Ue5SUX7IuWhpDaEyxk4vAZTjdUv7jAipAEZd41SjSjvlL5TUt9DlST6ASlDN3ObplY2rp0F3, vPA9, dXNBv1xjF8ZdpX9C5ZY59h, hXQEKzRGitGm2rkfhPfIdX7NNi8fC9eUKHbhKQc0bCYivC0xaHYo4yW9Z2yoPdwib39HnBYNhBDRJTDRTaCCmHUEDffrdt0hDlxNOVQ, m0XmdKuUpvl1bxpzt3eNaLIlYDGcVkOcEU, zgiCcx0Ii2UjTDawJHXK8ztW9TxnEs4BqGMIL0KGRQaZG25eHlZnVVD, oGOiwYg4Ni0FnbwxphNIY, cwECL7xY8iScG2ySRm0ti8l2SM98hhZH6aJ3n0PQlTb6CrOU12M, lx8mkvXnvNTddobS7yISY81hUkWXF2snOu4LxOpUVQdxNdAZWzaTZidvQ4UBQRrrRjcg2, ptUB2ALkx6BCK, cUmKmyddS6PXGo2GUNkzZTN7T8aUYA0TyjV6gg8oQ8km8N, rvcG9Wifo9QGqWkQA5WvYZTzYufmDdQBlhPBoANWGrgHdzdN2lO0phAeCeu8SZdsOzaR968R37lkJpZsbmUgtb4i7FPQtIFgLwfKlSeWx358mVm, rwovOOJgVwMF19p, a7S0yryJFshXqvdklI0kKojQNDdCjzZ8njL6OTEEJoDUELF3hXybX2H2j34fqApjlTLas7RndLmWeG6qHlGhOyzCgtsiZ0Ac47CQHla, zMYCpG8uLegaVSIotRhQZx9PUKAk9VScJbUaj3SIoQmgSdtj9V2ZCbZwo1VcBwjscjYOE, cTVZ9beGFz5WuA0xss0ZcVMok7s3r15KQjkTmwkdfiHoYBzsQm, vKR, hvGdY7ny33CZqb970HPMtRgqxyb38sWpNP3mqaFM3CQIF0MzGSbmSEHFblwNDXjlMjbmd6oojyTEkWwbG8ev426SvUvPZ9A, m3pIRkjqdB9DhTQmsqsPA9jjo9dtLe5mvTUlTIQQYTPzRraJUf3LhrMwlEr4tDz2kKvxYyzWUPJ8EjiiHKNKCXEwEZoxVeJf772cnNx3WWuCx, r51OBn836H4CGwaJbpKGSPoz2Po91zoZIvhLGK3o9k9cC7nDxL65U0g1z1ZH6SRsJ, sidyALRX9OvYQ64hbL3cEsPe0uJU54P, ga, pb7Hf9j3EU0fbPaQCJQBMELlAYwXQxoYkOWXxaA9r4NGEO6SWvJyMkzPaibJ7IdF2SoiamwTX23EVkG7LbBVAM4VhhrTULwtCWWSSLFVgKl, rdW5Fk2Xx9e69ZaE5r2a5LVVkO28ktahTi37iiNWVfM7OmTwDZXnoapZ2zZ23rbUFfBgi5Ci858X10XQUAsdKLQS9Rhb0D46jH, u0umaKghoGC1G6mnpX9aEDFLa9OyEPh1KfTJ2XtKcmX2gKfcN1yMKgAiPgrX5Y97NLxnkI50K7fh4yh, tTmkofWz52M2axQpt6G4OMLgBcYOQdI3KBdWdFrGq4Yda58ua, uphJqGX9ZtsAfGdpAd4mdG0SrI6BNfG39y4KCNb1pJugfMZaOEzfodJY, alki5J0u0ZkgrMwbrPRnhcNyFwEkMNzj1pZdybyIUA9DwZtyEtDMem5uM7NxfYZroUPGAxgjDAditFdK8Kcw6TBPwZ3dQQmsU, naXIPTVHPd9, uyqvkdRlrbdXkbb1ABUeKJrZpArqCmDs3O3oPlX, jj8GIOzvZwvVFjltDA5TlBEtc0thYFrEsT6AYhuTR1DCfRjSYsVExVFXH3kludlk, ieZaTIVxTgxp4XntAsQOYQiSvSiSzvhtep7YT7aG3eKqH3MfzAo4WcjBx65PerpVd, whwF81Q8dhsvJdCQotqTLGbBiGuprfUBKRivefPWwIc1Xv8qA8HKIjqNcwarJ2ywKAXiPeFuF1fGcby1Ur, k, moKtttvRNzgiambEv0ElsCn6SOnGFRtwdcwAG29VbIQADaZAhM037grEV80IiS9NXggAW1g6VMQ0omx9XrAvJ7PcqBFkKi188lEes6kJq3cx1rdArLgM, jM0j1vnW9Ph4mrAgkNml08uYIFLEOMyaTss5EIhHKPvtaTTtrkI, gSSsoo0WfLIj4c4pSfB7SH7FnRPf5BbXG3Mc6P6keRNHhbSQgnV9k7fqiumr11djFHVEAudmOEZ2l8D8hwZVsgHpXKH8CmUp09rXlTnZegeJ2yJiGg, cEgq0WGJ4n9DXPcG1DQITQYPNFnmefNHJ0gdAnOehKZ2p6GyG6dQg, xGBke, fFZ3jGvpoJ6qs0TpDOjWxZ6mt4OEwL85kU5gEJqg5PFLEcgUZ, bwhE3, vNawQMPnoqjbFKmoVzXFFj4MwASHGDlEsKnciZSThPfc6iBHAuT6Q2YrKatxfj, lJ3A33n8Mq8N1x8r2aN10aY5KsOvYQ3zHasBY7b8E7MeEBZdKNOrAKHFoEXfv8VsRcmUOjUq, g33CYBTGPqF92hNZUIGRp6UD5aECTMSEJd6FpHJQxOY7CtKloNalX6iyEznlLIfKye109jwqbAtkEYzgh4ocEtcY6NhlUUgdK7sVR8ywttsjkKYWnxXId, xgfnyJIytCnNTK, ocEx4eG5KiMIDuAKa3dejESCdVvgKPoXAmkyA5hbCRXMuX7rENyPIo, q6MTUPxEAeyXKMifVbWAq5yiwxg0WcPqJPO92LkmCdDHggelkCkd9dNLT9aFBaZ3YONXBk9EWDNlzIlMGTojmRcGiV6RYIwJ6NAGeVNFTgs4WBf3Wl, eYaJ0EQqIPYRLHBvqxhVnw5MCrO2yFLWx51zWw5Of9y, qC0lAOIYQE3zbfIiluDtQbX9kAzSxirqj9YNSH8C1JHkAErAIy1H4XSevvZAiDD8PELJG7VHi, eP5qEMgP2Xnk30GtLMzD5LEEp8xhqXaLKSqNIhCtj8mQINTnYfrdZIBiIiu, q2lslxSqzKtgsPRsGzKgsKKJtrcbcVRgCCy, pPVCCskU8t4Fbz6INc3sZRwlTvGTC6zWoY5tU2DcNbdF2Ici93tTq3JATIBcPCuHtvaBsdXUaJz, yUzmfhluvJPwrDp1VLRCY5ie1uvw9DGG7E0fYsp3r3cQOGc03HgWouEucwYBQ08HaXYsn, fqEDJDLNtlexAS4PhM6sKqSqS1YZOMhojD9DFqH8Us6zkaEBVKv3ohCj5AHpC54qu5Yzi0604JQRIY8, iDA6ycv5MPxc3hgQ16SRcpMd8GrKYzB6WxeGF9k, y4DZIxYVUiiATh6NltzAHxY0VsH6M3MCkL3n3eon1lxXVFUqYDky0qGGaL1ksz5XBUXbD6d79dcxf2aVIOiZuQiC6Aru3KsXRLwaBH, qAPu, u, bOIsQ8d8GVM) == aP9UfZ2zZEj9UUSK4oxi1LmbJ6PXE8gvU6q3GS04q5VelSnO4TAVpH3Dka8Vj9224XWyXX9dhJyJKVcAQF1 ukBmRCtcxU4Z3Yksh0YjLv37MqG99dzPRYxTVv8OCeIwGKh9SwfPSVAXDxWm4T(nyb2Il2gW8dHLUWW4p0IPl7lRCwDCI, q71PuuOLcWFWM12bsnpvqgv4m7uQpM5SbNYxFzyUcheNfOrOdgOv7ZC8TSURQVM4CxsuHzya3uFEVJ65Rne6lO, jGueCxB, jDsrI935UaJyVhce, m8pHde1ec1gY, iotRSKGrRcs4opYC21UM9ERt4bwPjxjwD18a9TYB4EJsQtpFPuybb8xGLgWJDg5Z0eNeGMNC, rsBUK9zYElS2cQsqX2vNWgNm1qAloPP4RPtciMXDX45EhzTPMNp6RZhLlzFovaVdHdO0EViwTttInwqNRjPa1Q3CyeY0ZD5GVAGgHorv7n6AT6, aCbVK4bc44RJSB12Mbba4KhlNUd2AoJSGb2vUKIp1S29aIRGhxh02jYga, dR0tnBY9KUovDwO19VKuTnmSIBpDGgC7u721Hv, x1lnZT49wU1tTxyMcVQYceJ5gmsIwMromJTw8YiWNjDZn1is8psWwz7nvSZrFz50dHVgwJXdAemzpgMZzAsmt, ehKs6sNuZhfo60rG2sg3R1QE5CVTcWG2N7K5WtJBizlRZLVtd, sR7JVAjAVdvlxD456IJ3NvuT0CmjliP, kdUl2CTj, y7TkhjqDzL6ubH, o6thVMlWBmtwYbrcrEiBB8WQfeKvMhyAeCv1P87Aya, u5J9mWoWXYLh5wmdR6YjKcUJtt9qCeQZDAl, jDJPvWrhjydEEYKuKlywSj3ULE10h2dDfhGpjTlGPj7ImhAEMVwXqE24JKmYSzZ7Mp2ftKU5KWoVhxRRGFDKETVR9k0Eavmp, natnlvtTyMOYXqw5u7fHGg0iELBvSL70dxn6PDm8j3SbDjWSkggBG4DFQvO0yCEXBBfAe3bzn0PIem1NIWvi1, lRXB1iqx08OAZGcFwFyuApGbCzQM8qvAq4SC7nOST4awVvYYChJKet, zlm90l5Tu12iJlCg5vGwjGfieiFxrqp27XXNJsCaWlwnrl4wMWIrzdD4u8oJ6i5lXO9e) == lRXB1iqx08OAZGcFwFyuApGbCzQM8qvAq4SC7nOST4awVvYYChJKet bxqRuwNj67l1Tw0tG4FnJoCpbcwAITjSRFP1I7Gz9BYYEOtYCbQNVLKoEIx0CSFwIyMkChMguq0JB4zT4HXTZdyPn0hn6D4EmtYKzcNEuKBXWJ(uQKOCatlf16egTz9aQedQmOycWBubYLr0FK6oPRqXKV3dbBmO08OiqIS6fYMbg3da7N42C7TZsObO5CaU1CA9051loKrLv4lqizxYz7XN8s8, aSBKtbpBn3rK2oORAyA6MoTROaa77w7IwzLtDcsgLax5OF1Og6b17CUWWGPW8Rg2wBSQDrrkqQqZbqgQbmnNB3icV1KjqtR6XXRZDe, cvWtM6M0aZ9GrzoKN4gllrlyIjtOUWUKBQiGXYT7DFyFzcRB0, lHiIHLn7Dmi2N0yX06JfZlhPboAMDmDkX6nKXZSHwvuzdAwMzrRjjaaIGcNZoDr, q3GxRQPGNOiCkdTjH3XOLCIEHSCR4qK593q75ytYrCnibjD, aC6bZpF0eo7Nc40PnIq9BnapFYjDthyAe7T8V9XI7ePR3VIuihpwqEJuWO7Sga1Ar2EtAYmgzOekIDFnWGhAIDMCh66OYflzfGtwLkUFuvw, aIThXsUSsufSEXBuWRynAC1amycmWnjFNzk2YZoQdw, azy3TQcyTDxmalOQ8hQ1R, x2vzC1BV0ccqEb0JQH4JNj1lxdAJqAS5JqYM3n6MfsAgoxBuMeWfVivojVbSebpV2Isyle3x7bQSiIBLdehUUpT7WcRtrxwTbeBM, dycm4g, e6fp7MZDbcL40Dzxi19tsqc0NOFOMptZXKok3cNaw39jz1Y5olxY, fvpGUtlF4jbJlaEYIEf0KKErG9yMSULSamF3p6uX0ekan7FkYJ1GfGY38FnvaI1xCmJ8, tJZWvhtv5t3w4YOudUqIqxcButdvxdk7QrSkfXrRqxVm0PDDbkDGjxXusW1zEUOz8vtC33GLKmLiaHqvodkyGwzNQqMDN9G7YlWvHFkqz, d9CiJ67ihdcsq1zGpto, l, kfrmqCShcCimYColT2QdFsygTpY1UvNUpV1F0OowzVmgYWEGVThFFpDzf2kmV2bkY7iGzh3wjpLozJIKcFM8I7jjzR6xT65S2N8DLzSvyNlfmE3fgRF04, kiEBQpQU1jo6xyK8efcGcW0jAoRCr5r4wnEavbUsAdlxFvgolAab8QdiIp1Gn992bqEFPvfvm34BvkOQO6, iKFAEtFY7hy4ljNTleW62hcjlpteNLqZpH5UB3uQ5AYqimTymiXDGyjxbjepAcESn8IHZ6bUyxrMKTlGHw8vtAMSzjCVEk7, xgAmcY408twaQxSDXaB8ExSZhkDoIOUqrEDbuUPW6KriB9WX4oItCZGLuCw7zRBWKv6auaHR, hk4VkY4ZiUu63GVigOsSjHmYOyH7djLQNJH, o5IzQoYsUrfVa4i30vvpTktVYGMTG03IMKqD2O8tzsSPuBM3f, q08mHqx7dfTfgggiLK2aNOcXIE2Qu1aXdk0xNvjGzhAfytfEqhn7PI8dZbzgmKhCTuLHcZsTNglm1ZRGzkYO, aJ6DcsWlrdtzTbSTp2pOl1Hbhlato7S9I4f6veppCSYWAiGQuamaV2aG5nVfKUHl3wyOpJZqGTgP7wJJVtvg1a3N, qGugRgMtXAsyiug2, jfMuGqGfx3uqKFk5SD2sEJ275K88pOCqxvsQhMMO891qzSPrX, jtY6HpnYNk6doqATtd, iN7xhv1MzuzYOiCT4Sh7VEShwfS6sa2FuSTedejWWSnBGSArKrArNYfPvncTWyAvaLlVSyF1QuOnxdjlfimPKqXVCidOfv, fsovO0g0buqgPfCT0iUyGA9qkdqp0xiHMAIG49G55vlE09nKWbLyZtvKsrDMVdanfzutwMxLqAmTYzcrqnEllcQqBl4BvccoSuTAO8, yNtOMcEdkEmNHxHRNr4rjaNgiwfw1GDkwQD6XPeqiRyGlBjcQL7YYe4S5Zio834Tr5wv3WEroBdFzeiBT3q5qvcwkjZS80CYMh0GYdA1, eUKe2HagRA189MJo06zexEUWOxxG42bmGx6udVAj5e9DmDbWOWIR99Gy9cksjYRqdTDipT87p7Xg1O0422N2qKqmcIGLqn, b8ddK4eqk8erPJfE3PuBCt6R1nR8z7NaX3af8RpBE8BmAREE4Dm5TkAjRAok0lqrmVEt31Z2eIU, jlw8fsBEtqRnuqaouK2iwD, u0HfGRjE5jId7Jhdx9DjpuZyYrWocemqVPN2AduRPIFnNOINUlVrveUoHJYa2BwoL9qWNMkvPO00sIMUJNP, zZrD2GEI3btaWmmFMhTWt6njd56i9O2AhKTWC8sBzgZYFJjbN8JG8qvCWGfOx8sHyBtJVWKg11uGBZxp, rJANcC7QzWMHjQUaXUF2mXXhnc16yDhM1fHMS9ySiXRK3R0AnaDWDuff, a4kMZiT0UviUzwO7ZTaBAipAVX3NmEFSECOZuvdMwni2OUgKP0tjPxcLFcMVpe3GxGsUwIRp04H9GPhywpx, d1ZxaiQ7KROXHTKbugNHaWJwzfqFqpnZvqF0uVRvL6qe4NDOlicOjmSIRG3aCAQNDVjqA8T7hcKt6L748YJjXpsT, dkh9dftAKQCsEu, uBHkN6sQPuvNQ2R4SxtqVtCWabcO6Cw9u9, tSr2ZDgbgVIWcGa, sfH8ZI89OKbTq2, r, dW1tf5x24MAFXIZwyZL14oxKVN28EhJkpIYSmr64ETHGdMn0GSx7udq2c, t1Vj1Y9RtOoB93Ckt6kan7wmWcLVaxgOOyiX5N6USZkFreiIb9ZabpDGYMtLJwTStnXx24GHIU15QqTnsAOaqSeOoV7Trv6sk2L, n2LQazbNy71xCM5yt9hndpmiEGboqRJ15GZ29b2B, ynKpefQii8aRVNTmUfBP9dP9B2QRq1pU5SyFa7Ypq7CfIV7ZrouSG2JWHiA0c7BAy, ocsxTpiMPrCwBoKLmnJnVTDAIygjTtQq3HK4ZLnetcZVv6Ego8thDXL6MGaWRUdlSzqMeTjId4DsWdnomE26RGdNObdgArTJTMu64ewiS, xHPS0KAxYP4ARqQi6DAEH58yXjI5cyycLKcsZyxy4Kj2IWjcTDW0cA, wxIfXMQKmfhuwZ1AkGH2joSj8Js4E, mXLeZojiw7j0DmWYcbEzGgKD3XxcD3bElIEzpvo2zc124j7eNKJm35WBANvQfL, aw4BXjBAl0R2ui, ou9g1IqqeQfEnYj, k4WP6HSX60Pe7oJUbyiD, hXBgjNmFO64gshs3, dBesg6m9CJunJHw5V9DVeTONVdkh6zQ4qDLYyMIV94vYM85zh4ykeswLKbyj0YSa, raR1ezEVYkGNdZ8dfrwfWa9s6WF, erPhH0uA9ar74awWPit8BRDHHVvWm9PAN5YQ2r, zXgx1ZIcnmfAt8eeR6AoYrUZxMN3PDKsBFjHRPMCUM4kSQHAPzNFMwHA7kulY5mmd1IqmmZrbtgqJ1go9, wX4DbY5Cjz74DH2EBMTqEEmAgPmORwLzyzvrgzK61cM1FkFWNOuXRRjxGvySbh47uekGKC51CZH0K6PnSYnf, pHQbaz8L2o4vtwfkHITGp3hLmBsEzUfnnREIVVb7w0QPiLtnO5wQOvOCUsnefuaS92hqEfEovByLvfZSALyW53iZ0B, vN0oAukCuH1tidxYDNv3tpho9bGH3dSN73iLyPT4LBhKLcweYencnOhr0IVE2WqOLpNqmSXM9e9EmuyntNAvXX1zAXw8, zwwrnscjMRSo4ybtRdBfaCWo5p, u9NLz8UiJfrpRokx6Klej3lJwzxIXELFLovaChsZCbaF7sRLeAjVOdqXk6wPOqM0b2hsfLzYigVIw2IeHxumWrhdxz30Db7itIInwdLJENUAR4, onQcOt48AFx2g3vcKr7JeP16DTWGKYuPbOPe0fPztj1pyHS5P4VKSrUkX9DuGqNISiGnqoDfMWtPqJ695WBCVZuqsy87ZWLKreaaiJJlL2mQEvTKGcq, nzSv46djtF8jRAb0x1tkPL0pJAgZeGMg8mjp0HfO79wuKKHL17c4Qouz528vcFr7U7U7qSK2EHn41dubI, haqvardC6HFV9aBiVpOkhAZOCsnl0AdN7O5jSmdwo4FOHk8GRwsYhBL8Vojo2YZubGmtsEVBuL8OgqDX7go36puITdRih4, tdDITA9zAIMITHRr8Tu7k1MKQvapl1SjqGBfkNpAq7C4WPXgALuD22gJlCQEkDwFLZDM3B, gtcDnKpcoxXxmgSEaDbvuU0S3JFm) == xgAmcY408twaQxSDXaB8ExSZhkDoIOUqrEDbuUPW6KriB9WX4oItCZGLuCw7zRBWKv6auaHR oGNcam7no50VFS9bNVSLFrVV9tFOTIhTwd9VlrW1xT(am8bWyy6KnGD7pbjuRLHR01nW, i0s8KBm44MBD7jP973D5Eu4zNKCiXaPohAQsXTb4CMmE4z7uccxlcgtrtLf6tVytqIhsXxkf, kwC5NvLfjhrgra7nBauJjJdcPCGZMVFBHk9of51zPNdpV0LNTaraqDEhs9qKYY8Gngi5uy9gknn, ehW25vry3ut0fMujKtUZrmrmPZ7SGzViNd7FExfqWnXySATsZ0eFyWdwwbSx5a8XFouh1UrVdF3otRcwQsbBWkjICbhdFUD0zy6VKEfDFJ4qJ8rlBpk, vcYhmXYbqt6NOh, fjjQWlZST5w8UQJSGYmMExwrE4KiHMs2vva86I7hMGFIXjZMt6Pr6inLcbQaI2fDvv3wzAj, iGP7JEUvz0e5rYJkVm4vSagOFQ98H9ywKRqYsAca8p4yX5XVkKKphJUGP4n, cStGYyv8V, l1CWGSnDAFA9JP69nGrlo2f5ohVH7g6O4yTqWxznzWqFPNBGhTDvk1nDQDU398teHkao4sK2n38qz7zl, aiV1iGsofLK7qe1lQxjSZe55J51Q0s4z, mb2f4sCh9wj7JdY2V3cEmrIv99amnXuMutObxCvZ5aqlj72, p05MeTxF9stYUJ2JXqTIioRDLc4, cZHjp2fGGJxnXXb2t9XjqSQprA5WQtkCwSETFbkGseDOjuuZRbJo6VRiLEn, zyaZUPLlnqpNKeTj3tokZX4dDrnkdjnPvHdgCamm8YLu0WH8IWxsYZnE7tsnbXfHudC7VRYjNvOinB9oyHyaIRlCVKAF2M7dkDCbYxQKSKTU1q9SGZ, uJh6jOSh5uGYgEEzpgdPGVh4TXRlrRvsDzgqdchE5JJdHJTfqOLbxIlSoJf, vXSvT2saRKtTIpFQ9Lb15wveUQM82wTqNV7k2ilR3nd0leLNv8KIm3nmq51aDmkfPmTHRBaNAbZLxFouVAd4ywUHeHEA3tA8mYYCCDpcJNhzIsPo, koSPqSVrdMCYlCkJixR4xlBZmf47UdD0qwxD36fauTxnkYeonmYd3VgUmL695pjXrOsE5puEJtJn, toHkXVSgsIWfecbbl4rfUKKsNhId3D, vLzSLfHX7fGw3l) == l1CWGSnDAFA9JP69nGrlo2f5ohVH7g6O4yTqWxznzWqFPNBGhTDvk1nDQDU398teHkao4sK2n38qz7zl - IN <<>>, gSapU9sycL2vu74K0nFmmgiTgxxxtWq92c0ho \in [bV2U08WxrbJW4YyisaWLdDTlnnQZN48YPIYI1 \in Seq({}), <> \in ";nT!E/a\"~A'^[uvN51;+TePI5&t$^^Daj.]7eDe:_41h;{8(jzvkM`TLwt8" |-> Head({})], <> \in {qxbM0ySqkdzWhn6gaROcgBgxFwsaY7adHaF3zhWU3qvyZMiXDYvhlbWBjZSc6nCHr8DLrsWqkB1ZScZHg8LjT4uJqajwOdLZpq4pEzU6a6Gc : <> \in "Or4uYZ'{+a\*`I/tHTU'@Fw=}G/B/d%h\):%R.FE[0}o-\\ -8'jRgIskN&SKdu\\,\"\)9%r;op>bex\)&O5eqhS/xtaJG,nV#QWjd-c_f:\)d", oyarDkIO1XeNWlRTWPoDsk1rDzx2KhOGK4xnI3CjESXu \in Nat, lAPrrMqrU4ntxPtOdkQigX04o9A1UhGZEbuFmCpVZXsEtPOamE6NNhWjuNSx4u9QGUQi1eGldztPwD9aM6xX3 \in 55, <> \in ">&cXJ\)Blo@-}ot<1`,WaQ4UI%BWVB\)psW,;X", <> \in <<>>, <> \in 68}, nrk37ZYFObeGv0nT \in {"w5:3;Z'1> \in f8FerpPpvVx9MMkWzCPTDTuHTYdIgpO2mcb8SJJFRoo6DrVmr9MPdwFWO4DUFYF6L2lp7vY3RgJuBCEHbcRwltB2NSEmn0RsHtvn4Dchoua9Zh, <> \in uTBOegzf41xwPV9PP4Jyej8A4q8GFeUm044NwlkPT5BL3eI1AIfiH8e |-> kKa0FOAnjnOrXmqpw5mzjiGjspYPvCI3puDlt1jTnz0hhp6eg73Xe9igS9tmIDWBiLcPUA9cZz9cSSqKDCG5DRShCWvfozxKiwTRbTHl93hm] + IN <<>>, gSapU9sycL2vu74K0nFmmgiTgxxxtWq92c0ho \in [bV2U08WxrbJW4YyisaWLdDTlnnQZN48YPIYI1 \in Seq({}), <> \in ";nT!E/a\"~A'^[uvN51;+TePI5&t$^^Daj.]7eDe:_41h;{8(jzvkM`TLwt8" |-> Head({})], <> \in {qxbM0ySqkdzWhn6gaROcgBgxFwsaY7adHaF3zhWU3qvyZMiXDYvhlbWBjZSc6nCHr8DLrsWqkB1ZScZHg8LjT4uJqajwOdLZpq4pEzU6a6Gc : <> \in "Or4uYZ'{+a\*`I/tHTU'@Fw=}G/B/d%h\):%R.FE[0}o-\\ -8'jRgIskN&SKdu\\,\"\)9%r;op>bex\)&O5eqhS/xtaJG,nV#QWjd-c_f:\)d", oyarDkIO1XeNWlRTWPoDsk1rDzx2KhOGK4xnI3CjESXu \in Zero, lAPrrMqrU4ntxPtOdkQigX04o9A1UhGZEbuFmCpVZXsEtPOamE6NNhWjuNSx4u9QGUQi1eGldztPwD9aM6xX3 \in 55, <> \in ">&cXJ\)Blo@-}ot<1`,WaQ4UI%BWVB\)psW,;X", <> \in <<>>, <> \in 68}, nrk37ZYFObeGv0nT \in {"w5:3;Z'1> \in f8FerpPpvVx9MMkWzCPTDTuHTYdIgpO2mcb8SJJFRoo6DrVmr9MPdwFWO4DUFYF6L2lp7vY3RgJuBCEHbcRwltB2NSEmn0RsHtvn4Dchoua9Zh, <> \in uTBOegzf41xwPV9PP4Jyej8A4q8GFeUm044NwlkPT5BL3eI1AIfiH8e |-> kKa0FOAnjnOrXmqpw5mzjiGjspYPvCI3puDlt1jTnz0hhp6eg73Xe9igS9tmIDWBiLcPUA9cZz9cSSqKDCG5DRShCWvfozxKiwTRbTHl93hm] \* this being empty is also a test; can PGo compile 0 archetypes? (* --mpcal ExprTests { diff --git a/test/files/general/ExprTests.tla.gotests/ExprTests.go b/test/files/general/ExprTests.tla.gotests/ExprTests.go index 6da2bd270..2e0cf8b8f 100644 --- a/test/files/general/ExprTests.tla.gotests/ExprTests.go +++ b/test/files/general/ExprTests.tla.gotests/ExprTests.go @@ -25,14 +25,14 @@ func Test1(constants Constants) distsys.TLAValue { func Test2(constants Constants) distsys.TLAValue { return distsys.TLAQuantifiedUniversal([]distsys.TLAValue{distsys.NewTLAString("W\"!YVw#\\#]8?t=]ndqUQnWNDhr([Q2Zd6;")}, {distsys.NewTLAString("fHeAZdw1vCnj3xfH9h22hrUcMclAc21eFx"), distsys.NewTLATuple()}, - {distsys.NewTLAString("kPKP6DMtdXB26DOcOq"), distsys.TLA_Int}, - {distsys.NewTLAString("kOufhkQQBNihpnqM5EG2ave4gvDLXzM4eM3AF0s1vozipbR3jl8f25jIZF2l1DrHNVNGzYyh"), distsys.TLA_Nat}, + {distsys.NewTLAString("kPKP6DMtdXB26DOcOq"), distsys.TLA_Zero}, + {distsys.NewTLAString("kOufhkQQBNihpnqM5EG2ave4gvDLXzM4eM3AF0s1vozipbR3jl8f25jIZF2l1DrHNVNGzYyh"), distsys.TLA_Zero}, {distsys.NewTLAString("pes31jiQYk7kh9MbAqDybYqzToYtXL24"), distsys.NewTLANumber(105)}, - }), distsys.TLASetComprehension([]distsys.TLAValue{distsys.NewTLANumber(66), distsys.NewTLANumber(99), distsys.TLA_Nat, distsys.TLA_Int, distsys.TLA_Nat, distsys.TLA_Nat}, func(args3 []distsys.TLAValue) distsys.TLAValue { + }), distsys.TLASetComprehension([]distsys.TLAValue{distsys.NewTLANumber(66), distsys.NewTLANumber(99), distsys.TLA_Zero, distsys.TLA_Zero, distsys.TLA_Zero, distsys.TLA_Zero}, func(args3 []distsys.TLAValue) distsys.TLAValue { var nocBmpMYH5HkfAmS1Hxov1sNAmNpre32Go2PPwiq2V distsys.TLAValue = args3[0] _ = nocBmpMYH5HkfAmS1Hxov1sNAmNpre32Go2PPwiq2V var j8KL43er distsys.TLAValue = args3[1] @@ -164,7 +164,7 @@ func Test2(constants Constants) distsys.TLAValue { var yXTIbTDjWUn6gCVk2lQGSZr3TCdqbtiHw4edqxs6DLzkJMdFyeYs1jl7Ls6yXVKXlKM7bbGw1v7022fiJIzpF6Rf distsys.TLAValue = args3[5].ApplyFunction(distsys.NewTLANumber(59)) _ = yXTIbTDjWUn6gCVk2lQGSZr3TCdqbtiHw4edqxs6DLzkJMdFyeYs1jl7Ls6yXVKXlKM7bbGw1v7022fiJIzpF6Rf return dVpTt5jrKlWu0I6Hq6H80zTmUxwUAJYO4dKwf6DQfbTQWe9fGr8TtnynL58wFnRcfuVdaQJ6yRM - }), distsys.TLASetComprehension([]distsys.TLAValue{distsys.NewTLANumber(68), distsys.TLA_Len(distsys.TLA_Nat), distsys.TLA_Tail(distsys.NewTLATuple())}, func(args4 []distsys.TLAValue) distsys.TLAValue { + }), distsys.TLASetComprehension([]distsys.TLAValue{distsys.NewTLANumber(68), distsys.TLA_Len(distsys.TLA_Zero), distsys.TLA_Tail(distsys.NewTLATuple())}, func(args4 []distsys.TLAValue) distsys.TLAValue { var nMDLcmFYG6N5X5qUG4Q4ELPxCZRP1ByOFD8cIbWHPjvMaPtf5Q7BBDw71oHBnalYi6KgmUCNtO0j7r3nAkq7Wn3ClMSz44nnJXpgNIZZydK distsys.TLAValue = args4[0] _ = nMDLcmFYG6N5X5qUG4Q4ELPxCZRP1ByOFD8cIbWHPjvMaPtf5Q7BBDw71oHBnalYi6KgmUCNtO0j7r3nAkq7Wn3ClMSz44nnJXpgNIZZydK var vvmBdcUQcmzi3aF14n2S3Oie2iBRkC6Pq5dh91BNivvWOU8pQ8lX0buK5SxjDEHFi distsys.TLAValue = args4[1] @@ -250,7 +250,7 @@ func Test2(constants Constants) distsys.TLAValue { var kKrE0nlxzpu1lHtP7uXyLbghdH3rmMWbOEAY7Cqkn4xchUmVC distsys.TLAValue = args4[2].ApplyFunction(distsys.NewTLANumber(39)) _ = kKrE0nlxzpu1lHtP7uXyLbghdH3rmMWbOEAY7Cqkn4xchUmVC return distsys.NewTLASet(zWSbRBDcKvPAzjLcOPdpDMdxHB07sO7kEq9Sk9MydQzf7b5IguRfwHTQeQwDS8uwsPPE77kph4VdYlWi6GlfISwJgzUF5mDwt) - }), distsys.TLA_Nat, distsys.TLA_Len(distsys.TLA_Nat).ApplyFunction(distsys.NewTLATuple(distsys.TLA_Int, distsys.TLA_Head(distsys.TLA_Nat), distsys.TLA_Cardinality(distsys.NewTLATuple()))), distsys.TLASetComprehension([]distsys.TLAValue{distsys.NewTLATuple()}, func(args5 []distsys.TLAValue) distsys.TLAValue { + }), distsys.TLA_Zero, distsys.TLA_Len(distsys.TLA_Zero).ApplyFunction(distsys.NewTLATuple(distsys.TLA_Zero, distsys.TLA_Head(distsys.TLA_Zero), distsys.TLA_Cardinality(distsys.NewTLATuple()))), distsys.TLASetComprehension([]distsys.TLAValue{distsys.NewTLATuple()}, func(args5 []distsys.TLAValue) distsys.TLAValue { var jFSnew60k9UkNMbOwRMQkAjaDOsCVlPPzNCyFhfU0fyWovez0zXZDVqaX3EHHxW8P9RjGDPX8z8k8OPG6zvn distsys.TLAValue = args5[0] _ = jFSnew60k9UkNMbOwRMQkAjaDOsCVlPPzNCyFhfU0fyWovez0zXZDVqaX3EHHxW8P9RjGDPX8z8k8OPG6zvn return distsys.TLASetComprehension([]distsys.TLAValue{distsys.NewTLASet()}, func(args6 []distsys.TLAValue) distsys.TLAValue { @@ -261,11 +261,11 @@ func Test2(constants Constants) distsys.TLAValue { }), func() distsys.TLAValue { switch { case distsys.NewTLATuple(distsys.NewTLAString("|AP8[H3v] 0TXS4l;{MD>jLmGb~(,$M3&I+03G/|yp\\lCm\"gW{Y,|Jp`i$ICm_%\").WjP_Q/lA5")).AsBool(): - return distsys.TLA_Nat + return distsys.TLA_Zero case distsys.NewTLAString("~ l").AsBool(): return distsys.NewTLANumber(34) - case distsys.TLA_Int.ApplyFunction(distsys.NewTLAString("tpFXgtDC996txdhqxvc6uTZ7LGguVCIqPWhb4GPq0vrjsU6VJ36ivYQrBcr6eLu6EeizwwVG4duDRq6")).AsBool(): - return distsys.TLA_Cardinality(distsys.TLA_Nat) + case distsys.TLA_Zero.ApplyFunction(distsys.NewTLAString("tpFXgtDC996txdhqxvc6uTZ7LGguVCIqPWhb4GPq0vrjsU6VJ36ivYQrBcr6eLu6EeizwwVG4duDRq6")).AsBool(): + return distsys.TLA_Cardinality(distsys.TLA_Zero) default: panic("no cases matched for TLA+ case expression!") } @@ -274,7 +274,7 @@ func Test2(constants Constants) distsys.TLAValue { {distsys.NewTLAString("izEEDYZa31aMoAX0ZZSPtnzZiSJasTS5zXqdJAympTsARWZkLDJD"), distsys.NewTLANumber(113)}, {distsys.NewTLAString("dyEu1EeADkIvzDaPjLTdpJIcifTMU16PgoOR7843Gu7mpKqkARv0JE2u1zPr2eQ4vy0VjJul5uqeh7XlPAPV9enWRCf8t0B0xY0IzPaYhk71Y"), distsys.NewTLATuple()}, {distsys.NewTLAString("ihxh4hux8hT1KYXTuUzKlwPYkKAA"), distsys.NewTLASet()}, - {distsys.NewTLAString("ztbbVgCSX1bb5RMzZV4BCFgYkbdQlRyqG57NRyYuAN37oz96UHjVkC7HEElI4leshq4qEfyyLaNoJgFjFiy1Ucxd5jJpteH1vEaWkHa6yFo0Zzk"), distsys.TLA_Int}, + {distsys.NewTLAString("ztbbVgCSX1bb5RMzZV4BCFgYkbdQlRyqG57NRyYuAN37oz96UHjVkC7HEElI4leshq4qEfyyLaNoJgFjFiy1Ucxd5jJpteH1vEaWkHa6yFo0Zzk"), distsys.TLA_Zero}, {distsys.NewTLAString("zjWP4mQbVQ2lc9Ah2qo2sENITxJ9Fk"), distsys.NewTLASet()}, {distsys.NewTLAString("v4uawbLQboCq5rPaF4O4P9LhHxvqZlwWboXHoHD4oeoKTh3DhpLroR9zLte1WE3VZl5QuYZf71I5yofGfhfrcAeWZq4MopRwyEv"), distsys.NewTLATuple()}, }), func() distsys.TLAValue { @@ -347,7 +347,7 @@ func Test2(constants Constants) distsys.TLAValue { var tnD4 distsys.TLAValue = args7[1].ApplyFunction(distsys.NewTLANumber(19)) _ = tnD4 return distsys.TLA_Head(distsys.NewTLASet()) - }), distsys.TLASetComprehension([]distsys.TLAValue{distsys.NewTLAString("Or4uYZ'{+a*`I/tHTU'@Fw=}G/B/d%h):%R.FE[0}o-\\ -8'jRgIskN&SKdu\\,\")9%r;op>bex)&O5eqhS/xtaJG,nV#QWjd-c_f:)d"), distsys.TLA_Nat, distsys.NewTLANumber(55), distsys.NewTLAString(">&cXJ)Blo@-}ot<1`,WaQ4UI%BWVB)psW,;X"), distsys.NewTLATuple(), distsys.NewTLANumber(68)}, func(args8 []distsys.TLAValue) distsys.TLAValue { + }), distsys.TLASetComprehension([]distsys.TLAValue{distsys.NewTLAString("Or4uYZ'{+a*`I/tHTU'@Fw=}G/B/d%h):%R.FE[0}o-\\ -8'jRgIskN&SKdu\\,\")9%r;op>bex)&O5eqhS/xtaJG,nV#QWjd-c_f:)d"), distsys.TLA_Zero, distsys.NewTLANumber(55), distsys.NewTLAString(">&cXJ)Blo@-}ot<1`,WaQ4UI%BWVB)psW,;X"), distsys.NewTLATuple(), distsys.NewTLANumber(68)}, func(args8 []distsys.TLAValue) distsys.TLAValue { var kO0o8ujUrtEZSKXpafhXQv9EHVxF45b4MkRvqWCB76Ex6z1DdtwByAbWNZyQ6UfhvyVKTxjOmES5Jlx2nCIGaQB7KsdUw00Ozvmm7CtuhSt4GEGL1Hvf distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(0)) _ = kO0o8ujUrtEZSKXpafhXQv9EHVxF45b4MkRvqWCB76Ex6z1DdtwByAbWNZyQ6UfhvyVKTxjOmES5Jlx2nCIGaQB7KsdUw00Ozvmm7CtuhSt4GEGL1Hvf var ldBDvTLTWC5zA7k distsys.TLAValue = args8[0].ApplyFunction(distsys.NewTLANumber(1)) @@ -876,7 +876,7 @@ func Test2(constants Constants) distsys.TLAValue { _ = udHap4MoGBwMbWe3wfkwHtySrtHxLY7fUmyjYtOczUnO4wn09ksrx return qxbM0ySqkdzWhn6gaROcgBgxFwsaY7adHaF3zhWU3qvyZMiXDYvhlbWBjZSc6nCHr8DLrsWqkB1ZScZHg8LjT4uJqajwOdLZpq4pEzU6a6Gc }), distsys.NewTLASet(distsys.NewTLAString("w5:3;Z'1>; - } -} -*) -\* BEGIN TRANSLATION -VARIABLES a, b, count, pc - -vars == << a, b, count, pc >> - -ProcSet == (1..2) - -Init == (* Global variables *) - /\ a = 1 - /\ b = 2 - /\ count = 0 - /\ pc = [self \in ProcSet |-> "l2"] - -l2(self) == /\ pc[self] = "l2" - /\ \/ /\ a' = 10 - /\ self = 1 - /\ pc' = [pc EXCEPT ![self] = "l3"] - /\ b' = b - \/ /\ b' = 20 - /\ self = 2 - /\ pc' = [pc EXCEPT ![self] = "l4"] - /\ a' = a - /\ count' = count - -l3(self) == /\ pc[self] = "l3" - /\ count' = count + 1 - /\ pc' = [pc EXCEPT ![self] = "l5"] - /\ UNCHANGED << a, b >> - -l4(self) == /\ pc[self] = "l4" - /\ count' = count + 1 - /\ pc' = [pc EXCEPT ![self] = "l5"] - /\ UNCHANGED << a, b >> - -l5(self) == /\ pc[self] = "l5" - /\ count = 2 - /\ pc' = [pc EXCEPT ![self] = "l6"] - /\ UNCHANGED << a, b, count >> - -l6(self) == /\ pc[self] = "l6" - /\ PrintT(<>) - /\ pc' = [pc EXCEPT ![self] = "Done"] - /\ UNCHANGED << a, b, count >> - -P(self) == l2(self) \/ l3(self) \/ l4(self) \/ l5(self) \/ l6(self) - -Next == (\E self \in 1..2: P(self)) - \/ (* Disjunct to prevent deadlock on termination *) - ((\A self \in ProcSet: pc[self] = "Done") /\ UNCHANGED vars) - -Spec == Init /\ [][Next]_vars - -Termination == <>(\A self \in ProcSet: pc[self] = "Done") - -\* END TRANSLATION -======================= diff --git a/test/integration/EitherRepeatedExec.tla b/test/integration/EitherRepeatedExec.tla deleted file mode 100644 index 90916e5e2..000000000 --- a/test/integration/EitherRepeatedExec.tla +++ /dev/null @@ -1,57 +0,0 @@ ----- MODULE EitherRepeatedExec ---- -EXTENDS Integers, Sequences, TLC - -(* ---algorithm EitherRepeatedExec { - process (P = "P") - variable a = 0; - { - l1: while (TRUE) { - either { - await a >= 3; - goto l2; - } or { - await a < 3; - a := a + 1; - }; - }; - l2: print a; - } -} -*) -\* BEGIN TRANSLATION -VARIABLES pc, a - -vars == << pc, a >> - -ProcSet == {"P"} - -Init == (* Process P *) - /\ a = 0 - /\ pc = [self \in ProcSet |-> "l1"] - -l1 == /\ pc["P"] = "l1" - /\ \/ /\ a >= 3 - /\ pc' = [pc EXCEPT !["P"] = "l2"] - /\ a' = a - \/ /\ a < 3 - /\ a' = a + 1 - /\ pc' = [pc EXCEPT !["P"] = "l1"] - -l2 == /\ pc["P"] = "l2" - /\ PrintT(a) - /\ pc' = [pc EXCEPT !["P"] = "Done"] - /\ a' = a - -P == l1 \/ l2 - -Next == P - \/ (* Disjunct to prevent deadlock on termination *) - ((\A self \in ProcSet: pc[self] = "Done") /\ UNCHANGED vars) - -Spec == Init /\ [][Next]_vars - -Termination == <>(\A self \in ProcSet: pc[self] = "Done") - -\* END TRANSLATION -======================= diff --git a/test/integration/Procedures.tla b/test/integration/Procedures.tla deleted file mode 100644 index d9fafc955..000000000 --- a/test/integration/Procedures.tla +++ /dev/null @@ -1,149 +0,0 @@ ----------------------------- MODULE Procedures ---------------------------- -EXTENDS Integers, Sequences, TLC - -CONSTANT N - -(*************************************************************************** ---algorithm Procedures -{ - macro PrintNum(num) { - print num; - } - - procedure Fizz() { - p: print "fizz"; - return; - } - - procedure Buzz() { - p: print "buzz"; - return; - } - - procedure FizzBuzz() { - p: print "fizzbuzz"; - return; - } - - procedure RunFizzBuzz(k) { - check: if ((k % 3 = 0) /\ (k % 5 = 0)) { - call FizzBuzz(); - } else if (k % 3 = 0) { - call Fizz(); - } else if (k % 5 = 0) { - call Buzz(); - } else { - PrintNum(k); - }; - - ret: return; - } - - process (Dummy = 0) - variable n = 0; { - l1: while (n < N) { - inc: n := n + 1; - call RunFizzBuzz(n); - } - } -} - ***************************************************************************) -\* BEGIN TRANSLATION -\* Label p of procedure Fizz at line 14 col 12 changed to p_ -\* Label p of procedure Buzz at line 19 col 12 changed to p_B -CONSTANT defaultInitValue -VARIABLES pc, stack, k, n - -vars == << pc, stack, k, n >> - -ProcSet == {0} - -Init == (* Procedure RunFizzBuzz *) - /\ k = [ self \in ProcSet |-> defaultInitValue] - (* Process Dummy *) - /\ n = 0 - /\ stack = [self \in ProcSet |-> << >>] - /\ pc = [self \in ProcSet |-> "l1"] - -p_(self) == /\ pc[self] = "p_" - /\ PrintT("fizz") - /\ pc' = [pc EXCEPT ![self] = Head(stack[self]).pc] - /\ stack' = [stack EXCEPT ![self] = Tail(stack[self])] - /\ UNCHANGED << k, n >> - -Fizz(self) == p_(self) - -p_B(self) == /\ pc[self] = "p_B" - /\ PrintT("buzz") - /\ pc' = [pc EXCEPT ![self] = Head(stack[self]).pc] - /\ stack' = [stack EXCEPT ![self] = Tail(stack[self])] - /\ UNCHANGED << k, n >> - -Buzz(self) == p_B(self) - -p(self) == /\ pc[self] = "p" - /\ PrintT("fizzbuzz") - /\ pc' = [pc EXCEPT ![self] = Head(stack[self]).pc] - /\ stack' = [stack EXCEPT ![self] = Tail(stack[self])] - /\ UNCHANGED << k, n >> - -FizzBuzz(self) == p(self) - -check(self) == /\ pc[self] = "check" - /\ IF (k[self] % 3 = 0) /\ (k[self] % 5 = 0) - THEN /\ stack' = [stack EXCEPT ![self] = << [ procedure |-> "FizzBuzz", - pc |-> "ret" ] >> - \o stack[self]] - /\ pc' = [pc EXCEPT ![self] = "p"] - ELSE /\ IF k[self] % 3 = 0 - THEN /\ stack' = [stack EXCEPT ![self] = << [ procedure |-> "Fizz", - pc |-> "ret" ] >> - \o stack[self]] - /\ pc' = [pc EXCEPT ![self] = "p_"] - ELSE /\ IF k[self] % 5 = 0 - THEN /\ stack' = [stack EXCEPT ![self] = << [ procedure |-> "Buzz", - pc |-> "ret" ] >> - \o stack[self]] - /\ pc' = [pc EXCEPT ![self] = "p_B"] - ELSE /\ PrintT(k[self]) - /\ pc' = [pc EXCEPT ![self] = "ret"] - /\ stack' = stack - /\ UNCHANGED << k, n >> - -ret(self) == /\ pc[self] = "ret" - /\ pc' = [pc EXCEPT ![self] = Head(stack[self]).pc] - /\ k' = [k EXCEPT ![self] = Head(stack[self]).k] - /\ stack' = [stack EXCEPT ![self] = Tail(stack[self])] - /\ n' = n - -RunFizzBuzz(self) == check(self) \/ ret(self) - -l1 == /\ pc[0] = "l1" - /\ IF n < N - THEN /\ pc' = [pc EXCEPT ![0] = "inc"] - ELSE /\ pc' = [pc EXCEPT ![0] = "Done"] - /\ UNCHANGED << stack, k, n >> - -inc == /\ pc[0] = "inc" - /\ n' = n + 1 - /\ /\ k' = [k EXCEPT ![0] = n'] - /\ stack' = [stack EXCEPT ![0] = << [ procedure |-> "RunFizzBuzz", - pc |-> "l1", - k |-> k[0] ] >> - \o stack[0]] - /\ pc' = [pc EXCEPT ![0] = "check"] - -Dummy == l1 \/ inc - -Next == Dummy - \/ (\E self \in ProcSet: \/ Fizz(self) \/ Buzz(self) \/ FizzBuzz(self) - \/ RunFizzBuzz(self)) - \/ (* Disjunct to prevent deadlock on termination *) - ((\A self \in ProcSet: pc[self] = "Done") /\ UNCHANGED vars) - -Spec == Init /\ [][Next]_vars - -Termination == <>(\A self \in ProcSet: pc[self] = "Done") - -\* END TRANSLATION -============================================================================= \ No newline at end of file diff --git a/test/integration/ProceduresPSyntax.tla b/test/integration/ProceduresPSyntax.tla deleted file mode 100644 index 030e48454..000000000 --- a/test/integration/ProceduresPSyntax.tla +++ /dev/null @@ -1,150 +0,0 @@ ----------------------------- MODULE ProceduresPSyntax ---------------------------- -EXTENDS Integers, Sequences, TLC - -CONSTANT N - -(*************************************************************************** ---algorithm ProcPSyntax - variable n = 0; - - macro PrintNum(num) begin - print num; - end macro; - - procedure Fizz() begin - p: print "fizz"; - return; - end procedure; - - procedure Buzz() begin - p: print "buzz"; - return; - end procedure; - - procedure FizzBuzz() begin - p: print "fizzbuzz"; - return; - end procedure; - - procedure RunFizzBuzz(k) begin - check: if ((k % 3 = 0) /\ (k % 5 = 0)) then - call FizzBuzz(); - elsif (k % 3 = 0) then - call Fizz(); - elsif (k % 5 = 0) then - call Buzz(); - else - PrintNum(k); - end if; - - ret: return; - end procedure; - - process Dummy = 0 begin - l1: while (n < N) do - inc: n := n + 1; - call RunFizzBuzz(n); - end while; - end process -end algorithm - - ***************************************************************************) -\* BEGIN TRANSLATION -\* Label p of procedure Fizz at line 15 col 12 changed to p_ -\* Label p of procedure Buzz at line 20 col 12 changed to p_B -CONSTANT defaultInitValue -VARIABLES n, pc, stack, k - -vars == << n, pc, stack, k >> - -ProcSet == {0} - -Init == (* Global variables *) - /\ n = 0 - (* Procedure RunFizzBuzz *) - /\ k = [ self \in ProcSet |-> defaultInitValue] - /\ stack = [self \in ProcSet |-> << >>] - /\ pc = [self \in ProcSet |-> "l1"] - -p_(self) == /\ pc[self] = "p_" - /\ PrintT("fizz") - /\ pc' = [pc EXCEPT ![self] = Head(stack[self]).pc] - /\ stack' = [stack EXCEPT ![self] = Tail(stack[self])] - /\ UNCHANGED << n, k >> - -Fizz(self) == p_(self) - -p_B(self) == /\ pc[self] = "p_B" - /\ PrintT("buzz") - /\ pc' = [pc EXCEPT ![self] = Head(stack[self]).pc] - /\ stack' = [stack EXCEPT ![self] = Tail(stack[self])] - /\ UNCHANGED << n, k >> - -Buzz(self) == p_B(self) - -p(self) == /\ pc[self] = "p" - /\ PrintT("fizzbuzz") - /\ pc' = [pc EXCEPT ![self] = Head(stack[self]).pc] - /\ stack' = [stack EXCEPT ![self] = Tail(stack[self])] - /\ UNCHANGED << n, k >> - -FizzBuzz(self) == p(self) - -check(self) == /\ pc[self] = "check" - /\ IF ((k[self] % 3 = 0) /\ (k[self] % 5 = 0)) - THEN /\ stack' = [stack EXCEPT ![self] = << [ procedure |-> "FizzBuzz", - pc |-> "ret" ] >> - \o stack[self]] - /\ pc' = [pc EXCEPT ![self] = "p"] - ELSE /\ IF (k[self] % 3 = 0) - THEN /\ stack' = [stack EXCEPT ![self] = << [ procedure |-> "Fizz", - pc |-> "ret" ] >> - \o stack[self]] - /\ pc' = [pc EXCEPT ![self] = "p_"] - ELSE /\ IF (k[self] % 5 = 0) - THEN /\ stack' = [stack EXCEPT ![self] = << [ procedure |-> "Buzz", - pc |-> "ret" ] >> - \o stack[self]] - /\ pc' = [pc EXCEPT ![self] = "p_B"] - ELSE /\ PrintT(k[self]) - /\ pc' = [pc EXCEPT ![self] = "ret"] - /\ stack' = stack - /\ UNCHANGED << n, k >> - -ret(self) == /\ pc[self] = "ret" - /\ pc' = [pc EXCEPT ![self] = Head(stack[self]).pc] - /\ k' = [k EXCEPT ![self] = Head(stack[self]).k] - /\ stack' = [stack EXCEPT ![self] = Tail(stack[self])] - /\ n' = n - -RunFizzBuzz(self) == check(self) \/ ret(self) - -l1 == /\ pc[0] = "l1" - /\ IF (n < N) - THEN /\ pc' = [pc EXCEPT ![0] = "inc"] - ELSE /\ pc' = [pc EXCEPT ![0] = "Done"] - /\ UNCHANGED << n, stack, k >> - -inc == /\ pc[0] = "inc" - /\ n' = n + 1 - /\ /\ k' = [k EXCEPT ![0] = n'] - /\ stack' = [stack EXCEPT ![0] = << [ procedure |-> "RunFizzBuzz", - pc |-> "l1", - k |-> k[0] ] >> - \o stack[0]] - /\ pc' = [pc EXCEPT ![0] = "check"] - -Dummy == l1 \/ inc - -Next == Dummy - \/ (\E self \in ProcSet: \/ Fizz(self) \/ Buzz(self) \/ FizzBuzz(self) - \/ RunFizzBuzz(self)) - \/ (* Disjunct to prevent deadlock on termination *) - ((\A self \in ProcSet: pc[self] = "Done") /\ UNCHANGED vars) - -Spec == Init /\ [][Next]_vars - -Termination == <>(\A self \in ProcSet: pc[self] = "Done") - -\* END TRANSLATION -============================================================================= diff --git a/test/integration/SimpleEither.tla b/test/integration/SimpleEither.tla deleted file mode 100644 index 272e17974..000000000 --- a/test/integration/SimpleEither.tla +++ /dev/null @@ -1,62 +0,0 @@ ----- MODULE SimpleEither ---- -EXTENDS Integers, Sequences, TLC - -(* ---algorithm SimpleEither { - process (P \in 1..3) - variables a = 1, b = 2; - { - l1: either { - a := 10; - await b = 30; - } or { - b := 30; - l2: await a = 1; - }; - l3: print <>; - } -} -*) -\* BEGIN TRANSLATION -VARIABLES pc, a, b - -vars == << pc, a, b >> - -ProcSet == (1..3) - -Init == (* Process P *) - /\ a = [self \in 1..3 |-> 1] - /\ b = [self \in 1..3 |-> 2] - /\ pc = [self \in ProcSet |-> "l1"] - -l1(self) == /\ pc[self] = "l1" - /\ \/ /\ a' = [a EXCEPT ![self] = 10] - /\ b[self] = 30 - /\ pc' = [pc EXCEPT ![self] = "l3"] - /\ b' = b - \/ /\ b' = [b EXCEPT ![self] = 30] - /\ pc' = [pc EXCEPT ![self] = "l2"] - /\ a' = a - -l2(self) == /\ pc[self] = "l2" - /\ a[self] = 1 - /\ pc' = [pc EXCEPT ![self] = "l3"] - /\ UNCHANGED << a, b >> - -l3(self) == /\ pc[self] = "l3" - /\ PrintT(<>) - /\ pc' = [pc EXCEPT ![self] = "Done"] - /\ UNCHANGED << a, b >> - -P(self) == l1(self) \/ l2(self) \/ l3(self) - -Next == (\E self \in 1..3: P(self)) - \/ (* Disjunct to prevent deadlock on termination *) - ((\A self \in ProcSet: pc[self] = "Done") /\ UNCHANGED vars) - -Spec == Init /\ [][Next]_vars - -Termination == <>(\A self \in ProcSet: pc[self] = "Done") - -\* END TRANSLATION -======================= diff --git a/test/integration/SingleProcess.tla b/test/integration/SingleProcess.tla deleted file mode 100644 index d024772f1..000000000 --- a/test/integration/SingleProcess.tla +++ /dev/null @@ -1,144 +0,0 @@ ----------------------------- MODULE SingleProcess ---------------------------- -EXTENDS Integers, Sequences, TLC - -CONSTANT N - -(*************************************************************************** ---algorithm SingleProcess -{ - variable n = 0; - - macro PrintNum(num) { - print num; - } - - procedure Fizz() { - p: print "fizz"; - return; - } - - procedure Buzz() { - p: print "buzz"; - return; - } - - procedure FizzBuzz() { - p: print "fizzbuzz"; - return; - } - - procedure RunFizzBuzz(k) { - check: if ((k % 3 = 0) /\ (k % 5 = 0)) { - call FizzBuzz(); - } else if (k % 3 = 0) { - call Fizz(); - } else if (k % 5 = 0) { - call Buzz(); - } else { - PrintNum(k); - }; - - ret: return; - } - - { - l1: while (n < N) { - inc: n := n + 1; - call RunFizzBuzz(n); - } - } -} - ***************************************************************************) -\* BEGIN TRANSLATION -\* Label p of procedure Fizz at line 16 col 12 changed to p_ -\* Label p of procedure Buzz at line 21 col 12 changed to p_B -CONSTANT defaultInitValue -VARIABLES n, pc, stack, k - -vars == << n, pc, stack, k >> - -Init == (* Global variables *) - /\ n = 0 - (* Procedure RunFizzBuzz *) - /\ k = defaultInitValue - /\ stack = << >> - /\ pc = "l1" - -p_ == /\ pc = "p_" - /\ PrintT("fizz") - /\ pc' = Head(stack).pc - /\ stack' = Tail(stack) - /\ UNCHANGED << n, k >> - -Fizz == p_ - -p_B == /\ pc = "p_B" - /\ PrintT("buzz") - /\ pc' = Head(stack).pc - /\ stack' = Tail(stack) - /\ UNCHANGED << n, k >> - -Buzz == p_B - -p == /\ pc = "p" - /\ PrintT("fizzbuzz") - /\ pc' = Head(stack).pc - /\ stack' = Tail(stack) - /\ UNCHANGED << n, k >> - -FizzBuzz == p - -check == /\ pc = "check" - /\ IF (k % 3 = 0) /\ (k % 5 = 0) - THEN /\ stack' = << [ procedure |-> "FizzBuzz", - pc |-> "ret" ] >> - \o stack - /\ pc' = "p" - ELSE /\ IF k % 3 = 0 - THEN /\ stack' = << [ procedure |-> "Fizz", - pc |-> "ret" ] >> - \o stack - /\ pc' = "p_" - ELSE /\ IF k % 5 = 0 - THEN /\ stack' = << [ procedure |-> "Buzz", - pc |-> "ret" ] >> - \o stack - /\ pc' = "p_B" - ELSE /\ PrintT(k) - /\ pc' = "ret" - /\ stack' = stack - /\ UNCHANGED << n, k >> - -ret == /\ pc = "ret" - /\ pc' = Head(stack).pc - /\ k' = Head(stack).k - /\ stack' = Tail(stack) - /\ n' = n - -RunFizzBuzz == check \/ ret - -l1 == /\ pc = "l1" - /\ IF n < N - THEN /\ pc' = "inc" - ELSE /\ pc' = "Done" - /\ UNCHANGED << n, stack, k >> - -inc == /\ pc = "inc" - /\ n' = n + 1 - /\ /\ k' = n' - /\ stack' = << [ procedure |-> "RunFizzBuzz", - pc |-> "l1", - k |-> k ] >> - \o stack - /\ pc' = "check" - -Next == Fizz \/ Buzz \/ FizzBuzz \/ RunFizzBuzz \/ l1 \/ inc - \/ (* Disjunct to prevent deadlock on termination *) - (pc = "Done" /\ UNCHANGED vars) - -Spec == Init /\ [][Next]_vars - -Termination == <>(pc = "Done") - -\* END TRANSLATION -============================================================================= \ No newline at end of file diff --git a/test/mpcal/go/concurrent_replicated_kv/client2_in.txt b/test/mpcal/go/concurrent_replicated_kv/client2_in.txt deleted file mode 100644 index e74b727a0..000000000 --- a/test/mpcal/go/concurrent_replicated_kv/client2_in.txt +++ /dev/null @@ -1,100 +0,0 @@ -Put xQt30C7iOBWxhCr4ceZq7Q2Y6NPOS8OK di8ubhvM1Vi6cVGv8lxy52Yill7IFrENfGdvWHp1sF8YdbcVQcEOndwBEdWhqFpA -Get Cgs36nrOzdvKgJbZTFxcoT39cbzpMgf3 -Put SwAp6z3KP6TrFFBWXOeFg09mj1dDGdJb vTbg5HAh8gISZzZIf3DAdvX149il8iYsFexa883rrCXtv6MLuZ70yytUwPcpNAjH -Get A4rIBzEAgPHvLxlCNHCGl6MeUwxPp5l5 -Get yatl7cYA8EeVMkw9XBs4LAcHIqANX7y7 -Put w9mFiiwNJikvPLAYdyQuvsDDqjFnbbEU fBa1DuTaAKNDYJQVsN4kTPk60EE3w6wO6bPdpVv4B3UjnmjPVPB4rTDmU133L4af -Get QvdUBwwMeM0U0HXoC1WIqR4cJl3NwJLN -Put J2irx8YzGxD9NJ2TXb0G9wNDP244y6Mb VI4g2f8eiSHAdQ5p0awMvr9s9lMZkHVOV4ey2LfuiFiIu3ORPzlxxG1rAVrCfiG2 -Put 3XH0fJMmtbfCwD1DcPzqBeIRBsPEhW9A Osc3Wrqn36nkZLiVucni7uic4y2R4goxKyK9WwCC1GHrUt9x9C2ocJwY85VLL57N -Get PUyPPxbidhsLok1mdq7QAB8T4gWEG0iE -Put cltWsGydp9xP5wUDRI3eOrsExsfeS3ga EtV3e1TSBxoBjMS7MdCByGSv1GvhhL3uRc5odj7oUcOEamv9iqWAyeyGFpYGw1PV -Put F4yu8GUypdEGTy6r826mnMAz3kOwXRxv 4DdnEHyjFeA1LsPDgFHs0af9wM9w7H61AuPEdNboBhLusgC65fiqQv2yUtYAnXQs -Get sUFfKcH73Ydb1Pdk5LArn8O4iZ7nZJ79 -Get JyVVM5RV3FE6nUafOdGXVaqgIQnWJQ3D -Get lwNf2322UuRuZfSRdUfNg9sRRSnWxih2 -Put cvFNCELpLbynm8sZ8VoOFQrDOC3nsDe5 Vu4SEc9jb1Kx5wufXsyCzrAguoittKi9Ib7bsrPb5eePiBYkI4d04DO81dppUoCY -Get oIN9u4kMTYtgX7SUf86uvfpV9ENEgbjn -Put EY9Ps27MrUqh7bLoolCvVtfmNT4GYQHv 4lpi9lwPGDxi0F12cld8NVv6P7tHvsHG9A6YdY3Ow6cCa1CkPboR3STlFKvN5H0R -Put 90DpqkWyxzywWBqBVJxWgF3E4W1DTeKm MSbQBQoNaBqoCZobWO7G3Ytn42sH7Y3VYrygqsqx3rEaMMzF9XDAD52Z4Jk2g00r -Get kSreSkAuZO81RC3IZ6Ait37iOiYdP4a5 -Put l5mZOvqHpUbHoa8TtPZuDCnMa9YzPJPW y6RF5l4chNBcHKEVTdqJiwMcQ5hgaTEGzngYUJIwtBaFkpb1a4PYgV0EPJDMnYgD -Put dwYE00tCy1uJmEvM4KWdxCwoqF3DeMO8 ClzVhAqU2L2zGSqcnU8oeeH4Tibv6LfNwXUVowizt5bWd2lODnKLmHjzBAMR6vPR -Put BCesKJISzeQwjzg7c4z8izrQzlsDs7zr QvSVrJk4Wsd8Z3j0FpXiRR2akVN6MkjM8ifie77Tz2GeI6pJmP2ctlimx2isBvsz -Get ykNyf8JesiDKFE8Vo4noVC0dVaXi3tiv -Get KovTNz1CY8YNFTvdAE0bwwFqhShWTZmM -Get ICp5XipBHWICswxbREfKjb2zhiTcByWD -Get ciuF2sgoe9jpRnwGMmY6an9vavzoDYhB -Get RBG7HW4UZIsjjQhQX6UhyAYWYODk728G -Put I9oEjcthDFjUoj47UBYxtOuneNh1qjuX FRdnBLcSUxqVpnKtcFB8CqNzGjOr2uh852wOxkHHpairMWWME4ssNeM8aXzTCuJv -Put Avzj5eFCttrqAF6EzobsNocuhN4ooB3T RfMjvc2QSlSr3UqrEubTLAFqt0PoJpuM5sEejOnsJnOPSboRKwxRdU6693qDJfBY -Put l278j4l4p94y84ymmVJyrjwMLp88O0VW fMlLPKs3a53BueLKJuuYY14FliPRSItEqYFIhQXYCs3tutO1rgxooTFpXnJhkPMK -Put PlyfbDIfcdKC2O4msPhNqqGoH08bM0cX Zb4Ra3ttWU7SW03EFJiwZIr6RzTeo0hJeQD9HYSJx3zaYllb2SzSu10f80qOe8NX -Get 3nlhAsm2OL6TsrdlqHtUADO1FyJwRAe5 -Get 7aFnPQ92rXtLW7tQvgT6ahsyAtQiG0q2 -Put UiPQk3eTYKeesAOf1TaUPympHJsopBTf u3iqKr6X0vZE2wr0emx4eh6i5FD1JOG2aFoph2nsa1kk5M7ZkjFtbyIaewi5UTAs -Put ORktdd1x6fpyG9AiUDFgCeJbB6IA8ki5 ZNn5nQUUehQW4u1GTBwjpcWFQBBbexpl48dTcKumfCuQVP2gLnP9tgNZepDNdCvH -Get mheSIlJaoh0JYizZlj8Ss0s4NjfpWRN2 -Put Zk5BaMU1IrLFTGXf8Ck9jzHt7KgosyjB ILr25wFMfr3gaEDdIPggLpDu95j96qis4gfd0vyvWFSefEajh5z2kHMpIGXV7nNv -Put YHszXLLP2nYsaxUEfUl0IsxZah1uy9cM lQv0OFa5DI9jeZbOoYpyFRzK9sJNsB7eZ6d47MGRtq95uNfwKH5haDhLoaCPHdrE -Get daZKERGqiMJZ9pjSHdAs0xoQXF2q4ooF -Put JtXZSGXQsotZMQncQjwH19CXkQyQQTRS pRG1Goiw5CnApU2rU6yUWRLZGRNuwHzax0NrTY0ydBjWBHGLYFZvQhYTdBYvoUXY -Put az3XeVpATQ5rwh7UnRQvTpMBrkHRrgWj kveIZX31p2DseNGbF3RL5sisOoB660n0JlKcZmAqCMSqBoQV4s2sZOjItaCDm7kv -Get pkfVr7osn1f5YBUcV80BPewhWAW2Dpv1 -Get V0oZYjwkxKLJ1k229nLb9h5VqhXAt7P7 -Get mkvMWnKs8JrizivShRC5zm7Gn1JQtj3Q -Put FU5EZUHPD17u9ufF1gGTcd6ib7uBc7Yz mlaQma19uyUlMb2ug2BijlE1SOqTxs8tW58I2k8s7BTHRAc1Kt5OIOTSpiWf8IWa -Put ctdFDDFUPf5WRSqmpBDqWqeK5LEBNJFw wM9vRHJIagwpMVJW7i5Vk5MMfHNHrdNyqqCNKAi8avI32NlcBSlVym2AFzpnhLzm -Get oKOUrC3Koo5jFvZJPJVxD0OxWkkE8WfP -Put 8FYuIv0YYtUMBwhdVjULmbilArf7Yw9s uWKkb9RJO06v1tu6UfwzUfRX6AAmxXsQsZGc1gZvsZrCFZqaFIPD5o4fq0fhLBPe -Put s8x1rShvbamr8E7JuYH5NBjrlLHFEX9l zI3lJX2QSSemm21tTx2KJoQ3j9mElbdEPtqkPFhIa0YlKIPMXh6agh1TpAprxVPw -Get yDWaIfIWc29HawYPHe1e4fjU3U9l8S36 -Put WhEDGf4h5qFfKVZ2Vk83vmwdthK0H5Li tA1AtdQ7qwtxqpfZyspjIETwiquMM8ZwGBb2DXod8mPxQOssAnEuIak9iKMRidEq -Get 98IFIO5nLCt5mlZ7bdkbnq5CRwSvRlvF -Get vbccR9huhFyzbwjk07AGorErB3JXd1mI -Get KtfaHR9lLqYD1WiyXJxvnHVENBGbIIul -Get dOcUarH4l8DoUj7y4ZT1VqxgFRGwSN3c -Put mHSG1wYohYBHVC7e9GfzRYy34aSMzE9y zki6lnB0Oj6gZPHIsClqf2sGHr8csWXhP9y14FiCPxbP4d7OyIsHcbYw4ye7xGYs -Get 96hY9pAvguApGEQeq2wShPa0i6skKPsm -Get fUXpaUlVfD3tVsnKJRJZiq00Ufpaz0K7 -Put 4ywRlUlvYh6UbJ6LUTtQ8gKjYAjRDNEi 4Zvvb2Rp7n0epfarBSUZYyKTOFMH2MdpLvuoEOoLBWdcIN7zjqUYS6weA1dkUw5f -Get Tvsp1nNpfMaHWyNWKNtAlXf2qeWvvQX9 -Put 3PnjLMKV8sOqaxNmgDHEN8NftfuOgqZN oG5bmlW8OMpLPmgnPTVySIzYYmUroFwiQ1n5Yo0zPoskT2IURg6N3SEsLjJCjg4x -Get rkz12goa7zeGZBcVwSdJYMCttCM5EwC1 -Put PXdYIMUA9DdtYji8chuZ2Z7uXvxWG8jg LM3k0ERaexBGmFpSPfhOlCrGqiHkrsN50vsluxgwwxNtbdgAN1UB6c14rGtrWpfJ -Put zFfVc52kMC3kgK5CJqQXYn76heDJ8V4I cuBoClKhYYrBq2XErR8uRb6p91dSgGBIqghKSm4EF2XLr74Lpu1dyv2S9REZ5Rwp -Get V6oIx4Vsyf6dlYKO7FMs6mGeRHOduUPu -Get IWrRyTSJmPBuexqfwUNAxdFb6O5i4wiN -Get oGfp72TkMPeP7HK8U3Rrq789GWPgt9Ru -Put 7eMPCljnoK0fAH6dsPv5D8GWxAWQlujW 7vTOzwQ0QZK4TPYAixouqpBerD1l9Oz5N2Aw4bAamm0SWdd5t7Cmuet8Q6T3ZUK9 -Get XHkb7KDcPsQ5Lt8GzKdV9CjavS4kq2SV -Put shJlyYIn4Y57IeVo38r7kLF3VufYSND2 JpfUcPH32ILNkGgimlDx8xrM9TaFbJZJQhOfute2XcrrmGLCC19jwEozWOTGJQbM -Get cpTBbzH3PmzVZCdI0ndYWsfS2zfx5II6 -Put ONzHZmxZ7zkxvICTQkHbZTtwX3lk3mDO d9jriT2Y08jGo87LSm1FHdtnQcbqAgwHbENhcHki9ymvpjnuK0Wj6HyML8diKIZy -Put oyGzmjJzZn6NpayIgg1vqKsCnwbrln7N pcB6xgs4rwtJFao1QMEnureZRkZMMD9hgFTA6datto20wbmrpRxHQ7R1MzmspEB0 -Get vwllCRolXwrjUzPXrwPzf9C9N25rCEFq -Put sf9hAA7Jh8BSfY6WbTH3iifbcJ4yywIW 8Gngw6qd1sPWqXaQzt3e4DMPEjZUd3yIK3GZSILzlpGGp6p4HkXzF8nBFulwPxf3 -Get TSEl3liTsYoasFiZbCMG3TBuE65kMSwn -Get haI5ImoqRFMX50lFN2L4Xwiz88on7wdF -Put yCBP0w0cPWk2hKJEtXd7smAlJ3TE2pxp CF72KUUNzwaReXPRw3s2rB0kNWvvIheWJI9vRpvJACBiKh3fn9g3q0ZGcZBu1YGO -Get Y5KdievmrBozZl2sCWTJLZ2J7BsVljM7 -Put rtGf0pgW3iEJgKD662W1298xlLEJuoGU kpQZEkORAq3v0NUqXSbQxGtZqUf99y9nZUocLuMRmKLVkJ4Eneqcmx4mfK9ALcI4 -Put aFx1GPILUtL8PUu9erfQugDnVbqJYDPJ 63Lw4J8Ou1lj4cScroxePUwmDDmQnSVRhcRiM2ARZYk5byLBZZVatBcmeFE4XGLd -Put oDVZvqu3lhxpKYu4ad1QpVgqdiFRZNeo jzCztQpOybHwqxLt1tryjPfuJWgUHtG90ILSvop9HswJO22jtOmtfXlTqtiZrgSo -Put EZJwNJR8T7OmGRZak9cJq5ktK2SAORy5 ahPenvGom2gUeE2egO9gVpaHS0H8wvGUWp9cQCx9q3qVKFqIUOZqBAa2DCml2JRQ -Get IU2J0TMhPdMIKwy0nxiH6bGEInItB1tY -Get b37YXCcFyUgkXAjWKJWKx6640AU5ypEp -Get kG4bLjR6FOd7AcBSEZmfXpojrKnupW6D -Get QKE1lnwn4IMQSK83GvHVBbCK2noUEL7e -Put 0f8EXoSL1lx87qXqgZxfkE7PMmJNcVnu 4t1jMJVNX9lbelKP2FTZJngRu75VjHIVr8U0hTXgZ0SFkeOL0Xn2h2NEikzKDmyC -Get Wx7QT6AxKl6QVakmUJemuL151XEM5cor -Put 1M2QWT8JifCOEOyRyLfEbzhfZQIV0zrD coSfNXffL9wVfchSAoh6N8nHznkTVr381IOu7ylR4wJbOZVIT9ULODXyMN3bAnVV -Get 6OhB8kTXb2JYZ4NFd2PF7Jnmh1Vz1WLe -Get 442U3BBnc377MekC9stbpcpFWrWGiG5g -Get tcrHkD8eIrJb0cxG7Yo0f7xlRN31bofb -Get zWqBjplHIWmD1VzSoCccYGdXVJ4KHDY9 -Put qFoPxb3g9WXCgfqBZTbM9FBghzhlGtP1 OUYSeUlUMa1pczdmG3V0DPtsA35YABX43W85fE3ScHJ3ZtOT9bw4z7OjgMf74S2F -Put RmvbDARSTGu92uwlGDzaOmTYfk3YxIcX zTZ0vAVbsZegXOCxUpW2sFvx4qLQKvqTJNAqAt8mQEW42LvGfErBD9zXXD37B8KY -Get p5oWZH8j3vjGz5Eaw90AGXzMSkDjuygy -Put wFteV09JaGijCbB0DumErH1jFL9FdeoN UwzA1hnoqIVL7RMzrICmC1GLjqpCOuQBocpLvZ610NUuGMKPr3ma5AKv1NvL8CEI -Get Yhie6pVft71NbZcMI6H45qPEaMSuAbhX diff --git a/test/mpcal/go/concurrent_replicated_kv/client3_in.txt b/test/mpcal/go/concurrent_replicated_kv/client3_in.txt deleted file mode 100644 index 8175e0d9f..000000000 --- a/test/mpcal/go/concurrent_replicated_kv/client3_in.txt +++ /dev/null @@ -1,100 +0,0 @@ -Get ubRimpjKTg3qvJw60aS9VDNoe9KeYpqw -Put wwkuNA2Qn9FqlyvZExTMObACsDxUZZ23 o8iZfmwIcfPOqsDBvev0IgKNN6AXUlcnoE62dkSuy5hS3RS75STRmMDOcFnGR00V -Put TZbNgyvDHQpWXc650Xedq4k7i4CdJU5p LNPLpRuXIuh52mcxiJoG3vp6epah1EtvFr7h8E9q5V62BB36A7J9My716KN38tKu -Get ORqyVg3wLlvGsa6zx9shhRkPuLYE7QkS -Get sLNoYtMRtVPqieyfjdl9dG2nn9wKd4RI -Put 4A1hyjkYeS0eXPNo6DCcvSoQrKLON8NR x66c5Tilf2REw8Ju0wAnpdLHCtNZUDQEB5HSOIyCZNmWOSWbRm5zu5DfaMf5RXuc -Get SdnmxAuXcSg2BxU4p7zHiRb3DEduyJKn -Put SaGqNG8Ps3Z0PmYq5GVjijntYckVSUpJ kGFymhpSQuw672RFeAAMhgm6YhbppnVFveIC1Q3h794NFNwNQ4uylL9DIhPpW5Mr -Get gW8Or4yzhr7msliSafOewEyS17sGKb8j -Get n1bZYl1Dl3k4eQvfmdPismzG7pXPW7JY -Put F4fMBDdsTCKQaM7LESPL9QQhlWnt3QS2 Zn7A0JdWoGeqd3QxkycyvBW90fYSiP24bf1O1QRLclJaULqZFYHMVnIyhK1edFRm -Get wdHkEEMMjITKkenApiaipTgb3HD70m6N -Put 2b3CVX2mh52MYCJq52holiJOIdpCImRp 47gzV47HUg60SYId9kxMUJFbQ1F6nCeUeAkf3DYSdx7UZ2lnPt2gQxniNhnQEZkW -Get mFwLx8mQGougbhAmPUV9vzIOq1wmRvE0 -Put aBt5rlDv6OsoGRSkIRnv60NW5x5Jayle esEBJ2NrTWJe8VaHd1ammhHSOSa1IFEbTGRim5gYtRgeHHoCdBOcddYFTwE96r57 -Put daZG6PJleEtvy3gyxdZQdmHLQ1suwr6m DiwySXp2wVyRkPmW5lslC1YcxJB3BVIDdlTeGxZfKo5qfl7ZOneEihn7AofcGtoc -Get KKjubHJ8ZeJlFD4dJyIYDbmUCaNbISf9 -Get TKseySClQQ6E9hdSlblPjMYOmbWRewQR -Put 03TC5FpXEVO8qgg9hCeQaZjp3yKFWo7h nlvnSSJnN1WxsbbJLkywQ8Lj2U8PICr9gFx1wyxpW2s3gNumx0yowFVZ0TIreJTO -Put nr4kBf1XNEnIN0BxroGa5VYGXs2d9P2D 6SlChlTgPeqmeBgQLk44qoxSIwD2mFDUubIjHJOZ0NruKQHdUkQcuwaWyGpBmbLl -Put VrFHiBTE3oZ98lDoyYHu1njBB6DMzAap 4l9WMFGRq5FftgRKI2Zm45ww0cUzMfh7xfJqkv6UzP8ib6aHKGwqpyYwPfMWkW1d -Put OMuzbQdC3554tI32JX5XqrBy5L6cXDWS iRpfKMHoQN51zNM6jcDh2oBPrla3Vph3AWbLmpkaYSODTc9kofJ7m6q7F2Q9In6U -Get axBwUbvyVUX3cicOg5cXrYloww4CmYwk -Get IWLv47JQFDFjgswv5nGD4R7pFJQMVl5C -Put JfjT2n1JY36vtg85yTy00dvdgvYV0bO3 o6JQlR9wilbdpXXFYCGcasXrzLmEjl0DehaYuZr7SODChqdwKC2n9SZFGMViOHfS -Put 1R2arsoAd7YPDjMJD4Wxh2fMDalpIJ9K jx8UYce39Q7clv4H1Zo34iE2tIOE9NwH2GmquOj95y69QjBU8vv6CVwiq5Lm36mx -Get IbRaneQWHtaqjV6jpoXA8WBVXhVTATpF -Put iEdLBhdykNcWWdwIFAmnYYRqRYRwOs9T eYImF57zbAyXrP1SIVjG0bNzDTgcdHzCdoFNcABi53V6h17C8Sc5Cz1U1mPbfRxC -Put SIK3nxTeNS0Vvd1VeEt0GH5huHnPdEO4 D7Q0Gv9tn96J3zRwc2fnZJOQzC7WMJIDpnXOqSkrehxzEZUxaoLo9Z3CZjRVnBLP -Put 5wc98R2QU3p4ldoTF1Fy5yXCFqF0Pw8m y6F7ZgCieNlUx7XaXD2RvW988P1GvxTnM2M1hhb3xD1gutxxCm42JUaLwwgEcrfZ -Get 43bprn2Du8IV30CkNXlOgzHzxyK0plGd -Get 58Z9qDiN9xKeYqPc7NFZzGMBsESs2LLX -Get 8jThImg2hgLB98NTGwI6YOkJzUus8VMH -Get A1lCq0bgSBLXMebBXZvZ7gCkCAE3FYpC -Get zn4kLGSaSkjuCTMYTXHSejRWcxEJFkc1 -Put bZt4UbXcpJiS4gISyFWyJdId4U0uyjvR alQyJ3nhfdLA8dgEmMhnwJEsQs4z7wiryhszWpgYoKJOt67vjYGjIskVWg9jkxpD -Put QrvyHezLniuraGk4Qr9VrPuJanFdur87 rLqWzlBmCzoQR6T0Bz3Eerjz1O8aAnkPbhfdNXsczhuyo1sx6yPw2moZFiSLCmj6 -Put KkQXql4CeaJhCz35jJdhXSf1bW8cB5Tl 2B1fE8XT8ad4hqNHCpYCcjstknGd3goHmPCIr8yyHMqXYshB8XZnP7qEzP0PGAZC -Put R60QZPVLfVMq0f2ahoARBpNHyYpPDNjJ WqKd1I42hyVpjFWzCcZyvRakHM9uNDaB8ImW5aNmweWIpJ8wuC4aZzbcwl1kkct4 -Put hpcJGkvr5tfF55b8AxHj3ox4CcvzVKtD WwMeT2cIxkUExDOEj553FTp8YgRpth18inypMlbJgr3sWp9uPBQqVpYWjgs1ZGi7 -Put nCu8tQYlAzy9dnb4SiVQHs160xYnQu7k hEZf7ArbOXPuNQaiv2oT049Mg8bZhcenZwkGKdymZ9g85F28AUQStziiBT2FAgyC -Put Q2iWNZAx9jJeEsQuJ7g9OeUXyvDR7sPZ C7UhUGNdvyj1jfGkfr5JCJgtWiRav5lqZ54BZWPI6Mx8XqotKYydlnsSL4ckRSoQ -Put fMDxBk7WeZtORMX7Ij9SbB4anjvg1UgW fYyAGD9YgVp3iKSwNQRFK2cmXagTXhyD1qISnpcwq3O0lZTjkw9MwjlaEa0G4EpP -Get vDpbmhydLhD0tZyLccDNLsCxPZSdlFHp -Put HtIbAAZ1Ag9Ay44o0eF7zfrkPx45VC6r OISZEqf9Gq52d1iR91fbndMRFRtXaHtTFYKovfREPTG2nytAHwSXUeK21vhvdwz2 -Get YdOzdPN8wCvJkTkCrWFkQTdUtSD2IiSR -Put 9W8X1PPPnrscCxnn5NjpjizvMaxr2hwj 4WBGvggR4L8x77zjk6oh1NPLgBUWV07Kwo5XewWgGdHrqnkIvYcw7Y74VYlv2ZQF -Get 7W3pKGpDpw7fTEtmzIwcKrYAgWMbYB3L -Get 2ivH4YBqnVv9hgEp8r2y8gbkAj1m3XED -Get odJLpqMcoQDWYHIFyr7Q3o1a51VePnSs -Get 3LZfdyfLFYsNBlrkK6xfs5fpL62e7WrS -Put bD6qrgEuGhq5CQHSTOdmFCBIrwZpJDKa fD8DMvngfx9VKraIM8cAktZUS8sHqSdIWWOS9QXtozsinviWJQb1hk3n6XMyqyyU -Get vk61QLsKyij1D1wwEEqLU8SvcoIEH42h -Put pGORfLuH2Q9W0cYq88iA3c3HEyoxgRw1 6LwIZsnGCAKb5LoNtjfoMbHwJuItVtB5F14kHolFKooKt3IRivzqZRqyAn5g9O0O -Get mBolUTYpZTScBQe1Hh6JCKF2oBlEaKZv -Get hyYRLY8Yu1W4CO8zBtbtSSp0TG5mRZ3X -Get j1hWno6FvhXrzwvTeRf7k35nEp9cVdBT -Put WaaaDNFaIbT8I49xxFOFHCgA29dJMAiY K4USbwF0PJBDnx7ycAzv5fM5FACquXnWs6WUzqtqaoRWD37HB9RJsn9bv846yJgv -Put xYrrmrQUUfA0G7dKdWov2r6f6qhLRLpN w0QgfK7ptn5Pebpbh3qAfhSUyfM6XsS0d0QlJbXrpn9s8NE9XLiWP3Dk4pght1pH -Put hrIfkqa1Wo2VeEm0Khc0JYUgEr5JPq8c rawDGwz3JBsuXaL0lQ5l2nquLTjOfhnOHlblLPiv7BYf8wTS4Xb3YNkeOmzZCe1m -Put 50ITnTKK6vQAkeh7T9ad6guuK0FwiiT6 yGEMlAP7dpUDBqA1Fae0NxvAfnCIRyqx9rXYew3LTxVrXZss2eSeFmEF7wUFMVQ6 -Put Mm6gqQ9sLUmI87xcIUnWCc1WrJf9lYhX mWf0r0vcs5MILFfx5XoqIgQiHfEnvjbOjgquMPGXDAYAHOVy1oRCI2QupNCKQkNp -Put GoRGKnUPn75DPH4pDqkECwEtCWUprip0 MD25LlT1fWgqrEunBnmW9eagK2O7pNQESQPPyaBlh2xvJS3ROMPihCPNw2F1KiMB -Put L9QLjg6RhDCc4wpZLsKBVt8vRsebGDDJ nafu34cWxMf5vyesNU87EM3KL1Ps9IpjQtOmIqrsHfNKBzrzzjrRmcg78y3THPzC -Get UxotLaiDk0jorFukxO7l6hjOp0g1uIeJ -Put 8MJeUclqiAWVT7e0karYXhsMtyHe1SBi txudMF4cpHONLo7k6pyQkTP3gNWdweBQtnvwpQaSB3ECOaNouhpGCrKfBWzhSSbe -Get 9Cww4jw2XcIMWdkvS7qhRPcS2ajE7XAB -Get pjvAiNBFbbcw4wpBW2FKuCqPifOOkaR4 -Get VGbsC0xSad7hEN4uXqSe1mzY35FG0Vf1 -Put SKcnsxgqYmiEAeYlNcOQba98G32a1znu vj9lzqZhuyOHhpMwarVZnTmZaIDkHG5r2RlFpPsOa7ORBPERnixBx5k9OcJQgJ2t -Put 9opIfQPwdqBBvHc40KqP0CN2irllkoGg xca8A0QzbLKu9J2Su3L1aFog4LY4z2sHaqQsVKqMkUkTOxbB7tBZiINzmkvZnKSe -Get MTpZsGnteYAyLWkGUN3iuaAm2spykoqj -Get QtXTTHP3LyNWX3PS69mAifvKuTAUx9NH -Get jxGOKGRXh2fG5GCfd1VtsiizPi9S4sfQ -Get VMnUQlCcKjjghbBWr3uiWVNuzagoLM2y -Get ZIFFlbBeMSx1CIzwnYWyppa4I7t9vB8K -Get sPwCB1hJkWo5dfbkeF1xaqs5fA6jIO4r -Get 9aT7gKdMqvyt7RpGbZeWVROQmb0Q2jLt -Get GgbmGSMWZTHeWLLapveEUEs8h5YWGotU -Get tNdZN3umuEw3xM4FusGoi7DzhlNvnvna -Get gdKbroVsBQFL2jZpUHy0LQbCIQbvL48U -Put DOr2BOnWGATILeGTaMZREaRCk5QvfkUN laEblvLgQ1Y26o16YfoANjayqGUoDZhHcJGwH0wpKJRLLC853LfdMds4VbA951pI -Get wdTX8NMa6I5kHM1zbQZV6mfQM2IO2D29 -Put 6r7qQ9vheEfGe5DnDJD9U4ZK05fWotZl g5IL0DtJJ7ZPx8v90L0Daltl9pFquNJx6pINKYWUeQ0bVvIguBfCJ0y1BCTP5cCx -Put WPvpsbo1PSglNWRCKwCC9slPzBJuQoTj NMJCfyh9AgfEToZ0XMfTwzE52n3HFlk0XZmJiVTQXXS0AWPGl81fhwh8msEbCRvX -Get 4RIgBxNkFwyqhZOIR4WjhvZRWdfjzZ7D -Get es7hODIhhtGNHGUC2M5hmhcLJHm9ZBx5 -Get 6ALH5WdiFwqXwi2HiDQInkHHffXN4z9D -Get HpAgUrKBClhfDcnKJJ1cW60ZEREVTnFc -Get 3MOowZfXcIpv2PQbCGcT5k46gNUKdzP0 -Get p6RberjKrTYzMAgSlY1Vy8MSneWiEKhU -Get xqfumwisAh7GlgJIgzwtr9deeKkEQTKh -Get 79mX9togly4916LG5oL2uKcE5cU0Girn -Get WSCKPAcCx5WY8x6FhYsz6MROU6Rchz2i -Put du7uMpAe1eRzw9iq2tgplJh7xBsJVBXX 9BBcD00eLtoSbhb4GKPyclqy6NNWYztKCZViqVAbu8dG0fPi1K1Ez2AqzlDSuDdH -Get yPfibpMOjqtrSbe1QbnVykcGMA0hI9WY -Put 6ijXXIvrmIVkamDOEIeLLfBLEQatTOlj 6OlnXlfxQ43bvLe15TopoKOA4emxzMCaG8NfnlNOHAjAQMfyBfBvVekYcuaXYQWM -Get CLkz8eQpsxhoQFgqdwboO684Kfs5mAcB -Put UKlazMCQmurMoj1gSLBYFACmGBT48zr4 svfxPjeqTmFYRASxz8QFANe11eVNknib5scBYb8lovSNr1zQjQzrXRKeNgA7mCP5 -Put W2qNjUMks5LkrwnfSXcHOuwmCx0hl6wb nrAJaImFQD42zHcWVWL4XnpoPjoGzjmhoynIT3svoSonz6PfPtxJV7chnyPg87kF diff --git a/test/mpcal/go/concurrent_replicated_kv/client4_in.txt b/test/mpcal/go/concurrent_replicated_kv/client4_in.txt deleted file mode 100644 index 85c2c031d..000000000 --- a/test/mpcal/go/concurrent_replicated_kv/client4_in.txt +++ /dev/null @@ -1,100 +0,0 @@ -Get SRH7aHHTt9XhQT9mTLOcigfk7LOFuT6v -Get HKIa5vhkjaAUPXPDqQqjDXAcER4wxl4A -Get Iiwj7kmH8RBi2xYdu4X3gw4XwCR4jr5V -Get m4vQZPLkudN9v8PaP9kETnCI7vmVsJA4 -Get k5JyEYZpJaAoEcNzakJzqQHjGqgy24YW -Get KA9Npts6r3jZVlnXVBwEjKsOPaIHv4pl -Get wyUpoEpDrGKqaz3CgyX6wVN3rPoGQfQ3 -Put Zdkg4YRRT6S6goezb03BMHmAyihJBKx1 Z0GdML7ma6mNB2mkYg8YRYxATQLfTseJOh16WGkuN3Iru1ZuuUxrwJ7DgIMTUvAl -Put EYsAXFfzineGMuNgmU1nxxucQGqUsESp DcHMHtN8mQNHD0WP4BUNMPOcek88VZ6VE0JkXSEMd6VcSpCiUrdtm6TbGg7Cn8n3 -Put jYPKdoadL8z4cget1PrKLPU8UWRokbe6 dleWyzRSUzmwwoKRxPTvbkXCHMjlDDzGoq0RzCWsM7WMX7nwX0KMbfFTNRUFWA4p -Get q7zNhw9GCasfZ4qugUphTroX0Q7oUyDk -Put Ioa534qioFzhonZM8xhcQ5Frimay9eik BClkLNA6oEDkHzNNHkFwFoj3NSE5e8zF7vXDleiP1MoMzfHKZG4dSIvpG2ki7n2T -Put jhcS3sKKBRV19n8u7LQSDVAr5Z4RHejt kYSwL03ygayAqlqHrLjvIyziJ3unUjq5G6NkWjT3t5FhEEMLwG9wIm6sxlzAh85p -Get RYeCkzfwtbsR7ptUdEq4vEaEWJjmWdPr -Get x1yq5klV1akCW6KQUoj1umsdUthVyKWV -Put bYDK3Tcapry4X0Vni9KLxfzO9NKTkMDy i1mUAazw1furvByHGSPJpftcjNQZXDKgqpzjty3abaTGdrvqTx916SX2spaeR01E -Put TazdggjU3tVpdek7bEAd4C2YMrnS1Z0x fZNbF6el9HVfwBmYdgs6EMrzaxywy5HL0X53ffFoomu4JTWsIVemQnOHeLmie2Tb -Get tdFMYxIHsBqgjizlje3JsURSqKwM03i3 -Put j64jz4YzCnb8WrIL9iLA1xgDnzS0Fm73 VZdHe9TiF4w69eeQubVeQvXd2lyXBPLEg02u1xhKbvog3puF7aXbrahak6SyvOIt -Put 6pFWZLEh65qtz2o5vNCk4Bjh9fWkpU1Z pb60P5kMAsQtKB7a5SeD1b3UpCCxKZApi8k9LZ3v35LDaeYlfg8aZbDCG3zmF8qV -Put 4hPCM8lL6oPLN6pcvbEcqe7KRTaLE3QX 9Ej2DNGyxw4nbaVeEn5nraCP52V0iaSZigU95UPfXglqopHDtUbN8f8uUJ9FrdyQ -Get DGXyiNzkW81shwWF0TGC4NNVRR8gUABd -Get DvLYDyVqePwTjH2JZXLPx1efcVikVqQP -Put BtxakyO5Xm7uZY8x5s8O4OgHG2BeMMos s65gSH5hwfl623YGKgdwOwGwiwT82rDSjlJlVeKIEagnKRWKMbwPwDY2rQDGWV5Y -Put ytgfu1gHZDvknPY8pna1LttilDYL7Vv5 AHao3NzQFUKXmVRRdVEevjrYDn1ZagP1vC6wQfPwdPVVlOUtsqFCYeqkBihlix8G -Put ypXFDr2FYMGC4RM19LvRcpWkMl8t3Ibx itu4F1fBKHrxITaTMQvLMUFXNcrrCvLO2Ox3NkffHerH0RCUmrk31zORQI4ecvLQ -Get DHrKdkkFt7hq3blLxgUoIKq1BkulqIoT -Get OZvpuhnrtSSZew0JC4IQXPxVKtiojOsV -Get 4g1Pgm0RI8O67TqB2Td16wFaAhPn1OyZ -Get Zd3iicQbZYmTAUwcpmWNOu3F6lerHPL7 -Get z9MvmGUXy7p3wHxm4kLbxI2klaRU5luR -Get rlQcT0nBdbC07pfPxsXt6CFdHPED8iET -Get x0fGBWutGMBwmlNEW6RjqMHFLuhpmSx4 -Get sbQLCIOspMlg6yQS7SWivdy1QHMEftgW -Get oVGLkcpZcZW8F05iHLuicD1p9FKx34cP -Get 4sJ83XaJcs2EMS1S89DRGROi7Qxc3S9K -Put HgaWhamkO0mpO0yL6yN6y119ItyQVgs8 XoWITBCMnKBp2fT9fq7MalnPnwpvu34HdGx7cVAMVhgMO2AbPvlnLXg8SrRo7AaW -Get PgPCqLGTcyIt9ZYntfJdhalw4TdzCeDi -Put XsliHhtFxqRaw6einjeHGyBIzAgnQnJ5 1y3yhCG9V4hOBz78MDWCPnMx4pdCTPy6SvBAZnr1Rq98YNNkWdNHNRbvk9Fqw921 -Get 1UC4tPWH7Nnspiv5GHNm6V6chrZV9C9T -Put b24GyFlrKjHEMkPmojgTupkLv94T1wQw jUIlP3eHVHdi8eSrGgZx1WsmUjvjV8e4Tadxg0BcF5jZxCTeSKPgDkCGMfA6oKp6 -Get UMLzbJnFsVA7l2Xd1FsdxUXrLNyxAUzJ -Get U4QZPgqj6k0I1B1yuCNiD8b5gIPRcSZQ -Get 3Z4rAcTxILtTvJqciwjxijVzLnyYYNAS -Get s17eNXZDYq6LXy7ge59nQMD8u78pifBr -Put eeJgOnX0D7Ck1sgACPGon52qo9luRwJ1 Mtc9v2reuJjjB6khm8pw3LNvC6CG75Qynct4Io1SyGaBnf4dGUuDO1ke11t1jOQz -Put Coh4QfzzcMqcOrQMWQAkyAD1IiuH1WPH wB3VZyHk8gtQT6opfJxpmXk99nd2QVov9MKdJTc5ePtZkfECBOibBCE3vdMz7WvD -Put QJS58YB1GbvwILGKT6arIVq0VaSuv0ms f9sa6J617mmGhBUvhsa6ZuWhtcUqmOkQECFgeWfcxoRBymdAwv1wQf3s4YWsk8VI -Put m2prxn108ugbVlA1MdR9pnxeIk9mnbyQ lJGZxGdHHSNVAZmgaqGgqJHJTv34AWS9atujdj6EUx3KrWuC3zRcII4BjjCv14fw -Get Fp0iTcxHQYjDwScu5MMKF5nez32gwHvz -Get NMi21oEI3nGrUXRv7BfP7yxqNLEcGdFG -Put 1xDWWBoZX97vKapRykhpxYm8liVrOCRb tLCcKf9OgS8WpsveaN7DmOg3dwgAVbTaBOtNUbehMoKAKiLVv8o3t0ho5fl5Th4B -Put ghPBZV6LSWf6cZDSeKACANaPRREOMmhp jwHQFEbfmFDd6i5AXbp7GzFszK6zJvnIatr61yt3GFA71QWZfCRM2dlAUbwqyshx -Get NPqaDfKkVvhSqR1ukMc2DJpYrPAT4hCd -Put MVpHUvTlGzzDDyoXqhfmXJcJU3NhRtz6 kOAXbXbqED2HJq5lFc30mbpuwDxDE6IeJdp43OOz2As2xMqJo7BtU4PQJiG1E5Vp -Get JxBw06gxuhuaTc50NWJYzRQ5URCehVmC -Put oeGrtFzhU0pNrd4pRIE4xA1B3K17ZaA5 mR9PkDl7lf5WCFehkvroF1HFhbDPdxOROHlqLy6qp50HAJkERjYqOPp2jiCBOf8B -Get tQyMBLoR8uYJgpWOZoIjZmnIauqn2CRk -Put QdnwRxb88DrmCTnYAMur5CQgxnQLSu2P f2w2XsCzt18zdJvDFPQ8dJr1pbJpqU2cCZuHcpN9MH1x90XhaoV8oHM4YlCUMxyp -Put 1AOlf4dFXSyHby8L3bB02zlkNWzPBzvd xCYS9g1EEAZbpkGoDbR3xxlWXs7DJQWjLrYesnmPHVemJIfvvvjXAN0hJGOZ7CI9 -Put VyD9qO4N92XdLz2CGRFGbirZhW0h4Ac2 MHsF41DLBOdLc7iEQNVOyla75o6bTyJspaEirUtAEe9XWL7RyrH6KlGdZS9IZI1S -Put zr13e5LGSdckVzdyQliJbij5DoOfp4mY wNHailOlkfuceyrnvbTMObJRJZERFyBuLxqLAfvSkwyH9F8UEwDIK5QuZVaKZiSG -Put DBr5sPG84r5xW6BewbF0kxNgK4EjaU11 QimgwDgV3D4jOyZz5kiqgiwdQm5GaQfeEGZfbZJRkiT3aMOGTBKvM19609ShlF7w -Put aFFtW4bBRq92M1jL017zPbM61FdaMHG1 7rs7aBZKgMAdNhwfl9skNwQxLd92GFrXvyKtEl0XPrxzEgfhYZf6ZlQfM1HCe831 -Get e4ypGjZ3nKxd00l5o1FJbO2Kn06Im8ZL -Put RN7CMlvyEcwg4xZTcxOrBBcBSkw2wrwz 293DLjHcOmxPhNsiiIYvoMiUwvoJ8bmBLpk8dHNk8EoydYcZBIyXqFrqrjcY6tVn -Put 49VpNRMyvfZNWSppn4PoIFVAqmakgFz1 1NNZkjF6iCWxjLrcGEzcKgBhD5NB5kbJ8j7wD8iMJ7qczX7P1DoYTMpIURRfbudM -Put pZiRakAeDGKMI3cOsHEJ4Vphg0MNjaOa 5lFa8HWMQsSGoDSujsd1JcUdHaDKl9jEN6LNfx7M5RDTVBVrVSItK54vlLsn5Lm4 -Get fLelv1vXEcTyOVYuCeRrM0EnlidplQIx -Get 8PYoDJfZaiQm1bV8sWiZQY7wziHia6uY -Put HfLoxm3eL72giJqs0najUBlbPCMY5ryJ C2r6qGO0jEWkaWVFcIAYxWTlUMrcdlWqeBFQUduGjdR9stBKY7D8cpashP3Vp0TM -Put 6nCDViYkemgnAnVhOrFlj84lQLkyHHGU 1N3WDLJDdOc32ycI4XTcSH1NxVAsu73ABK4gA37mISgv2cqXpbnASlmyIesaRSnW -Get Y7r8PHrGDYE0duooa41OT7SysDAfRbV4 -Get 7cDmNcFepaj9jF1ViJtazj8g1ubfgdJk -Get E41jN2iTpntZxIwvanZhS9vrfaM3SEEp -Get HRJo8lvgRacT4UpdkwBqmjODIYzcQCFD -Get k1sDsLyOwPcXKrnrsXbcNXNRW7TWMpjV -Get AqYN1tlSHXi6Roe4CbYSzVyMB5HSmoo6 -Get bu8oq15iR2zYPviFFufmKAxmzapEdPHt -Put LHCLEVJODnHcLwdUoDS87TH3QWJfuLcs PUKwdbM0D6bpHdoGTdF0lgKjvvDH5kB63AwiOvSfUIZkdnWCEBtlcKwlnRtDBeG4 -Get 91gEunNoDdkqCiNIBKKLxN0h9hIcEtXg -Put Kbg4eicDIQyqtwQMtfMPqy75dI39VQTb hA2vW3fb011J7Peo6Nk6vo96TfM2TQ7xg4AViu8fqLx4D4vIhhsoIOPz6tr4mgv3 -Put PqKPeCFqZC7gCnaWFPNlAS5Dqqdong0b 4B8AvemhHozRKBdpIVhCzFpc9iX95JrRjP1XkX8rcous5FCZQ5yMCK5Rd2PeIVxU -Put 6vEpC4DOUMvyyP3rgeFtTnOoYcWOeUjx EJgaBQRAplTNWrRyWV0mjtZ1vsnOeFIo6Y1WazvZWVgChTqr8PWYZeJ1BJyR4kQe -Get vVgJfDNjpfTwIMbDhU59rjS1YC0eiHPo -Get WEhWYirCeyF9cLsuQamWHn7TZ2moPa98 -Get gd2qWsvYdKuzBlfkfgFJq92piuwOm4fo -Get L9guYD5G14MqqyVSLZB7LHUMcAuE9OsG -Get HsIUB0sQtegbkK7mM9jmJGeogu3UyLn0 -Get Zpzg588tfuHhleTHWRVEH55zY5CntIVb -Get Za2vCSvPeEq8W3ke0ddYEgihdsNjUChA -Put fRaz8skEtJE9mJc5pAWOYBT33cOsrewC cWL2TnMrmg5HZOHMBuYQnoQJou77cRNTWlIAmtQC1h6BFezlbX0HQW7ELSresn6R -Get nHoCTIcnox9a6AhUECp5JQy1W4aA7F8f -Put w3AYqZLwPQ5GSB8OWJDmWGpAUDOrFNsD M8ifPwlU5TvAbzNmdeH8KorCMCQk0gHLr4Cm8E5wcgDFEHeKZ8WCZxEgV86me6LT -Get R6VcfOkpiNA3E6wwqL9Czu3BhrzR7lNK -Put Hi6yWgZmd5yeNuxgKrCdyyyH3nVwGYxJ OszU8JfX6JLfBq2eYEMOyJ87XrMwvU8u63cnfnUdp1I7C01nDuVKbp6Tyy3M76Zg -Get Z5E5SioF83c6baYinklL9J7eeGhM1Xww -Put lTTJP1IiM7VhCSbIoV9i2vmRn9CZCbHe E15b6aVSCgI4vzK7eNwHxuAHtLLpxMSHjoPKjSJ8i1Jq5cHmebs10aCxcH0jASJD -Get rLFVqu91xkOVxPnabs5ojn4IKG6fCaoe -Get W5znsqW5Epqyw2bQkiIW02imBGsuQoZI diff --git a/test/mpcal/go/concurrent_replicated_kv/main.go b/test/mpcal/go/concurrent_replicated_kv/main.go deleted file mode 100644 index bb71eb688..000000000 --- a/test/mpcal/go/concurrent_replicated_kv/main.go +++ /dev/null @@ -1,386 +0,0 @@ -package main - -import ( - "bufio" - "fmt" - "io" - "os" - "replicated_kv" - "sort" - "strconv" - "strings" - "sync" - "time" - - "pgo/distsys" -) - -const ( - MAILBOX_SIZE = 1000 // message buffer size - CLOCK_UPDATE_TICK = 80 // clock update 0.2s - - CLIENT_POOL_SIZE = 100 - CONNECTION_TIMEOUT = 1000 // time out RPC calls after 1s - - GET = iota - PUT - DISCONNECT -) - -var configuration map[string]string -var id string -var role string -var selfStr string -var self int -var connections *distsys.Connections -var barrier *distsys.SyncBarrier -var err error - -var spin distsys.ArchetypeResource - -// connections to clients and replicas -var clients distsys.ArchetypeResourceCollection -var mboxPool *distsys.ResourcePool -var replicas distsys.ArchetypeResourceCollection - -var clientId distsys.ArchetypeResource -var clock distsys.ArchetypeResourceCollection -var lock sync.Mutex - -// replica variables -var db *distsys.ArchetypeResourceMap - -// storage check mutex -var mut sync.Mutex - -// continue ticking? -var tick bool - -// change to run every command in a separate Go routine -var concurrentMode = true - -type Command interface { - Run() chan bool -} - -type Get struct { - key string -} - -func runCommand(cmd func()) { - if concurrentMode { - go cmd() - return - } - - cmd() -} - -func (g Get) Run() chan bool { - done := make(chan bool, 1) - - runCommand(func() { - resource, handle := mboxPool.Retrieve() - defer mboxPool.Return(handle) - - mailbox := distsys.NewSingletonCollection(resource) - mboxAddress := (self-replicated_kv.NUM_REPLICAS)*CLIENT_POOL_SIZE + handle - - getKey := distsys.NewImmutableResource(g.key) - response := distsys.NewLocallySharedResource("getResponse", nil) - - if err := replicated_kv.Get(mboxAddress, clientId, replicas, mailbox, getKey, clock, spin, response); err != nil { - panic(fmt.Sprintf("Get error: %v", err)) - } - - // Read without Acquire because we know `response` is not - // shared - response.Read() - done <- true - }) - - return done -} - -type Put struct { - key string - value string -} - -func (p Put) Run() chan bool { - done := make(chan bool, 1) - runCommand(func() { - resource, handle := mboxPool.Retrieve() - defer mboxPool.Return(handle) - - mailbox := distsys.NewSingletonCollection(resource) - mboxAddress := (self-replicated_kv.NUM_REPLICAS)*CLIENT_POOL_SIZE + handle - - putKey := distsys.NewImmutableResource(p.key) - putValue := distsys.NewImmutableResource(p.value) - response := distsys.NewLocallySharedResource("putResponse", nil) - - if err := replicated_kv.Put(mboxAddress, clientId, replicas, mailbox, putKey, putValue, clock, spin, response); err != nil { - panic(fmt.Sprintf("Put error: %v", err)) - } - - done <- true - }) - - return done -} - -type Disconnect int - -func (d Disconnect) Run() chan bool { - done := make(chan bool, 1) - runCommand(func() { - disconnect() - done <- true - }) - - return done -} - -func init() { - if len(os.Args) < 2 { - fmt.Printf("Usage: %s processName(processArgument)\n", os.Args[0]) - } - - id = os.Args[1] - configuration = map[string]string{ - "Replica(0)": "127.0.0.1:5555", - "Replica(1)": "127.0.0.1:6666", - "Client(2)": "127.0.0.1:2222", - "Client(3)": "127.0.0.1:3333", - "Client(4)": "127.0.0.1:4444", - } - - if _, ok := configuration[id]; !ok { - fmt.Fprintf(os.Stderr, "Unknown process: %s\n", id) - os.Exit(1) - } - - ipPort := configuration[id] - role, selfStr = distsys.ParseProcessId(id) - coordinator := configuration["Replica(1)"] - connections = distsys.NewConnections(ipPort) - barrier = distsys.NewSyncBarrier(configuration, connections, ipPort, coordinator) - - self, err = strconv.Atoi(selfStr) - if err != nil { - panic(err) - } - - // archetype resource functions do not spin in this context - spin = distsys.NewImmutableResource(false) - tick = true -} - -func fatal(msg string) { - fmt.Fprintf(os.Stderr, fmt.Sprintf("%s\n", msg)) - os.Exit(1) -} - -func makeMailboxRef(name string, version int) *distsys.Mailbox { - mbox, err := distsys.MailboxRef(name, version, connections, configuration, []string{id}, MAILBOX_SIZE, CONNECTION_TIMEOUT) - if err != nil { - panic(err) - } - - return mbox -} - -func waitBarrier() { - if err := barrier.WaitPeers(); err != nil { - fatal(fmt.Sprintf("Error: %v\n", err)) - } -} - -func parseCommands(defs []string) []Command { - if len(defs) == 0 { - fatal("Clients need at least one command") - } - - commands := []Command{} - - for _, c := range defs { - fields := strings.Fields(c) - - action := strings.ToUpper(fields[0]) - if action == "GET" { - if len(fields) != 2 { - fatal(fmt.Sprintf("Invalid command: %s", c)) - } - - key := fields[1] - commands = append(commands, Get{key: key}) - - } else if action == "PUT" { - if len(fields) != 3 { - fatal(fmt.Sprintf("Invalid command: %s", c)) - } - - key := fields[1] - val := fields[2] - - commands = append(commands, Put{key: key, value: val}) - - } else if action == "DISCONNECT" { - if len(fields) != 1 { - fatal(fmt.Sprintf("Invalid command: %s", c)) - } - - commands = append(commands, Disconnect(0)) - - } else { - fatal(fmt.Sprintf("Invalid command: %s", c)) - } - } - - return commands -} - -func disconnect() error { - return replicated_kv.Disconnect(self, clientId, replicas, clock) -} - -func clockUpdate() error { - for tick { - time.Sleep(CLOCK_UPDATE_TICK * time.Millisecond) - - if err := replicated_kv.ClockUpdate(self, clientId, replicas, clock, spin); err != nil { - panic(fmt.Sprintf("Clock Update error: %v\n", err)) - } - } - - return nil -} - -func initClientRoutines() { - // set up ClockUpdate routine - go clockUpdate() -} - -func dumpStorage() { - storage := db.ToMap() - - if len(storage) == 0 { - fmt.Printf("Replica snapshot: (empty)\n") - return - } - - fmt.Printf("Replica snapshot (%d keys):\n", len(storage)) - keys := []string{} - - for k, _ := range storage { - keys = append(keys, k.(string)) - } - - sort.Strings(keys) - for _, k := range keys { - fmt.Printf("\t%s -> %s\n", k, storage[k].(string)) - } -} - -func main() { - // if role == "Replica" { - // f, err := ioutil.TempFile("/tmp", "replica.prof") - // if err != nil { - // fatal(err.Error()) - // } - - // pprof.StartCPUProfile(f) - // defer func() { - // pprof.StopCPUProfile() - // fmt.Printf("CPU profile saved at: %s\n", f.Name()) - // }() - // } - - var commands []Command - - // parse commands immediately to avoid finding out invalid command - // after all processes are up - if role == "Client" { - reader := bufio.NewReader(os.Stdin) - defs := []string{} - for { - line, err := reader.ReadString('\n') - if err == io.EOF { - break - } else if err != nil { - fatal(fmt.Sprintf("IO Error: %v", err)) - } - - defs = append(defs, line) - } - - commands = parseCommands(defs) - } - - // set up connections - clientConns := []distsys.ArchetypeResource{} - replicaConns := []distsys.ArchetypeResource{} - - for _, i := range replicated_kv.ReplicaSet() { - replicaConns = append(replicaConns, makeMailboxRef(fmt.Sprintf("Replica(%d)", i), 0)) - clientConns = append(clientConns, nil) - } - - replicas = distsys.ArchetypeResourceSlice(replicaConns) - - resources := []distsys.ArchetypeResource{} - for _, clientId := range replicated_kv.ClientSet() { - for i := 0; i < CLIENT_POOL_SIZE; i++ { - resources = append(resources, makeMailboxRef(fmt.Sprintf("Client(%d)", clientId), i)) - } - } - clients = distsys.ArchetypeResourceSlice(resources) - - // create the mailbox resource pool if we are a client - if role == "Client" { - j := (self - replicated_kv.NUM_REPLICAS) * CLIENT_POOL_SIZE - mboxPool = distsys.NewResourcePool(CLIENT_POOL_SIZE, func() distsys.ArchetypeResource { - r := resources[j] - j++ - - return r - }) - } - - // wait for all process to come online - waitBarrier() - - if role == "Client" { - clientId = distsys.NewImmutableResource(self) - clock = distsys.NewSingletonCollection(distsys.NewAtomicInteger("clock", 0)) - - initClientRoutines() - - ch := []chan bool{} - for _, command := range commands { - ch = append(ch, command.Run()) - } - - // wait for all commands to complete - for _, c := range ch { - <-c - } - - // once all commands are finished, disconnect - disconnect() - - } else if role == "Replica" { - db = distsys.NewArchetypeResourceMap() - go replicated_kv.AReplica(self, clients, replicas, db) - } - - // wait for all clients to disconnect - waitBarrier() - - if role == "Replica" { - // print the storage status if it hasn't been print before - mut.Lock() - dumpStorage() - } -} diff --git a/test/mpcal/go/concurrent_replicated_kv/replicas_out.txt b/test/mpcal/go/concurrent_replicated_kv/replicas_out.txt deleted file mode 100644 index e8c86f055..000000000 --- a/test/mpcal/go/concurrent_replicated_kv/replicas_out.txt +++ /dev/null @@ -1,138 +0,0 @@ -Replica snapshot (137 keys): - 03TC5FpXEVO8qgg9hCeQaZjp3yKFWo7h -> nlvnSSJnN1WxsbbJLkywQ8Lj2U8PICr9gFx1wyxpW2s3gNumx0yowFVZ0TIreJTO - 0f8EXoSL1lx87qXqgZxfkE7PMmJNcVnu -> 4t1jMJVNX9lbelKP2FTZJngRu75VjHIVr8U0hTXgZ0SFkeOL0Xn2h2NEikzKDmyC - 1AOlf4dFXSyHby8L3bB02zlkNWzPBzvd -> xCYS9g1EEAZbpkGoDbR3xxlWXs7DJQWjLrYesnmPHVemJIfvvvjXAN0hJGOZ7CI9 - 1M2QWT8JifCOEOyRyLfEbzhfZQIV0zrD -> coSfNXffL9wVfchSAoh6N8nHznkTVr381IOu7ylR4wJbOZVIT9ULODXyMN3bAnVV - 1R2arsoAd7YPDjMJD4Wxh2fMDalpIJ9K -> jx8UYce39Q7clv4H1Zo34iE2tIOE9NwH2GmquOj95y69QjBU8vv6CVwiq5Lm36mx - 1xDWWBoZX97vKapRykhpxYm8liVrOCRb -> tLCcKf9OgS8WpsveaN7DmOg3dwgAVbTaBOtNUbehMoKAKiLVv8o3t0ho5fl5Th4B - 2b3CVX2mh52MYCJq52holiJOIdpCImRp -> 47gzV47HUg60SYId9kxMUJFbQ1F6nCeUeAkf3DYSdx7UZ2lnPt2gQxniNhnQEZkW - 3PnjLMKV8sOqaxNmgDHEN8NftfuOgqZN -> oG5bmlW8OMpLPmgnPTVySIzYYmUroFwiQ1n5Yo0zPoskT2IURg6N3SEsLjJCjg4x - 3XH0fJMmtbfCwD1DcPzqBeIRBsPEhW9A -> Osc3Wrqn36nkZLiVucni7uic4y2R4goxKyK9WwCC1GHrUt9x9C2ocJwY85VLL57N - 49VpNRMyvfZNWSppn4PoIFVAqmakgFz1 -> 1NNZkjF6iCWxjLrcGEzcKgBhD5NB5kbJ8j7wD8iMJ7qczX7P1DoYTMpIURRfbudM - 4A1hyjkYeS0eXPNo6DCcvSoQrKLON8NR -> x66c5Tilf2REw8Ju0wAnpdLHCtNZUDQEB5HSOIyCZNmWOSWbRm5zu5DfaMf5RXuc - 4hPCM8lL6oPLN6pcvbEcqe7KRTaLE3QX -> 9Ej2DNGyxw4nbaVeEn5nraCP52V0iaSZigU95UPfXglqopHDtUbN8f8uUJ9FrdyQ - 4ywRlUlvYh6UbJ6LUTtQ8gKjYAjRDNEi -> 4Zvvb2Rp7n0epfarBSUZYyKTOFMH2MdpLvuoEOoLBWdcIN7zjqUYS6weA1dkUw5f - 50ITnTKK6vQAkeh7T9ad6guuK0FwiiT6 -> yGEMlAP7dpUDBqA1Fae0NxvAfnCIRyqx9rXYew3LTxVrXZss2eSeFmEF7wUFMVQ6 - 5wc98R2QU3p4ldoTF1Fy5yXCFqF0Pw8m -> y6F7ZgCieNlUx7XaXD2RvW988P1GvxTnM2M1hhb3xD1gutxxCm42JUaLwwgEcrfZ - 6ijXXIvrmIVkamDOEIeLLfBLEQatTOlj -> 6OlnXlfxQ43bvLe15TopoKOA4emxzMCaG8NfnlNOHAjAQMfyBfBvVekYcuaXYQWM - 6nCDViYkemgnAnVhOrFlj84lQLkyHHGU -> 1N3WDLJDdOc32ycI4XTcSH1NxVAsu73ABK4gA37mISgv2cqXpbnASlmyIesaRSnW - 6pFWZLEh65qtz2o5vNCk4Bjh9fWkpU1Z -> pb60P5kMAsQtKB7a5SeD1b3UpCCxKZApi8k9LZ3v35LDaeYlfg8aZbDCG3zmF8qV - 6r7qQ9vheEfGe5DnDJD9U4ZK05fWotZl -> g5IL0DtJJ7ZPx8v90L0Daltl9pFquNJx6pINKYWUeQ0bVvIguBfCJ0y1BCTP5cCx - 6vEpC4DOUMvyyP3rgeFtTnOoYcWOeUjx -> EJgaBQRAplTNWrRyWV0mjtZ1vsnOeFIo6Y1WazvZWVgChTqr8PWYZeJ1BJyR4kQe - 7eMPCljnoK0fAH6dsPv5D8GWxAWQlujW -> 7vTOzwQ0QZK4TPYAixouqpBerD1l9Oz5N2Aw4bAamm0SWdd5t7Cmuet8Q6T3ZUK9 - 8FYuIv0YYtUMBwhdVjULmbilArf7Yw9s -> uWKkb9RJO06v1tu6UfwzUfRX6AAmxXsQsZGc1gZvsZrCFZqaFIPD5o4fq0fhLBPe - 8MJeUclqiAWVT7e0karYXhsMtyHe1SBi -> txudMF4cpHONLo7k6pyQkTP3gNWdweBQtnvwpQaSB3ECOaNouhpGCrKfBWzhSSbe - 90DpqkWyxzywWBqBVJxWgF3E4W1DTeKm -> MSbQBQoNaBqoCZobWO7G3Ytn42sH7Y3VYrygqsqx3rEaMMzF9XDAD52Z4Jk2g00r - 9W8X1PPPnrscCxnn5NjpjizvMaxr2hwj -> 4WBGvggR4L8x77zjk6oh1NPLgBUWV07Kwo5XewWgGdHrqnkIvYcw7Y74VYlv2ZQF - 9opIfQPwdqBBvHc40KqP0CN2irllkoGg -> xca8A0QzbLKu9J2Su3L1aFog4LY4z2sHaqQsVKqMkUkTOxbB7tBZiINzmkvZnKSe - Avzj5eFCttrqAF6EzobsNocuhN4ooB3T -> RfMjvc2QSlSr3UqrEubTLAFqt0PoJpuM5sEejOnsJnOPSboRKwxRdU6693qDJfBY - BCesKJISzeQwjzg7c4z8izrQzlsDs7zr -> QvSVrJk4Wsd8Z3j0FpXiRR2akVN6MkjM8ifie77Tz2GeI6pJmP2ctlimx2isBvsz - BtxakyO5Xm7uZY8x5s8O4OgHG2BeMMos -> s65gSH5hwfl623YGKgdwOwGwiwT82rDSjlJlVeKIEagnKRWKMbwPwDY2rQDGWV5Y - Coh4QfzzcMqcOrQMWQAkyAD1IiuH1WPH -> wB3VZyHk8gtQT6opfJxpmXk99nd2QVov9MKdJTc5ePtZkfECBOibBCE3vdMz7WvD - DBr5sPG84r5xW6BewbF0kxNgK4EjaU11 -> QimgwDgV3D4jOyZz5kiqgiwdQm5GaQfeEGZfbZJRkiT3aMOGTBKvM19609ShlF7w - DOr2BOnWGATILeGTaMZREaRCk5QvfkUN -> laEblvLgQ1Y26o16YfoANjayqGUoDZhHcJGwH0wpKJRLLC853LfdMds4VbA951pI - EY9Ps27MrUqh7bLoolCvVtfmNT4GYQHv -> 4lpi9lwPGDxi0F12cld8NVv6P7tHvsHG9A6YdY3Ow6cCa1CkPboR3STlFKvN5H0R - EYsAXFfzineGMuNgmU1nxxucQGqUsESp -> DcHMHtN8mQNHD0WP4BUNMPOcek88VZ6VE0JkXSEMd6VcSpCiUrdtm6TbGg7Cn8n3 - EZJwNJR8T7OmGRZak9cJq5ktK2SAORy5 -> ahPenvGom2gUeE2egO9gVpaHS0H8wvGUWp9cQCx9q3qVKFqIUOZqBAa2DCml2JRQ - F4fMBDdsTCKQaM7LESPL9QQhlWnt3QS2 -> Zn7A0JdWoGeqd3QxkycyvBW90fYSiP24bf1O1QRLclJaULqZFYHMVnIyhK1edFRm - F4yu8GUypdEGTy6r826mnMAz3kOwXRxv -> 4DdnEHyjFeA1LsPDgFHs0af9wM9w7H61AuPEdNboBhLusgC65fiqQv2yUtYAnXQs - FU5EZUHPD17u9ufF1gGTcd6ib7uBc7Yz -> mlaQma19uyUlMb2ug2BijlE1SOqTxs8tW58I2k8s7BTHRAc1Kt5OIOTSpiWf8IWa - GoRGKnUPn75DPH4pDqkECwEtCWUprip0 -> MD25LlT1fWgqrEunBnmW9eagK2O7pNQESQPPyaBlh2xvJS3ROMPihCPNw2F1KiMB - HfLoxm3eL72giJqs0najUBlbPCMY5ryJ -> C2r6qGO0jEWkaWVFcIAYxWTlUMrcdlWqeBFQUduGjdR9stBKY7D8cpashP3Vp0TM - HgaWhamkO0mpO0yL6yN6y119ItyQVgs8 -> XoWITBCMnKBp2fT9fq7MalnPnwpvu34HdGx7cVAMVhgMO2AbPvlnLXg8SrRo7AaW - Hi6yWgZmd5yeNuxgKrCdyyyH3nVwGYxJ -> OszU8JfX6JLfBq2eYEMOyJ87XrMwvU8u63cnfnUdp1I7C01nDuVKbp6Tyy3M76Zg - HtIbAAZ1Ag9Ay44o0eF7zfrkPx45VC6r -> OISZEqf9Gq52d1iR91fbndMRFRtXaHtTFYKovfREPTG2nytAHwSXUeK21vhvdwz2 - I9oEjcthDFjUoj47UBYxtOuneNh1qjuX -> FRdnBLcSUxqVpnKtcFB8CqNzGjOr2uh852wOxkHHpairMWWME4ssNeM8aXzTCuJv - Ioa534qioFzhonZM8xhcQ5Frimay9eik -> BClkLNA6oEDkHzNNHkFwFoj3NSE5e8zF7vXDleiP1MoMzfHKZG4dSIvpG2ki7n2T - J2irx8YzGxD9NJ2TXb0G9wNDP244y6Mb -> VI4g2f8eiSHAdQ5p0awMvr9s9lMZkHVOV4ey2LfuiFiIu3ORPzlxxG1rAVrCfiG2 - JfjT2n1JY36vtg85yTy00dvdgvYV0bO3 -> o6JQlR9wilbdpXXFYCGcasXrzLmEjl0DehaYuZr7SODChqdwKC2n9SZFGMViOHfS - JtXZSGXQsotZMQncQjwH19CXkQyQQTRS -> pRG1Goiw5CnApU2rU6yUWRLZGRNuwHzax0NrTY0ydBjWBHGLYFZvQhYTdBYvoUXY - Kbg4eicDIQyqtwQMtfMPqy75dI39VQTb -> hA2vW3fb011J7Peo6Nk6vo96TfM2TQ7xg4AViu8fqLx4D4vIhhsoIOPz6tr4mgv3 - KkQXql4CeaJhCz35jJdhXSf1bW8cB5Tl -> 2B1fE8XT8ad4hqNHCpYCcjstknGd3goHmPCIr8yyHMqXYshB8XZnP7qEzP0PGAZC - L9QLjg6RhDCc4wpZLsKBVt8vRsebGDDJ -> nafu34cWxMf5vyesNU87EM3KL1Ps9IpjQtOmIqrsHfNKBzrzzjrRmcg78y3THPzC - LHCLEVJODnHcLwdUoDS87TH3QWJfuLcs -> PUKwdbM0D6bpHdoGTdF0lgKjvvDH5kB63AwiOvSfUIZkdnWCEBtlcKwlnRtDBeG4 - MVpHUvTlGzzDDyoXqhfmXJcJU3NhRtz6 -> kOAXbXbqED2HJq5lFc30mbpuwDxDE6IeJdp43OOz2As2xMqJo7BtU4PQJiG1E5Vp - Mm6gqQ9sLUmI87xcIUnWCc1WrJf9lYhX -> mWf0r0vcs5MILFfx5XoqIgQiHfEnvjbOjgquMPGXDAYAHOVy1oRCI2QupNCKQkNp - OMuzbQdC3554tI32JX5XqrBy5L6cXDWS -> iRpfKMHoQN51zNM6jcDh2oBPrla3Vph3AWbLmpkaYSODTc9kofJ7m6q7F2Q9In6U - ONzHZmxZ7zkxvICTQkHbZTtwX3lk3mDO -> d9jriT2Y08jGo87LSm1FHdtnQcbqAgwHbENhcHki9ymvpjnuK0Wj6HyML8diKIZy - ORktdd1x6fpyG9AiUDFgCeJbB6IA8ki5 -> ZNn5nQUUehQW4u1GTBwjpcWFQBBbexpl48dTcKumfCuQVP2gLnP9tgNZepDNdCvH - PXdYIMUA9DdtYji8chuZ2Z7uXvxWG8jg -> LM3k0ERaexBGmFpSPfhOlCrGqiHkrsN50vsluxgwwxNtbdgAN1UB6c14rGtrWpfJ - PlyfbDIfcdKC2O4msPhNqqGoH08bM0cX -> Zb4Ra3ttWU7SW03EFJiwZIr6RzTeo0hJeQD9HYSJx3zaYllb2SzSu10f80qOe8NX - PqKPeCFqZC7gCnaWFPNlAS5Dqqdong0b -> 4B8AvemhHozRKBdpIVhCzFpc9iX95JrRjP1XkX8rcous5FCZQ5yMCK5Rd2PeIVxU - Q2iWNZAx9jJeEsQuJ7g9OeUXyvDR7sPZ -> C7UhUGNdvyj1jfGkfr5JCJgtWiRav5lqZ54BZWPI6Mx8XqotKYydlnsSL4ckRSoQ - QJS58YB1GbvwILGKT6arIVq0VaSuv0ms -> f9sa6J617mmGhBUvhsa6ZuWhtcUqmOkQECFgeWfcxoRBymdAwv1wQf3s4YWsk8VI - QdnwRxb88DrmCTnYAMur5CQgxnQLSu2P -> f2w2XsCzt18zdJvDFPQ8dJr1pbJpqU2cCZuHcpN9MH1x90XhaoV8oHM4YlCUMxyp - QrvyHezLniuraGk4Qr9VrPuJanFdur87 -> rLqWzlBmCzoQR6T0Bz3Eerjz1O8aAnkPbhfdNXsczhuyo1sx6yPw2moZFiSLCmj6 - R60QZPVLfVMq0f2ahoARBpNHyYpPDNjJ -> WqKd1I42hyVpjFWzCcZyvRakHM9uNDaB8ImW5aNmweWIpJ8wuC4aZzbcwl1kkct4 - RN7CMlvyEcwg4xZTcxOrBBcBSkw2wrwz -> 293DLjHcOmxPhNsiiIYvoMiUwvoJ8bmBLpk8dHNk8EoydYcZBIyXqFrqrjcY6tVn - RmvbDARSTGu92uwlGDzaOmTYfk3YxIcX -> zTZ0vAVbsZegXOCxUpW2sFvx4qLQKvqTJNAqAt8mQEW42LvGfErBD9zXXD37B8KY - SIK3nxTeNS0Vvd1VeEt0GH5huHnPdEO4 -> D7Q0Gv9tn96J3zRwc2fnZJOQzC7WMJIDpnXOqSkrehxzEZUxaoLo9Z3CZjRVnBLP - SKcnsxgqYmiEAeYlNcOQba98G32a1znu -> vj9lzqZhuyOHhpMwarVZnTmZaIDkHG5r2RlFpPsOa7ORBPERnixBx5k9OcJQgJ2t - SaGqNG8Ps3Z0PmYq5GVjijntYckVSUpJ -> kGFymhpSQuw672RFeAAMhgm6YhbppnVFveIC1Q3h794NFNwNQ4uylL9DIhPpW5Mr - SwAp6z3KP6TrFFBWXOeFg09mj1dDGdJb -> vTbg5HAh8gISZzZIf3DAdvX149il8iYsFexa883rrCXtv6MLuZ70yytUwPcpNAjH - TZbNgyvDHQpWXc650Xedq4k7i4CdJU5p -> LNPLpRuXIuh52mcxiJoG3vp6epah1EtvFr7h8E9q5V62BB36A7J9My716KN38tKu - TazdggjU3tVpdek7bEAd4C2YMrnS1Z0x -> fZNbF6el9HVfwBmYdgs6EMrzaxywy5HL0X53ffFoomu4JTWsIVemQnOHeLmie2Tb - UKlazMCQmurMoj1gSLBYFACmGBT48zr4 -> svfxPjeqTmFYRASxz8QFANe11eVNknib5scBYb8lovSNr1zQjQzrXRKeNgA7mCP5 - UiPQk3eTYKeesAOf1TaUPympHJsopBTf -> u3iqKr6X0vZE2wr0emx4eh6i5FD1JOG2aFoph2nsa1kk5M7ZkjFtbyIaewi5UTAs - VrFHiBTE3oZ98lDoyYHu1njBB6DMzAap -> 4l9WMFGRq5FftgRKI2Zm45ww0cUzMfh7xfJqkv6UzP8ib6aHKGwqpyYwPfMWkW1d - VyD9qO4N92XdLz2CGRFGbirZhW0h4Ac2 -> MHsF41DLBOdLc7iEQNVOyla75o6bTyJspaEirUtAEe9XWL7RyrH6KlGdZS9IZI1S - W2qNjUMks5LkrwnfSXcHOuwmCx0hl6wb -> nrAJaImFQD42zHcWVWL4XnpoPjoGzjmhoynIT3svoSonz6PfPtxJV7chnyPg87kF - WPvpsbo1PSglNWRCKwCC9slPzBJuQoTj -> NMJCfyh9AgfEToZ0XMfTwzE52n3HFlk0XZmJiVTQXXS0AWPGl81fhwh8msEbCRvX - WaaaDNFaIbT8I49xxFOFHCgA29dJMAiY -> K4USbwF0PJBDnx7ycAzv5fM5FACquXnWs6WUzqtqaoRWD37HB9RJsn9bv846yJgv - WhEDGf4h5qFfKVZ2Vk83vmwdthK0H5Li -> tA1AtdQ7qwtxqpfZyspjIETwiquMM8ZwGBb2DXod8mPxQOssAnEuIak9iKMRidEq - XsliHhtFxqRaw6einjeHGyBIzAgnQnJ5 -> 1y3yhCG9V4hOBz78MDWCPnMx4pdCTPy6SvBAZnr1Rq98YNNkWdNHNRbvk9Fqw921 - YHszXLLP2nYsaxUEfUl0IsxZah1uy9cM -> lQv0OFa5DI9jeZbOoYpyFRzK9sJNsB7eZ6d47MGRtq95uNfwKH5haDhLoaCPHdrE - Zdkg4YRRT6S6goezb03BMHmAyihJBKx1 -> Z0GdML7ma6mNB2mkYg8YRYxATQLfTseJOh16WGkuN3Iru1ZuuUxrwJ7DgIMTUvAl - Zk5BaMU1IrLFTGXf8Ck9jzHt7KgosyjB -> ILr25wFMfr3gaEDdIPggLpDu95j96qis4gfd0vyvWFSefEajh5z2kHMpIGXV7nNv - aBt5rlDv6OsoGRSkIRnv60NW5x5Jayle -> esEBJ2NrTWJe8VaHd1ammhHSOSa1IFEbTGRim5gYtRgeHHoCdBOcddYFTwE96r57 - aFFtW4bBRq92M1jL017zPbM61FdaMHG1 -> 7rs7aBZKgMAdNhwfl9skNwQxLd92GFrXvyKtEl0XPrxzEgfhYZf6ZlQfM1HCe831 - aFx1GPILUtL8PUu9erfQugDnVbqJYDPJ -> 63Lw4J8Ou1lj4cScroxePUwmDDmQnSVRhcRiM2ARZYk5byLBZZVatBcmeFE4XGLd - az3XeVpATQ5rwh7UnRQvTpMBrkHRrgWj -> kveIZX31p2DseNGbF3RL5sisOoB660n0JlKcZmAqCMSqBoQV4s2sZOjItaCDm7kv - b24GyFlrKjHEMkPmojgTupkLv94T1wQw -> jUIlP3eHVHdi8eSrGgZx1WsmUjvjV8e4Tadxg0BcF5jZxCTeSKPgDkCGMfA6oKp6 - bD6qrgEuGhq5CQHSTOdmFCBIrwZpJDKa -> fD8DMvngfx9VKraIM8cAktZUS8sHqSdIWWOS9QXtozsinviWJQb1hk3n6XMyqyyU - bYDK3Tcapry4X0Vni9KLxfzO9NKTkMDy -> i1mUAazw1furvByHGSPJpftcjNQZXDKgqpzjty3abaTGdrvqTx916SX2spaeR01E - bZt4UbXcpJiS4gISyFWyJdId4U0uyjvR -> alQyJ3nhfdLA8dgEmMhnwJEsQs4z7wiryhszWpgYoKJOt67vjYGjIskVWg9jkxpD - cltWsGydp9xP5wUDRI3eOrsExsfeS3ga -> EtV3e1TSBxoBjMS7MdCByGSv1GvhhL3uRc5odj7oUcOEamv9iqWAyeyGFpYGw1PV - ctdFDDFUPf5WRSqmpBDqWqeK5LEBNJFw -> wM9vRHJIagwpMVJW7i5Vk5MMfHNHrdNyqqCNKAi8avI32NlcBSlVym2AFzpnhLzm - cvFNCELpLbynm8sZ8VoOFQrDOC3nsDe5 -> Vu4SEc9jb1Kx5wufXsyCzrAguoittKi9Ib7bsrPb5eePiBYkI4d04DO81dppUoCY - daZG6PJleEtvy3gyxdZQdmHLQ1suwr6m -> DiwySXp2wVyRkPmW5lslC1YcxJB3BVIDdlTeGxZfKo5qfl7ZOneEihn7AofcGtoc - du7uMpAe1eRzw9iq2tgplJh7xBsJVBXX -> 9BBcD00eLtoSbhb4GKPyclqy6NNWYztKCZViqVAbu8dG0fPi1K1Ez2AqzlDSuDdH - dwYE00tCy1uJmEvM4KWdxCwoqF3DeMO8 -> ClzVhAqU2L2zGSqcnU8oeeH4Tibv6LfNwXUVowizt5bWd2lODnKLmHjzBAMR6vPR - eeJgOnX0D7Ck1sgACPGon52qo9luRwJ1 -> Mtc9v2reuJjjB6khm8pw3LNvC6CG75Qynct4Io1SyGaBnf4dGUuDO1ke11t1jOQz - fMDxBk7WeZtORMX7Ij9SbB4anjvg1UgW -> fYyAGD9YgVp3iKSwNQRFK2cmXagTXhyD1qISnpcwq3O0lZTjkw9MwjlaEa0G4EpP - fRaz8skEtJE9mJc5pAWOYBT33cOsrewC -> cWL2TnMrmg5HZOHMBuYQnoQJou77cRNTWlIAmtQC1h6BFezlbX0HQW7ELSresn6R - ghPBZV6LSWf6cZDSeKACANaPRREOMmhp -> jwHQFEbfmFDd6i5AXbp7GzFszK6zJvnIatr61yt3GFA71QWZfCRM2dlAUbwqyshx - hpcJGkvr5tfF55b8AxHj3ox4CcvzVKtD -> WwMeT2cIxkUExDOEj553FTp8YgRpth18inypMlbJgr3sWp9uPBQqVpYWjgs1ZGi7 - hrIfkqa1Wo2VeEm0Khc0JYUgEr5JPq8c -> rawDGwz3JBsuXaL0lQ5l2nquLTjOfhnOHlblLPiv7BYf8wTS4Xb3YNkeOmzZCe1m - iEdLBhdykNcWWdwIFAmnYYRqRYRwOs9T -> eYImF57zbAyXrP1SIVjG0bNzDTgcdHzCdoFNcABi53V6h17C8Sc5Cz1U1mPbfRxC - j64jz4YzCnb8WrIL9iLA1xgDnzS0Fm73 -> VZdHe9TiF4w69eeQubVeQvXd2lyXBPLEg02u1xhKbvog3puF7aXbrahak6SyvOIt - jYPKdoadL8z4cget1PrKLPU8UWRokbe6 -> dleWyzRSUzmwwoKRxPTvbkXCHMjlDDzGoq0RzCWsM7WMX7nwX0KMbfFTNRUFWA4p - jhcS3sKKBRV19n8u7LQSDVAr5Z4RHejt -> kYSwL03ygayAqlqHrLjvIyziJ3unUjq5G6NkWjT3t5FhEEMLwG9wIm6sxlzAh85p - l278j4l4p94y84ymmVJyrjwMLp88O0VW -> fMlLPKs3a53BueLKJuuYY14FliPRSItEqYFIhQXYCs3tutO1rgxooTFpXnJhkPMK - l5mZOvqHpUbHoa8TtPZuDCnMa9YzPJPW -> y6RF5l4chNBcHKEVTdqJiwMcQ5hgaTEGzngYUJIwtBaFkpb1a4PYgV0EPJDMnYgD - lTTJP1IiM7VhCSbIoV9i2vmRn9CZCbHe -> E15b6aVSCgI4vzK7eNwHxuAHtLLpxMSHjoPKjSJ8i1Jq5cHmebs10aCxcH0jASJD - m2prxn108ugbVlA1MdR9pnxeIk9mnbyQ -> lJGZxGdHHSNVAZmgaqGgqJHJTv34AWS9atujdj6EUx3KrWuC3zRcII4BjjCv14fw - mHSG1wYohYBHVC7e9GfzRYy34aSMzE9y -> zki6lnB0Oj6gZPHIsClqf2sGHr8csWXhP9y14FiCPxbP4d7OyIsHcbYw4ye7xGYs - nCu8tQYlAzy9dnb4SiVQHs160xYnQu7k -> hEZf7ArbOXPuNQaiv2oT049Mg8bZhcenZwkGKdymZ9g85F28AUQStziiBT2FAgyC - nr4kBf1XNEnIN0BxroGa5VYGXs2d9P2D -> 6SlChlTgPeqmeBgQLk44qoxSIwD2mFDUubIjHJOZ0NruKQHdUkQcuwaWyGpBmbLl - oDVZvqu3lhxpKYu4ad1QpVgqdiFRZNeo -> jzCztQpOybHwqxLt1tryjPfuJWgUHtG90ILSvop9HswJO22jtOmtfXlTqtiZrgSo - oeGrtFzhU0pNrd4pRIE4xA1B3K17ZaA5 -> mR9PkDl7lf5WCFehkvroF1HFhbDPdxOROHlqLy6qp50HAJkERjYqOPp2jiCBOf8B - oyGzmjJzZn6NpayIgg1vqKsCnwbrln7N -> pcB6xgs4rwtJFao1QMEnureZRkZMMD9hgFTA6datto20wbmrpRxHQ7R1MzmspEB0 - pGORfLuH2Q9W0cYq88iA3c3HEyoxgRw1 -> 6LwIZsnGCAKb5LoNtjfoMbHwJuItVtB5F14kHolFKooKt3IRivzqZRqyAn5g9O0O - pZiRakAeDGKMI3cOsHEJ4Vphg0MNjaOa -> 5lFa8HWMQsSGoDSujsd1JcUdHaDKl9jEN6LNfx7M5RDTVBVrVSItK54vlLsn5Lm4 - qFoPxb3g9WXCgfqBZTbM9FBghzhlGtP1 -> OUYSeUlUMa1pczdmG3V0DPtsA35YABX43W85fE3ScHJ3ZtOT9bw4z7OjgMf74S2F - rtGf0pgW3iEJgKD662W1298xlLEJuoGU -> kpQZEkORAq3v0NUqXSbQxGtZqUf99y9nZUocLuMRmKLVkJ4Eneqcmx4mfK9ALcI4 - s8x1rShvbamr8E7JuYH5NBjrlLHFEX9l -> zI3lJX2QSSemm21tTx2KJoQ3j9mElbdEPtqkPFhIa0YlKIPMXh6agh1TpAprxVPw - sf9hAA7Jh8BSfY6WbTH3iifbcJ4yywIW -> 8Gngw6qd1sPWqXaQzt3e4DMPEjZUd3yIK3GZSILzlpGGp6p4HkXzF8nBFulwPxf3 - shJlyYIn4Y57IeVo38r7kLF3VufYSND2 -> JpfUcPH32ILNkGgimlDx8xrM9TaFbJZJQhOfute2XcrrmGLCC19jwEozWOTGJQbM - w3AYqZLwPQ5GSB8OWJDmWGpAUDOrFNsD -> M8ifPwlU5TvAbzNmdeH8KorCMCQk0gHLr4Cm8E5wcgDFEHeKZ8WCZxEgV86me6LT - w9mFiiwNJikvPLAYdyQuvsDDqjFnbbEU -> fBa1DuTaAKNDYJQVsN4kTPk60EE3w6wO6bPdpVv4B3UjnmjPVPB4rTDmU133L4af - wFteV09JaGijCbB0DumErH1jFL9FdeoN -> UwzA1hnoqIVL7RMzrICmC1GLjqpCOuQBocpLvZ610NUuGMKPr3ma5AKv1NvL8CEI - wwkuNA2Qn9FqlyvZExTMObACsDxUZZ23 -> o8iZfmwIcfPOqsDBvev0IgKNN6AXUlcnoE62dkSuy5hS3RS75STRmMDOcFnGR00V - xQt30C7iOBWxhCr4ceZq7Q2Y6NPOS8OK -> di8ubhvM1Vi6cVGv8lxy52Yill7IFrENfGdvWHp1sF8YdbcVQcEOndwBEdWhqFpA - xYrrmrQUUfA0G7dKdWov2r6f6qhLRLpN -> w0QgfK7ptn5Pebpbh3qAfhSUyfM6XsS0d0QlJbXrpn9s8NE9XLiWP3Dk4pght1pH - yCBP0w0cPWk2hKJEtXd7smAlJ3TE2pxp -> CF72KUUNzwaReXPRw3s2rB0kNWvvIheWJI9vRpvJACBiKh3fn9g3q0ZGcZBu1YGO - ypXFDr2FYMGC4RM19LvRcpWkMl8t3Ibx -> itu4F1fBKHrxITaTMQvLMUFXNcrrCvLO2Ox3NkffHerH0RCUmrk31zORQI4ecvLQ - ytgfu1gHZDvknPY8pna1LttilDYL7Vv5 -> AHao3NzQFUKXmVRRdVEevjrYDn1ZagP1vC6wQfPwdPVVlOUtsqFCYeqkBihlix8G - zFfVc52kMC3kgK5CJqQXYn76heDJ8V4I -> cuBoClKhYYrBq2XErR8uRb6p91dSgGBIqghKSm4EF2XLr74Lpu1dyv2S9REZ5Rwp - zr13e5LGSdckVzdyQliJbij5DoOfp4mY -> wNHailOlkfuceyrnvbTMObJRJZERFyBuLxqLAfvSkwyH9F8UEwDIK5QuZVaKZiSG diff --git a/test/mpcal/go/load_balancer_file_system/main.go b/test/mpcal/go/load_balancer_file_system/main.go deleted file mode 100644 index dd9ce3ab2..000000000 --- a/test/mpcal/go/load_balancer_file_system/main.go +++ /dev/null @@ -1,108 +0,0 @@ -package main - -import ( - "fmt" - "load_balancer" - "os" - "pgo/distsys" - "strconv" - "strings" -) - -var configuration map[string]string -var id string -var role string -var selfStr string -var connections *distsys.Connections -var barrier *distsys.SyncBarrier - -const ( - MAILBOX_SIZE = 10 -) - -func init() { - if len(os.Args) < 3 { - fmt.Printf("Usage: %s processName(processArgument) ip:port\n", os.Args[0]) - } - - id = os.Args[1] - ipPort := os.Args[2] - configuration = map[string]string{ - "ALoadBalancer(0)": "127.0.0.1:2222", - "AServer(1)": "127.0.0.1:3333", - "AServer(2)": "127.0.0.1:4444", - "AClient(3)": "127.0.0.1:5555", - } - - if _, ok := configuration[id]; !ok { - fmt.Fprintf(os.Stderr, "Unknown process: %s\n", id) - os.Exit(1) - } - - role, selfStr = distsys.ParseProcessId(id) - coordinator := configuration["ALoadBalancer(0)"] - connections = distsys.NewConnections(ipPort) - barrier = distsys.NewSyncBarrier(configuration, connections, ipPort, coordinator) -} - -func makeMailboxRef(name string) *distsys.Mailbox { - mbox, err := distsys.MailboxRef(name, 0, connections, configuration, []string{id}, MAILBOX_SIZE, 0) - if err != nil { - panic(err) - } - - return mbox -} - -func waitBarrier() { - if err := barrier.WaitPeers(); err != nil { - fmt.Printf("Error: %v\n", err) - os.Exit(1) - } -} - -func main() { - mailboxes := []distsys.ArchetypeResource{} - mailboxes = append(mailboxes, makeMailboxRef("ALoadBalancer(0)")) - - for i := 1; i <= load_balancer.NUM_SERVERS; i++ { - mailboxes = append(mailboxes, makeMailboxRef(fmt.Sprintf("AServer(%d)", i))) - } - - for i := load_balancer.NUM_SERVERS + 1; i <= load_balancer.NUM_SERVERS+load_balancer.NUM_CLIENTS; i++ { - mailboxes = append(mailboxes, makeMailboxRef(fmt.Sprintf("AClient(%d)", i))) - } - - self, err := strconv.Atoi(selfStr) - if err != nil { - panic(err) - } - - // wait for all process to come online - waitBarrier() - - if role == "ALoadBalancer" { - go load_balancer.ALoadBalancer(self, distsys.ArchetypeResourceSlice(mailboxes)) - } else if role == "AServer" { - path := os.Args[3] - fs := distsys.NewFileSystemDirectory(path) - - go load_balancer.AServer(self, distsys.ArchetypeResourceSlice(mailboxes), fs) - } else { - fmt.Printf("Connected!\n") - - in := distsys.NewLocalChannel("in", 0) - out := distsys.NewLocalChannel("out", 0) - - go load_balancer.AClient(self, distsys.ArchetypeResourceSlice(mailboxes), in, out) - - for _, path := range []string{"page1.html", "page1.html", "page2.html"} { - in.Send(path) - bArray := out.Receive().([]byte) - fmt.Printf("Received page: %s\n", strings.TrimSpace(string(bArray[:len(bArray)]))) - } - } - - // Wait for all peers to disconnect - waitBarrier() -} diff --git a/test/mpcal/go/load_balancer_file_system/pages/page1.html b/test/mpcal/go/load_balancer_file_system/pages/page1.html deleted file mode 100644 index a87b42ff7..000000000 --- a/test/mpcal/go/load_balancer_file_system/pages/page1.html +++ /dev/null @@ -1 +0,0 @@ -This is server 1! diff --git a/test/mpcal/go/load_balancer_file_system/pages/page2.html b/test/mpcal/go/load_balancer_file_system/pages/page2.html deleted file mode 100644 index 6c693c240..000000000 --- a/test/mpcal/go/load_balancer_file_system/pages/page2.html +++ /dev/null @@ -1 +0,0 @@ -This is server 2! diff --git a/test/mpcal/go/load_balancer_record_payloads/main.go b/test/mpcal/go/load_balancer_record_payloads/main.go deleted file mode 100644 index f71624124..000000000 --- a/test/mpcal/go/load_balancer_record_payloads/main.go +++ /dev/null @@ -1,108 +0,0 @@ -package main - -import ( - "fmt" - "load_balancer" - "os" - "pgo/distsys" - "strconv" - "strings" -) - -var configuration map[string]string -var id string -var role string -var selfStr string -var connections *distsys.Connections -var barrier *distsys.SyncBarrier - -const ( - MAILBOX_SIZE = 10 -) - -func init() { - if len(os.Args) < 3 { - fmt.Printf("Usage: %s processName(processArgument) ip:port\n", os.Args[0]) - } - - id = os.Args[1] - ipPort := os.Args[2] - configuration = map[string]string{ - "ALoadBalancer(0)": "127.0.0.1:2222", - "AServer(1)": "127.0.0.1:3333", - "AServer(2)": "127.0.0.1:4444", - "AClient(3)": "127.0.0.1:5555", - } - - if _, ok := configuration[id]; !ok { - fmt.Fprintf(os.Stderr, "Unknown process: %s\n", id) - os.Exit(1) - } - - role, selfStr = distsys.ParseProcessId(id) - coordinator := configuration["ALoadBalancer(0)"] - connections = distsys.NewConnections(ipPort) - barrier = distsys.NewSyncBarrier(configuration, connections, ipPort, coordinator) -} - -func makeMailboxRef(name string) *distsys.Mailbox { - mbox, err := distsys.MailboxRef(name, 0, connections, configuration, []string{id}, MAILBOX_SIZE, 0) - if err != nil { - panic(err) - } - - return mbox -} - -func waitBarrier() { - if err := barrier.WaitPeers(); err != nil { - fmt.Printf("Error: %v\n", err) - os.Exit(1) - } -} - -func main() { - mailboxes := []distsys.ArchetypeResource{} - mailboxes = append(mailboxes, makeMailboxRef("ALoadBalancer(0)")) - - for i := 1; i <= load_balancer.NUM_SERVERS; i++ { - mailboxes = append(mailboxes, makeMailboxRef(fmt.Sprintf("AServer(%d)", i))) - } - - for i := load_balancer.NUM_SERVERS + 1; i <= load_balancer.NUM_SERVERS+load_balancer.NUM_CLIENTS; i++ { - mailboxes = append(mailboxes, makeMailboxRef(fmt.Sprintf("AClient(%d)", i))) - } - - self, err := strconv.Atoi(selfStr) - if err != nil { - panic(err) - } - - // wait for all process to come online - waitBarrier() - - if role == "ALoadBalancer" { - go load_balancer.ALoadBalancer(self, distsys.ArchetypeResourceSlice(mailboxes)) - } else if role == "AServer" { - path := os.Args[3] - page := distsys.NewFileResource(path) - - go load_balancer.AServer(self, distsys.ArchetypeResourceSlice(mailboxes), page) - } else { - fmt.Printf("Connected!\n") - - in := distsys.NewLocalChannel("in", 0) - out := distsys.NewLocalChannel("out", 0) - - go load_balancer.AClient(self, distsys.ArchetypeResourceSlice(mailboxes), in, out) - - for i := 0; i < 4; i++ { - in.Send(0) // send any dummy value - bArray := out.Receive().([]byte) - fmt.Printf("Received page: %s\n", strings.TrimSpace(string(bArray[:len(bArray)]))) - } - } - - // Wait for all peers to disconnect - waitBarrier() -} diff --git a/test/mpcal/go/load_balancer_record_payloads/page1.html b/test/mpcal/go/load_balancer_record_payloads/page1.html deleted file mode 100644 index a87b42ff7..000000000 --- a/test/mpcal/go/load_balancer_record_payloads/page1.html +++ /dev/null @@ -1 +0,0 @@ -This is server 1! diff --git a/test/mpcal/go/load_balancer_record_payloads/page2.html b/test/mpcal/go/load_balancer_record_payloads/page2.html deleted file mode 100644 index 6c693c240..000000000 --- a/test/mpcal/go/load_balancer_record_payloads/page2.html +++ /dev/null @@ -1 +0,0 @@ -This is server 2! diff --git a/test/mpcal/go/load_balancer_tuples/main.go b/test/mpcal/go/load_balancer_tuples/main.go deleted file mode 100644 index f71624124..000000000 --- a/test/mpcal/go/load_balancer_tuples/main.go +++ /dev/null @@ -1,108 +0,0 @@ -package main - -import ( - "fmt" - "load_balancer" - "os" - "pgo/distsys" - "strconv" - "strings" -) - -var configuration map[string]string -var id string -var role string -var selfStr string -var connections *distsys.Connections -var barrier *distsys.SyncBarrier - -const ( - MAILBOX_SIZE = 10 -) - -func init() { - if len(os.Args) < 3 { - fmt.Printf("Usage: %s processName(processArgument) ip:port\n", os.Args[0]) - } - - id = os.Args[1] - ipPort := os.Args[2] - configuration = map[string]string{ - "ALoadBalancer(0)": "127.0.0.1:2222", - "AServer(1)": "127.0.0.1:3333", - "AServer(2)": "127.0.0.1:4444", - "AClient(3)": "127.0.0.1:5555", - } - - if _, ok := configuration[id]; !ok { - fmt.Fprintf(os.Stderr, "Unknown process: %s\n", id) - os.Exit(1) - } - - role, selfStr = distsys.ParseProcessId(id) - coordinator := configuration["ALoadBalancer(0)"] - connections = distsys.NewConnections(ipPort) - barrier = distsys.NewSyncBarrier(configuration, connections, ipPort, coordinator) -} - -func makeMailboxRef(name string) *distsys.Mailbox { - mbox, err := distsys.MailboxRef(name, 0, connections, configuration, []string{id}, MAILBOX_SIZE, 0) - if err != nil { - panic(err) - } - - return mbox -} - -func waitBarrier() { - if err := barrier.WaitPeers(); err != nil { - fmt.Printf("Error: %v\n", err) - os.Exit(1) - } -} - -func main() { - mailboxes := []distsys.ArchetypeResource{} - mailboxes = append(mailboxes, makeMailboxRef("ALoadBalancer(0)")) - - for i := 1; i <= load_balancer.NUM_SERVERS; i++ { - mailboxes = append(mailboxes, makeMailboxRef(fmt.Sprintf("AServer(%d)", i))) - } - - for i := load_balancer.NUM_SERVERS + 1; i <= load_balancer.NUM_SERVERS+load_balancer.NUM_CLIENTS; i++ { - mailboxes = append(mailboxes, makeMailboxRef(fmt.Sprintf("AClient(%d)", i))) - } - - self, err := strconv.Atoi(selfStr) - if err != nil { - panic(err) - } - - // wait for all process to come online - waitBarrier() - - if role == "ALoadBalancer" { - go load_balancer.ALoadBalancer(self, distsys.ArchetypeResourceSlice(mailboxes)) - } else if role == "AServer" { - path := os.Args[3] - page := distsys.NewFileResource(path) - - go load_balancer.AServer(self, distsys.ArchetypeResourceSlice(mailboxes), page) - } else { - fmt.Printf("Connected!\n") - - in := distsys.NewLocalChannel("in", 0) - out := distsys.NewLocalChannel("out", 0) - - go load_balancer.AClient(self, distsys.ArchetypeResourceSlice(mailboxes), in, out) - - for i := 0; i < 4; i++ { - in.Send(0) // send any dummy value - bArray := out.Receive().([]byte) - fmt.Printf("Received page: %s\n", strings.TrimSpace(string(bArray[:len(bArray)]))) - } - } - - // Wait for all peers to disconnect - waitBarrier() -} diff --git a/test/mpcal/go/load_balancer_tuples/page1.html b/test/mpcal/go/load_balancer_tuples/page1.html deleted file mode 100644 index a87b42ff7..000000000 --- a/test/mpcal/go/load_balancer_tuples/page1.html +++ /dev/null @@ -1 +0,0 @@ -This is server 1! diff --git a/test/mpcal/go/load_balancer_tuples/page2.html b/test/mpcal/go/load_balancer_tuples/page2.html deleted file mode 100644 index 6c693c240..000000000 --- a/test/mpcal/go/load_balancer_tuples/page2.html +++ /dev/null @@ -1 +0,0 @@ -This is server 2! diff --git a/test/mpcal/go/replicated_kv/main.go b/test/mpcal/go/replicated_kv/main.go deleted file mode 100644 index bede21956..000000000 --- a/test/mpcal/go/replicated_kv/main.go +++ /dev/null @@ -1,327 +0,0 @@ -package main - -import ( - "fmt" - "os" - "replicated_kv" - "sort" - "strconv" - "strings" - "sync" - "time" - - "pgo/distsys" -) - -const ( - MAILBOX_SIZE = 10 // message buffer size - CLOCK_UPDATE_TICK = 200 // clock update 0.2s - - CONNECTION_TIMEOUT = 1000 // time out RPC calls after 1s - - REPLICA_STATUS_CHECK = 5 // print replica database state every 5 seconds - - GET = iota - PUT - DISCONNECT -) - -var configuration map[string]string -var id string -var role string -var selfStr string -var self int -var connections *distsys.Connections -var barrier *distsys.SyncBarrier -var err error - -var spin distsys.ArchetypeResource - -// connections to clients and replicas -var clients distsys.ArchetypeResourceCollection -var replicas distsys.ArchetypeResourceCollection - -var clientId distsys.ArchetypeResource -var clock distsys.ArchetypeResourceCollection -var locked distsys.ArchetypeResourceCollection - -// replica variables -var db *distsys.ArchetypeResourceMap - -// storage check mutex -var mut sync.Mutex -var checkCount int - -// continue ticking? -var tick bool - -type Command interface { - Run() error -} - -type Get struct { - key string -} - -func (g Get) Run() error { - getKey := distsys.NewImmutableResource(g.key) - response := distsys.NewLocallySharedResource("getResponse", nil) - - replicated_kv.Get(self, clientId, replicas, clients, getKey, locked, clock, spin, response) - - // Read without Acquire because we know `response` is not - // shared - val, _ := response.Read() - if val == nil { - fmt.Printf("-- Get %s: %v\n", g.key, nil) - } else { - fmt.Printf("-- Get %s: %s\n", g.key, val.(string)) - } - - return nil -} - -type Put struct { - key string - value string -} - -func (p Put) Run() error { - putKey := distsys.NewImmutableResource(p.key) - putValue := distsys.NewImmutableResource(p.value) - response := distsys.NewLocallySharedResource("putResponse", nil) - - replicated_kv.Put(self, clientId, replicas, clients, putKey, putValue, locked, clock, spin, response) - - fmt.Printf("-- Put (%s, %s): OK\n", p.key, p.value) - return nil -} - -type Disconnect int - -func (d Disconnect) Run() error { - return disconnect() -} - -func init() { - if len(os.Args) < 2 { - fmt.Printf("Usage: %s processName(processArgument)\n", os.Args[0]) - } - - id = os.Args[1] - configuration = map[string]string{ - "Replica(0)": "127.0.0.1:4444", - "Replica(1)": "127.0.0.1:5555", - "Replica(2)": "127.0.0.1:6666", - "Client(3)": "127.0.0.1:2222", - "Client(4)": "127.0.0.1:3333", - } - - if _, ok := configuration[id]; !ok { - fmt.Fprintf(os.Stderr, "Unknown process: %s\n", id) - os.Exit(1) - } - - ipPort := configuration[id] - role, selfStr = distsys.ParseProcessId(id) - coordinator := configuration["Replica(1)"] - connections = distsys.NewConnections(ipPort) - barrier = distsys.NewSyncBarrier(configuration, connections, ipPort, coordinator) - - self, err = strconv.Atoi(selfStr) - if err != nil { - panic(err) - } - - // archetype resource functions do not spin in this context - spin = distsys.NewImmutableResource(false) - - checkCount = 0 - tick = true -} - -func fatal(msg string) { - fmt.Fprintf(os.Stderr, fmt.Sprintf("%s\n", msg)) - os.Exit(1) -} - -func makeMailboxRef(name string) *distsys.Mailbox { - mbox, err := distsys.MailboxRef(name, 0, connections, configuration, []string{id}, MAILBOX_SIZE, CONNECTION_TIMEOUT) - if err != nil { - panic(err) - } - - return mbox -} - -func waitBarrier() { - if err := barrier.WaitPeers(); err != nil { - fatal(fmt.Sprintf("Error: %v\n", err)) - } -} - -func parseCommands(defs []string) []Command { - if len(defs) == 0 { - fatal("Clients need at least one command") - } - - commands := []Command{} - - for _, c := range defs { - fields := strings.Fields(c) - - action := strings.ToUpper(fields[0]) - if action == "GET" { - if len(fields) != 2 { - fatal(fmt.Sprintf("Invalid command: %s", c)) - } - - key := fields[1] - commands = append(commands, Get{key: key}) - - } else if action == "PUT" { - if len(fields) != 3 { - fatal(fmt.Sprintf("Invalid command: %s", c)) - } - - key := fields[1] - val := fields[2] - - commands = append(commands, Put{key: key, value: val}) - - } else if action == "DISCONNECT" { - if len(fields) != 1 { - fatal(fmt.Sprintf("Invalid command: %s", c)) - } - - commands = append(commands, Disconnect(0)) - - } else { - fatal(fmt.Sprintf("Invalid command: %s", c)) - } - } - - return commands -} - -func disconnect() error { - return replicated_kv.Disconnect(self, clientId, replicas, locked, clock) -} - -func clockUpdate() error { - for tick { - time.Sleep(CLOCK_UPDATE_TICK * time.Millisecond) - - if err := replicated_kv.ClockUpdate(self, clientId, replicas, clock, spin); err != nil { - fmt.Printf("Clock Update error: %v\n", err) - return err - } - } - - return nil -} - -func initClientRoutines() { - // set up ClockUpdate routine - go clockUpdate() -} - -func dumpStorage() { - storage := db.ToMap() - - if len(storage) == 0 { - fmt.Printf("Replica snapshot: (empty)\n") - return - } - - fmt.Printf("Replica snapshot:\n") - keys := []string{} - - for k, _ := range storage { - keys = append(keys, k.(string)) - } - - sort.Strings(keys) - for _, k := range keys { - fmt.Printf("\t%s -> %s\n", k, storage[k].(string)) - } -} - -func storageStatusCheck() { - for { - time.Sleep(REPLICA_STATUS_CHECK * time.Second) - mut.Lock() - - dumpStorage() - checkCount += 1 - - mut.Unlock() - } - -} - -func main() { - var commands []Command - - // parse command line options soon to avoid finding out invalid - // command after all processes are up - if role == "Client" { - commands = parseCommands(os.Args[2:]) - } - - // set up connections - clientConns := []distsys.ArchetypeResource{} - replicaConns := []distsys.ArchetypeResource{} - - for _, i := range replicated_kv.ReplicaSet() { - replicaConns = append(replicaConns, makeMailboxRef(fmt.Sprintf("Replica(%d)", i))) - clientConns = append(clientConns, nil) - } - - for _, i := range replicated_kv.ClientSet() { - clientConns = append(clientConns, makeMailboxRef(fmt.Sprintf("Client(%d)", i))) - } - - clients = distsys.ArchetypeResourceSlice(clientConns) - replicas = distsys.ArchetypeResourceSlice(replicaConns) - - // wait for all process to come online - waitBarrier() - - if role == "Client" { - if len(os.Args) == 3 { - fmt.Fprintf(os.Stderr, "Client requires a list of commands") - os.Exit(1) - } - - clientId = distsys.NewImmutableResource(self) - locked = distsys.NewSingletonCollection(distsys.NewLocallySharedResource("locked", false)) - clock = distsys.NewSingletonCollection(distsys.NewLocallySharedResource("clock", 0)) - - initClientRoutines() - - for _, command := range commands { - command.Run() - } - - } else if role == "Replica" { - db = distsys.NewArchetypeResourceMap() - go replicated_kv.AReplica(self, clients, replicas, db) - go storageStatusCheck() - } - - // wait for all clients to disconnect - waitBarrier() - - // all process are done, stop ticking the clock - tick = false - - if role == "Replica" { - // print the storage status if it hasn't been print before - mut.Lock() - - if checkCount == 0 { - dumpStorage() - } - } -} diff --git a/test/mpcal/spec/concurrent_replicated_kv.tla b/test/mpcal/spec/concurrent_replicated_kv.tla deleted file mode 100644 index 6b5e35991..000000000 --- a/test/mpcal/spec/concurrent_replicated_kv.tla +++ /dev/null @@ -1,2707 +0,0 @@ ------------------------------ MODULE replicated_kv ----------------------------- -(***************************************************************************************) -(* Specifies a simple replicated Key-Value store in MPCal. *) -(* *) -(* Specifies a replicated state machines (RSM) approach as described in: *) -(* *) -(* Implementing fault-tolerant services using the state machine approach: a tutorial. *) -(* http://dl.acm.org/citation.cfm?id=98167 *) -(***************************************************************************************) - -\* Use some built-in TLA+ modules -EXTENDS Integers, Sequences, FiniteSets, TLC - -\* Constant Definitions -\* -------------------- - -\* Defines the size of the network buffer in a FIFOChannel (the mapping macro). -\* -\* TLC will explore states with up to `BUFFER_SIZE` messages being held on the buffer. -\* If the communication buffer is full, a process that attempts to send a message will not -\* run until a message on the other end of the channel is received. -CONSTANT BUFFER_SIZE - -\* Defines the number of key-value store replicas and clients in the system. The specification -\* is orthogonal to these numbers. Note, however, that increasing the number of replicas and/or -\* clients exponentially increases the state space that TLC needs to explore in order to model -\* check your specification. -CONSTANTS NUM_REPLICAS, NUM_CLIENTS - -\* When a client sends a message to a replica, the client needs to be able to identify -\* what type of message it just received. These constants below are such labels. Make sure -\* to give them distinct concrete values when model checking. -CONSTANTS DISCONNECT_MSG, GET_MSG, PUT_MSG, NULL_MSG - -\* labels that identify a payload corresponds to the response of a previously issues Get -\* or Put request. -CONSTANTS GET_RESPONSE, PUT_RESPONSE - -\* an arbitrary `NULL` value. We model the underlying key-value store as a function from -\* a certain key-space (function domain) to this `NULL` element. When a client issues a `PUT` -\* request, the database is updated and the key being set no longer maps to `NULL`. -CONSTANT NULL - -\* Defines which keys are used by clients when performing Get and Put operations -\* Since we are interested to test properties like message stability detection -\* and the semantics of the database, we keep these constant throughout model checking. -CONSTANT GET_KEY, PUT_KEY - -\* Whenever clients issue PUT requests, they set keys to the value declared in this constant. -CONSTANT PUT_VALUE - -\* Defines the set of keys a client may set. In this specification, we restrict -\* it to them to GET_KEY and PUT_KEY -KeySpace == { GET_KEY, PUT_KEY } - -\* These constants allow PlusCal processes to derive their client identifiers from -\* their PlusCal identifiers. -GET_ORDER == 0 -PUT_ORDER == 1 -DISCONNECT_ORDER == 2 -NULL_ORDER == 3 - -\* We have clients that perform each of the operations supported by our Replicated KV-store: -\* Get, Put, Disconnect, and ClockUpdate (or 'null' request). PlusCal requires that every process -\* has a unique identifier. The set definitions below just ensure that our clients have -\* consecutive identifiers. -GetSet == (NUM_REPLICAS)..(NUM_REPLICAS+NUM_CLIENTS-1) -PutSet == (NUM_REPLICAS+NUM_CLIENTS)..(NUM_REPLICAS + 2*NUM_CLIENTS - 1) -DisconnectSet == (NUM_REPLICAS+2*NUM_CLIENTS)..(NUM_REPLICAS+3*NUM_CLIENTS-1) -NullSet == (NUM_REPLICAS+3*NUM_CLIENTS)..(NUM_REPLICAS+4*NUM_CLIENTS-1) - -(*************************************************************************** ---mpcal ReplicatedKV { - define { - \* Define NUM_NODES to be the total number of nodes in the system, i.e., the number of - \* clients plus the number of replicas - NUM_NODES == NUM_REPLICAS + NUM_CLIENTS - - \* Each replica and each client in the system need an identifier. By default, replicas - \* are identified from 1 to NUM_REPLICAS, and the clients are identified from NUM_REPLICAS+1 - \* to NUM_NODES. It is important that identifiers are unique, consecutive and non-overlapping, - \* due to the way we are modeling our network in this specification. - ReplicaSet == 0..(NUM_REPLICAS-1) - ClientSet == NUM_REPLICAS..(NUM_NODES-1) - } - - \* Broadcasts a certain `msg` to `nodes` with identifiers ranging from - \* `domainStart` to `domainEnd`. - \* - \* Only returns once every message has been sent (i.e., it may "block" if - \* the buffer of one of the receivers is full). - macro Broadcast(nodes, i, until, msg, clock) { - while (i <= until /\ clock # -1) { - nodes[i] := msg; - i := i + 1; - } - } - - \* Models a FIFO channel. Messages are always delivered. Every process - \* can have up to `BUFFER_SIZE` messages in its buffer before being - \* processed. - mapping macro FIFOChannel { - read { - await Len($variable) > 0; - with (msg = Head($variable)) { - $variable := Tail($variable); - yield msg; - }; - } - - write { - await Len($variable) < BUFFER_SIZE; - yield Append($variable, $value); - } - } - - \* The following mapping macros make sure that archetypes that - \* perform client functions read the correct client identifier with - \* respect to their PlusCal process identifier (`self`). - - mapping macro GetClientId { - read { yield self - (NUM_CLIENTS * GET_ORDER); } - write { assert(FALSE); yield $value; } - } - - mapping macro PutClientId { - read { yield self - (NUM_CLIENTS * PUT_ORDER); } - write { assert(FALSE); yield $value; } - } - - mapping macro DisconnectClientId { - read { yield self - (NUM_CLIENTS * DISCONNECT_ORDER); } - write { assert(FALSE); yield $value; } - } - - mapping macro NullClientId { - read { yield self - (NUM_CLIENTS * NULL_ORDER); } - write { assert(FALSE); yield $value; } - } - - \* Mapping via identity is sometimes necessary in order to inform - \* the compiler that a certain resource is to be function mapped, but - \* no meaningful manipulation on reads and writes is necessary. - mapping macro Identity { - read { yield $variable; } - write { yield $value; } - } - - \* This archetype defines the behavior of the replica servers in the system. - \* Its parameters are: - \* - \* - clients: connections to all clients in the system; it needs to wait - \* for client requests in order to perform operations. - \* - replicas: connections to replicas. Since replicas do not talk to each - \* other, this parameter is only used in order to listen to - \* incoming messages. - \* - kv: the underlying "database". When 'put' requests become stable, this - \* database is updated to include the value being set by the client. - archetype AReplica(ref clients, replicas, ref kv) - - \* Local state in a replica: - variables - \* Each replica knows which clients are live (i.e., haven't disconnected) - \* Initially, all clients are live. - liveClients = ClientSet, - - \* Replicas remember which requests are pending (i.e., have not been - \* replied yet). This variable maps client identifiers to a sequence - \* of pending requests - pendingRequests = [c \in liveClients |-> <<>>], - - \* Temporary variables: holds messages that are stable - stableMessages = <<>>, - - \* incremented during in loops - i, - - \* temporary variable: holds the first pending message from - \* a client. The first pending message has the lowest logical - \* clock in the sequence (logical clocks are monotonically increasing) - firstPending, - - \* temporary variables used while finding the set of stable - \* messages. - timestamp, - nextClient, - lowestPending, - chooseMessage, - - \* the replica needs to know the logical clocks of the last - \* message received by each client in order to determine - \* request stability. - currentClocks = [c \in liveClients |-> 0]; - - \* determines the lowest logical clock value seen from all - \* clients. Any pending messages with timestamp lower than this - \* can be considered stable. - minClock, - - \* controls while loop execution. See the 'findStableRequestsLoop' - \* step for more information - continue, - - \* temporary variable: live clients that have pending - \* messages (stable or not) - pendingClients, - - \* Used when iterating over sets of clients - clientsIter, - - \* used to hold messages sent/received by the replica - msg, - - \* put requests were successful - ok, - - \* holds keys/values to be read from/written to the database - key, - val; { - - \* Main replica loop. In each iteration of the loop, the replica: - \* - \* 1. Waits for incoming messages from clients; - \* 2. Finds stable messages; - \* 3. Replies to all stable messages. - replicaLoop: - while (TRUE) { - - stableMessages := <<>>; - continue := TRUE; - - \* Waits for an incoming message from any client. This statement will - \* "block" the replica until a message is read into 'msg'. - \* See definition of client archetypes for the format of the messages. - receiveClientRequest: - msg := replicas[self]; - - \* if the message received is a disconnection from a client, - \* remove the client from the set of live clients - clientDisconnected: - if (msg.op = DISCONNECT_MSG) { - liveClients := liveClients \ {msg.client}; - }; - - \* if the message is a Get request: - replicaGetRequest: - if (msg.op = GET_MSG) { - \* safety assertion: a client requesting for a key must be live - assert(msg.client \in liveClients); - - \* update our records of the current logical clock of the - \* requesting client. - currentClocks[msg.client] := msg.timestamp; - - \* make this a pending message (to be dealt with later, during - \* stability check) - pendingRequests[msg.client] := Append(pendingRequests[msg.client], msg); - }; - - \* if the message is a Put request: similar to Get request. - replicaPutRequest: - if (msg.op = PUT_MSG) { - currentClocks[msg.client] := msg.timestamp; - pendingRequests[msg.client] := Append(pendingRequests[msg.client], msg); - }; - - \* if the message is a clock update from a client, inspect the logical clock - \* to check if it's lower than that of any other message seen before. - replicaNullRequest: - if (msg.op = NULL_MSG) { - currentClocks[msg.client] := msg.timestamp; - }; - - \* Message stability - \* ----------------- - \* - \* The replica needs to detect when messages become stable, and then respond to - \* those messages. Finding out which messages are stable and totally ordering them - \* is crucial for the correctness of the algorithm. If message stability does not work - \* correctly in the replicas, the database may get inconsistent across replicas - \* (if operations are applied in a different order), or clients may get "stuck" - \* (if stable messages are not replied). - - - \* This is the main loop that finds which of the pending requests (if any) are stable - findStableRequestsLoop: - while (continue) { - - \* only consider clients that have messages pending - pendingClients := {c \in liveClients : Len(pendingRequests[c]) > 0}; - - \* if two messages have the same logical clock, total ordering is enforced - \* based on the client identifier: requests from smaller client identifiers - \* are applied first - nextClient := NUM_NODES + 1; - - clientsIter := liveClients; - i := 0; - minClock := 0; - - \* in order to find the set of stable messages, we need to determine - \* the lowest logical clock among our set of live clients. Then, every - \* pending message with a timestamp greater than 'minClock' can be - \* considered stable. - findMinClock: - while (i < Cardinality(clientsIter)) { - with (client \in clientsIter) { - if (minClock = 0 \/ currentClocks[client] < minClock) { - minClock := currentClocks[client]; - }; - - clientsIter := clientsIter \ {client}; - } - }; - - \* this variable holds the timestamp of the request with the lowest clock - \* value that is pending and stable - lowestPending := minClock + 1; - - i := 0; - - \* find the next stable message to be processed - findMinClient: - while (i < Cardinality(pendingClients)) { - with (client \in pendingClients) { - - \* for each client with pending requests: - \* - inspect the first pending message (by definition, the message with - \* lowest clock from that client) - \* - extract the timestamp from the message - \* - record the client and timestamp in case this is the "oldest" message - - firstPending := Head(pendingRequests[client]); - assert(firstPending.op = GET_MSG \/ firstPending.op = PUT_MSG); - timestamp := firstPending.timestamp; - - \* a message is only stable if its timestamp is lower than - \* minClock - if (timestamp < minClock) { - - \* this is the next stable message if it has the lowest - \* timestamp seen so far; if the timestamp is the same as - \* the lowest seen so far, do a client-id comparison - chooseMessage := (timestamp < lowestPending) \/ ((timestamp = lowestPending) /\ (client < nextClient)); - if (chooseMessage) { - nextClient := client; - lowestPending := timestamp; - } - }; - - pendingClients := pendingClients \ {client}; - } - }; - - \* add the next stable message to the 'stableMessages' sequence. - \* if 'lowestPending' is >= 'minClock', it means no more stable messages - \* are pending, and we can leave this loop. - addStableMessage: - if (lowestPending < minClock) { - msg := Head(pendingRequests[nextClient]); - pendingRequests[nextClient] := Tail(pendingRequests[nextClient]); - - stableMessages := Append(stableMessages, msg); - } else { - continue := FALSE; - } - }; - - i := 1; - - \* iterate over our sequence of 'stableMessages' built in the previous - \* step, responding to each of them in order. - respondPendingRequestsLoop: - while (i <= Len(stableMessages)) { - msg := stableMessages[i]; - i := i + 1; - - respondStableGet: - if (msg.op = GET_MSG) { - key := msg.key; - val := kv[key]; - - \* send the value read from the database back to the client - clients[msg.reply_to] := [type |-> GET_RESPONSE, result |-> val]; - }; - - respondStablePut: - if (msg.op = PUT_MSG) { - key := msg.key; - val := msg.value; - - \* update our database and send an OK back to the client - kv[key] := val; - - clients[msg.reply_to] := [type |-> PUT_RESPONSE, result |-> ok]; - }; - } - } - } - - \* Client Definitions - \* ------------------ - \* - \* The following archetypes define the client functions as specified in A1. - \* Note that these operations are the "logical" versions of the API: for example, - \* a Put archetype here sends a "Put" message to all replicas. - \* - \* In all of the definitions below, note that 'clocks' represent the client's - \* logical clock. However, upon disconnection, the clock is set to '-1', and - \* clients know to terminate when that happens. - - - \* Specifies a Get request from a client. Arguments: - \* - \* - clientId: client identifier, used by the replica to identify which client is - \* performing the operation - \* - replicas: connections to replica servers - \* - clients: connections to clients. Used only to listen for incoming messages - \* from replicas (i.e., to send the value of the key being read). - \* - key: the key being read. This *must* belong to the KeySpace set. - \* - clock: The initial logical clock - \* - \* A Get message sent to the replica is a record in the following format: - \* - \* [op: GET_MSG, key: key, client: client_id, timestamp: lamport_clock] - archetype Get(clientId, ref replicas, clients, key, ref clock, spin, ref outside) - variable continue = TRUE, getReq, getResp; - { - \* Loop until disconnected - getLoop: - while (continue) { - getRequest: - \* if disconnected, return - if (clock[clientId] = -1) { - continue := FALSE - } else { - \* increment the logical clock, and construct a valid - \* Get message. - clock[clientId] := clock[clientId] + 1; - getReq := [op |-> GET_MSG, key |-> key, client |-> clientId, timestamp |-> clock[clientId], reply_to |-> self]; - - \* Choose some replica from the set of replicas to send this - \* request to - with (dst \in ReplicaSet) { - replicas[dst] := getReq; - }; - - getReply: - if (clock[clientId] = -1) { - \* Client disconnected -- terminate - continue := FALSE; - } else { - \* Waits for the response from the replica - getResp := clients[self]; - assert(getResp.type = GET_RESPONSE); - outside := getResp.result; - } - }; - - getCheckSpin: - if (~spin) { - continue := FALSE; - } - } - } - - \* Specifies a Put request from a client. Arguments: - \* - \* - clientId: client identifier, used by the replica to identify which client is - \* performing the operation - \* - replicas: connection to the replicas. - \* - clients: connection to the clients. Used to read incoming messages (response - \* from the Put request - \* - key: the key being set. - \* - value: the value being written to the key - \* - clock: Lamport clocks - \* - \* A Put message sent to the replica is a record in the following format: - \* - \* [op: PUT_MSG, key: key, value: value, client: client_id, timestamp: lamport_clock] - archetype Put(clientId, ref replicas, clients, key, value, ref clock, spin, ref outside) - variables continue = TRUE, i, j, putReq, putResp; - { - \* Loops indefinitely until disconnected - putLoop: - while (continue) { - putRequest: - \* if disconnected, return - if (clock[clientId] = -1) { - continue := FALSE; - } else { - \* increment the logical clock, construct the payload to be sent - \* to the replica, and set 'locked' to TRUE - clock[clientId] := clock[clientId] + 1; - putReq := [op |-> PUT_MSG, key |-> key, value |-> value, client |-> clientId, timestamp |-> clock[clientId], reply_to |-> self]; - i := 0; - j := 0; - - \* Put requests must be broadcast to all replicas - putBroadcast: - Broadcast(replicas, j, NUM_REPLICAS-1, putReq, clock[clientId]); - - \* wait for a response from all replicas, and allow other - \* calls to the replica to happen after that. - putResponse: - while (i < Cardinality(ReplicaSet)) { - if (clock[clientId] = -1) { - continue := FALSE; - goto putLoop; - } else { - putResp := clients[self]; - assert(putResp.type = PUT_RESPONSE); - - i := i + 1; - } - }; - - putComplete: - outside := PUT_RESPONSE; - }; - - putCheckSpin: - if (~spin) { - continue := FALSE; - } - } - } - - \* Specifies a Disconnect message from the client. - \* - \* A Disconnect message sent to the replica is a record in the following format: - \* - \* [op: DISCONNECT_MSG, client: client_id] - archetype Disconnect(clientId, ref replicas, ref clock) - variables msg, j; - { - sendDisconnectRequest: - msg := [op |-> DISCONNECT_MSG, client |-> clientId]; - - \* setting the logical clock internally to -1 indicates that this client - \* has disconnected. Other operations terminate accordingly. - clock[clientId] := -1; - j := 0; - - \* Disconnection messages need to be broadcast to all replicas. - \* "Clock" is set to zero because the replica is disconnected but we - \* *do* want to broadcast that message - disconnectBroadcast: - Broadcast(replicas, j, NUM_REPLICAS-1, msg, 0); - } - - \* Specifies a ClockUpdate ('null') message from the client. - \* If the client has disconnected, no more clock updates are sent. - \* - \* A ClockUpdate message sent to the replica is a record in the following format: - \* - \* [op: NULL_MSG, client: client_id, timestamp: logical_clock] - archetype ClockUpdate(clientId, ref replicas, ref clock, spin) - variables continue = TRUE, j, msg; - { - clockUpdateLoop: - while (continue) { - \* if we have disconnected, return - if (clock[clientId] = -1) { - continue := FALSE; - } else { - \* tick the lock and construct the message accordingly - clock[clientId] := clock[clientId] + 1; - msg := [op |-> NULL_MSG, client |-> clientId, timestamp |-> clock[clientId]]; - j := 0; - - nullBroadcast: - \* clock update messages must be broadcast to all replicas. - Broadcast(replicas, j, NUM_REPLICAS-1, msg, clock[clientId]); - }; - - nullCheckSpin: - if (~spin) { - continue := FALSE; - } - } - } - - \* Global Variables - \* ---------------- - - variables - \* queue of incoming messages for each of the replicas - replicasNetwork = [id \in ReplicaSet |-> <<>>], - - \* all clients performing operations in this model - allClients = GetSet \cup PutSet \cup DisconnectSet \cup NullSet, - - \* queue of incoming messages for each of the clients - clientMailboxes = [id \in allClients |-> <<>>], - - \* client identifier: to be appropriately mapped - cid = 0, - - \* communication channel with the caller; astracted - \* in this specification - out = 0, - - \* all clocks set to 0 initially - clocks = [c \in ClientSet |-> 0]; - - - \* Process Instantiations - \* ---------------------- - \* - \* This is where the archetypes defined above are instantiated into actual PlusCal - \* processes. We instantiate NUM_REPLICAS replica servers and NUM_CLIENTS client - \* processes for each possible client operation. TLC will be responsible for - \* exploring the different orderings in which these clients and replicas - \* may interact. - - - \* Instantiate replica servers. The network model used is the one defined in - \* the FIFOChannel mapping macro. - fair process (Replica \in ReplicaSet) == instance AReplica(ref clientMailboxes, replicasNetwork, [k \in KeySpace |-> NULL]) - mapping @1[_] via FIFOChannel - mapping @2[_] via FIFOChannel - mapping @3[_] via Identity; - - \* Instantiate clients: - - fair process (GetClient \in GetSet) == instance Get(cid, ref replicasNetwork, clientMailboxes, GET_KEY, ref clocks, TRUE, ref out) - mapping cid via GetClientId - mapping replicasNetwork[_] via FIFOChannel - mapping clientMailboxes[_] via FIFOChannel - mapping clocks[_] via Identity; - - fair process (PutClient \in PutSet) == instance Put(cid, ref replicasNetwork, clientMailboxes, PUT_KEY, PUT_VALUE, ref clocks, TRUE, ref out) - mapping cid via PutClientId - mapping replicasNetwork[_] via FIFOChannel - mapping clientMailboxes[_] via FIFOChannel - mapping clocks[_] via Identity; - - fair process (DisconnectClient \in DisconnectSet) == instance Disconnect(cid, ref replicasNetwork, ref clocks) - mapping cid via DisconnectClientId - mapping replicasNetwork[_] via FIFOChannel - mapping clocks[_] via Identity; - - fair process (ClockUpdateClient \in NullSet) == instance ClockUpdate(cid, ref replicasNetwork, ref clocks, TRUE) - mapping cid via NullClientId - mapping replicasNetwork[_] via FIFOChannel - mapping clocks[_] via Identity; -} - -\* BEGIN PLUSCAL TRANSLATION ---algorithm ReplicatedKV { - variables replicasNetwork = [id \in ReplicaSet |-> <<>>], allClients = (((GetSet) \cup (PutSet)) \cup (DisconnectSet)) \cup (NullSet), clientMailboxes = [id \in allClients |-> <<>>], cid = 0, out = 0, clocks = [c \in ClientSet |-> 0], replicasRead, replicasWrite, kvRead, clientsWrite, clientsWrite0, kvWrite, kvWrite0, clientsWrite1, clientIdRead, clockRead, clientIdRead0, clockRead0, clientIdRead1, clockWrite, keyRead, clientIdRead2, clientIdRead3, clockRead1, replicasWrite0, clientsRead, clientsWrite2, outsideWrite, clientsWrite3, outsideWrite0, spinRead, clientIdRead4, clockRead2, clientIdRead5, clockRead3, clientIdRead6, clockWrite0, keyRead0, valueRead, clientIdRead7, clientIdRead8, clockRead4, replicasWrite1, replicasWrite2, clientsRead0, clientsWrite4, clientsWrite5, outsideWrite1, spinRead0, clientIdRead9, clientIdRead10, clockWrite1, replicasWrite3, replicasWrite4, clientIdRead11, clockRead5, clientIdRead12, clockRead6, clientIdRead13, clockWrite2, clientIdRead14, clientIdRead15, clockRead7, replicasWrite5, replicasWrite6, spinRead1; - define { - NUM_NODES == (NUM_REPLICAS) + (NUM_CLIENTS) - ReplicaSet == (0) .. ((NUM_REPLICAS) - (1)) - ClientSet == (NUM_REPLICAS) .. ((NUM_NODES) - (1)) - } - fair process (Replica \in ReplicaSet) - variables kvLocal = [k \in KeySpace |-> NULL], liveClients = ClientSet, pendingRequests = [c \in liveClients |-> <<>>], stableMessages = <<>>, i, firstPending, timestamp, nextClient, lowestPending, chooseMessage, currentClocks = [c \in liveClients |-> 0], minClock, continue, pendingClients, clientsIter, msg, ok, key, val; - { - replicaLoop: - if (TRUE) { - stableMessages := <<>>; - continue := TRUE; - receiveClientRequest: - await (Len(replicasNetwork[self])) > (0); - with (msg0 = Head(replicasNetwork[self])) { - replicasWrite := [replicasNetwork EXCEPT ![self] = Tail(replicasNetwork[self])]; - replicasRead := msg0; - }; - msg := replicasRead; - replicasNetwork := replicasWrite; - - clientDisconnected: - if (((msg).op) = (DISCONNECT_MSG)) { - liveClients := (liveClients) \ ({(msg).client}); - }; - - replicaGetRequest: - if (((msg).op) = (GET_MSG)) { - assert ((msg).client) \in (liveClients); - currentClocks[(msg).client] := (msg).timestamp; - pendingRequests[(msg).client] := Append(pendingRequests[(msg).client], msg); - }; - - replicaPutRequest: - if (((msg).op) = (PUT_MSG)) { - currentClocks[(msg).client] := (msg).timestamp; - pendingRequests[(msg).client] := Append(pendingRequests[(msg).client], msg); - }; - - replicaNullRequest: - if (((msg).op) = (NULL_MSG)) { - currentClocks[(msg).client] := (msg).timestamp; - }; - - findStableRequestsLoop: - if (continue) { - pendingClients := {c \in liveClients : (Len(pendingRequests[c])) > (0)}; - nextClient := (NUM_NODES) + (1); - clientsIter := liveClients; - i := 0; - minClock := 0; - findMinClock: - if ((i) < (Cardinality(clientsIter))) { - with (client \in clientsIter) { - if (((minClock) = (0)) \/ ((currentClocks[client]) < (minClock))) { - minClock := currentClocks[client]; - }; - clientsIter := (clientsIter) \ ({client}); - }; - goto findMinClock; - } else { - lowestPending := (minClock) + (1); - i := 0; - }; - - findMinClient: - if ((i) < (Cardinality(pendingClients))) { - with (client \in pendingClients) { - firstPending := Head(pendingRequests[client]); - assert (((firstPending).op) = (GET_MSG)) \/ (((firstPending).op) = (PUT_MSG)); - timestamp := (firstPending).timestamp; - if ((timestamp) < (minClock)) { - chooseMessage := ((timestamp) < (lowestPending)) \/ (((timestamp) = (lowestPending)) /\ ((client) < (nextClient))); - if (chooseMessage) { - nextClient := client; - lowestPending := timestamp; - }; - }; - pendingClients := (pendingClients) \ ({client}); - }; - goto findMinClient; - }; - - addStableMessage: - if ((lowestPending) < (minClock)) { - msg := Head(pendingRequests[nextClient]); - pendingRequests[nextClient] := Tail(pendingRequests[nextClient]); - stableMessages := Append(stableMessages, msg); - goto findStableRequestsLoop; - } else { - continue := FALSE; - goto findStableRequestsLoop; - }; - - } else { - i := 1; - }; - - respondPendingRequestsLoop: - if ((i) <= (Len(stableMessages))) { - msg := stableMessages[i]; - i := (i) + (1); - respondStableGet: - if (((msg).op) = (GET_MSG)) { - key := (msg).key; - kvRead := kvLocal[key]; - val := kvRead; - await (Len(clientMailboxes[(msg).reply_to])) < (BUFFER_SIZE); - clientsWrite := [clientMailboxes EXCEPT ![(msg).reply_to] = Append(clientMailboxes[(msg).reply_to], [type |-> GET_RESPONSE, result |-> val])]; - clientsWrite0 := clientsWrite; - clientMailboxes := clientsWrite0; - } else { - clientsWrite0 := clientMailboxes; - clientMailboxes := clientsWrite0; - }; - - respondStablePut: - if (((msg).op) = (PUT_MSG)) { - key := (msg).key; - val := (msg).value; - kvWrite := [kvLocal EXCEPT ![key] = val]; - await (Len(clientMailboxes[(msg).reply_to])) < (BUFFER_SIZE); - clientsWrite := [clientMailboxes EXCEPT ![(msg).reply_to] = Append(clientMailboxes[(msg).reply_to], [type |-> PUT_RESPONSE, result |-> ok])]; - kvWrite0 := kvWrite; - clientsWrite1 := clientsWrite; - clientMailboxes := clientsWrite1; - kvLocal := kvWrite0; - goto respondPendingRequestsLoop; - } else { - kvWrite0 := kvLocal; - clientsWrite1 := clientMailboxes; - clientMailboxes := clientsWrite1; - kvLocal := kvWrite0; - goto respondPendingRequestsLoop; - }; - - } else { - goto replicaLoop; - }; - - }; - - } - fair process (GetClient \in GetSet) - variables spinLocal = TRUE, continue = TRUE, getReq, getResp; - { - getLoop: - if (continue) { - getRequest: - clientIdRead := (self) - ((NUM_CLIENTS) * (GET_ORDER)); - clockRead := clocks[clientIdRead]; - if ((clockRead) = (-(1))) { - continue := FALSE; - } else { - clientIdRead0 := (self) - ((NUM_CLIENTS) * (GET_ORDER)); - clockRead0 := clocks[clientIdRead0]; - clientIdRead1 := (self) - ((NUM_CLIENTS) * (GET_ORDER)); - clockWrite := [clocks EXCEPT ![clientIdRead1] = (clockRead0) + (1)]; - keyRead := GET_KEY; - clientIdRead2 := (self) - ((NUM_CLIENTS) * (GET_ORDER)); - clientIdRead3 := (self) - ((NUM_CLIENTS) * (GET_ORDER)); - clockRead1 := clockWrite[clientIdRead3]; - getReq := [op |-> GET_MSG, key |-> keyRead, client |-> clientIdRead2, timestamp |-> clockRead1, reply_to |-> self]; - with (dst \in ReplicaSet) { - await (Len(replicasNetwork[dst])) < (BUFFER_SIZE); - replicasWrite0 := [replicasNetwork EXCEPT ![dst] = Append(replicasNetwork[dst], getReq)]; - }; - replicasNetwork := replicasWrite0; - clocks := clockWrite; - getReply: - clientIdRead := (self) - ((NUM_CLIENTS) * (GET_ORDER)); - clockRead := clocks[clientIdRead]; - if ((clockRead) = (-(1))) { - continue := FALSE; - clientsWrite3 := clientMailboxes; - outsideWrite0 := out; - clientMailboxes := clientsWrite3; - out := outsideWrite0; - } else { - await (Len(clientMailboxes[self])) > (0); - with (msg1 = Head(clientMailboxes[self])) { - clientsWrite2 := [clientMailboxes EXCEPT ![self] = Tail(clientMailboxes[self])]; - clientsRead := msg1; - }; - getResp := clientsRead; - assert ((getResp).type) = (GET_RESPONSE); - outsideWrite := (getResp).result; - clientsWrite3 := clientsWrite2; - outsideWrite0 := outsideWrite; - clientMailboxes := clientsWrite3; - out := outsideWrite0; - }; - - }; - - getCheckSpin: - spinRead := spinLocal; - if (~(spinRead)) { - continue := FALSE; - goto getLoop; - } else { - goto getLoop; - }; - - }; - - } - fair process (PutClient \in PutSet) - variables spinLocal0 = TRUE, continue = TRUE, i, j, putReq, putResp; - { - putLoop: - if (continue) { - putRequest: - clientIdRead4 := (self) - ((NUM_CLIENTS) * (PUT_ORDER)); - clockRead2 := clocks[clientIdRead4]; - if ((clockRead2) = (-(1))) { - continue := FALSE; - } else { - clientIdRead5 := (self) - ((NUM_CLIENTS) * (PUT_ORDER)); - clockRead3 := clocks[clientIdRead5]; - clientIdRead6 := (self) - ((NUM_CLIENTS) * (PUT_ORDER)); - clockWrite0 := [clocks EXCEPT ![clientIdRead6] = (clockRead3) + (1)]; - keyRead0 := PUT_KEY; - valueRead := PUT_VALUE; - clientIdRead7 := (self) - ((NUM_CLIENTS) * (PUT_ORDER)); - clientIdRead8 := (self) - ((NUM_CLIENTS) * (PUT_ORDER)); - clockRead4 := clockWrite0[clientIdRead8]; - putReq := [op |-> PUT_MSG, key |-> keyRead0, value |-> valueRead, client |-> clientIdRead7, timestamp |-> clockRead4, reply_to |-> self]; - i := 0; - j := 0; - clocks := clockWrite0; - putBroadcast: - clientIdRead4 := (self) - ((NUM_CLIENTS) * (PUT_ORDER)); - clockRead2 := clocks[clientIdRead4]; - if (((j) <= ((NUM_REPLICAS) - (1))) /\ ((clockRead2) # (-(1)))) { - await (Len(replicasNetwork[j])) < (BUFFER_SIZE); - replicasWrite1 := [replicasNetwork EXCEPT ![j] = Append(replicasNetwork[j], putReq)]; - j := (j) + (1); - replicasWrite2 := replicasWrite1; - replicasNetwork := replicasWrite2; - goto putBroadcast; - } else { - replicasWrite2 := replicasNetwork; - replicasNetwork := replicasWrite2; - }; - - putResponse: - if ((i) < (Cardinality(ReplicaSet))) { - clientIdRead4 := (self) - ((NUM_CLIENTS) * (PUT_ORDER)); - clockRead2 := clocks[clientIdRead4]; - if ((clockRead2) = (-(1))) { - continue := FALSE; - clientsWrite5 := clientMailboxes; - clientMailboxes := clientsWrite5; - goto putLoop; - } else { - await (Len(clientMailboxes[self])) > (0); - with (msg2 = Head(clientMailboxes[self])) { - clientsWrite4 := [clientMailboxes EXCEPT ![self] = Tail(clientMailboxes[self])]; - clientsRead0 := msg2; - }; - putResp := clientsRead0; - assert ((putResp).type) = (PUT_RESPONSE); - i := (i) + (1); - clientsWrite5 := clientsWrite4; - clientMailboxes := clientsWrite5; - goto putResponse; - }; - } else { - clientMailboxes := clientsWrite5; - }; - - putComplete: - outsideWrite1 := PUT_RESPONSE; - out := outsideWrite1; - - }; - - putCheckSpin: - spinRead0 := spinLocal0; - if (~(spinRead0)) { - continue := FALSE; - goto putLoop; - } else { - goto putLoop; - }; - - }; - - } - fair process (DisconnectClient \in DisconnectSet) - variables msg, j; - { - sendDisconnectRequest: - clientIdRead9 := (self) - ((NUM_CLIENTS) * (DISCONNECT_ORDER)); - msg := [op |-> DISCONNECT_MSG, client |-> clientIdRead9]; - clientIdRead10 := (self) - ((NUM_CLIENTS) * (DISCONNECT_ORDER)); - clockWrite1 := [clocks EXCEPT ![clientIdRead10] = -(1)]; - j := 0; - clocks := clockWrite1; - disconnectBroadcast: - if (((j) <= ((NUM_REPLICAS) - (1))) /\ ((0) # (-(1)))) { - await (Len(replicasNetwork[j])) < (BUFFER_SIZE); - replicasWrite3 := [replicasNetwork EXCEPT ![j] = Append(replicasNetwork[j], msg)]; - j := (j) + (1); - replicasWrite4 := replicasWrite3; - replicasNetwork := replicasWrite4; - goto disconnectBroadcast; - } else { - replicasWrite4 := replicasNetwork; - replicasNetwork := replicasWrite4; - }; - - } - fair process (ClockUpdateClient \in NullSet) - variables spinLocal1 = TRUE, continue = TRUE, j, msg; - { - clockUpdateLoop: - if (continue) { - clientIdRead11 := (self) - ((NUM_CLIENTS) * (NULL_ORDER)); - clockRead5 := clocks[clientIdRead11]; - if ((clockRead5) = (-(1))) { - continue := FALSE; - } else { - clientIdRead12 := (self) - ((NUM_CLIENTS) * (NULL_ORDER)); - clockRead6 := clocks[clientIdRead12]; - clientIdRead13 := (self) - ((NUM_CLIENTS) * (NULL_ORDER)); - clockWrite2 := [clocks EXCEPT ![clientIdRead13] = (clockRead6) + (1)]; - clientIdRead14 := (self) - ((NUM_CLIENTS) * (NULL_ORDER)); - clientIdRead15 := (self) - ((NUM_CLIENTS) * (NULL_ORDER)); - clockRead7 := clockWrite2[clientIdRead15]; - msg := [op |-> NULL_MSG, client |-> clientIdRead14, timestamp |-> clockRead7]; - j := 0; - clocks := clockWrite2; - nullBroadcast: - clientIdRead11 := (self) - ((NUM_CLIENTS) * (NULL_ORDER)); - clockRead5 := clocks[clientIdRead11]; - if (((j) <= ((NUM_REPLICAS) - (1))) /\ ((clockRead5) # (-(1)))) { - await (Len(replicasNetwork[j])) < (BUFFER_SIZE); - replicasWrite5 := [replicasNetwork EXCEPT ![j] = Append(replicasNetwork[j], msg)]; - j := (j) + (1); - replicasWrite6 := replicasWrite5; - replicasNetwork := replicasWrite6; - goto nullBroadcast; - } else { - replicasWrite6 := replicasNetwork; - replicasNetwork := replicasWrite6; - }; - - }; - nullCheckSpin: - spinRead1 := spinLocal1; - if (~(spinRead1)) { - continue := FALSE; - goto clockUpdateLoop; - } else { - goto clockUpdateLoop; - }; - - }; - - } -} -\* END PLUSCAL TRANSLATION - - -***************************************************************************) -\* BEGIN TRANSLATION -\* Process variable i of process Replica at line 659 col 148 changed to i_ -\* Process variable continue of process Replica at line 659 col 271 changed to continue_ -\* Process variable msg of process Replica at line 659 col 310 changed to msg_ -\* Process variable continue of process GetClient at line 797 col 33 changed to continue_G -\* Process variable continue of process PutClient at line 861 col 34 changed to continue_P -\* Process variable j of process PutClient at line 861 col 54 changed to j_ -\* Process variable msg of process DisconnectClient at line 944 col 15 changed to msg_D -\* Process variable j of process DisconnectClient at line 944 col 20 changed to j_D -CONSTANT defaultInitValue -VARIABLES replicasNetwork, allClients, clientMailboxes, cid, out, clocks, - replicasRead, replicasWrite, kvRead, clientsWrite, clientsWrite0, - kvWrite, kvWrite0, clientsWrite1, clientIdRead, clockRead, - clientIdRead0, clockRead0, clientIdRead1, clockWrite, keyRead, - clientIdRead2, clientIdRead3, clockRead1, replicasWrite0, - clientsRead, clientsWrite2, outsideWrite, clientsWrite3, - outsideWrite0, spinRead, clientIdRead4, clockRead2, clientIdRead5, - clockRead3, clientIdRead6, clockWrite0, keyRead0, valueRead, - clientIdRead7, clientIdRead8, clockRead4, replicasWrite1, - replicasWrite2, clientsRead0, clientsWrite4, clientsWrite5, - outsideWrite1, spinRead0, clientIdRead9, clientIdRead10, - clockWrite1, replicasWrite3, replicasWrite4, clientIdRead11, - clockRead5, clientIdRead12, clockRead6, clientIdRead13, clockWrite2, - clientIdRead14, clientIdRead15, clockRead7, replicasWrite5, - replicasWrite6, spinRead1, pc - -(* define statement *) -NUM_NODES == (NUM_REPLICAS) + (NUM_CLIENTS) -ReplicaSet == (0) .. ((NUM_REPLICAS) - (1)) -ClientSet == (NUM_REPLICAS) .. ((NUM_NODES) - (1)) - -VARIABLES kvLocal, liveClients, pendingRequests, stableMessages, i_, - firstPending, timestamp, nextClient, lowestPending, chooseMessage, - currentClocks, minClock, continue_, pendingClients, clientsIter, - msg_, ok, key, val, spinLocal, continue_G, getReq, getResp, - spinLocal0, continue_P, i, j_, putReq, putResp, msg_D, j_D, - spinLocal1, continue, j, msg - -vars == << replicasNetwork, allClients, clientMailboxes, cid, out, clocks, - replicasRead, replicasWrite, kvRead, clientsWrite, clientsWrite0, - kvWrite, kvWrite0, clientsWrite1, clientIdRead, clockRead, - clientIdRead0, clockRead0, clientIdRead1, clockWrite, keyRead, - clientIdRead2, clientIdRead3, clockRead1, replicasWrite0, - clientsRead, clientsWrite2, outsideWrite, clientsWrite3, - outsideWrite0, spinRead, clientIdRead4, clockRead2, clientIdRead5, - clockRead3, clientIdRead6, clockWrite0, keyRead0, valueRead, - clientIdRead7, clientIdRead8, clockRead4, replicasWrite1, - replicasWrite2, clientsRead0, clientsWrite4, clientsWrite5, - outsideWrite1, spinRead0, clientIdRead9, clientIdRead10, - clockWrite1, replicasWrite3, replicasWrite4, clientIdRead11, - clockRead5, clientIdRead12, clockRead6, clientIdRead13, - clockWrite2, clientIdRead14, clientIdRead15, clockRead7, - replicasWrite5, replicasWrite6, spinRead1, pc, kvLocal, - liveClients, pendingRequests, stableMessages, i_, firstPending, - timestamp, nextClient, lowestPending, chooseMessage, currentClocks, - minClock, continue_, pendingClients, clientsIter, msg_, ok, key, - val, spinLocal, continue_G, getReq, getResp, spinLocal0, - continue_P, i, j_, putReq, putResp, msg_D, j_D, spinLocal1, - continue, j, msg >> - -ProcSet == (ReplicaSet) \cup (GetSet) \cup (PutSet) \cup (DisconnectSet) \cup (NullSet) - -Init == (* Global variables *) - /\ replicasNetwork = [id \in ReplicaSet |-> <<>>] - /\ allClients = ((((GetSet) \cup (PutSet)) \cup (DisconnectSet)) \cup (NullSet)) - /\ clientMailboxes = [id \in allClients |-> <<>>] - /\ cid = 0 - /\ out = 0 - /\ clocks = [c \in ClientSet |-> 0] - /\ replicasRead = defaultInitValue - /\ replicasWrite = defaultInitValue - /\ kvRead = defaultInitValue - /\ clientsWrite = defaultInitValue - /\ clientsWrite0 = defaultInitValue - /\ kvWrite = defaultInitValue - /\ kvWrite0 = defaultInitValue - /\ clientsWrite1 = defaultInitValue - /\ clientIdRead = defaultInitValue - /\ clockRead = defaultInitValue - /\ clientIdRead0 = defaultInitValue - /\ clockRead0 = defaultInitValue - /\ clientIdRead1 = defaultInitValue - /\ clockWrite = defaultInitValue - /\ keyRead = defaultInitValue - /\ clientIdRead2 = defaultInitValue - /\ clientIdRead3 = defaultInitValue - /\ clockRead1 = defaultInitValue - /\ replicasWrite0 = defaultInitValue - /\ clientsRead = defaultInitValue - /\ clientsWrite2 = defaultInitValue - /\ outsideWrite = defaultInitValue - /\ clientsWrite3 = defaultInitValue - /\ outsideWrite0 = defaultInitValue - /\ spinRead = defaultInitValue - /\ clientIdRead4 = defaultInitValue - /\ clockRead2 = defaultInitValue - /\ clientIdRead5 = defaultInitValue - /\ clockRead3 = defaultInitValue - /\ clientIdRead6 = defaultInitValue - /\ clockWrite0 = defaultInitValue - /\ keyRead0 = defaultInitValue - /\ valueRead = defaultInitValue - /\ clientIdRead7 = defaultInitValue - /\ clientIdRead8 = defaultInitValue - /\ clockRead4 = defaultInitValue - /\ replicasWrite1 = defaultInitValue - /\ replicasWrite2 = defaultInitValue - /\ clientsRead0 = defaultInitValue - /\ clientsWrite4 = defaultInitValue - /\ clientsWrite5 = defaultInitValue - /\ outsideWrite1 = defaultInitValue - /\ spinRead0 = defaultInitValue - /\ clientIdRead9 = defaultInitValue - /\ clientIdRead10 = defaultInitValue - /\ clockWrite1 = defaultInitValue - /\ replicasWrite3 = defaultInitValue - /\ replicasWrite4 = defaultInitValue - /\ clientIdRead11 = defaultInitValue - /\ clockRead5 = defaultInitValue - /\ clientIdRead12 = defaultInitValue - /\ clockRead6 = defaultInitValue - /\ clientIdRead13 = defaultInitValue - /\ clockWrite2 = defaultInitValue - /\ clientIdRead14 = defaultInitValue - /\ clientIdRead15 = defaultInitValue - /\ clockRead7 = defaultInitValue - /\ replicasWrite5 = defaultInitValue - /\ replicasWrite6 = defaultInitValue - /\ spinRead1 = defaultInitValue - (* Process Replica *) - /\ kvLocal = [self \in ReplicaSet |-> [k \in KeySpace |-> NULL]] - /\ liveClients = [self \in ReplicaSet |-> ClientSet] - /\ pendingRequests = [self \in ReplicaSet |-> [c \in liveClients[self] |-> <<>>]] - /\ stableMessages = [self \in ReplicaSet |-> <<>>] - /\ i_ = [self \in ReplicaSet |-> defaultInitValue] - /\ firstPending = [self \in ReplicaSet |-> defaultInitValue] - /\ timestamp = [self \in ReplicaSet |-> defaultInitValue] - /\ nextClient = [self \in ReplicaSet |-> defaultInitValue] - /\ lowestPending = [self \in ReplicaSet |-> defaultInitValue] - /\ chooseMessage = [self \in ReplicaSet |-> defaultInitValue] - /\ currentClocks = [self \in ReplicaSet |-> [c \in liveClients[self] |-> 0]] - /\ minClock = [self \in ReplicaSet |-> defaultInitValue] - /\ continue_ = [self \in ReplicaSet |-> defaultInitValue] - /\ pendingClients = [self \in ReplicaSet |-> defaultInitValue] - /\ clientsIter = [self \in ReplicaSet |-> defaultInitValue] - /\ msg_ = [self \in ReplicaSet |-> defaultInitValue] - /\ ok = [self \in ReplicaSet |-> defaultInitValue] - /\ key = [self \in ReplicaSet |-> defaultInitValue] - /\ val = [self \in ReplicaSet |-> defaultInitValue] - (* Process GetClient *) - /\ spinLocal = [self \in GetSet |-> TRUE] - /\ continue_G = [self \in GetSet |-> TRUE] - /\ getReq = [self \in GetSet |-> defaultInitValue] - /\ getResp = [self \in GetSet |-> defaultInitValue] - (* Process PutClient *) - /\ spinLocal0 = [self \in PutSet |-> TRUE] - /\ continue_P = [self \in PutSet |-> TRUE] - /\ i = [self \in PutSet |-> defaultInitValue] - /\ j_ = [self \in PutSet |-> defaultInitValue] - /\ putReq = [self \in PutSet |-> defaultInitValue] - /\ putResp = [self \in PutSet |-> defaultInitValue] - (* Process DisconnectClient *) - /\ msg_D = [self \in DisconnectSet |-> defaultInitValue] - /\ j_D = [self \in DisconnectSet |-> defaultInitValue] - (* Process ClockUpdateClient *) - /\ spinLocal1 = [self \in NullSet |-> TRUE] - /\ continue = [self \in NullSet |-> TRUE] - /\ j = [self \in NullSet |-> defaultInitValue] - /\ msg = [self \in NullSet |-> defaultInitValue] - /\ pc = [self \in ProcSet |-> CASE self \in ReplicaSet -> "replicaLoop" - [] self \in GetSet -> "getLoop" - [] self \in PutSet -> "putLoop" - [] self \in DisconnectSet -> "sendDisconnectRequest" - [] self \in NullSet -> "clockUpdateLoop"] - -replicaLoop(self) == /\ pc[self] = "replicaLoop" - /\ IF TRUE - THEN /\ stableMessages' = [stableMessages EXCEPT ![self] = <<>>] - /\ continue_' = [continue_ EXCEPT ![self] = TRUE] - /\ pc' = [pc EXCEPT ![self] = "receiveClientRequest"] - ELSE /\ pc' = [pc EXCEPT ![self] = "Done"] - /\ UNCHANGED << stableMessages, continue_ >> - /\ UNCHANGED << replicasNetwork, allClients, - clientMailboxes, cid, out, clocks, - replicasRead, replicasWrite, kvRead, - clientsWrite, clientsWrite0, kvWrite, - kvWrite0, clientsWrite1, clientIdRead, - clockRead, clientIdRead0, clockRead0, - clientIdRead1, clockWrite, keyRead, - clientIdRead2, clientIdRead3, clockRead1, - replicasWrite0, clientsRead, - clientsWrite2, outsideWrite, - clientsWrite3, outsideWrite0, spinRead, - clientIdRead4, clockRead2, clientIdRead5, - clockRead3, clientIdRead6, clockWrite0, - keyRead0, valueRead, clientIdRead7, - clientIdRead8, clockRead4, replicasWrite1, - replicasWrite2, clientsRead0, - clientsWrite4, clientsWrite5, - outsideWrite1, spinRead0, clientIdRead9, - clientIdRead10, clockWrite1, - replicasWrite3, replicasWrite4, - clientIdRead11, clockRead5, - clientIdRead12, clockRead6, - clientIdRead13, clockWrite2, - clientIdRead14, clientIdRead15, - clockRead7, replicasWrite5, - replicasWrite6, spinRead1, kvLocal, - liveClients, pendingRequests, i_, - firstPending, timestamp, nextClient, - lowestPending, chooseMessage, - currentClocks, minClock, pendingClients, - clientsIter, msg_, ok, key, val, - spinLocal, continue_G, getReq, getResp, - spinLocal0, continue_P, i, j_, putReq, - putResp, msg_D, j_D, spinLocal1, continue, - j, msg >> - -receiveClientRequest(self) == /\ pc[self] = "receiveClientRequest" - /\ (Len(replicasNetwork[self])) > (0) - /\ LET msg0 == Head(replicasNetwork[self]) IN - /\ replicasWrite' = [replicasNetwork EXCEPT ![self] = Tail(replicasNetwork[self])] - /\ replicasRead' = msg0 - /\ msg_' = [msg_ EXCEPT ![self] = replicasRead'] - /\ replicasNetwork' = replicasWrite' - /\ pc' = [pc EXCEPT ![self] = "clientDisconnected"] - /\ UNCHANGED << allClients, clientMailboxes, cid, - out, clocks, kvRead, - clientsWrite, clientsWrite0, - kvWrite, kvWrite0, clientsWrite1, - clientIdRead, clockRead, - clientIdRead0, clockRead0, - clientIdRead1, clockWrite, - keyRead, clientIdRead2, - clientIdRead3, clockRead1, - replicasWrite0, clientsRead, - clientsWrite2, outsideWrite, - clientsWrite3, outsideWrite0, - spinRead, clientIdRead4, - clockRead2, clientIdRead5, - clockRead3, clientIdRead6, - clockWrite0, keyRead0, valueRead, - clientIdRead7, clientIdRead8, - clockRead4, replicasWrite1, - replicasWrite2, clientsRead0, - clientsWrite4, clientsWrite5, - outsideWrite1, spinRead0, - clientIdRead9, clientIdRead10, - clockWrite1, replicasWrite3, - replicasWrite4, clientIdRead11, - clockRead5, clientIdRead12, - clockRead6, clientIdRead13, - clockWrite2, clientIdRead14, - clientIdRead15, clockRead7, - replicasWrite5, replicasWrite6, - spinRead1, kvLocal, liveClients, - pendingRequests, stableMessages, - i_, firstPending, timestamp, - nextClient, lowestPending, - chooseMessage, currentClocks, - minClock, continue_, - pendingClients, clientsIter, ok, - key, val, spinLocal, continue_G, - getReq, getResp, spinLocal0, - continue_P, i, j_, putReq, - putResp, msg_D, j_D, spinLocal1, - continue, j, msg >> - -clientDisconnected(self) == /\ pc[self] = "clientDisconnected" - /\ IF ((msg_[self]).op) = (DISCONNECT_MSG) - THEN /\ liveClients' = [liveClients EXCEPT ![self] = (liveClients[self]) \ ({(msg_[self]).client})] - ELSE /\ TRUE - /\ UNCHANGED liveClients - /\ pc' = [pc EXCEPT ![self] = "replicaGetRequest"] - /\ UNCHANGED << replicasNetwork, allClients, - clientMailboxes, cid, out, clocks, - replicasRead, replicasWrite, - kvRead, clientsWrite, - clientsWrite0, kvWrite, kvWrite0, - clientsWrite1, clientIdRead, - clockRead, clientIdRead0, - clockRead0, clientIdRead1, - clockWrite, keyRead, clientIdRead2, - clientIdRead3, clockRead1, - replicasWrite0, clientsRead, - clientsWrite2, outsideWrite, - clientsWrite3, outsideWrite0, - spinRead, clientIdRead4, - clockRead2, clientIdRead5, - clockRead3, clientIdRead6, - clockWrite0, keyRead0, valueRead, - clientIdRead7, clientIdRead8, - clockRead4, replicasWrite1, - replicasWrite2, clientsRead0, - clientsWrite4, clientsWrite5, - outsideWrite1, spinRead0, - clientIdRead9, clientIdRead10, - clockWrite1, replicasWrite3, - replicasWrite4, clientIdRead11, - clockRead5, clientIdRead12, - clockRead6, clientIdRead13, - clockWrite2, clientIdRead14, - clientIdRead15, clockRead7, - replicasWrite5, replicasWrite6, - spinRead1, kvLocal, - pendingRequests, stableMessages, - i_, firstPending, timestamp, - nextClient, lowestPending, - chooseMessage, currentClocks, - minClock, continue_, - pendingClients, clientsIter, msg_, - ok, key, val, spinLocal, - continue_G, getReq, getResp, - spinLocal0, continue_P, i, j_, - putReq, putResp, msg_D, j_D, - spinLocal1, continue, j, msg >> - -replicaGetRequest(self) == /\ pc[self] = "replicaGetRequest" - /\ IF ((msg_[self]).op) = (GET_MSG) - THEN /\ Assert(((msg_[self]).client) \in (liveClients[self]), - "Failure of assertion at line 681, column 25.") - /\ currentClocks' = [currentClocks EXCEPT ![self][(msg_[self]).client] = (msg_[self]).timestamp] - /\ pendingRequests' = [pendingRequests EXCEPT ![self][(msg_[self]).client] = Append(pendingRequests[self][(msg_[self]).client], msg_[self])] - ELSE /\ TRUE - /\ UNCHANGED << pendingRequests, - currentClocks >> - /\ pc' = [pc EXCEPT ![self] = "replicaPutRequest"] - /\ UNCHANGED << replicasNetwork, allClients, - clientMailboxes, cid, out, clocks, - replicasRead, replicasWrite, kvRead, - clientsWrite, clientsWrite0, - kvWrite, kvWrite0, clientsWrite1, - clientIdRead, clockRead, - clientIdRead0, clockRead0, - clientIdRead1, clockWrite, keyRead, - clientIdRead2, clientIdRead3, - clockRead1, replicasWrite0, - clientsRead, clientsWrite2, - outsideWrite, clientsWrite3, - outsideWrite0, spinRead, - clientIdRead4, clockRead2, - clientIdRead5, clockRead3, - clientIdRead6, clockWrite0, - keyRead0, valueRead, clientIdRead7, - clientIdRead8, clockRead4, - replicasWrite1, replicasWrite2, - clientsRead0, clientsWrite4, - clientsWrite5, outsideWrite1, - spinRead0, clientIdRead9, - clientIdRead10, clockWrite1, - replicasWrite3, replicasWrite4, - clientIdRead11, clockRead5, - clientIdRead12, clockRead6, - clientIdRead13, clockWrite2, - clientIdRead14, clientIdRead15, - clockRead7, replicasWrite5, - replicasWrite6, spinRead1, kvLocal, - liveClients, stableMessages, i_, - firstPending, timestamp, nextClient, - lowestPending, chooseMessage, - minClock, continue_, pendingClients, - clientsIter, msg_, ok, key, val, - spinLocal, continue_G, getReq, - getResp, spinLocal0, continue_P, i, - j_, putReq, putResp, msg_D, j_D, - spinLocal1, continue, j, msg >> - -replicaPutRequest(self) == /\ pc[self] = "replicaPutRequest" - /\ IF ((msg_[self]).op) = (PUT_MSG) - THEN /\ currentClocks' = [currentClocks EXCEPT ![self][(msg_[self]).client] = (msg_[self]).timestamp] - /\ pendingRequests' = [pendingRequests EXCEPT ![self][(msg_[self]).client] = Append(pendingRequests[self][(msg_[self]).client], msg_[self])] - ELSE /\ TRUE - /\ UNCHANGED << pendingRequests, - currentClocks >> - /\ pc' = [pc EXCEPT ![self] = "replicaNullRequest"] - /\ UNCHANGED << replicasNetwork, allClients, - clientMailboxes, cid, out, clocks, - replicasRead, replicasWrite, kvRead, - clientsWrite, clientsWrite0, - kvWrite, kvWrite0, clientsWrite1, - clientIdRead, clockRead, - clientIdRead0, clockRead0, - clientIdRead1, clockWrite, keyRead, - clientIdRead2, clientIdRead3, - clockRead1, replicasWrite0, - clientsRead, clientsWrite2, - outsideWrite, clientsWrite3, - outsideWrite0, spinRead, - clientIdRead4, clockRead2, - clientIdRead5, clockRead3, - clientIdRead6, clockWrite0, - keyRead0, valueRead, clientIdRead7, - clientIdRead8, clockRead4, - replicasWrite1, replicasWrite2, - clientsRead0, clientsWrite4, - clientsWrite5, outsideWrite1, - spinRead0, clientIdRead9, - clientIdRead10, clockWrite1, - replicasWrite3, replicasWrite4, - clientIdRead11, clockRead5, - clientIdRead12, clockRead6, - clientIdRead13, clockWrite2, - clientIdRead14, clientIdRead15, - clockRead7, replicasWrite5, - replicasWrite6, spinRead1, kvLocal, - liveClients, stableMessages, i_, - firstPending, timestamp, nextClient, - lowestPending, chooseMessage, - minClock, continue_, pendingClients, - clientsIter, msg_, ok, key, val, - spinLocal, continue_G, getReq, - getResp, spinLocal0, continue_P, i, - j_, putReq, putResp, msg_D, j_D, - spinLocal1, continue, j, msg >> - -replicaNullRequest(self) == /\ pc[self] = "replicaNullRequest" - /\ IF ((msg_[self]).op) = (NULL_MSG) - THEN /\ currentClocks' = [currentClocks EXCEPT ![self][(msg_[self]).client] = (msg_[self]).timestamp] - ELSE /\ TRUE - /\ UNCHANGED currentClocks - /\ pc' = [pc EXCEPT ![self] = "findStableRequestsLoop"] - /\ UNCHANGED << replicasNetwork, allClients, - clientMailboxes, cid, out, clocks, - replicasRead, replicasWrite, - kvRead, clientsWrite, - clientsWrite0, kvWrite, kvWrite0, - clientsWrite1, clientIdRead, - clockRead, clientIdRead0, - clockRead0, clientIdRead1, - clockWrite, keyRead, clientIdRead2, - clientIdRead3, clockRead1, - replicasWrite0, clientsRead, - clientsWrite2, outsideWrite, - clientsWrite3, outsideWrite0, - spinRead, clientIdRead4, - clockRead2, clientIdRead5, - clockRead3, clientIdRead6, - clockWrite0, keyRead0, valueRead, - clientIdRead7, clientIdRead8, - clockRead4, replicasWrite1, - replicasWrite2, clientsRead0, - clientsWrite4, clientsWrite5, - outsideWrite1, spinRead0, - clientIdRead9, clientIdRead10, - clockWrite1, replicasWrite3, - replicasWrite4, clientIdRead11, - clockRead5, clientIdRead12, - clockRead6, clientIdRead13, - clockWrite2, clientIdRead14, - clientIdRead15, clockRead7, - replicasWrite5, replicasWrite6, - spinRead1, kvLocal, liveClients, - pendingRequests, stableMessages, - i_, firstPending, timestamp, - nextClient, lowestPending, - chooseMessage, minClock, continue_, - pendingClients, clientsIter, msg_, - ok, key, val, spinLocal, - continue_G, getReq, getResp, - spinLocal0, continue_P, i, j_, - putReq, putResp, msg_D, j_D, - spinLocal1, continue, j, msg >> - -findStableRequestsLoop(self) == /\ pc[self] = "findStableRequestsLoop" - /\ IF continue_[self] - THEN /\ pendingClients' = [pendingClients EXCEPT ![self] = {c \in liveClients[self] : (Len(pendingRequests[self][c])) > (0)}] - /\ nextClient' = [nextClient EXCEPT ![self] = (NUM_NODES) + (1)] - /\ clientsIter' = [clientsIter EXCEPT ![self] = liveClients[self]] - /\ i_' = [i_ EXCEPT ![self] = 0] - /\ minClock' = [minClock EXCEPT ![self] = 0] - /\ pc' = [pc EXCEPT ![self] = "findMinClock"] - ELSE /\ i_' = [i_ EXCEPT ![self] = 1] - /\ pc' = [pc EXCEPT ![self] = "respondPendingRequestsLoop"] - /\ UNCHANGED << nextClient, - minClock, - pendingClients, - clientsIter >> - /\ UNCHANGED << replicasNetwork, allClients, - clientMailboxes, cid, out, - clocks, replicasRead, - replicasWrite, kvRead, - clientsWrite, clientsWrite0, - kvWrite, kvWrite0, - clientsWrite1, clientIdRead, - clockRead, clientIdRead0, - clockRead0, clientIdRead1, - clockWrite, keyRead, - clientIdRead2, clientIdRead3, - clockRead1, replicasWrite0, - clientsRead, clientsWrite2, - outsideWrite, clientsWrite3, - outsideWrite0, spinRead, - clientIdRead4, clockRead2, - clientIdRead5, clockRead3, - clientIdRead6, clockWrite0, - keyRead0, valueRead, - clientIdRead7, clientIdRead8, - clockRead4, replicasWrite1, - replicasWrite2, clientsRead0, - clientsWrite4, clientsWrite5, - outsideWrite1, spinRead0, - clientIdRead9, clientIdRead10, - clockWrite1, replicasWrite3, - replicasWrite4, clientIdRead11, - clockRead5, clientIdRead12, - clockRead6, clientIdRead13, - clockWrite2, clientIdRead14, - clientIdRead15, clockRead7, - replicasWrite5, replicasWrite6, - spinRead1, kvLocal, - liveClients, pendingRequests, - stableMessages, firstPending, - timestamp, lowestPending, - chooseMessage, currentClocks, - continue_, msg_, ok, key, val, - spinLocal, continue_G, getReq, - getResp, spinLocal0, - continue_P, i, j_, putReq, - putResp, msg_D, j_D, - spinLocal1, continue, j, msg >> - -findMinClock(self) == /\ pc[self] = "findMinClock" - /\ IF (i_[self]) < (Cardinality(clientsIter[self])) - THEN /\ \E client \in clientsIter[self]: - /\ IF ((minClock[self]) = (0)) \/ ((currentClocks[self][client]) < (minClock[self])) - THEN /\ minClock' = [minClock EXCEPT ![self] = currentClocks[self][client]] - ELSE /\ TRUE - /\ UNCHANGED minClock - /\ clientsIter' = [clientsIter EXCEPT ![self] = (clientsIter[self]) \ ({client})] - /\ pc' = [pc EXCEPT ![self] = "findMinClock"] - /\ UNCHANGED << i_, lowestPending >> - ELSE /\ lowestPending' = [lowestPending EXCEPT ![self] = (minClock[self]) + (1)] - /\ i_' = [i_ EXCEPT ![self] = 0] - /\ pc' = [pc EXCEPT ![self] = "findMinClient"] - /\ UNCHANGED << minClock, clientsIter >> - /\ UNCHANGED << replicasNetwork, allClients, - clientMailboxes, cid, out, clocks, - replicasRead, replicasWrite, kvRead, - clientsWrite, clientsWrite0, kvWrite, - kvWrite0, clientsWrite1, clientIdRead, - clockRead, clientIdRead0, clockRead0, - clientIdRead1, clockWrite, keyRead, - clientIdRead2, clientIdRead3, clockRead1, - replicasWrite0, clientsRead, - clientsWrite2, outsideWrite, - clientsWrite3, outsideWrite0, spinRead, - clientIdRead4, clockRead2, clientIdRead5, - clockRead3, clientIdRead6, clockWrite0, - keyRead0, valueRead, clientIdRead7, - clientIdRead8, clockRead4, - replicasWrite1, replicasWrite2, - clientsRead0, clientsWrite4, - clientsWrite5, outsideWrite1, spinRead0, - clientIdRead9, clientIdRead10, - clockWrite1, replicasWrite3, - replicasWrite4, clientIdRead11, - clockRead5, clientIdRead12, clockRead6, - clientIdRead13, clockWrite2, - clientIdRead14, clientIdRead15, - clockRead7, replicasWrite5, - replicasWrite6, spinRead1, kvLocal, - liveClients, pendingRequests, - stableMessages, firstPending, timestamp, - nextClient, chooseMessage, currentClocks, - continue_, pendingClients, msg_, ok, key, - val, spinLocal, continue_G, getReq, - getResp, spinLocal0, continue_P, i, j_, - putReq, putResp, msg_D, j_D, spinLocal1, - continue, j, msg >> - -findMinClient(self) == /\ pc[self] = "findMinClient" - /\ IF (i_[self]) < (Cardinality(pendingClients[self])) - THEN /\ \E client \in pendingClients[self]: - /\ firstPending' = [firstPending EXCEPT ![self] = Head(pendingRequests[self][client])] - /\ Assert((((firstPending'[self]).op) = (GET_MSG)) \/ (((firstPending'[self]).op) = (PUT_MSG)), - "Failure of assertion at line 722, column 37.") - /\ timestamp' = [timestamp EXCEPT ![self] = (firstPending'[self]).timestamp] - /\ IF (timestamp'[self]) < (minClock[self]) - THEN /\ chooseMessage' = [chooseMessage EXCEPT ![self] = ((timestamp'[self]) < (lowestPending[self])) \/ (((timestamp'[self]) = (lowestPending[self])) /\ ((client) < (nextClient[self])))] - /\ IF chooseMessage'[self] - THEN /\ nextClient' = [nextClient EXCEPT ![self] = client] - /\ lowestPending' = [lowestPending EXCEPT ![self] = timestamp'[self]] - ELSE /\ TRUE - /\ UNCHANGED << nextClient, - lowestPending >> - ELSE /\ TRUE - /\ UNCHANGED << nextClient, - lowestPending, - chooseMessage >> - /\ pendingClients' = [pendingClients EXCEPT ![self] = (pendingClients[self]) \ ({client})] - /\ pc' = [pc EXCEPT ![self] = "findMinClient"] - ELSE /\ pc' = [pc EXCEPT ![self] = "addStableMessage"] - /\ UNCHANGED << firstPending, timestamp, - nextClient, lowestPending, - chooseMessage, - pendingClients >> - /\ UNCHANGED << replicasNetwork, allClients, - clientMailboxes, cid, out, clocks, - replicasRead, replicasWrite, kvRead, - clientsWrite, clientsWrite0, kvWrite, - kvWrite0, clientsWrite1, clientIdRead, - clockRead, clientIdRead0, clockRead0, - clientIdRead1, clockWrite, keyRead, - clientIdRead2, clientIdRead3, - clockRead1, replicasWrite0, clientsRead, - clientsWrite2, outsideWrite, - clientsWrite3, outsideWrite0, spinRead, - clientIdRead4, clockRead2, - clientIdRead5, clockRead3, - clientIdRead6, clockWrite0, keyRead0, - valueRead, clientIdRead7, clientIdRead8, - clockRead4, replicasWrite1, - replicasWrite2, clientsRead0, - clientsWrite4, clientsWrite5, - outsideWrite1, spinRead0, clientIdRead9, - clientIdRead10, clockWrite1, - replicasWrite3, replicasWrite4, - clientIdRead11, clockRead5, - clientIdRead12, clockRead6, - clientIdRead13, clockWrite2, - clientIdRead14, clientIdRead15, - clockRead7, replicasWrite5, - replicasWrite6, spinRead1, kvLocal, - liveClients, pendingRequests, - stableMessages, i_, currentClocks, - minClock, continue_, clientsIter, msg_, - ok, key, val, spinLocal, continue_G, - getReq, getResp, spinLocal0, continue_P, - i, j_, putReq, putResp, msg_D, j_D, - spinLocal1, continue, j, msg >> - -addStableMessage(self) == /\ pc[self] = "addStableMessage" - /\ IF (lowestPending[self]) < (minClock[self]) - THEN /\ msg_' = [msg_ EXCEPT ![self] = Head(pendingRequests[self][nextClient[self]])] - /\ pendingRequests' = [pendingRequests EXCEPT ![self][nextClient[self]] = Tail(pendingRequests[self][nextClient[self]])] - /\ stableMessages' = [stableMessages EXCEPT ![self] = Append(stableMessages[self], msg_'[self])] - /\ pc' = [pc EXCEPT ![self] = "findStableRequestsLoop"] - /\ UNCHANGED continue_ - ELSE /\ continue_' = [continue_ EXCEPT ![self] = FALSE] - /\ pc' = [pc EXCEPT ![self] = "findStableRequestsLoop"] - /\ UNCHANGED << pendingRequests, - stableMessages, msg_ >> - /\ UNCHANGED << replicasNetwork, allClients, - clientMailboxes, cid, out, clocks, - replicasRead, replicasWrite, kvRead, - clientsWrite, clientsWrite0, kvWrite, - kvWrite0, clientsWrite1, - clientIdRead, clockRead, - clientIdRead0, clockRead0, - clientIdRead1, clockWrite, keyRead, - clientIdRead2, clientIdRead3, - clockRead1, replicasWrite0, - clientsRead, clientsWrite2, - outsideWrite, clientsWrite3, - outsideWrite0, spinRead, - clientIdRead4, clockRead2, - clientIdRead5, clockRead3, - clientIdRead6, clockWrite0, keyRead0, - valueRead, clientIdRead7, - clientIdRead8, clockRead4, - replicasWrite1, replicasWrite2, - clientsRead0, clientsWrite4, - clientsWrite5, outsideWrite1, - spinRead0, clientIdRead9, - clientIdRead10, clockWrite1, - replicasWrite3, replicasWrite4, - clientIdRead11, clockRead5, - clientIdRead12, clockRead6, - clientIdRead13, clockWrite2, - clientIdRead14, clientIdRead15, - clockRead7, replicasWrite5, - replicasWrite6, spinRead1, kvLocal, - liveClients, i_, firstPending, - timestamp, nextClient, lowestPending, - chooseMessage, currentClocks, - minClock, pendingClients, - clientsIter, ok, key, val, spinLocal, - continue_G, getReq, getResp, - spinLocal0, continue_P, i, j_, - putReq, putResp, msg_D, j_D, - spinLocal1, continue, j, msg >> - -respondPendingRequestsLoop(self) == /\ pc[self] = "respondPendingRequestsLoop" - /\ IF (i_[self]) <= (Len(stableMessages[self])) - THEN /\ msg_' = [msg_ EXCEPT ![self] = stableMessages[self][i_[self]]] - /\ i_' = [i_ EXCEPT ![self] = (i_[self]) + (1)] - /\ pc' = [pc EXCEPT ![self] = "respondStableGet"] - ELSE /\ pc' = [pc EXCEPT ![self] = "replicaLoop"] - /\ UNCHANGED << i_, msg_ >> - /\ UNCHANGED << replicasNetwork, - allClients, - clientMailboxes, cid, out, - clocks, replicasRead, - replicasWrite, kvRead, - clientsWrite, - clientsWrite0, kvWrite, - kvWrite0, clientsWrite1, - clientIdRead, clockRead, - clientIdRead0, clockRead0, - clientIdRead1, clockWrite, - keyRead, clientIdRead2, - clientIdRead3, clockRead1, - replicasWrite0, - clientsRead, clientsWrite2, - outsideWrite, - clientsWrite3, - outsideWrite0, spinRead, - clientIdRead4, clockRead2, - clientIdRead5, clockRead3, - clientIdRead6, clockWrite0, - keyRead0, valueRead, - clientIdRead7, - clientIdRead8, clockRead4, - replicasWrite1, - replicasWrite2, - clientsRead0, - clientsWrite4, - clientsWrite5, - outsideWrite1, spinRead0, - clientIdRead9, - clientIdRead10, - clockWrite1, - replicasWrite3, - replicasWrite4, - clientIdRead11, clockRead5, - clientIdRead12, clockRead6, - clientIdRead13, - clockWrite2, - clientIdRead14, - clientIdRead15, clockRead7, - replicasWrite5, - replicasWrite6, spinRead1, - kvLocal, liveClients, - pendingRequests, - stableMessages, - firstPending, timestamp, - nextClient, lowestPending, - chooseMessage, - currentClocks, minClock, - continue_, pendingClients, - clientsIter, ok, key, val, - spinLocal, continue_G, - getReq, getResp, - spinLocal0, continue_P, i, - j_, putReq, putResp, msg_D, - j_D, spinLocal1, continue, - j, msg >> - -respondStableGet(self) == /\ pc[self] = "respondStableGet" - /\ IF ((msg_[self]).op) = (GET_MSG) - THEN /\ key' = [key EXCEPT ![self] = (msg_[self]).key] - /\ kvRead' = kvLocal[self][key'[self]] - /\ val' = [val EXCEPT ![self] = kvRead'] - /\ (Len(clientMailboxes[(msg_[self]).reply_to])) < (BUFFER_SIZE) - /\ clientsWrite' = [clientMailboxes EXCEPT ![(msg_[self]).reply_to] = Append(clientMailboxes[(msg_[self]).reply_to], [type |-> GET_RESPONSE, result |-> val'[self]])] - /\ clientsWrite0' = clientsWrite' - /\ clientMailboxes' = clientsWrite0' - ELSE /\ clientsWrite0' = clientMailboxes - /\ clientMailboxes' = clientsWrite0' - /\ UNCHANGED << kvRead, clientsWrite, key, - val >> - /\ pc' = [pc EXCEPT ![self] = "respondStablePut"] - /\ UNCHANGED << replicasNetwork, allClients, cid, - out, clocks, replicasRead, - replicasWrite, kvWrite, kvWrite0, - clientsWrite1, clientIdRead, - clockRead, clientIdRead0, clockRead0, - clientIdRead1, clockWrite, keyRead, - clientIdRead2, clientIdRead3, - clockRead1, replicasWrite0, - clientsRead, clientsWrite2, - outsideWrite, clientsWrite3, - outsideWrite0, spinRead, - clientIdRead4, clockRead2, - clientIdRead5, clockRead3, - clientIdRead6, clockWrite0, keyRead0, - valueRead, clientIdRead7, - clientIdRead8, clockRead4, - replicasWrite1, replicasWrite2, - clientsRead0, clientsWrite4, - clientsWrite5, outsideWrite1, - spinRead0, clientIdRead9, - clientIdRead10, clockWrite1, - replicasWrite3, replicasWrite4, - clientIdRead11, clockRead5, - clientIdRead12, clockRead6, - clientIdRead13, clockWrite2, - clientIdRead14, clientIdRead15, - clockRead7, replicasWrite5, - replicasWrite6, spinRead1, kvLocal, - liveClients, pendingRequests, - stableMessages, i_, firstPending, - timestamp, nextClient, lowestPending, - chooseMessage, currentClocks, - minClock, continue_, pendingClients, - clientsIter, msg_, ok, spinLocal, - continue_G, getReq, getResp, - spinLocal0, continue_P, i, j_, - putReq, putResp, msg_D, j_D, - spinLocal1, continue, j, msg >> - -respondStablePut(self) == /\ pc[self] = "respondStablePut" - /\ IF ((msg_[self]).op) = (PUT_MSG) - THEN /\ key' = [key EXCEPT ![self] = (msg_[self]).key] - /\ val' = [val EXCEPT ![self] = (msg_[self]).value] - /\ kvWrite' = [kvLocal[self] EXCEPT ![key'[self]] = val'[self]] - /\ (Len(clientMailboxes[(msg_[self]).reply_to])) < (BUFFER_SIZE) - /\ clientsWrite' = [clientMailboxes EXCEPT ![(msg_[self]).reply_to] = Append(clientMailboxes[(msg_[self]).reply_to], [type |-> PUT_RESPONSE, result |-> ok[self]])] - /\ kvWrite0' = kvWrite' - /\ clientsWrite1' = clientsWrite' - /\ clientMailboxes' = clientsWrite1' - /\ kvLocal' = [kvLocal EXCEPT ![self] = kvWrite0'] - /\ pc' = [pc EXCEPT ![self] = "respondPendingRequestsLoop"] - ELSE /\ kvWrite0' = kvLocal[self] - /\ clientsWrite1' = clientMailboxes - /\ clientMailboxes' = clientsWrite1' - /\ kvLocal' = [kvLocal EXCEPT ![self] = kvWrite0'] - /\ pc' = [pc EXCEPT ![self] = "respondPendingRequestsLoop"] - /\ UNCHANGED << clientsWrite, kvWrite, - key, val >> - /\ UNCHANGED << replicasNetwork, allClients, cid, - out, clocks, replicasRead, - replicasWrite, kvRead, clientsWrite0, - clientIdRead, clockRead, - clientIdRead0, clockRead0, - clientIdRead1, clockWrite, keyRead, - clientIdRead2, clientIdRead3, - clockRead1, replicasWrite0, - clientsRead, clientsWrite2, - outsideWrite, clientsWrite3, - outsideWrite0, spinRead, - clientIdRead4, clockRead2, - clientIdRead5, clockRead3, - clientIdRead6, clockWrite0, keyRead0, - valueRead, clientIdRead7, - clientIdRead8, clockRead4, - replicasWrite1, replicasWrite2, - clientsRead0, clientsWrite4, - clientsWrite5, outsideWrite1, - spinRead0, clientIdRead9, - clientIdRead10, clockWrite1, - replicasWrite3, replicasWrite4, - clientIdRead11, clockRead5, - clientIdRead12, clockRead6, - clientIdRead13, clockWrite2, - clientIdRead14, clientIdRead15, - clockRead7, replicasWrite5, - replicasWrite6, spinRead1, - liveClients, pendingRequests, - stableMessages, i_, firstPending, - timestamp, nextClient, lowestPending, - chooseMessage, currentClocks, - minClock, continue_, pendingClients, - clientsIter, msg_, ok, spinLocal, - continue_G, getReq, getResp, - spinLocal0, continue_P, i, j_, - putReq, putResp, msg_D, j_D, - spinLocal1, continue, j, msg >> - -Replica(self) == replicaLoop(self) \/ receiveClientRequest(self) - \/ clientDisconnected(self) \/ replicaGetRequest(self) - \/ replicaPutRequest(self) \/ replicaNullRequest(self) - \/ findStableRequestsLoop(self) \/ findMinClock(self) - \/ findMinClient(self) \/ addStableMessage(self) - \/ respondPendingRequestsLoop(self) - \/ respondStableGet(self) \/ respondStablePut(self) - -getLoop(self) == /\ pc[self] = "getLoop" - /\ IF continue_G[self] - THEN /\ pc' = [pc EXCEPT ![self] = "getRequest"] - ELSE /\ pc' = [pc EXCEPT ![self] = "Done"] - /\ UNCHANGED << replicasNetwork, allClients, clientMailboxes, - cid, out, clocks, replicasRead, replicasWrite, - kvRead, clientsWrite, clientsWrite0, kvWrite, - kvWrite0, clientsWrite1, clientIdRead, - clockRead, clientIdRead0, clockRead0, - clientIdRead1, clockWrite, keyRead, - clientIdRead2, clientIdRead3, clockRead1, - replicasWrite0, clientsRead, clientsWrite2, - outsideWrite, clientsWrite3, outsideWrite0, - spinRead, clientIdRead4, clockRead2, - clientIdRead5, clockRead3, clientIdRead6, - clockWrite0, keyRead0, valueRead, - clientIdRead7, clientIdRead8, clockRead4, - replicasWrite1, replicasWrite2, clientsRead0, - clientsWrite4, clientsWrite5, outsideWrite1, - spinRead0, clientIdRead9, clientIdRead10, - clockWrite1, replicasWrite3, replicasWrite4, - clientIdRead11, clockRead5, clientIdRead12, - clockRead6, clientIdRead13, clockWrite2, - clientIdRead14, clientIdRead15, clockRead7, - replicasWrite5, replicasWrite6, spinRead1, - kvLocal, liveClients, pendingRequests, - stableMessages, i_, firstPending, timestamp, - nextClient, lowestPending, chooseMessage, - currentClocks, minClock, continue_, - pendingClients, clientsIter, msg_, ok, key, - val, spinLocal, continue_G, getReq, getResp, - spinLocal0, continue_P, i, j_, putReq, - putResp, msg_D, j_D, spinLocal1, continue, j, - msg >> - -getRequest(self) == /\ pc[self] = "getRequest" - /\ clientIdRead' = (self) - ((NUM_CLIENTS) * (GET_ORDER)) - /\ clockRead' = clocks[clientIdRead'] - /\ IF (clockRead') = (-(1)) - THEN /\ continue_G' = [continue_G EXCEPT ![self] = FALSE] - /\ pc' = [pc EXCEPT ![self] = "getCheckSpin"] - /\ UNCHANGED << replicasNetwork, clocks, - clientIdRead0, clockRead0, - clientIdRead1, clockWrite, - keyRead, clientIdRead2, - clientIdRead3, clockRead1, - replicasWrite0, getReq >> - ELSE /\ clientIdRead0' = (self) - ((NUM_CLIENTS) * (GET_ORDER)) - /\ clockRead0' = clocks[clientIdRead0'] - /\ clientIdRead1' = (self) - ((NUM_CLIENTS) * (GET_ORDER)) - /\ clockWrite' = [clocks EXCEPT ![clientIdRead1'] = (clockRead0') + (1)] - /\ keyRead' = GET_KEY - /\ clientIdRead2' = (self) - ((NUM_CLIENTS) * (GET_ORDER)) - /\ clientIdRead3' = (self) - ((NUM_CLIENTS) * (GET_ORDER)) - /\ clockRead1' = clockWrite'[clientIdRead3'] - /\ getReq' = [getReq EXCEPT ![self] = [op |-> GET_MSG, key |-> keyRead', client |-> clientIdRead2', timestamp |-> clockRead1', reply_to |-> self]] - /\ \E dst \in ReplicaSet: - /\ (Len(replicasNetwork[dst])) < (BUFFER_SIZE) - /\ replicasWrite0' = [replicasNetwork EXCEPT ![dst] = Append(replicasNetwork[dst], getReq'[self])] - /\ replicasNetwork' = replicasWrite0' - /\ clocks' = clockWrite' - /\ pc' = [pc EXCEPT ![self] = "getReply"] - /\ UNCHANGED continue_G - /\ UNCHANGED << allClients, clientMailboxes, cid, out, - replicasRead, replicasWrite, kvRead, - clientsWrite, clientsWrite0, kvWrite, - kvWrite0, clientsWrite1, clientsRead, - clientsWrite2, outsideWrite, clientsWrite3, - outsideWrite0, spinRead, clientIdRead4, - clockRead2, clientIdRead5, clockRead3, - clientIdRead6, clockWrite0, keyRead0, - valueRead, clientIdRead7, clientIdRead8, - clockRead4, replicasWrite1, replicasWrite2, - clientsRead0, clientsWrite4, clientsWrite5, - outsideWrite1, spinRead0, clientIdRead9, - clientIdRead10, clockWrite1, - replicasWrite3, replicasWrite4, - clientIdRead11, clockRead5, clientIdRead12, - clockRead6, clientIdRead13, clockWrite2, - clientIdRead14, clientIdRead15, clockRead7, - replicasWrite5, replicasWrite6, spinRead1, - kvLocal, liveClients, pendingRequests, - stableMessages, i_, firstPending, - timestamp, nextClient, lowestPending, - chooseMessage, currentClocks, minClock, - continue_, pendingClients, clientsIter, - msg_, ok, key, val, spinLocal, getResp, - spinLocal0, continue_P, i, j_, putReq, - putResp, msg_D, j_D, spinLocal1, continue, - j, msg >> - -getReply(self) == /\ pc[self] = "getReply" - /\ clientIdRead' = (self) - ((NUM_CLIENTS) * (GET_ORDER)) - /\ clockRead' = clocks[clientIdRead'] - /\ IF (clockRead') = (-(1)) - THEN /\ continue_G' = [continue_G EXCEPT ![self] = FALSE] - /\ clientsWrite3' = clientMailboxes - /\ outsideWrite0' = out - /\ clientMailboxes' = clientsWrite3' - /\ out' = outsideWrite0' - /\ UNCHANGED << clientsRead, clientsWrite2, - outsideWrite, getResp >> - ELSE /\ (Len(clientMailboxes[self])) > (0) - /\ LET msg1 == Head(clientMailboxes[self]) IN - /\ clientsWrite2' = [clientMailboxes EXCEPT ![self] = Tail(clientMailboxes[self])] - /\ clientsRead' = msg1 - /\ getResp' = [getResp EXCEPT ![self] = clientsRead'] - /\ Assert(((getResp'[self]).type) = (GET_RESPONSE), - "Failure of assertion at line 838, column 33.") - /\ outsideWrite' = (getResp'[self]).result - /\ clientsWrite3' = clientsWrite2' - /\ outsideWrite0' = outsideWrite' - /\ clientMailboxes' = clientsWrite3' - /\ out' = outsideWrite0' - /\ UNCHANGED continue_G - /\ pc' = [pc EXCEPT ![self] = "getCheckSpin"] - /\ UNCHANGED << replicasNetwork, allClients, cid, clocks, - replicasRead, replicasWrite, kvRead, - clientsWrite, clientsWrite0, kvWrite, - kvWrite0, clientsWrite1, clientIdRead0, - clockRead0, clientIdRead1, clockWrite, - keyRead, clientIdRead2, clientIdRead3, - clockRead1, replicasWrite0, spinRead, - clientIdRead4, clockRead2, clientIdRead5, - clockRead3, clientIdRead6, clockWrite0, - keyRead0, valueRead, clientIdRead7, - clientIdRead8, clockRead4, replicasWrite1, - replicasWrite2, clientsRead0, clientsWrite4, - clientsWrite5, outsideWrite1, spinRead0, - clientIdRead9, clientIdRead10, clockWrite1, - replicasWrite3, replicasWrite4, - clientIdRead11, clockRead5, clientIdRead12, - clockRead6, clientIdRead13, clockWrite2, - clientIdRead14, clientIdRead15, clockRead7, - replicasWrite5, replicasWrite6, spinRead1, - kvLocal, liveClients, pendingRequests, - stableMessages, i_, firstPending, timestamp, - nextClient, lowestPending, chooseMessage, - currentClocks, minClock, continue_, - pendingClients, clientsIter, msg_, ok, key, - val, spinLocal, getReq, spinLocal0, - continue_P, i, j_, putReq, putResp, msg_D, - j_D, spinLocal1, continue, j, msg >> - -getCheckSpin(self) == /\ pc[self] = "getCheckSpin" - /\ spinRead' = spinLocal[self] - /\ IF ~(spinRead') - THEN /\ continue_G' = [continue_G EXCEPT ![self] = FALSE] - /\ pc' = [pc EXCEPT ![self] = "getLoop"] - ELSE /\ pc' = [pc EXCEPT ![self] = "getLoop"] - /\ UNCHANGED continue_G - /\ UNCHANGED << replicasNetwork, allClients, - clientMailboxes, cid, out, clocks, - replicasRead, replicasWrite, kvRead, - clientsWrite, clientsWrite0, kvWrite, - kvWrite0, clientsWrite1, clientIdRead, - clockRead, clientIdRead0, clockRead0, - clientIdRead1, clockWrite, keyRead, - clientIdRead2, clientIdRead3, clockRead1, - replicasWrite0, clientsRead, - clientsWrite2, outsideWrite, - clientsWrite3, outsideWrite0, - clientIdRead4, clockRead2, clientIdRead5, - clockRead3, clientIdRead6, clockWrite0, - keyRead0, valueRead, clientIdRead7, - clientIdRead8, clockRead4, - replicasWrite1, replicasWrite2, - clientsRead0, clientsWrite4, - clientsWrite5, outsideWrite1, spinRead0, - clientIdRead9, clientIdRead10, - clockWrite1, replicasWrite3, - replicasWrite4, clientIdRead11, - clockRead5, clientIdRead12, clockRead6, - clientIdRead13, clockWrite2, - clientIdRead14, clientIdRead15, - clockRead7, replicasWrite5, - replicasWrite6, spinRead1, kvLocal, - liveClients, pendingRequests, - stableMessages, i_, firstPending, - timestamp, nextClient, lowestPending, - chooseMessage, currentClocks, minClock, - continue_, pendingClients, clientsIter, - msg_, ok, key, val, spinLocal, getReq, - getResp, spinLocal0, continue_P, i, j_, - putReq, putResp, msg_D, j_D, spinLocal1, - continue, j, msg >> - -GetClient(self) == getLoop(self) \/ getRequest(self) \/ getReply(self) - \/ getCheckSpin(self) - -putLoop(self) == /\ pc[self] = "putLoop" - /\ IF continue_P[self] - THEN /\ pc' = [pc EXCEPT ![self] = "putRequest"] - ELSE /\ pc' = [pc EXCEPT ![self] = "Done"] - /\ UNCHANGED << replicasNetwork, allClients, clientMailboxes, - cid, out, clocks, replicasRead, replicasWrite, - kvRead, clientsWrite, clientsWrite0, kvWrite, - kvWrite0, clientsWrite1, clientIdRead, - clockRead, clientIdRead0, clockRead0, - clientIdRead1, clockWrite, keyRead, - clientIdRead2, clientIdRead3, clockRead1, - replicasWrite0, clientsRead, clientsWrite2, - outsideWrite, clientsWrite3, outsideWrite0, - spinRead, clientIdRead4, clockRead2, - clientIdRead5, clockRead3, clientIdRead6, - clockWrite0, keyRead0, valueRead, - clientIdRead7, clientIdRead8, clockRead4, - replicasWrite1, replicasWrite2, clientsRead0, - clientsWrite4, clientsWrite5, outsideWrite1, - spinRead0, clientIdRead9, clientIdRead10, - clockWrite1, replicasWrite3, replicasWrite4, - clientIdRead11, clockRead5, clientIdRead12, - clockRead6, clientIdRead13, clockWrite2, - clientIdRead14, clientIdRead15, clockRead7, - replicasWrite5, replicasWrite6, spinRead1, - kvLocal, liveClients, pendingRequests, - stableMessages, i_, firstPending, timestamp, - nextClient, lowestPending, chooseMessage, - currentClocks, minClock, continue_, - pendingClients, clientsIter, msg_, ok, key, - val, spinLocal, continue_G, getReq, getResp, - spinLocal0, continue_P, i, j_, putReq, - putResp, msg_D, j_D, spinLocal1, continue, j, - msg >> - -putRequest(self) == /\ pc[self] = "putRequest" - /\ clientIdRead4' = (self) - ((NUM_CLIENTS) * (PUT_ORDER)) - /\ clockRead2' = clocks[clientIdRead4'] - /\ IF (clockRead2') = (-(1)) - THEN /\ continue_P' = [continue_P EXCEPT ![self] = FALSE] - /\ pc' = [pc EXCEPT ![self] = "putCheckSpin"] - /\ UNCHANGED << clocks, clientIdRead5, - clockRead3, clientIdRead6, - clockWrite0, keyRead0, - valueRead, clientIdRead7, - clientIdRead8, clockRead4, i, - j_, putReq >> - ELSE /\ clientIdRead5' = (self) - ((NUM_CLIENTS) * (PUT_ORDER)) - /\ clockRead3' = clocks[clientIdRead5'] - /\ clientIdRead6' = (self) - ((NUM_CLIENTS) * (PUT_ORDER)) - /\ clockWrite0' = [clocks EXCEPT ![clientIdRead6'] = (clockRead3') + (1)] - /\ keyRead0' = PUT_KEY - /\ valueRead' = PUT_VALUE - /\ clientIdRead7' = (self) - ((NUM_CLIENTS) * (PUT_ORDER)) - /\ clientIdRead8' = (self) - ((NUM_CLIENTS) * (PUT_ORDER)) - /\ clockRead4' = clockWrite0'[clientIdRead8'] - /\ putReq' = [putReq EXCEPT ![self] = [op |-> PUT_MSG, key |-> keyRead0', value |-> valueRead', client |-> clientIdRead7', timestamp |-> clockRead4', reply_to |-> self]] - /\ i' = [i EXCEPT ![self] = 0] - /\ j_' = [j_ EXCEPT ![self] = 0] - /\ clocks' = clockWrite0' - /\ pc' = [pc EXCEPT ![self] = "putBroadcast"] - /\ UNCHANGED continue_P - /\ UNCHANGED << replicasNetwork, allClients, - clientMailboxes, cid, out, replicasRead, - replicasWrite, kvRead, clientsWrite, - clientsWrite0, kvWrite, kvWrite0, - clientsWrite1, clientIdRead, clockRead, - clientIdRead0, clockRead0, clientIdRead1, - clockWrite, keyRead, clientIdRead2, - clientIdRead3, clockRead1, replicasWrite0, - clientsRead, clientsWrite2, outsideWrite, - clientsWrite3, outsideWrite0, spinRead, - replicasWrite1, replicasWrite2, - clientsRead0, clientsWrite4, clientsWrite5, - outsideWrite1, spinRead0, clientIdRead9, - clientIdRead10, clockWrite1, - replicasWrite3, replicasWrite4, - clientIdRead11, clockRead5, clientIdRead12, - clockRead6, clientIdRead13, clockWrite2, - clientIdRead14, clientIdRead15, clockRead7, - replicasWrite5, replicasWrite6, spinRead1, - kvLocal, liveClients, pendingRequests, - stableMessages, i_, firstPending, - timestamp, nextClient, lowestPending, - chooseMessage, currentClocks, minClock, - continue_, pendingClients, clientsIter, - msg_, ok, key, val, spinLocal, continue_G, - getReq, getResp, spinLocal0, putResp, - msg_D, j_D, spinLocal1, continue, j, msg >> - -putBroadcast(self) == /\ pc[self] = "putBroadcast" - /\ clientIdRead4' = (self) - ((NUM_CLIENTS) * (PUT_ORDER)) - /\ clockRead2' = clocks[clientIdRead4'] - /\ IF ((j_[self]) <= ((NUM_REPLICAS) - (1))) /\ ((clockRead2') # (-(1))) - THEN /\ (Len(replicasNetwork[j_[self]])) < (BUFFER_SIZE) - /\ replicasWrite1' = [replicasNetwork EXCEPT ![j_[self]] = Append(replicasNetwork[j_[self]], putReq[self])] - /\ j_' = [j_ EXCEPT ![self] = (j_[self]) + (1)] - /\ replicasWrite2' = replicasWrite1' - /\ replicasNetwork' = replicasWrite2' - /\ pc' = [pc EXCEPT ![self] = "putBroadcast"] - ELSE /\ replicasWrite2' = replicasNetwork - /\ replicasNetwork' = replicasWrite2' - /\ pc' = [pc EXCEPT ![self] = "putResponse"] - /\ UNCHANGED << replicasWrite1, j_ >> - /\ UNCHANGED << allClients, clientMailboxes, cid, out, - clocks, replicasRead, replicasWrite, - kvRead, clientsWrite, clientsWrite0, - kvWrite, kvWrite0, clientsWrite1, - clientIdRead, clockRead, clientIdRead0, - clockRead0, clientIdRead1, clockWrite, - keyRead, clientIdRead2, clientIdRead3, - clockRead1, replicasWrite0, clientsRead, - clientsWrite2, outsideWrite, - clientsWrite3, outsideWrite0, spinRead, - clientIdRead5, clockRead3, clientIdRead6, - clockWrite0, keyRead0, valueRead, - clientIdRead7, clientIdRead8, clockRead4, - clientsRead0, clientsWrite4, - clientsWrite5, outsideWrite1, spinRead0, - clientIdRead9, clientIdRead10, - clockWrite1, replicasWrite3, - replicasWrite4, clientIdRead11, - clockRead5, clientIdRead12, clockRead6, - clientIdRead13, clockWrite2, - clientIdRead14, clientIdRead15, - clockRead7, replicasWrite5, - replicasWrite6, spinRead1, kvLocal, - liveClients, pendingRequests, - stableMessages, i_, firstPending, - timestamp, nextClient, lowestPending, - chooseMessage, currentClocks, minClock, - continue_, pendingClients, clientsIter, - msg_, ok, key, val, spinLocal, - continue_G, getReq, getResp, spinLocal0, - continue_P, i, putReq, putResp, msg_D, - j_D, spinLocal1, continue, j, msg >> - -putResponse(self) == /\ pc[self] = "putResponse" - /\ IF (i[self]) < (Cardinality(ReplicaSet)) - THEN /\ clientIdRead4' = (self) - ((NUM_CLIENTS) * (PUT_ORDER)) - /\ clockRead2' = clocks[clientIdRead4'] - /\ IF (clockRead2') = (-(1)) - THEN /\ continue_P' = [continue_P EXCEPT ![self] = FALSE] - /\ clientsWrite5' = clientMailboxes - /\ clientMailboxes' = clientsWrite5' - /\ pc' = [pc EXCEPT ![self] = "putLoop"] - /\ UNCHANGED << clientsRead0, - clientsWrite4, i, - putResp >> - ELSE /\ (Len(clientMailboxes[self])) > (0) - /\ LET msg2 == Head(clientMailboxes[self]) IN - /\ clientsWrite4' = [clientMailboxes EXCEPT ![self] = Tail(clientMailboxes[self])] - /\ clientsRead0' = msg2 - /\ putResp' = [putResp EXCEPT ![self] = clientsRead0'] - /\ Assert(((putResp'[self]).type) = (PUT_RESPONSE), - "Failure of assertion at line 915, column 37.") - /\ i' = [i EXCEPT ![self] = (i[self]) + (1)] - /\ clientsWrite5' = clientsWrite4' - /\ clientMailboxes' = clientsWrite5' - /\ pc' = [pc EXCEPT ![self] = "putResponse"] - /\ UNCHANGED continue_P - ELSE /\ clientMailboxes' = clientsWrite5 - /\ pc' = [pc EXCEPT ![self] = "putComplete"] - /\ UNCHANGED << clientIdRead4, clockRead2, - clientsRead0, clientsWrite4, - clientsWrite5, continue_P, i, - putResp >> - /\ UNCHANGED << replicasNetwork, allClients, cid, out, - clocks, replicasRead, replicasWrite, - kvRead, clientsWrite, clientsWrite0, - kvWrite, kvWrite0, clientsWrite1, - clientIdRead, clockRead, clientIdRead0, - clockRead0, clientIdRead1, clockWrite, - keyRead, clientIdRead2, clientIdRead3, - clockRead1, replicasWrite0, clientsRead, - clientsWrite2, outsideWrite, - clientsWrite3, outsideWrite0, spinRead, - clientIdRead5, clockRead3, clientIdRead6, - clockWrite0, keyRead0, valueRead, - clientIdRead7, clientIdRead8, clockRead4, - replicasWrite1, replicasWrite2, - outsideWrite1, spinRead0, clientIdRead9, - clientIdRead10, clockWrite1, - replicasWrite3, replicasWrite4, - clientIdRead11, clockRead5, - clientIdRead12, clockRead6, - clientIdRead13, clockWrite2, - clientIdRead14, clientIdRead15, - clockRead7, replicasWrite5, - replicasWrite6, spinRead1, kvLocal, - liveClients, pendingRequests, - stableMessages, i_, firstPending, - timestamp, nextClient, lowestPending, - chooseMessage, currentClocks, minClock, - continue_, pendingClients, clientsIter, - msg_, ok, key, val, spinLocal, continue_G, - getReq, getResp, spinLocal0, j_, putReq, - msg_D, j_D, spinLocal1, continue, j, msg >> - -putComplete(self) == /\ pc[self] = "putComplete" - /\ outsideWrite1' = PUT_RESPONSE - /\ out' = outsideWrite1' - /\ pc' = [pc EXCEPT ![self] = "putCheckSpin"] - /\ UNCHANGED << replicasNetwork, allClients, - clientMailboxes, cid, clocks, - replicasRead, replicasWrite, kvRead, - clientsWrite, clientsWrite0, kvWrite, - kvWrite0, clientsWrite1, clientIdRead, - clockRead, clientIdRead0, clockRead0, - clientIdRead1, clockWrite, keyRead, - clientIdRead2, clientIdRead3, clockRead1, - replicasWrite0, clientsRead, - clientsWrite2, outsideWrite, - clientsWrite3, outsideWrite0, spinRead, - clientIdRead4, clockRead2, clientIdRead5, - clockRead3, clientIdRead6, clockWrite0, - keyRead0, valueRead, clientIdRead7, - clientIdRead8, clockRead4, replicasWrite1, - replicasWrite2, clientsRead0, - clientsWrite4, clientsWrite5, spinRead0, - clientIdRead9, clientIdRead10, - clockWrite1, replicasWrite3, - replicasWrite4, clientIdRead11, - clockRead5, clientIdRead12, clockRead6, - clientIdRead13, clockWrite2, - clientIdRead14, clientIdRead15, - clockRead7, replicasWrite5, - replicasWrite6, spinRead1, kvLocal, - liveClients, pendingRequests, - stableMessages, i_, firstPending, - timestamp, nextClient, lowestPending, - chooseMessage, currentClocks, minClock, - continue_, pendingClients, clientsIter, - msg_, ok, key, val, spinLocal, continue_G, - getReq, getResp, spinLocal0, continue_P, - i, j_, putReq, putResp, msg_D, j_D, - spinLocal1, continue, j, msg >> - -putCheckSpin(self) == /\ pc[self] = "putCheckSpin" - /\ spinRead0' = spinLocal0[self] - /\ IF ~(spinRead0') - THEN /\ continue_P' = [continue_P EXCEPT ![self] = FALSE] - /\ pc' = [pc EXCEPT ![self] = "putLoop"] - ELSE /\ pc' = [pc EXCEPT ![self] = "putLoop"] - /\ UNCHANGED continue_P - /\ UNCHANGED << replicasNetwork, allClients, - clientMailboxes, cid, out, clocks, - replicasRead, replicasWrite, kvRead, - clientsWrite, clientsWrite0, kvWrite, - kvWrite0, clientsWrite1, clientIdRead, - clockRead, clientIdRead0, clockRead0, - clientIdRead1, clockWrite, keyRead, - clientIdRead2, clientIdRead3, clockRead1, - replicasWrite0, clientsRead, - clientsWrite2, outsideWrite, - clientsWrite3, outsideWrite0, spinRead, - clientIdRead4, clockRead2, clientIdRead5, - clockRead3, clientIdRead6, clockWrite0, - keyRead0, valueRead, clientIdRead7, - clientIdRead8, clockRead4, - replicasWrite1, replicasWrite2, - clientsRead0, clientsWrite4, - clientsWrite5, outsideWrite1, - clientIdRead9, clientIdRead10, - clockWrite1, replicasWrite3, - replicasWrite4, clientIdRead11, - clockRead5, clientIdRead12, clockRead6, - clientIdRead13, clockWrite2, - clientIdRead14, clientIdRead15, - clockRead7, replicasWrite5, - replicasWrite6, spinRead1, kvLocal, - liveClients, pendingRequests, - stableMessages, i_, firstPending, - timestamp, nextClient, lowestPending, - chooseMessage, currentClocks, minClock, - continue_, pendingClients, clientsIter, - msg_, ok, key, val, spinLocal, - continue_G, getReq, getResp, spinLocal0, - i, j_, putReq, putResp, msg_D, j_D, - spinLocal1, continue, j, msg >> - -PutClient(self) == putLoop(self) \/ putRequest(self) \/ putBroadcast(self) - \/ putResponse(self) \/ putComplete(self) - \/ putCheckSpin(self) - -sendDisconnectRequest(self) == /\ pc[self] = "sendDisconnectRequest" - /\ clientIdRead9' = (self) - ((NUM_CLIENTS) * (DISCONNECT_ORDER)) - /\ msg_D' = [msg_D EXCEPT ![self] = [op |-> DISCONNECT_MSG, client |-> clientIdRead9']] - /\ clientIdRead10' = (self) - ((NUM_CLIENTS) * (DISCONNECT_ORDER)) - /\ clockWrite1' = [clocks EXCEPT ![clientIdRead10'] = -(1)] - /\ j_D' = [j_D EXCEPT ![self] = 0] - /\ clocks' = clockWrite1' - /\ pc' = [pc EXCEPT ![self] = "disconnectBroadcast"] - /\ UNCHANGED << replicasNetwork, allClients, - clientMailboxes, cid, out, - replicasRead, replicasWrite, - kvRead, clientsWrite, - clientsWrite0, kvWrite, - kvWrite0, clientsWrite1, - clientIdRead, clockRead, - clientIdRead0, clockRead0, - clientIdRead1, clockWrite, - keyRead, clientIdRead2, - clientIdRead3, clockRead1, - replicasWrite0, clientsRead, - clientsWrite2, outsideWrite, - clientsWrite3, outsideWrite0, - spinRead, clientIdRead4, - clockRead2, clientIdRead5, - clockRead3, clientIdRead6, - clockWrite0, keyRead0, - valueRead, clientIdRead7, - clientIdRead8, clockRead4, - replicasWrite1, replicasWrite2, - clientsRead0, clientsWrite4, - clientsWrite5, outsideWrite1, - spinRead0, replicasWrite3, - replicasWrite4, clientIdRead11, - clockRead5, clientIdRead12, - clockRead6, clientIdRead13, - clockWrite2, clientIdRead14, - clientIdRead15, clockRead7, - replicasWrite5, replicasWrite6, - spinRead1, kvLocal, liveClients, - pendingRequests, stableMessages, - i_, firstPending, timestamp, - nextClient, lowestPending, - chooseMessage, currentClocks, - minClock, continue_, - pendingClients, clientsIter, - msg_, ok, key, val, spinLocal, - continue_G, getReq, getResp, - spinLocal0, continue_P, i, j_, - putReq, putResp, spinLocal1, - continue, j, msg >> - -disconnectBroadcast(self) == /\ pc[self] = "disconnectBroadcast" - /\ IF ((j_D[self]) <= ((NUM_REPLICAS) - (1))) /\ ((0) # (-(1))) - THEN /\ (Len(replicasNetwork[j_D[self]])) < (BUFFER_SIZE) - /\ replicasWrite3' = [replicasNetwork EXCEPT ![j_D[self]] = Append(replicasNetwork[j_D[self]], msg_D[self])] - /\ j_D' = [j_D EXCEPT ![self] = (j_D[self]) + (1)] - /\ replicasWrite4' = replicasWrite3' - /\ replicasNetwork' = replicasWrite4' - /\ pc' = [pc EXCEPT ![self] = "disconnectBroadcast"] - ELSE /\ replicasWrite4' = replicasNetwork - /\ replicasNetwork' = replicasWrite4' - /\ pc' = [pc EXCEPT ![self] = "Done"] - /\ UNCHANGED << replicasWrite3, j_D >> - /\ UNCHANGED << allClients, clientMailboxes, cid, - out, clocks, replicasRead, - replicasWrite, kvRead, - clientsWrite, clientsWrite0, - kvWrite, kvWrite0, clientsWrite1, - clientIdRead, clockRead, - clientIdRead0, clockRead0, - clientIdRead1, clockWrite, - keyRead, clientIdRead2, - clientIdRead3, clockRead1, - replicasWrite0, clientsRead, - clientsWrite2, outsideWrite, - clientsWrite3, outsideWrite0, - spinRead, clientIdRead4, - clockRead2, clientIdRead5, - clockRead3, clientIdRead6, - clockWrite0, keyRead0, valueRead, - clientIdRead7, clientIdRead8, - clockRead4, replicasWrite1, - replicasWrite2, clientsRead0, - clientsWrite4, clientsWrite5, - outsideWrite1, spinRead0, - clientIdRead9, clientIdRead10, - clockWrite1, clientIdRead11, - clockRead5, clientIdRead12, - clockRead6, clientIdRead13, - clockWrite2, clientIdRead14, - clientIdRead15, clockRead7, - replicasWrite5, replicasWrite6, - spinRead1, kvLocal, liveClients, - pendingRequests, stableMessages, - i_, firstPending, timestamp, - nextClient, lowestPending, - chooseMessage, currentClocks, - minClock, continue_, - pendingClients, clientsIter, msg_, - ok, key, val, spinLocal, - continue_G, getReq, getResp, - spinLocal0, continue_P, i, j_, - putReq, putResp, msg_D, - spinLocal1, continue, j, msg >> - -DisconnectClient(self) == sendDisconnectRequest(self) - \/ disconnectBroadcast(self) - -clockUpdateLoop(self) == /\ pc[self] = "clockUpdateLoop" - /\ IF continue[self] - THEN /\ clientIdRead11' = (self) - ((NUM_CLIENTS) * (NULL_ORDER)) - /\ clockRead5' = clocks[clientIdRead11'] - /\ IF (clockRead5') = (-(1)) - THEN /\ continue' = [continue EXCEPT ![self] = FALSE] - /\ pc' = [pc EXCEPT ![self] = "nullCheckSpin"] - /\ UNCHANGED << clocks, - clientIdRead12, - clockRead6, - clientIdRead13, - clockWrite2, - clientIdRead14, - clientIdRead15, - clockRead7, j, - msg >> - ELSE /\ clientIdRead12' = (self) - ((NUM_CLIENTS) * (NULL_ORDER)) - /\ clockRead6' = clocks[clientIdRead12'] - /\ clientIdRead13' = (self) - ((NUM_CLIENTS) * (NULL_ORDER)) - /\ clockWrite2' = [clocks EXCEPT ![clientIdRead13'] = (clockRead6') + (1)] - /\ clientIdRead14' = (self) - ((NUM_CLIENTS) * (NULL_ORDER)) - /\ clientIdRead15' = (self) - ((NUM_CLIENTS) * (NULL_ORDER)) - /\ clockRead7' = clockWrite2'[clientIdRead15'] - /\ msg' = [msg EXCEPT ![self] = [op |-> NULL_MSG, client |-> clientIdRead14', timestamp |-> clockRead7']] - /\ j' = [j EXCEPT ![self] = 0] - /\ clocks' = clockWrite2' - /\ pc' = [pc EXCEPT ![self] = "nullBroadcast"] - /\ UNCHANGED continue - ELSE /\ pc' = [pc EXCEPT ![self] = "Done"] - /\ UNCHANGED << clocks, clientIdRead11, - clockRead5, clientIdRead12, - clockRead6, clientIdRead13, - clockWrite2, - clientIdRead14, - clientIdRead15, clockRead7, - continue, j, msg >> - /\ UNCHANGED << replicasNetwork, allClients, - clientMailboxes, cid, out, - replicasRead, replicasWrite, kvRead, - clientsWrite, clientsWrite0, kvWrite, - kvWrite0, clientsWrite1, clientIdRead, - clockRead, clientIdRead0, clockRead0, - clientIdRead1, clockWrite, keyRead, - clientIdRead2, clientIdRead3, - clockRead1, replicasWrite0, - clientsRead, clientsWrite2, - outsideWrite, clientsWrite3, - outsideWrite0, spinRead, - clientIdRead4, clockRead2, - clientIdRead5, clockRead3, - clientIdRead6, clockWrite0, keyRead0, - valueRead, clientIdRead7, - clientIdRead8, clockRead4, - replicasWrite1, replicasWrite2, - clientsRead0, clientsWrite4, - clientsWrite5, outsideWrite1, - spinRead0, clientIdRead9, - clientIdRead10, clockWrite1, - replicasWrite3, replicasWrite4, - replicasWrite5, replicasWrite6, - spinRead1, kvLocal, liveClients, - pendingRequests, stableMessages, i_, - firstPending, timestamp, nextClient, - lowestPending, chooseMessage, - currentClocks, minClock, continue_, - pendingClients, clientsIter, msg_, ok, - key, val, spinLocal, continue_G, - getReq, getResp, spinLocal0, - continue_P, i, j_, putReq, putResp, - msg_D, j_D, spinLocal1 >> - -nullCheckSpin(self) == /\ pc[self] = "nullCheckSpin" - /\ spinRead1' = spinLocal1[self] - /\ IF ~(spinRead1') - THEN /\ continue' = [continue EXCEPT ![self] = FALSE] - /\ pc' = [pc EXCEPT ![self] = "clockUpdateLoop"] - ELSE /\ pc' = [pc EXCEPT ![self] = "clockUpdateLoop"] - /\ UNCHANGED continue - /\ UNCHANGED << replicasNetwork, allClients, - clientMailboxes, cid, out, clocks, - replicasRead, replicasWrite, kvRead, - clientsWrite, clientsWrite0, kvWrite, - kvWrite0, clientsWrite1, clientIdRead, - clockRead, clientIdRead0, clockRead0, - clientIdRead1, clockWrite, keyRead, - clientIdRead2, clientIdRead3, - clockRead1, replicasWrite0, clientsRead, - clientsWrite2, outsideWrite, - clientsWrite3, outsideWrite0, spinRead, - clientIdRead4, clockRead2, - clientIdRead5, clockRead3, - clientIdRead6, clockWrite0, keyRead0, - valueRead, clientIdRead7, clientIdRead8, - clockRead4, replicasWrite1, - replicasWrite2, clientsRead0, - clientsWrite4, clientsWrite5, - outsideWrite1, spinRead0, clientIdRead9, - clientIdRead10, clockWrite1, - replicasWrite3, replicasWrite4, - clientIdRead11, clockRead5, - clientIdRead12, clockRead6, - clientIdRead13, clockWrite2, - clientIdRead14, clientIdRead15, - clockRead7, replicasWrite5, - replicasWrite6, kvLocal, liveClients, - pendingRequests, stableMessages, i_, - firstPending, timestamp, nextClient, - lowestPending, chooseMessage, - currentClocks, minClock, continue_, - pendingClients, clientsIter, msg_, ok, - key, val, spinLocal, continue_G, getReq, - getResp, spinLocal0, continue_P, i, j_, - putReq, putResp, msg_D, j_D, spinLocal1, - j, msg >> - -nullBroadcast(self) == /\ pc[self] = "nullBroadcast" - /\ clientIdRead11' = (self) - ((NUM_CLIENTS) * (NULL_ORDER)) - /\ clockRead5' = clocks[clientIdRead11'] - /\ IF ((j[self]) <= ((NUM_REPLICAS) - (1))) /\ ((clockRead5') # (-(1))) - THEN /\ (Len(replicasNetwork[j[self]])) < (BUFFER_SIZE) - /\ replicasWrite5' = [replicasNetwork EXCEPT ![j[self]] = Append(replicasNetwork[j[self]], msg[self])] - /\ j' = [j EXCEPT ![self] = (j[self]) + (1)] - /\ replicasWrite6' = replicasWrite5' - /\ replicasNetwork' = replicasWrite6' - /\ pc' = [pc EXCEPT ![self] = "nullBroadcast"] - ELSE /\ replicasWrite6' = replicasNetwork - /\ replicasNetwork' = replicasWrite6' - /\ pc' = [pc EXCEPT ![self] = "nullCheckSpin"] - /\ UNCHANGED << replicasWrite5, j >> - /\ UNCHANGED << allClients, clientMailboxes, cid, out, - clocks, replicasRead, replicasWrite, - kvRead, clientsWrite, clientsWrite0, - kvWrite, kvWrite0, clientsWrite1, - clientIdRead, clockRead, clientIdRead0, - clockRead0, clientIdRead1, clockWrite, - keyRead, clientIdRead2, clientIdRead3, - clockRead1, replicasWrite0, clientsRead, - clientsWrite2, outsideWrite, - clientsWrite3, outsideWrite0, spinRead, - clientIdRead4, clockRead2, - clientIdRead5, clockRead3, - clientIdRead6, clockWrite0, keyRead0, - valueRead, clientIdRead7, clientIdRead8, - clockRead4, replicasWrite1, - replicasWrite2, clientsRead0, - clientsWrite4, clientsWrite5, - outsideWrite1, spinRead0, clientIdRead9, - clientIdRead10, clockWrite1, - replicasWrite3, replicasWrite4, - clientIdRead12, clockRead6, - clientIdRead13, clockWrite2, - clientIdRead14, clientIdRead15, - clockRead7, spinRead1, kvLocal, - liveClients, pendingRequests, - stableMessages, i_, firstPending, - timestamp, nextClient, lowestPending, - chooseMessage, currentClocks, minClock, - continue_, pendingClients, clientsIter, - msg_, ok, key, val, spinLocal, - continue_G, getReq, getResp, spinLocal0, - continue_P, i, j_, putReq, putResp, - msg_D, j_D, spinLocal1, continue, msg >> - -ClockUpdateClient(self) == clockUpdateLoop(self) \/ nullCheckSpin(self) - \/ nullBroadcast(self) - -Next == (\E self \in ReplicaSet: Replica(self)) - \/ (\E self \in GetSet: GetClient(self)) - \/ (\E self \in PutSet: PutClient(self)) - \/ (\E self \in DisconnectSet: DisconnectClient(self)) - \/ (\E self \in NullSet: ClockUpdateClient(self)) - \/ (* Disjunct to prevent deadlock on termination *) - ((\A self \in ProcSet: pc[self] = "Done") /\ UNCHANGED vars) - -Spec == /\ Init /\ [][Next]_vars - /\ \A self \in ReplicaSet : WF_vars(Replica(self)) - /\ \A self \in GetSet : WF_vars(GetClient(self)) - /\ \A self \in PutSet : WF_vars(PutClient(self)) - /\ \A self \in DisconnectSet : WF_vars(DisconnectClient(self)) - /\ \A self \in NullSet : WF_vars(ClockUpdateClient(self)) - -Termination == <>(\A self \in ProcSet: pc[self] = "Done") - -\* END TRANSLATION - -\* This predicate is true when all client processes are finished. -AllClientsDisconnected == \A client \in allClients : pc[client] = "Done" - - -\* Invariants -\* ********** - -\* These ensure that, in all states explored by TLC, the buffers (from client to replica and vice versa) -\* are within bounds. Using the FIFOChannel mapping macro is sufficient for this invariant to -\* hold. -BufferOk(net, node) == Len(net[node]) >= 0 /\ Len(net[node]) <= BUFFER_SIZE -ClientBuffersOk == \A node \in DOMAIN clientMailboxes : BufferOk(clientMailboxes, node) -ReplicaBuffersOk == \A node \in DOMAIN replicasNetwork : BufferOk(replicasNetwork, node) -AllBuffersOk == ClientBuffersOk /\ ReplicaBuffersOk - -\* This invariant tests that message stability detection in the replica is safe: -\* every message considered stable must have a timestamp lower than the current logical -\* clock of any live client. -MessageStability == \A replica \in ReplicaSet : - LET stable == stableMessages[replica] - alive == { c \in ClientSet : clocks[c] > 0 } - IN - Len(stable) > 0 => - \A m_id \in DOMAIN stable : - \A client \in alive : stable[m_id].timestamp < clocks[client] - - -\* Put semantics: once a client has been notified that a Put request was succesful -\* every replica must have the updated value. -PersistentPut == \A client \in PutSet : - pc[client] = "putComplete" => \A replica \in ReplicaSet : kvLocal[replica][PUT_KEY] = PUT_VALUE - - -\* Properties -\* ********** - -\* Logical clocks are monotonically increasing. This property checks that in every state, -\* pending messages in the replicas have increasing timestamps (or the process disconnected) -ClockIncreased == clocks' /= clocks => - \E c \in ClientSet : clocks'[c] = clocks[c]+1 \/ clocks'[c] = -1 - -MonotonicallyIncreasingClocks == [][ClockIncreased]_<> - - -\* Safety of disconnection: once a client has disconnected (and sent a message to all replicas -\* informing of that event), then the logical clock of that client should remain -\* unchanced -- i.e., no more messages from that client should be seen in the system. -DisconnectionSafe == \A client \in ClientSet : <>[](clocks[client] = -1) - -============================================================================= -\* Modification History -\* Last modified Thu Apr 11 09:46:33 PDT 2019 by rmc -\* Last modified Wed Feb 27 12:42:52 PST 2019 by minh diff --git a/test/mpcal/spec/load_balancer_file_system.tla b/test/mpcal/spec/load_balancer_file_system.tla deleted file mode 100644 index bfaae6181..000000000 --- a/test/mpcal/spec/load_balancer_file_system.tla +++ /dev/null @@ -1,573 +0,0 @@ ------------------------------ MODULE load_balancer ----------------------------- -(***************************************************************************) -(* Specifies a simple load balancer. *) -(***************************************************************************) - -\* Extends some built-in TLA+ modules -EXTENDS Naturals, Sequences, TLC - -\* The `TCPChannel` mapping macro used in this specification is parameterized -\* by a `BUFFER_SIZE` constant. This value controls the number of messages being -\* held in a buffer by each process. Processes trying to send a message to another -\* process with a full buffer wil "block" (not be scheduled by TLC). -CONSTANT BUFFER_SIZE - -\* Define a constant identifier for the load balancer. -CONSTANT LoadBalancerId - -\* The number of servers and clients in the model checking setup. -CONSTANTS NUM_SERVERS, NUM_CLIENTS - -\* TLC should assume that both numbers are greater than zero (i.e., we always -\* have at least one server and one client). Note, however, that increasing -\* these numbers makes the number of states to be checked by TLC to grow -\* exponentially. -ASSUME NUM_SERVERS > 0 /\ NUM_CLIENTS > 0 - -\* GET_PAGE is a label attached to messages sent from the clients to -\* the load balancer. -CONSTANTS GET_PAGE - -\* Represents a file that can be returned by the server -CONSTANT WEB_PAGE - -(*************************************************************************** ---mpcal LoadBalancer { - define { - \* total nodes in the system: - \* number of clients + number of servers + the load balancer - NUM_NODES == NUM_CLIENTS + NUM_SERVERS + 1 - } - - \* The TCPChannel mapping macro models a communication channel - \* between two processes using TCP-like semantics. In particular: - \* - \* - reading from the channel "blocks" unless there is a message - \* ready to be read. - \* - message delivery is reliable and ordered (i.e., FIFO). - mapping macro TCPChannel { - read { - await Len($variable) > 0; - with (msg = Head($variable)) { - $variable := Tail($variable); - yield msg; - }; - } - - write { - await Len($variable) < BUFFER_SIZE; - yield Append($variable, $value); - } - } - - \* Mapping macros keep implementation-specific behavior that we don't - \* want to model check outside of our archetype definitions. - \* In the case of this load balancer, how a server retrieves a web page - \* is orthogonal to the correctness of the properties we are interested - \* to check with this specification. - \* - \* This mapping macro abstracts the process of reading a web page by - \* always returning the `WEB_PAGE` constant when the variable is read. - \* - \* Since "writing" to this mapping is meaningless, the attempting to write - \* to a variable mapped with WebPage will result in a model checking - \* error (see `assert(FALSE)` in the write definition). - mapping macro WebPages { - read { - yield WEB_PAGE; - } - - write { - assert(FALSE); - yield $value; - } - } - - \* ALoadBalancer is the archetype that defines the behavior of - \* the load balancer process. The `mailboxes` parameter represents - \* connections to all nodes in the system. - archetype ALoadBalancer(ref mailboxes) - - \* Local variables of this archetype: - variables - \* Holds messages received by the load balancer (sent - \* by clients) - msg, - - \* identifier attached to every message sent to servers by - \* the load balancer. - next = 0; - { - main: - while (TRUE) { - - \* waits for a message to be received. Upon receipt, the `assert` - \* call ensures that the message is of type `GET_PAGE`, the only - \* type of message supported in this simple specification. - \* - \* Every message received by the load balancer is expected to - \* be a record of the following type. - \* - \* [message_type : Int, client_id : Int, path: Interface{}] - \* - \* Note that tuples are 1-indexed. - rcvMsg: - msg := mailboxes[LoadBalancerId]; - assert(msg.message_type = GET_PAGE); - - \* the load balancer needs to forward the client request to the - \* server, who will process the request and send a web page back to - \* the client. - \* - \* The message sent to the server is a tuple in the format: - \* - \* [message_id : Int, client_id : Int, path: Interface{}] - \* - \* We send the client ID here so that the server can directly - \* reply to a client, bypassing the load balancer. This is usually - \* not what happens in practice, but the model is simple - \* enough for our (illustrative) purposes. - sendServer: - next := (next % NUM_SERVERS) + 1; - mailboxes[next] := [message_id |-> next, client_id |-> msg.client_id, path |-> msg.path]; - } - } - - \* AServer is the archetype that defines the behavior of the servers - \* in our system. The two parameters it recieves are: - \* - \* - mailboxes: contains connections to every node in the system - \* - file_system: abstraction of a real file system. In practice, - \* this is implementation specific and irrelevant for - \* the properties we want to check in this specification - archetype AServer(ref mailboxes, file_system) - - \* Local variables - variable - \* temporary buffer to hold incoming messages - msg; - { - serverLoop: - while (TRUE) { - - \* waits for an incoming message. Note that the only process - \* that sends messages to the server is the load balancer process - \* (defined according to the ALoadBalancer archetype) and the - \* message has the type [message_id : Int, client_id : Int] - rcvReq: - msg := mailboxes[self]; - - sendPage: - \* sends a web page (read from `page_stream`) back to the requester - \* i.e., the client. - mailboxes[msg.client_id] := file_system[msg.path]; - } - } - - \* Client processes are given integer identifiers starting from NUM_SERVERS+1. - \* Keep in mind that this "range" notation in PlusCal defines a set, and is - \* _inclusive_ (i.e., NUM_SERVERS+NUM_CLIENTS+1 is part of the set). - \* - \* The parameters received by a client are: - \* - \* - mailboxes: contains connections to every node in the system - \* - instream: a stream of inputs to the client - \* - outstream: an output stream, where the client sends the messages it receives - \* from servers. - archetype AClient(ref mailboxes, instream, ref outstream) - - \* Local variables - variable - \* Temporary buffers to hold messages - req, resp; - { - clientLoop: - while (TRUE) { - - \* First, the client makes a request to the load balancer. - \* The format of the message is a tuple: - \* - \* [message_type : Int, client_id : Int, path : Interface{}]. - \* - \* If you check the ALoadBalancer definition, this is the message format - \* expected there. - \* - \* Remember that `self` is an implicitly defined, immutable variable that - \* contains the process identifier of the "running" process. - clientRequest: - req := [message_type |-> GET_PAGE, client_id |-> self, path |-> instream]; - mailboxes[LoadBalancerId] := req; - - \* Clients then wait for the response to the previously sent request. - \* Since there is only one type of web page in this simple specification - \* (defined by the WEB_PAGE constant), we assert here that the message - \* received indeed is equal our expected web page. - clientReceive: - resp := mailboxes[self]; - outstream := resp; - } - } - - \* GLOBAL VARIABLES *\ - - variables - \* our network is modeled as a function from node identifier - \* to a sequence of incoming messages - network = [id \in 0..(NUM_NODES-1) |-> <<>>], - - \* set as input and output "streams" - in = 0, out = 0, - - fs = [f \in {in} |-> WEB_PAGE]; - - \* PROCESS INSTANTIATION *\ - - \* The system has a single load balancer entity, instantiated from the ALoadBalancer - \* archetype. The model of our network is going to be the one defined by the TCPChannel - \* mapping macro in all instantiations. - fair process (LoadBalancer = LoadBalancerId) == instance ALoadBalancer(ref network) - mapping network[_] via TCPChannel; - - \* Instantiate `NUM_SERVERS` server processes according to the AServer archetype. - \* We map the page stream according to the WebPages mapping macro since this is - \* an implementation detail that needs to be specified during implementation at - \* a later stage. - fair process (Servers \in 1..NUM_SERVERS) == instance AServer(ref network, fs) - mapping network[_] via TCPChannel - mapping fs[_] via WebPages; - - fair process (Client \in (NUM_SERVERS+1)..(NUM_SERVERS+NUM_CLIENTS)) == instance AClient(ref network, in, ref out) - mapping network[_] via TCPChannel; -} - -\* BEGIN PLUSCAL TRANSLATION ---algorithm LoadBalancer { - variables network = [id \in (0)..((NUM_NODES)-(1)) |-> <<>>], in = 0, out = 0, fs = [f \in {in} |-> WEB_PAGE]; - define { - NUM_NODES == ((NUM_CLIENTS)+(NUM_SERVERS))+(1)} - fair process (LoadBalancer = LoadBalancerId) - variables msg, next = 0, mailboxesRead, mailboxesWrite, mailboxesWrite0; - { - main: - if (TRUE) { - rcvMsg: - await (Len(network[LoadBalancerId]))>(0); - with (msg0 = Head(network[LoadBalancerId])) { - mailboxesWrite := [network EXCEPT ![LoadBalancerId] = Tail(network[LoadBalancerId])]; - mailboxesRead := msg0; - }; - msg := mailboxesRead; - assert ((msg).message_type)=(GET_PAGE); - network := mailboxesWrite; - - sendServer: - next := ((next)%(NUM_SERVERS))+(1); - await (Len(network[next]))<(BUFFER_SIZE); - mailboxesWrite := [network EXCEPT ![next] = Append(network[next], [message_id |-> next, client_id |-> (msg).client_id, path |-> (msg).path])]; - network := mailboxesWrite; - goto main; - - } else { - mailboxesWrite0 := network; - network := mailboxesWrite0; - }; - - } - fair process (Servers \in (1)..(NUM_SERVERS)) - variables msg, mailboxesRead0, mailboxesWrite1, file_systemRead, mailboxesWrite2; - { - serverLoop: - if (TRUE) { - rcvReq: - await (Len(network[self]))>(0); - with (msg1 = Head(network[self])) { - mailboxesWrite1 := [network EXCEPT ![self] = Tail(network[self])]; - mailboxesRead0 := msg1; - }; - msg := mailboxesRead0; - network := mailboxesWrite1; - - sendPage: - file_systemRead := WEB_PAGE; - await (Len(network[(msg).client_id]))<(BUFFER_SIZE); - mailboxesWrite1 := [network EXCEPT ![(msg).client_id] = Append(network[(msg).client_id], file_systemRead)]; - network := mailboxesWrite1; - goto serverLoop; - - } else { - mailboxesWrite2 := network; - network := mailboxesWrite2; - }; - - } - fair process (Client \in ((NUM_SERVERS)+(1))..((NUM_SERVERS)+(NUM_CLIENTS))) - variables req, resp, instreamRead, mailboxesWrite3, mailboxesRead1, outstreamWrite, mailboxesWrite4, outstreamWrite0; - { - clientLoop: - if (TRUE) { - clientRequest: - instreamRead := in; - req := [message_type |-> GET_PAGE, client_id |-> self, path |-> instreamRead]; - await (Len(network[LoadBalancerId]))<(BUFFER_SIZE); - mailboxesWrite3 := [network EXCEPT ![LoadBalancerId] = Append(network[LoadBalancerId], req)]; - network := mailboxesWrite3; - - clientReceive: - await (Len(network[self]))>(0); - with (msg2 = Head(network[self])) { - mailboxesWrite3 := [network EXCEPT ![self] = Tail(network[self])]; - mailboxesRead1 := msg2; - }; - resp := mailboxesRead1; - outstreamWrite := resp; - network := mailboxesWrite3; - out := outstreamWrite; - goto clientLoop; - - } else { - mailboxesWrite4 := network; - outstreamWrite0 := out; - network := mailboxesWrite4; - out := outstreamWrite0; - }; - - } -} -\* END PLUSCAL TRANSLATION - - - -***************************************************************************) -\* BEGIN TRANSLATION -\* Process variable msg of process LoadBalancer at line 249 col 15 changed to msg_ -CONSTANT defaultInitValue -VARIABLES network, in, out, fs, pc - -(* define statement *) -NUM_NODES == ((NUM_CLIENTS)+(NUM_SERVERS))+(1) - -VARIABLES msg_, next, mailboxesRead, mailboxesWrite, mailboxesWrite0, msg, - mailboxesRead0, mailboxesWrite1, file_systemRead, mailboxesWrite2, - req, resp, instreamRead, mailboxesWrite3, mailboxesRead1, - outstreamWrite, mailboxesWrite4, outstreamWrite0 - -vars == << network, in, out, fs, pc, msg_, next, mailboxesRead, - mailboxesWrite, mailboxesWrite0, msg, mailboxesRead0, - mailboxesWrite1, file_systemRead, mailboxesWrite2, req, resp, - instreamRead, mailboxesWrite3, mailboxesRead1, outstreamWrite, - mailboxesWrite4, outstreamWrite0 >> - -ProcSet == {LoadBalancerId} \cup ((1)..(NUM_SERVERS)) \cup (((NUM_SERVERS)+(1))..((NUM_SERVERS)+(NUM_CLIENTS))) - -Init == (* Global variables *) - /\ network = [id \in (0)..((NUM_NODES)-(1)) |-> <<>>] - /\ in = 0 - /\ out = 0 - /\ fs = [f \in {in} |-> WEB_PAGE] - (* Process LoadBalancer *) - /\ msg_ = defaultInitValue - /\ next = 0 - /\ mailboxesRead = defaultInitValue - /\ mailboxesWrite = defaultInitValue - /\ mailboxesWrite0 = defaultInitValue - (* Process Servers *) - /\ msg = [self \in (1)..(NUM_SERVERS) |-> defaultInitValue] - /\ mailboxesRead0 = [self \in (1)..(NUM_SERVERS) |-> defaultInitValue] - /\ mailboxesWrite1 = [self \in (1)..(NUM_SERVERS) |-> defaultInitValue] - /\ file_systemRead = [self \in (1)..(NUM_SERVERS) |-> defaultInitValue] - /\ mailboxesWrite2 = [self \in (1)..(NUM_SERVERS) |-> defaultInitValue] - (* Process Client *) - /\ req = [self \in ((NUM_SERVERS)+(1))..((NUM_SERVERS)+(NUM_CLIENTS)) |-> defaultInitValue] - /\ resp = [self \in ((NUM_SERVERS)+(1))..((NUM_SERVERS)+(NUM_CLIENTS)) |-> defaultInitValue] - /\ instreamRead = [self \in ((NUM_SERVERS)+(1))..((NUM_SERVERS)+(NUM_CLIENTS)) |-> defaultInitValue] - /\ mailboxesWrite3 = [self \in ((NUM_SERVERS)+(1))..((NUM_SERVERS)+(NUM_CLIENTS)) |-> defaultInitValue] - /\ mailboxesRead1 = [self \in ((NUM_SERVERS)+(1))..((NUM_SERVERS)+(NUM_CLIENTS)) |-> defaultInitValue] - /\ outstreamWrite = [self \in ((NUM_SERVERS)+(1))..((NUM_SERVERS)+(NUM_CLIENTS)) |-> defaultInitValue] - /\ mailboxesWrite4 = [self \in ((NUM_SERVERS)+(1))..((NUM_SERVERS)+(NUM_CLIENTS)) |-> defaultInitValue] - /\ outstreamWrite0 = [self \in ((NUM_SERVERS)+(1))..((NUM_SERVERS)+(NUM_CLIENTS)) |-> defaultInitValue] - /\ pc = [self \in ProcSet |-> CASE self = LoadBalancerId -> "main" - [] self \in (1)..(NUM_SERVERS) -> "serverLoop" - [] self \in ((NUM_SERVERS)+(1))..((NUM_SERVERS)+(NUM_CLIENTS)) -> "clientLoop"] - -main == /\ pc[LoadBalancerId] = "main" - /\ IF TRUE - THEN /\ pc' = [pc EXCEPT ![LoadBalancerId] = "rcvMsg"] - /\ UNCHANGED << network, mailboxesWrite0 >> - ELSE /\ mailboxesWrite0' = network - /\ network' = mailboxesWrite0' - /\ pc' = [pc EXCEPT ![LoadBalancerId] = "Done"] - /\ UNCHANGED << in, out, fs, msg_, next, mailboxesRead, mailboxesWrite, - msg, mailboxesRead0, mailboxesWrite1, file_systemRead, - mailboxesWrite2, req, resp, instreamRead, - mailboxesWrite3, mailboxesRead1, outstreamWrite, - mailboxesWrite4, outstreamWrite0 >> - -rcvMsg == /\ pc[LoadBalancerId] = "rcvMsg" - /\ (Len(network[LoadBalancerId]))>(0) - /\ LET msg0 == Head(network[LoadBalancerId]) IN - /\ mailboxesWrite' = [network EXCEPT ![LoadBalancerId] = Tail(network[LoadBalancerId])] - /\ mailboxesRead' = msg0 - /\ msg_' = mailboxesRead' - /\ Assert(((msg_').message_type)=(GET_PAGE), - "Failure of assertion at line 260, column 21.") - /\ network' = mailboxesWrite' - /\ pc' = [pc EXCEPT ![LoadBalancerId] = "sendServer"] - /\ UNCHANGED << in, out, fs, next, mailboxesWrite0, msg, - mailboxesRead0, mailboxesWrite1, file_systemRead, - mailboxesWrite2, req, resp, instreamRead, - mailboxesWrite3, mailboxesRead1, outstreamWrite, - mailboxesWrite4, outstreamWrite0 >> - -sendServer == /\ pc[LoadBalancerId] = "sendServer" - /\ next' = ((next)%(NUM_SERVERS))+(1) - /\ (Len(network[next']))<(BUFFER_SIZE) - /\ mailboxesWrite' = [network EXCEPT ![next'] = Append(network[next'], [message_id |-> next', client_id |-> (msg_).client_id, path |-> (msg_).path])] - /\ network' = mailboxesWrite' - /\ pc' = [pc EXCEPT ![LoadBalancerId] = "main"] - /\ UNCHANGED << in, out, fs, msg_, mailboxesRead, - mailboxesWrite0, msg, mailboxesRead0, - mailboxesWrite1, file_systemRead, - mailboxesWrite2, req, resp, instreamRead, - mailboxesWrite3, mailboxesRead1, outstreamWrite, - mailboxesWrite4, outstreamWrite0 >> - -LoadBalancer == main \/ rcvMsg \/ sendServer - -serverLoop(self) == /\ pc[self] = "serverLoop" - /\ IF TRUE - THEN /\ pc' = [pc EXCEPT ![self] = "rcvReq"] - /\ UNCHANGED << network, mailboxesWrite2 >> - ELSE /\ mailboxesWrite2' = [mailboxesWrite2 EXCEPT ![self] = network] - /\ network' = mailboxesWrite2'[self] - /\ pc' = [pc EXCEPT ![self] = "Done"] - /\ UNCHANGED << in, out, fs, msg_, next, mailboxesRead, - mailboxesWrite, mailboxesWrite0, msg, - mailboxesRead0, mailboxesWrite1, - file_systemRead, req, resp, instreamRead, - mailboxesWrite3, mailboxesRead1, - outstreamWrite, mailboxesWrite4, - outstreamWrite0 >> - -rcvReq(self) == /\ pc[self] = "rcvReq" - /\ (Len(network[self]))>(0) - /\ LET msg1 == Head(network[self]) IN - /\ mailboxesWrite1' = [mailboxesWrite1 EXCEPT ![self] = [network EXCEPT ![self] = Tail(network[self])]] - /\ mailboxesRead0' = [mailboxesRead0 EXCEPT ![self] = msg1] - /\ msg' = [msg EXCEPT ![self] = mailboxesRead0'[self]] - /\ network' = mailboxesWrite1'[self] - /\ pc' = [pc EXCEPT ![self] = "sendPage"] - /\ UNCHANGED << in, out, fs, msg_, next, mailboxesRead, - mailboxesWrite, mailboxesWrite0, - file_systemRead, mailboxesWrite2, req, resp, - instreamRead, mailboxesWrite3, mailboxesRead1, - outstreamWrite, mailboxesWrite4, - outstreamWrite0 >> - -sendPage(self) == /\ pc[self] = "sendPage" - /\ file_systemRead' = [file_systemRead EXCEPT ![self] = WEB_PAGE] - /\ (Len(network[(msg[self]).client_id]))<(BUFFER_SIZE) - /\ mailboxesWrite1' = [mailboxesWrite1 EXCEPT ![self] = [network EXCEPT ![(msg[self]).client_id] = Append(network[(msg[self]).client_id], file_systemRead'[self])]] - /\ network' = mailboxesWrite1'[self] - /\ pc' = [pc EXCEPT ![self] = "serverLoop"] - /\ UNCHANGED << in, out, fs, msg_, next, mailboxesRead, - mailboxesWrite, mailboxesWrite0, msg, - mailboxesRead0, mailboxesWrite2, req, resp, - instreamRead, mailboxesWrite3, - mailboxesRead1, outstreamWrite, - mailboxesWrite4, outstreamWrite0 >> - -Servers(self) == serverLoop(self) \/ rcvReq(self) \/ sendPage(self) - -clientLoop(self) == /\ pc[self] = "clientLoop" - /\ IF TRUE - THEN /\ pc' = [pc EXCEPT ![self] = "clientRequest"] - /\ UNCHANGED << network, out, mailboxesWrite4, - outstreamWrite0 >> - ELSE /\ mailboxesWrite4' = [mailboxesWrite4 EXCEPT ![self] = network] - /\ outstreamWrite0' = [outstreamWrite0 EXCEPT ![self] = out] - /\ network' = mailboxesWrite4'[self] - /\ out' = outstreamWrite0'[self] - /\ pc' = [pc EXCEPT ![self] = "Done"] - /\ UNCHANGED << in, fs, msg_, next, mailboxesRead, - mailboxesWrite, mailboxesWrite0, msg, - mailboxesRead0, mailboxesWrite1, - file_systemRead, mailboxesWrite2, req, - resp, instreamRead, mailboxesWrite3, - mailboxesRead1, outstreamWrite >> - -clientRequest(self) == /\ pc[self] = "clientRequest" - /\ instreamRead' = [instreamRead EXCEPT ![self] = in] - /\ req' = [req EXCEPT ![self] = [message_type |-> GET_PAGE, client_id |-> self, path |-> instreamRead'[self]]] - /\ (Len(network[LoadBalancerId]))<(BUFFER_SIZE) - /\ mailboxesWrite3' = [mailboxesWrite3 EXCEPT ![self] = [network EXCEPT ![LoadBalancerId] = Append(network[LoadBalancerId], req'[self])]] - /\ network' = mailboxesWrite3'[self] - /\ pc' = [pc EXCEPT ![self] = "clientReceive"] - /\ UNCHANGED << in, out, fs, msg_, next, mailboxesRead, - mailboxesWrite, mailboxesWrite0, msg, - mailboxesRead0, mailboxesWrite1, - file_systemRead, mailboxesWrite2, resp, - mailboxesRead1, outstreamWrite, - mailboxesWrite4, outstreamWrite0 >> - -clientReceive(self) == /\ pc[self] = "clientReceive" - /\ (Len(network[self]))>(0) - /\ LET msg2 == Head(network[self]) IN - /\ mailboxesWrite3' = [mailboxesWrite3 EXCEPT ![self] = [network EXCEPT ![self] = Tail(network[self])]] - /\ mailboxesRead1' = [mailboxesRead1 EXCEPT ![self] = msg2] - /\ resp' = [resp EXCEPT ![self] = mailboxesRead1'[self]] - /\ outstreamWrite' = [outstreamWrite EXCEPT ![self] = resp'[self]] - /\ network' = mailboxesWrite3'[self] - /\ out' = outstreamWrite'[self] - /\ pc' = [pc EXCEPT ![self] = "clientLoop"] - /\ UNCHANGED << in, fs, msg_, next, mailboxesRead, - mailboxesWrite, mailboxesWrite0, msg, - mailboxesRead0, mailboxesWrite1, - file_systemRead, mailboxesWrite2, req, - instreamRead, mailboxesWrite4, - outstreamWrite0 >> - -Client(self) == clientLoop(self) \/ clientRequest(self) - \/ clientReceive(self) - -Next == LoadBalancer - \/ (\E self \in (1)..(NUM_SERVERS): Servers(self)) - \/ (\E self \in ((NUM_SERVERS)+(1))..((NUM_SERVERS)+(NUM_CLIENTS)): Client(self)) - \/ (* Disjunct to prevent deadlock on termination *) - ((\A self \in ProcSet: pc[self] = "Done") /\ UNCHANGED vars) - -Spec == /\ Init /\ [][Next]_vars - /\ WF_vars(LoadBalancer) - /\ \A self \in (1)..(NUM_SERVERS) : WF_vars(Servers(self)) - /\ \A self \in ((NUM_SERVERS)+(1))..((NUM_SERVERS)+(NUM_CLIENTS)) : WF_vars(Client(self)) - -Termination == <>(\A self \in ProcSet: pc[self] = "Done") - -\* END TRANSLATION - - -(* INVARIANTS *) - - -\* This is an _invariant_ of our specification: in other words, -\* we expect the BuffersOk predicate to always be true in every step of execution -BufferOk(node) == Len(network[node]) >= 0 /\ Len(network[node]) <= BUFFER_SIZE -BuffersOk == \A node \in DOMAIN network : BufferOk(node) - - -(* PROPERTIES *) - -\* This is a property we would like to check about our specification. -\* Properties are defined using _temporal logic_. In this specific example, -\* we want to make sure that every client that requests a web page (i.e., are -\* in the 'clientRequest' label) eventually receive a response (i.e., are -\* in the 'clientReceive' label). In order to specify this property, we have to -\* write the formula as if the client enters 'clientReceive' label, it will -\* eventually successfully receive a response and then go back to issuing -\* another request in the 'clientRequest' label. -ReceivesPage(client) == pc[client] = "clientReceive" ~> pc[client] = "clientRequest" -ClientsOk == \A client \in (NUM_SERVERS+1)..(NUM_SERVERS+NUM_CLIENTS) : ReceivesPage(client) - -============================================================================= -\* Modification History -\* Last modified Wed Feb 27 14:42:14 PST 2019 by rmc -\* Last modified Mon Feb 25 14:25:46 PST 2019 by minh \ No newline at end of file diff --git a/test/mpcal/spec/load_balancer_record_payloads.tla b/test/mpcal/spec/load_balancer_record_payloads.tla deleted file mode 100644 index 16dd712bc..000000000 --- a/test/mpcal/spec/load_balancer_record_payloads.tla +++ /dev/null @@ -1,563 +0,0 @@ ------------------------------ MODULE load_balancer ----------------------------- -(***************************************************************************) -(* Specifies a simple load balancer. *) -(***************************************************************************) - -\* Extends some built-in TLA+ modules -EXTENDS Naturals, Sequences, TLC - -\* The `TCPChannel` mapping macro used in this specification is parameterized -\* by a `BUFFER_SIZE` constant. This value controls the number of messages being -\* held in a buffer by each process. Processes trying to send a message to another -\* process with a full buffer wil "block" (not be scheduled by TLC). -CONSTANT BUFFER_SIZE - -\* Define a constant identifier for the load balancer. -CONSTANT LoadBalancerId - -\* The number of servers and clients in the model checking setup. -CONSTANTS NUM_SERVERS, NUM_CLIENTS - -\* TLC should assume that both numbers are greater than zero (i.e., we always -\* have at least one server and one client). Note, however, that increasing -\* these numbers makes the number of states to be checked by TLC to grow -\* exponentially. -ASSUME NUM_SERVERS > 0 /\ NUM_CLIENTS > 0 - -\* GET_PAGE is a label attached to messages sent from the clients to -\* the load balancer. -\* -\* WEB_PAGE abstractly represents a web page that the server may return -\* to clients. The content of the webpage is, obviously, orthogonal to the -\* correctness of our load balancer. -CONSTANTS GET_PAGE, WEB_PAGE - -(*************************************************************************** ---mpcal LoadBalancer { - define { - \* total nodes in the system: - \* number of clients + number of servers + the load balancer - NUM_NODES == NUM_CLIENTS + NUM_SERVERS + 1 - } - - \* The TCPChannel mapping macro models a communication channel - \* between two processes using TCP-like semantics. In particular: - \* - \* - reading from the channel "blocks" unless there is a message - \* ready to be read. - \* - message delivery is reliable and ordered (i.e., FIFO). - mapping macro TCPChannel { - read { - await Len($variable) > 0; - with (msg = Head($variable)) { - $variable := Tail($variable); - yield msg; - }; - } - - write { - await Len($variable) < BUFFER_SIZE; - yield Append($variable, $value); - } - } - - \* Mapping macros keep implementation-specific behavior that we don't - \* want to model check outside of our archetype definitions. - \* In the case of this load balancer, how a server retrieves a web page - \* is orthogonal to the correctness of the properties we are interested - \* to check with this specification. - \* - \* This mapping macro abstracts the process of reading a web page by - \* always returning the `WEB_PAGE` constant when the variable is read. - \* - \* Since "writing" to this mapping is meaningless, the attempting to write - \* to a variable mapped with WebPage will result in a model checking - \* error (see `assert(FALSE)` in the write definition). - mapping macro WebPages { - read { - yield WEB_PAGE; - } - - write { - assert(FALSE); - yield $value; - } - } - - \* ALoadBalancer is the archetype that defines the behavior of - \* the load balancer process. The `mailboxes` parameter represents - \* connections to all nodes in the system. - archetype ALoadBalancer(ref mailboxes) - - \* Local variables of this archetype: - variables - \* Holds messages received by the load balancer (sent - \* by clients) - msg, - - \* identifier attached to every message sent to servers by - \* the load balancer. - next = 0; - { - main: - while (TRUE) { - - \* waits for a message to be received. Upon receipt, the `assert` - \* call ensures that the message is of type `GET_PAGE`, the only - \* type of message supported in this simple specification. - \* - \* Every message received by the load balancer is expected to - \* be a record of the following type. - \* - \* [message_type : Int, client_id : Int] - \* - \* Note that tuples are 1-indexed. - rcvMsg: - msg := mailboxes[LoadBalancerId]; - - \* the load balancer needs to forward the client request to the - \* server, who will process the request and send a web page back to - \* the client. - \* - \* The message sent to the server is a tuple in the format: - \* - \* [message_id : Int, client_id : Int] - \* - \* We send the client ID here so that the server can directly - \* reply to a client, bypassing the load balancer. This is usually - \* not what happens in practice, but the model is simple - \* enough for our (illustrative) purposes. - sendServer: - next := (next % NUM_SERVERS) + 1; - mailboxes[next] := [message_id |-> next, client_id |-> msg.client_id]; - } - } - - \* AServer is the archetype that defines the behavior of the servers - \* in our system. The two parameters it receives are: - \* - \* - mailboxes: contains connections to every node in the system - \* - page_stream: a source of web pages for the server. In practice, - \* this is implementation specific and irrelevant for - \* the properties we want to check in this specification - archetype AServer(ref mailboxes, page_stream) - - \* Local variables - variable - \* temporary buffer to hold incoming messages - msg; - { - serverLoop: - while (TRUE) { - - \* waits for an incoming message. Note that the only process - \* that sends messages to the server is the load balancer process - \* (defined according to the ALoadBalancer archetype) and the - \* message has the type [message_id : Int, client_id : Int] - rcvReq: - msg := mailboxes[self]; - - sendPage: - \* sends a web page (read from `page_stream`) back to the requester - \* i.e., the client. - mailboxes[msg.client_id] := page_stream; - } - } - - \* Client processes are given integer identifiers starting from NUM_SERVERS+1. - \* Keep in mind that this "range" notation in PlusCal defines a set, and is - \* _inclusive_ (i.e., NUM_SERVERS+NUM_CLIENTS+1 is part of the set). - archetype AClient(ref mailboxes, instream, ref outstream) - - \* Local variables - variable - \* Temporary buffers to hold messages - req, resp; - { - clientLoop: - while (TRUE) { - - \* First, the client makes a request to the load balancer. - \* The format of the message is a tuple: [message_type : Int, client_id : Int, instream : Interface{}]. - \* If you check the ALoadBalancer definition, this is the message format - \* expected there. - \* - \* Remember that `self` is an implicitly defined, immutable variable that - \* contains the process identifier of the "running" process. - clientRequest: - req := [message_type |-> GET_PAGE, client_id |-> self, instream |-> instream]; - mailboxes[LoadBalancerId] := req; - - \* Clients then wait for the response to the previously sent request. - \* Since there is only one type of web page in this simple specification - \* (defined by the WEB_PAGE constant), we assert here that the message - \* received indeed is equal our expected web page. - clientReceive: - resp := mailboxes[self]; - outstream := resp; - } - } - - \* GLOBAL VARIABLES *\ - - variables - \* our network is modeled as a function from node identifier - \* to a sequence of incoming messages - network = [id \in 0..(NUM_NODES-1) |-> <<>>], - - \* the stream of web pages to be served by the server. Since we - \* intend to map this variable using the WebPages mapping macro, - \* the initial value assigned to it here is irrelevant. - stream = 0, - - in = 0, out = 0; - - \* PROCESS INSTANTIATION *\ - - \* The system has a single load balancer entity, instantiated from the ALoadBalancer - \* archetype. The model of our network is going to be the one defined by the TCPChannel - \* mapping macro in all instantiations. - fair process (LoadBalancer = LoadBalancerId) == instance ALoadBalancer(ref network) - mapping network[_] via TCPChannel; - - \* Instantiate `NUM_SERVERS` server processes according to the AServer archetype. - \* We map the page stream according to the WebPages mapping macro since this is - \* an implementation detail that needs to be specified during implementation at - \* a later stage. - fair process (Servers \in 1..NUM_SERVERS) == instance AServer(ref network, stream) - mapping network[_] via TCPChannel - mapping stream via WebPages; - - fair process (Client \in (NUM_SERVERS+1)..(NUM_SERVERS+NUM_CLIENTS)) == instance AClient(ref network, in, ref out) - mapping network[_] via TCPChannel; -} - -\* BEGIN PLUSCAL TRANSLATION ---algorithm LoadBalancer { - variables network = [id \in (0)..((NUM_NODES)-(1)) |-> <<>>], stream = 0, in = 0, out = 0; - define { - NUM_NODES == ((NUM_CLIENTS)+(NUM_SERVERS))+(1)} - fair process (LoadBalancer = LoadBalancerId) - variables msg, next = 0, mailboxesRead, mailboxesWrite, mailboxesWrite0; - { - main: - if (TRUE) { - rcvMsg: - await (Len(network[LoadBalancerId]))>(0); - with (msg0 = Head(network[LoadBalancerId])) { - mailboxesWrite := [network EXCEPT ![LoadBalancerId] = Tail(network[LoadBalancerId])]; - mailboxesRead := msg0; - }; - msg := mailboxesRead; - network := mailboxesWrite; - - sendServer: - next := ((next)%(NUM_SERVERS))+(1); - await (Len(network[next]))<(BUFFER_SIZE); - mailboxesWrite := [network EXCEPT ![next] = Append(network[next], [message_id |-> next, client_id |-> (msg).client_id])]; - network := mailboxesWrite; - goto main; - - } else { - mailboxesWrite0 := network; - network := mailboxesWrite0; - }; - - } - fair process (Servers \in (1)..(NUM_SERVERS)) - variables msg, mailboxesRead0, mailboxesWrite1, page_streamRead, mailboxesWrite2; - { - serverLoop: - if (TRUE) { - rcvReq: - await (Len(network[self]))>(0); - with (msg1 = Head(network[self])) { - mailboxesWrite1 := [network EXCEPT ![self] = Tail(network[self])]; - mailboxesRead0 := msg1; - }; - msg := mailboxesRead0; - network := mailboxesWrite1; - - sendPage: - page_streamRead := WEB_PAGE; - await (Len(network[(msg).client_id]))<(BUFFER_SIZE); - mailboxesWrite1 := [network EXCEPT ![(msg).client_id] = Append(network[(msg).client_id], page_streamRead)]; - network := mailboxesWrite1; - goto serverLoop; - - } else { - mailboxesWrite2 := network; - network := mailboxesWrite2; - }; - - } - fair process (Client \in ((NUM_SERVERS)+(1))..((NUM_SERVERS)+(NUM_CLIENTS))) - variables req, resp, instreamRead, mailboxesWrite3, mailboxesRead1, outstreamWrite, mailboxesWrite4, outstreamWrite0; - { - clientLoop: - if (TRUE) { - clientRequest: - instreamRead := in; - req := [message_type |-> GET_PAGE, client_id |-> self, instream |-> instreamRead]; - await (Len(network[LoadBalancerId]))<(BUFFER_SIZE); - mailboxesWrite3 := [network EXCEPT ![LoadBalancerId] = Append(network[LoadBalancerId], req)]; - network := mailboxesWrite3; - - clientReceive: - await (Len(network[self]))>(0); - with (msg2 = Head(network[self])) { - mailboxesWrite3 := [network EXCEPT ![self] = Tail(network[self])]; - mailboxesRead1 := msg2; - }; - resp := mailboxesRead1; - outstreamWrite := resp; - network := mailboxesWrite3; - out := outstreamWrite; - goto clientLoop; - - } else { - mailboxesWrite4 := network; - outstreamWrite0 := out; - network := mailboxesWrite4; - out := outstreamWrite0; - }; - - } -} -\* END PLUSCAL TRANSLATION - - - -***************************************************************************) -\* BEGIN TRANSLATION -\* Process variable msg of process LoadBalancer at line 241 col 15 changed to msg_ -CONSTANT defaultInitValue -VARIABLES network, stream, in, out, pc - -(* define statement *) -NUM_NODES == ((NUM_CLIENTS)+(NUM_SERVERS))+(1) - -VARIABLES msg_, next, mailboxesRead, mailboxesWrite, mailboxesWrite0, msg, - mailboxesRead0, mailboxesWrite1, page_streamRead, mailboxesWrite2, - req, resp, instreamRead, mailboxesWrite3, mailboxesRead1, - outstreamWrite, mailboxesWrite4, outstreamWrite0 - -vars == << network, stream, in, out, pc, msg_, next, mailboxesRead, - mailboxesWrite, mailboxesWrite0, msg, mailboxesRead0, - mailboxesWrite1, page_streamRead, mailboxesWrite2, req, resp, - instreamRead, mailboxesWrite3, mailboxesRead1, outstreamWrite, - mailboxesWrite4, outstreamWrite0 >> - -ProcSet == {LoadBalancerId} \cup ((1)..(NUM_SERVERS)) \cup (((NUM_SERVERS)+(1))..((NUM_SERVERS)+(NUM_CLIENTS))) - -Init == (* Global variables *) - /\ network = [id \in (0)..((NUM_NODES)-(1)) |-> <<>>] - /\ stream = 0 - /\ in = 0 - /\ out = 0 - (* Process LoadBalancer *) - /\ msg_ = defaultInitValue - /\ next = 0 - /\ mailboxesRead = defaultInitValue - /\ mailboxesWrite = defaultInitValue - /\ mailboxesWrite0 = defaultInitValue - (* Process Servers *) - /\ msg = [self \in (1)..(NUM_SERVERS) |-> defaultInitValue] - /\ mailboxesRead0 = [self \in (1)..(NUM_SERVERS) |-> defaultInitValue] - /\ mailboxesWrite1 = [self \in (1)..(NUM_SERVERS) |-> defaultInitValue] - /\ page_streamRead = [self \in (1)..(NUM_SERVERS) |-> defaultInitValue] - /\ mailboxesWrite2 = [self \in (1)..(NUM_SERVERS) |-> defaultInitValue] - (* Process Client *) - /\ req = [self \in ((NUM_SERVERS)+(1))..((NUM_SERVERS)+(NUM_CLIENTS)) |-> defaultInitValue] - /\ resp = [self \in ((NUM_SERVERS)+(1))..((NUM_SERVERS)+(NUM_CLIENTS)) |-> defaultInitValue] - /\ instreamRead = [self \in ((NUM_SERVERS)+(1))..((NUM_SERVERS)+(NUM_CLIENTS)) |-> defaultInitValue] - /\ mailboxesWrite3 = [self \in ((NUM_SERVERS)+(1))..((NUM_SERVERS)+(NUM_CLIENTS)) |-> defaultInitValue] - /\ mailboxesRead1 = [self \in ((NUM_SERVERS)+(1))..((NUM_SERVERS)+(NUM_CLIENTS)) |-> defaultInitValue] - /\ outstreamWrite = [self \in ((NUM_SERVERS)+(1))..((NUM_SERVERS)+(NUM_CLIENTS)) |-> defaultInitValue] - /\ mailboxesWrite4 = [self \in ((NUM_SERVERS)+(1))..((NUM_SERVERS)+(NUM_CLIENTS)) |-> defaultInitValue] - /\ outstreamWrite0 = [self \in ((NUM_SERVERS)+(1))..((NUM_SERVERS)+(NUM_CLIENTS)) |-> defaultInitValue] - /\ pc = [self \in ProcSet |-> CASE self = LoadBalancerId -> "main" - [] self \in (1)..(NUM_SERVERS) -> "serverLoop" - [] self \in ((NUM_SERVERS)+(1))..((NUM_SERVERS)+(NUM_CLIENTS)) -> "clientLoop"] - -main == /\ pc[LoadBalancerId] = "main" - /\ IF TRUE - THEN /\ pc' = [pc EXCEPT ![LoadBalancerId] = "rcvMsg"] - /\ UNCHANGED << network, mailboxesWrite0 >> - ELSE /\ mailboxesWrite0' = network - /\ network' = mailboxesWrite0' - /\ pc' = [pc EXCEPT ![LoadBalancerId] = "Done"] - /\ UNCHANGED << stream, in, out, msg_, next, mailboxesRead, - mailboxesWrite, msg, mailboxesRead0, mailboxesWrite1, - page_streamRead, mailboxesWrite2, req, resp, - instreamRead, mailboxesWrite3, mailboxesRead1, - outstreamWrite, mailboxesWrite4, outstreamWrite0 >> - -rcvMsg == /\ pc[LoadBalancerId] = "rcvMsg" - /\ (Len(network[LoadBalancerId]))>(0) - /\ LET msg0 == Head(network[LoadBalancerId]) IN - /\ mailboxesWrite' = [network EXCEPT ![LoadBalancerId] = Tail(network[LoadBalancerId])] - /\ mailboxesRead' = msg0 - /\ msg_' = mailboxesRead' - /\ network' = mailboxesWrite' - /\ pc' = [pc EXCEPT ![LoadBalancerId] = "sendServer"] - /\ UNCHANGED << stream, in, out, next, mailboxesWrite0, msg, - mailboxesRead0, mailboxesWrite1, page_streamRead, - mailboxesWrite2, req, resp, instreamRead, - mailboxesWrite3, mailboxesRead1, outstreamWrite, - mailboxesWrite4, outstreamWrite0 >> - -sendServer == /\ pc[LoadBalancerId] = "sendServer" - /\ next' = ((next)%(NUM_SERVERS))+(1) - /\ (Len(network[next']))<(BUFFER_SIZE) - /\ mailboxesWrite' = [network EXCEPT ![next'] = Append(network[next'], [message_id |-> next', client_id |-> (msg_).client_id])] - /\ network' = mailboxesWrite' - /\ pc' = [pc EXCEPT ![LoadBalancerId] = "main"] - /\ UNCHANGED << stream, in, out, msg_, mailboxesRead, - mailboxesWrite0, msg, mailboxesRead0, - mailboxesWrite1, page_streamRead, - mailboxesWrite2, req, resp, instreamRead, - mailboxesWrite3, mailboxesRead1, outstreamWrite, - mailboxesWrite4, outstreamWrite0 >> - -LoadBalancer == main \/ rcvMsg \/ sendServer - -serverLoop(self) == /\ pc[self] = "serverLoop" - /\ IF TRUE - THEN /\ pc' = [pc EXCEPT ![self] = "rcvReq"] - /\ UNCHANGED << network, mailboxesWrite2 >> - ELSE /\ mailboxesWrite2' = [mailboxesWrite2 EXCEPT ![self] = network] - /\ network' = mailboxesWrite2'[self] - /\ pc' = [pc EXCEPT ![self] = "Done"] - /\ UNCHANGED << stream, in, out, msg_, next, mailboxesRead, - mailboxesWrite, mailboxesWrite0, msg, - mailboxesRead0, mailboxesWrite1, - page_streamRead, req, resp, instreamRead, - mailboxesWrite3, mailboxesRead1, - outstreamWrite, mailboxesWrite4, - outstreamWrite0 >> - -rcvReq(self) == /\ pc[self] = "rcvReq" - /\ (Len(network[self]))>(0) - /\ LET msg1 == Head(network[self]) IN - /\ mailboxesWrite1' = [mailboxesWrite1 EXCEPT ![self] = [network EXCEPT ![self] = Tail(network[self])]] - /\ mailboxesRead0' = [mailboxesRead0 EXCEPT ![self] = msg1] - /\ msg' = [msg EXCEPT ![self] = mailboxesRead0'[self]] - /\ network' = mailboxesWrite1'[self] - /\ pc' = [pc EXCEPT ![self] = "sendPage"] - /\ UNCHANGED << stream, in, out, msg_, next, mailboxesRead, - mailboxesWrite, mailboxesWrite0, - page_streamRead, mailboxesWrite2, req, resp, - instreamRead, mailboxesWrite3, mailboxesRead1, - outstreamWrite, mailboxesWrite4, - outstreamWrite0 >> - -sendPage(self) == /\ pc[self] = "sendPage" - /\ page_streamRead' = [page_streamRead EXCEPT ![self] = WEB_PAGE] - /\ (Len(network[(msg[self]).client_id]))<(BUFFER_SIZE) - /\ mailboxesWrite1' = [mailboxesWrite1 EXCEPT ![self] = [network EXCEPT ![(msg[self]).client_id] = Append(network[(msg[self]).client_id], page_streamRead'[self])]] - /\ network' = mailboxesWrite1'[self] - /\ pc' = [pc EXCEPT ![self] = "serverLoop"] - /\ UNCHANGED << stream, in, out, msg_, next, mailboxesRead, - mailboxesWrite, mailboxesWrite0, msg, - mailboxesRead0, mailboxesWrite2, req, resp, - instreamRead, mailboxesWrite3, - mailboxesRead1, outstreamWrite, - mailboxesWrite4, outstreamWrite0 >> - -Servers(self) == serverLoop(self) \/ rcvReq(self) \/ sendPage(self) - -clientLoop(self) == /\ pc[self] = "clientLoop" - /\ IF TRUE - THEN /\ pc' = [pc EXCEPT ![self] = "clientRequest"] - /\ UNCHANGED << network, out, mailboxesWrite4, - outstreamWrite0 >> - ELSE /\ mailboxesWrite4' = [mailboxesWrite4 EXCEPT ![self] = network] - /\ outstreamWrite0' = [outstreamWrite0 EXCEPT ![self] = out] - /\ network' = mailboxesWrite4'[self] - /\ out' = outstreamWrite0'[self] - /\ pc' = [pc EXCEPT ![self] = "Done"] - /\ UNCHANGED << stream, in, msg_, next, mailboxesRead, - mailboxesWrite, mailboxesWrite0, msg, - mailboxesRead0, mailboxesWrite1, - page_streamRead, mailboxesWrite2, req, - resp, instreamRead, mailboxesWrite3, - mailboxesRead1, outstreamWrite >> - -clientRequest(self) == /\ pc[self] = "clientRequest" - /\ instreamRead' = [instreamRead EXCEPT ![self] = in] - /\ req' = [req EXCEPT ![self] = [message_type |-> GET_PAGE, client_id |-> self, instream |-> instreamRead'[self]]] - /\ (Len(network[LoadBalancerId]))<(BUFFER_SIZE) - /\ mailboxesWrite3' = [mailboxesWrite3 EXCEPT ![self] = [network EXCEPT ![LoadBalancerId] = Append(network[LoadBalancerId], req'[self])]] - /\ network' = mailboxesWrite3'[self] - /\ pc' = [pc EXCEPT ![self] = "clientReceive"] - /\ UNCHANGED << stream, in, out, msg_, next, - mailboxesRead, mailboxesWrite, - mailboxesWrite0, msg, mailboxesRead0, - mailboxesWrite1, page_streamRead, - mailboxesWrite2, resp, mailboxesRead1, - outstreamWrite, mailboxesWrite4, - outstreamWrite0 >> - -clientReceive(self) == /\ pc[self] = "clientReceive" - /\ (Len(network[self]))>(0) - /\ LET msg2 == Head(network[self]) IN - /\ mailboxesWrite3' = [mailboxesWrite3 EXCEPT ![self] = [network EXCEPT ![self] = Tail(network[self])]] - /\ mailboxesRead1' = [mailboxesRead1 EXCEPT ![self] = msg2] - /\ resp' = [resp EXCEPT ![self] = mailboxesRead1'[self]] - /\ outstreamWrite' = [outstreamWrite EXCEPT ![self] = resp'[self]] - /\ network' = mailboxesWrite3'[self] - /\ out' = outstreamWrite'[self] - /\ pc' = [pc EXCEPT ![self] = "clientLoop"] - /\ UNCHANGED << stream, in, msg_, next, mailboxesRead, - mailboxesWrite, mailboxesWrite0, msg, - mailboxesRead0, mailboxesWrite1, - page_streamRead, mailboxesWrite2, req, - instreamRead, mailboxesWrite4, - outstreamWrite0 >> - -Client(self) == clientLoop(self) \/ clientRequest(self) - \/ clientReceive(self) - -Next == LoadBalancer - \/ (\E self \in (1)..(NUM_SERVERS): Servers(self)) - \/ (\E self \in ((NUM_SERVERS)+(1))..((NUM_SERVERS)+(NUM_CLIENTS)): Client(self)) - \/ (* Disjunct to prevent deadlock on termination *) - ((\A self \in ProcSet: pc[self] = "Done") /\ UNCHANGED vars) - -Spec == /\ Init /\ [][Next]_vars - /\ WF_vars(LoadBalancer) - /\ \A self \in (1)..(NUM_SERVERS) : WF_vars(Servers(self)) - /\ \A self \in ((NUM_SERVERS)+(1))..((NUM_SERVERS)+(NUM_CLIENTS)) : WF_vars(Client(self)) - -Termination == <>(\A self \in ProcSet: pc[self] = "Done") - -\* END TRANSLATION - - -(* INVARIANTS *) - - -\* This is an _invariant_ of our specification: in other words, -\* we expect the BuffersOk predicate to always be true in every step of execution -BufferOk(node) == Len(network[node]) >= 0 /\ Len(network[node]) <= BUFFER_SIZE -BuffersOk == \A node \in DOMAIN network : BufferOk(node) - - -(* PROPERTIES *) - -\* This is a property we would like to check about our specification. -\* Properties are defined using _temporal logic_. In this specific example, -\* we want to make sure that every client that requests a web page (i.e., are -\* in the 'clientRequest' label) eventually receive a response (i.e., are -\* in the 'clientReceive' label). In order to specify this property, we have to -\* write the formula as if the client enters 'clientReceive' label, it will -\* eventually successfully receive a response and then go back to issuing -\* another request in the 'clientRequest' label. -ReceivesPage(client) == pc[client] = "clientReceive" ~> pc[client] = "clientRequest" -ClientsOk == \A client \in (NUM_SERVERS+1)..(NUM_SERVERS+NUM_CLIENTS) : ReceivesPage(client) - -============================================================================= -\* Modification History -\* Last modified Mon Feb 25 14:25:46 PST 2019 by minh -\* Last modified Fri Feb 15 22:57:46 PST 2019 by rmc diff --git a/test/mpcal/spec/load_balancer_tuples.tla b/test/mpcal/spec/load_balancer_tuples.tla deleted file mode 100644 index a02718283..000000000 --- a/test/mpcal/spec/load_balancer_tuples.tla +++ /dev/null @@ -1,540 +0,0 @@ ------------------------------ MODULE load_balancer ----------------------------- -(***************************************************************************) -(* Specifies a simple load balancer. *) -(***************************************************************************) - -\* Extends some built-in TLA+ modules -EXTENDS Naturals, Sequences, TLC - -\* The `TCPChannel` mapping macro used in this specification is parameterized -\* by a `BUFFER_SIZE` constant. This value controls the number of messages being -\* held in a buffer by each process. Processes trying to send a message to another -\* process with a full buffer wil "block" (not be scheduled by TLC). -CONSTANT BUFFER_SIZE - -\* Define a constant identifier for the load balancer. -CONSTANT LoadBalancerId - -\* The number of servers and clients in the model checking setup. -CONSTANTS NUM_SERVERS, NUM_CLIENTS - -\* TLC should assume that both numbers are greater than zero (i.e., we always -\* have at least one server and one client). Note, however, that increasing -\* these numbers makes the number of states to be checked by TLC to grow -\* exponentially. -ASSUME NUM_SERVERS > 0 /\ NUM_CLIENTS > 0 - -\* GET_PAGE is a label attached to messages sent from the clients to -\* the load balancer. -\* -\* WEB_PAGE abstractly represents a web page that the server may return -\* to clients. The content of the webpage is, obviously, orthogonal to the -\* correctness of our load balancer. -CONSTANTS GET_PAGE, WEB_PAGE - -(*************************************************************************** ---mpcal LoadBalancer { - define { - \* total nodes in the system: - \* number of clients + number of servers + the load balancer - NUM_NODES == NUM_CLIENTS + NUM_SERVERS + 1 - } - - \* The TCPChannel mapping macro models a communication channel - \* between two processes using TCP-like semantics. In particular: - \* - \* - reading from the channel "blocks" unless there is a message - \* ready to be read. - \* - message delivery is reliable and ordered (i.e., FIFO). - mapping macro TCPChannel { - read { - await Len($variable) > 0; - with (msg = Head($variable)) { - $variable := Tail($variable); - yield msg; - }; - } - - write { - await Len($variable) < BUFFER_SIZE; - yield Append($variable, $value); - } - } - - \* Mapping macros keep implementation-specific behavior that we don't - \* want to model check outside of our archetype definitions. - \* In the case of this load balancer, how a server retrieves a web page - \* is orthogonal to the correctness of the properties we are interested - \* to check with this specification. - \* - \* This mapping macro abstracts the process of reading a web page by - \* always returning the `WEB_PAGE` constant when the variable is read. - \* - \* Since "writing" to this mapping is meaningless, the attempting to write - \* to a variable mapped with WebPage will result in a model checking - \* error (see `assert(FALSE)` in the write definition). - mapping macro WebPages { - read { - yield WEB_PAGE; - } - - write { - assert(FALSE); - yield $value; - } - } - - \* ALoadBalancer is the archetype that defines the behavior of - \* the load balancer process. The `mailboxes` parameter represents - \* connections to all nodes in the system. - archetype ALoadBalancer(ref mailboxes) - - \* Local variables of this archetype: - variables - \* Holds messages received by the load balancer (sent - \* by clients) - msg, - - \* identifier attached to every message sent to servers by - \* the load balancer. - next = 0; - { - main: - while (TRUE) { - - \* waits for a message to be received. Upon receipt, the `assert` - \* call ensures that the message is of type `GET_PAGE`, the only - \* type of message supported in this simple specification. - \* - \* Every message received by the load balancer is expected to - \* be a tuple in the format: - \* - \* << {message_type}, {client_id} >> - \* - \* Note that tuples are 1-indexed. - rcvMsg: - msg := mailboxes[LoadBalancerId]; - - \* the load balancer needs to forward the client request to the - \* server, who will process the request and send a web page back to - \* the client. - \* - \* The message sent to the server is a tuple in the format: - \* - \* << {message_id}, {client_id} >> - \* - \* We send the client ID here so that the server can directly - \* reply to a client, bypassing the load balancer. This is usually - \* not what happens in practice, but the model is simple - \* enough for our (illustrative) purposes. - sendServer: - next := (next % NUM_SERVERS) + 1; - mailboxes[next] := << next, msg[2] >>; - } - } - - \* AServer is the archetype that defines the behavior of the servers - \* in our system. The two parameters it receives are: - \* - \* - mailboxes: contains connections to every node in the system - \* - page_stream: a source of web pages for the server. In practice, - \* this is implementation specific and irrelevant for - \* the properties we want to check in this specification - archetype AServer(ref mailboxes, page_stream) - - \* Local variables - variable - \* temporary buffer to hold incoming messages - msg; - { - serverLoop: - while (TRUE) { - - \* waits for an incoming message. Note that the only process - \* that sends messages to the server is the load balancer process - \* (defined according to the ALoadBalancer archetype) and the - \* message has the format << {message_id}, {client_id} >> - rcvReq: - msg := mailboxes[self]; - - sendPage: - \* sends a web page (read from `page_stream`) back to the requester - \* i.e., the client. - mailboxes[msg[2]] := page_stream; - } - } - - \* Client processes are given integer identifiers starting from NUM_SERVERS+1. - \* Keep in mind that this "range" notation in PlusCal defines a set, and is - \* _inclusive_ (i.e., NUM_SERVERS+NUM_CLIENTS+1 is part of the set). - archetype AClient(ref mailboxes, instream, ref outstream) - - \* Local variables - variable - \* Temporary buffers to hold messages - req, resp; - { - clientLoop: - while (TRUE) { - - \* First, the client makes a request to the load balancer. - \* The format of the message is a tuple: << {message_type}, {client_id} >>. - \* If you check the ALoadBalancer definition, this is the message format - \* expected there. - \* - \* Remember that `self` is an implicitly defined, immutable variable that - \* contains the process identifier of the "running" process. - clientRequest: - req := << GET_PAGE, self, instream >>; - mailboxes[LoadBalancerId] := req; - - \* Clients then wait for the response to the previously sent request. - \* Since there is only one type of web page in this simple specification - \* (defined by the WEB_PAGE constant), we assert here that the message - \* received indeed is equal our expected web page. - clientReceive: - resp := mailboxes[self]; - outstream := resp; - } - } - - \* GLOBAL VARIABLES *\ - - variables - \* our network is modeled as a function from node identifier - \* to a sequence of incoming messages - network = [id \in 0..(NUM_NODES-1) |-> <<>>], - - \* the stream of web pages to be served by the server. Since we - \* intend to map this variable using the WebPages mapping macro, - \* the initial value assigned to it here is irrelevant. - stream = 0, - - in = 0, out = 0; - - \* PROCESS INSTANTIATION *\ - - \* The system has a single load balancer entity, instantiated from the ALoadBalancer - \* archetype. The model of our network is going to be the one defined by the TCPChannel - \* mapping macro in all instantiations. - fair process (LoadBalancer = LoadBalancerId) == instance ALoadBalancer(ref network) - mapping network[_] via TCPChannel; - - \* Instantiate `NUM_SERVERS` server processes according to the AServer archetype. - \* We map the page stream according to the WebPages mapping macro since this is - \* an implementation detail that needs to be specified during implementation at - \* a later stage. - fair process (Servers \in 1..NUM_SERVERS) == instance AServer(ref network, stream) - mapping network[_] via TCPChannel - mapping stream via WebPages; - - fair process (Client \in (NUM_SERVERS+1)..(NUM_SERVERS+NUM_CLIENTS)) == instance AClient(ref network, in, ref out) - mapping network[_] via TCPChannel; -} - -\* BEGIN PLUSCAL TRANSLATION ---algorithm LoadBalancer { - variables network = [id \in (0)..((NUM_NODES)-(1)) |-> <<>>], stream = 0; - define { - NUM_NODES == ((NUM_CLIENTS)+(NUM_SERVERS))+(1)} - fair process (LoadBalancer = LoadBalancerId) - variables msg, next = 0, mailboxesRead, mailboxesWrite, mailboxesWrite0; - { - main: - if (TRUE) { - rcvMsg: - await (Len(network[LoadBalancerId]))>(0); - with (msg0 = Head(network[LoadBalancerId])) { - mailboxesWrite := [network EXCEPT ![LoadBalancerId] = Tail(network[LoadBalancerId])]; - mailboxesRead := msg0; - }; - msg := mailboxesRead; - assert (msg[1])=(GET_PAGE); - network := mailboxesWrite; - - sendServer: - next := ((next)%(NUM_SERVERS))+(1); - await (Len(network[next]))<(BUFFER_SIZE); - mailboxesWrite := [network EXCEPT ![next] = Append(network[next], <>)]; - network := mailboxesWrite; - goto main; - - } else { - mailboxesWrite0 := network; - network := mailboxesWrite0; - }; - - } - fair process (Servers \in (1)..(NUM_SERVERS)) - variables msg, mailboxesRead0, mailboxesWrite1, page_streamRead, mailboxesWrite2; - { - serverLoop: - if (TRUE) { - rcvReq: - await (Len(network[self]))>(0); - with (msg1 = Head(network[self])) { - mailboxesWrite1 := [network EXCEPT ![self] = Tail(network[self])]; - mailboxesRead0 := msg1; - }; - msg := mailboxesRead0; - network := mailboxesWrite1; - - sendPage: - page_streamRead := WEB_PAGE; - await (Len(network[msg[2]]))<(BUFFER_SIZE); - mailboxesWrite1 := [network EXCEPT ![msg[2]] = Append(network[msg[2]], <>)]; - network := mailboxesWrite1; - goto serverLoop; - - } else { - mailboxesWrite2 := network; - network := mailboxesWrite2; - }; - - } - fair process (Client \in ((NUM_SERVERS)+(1))..((NUM_SERVERS)+(NUM_CLIENTS))) - variables req, resp, mailboxesWrite3, mailboxesRead1, mailboxesWrite4; - { - clientLoop: - if (TRUE) { - clientRequest: - req := <>; - await (Len(network[LoadBalancerId]))<(BUFFER_SIZE); - mailboxesWrite3 := [network EXCEPT ![LoadBalancerId] = Append(network[LoadBalancerId], req)]; - network := mailboxesWrite3; - - clientReceive: - await (Len(network[self]))>(0); - with (msg2 = Head(network[self])) { - mailboxesWrite3 := [network EXCEPT ![self] = Tail(network[self])]; - mailboxesRead1 := msg2; - }; - resp := mailboxesRead1; - assert (resp[2])=(WEB_PAGE); - network := mailboxesWrite3; - goto clientLoop; - - } else { - mailboxesWrite4 := network; - network := mailboxesWrite4; - }; - - } -} -\* END PLUSCAL TRANSLATION - - - -***************************************************************************) -\* BEGIN TRANSLATION -\* Process variable msg of process LoadBalancer at line 240 col 15 changed to msg_ -CONSTANT defaultInitValue -VARIABLES network, stream, pc - -(* define statement *) -NUM_NODES == ((NUM_CLIENTS)+(NUM_SERVERS))+(1) - -VARIABLES msg_, next, mailboxesRead, mailboxesWrite, mailboxesWrite0, msg, - mailboxesRead0, mailboxesWrite1, page_streamRead, mailboxesWrite2, - req, resp, mailboxesWrite3, mailboxesRead1, mailboxesWrite4 - -vars == << network, stream, pc, msg_, next, mailboxesRead, mailboxesWrite, - mailboxesWrite0, msg, mailboxesRead0, mailboxesWrite1, - page_streamRead, mailboxesWrite2, req, resp, mailboxesWrite3, - mailboxesRead1, mailboxesWrite4 >> - -ProcSet == {LoadBalancerId} \cup ((1)..(NUM_SERVERS)) \cup (((NUM_SERVERS)+(1))..((NUM_SERVERS)+(NUM_CLIENTS))) - -Init == (* Global variables *) - /\ network = [id \in (0)..((NUM_NODES)-(1)) |-> <<>>] - /\ stream = 0 - (* Process LoadBalancer *) - /\ msg_ = defaultInitValue - /\ next = 0 - /\ mailboxesRead = defaultInitValue - /\ mailboxesWrite = defaultInitValue - /\ mailboxesWrite0 = defaultInitValue - (* Process Servers *) - /\ msg = [self \in (1)..(NUM_SERVERS) |-> defaultInitValue] - /\ mailboxesRead0 = [self \in (1)..(NUM_SERVERS) |-> defaultInitValue] - /\ mailboxesWrite1 = [self \in (1)..(NUM_SERVERS) |-> defaultInitValue] - /\ page_streamRead = [self \in (1)..(NUM_SERVERS) |-> defaultInitValue] - /\ mailboxesWrite2 = [self \in (1)..(NUM_SERVERS) |-> defaultInitValue] - (* Process Client *) - /\ req = [self \in ((NUM_SERVERS)+(1))..((NUM_SERVERS)+(NUM_CLIENTS)) |-> defaultInitValue] - /\ resp = [self \in ((NUM_SERVERS)+(1))..((NUM_SERVERS)+(NUM_CLIENTS)) |-> defaultInitValue] - /\ mailboxesWrite3 = [self \in ((NUM_SERVERS)+(1))..((NUM_SERVERS)+(NUM_CLIENTS)) |-> defaultInitValue] - /\ mailboxesRead1 = [self \in ((NUM_SERVERS)+(1))..((NUM_SERVERS)+(NUM_CLIENTS)) |-> defaultInitValue] - /\ mailboxesWrite4 = [self \in ((NUM_SERVERS)+(1))..((NUM_SERVERS)+(NUM_CLIENTS)) |-> defaultInitValue] - /\ pc = [self \in ProcSet |-> CASE self = LoadBalancerId -> "main" - [] self \in (1)..(NUM_SERVERS) -> "serverLoop" - [] self \in ((NUM_SERVERS)+(1))..((NUM_SERVERS)+(NUM_CLIENTS)) -> "clientLoop"] - -main == /\ pc[LoadBalancerId] = "main" - /\ IF TRUE - THEN /\ pc' = [pc EXCEPT ![LoadBalancerId] = "rcvMsg"] - /\ UNCHANGED << network, mailboxesWrite0 >> - ELSE /\ mailboxesWrite0' = network - /\ network' = mailboxesWrite0' - /\ pc' = [pc EXCEPT ![LoadBalancerId] = "Done"] - /\ UNCHANGED << stream, msg_, next, mailboxesRead, mailboxesWrite, msg, - mailboxesRead0, mailboxesWrite1, page_streamRead, - mailboxesWrite2, req, resp, mailboxesWrite3, - mailboxesRead1, mailboxesWrite4 >> - -rcvMsg == /\ pc[LoadBalancerId] = "rcvMsg" - /\ (Len(network[LoadBalancerId]))>(0) - /\ LET msg0 == Head(network[LoadBalancerId]) IN - /\ mailboxesWrite' = [network EXCEPT ![LoadBalancerId] = Tail(network[LoadBalancerId])] - /\ mailboxesRead' = msg0 - /\ msg_' = mailboxesRead' - /\ Assert((msg_'[1])=(GET_PAGE), - "Failure of assertion at line 251, column 21.") - /\ network' = mailboxesWrite' - /\ pc' = [pc EXCEPT ![LoadBalancerId] = "sendServer"] - /\ UNCHANGED << stream, next, mailboxesWrite0, msg, mailboxesRead0, - mailboxesWrite1, page_streamRead, mailboxesWrite2, - req, resp, mailboxesWrite3, mailboxesRead1, - mailboxesWrite4 >> - -sendServer == /\ pc[LoadBalancerId] = "sendServer" - /\ next' = ((next)%(NUM_SERVERS))+(1) - /\ (Len(network[next']))<(BUFFER_SIZE) - /\ mailboxesWrite' = [network EXCEPT ![next'] = Append(network[next'], <>)] - /\ network' = mailboxesWrite' - /\ pc' = [pc EXCEPT ![LoadBalancerId] = "main"] - /\ UNCHANGED << stream, msg_, mailboxesRead, mailboxesWrite0, - msg, mailboxesRead0, mailboxesWrite1, - page_streamRead, mailboxesWrite2, req, resp, - mailboxesWrite3, mailboxesRead1, mailboxesWrite4 >> - -LoadBalancer == main \/ rcvMsg \/ sendServer - -serverLoop(self) == /\ pc[self] = "serverLoop" - /\ IF TRUE - THEN /\ pc' = [pc EXCEPT ![self] = "rcvReq"] - /\ UNCHANGED << network, mailboxesWrite2 >> - ELSE /\ mailboxesWrite2' = [mailboxesWrite2 EXCEPT ![self] = network] - /\ network' = mailboxesWrite2'[self] - /\ pc' = [pc EXCEPT ![self] = "Done"] - /\ UNCHANGED << stream, msg_, next, mailboxesRead, - mailboxesWrite, mailboxesWrite0, msg, - mailboxesRead0, mailboxesWrite1, - page_streamRead, req, resp, - mailboxesWrite3, mailboxesRead1, - mailboxesWrite4 >> - -rcvReq(self) == /\ pc[self] = "rcvReq" - /\ (Len(network[self]))>(0) - /\ LET msg1 == Head(network[self]) IN - /\ mailboxesWrite1' = [mailboxesWrite1 EXCEPT ![self] = [network EXCEPT ![self] = Tail(network[self])]] - /\ mailboxesRead0' = [mailboxesRead0 EXCEPT ![self] = msg1] - /\ msg' = [msg EXCEPT ![self] = mailboxesRead0'[self]] - /\ network' = mailboxesWrite1'[self] - /\ pc' = [pc EXCEPT ![self] = "sendPage"] - /\ UNCHANGED << stream, msg_, next, mailboxesRead, - mailboxesWrite, mailboxesWrite0, - page_streamRead, mailboxesWrite2, req, resp, - mailboxesWrite3, mailboxesRead1, - mailboxesWrite4 >> - -sendPage(self) == /\ pc[self] = "sendPage" - /\ page_streamRead' = [page_streamRead EXCEPT ![self] = WEB_PAGE] - /\ (Len(network[msg[self][2]]))<(BUFFER_SIZE) - /\ mailboxesWrite1' = [mailboxesWrite1 EXCEPT ![self] = [network EXCEPT ![msg[self][2]] = Append(network[msg[self][2]], <>)]] - /\ network' = mailboxesWrite1'[self] - /\ pc' = [pc EXCEPT ![self] = "serverLoop"] - /\ UNCHANGED << stream, msg_, next, mailboxesRead, - mailboxesWrite, mailboxesWrite0, msg, - mailboxesRead0, mailboxesWrite2, req, resp, - mailboxesWrite3, mailboxesRead1, - mailboxesWrite4 >> - -Servers(self) == serverLoop(self) \/ rcvReq(self) \/ sendPage(self) - -clientLoop(self) == /\ pc[self] = "clientLoop" - /\ IF TRUE - THEN /\ pc' = [pc EXCEPT ![self] = "clientRequest"] - /\ UNCHANGED << network, mailboxesWrite4 >> - ELSE /\ mailboxesWrite4' = [mailboxesWrite4 EXCEPT ![self] = network] - /\ network' = mailboxesWrite4'[self] - /\ pc' = [pc EXCEPT ![self] = "Done"] - /\ UNCHANGED << stream, msg_, next, mailboxesRead, - mailboxesWrite, mailboxesWrite0, msg, - mailboxesRead0, mailboxesWrite1, - page_streamRead, mailboxesWrite2, req, - resp, mailboxesWrite3, mailboxesRead1 >> - -clientRequest(self) == /\ pc[self] = "clientRequest" - /\ req' = [req EXCEPT ![self] = <>] - /\ (Len(network[LoadBalancerId]))<(BUFFER_SIZE) - /\ mailboxesWrite3' = [mailboxesWrite3 EXCEPT ![self] = [network EXCEPT ![LoadBalancerId] = Append(network[LoadBalancerId], req'[self])]] - /\ network' = mailboxesWrite3'[self] - /\ pc' = [pc EXCEPT ![self] = "clientReceive"] - /\ UNCHANGED << stream, msg_, next, mailboxesRead, - mailboxesWrite, mailboxesWrite0, msg, - mailboxesRead0, mailboxesWrite1, - page_streamRead, mailboxesWrite2, resp, - mailboxesRead1, mailboxesWrite4 >> - -clientReceive(self) == /\ pc[self] = "clientReceive" - /\ (Len(network[self]))>(0) - /\ LET msg2 == Head(network[self]) IN - /\ mailboxesWrite3' = [mailboxesWrite3 EXCEPT ![self] = [network EXCEPT ![self] = Tail(network[self])]] - /\ mailboxesRead1' = [mailboxesRead1 EXCEPT ![self] = msg2] - /\ resp' = [resp EXCEPT ![self] = mailboxesRead1'[self]] - /\ Assert((resp'[self][2])=(WEB_PAGE), - "Failure of assertion at line 312, column 21.") - /\ network' = mailboxesWrite3'[self] - /\ pc' = [pc EXCEPT ![self] = "clientLoop"] - /\ UNCHANGED << stream, msg_, next, mailboxesRead, - mailboxesWrite, mailboxesWrite0, msg, - mailboxesRead0, mailboxesWrite1, - page_streamRead, mailboxesWrite2, req, - mailboxesWrite4 >> - -Client(self) == clientLoop(self) \/ clientRequest(self) - \/ clientReceive(self) - -Next == LoadBalancer - \/ (\E self \in (1)..(NUM_SERVERS): Servers(self)) - \/ (\E self \in ((NUM_SERVERS)+(1))..((NUM_SERVERS)+(NUM_CLIENTS)): Client(self)) - \/ (* Disjunct to prevent deadlock on termination *) - ((\A self \in ProcSet: pc[self] = "Done") /\ UNCHANGED vars) - -Spec == /\ Init /\ [][Next]_vars - /\ WF_vars(LoadBalancer) - /\ \A self \in (1)..(NUM_SERVERS) : WF_vars(Servers(self)) - /\ \A self \in ((NUM_SERVERS)+(1))..((NUM_SERVERS)+(NUM_CLIENTS)) : WF_vars(Client(self)) - -Termination == <>(\A self \in ProcSet: pc[self] = "Done") - -\* END TRANSLATION - - -(* INVARIANTS *) - - -\* This is an _invariant_ of our specification: in other words, -\* we expect the BuffersOk predicate to always be true in every step of execution -BufferOk(node) == Len(network[node]) >= 0 /\ Len(network[node]) <= BUFFER_SIZE -BuffersOk == \A node \in DOMAIN network : BufferOk(node) - - -(* PROPERTIES *) - -\* This is a property we would like to check about our specification. -\* Properties are defined using _temporal logic_. In this specific example, -\* we want to make sure that every client that requests a web page (i.e., are -\* in the 'clientRequest' label) eventually receive a response (i.e., are -\* in the 'clientReceive' label). In order to specify this property, we have to -\* write the formula as if the client enters 'clientReceive' label, it will -\* eventually successfully receive a response and then go back to issuing -\* another request in the 'clientRequest' label. -ReceivesPage(client) == pc[client] = "clientReceive" ~> pc[client] = "clientRequest" -ClientsOk == \A client \in (NUM_SERVERS+1)..(NUM_SERVERS+NUM_CLIENTS) : ReceivesPage(client) - -============================================================================= -\* Modification History -\* Last modified Fri Feb 15 22:57:46 PST 2019 by rmc -\* Last modified Thu Feb 14 20:29:45 PST 2019 by minh diff --git a/test/mpcal/spec/replicated_kv.tla b/test/mpcal/spec/replicated_kv.tla deleted file mode 100644 index c6fa33add..000000000 --- a/test/mpcal/spec/replicated_kv.tla +++ /dev/null @@ -1,3019 +0,0 @@ ------------------------------ MODULE replicated_kv ----------------------------- -(***************************************************************************************) -(* Specifies a simple replicated Key-Value store in MPCal. *) -(* *) -(* Specifies a replicated state machines (RSM) approach as described in: *) -(* *) -(* Implementing fault-tolerant services using the state machine approach: a tutorial. *) -(* http://dl.acm.org/citation.cfm?id=98167 *) -(***************************************************************************************) - -\* Use some built-in TLA+ modules -EXTENDS Integers, Sequences, FiniteSets, TLC - -\* Constant Definitions -\* -------------------- - -\* Defines the size of the network buffer in a FIFOChannel (the mapping macro). -\* -\* TLC will explore states with up to `BUFFER_SIZE` messages being held on the buffer. -\* If the communication buffer is full, a process that attempts to send a message will not -\* run until a message on the other end of the channel is received. -CONSTANT BUFFER_SIZE - -\* Defines the number of key-value store replicas and clients in the system. The specification -\* is orthogonal to these numbers. Note, however, that increasing the number of replicas and/or -\* clients exponentially increases the state space that TLC needs to explore in order to model -\* check your specification. -CONSTANTS NUM_REPLICAS, NUM_CLIENTS - -\* When a client sends a message to a replica, the client needs to be able to identify -\* what type of message it just received. These constants below are such labels. Make sure -\* to give them distinct concrete values when model checking. -CONSTANTS DISCONNECT_MSG, GET_MSG, PUT_MSG, NULL_MSG - -\* labels that identify a payload corresponds to the response of a previously issues Get -\* or Put request. -CONSTANTS GET_RESPONSE, PUT_RESPONSE - -\* an arbitrary `NULL` value. We model the underlying key-value store as a function from -\* a certain key-space (function domain) to this `NULL` element. When a client issues a `PUT` -\* request, the database is updated and the key being set no longer maps to `NULL`. -CONSTANT NULL - -\* Defines which keys are used by clients when performing Get and Put operations -\* Since we are interested to test properties like message stability detection -\* and the semantics of the database, we keep these constant throughout model checking. -CONSTANT GET_KEY, PUT_KEY - -\* Whenever clients issue PUT requests, they set keys to the value declared in this constant. -CONSTANT PUT_VALUE - -\* Defines the set of keys a client may set. In this specification, we restrict -\* it to them to GET_KEY and PUT_KEY -KeySpace == { GET_KEY, PUT_KEY } - -\* These constants allow PlusCal processes to derive their client identifiers from -\* their PlusCal identifiers. -GET_ORDER == 0 -PUT_ORDER == 1 -DISCONNECT_ORDER == 2 -NULL_ORDER == 3 - -\* We have clients that perform each of the operations supported by our Replicated KV-store: -\* Get, Put, Disconnect, and ClockUpdate (or 'null' request). PlusCal requires that every process -\* has a unique identifier. The set definitions below just ensure that our clients have -\* consecutive identifiers. -GetSet == (NUM_REPLICAS)..(NUM_REPLICAS+NUM_CLIENTS-1) -PutSet == (NUM_REPLICAS+NUM_CLIENTS)..(NUM_REPLICAS + 2*NUM_CLIENTS - 1) -DisconnectSet == (NUM_REPLICAS+2*NUM_CLIENTS)..(NUM_REPLICAS+3*NUM_CLIENTS-1) -NullSet == (NUM_REPLICAS+3*NUM_CLIENTS)..(NUM_REPLICAS+4*NUM_CLIENTS-1) - -(*************************************************************************** ---mpcal ReplicatedKV { - define { - \* Define NUM_NODES to be the total number of nodes in the system, i.e., the number of - \* clients plus the number of replicas - NUM_NODES == NUM_REPLICAS + NUM_CLIENTS - - \* Each replica and each client in the system need an identifier. By default, replicas - \* are identified from 1 to NUM_REPLICAS, and the clients are identified from NUM_REPLICAS+1 - \* to NUM_NODES. It is important that identifiers are unique, consecutive and non-overlapping, - \* due to the way we are modeling our network in this specification. - ReplicaSet == 0..(NUM_REPLICAS-1) - ClientSet == NUM_REPLICAS..(NUM_NODES-1) - } - - \* Broadcasts a certain `msg` to `nodes` with identifiers ranging from - \* `domainStart` to `domainEnd`. - \* - \* Only returns once every message has been sent (i.e., it may "block" if - \* the buffer of one of the receivers is full). - macro Broadcast(nodes, i, until, msg) { - while (i <= until) { - nodes[i] := msg; - i := i + 1; - } - } - - \* Models a FIFO channel. Messages are always delivered. Every process - \* can have up to `BUFFER_SIZE` messages in its buffer before being - \* processed. - mapping macro FIFOChannel { - read { - await Len($variable) > 0; - with (msg = Head($variable)) { - $variable := Tail($variable); - yield msg; - }; - } - - write { - await Len($variable) < BUFFER_SIZE; - yield Append($variable, $value); - } - } - - \* The following mapping macros make sure that archetypes that - \* perform client functions read the correct client identifier with - \* respect to their PlusCal process identifier (`self`). - - mapping macro GetClientId { - read { yield self - (NUM_CLIENTS * GET_ORDER); } - write { assert(FALSE); yield $value; } - } - - mapping macro PutClientId { - read { yield self - (NUM_CLIENTS * PUT_ORDER); } - write { assert(FALSE); yield $value; } - } - - mapping macro DisconnectClientId { - read { yield self - (NUM_CLIENTS * DISCONNECT_ORDER); } - write { assert(FALSE); yield $value; } - } - - mapping macro NullClientId { - read { yield self - (NUM_CLIENTS * NULL_ORDER); } - write { assert(FALSE); yield $value; } - } - - \* Mapping via identity is sometimes necessary in order to inform - \* the compiler that a certain resource is to be function mapped, but - \* no meaningful manipulation on reads and writes is necessary. - mapping macro Identity { - read { yield $variable; } - write { yield $value; } - } - - mapping macro BlockingLock { - read { - await ~$variable; - yield FALSE; - } - - write { - yield $value; - } - } - - \* This archetype defines the behavior of the replica servers in the system. - \* Its parameters are: - \* - \* - clients: connections to all clients in the system; it needs to wait - \* for client requests in order to perform operations. - \* - replicas: connections to replicas. Since replicas do not talk to each - \* other, this parameter is only used in order to listen to - \* incoming messages. - \* - kv: the underlying "database". When 'put' requests become stable, this - \* database is updated to include the value being set by the client. - archetype AReplica(ref clients, replicas, ref kv) - - \* Local state in a replica: - variables - \* Each replica knows which clients are live (i.e., haven't disconnected) - \* Initially, all clients are live. - liveClients = ClientSet, - - \* Replicas remember which requests are pending (i.e., have not been - \* replied yet). This variable maps client identifiers to a sequence - \* of pending requests - pendingRequests = [c \in liveClients |-> <<>>], - - \* Temporary variables: holds messages that are stable - stableMessages = <<>>, - - \* incremented during in loops - i, - - \* temporary variable: holds the first pending message from - \* a client. The first pending message has the lowest logical - \* clock in the sequence (logical clocks are monotonically increasing) - firstPending, - - \* temporary variables used while finding the set of stable - \* messages. - timestamp, - nextClient, - lowestPending, - chooseMessage, - - \* the replica needs to know the logical clocks of the last - \* message received by each client in order to determine - \* request stability. - currentClocks = [c \in liveClients |-> 0]; - - \* determines the lowest logical clock value seen from all - \* clients. Any pending messages with timestamp lower than this - \* can be considered stable. - minClock, - - \* controls while loop execution. See the 'findStableRequestsLoop' - \* step for more information - continue, - - \* temporary variable: live clients that have pending - \* messages (stable or not) - pendingClients, - - \* Used when iterating over sets of clients - clientsIter, - - \* used to hold messages sent/received by the replica - msg, - - \* put requests were successful - ok, - - \* holds keys/values to be read from/written to the database - key, - val; { - - \* Main replica loop. In each iteration of the loop, the replica: - \* - \* 1. Waits for incoming messages from clients; - \* 2. Finds stable messages; - \* 3. Replies to all stable messages. - replicaLoop: - while (TRUE) { - - stableMessages := <<>>; - continue := TRUE; - - \* Waits for an incoming message from any client. This statement will - \* "block" the replica until a message is read into 'msg'. - \* See definition of client archetypes for the format of the messages. - receiveClientRequest: - msg := replicas[self]; - - \* if the message received is a disconnection from a client, - \* remove the client from the set of live clients - clientDisconnected: - if (msg.op = DISCONNECT_MSG) { - liveClients := liveClients \ {msg.client}; - }; - - \* if the message is a Get request: - replicaGetRequest: - if (msg.op = GET_MSG) { - \* safety assertion: a client requesting for a key must be live - assert(msg.client \in liveClients); - - \* update our records of the current logical clock of the - \* requesting client. - currentClocks[msg.client] := msg.timestamp; - - \* make this a pending message (to be dealt with later, during - \* stability check) - pendingRequests[msg.client] := Append(pendingRequests[msg.client], msg); - }; - - \* if the message is a Put request: similar to Get request. - replicaPutRequest: - if (msg.op = PUT_MSG) { - currentClocks[msg.client] := msg.timestamp; - pendingRequests[msg.client] := Append(pendingRequests[msg.client], msg); - }; - - \* if the message is a clock update from a client, inspect the logical clock - \* to check if it's lower than that of any other message seen before. - replicaNullRequest: - if (msg.op = NULL_MSG) { - currentClocks[msg.client] := msg.timestamp; - }; - - \* Message stability - \* ----------------- - \* - \* The replica needs to detect when messages become stable, and then respond to - \* those messages. Finding out which messages are stable and totally ordering them - \* is crucial for the correctness of the algorithm. If message stability does not work - \* correctly in the replicas, the database may get inconsistent across replicas - \* (if operations are applied in a different order), or clients may get "stuck" - \* (if stable messages are not replied). - - - \* This is the main loop that finds which of the pending requests (if any) are stable - findStableRequestsLoop: - while (continue) { - - \* only consider clients that have messages pending - pendingClients := {c \in liveClients : Len(pendingRequests[c]) > 0}; - - \* if two messages have the same logical clock, total ordering is enforced - \* based on the client identifier: requests from smaller client identifiers - \* are applied first - nextClient := NUM_NODES + 1; - - clientsIter := liveClients; - i := 0; - minClock := 0; - - \* in order to find the set of stable messages, we need to determine - \* the lowest logical clock among our set of live clients. Then, every - \* pending message with a timestamp greater than 'minClock' can be - \* considered stable. - findMinClock: - while (i < Cardinality(clientsIter)) { - with (client \in clientsIter) { - if (minClock = 0 \/ currentClocks[client] < minClock) { - minClock := currentClocks[client]; - }; - - clientsIter := clientsIter \ {client}; - } - }; - - \* this variable holds the timestamp of the request with the lowest clock - \* value that is pending and stable - lowestPending := minClock + 1; - - i := 0; - - \* find the next stable message to be processed - findMinClient: - while (i < Cardinality(pendingClients)) { - with (client \in pendingClients) { - - \* for each client with pending requests: - \* - inspect the first pending message (by definition, the message with - \* lowest clock from that client) - \* - extract the timestamp from the message - \* - record the client and timestamp in case this is the "oldest" message - - firstPending := Head(pendingRequests[client]); - assert(firstPending.op = GET_MSG \/ firstPending.op = PUT_MSG); - timestamp := firstPending.timestamp; - - \* a message is only stable if its timestamp is lower than - \* minClock - if (timestamp < minClock) { - - \* this is the next stable message if it has the lowest - \* timestamp seen so far; if the timestamp is the same as - \* the lowest seen so far, do a client-id comparison - chooseMessage := (timestamp < lowestPending) \/ ((timestamp = lowestPending) /\ (client < nextClient)); - if (chooseMessage) { - nextClient := client; - lowestPending := timestamp; - } - }; - - pendingClients := pendingClients \ {client}; - } - }; - - \* add the next stable message to the 'stableMessages' sequence. - \* if 'lowestPending' is >= 'minClock', it means no more stable messages - \* are pending, and we can leave this loop. - addStableMessage: - if (lowestPending < minClock) { - msg := Head(pendingRequests[nextClient]); - pendingRequests[nextClient] := Tail(pendingRequests[nextClient]); - - stableMessages := Append(stableMessages, msg); - } else { - continue := FALSE; - } - }; - - i := 1; - - \* iterate over our sequence of 'stableMessages' built in the previous - \* step, responding to each of them in order. - respondPendingRequestsLoop: - while (i <= Len(stableMessages)) { - msg := stableMessages[i]; - i := i + 1; - - respondStableGet: - if (msg.op = GET_MSG) { - key := msg.key; - val := kv[key]; - - \* send the value read from the database back to the client - clients[msg.client] := [type |-> GET_RESPONSE, result |-> val]; - }; - - respondStablePut: - if (msg.op = PUT_MSG) { - key := msg.key; - val := msg.value; - - \* update our database and send an OK back to the client - kv[key] := val; - - clients[msg.client] := [type |-> PUT_RESPONSE, result |-> ok]; - }; - } - } - } - - - \* Client Definitions - \* ------------------ - \* - \* The following archetypes define the client functions as specified in A1. - \* Note that these operations are the "logical" versions of the API: for example, - \* a Put archetype here sends a "Put" message to all replicas. - \* - \* In all of the definitions below, note that 'clocks' represent the client's - \* logical clock. However, upon disconnection, the clock is set to '-1', and - \* clients know to terminate when that happens. - - - \* Specifies a Get request from a client. Arguments: - \* - \* - replicas: connections to replica servers - \* - clients: connections to clients. Used only to listen for incoming messages - \* from replicas (i.e., to send the value of the key being read). - \* - key: the key being read. This *must* belong to the KeySpace set. - \* - locked: whether or not an RPC call is allowed. Clients do not send - \* concurrent requests. This stops a Get request from being sent - \* while a Put request is underway. - \* clock: The initial logical clock - \* - \* A Get message sent to the replica is a record in the following format: - \* - \* [op: GET_MSG, key: key, client: client_id, timestamp: lamport_clock] - archetype Get(clientId, ref replicas, clients, key, ref locked, ref clock, spin, ref outside) - variable continue = TRUE, getReq, getResp; - { - \* Loop until disconnected - getLoop: - while (continue) { - getRequest: - \* only perform a get request if not locked (i.e., Put request underway) - if (~locked[clientId]) { - \* if disconnected, return - if (clock[clientId] = -1) { - continue := FALSE - } else { - \* lock requests - locked[clientId] := TRUE; - - \* increment the logical clock, and construct a valid - \* Get message. - clock[clientId] := clock[clientId] + 1; - getReq := [op |-> GET_MSG, key |-> key, client |-> clientId, timestamp |-> clock[clientId]]; - - \* Choose some replica from the set of replicas to send this - \* request to - with (dst \in ReplicaSet) { - replicas[dst] := getReq; - }; - - \* Waits for the response from the replica - getReply: - getResp := clients[clientId]; - assert(getResp.type = GET_RESPONSE); - locked[clientId] := FALSE; - outside := getResp.result; - }; - }; - - getCheckSpin: - if (~spin) { - continue := FALSE; - } - } - } - - \* Specifies a Put request from a client. Arguments: - \* - \* - replicas: connection to the replicas. - \* - clients: connection to the clients. Used to read incoming messages (response - \* from the Put request - \* - key: the key being set. - \* - value: the value being written to the key - \* - locked: set when the Put request is sent to the replica to indicate that - \* other calls should wait for its completion - \* - clock: Lamport clocks - \* - \* A Put message sent to the replica is a record in the following format: - \* - \* [op: PUT_MSG, key: key, value: value, client: client_id, timestamp: lamport_clock] - archetype Put(clientId, ref replicas, clients, key, value, ref locked, ref clock, spin, ref outside) - variables continue = TRUE, i, j, putReq, putResp; - { - \* Loops indefinitely until disconnected - putLoop: - while (continue) { - putRequest: - \* only perform a get request if not locked (i.e., Get request underway) - if (~locked[clientId]) { - \* if disconnected, return - if (clock[clientId] = -1) { - continue := FALSE; - } else { - \* increment the logical clock, construct the payload to be sent - \* to the replica, and set 'locked' to TRUE - clock[clientId] := clock[clientId] + 1; - putReq := [op |-> PUT_MSG, key |-> key, value |-> value, client |-> clientId, timestamp |-> clock[clientId]]; - locked[clientId] := TRUE; - i := 0; - j := 0; - - \* Put requests must be broadcast to all replicas - putBroadcast: - Broadcast(replicas, j, NUM_REPLICAS-1, putReq); - - \* wait for a response from all replicas, and allow other - \* calls to the replica to happen after that. - putResponse: - while (i < Cardinality(ReplicaSet)) { - putResp := clients[clientId]; - assert(putResp.type = PUT_RESPONSE); - - i := i + 1; - }; - - locked[clientId] := FALSE; - - putComplete: - outside := PUT_RESPONSE; - }; - }; - - putCheckSpin: - if (~spin) { - continue := FALSE; - } - } - } - - \* Specifies a Disconnect message from the client. - \* Does not disconnect if 'locked' (i.e., a Put request is underway). - \* - \* A Disconnect message sent to the replica is a record in the following format: - \* - \* [op: DISCONNECT_MSG, client: client_id] - archetype Disconnect(clientId, ref replicas, locked, ref clock) - variables msg, j; - { - sendDisconnectRequest: - if (~locked[clientId]) { - msg := [op |-> DISCONNECT_MSG, client |-> clientId]; - - \* setting the logical clock internally to -1 indicates that this client - \* has disconnected. Other operations terminate accordingly. - clock[clientId] := -1; - j := 0; - }; - - \* Disconnection messages need to be broadcast to all replicas. - disconnectBroadcast: - Broadcast(replicas, j, NUM_REPLICAS-1, msg); - } - - \* Specifies a ClockUpdate ('null') message from the client. - \* If the client has disconnected, no more clock updates are sent. - \* - \* A ClockUpdate message sent to the replica is a record in the following format: - \* - \* [op: NULL_MSG, client: client_id, timestamp: logical_clock] - archetype ClockUpdate(clientId, ref replicas, ref clock, spin) - variables continue = TRUE, j, msg; - { - clockUpdateLoop: - while (continue) { - \* if we have disconnected, return - if (clock[clientId] = -1) { - continue := FALSE; - } else { - \* tick the lock and construct the message accordingly - clock[clientId] := clock[clientId] + 1; - msg := [op |-> NULL_MSG, client |-> clientId, timestamp |-> clock[clientId]]; - j := 0; - - \* clock update messages must be broadcast to all replicas. - nullBroadcast: - Broadcast(replicas, j, NUM_REPLICAS-1, msg); - }; - - nullCheckSpin: - if (~spin) { - continue := FALSE; - } - } - } - - \* Global Variables - \* ---------------- - - variables - \* queue of incoming messages for each of the replicas - replicasNetwork = [id \in ReplicaSet |-> <<>>], - - \* queue of incoming messages for each of the clients - clientsNetwork = [id \in ClientSet |-> <<>>], - - \* all clients are not locked initially - lock = [c \in ClientSet |-> FALSE], - - \* client identifier: to be appropriately mapped - cid = 0, - - \* communication channel with the caller; astracted - \* in this specification - out = 0, - - \* all clocks set to 0 initially - clocks = [c \in ClientSet |-> 0]; - - - \* Process Instantiations - \* ---------------------- - \* - \* This is where the archetypes defined above are instantiated into actual PlusCal - \* processes. We instantiate NUM_REPLICAS replica servers and NUM_CLIENTS client - \* processes for each possible client operation. TLC will be responsible for - \* exploring the different orderings in which these clients and replicas - \* may interact. - - - \* Instantiate replica servers. The network model used is the one defined in - \* the FIFOChannel mapping macro. - fair process (Replica \in ReplicaSet) == instance AReplica(ref clientsNetwork, replicasNetwork, [k \in KeySpace |-> NULL]) - mapping @1[_] via FIFOChannel - mapping @2[_] via FIFOChannel - mapping @3[_] via Identity; - - \* Instantiate clients: - - fair process (GetClient \in GetSet) == instance Get(cid, ref replicasNetwork, clientsNetwork, GET_KEY, ref lock, ref clocks, TRUE, ref out) - mapping cid via GetClientId - mapping replicasNetwork[_] via FIFOChannel - mapping clientsNetwork[_] via FIFOChannel - mapping lock[_] via BlockingLock - mapping clocks[_] via Identity; - - fair process (PutClient \in PutSet) == instance Put(cid, ref replicasNetwork, clientsNetwork, PUT_KEY, PUT_VALUE, ref lock, ref clocks, TRUE, ref out) - mapping cid via PutClientId - mapping replicasNetwork[_] via FIFOChannel - mapping clientsNetwork[_] via FIFOChannel - mapping lock[_] via BlockingLock - mapping clocks[_] via Identity; - - fair process (DisconnectClient \in DisconnectSet) == instance Disconnect(cid, ref replicasNetwork, lock, ref clocks) - mapping cid via DisconnectClientId - mapping replicasNetwork[_] via FIFOChannel - mapping lock[_] via BlockingLock - mapping clocks[_] via Identity; - - fair process (ClockUpdateClient \in NullSet) == instance ClockUpdate(cid, ref replicasNetwork, ref clocks, TRUE) - mapping cid via NullClientId - mapping replicasNetwork[_] via FIFOChannel - mapping clocks[_] via Identity; -} - -\* BEGIN PLUSCAL TRANSLATION ---algorithm ReplicatedKV { - variables replicasNetwork = [id \in ReplicaSet |-> <<>>], clientsNetwork = [id \in ClientSet |-> <<>>], lock = [c \in ClientSet |-> FALSE], cid = 0, out = 0, clocks = [c \in ClientSet |-> 0], replicasRead, replicasWrite, kvRead, clientsWrite, clientsWrite0, kvWrite, kvWrite0, clientsWrite1, clientIdRead, lockedRead, clientIdRead0, clockRead, clientIdRead1, lockedWrite, clientIdRead2, clockRead0, clientIdRead3, clockWrite, keyRead, clientIdRead4, clientIdRead5, clockRead1, replicasWrite0, clientsRead, clientsWrite2, outsideWrite, lockedWrite0, clockWrite0, replicasWrite1, clientsWrite3, outsideWrite0, spinRead, clientIdRead6, lockedRead0, clientIdRead7, clockRead2, clientIdRead8, clockRead3, clientIdRead9, clockWrite1, keyRead0, valueRead, clientIdRead10, clientIdRead11, clockRead4, clientIdRead12, lockedWrite1, replicasWrite2, replicasWrite3, clientsRead0, clientsWrite4, clientsWrite5, lockedWrite2, outsideWrite1, spinRead0, clientIdRead13, lockedRead1, clientIdRead14, clientIdRead15, clockWrite2, clockWrite3, replicasWrite4, replicasWrite5, clientIdRead16, clockRead5, clientIdRead17, clockRead6, clientIdRead18, clockWrite4, clientIdRead19, clientIdRead20, clockRead7, replicasWrite6, replicasWrite7, spinRead1; - define { - NUM_NODES == (NUM_REPLICAS) + (NUM_CLIENTS) - ReplicaSet == (0) .. ((NUM_REPLICAS) - (1)) - ClientSet == (NUM_REPLICAS) .. ((NUM_NODES) - (1)) - } - fair process (Replica \in ReplicaSet) - variables kvLocal = [k \in KeySpace |-> NULL], liveClients = ClientSet, pendingRequests = [c \in liveClients |-> <<>>], stableMessages = <<>>, i, firstPending, timestamp, nextClient, lowestPending, chooseMessage, currentClocks = [c \in liveClients |-> 0], minClock, continue, pendingClients, clientsIter, msg, ok, key, val; - { - replicaLoop: - if (TRUE) { - stableMessages := <<>>; - continue := TRUE; - receiveClientRequest: - await (Len(replicasNetwork[self])) > (0); - with (msg0 = Head(replicasNetwork[self])) { - replicasWrite := [replicasNetwork EXCEPT ![self] = Tail(replicasNetwork[self])]; - replicasRead := msg0; - }; - msg := replicasRead; - replicasNetwork := replicasWrite; - - clientDisconnected: - if (((msg).op) = (DISCONNECT_MSG)) { - liveClients := (liveClients) \ ({(msg).client}); - }; - - replicaGetRequest: - if (((msg).op) = (GET_MSG)) { - assert ((msg).client) \in (liveClients); - currentClocks[(msg).client] := (msg).timestamp; - pendingRequests[(msg).client] := Append(pendingRequests[(msg).client], msg); - }; - - replicaPutRequest: - if (((msg).op) = (PUT_MSG)) { - currentClocks[(msg).client] := (msg).timestamp; - pendingRequests[(msg).client] := Append(pendingRequests[(msg).client], msg); - }; - - replicaNullRequest: - if (((msg).op) = (NULL_MSG)) { - currentClocks[(msg).client] := (msg).timestamp; - }; - - findStableRequestsLoop: - if (continue) { - pendingClients := {c \in liveClients : (Len(pendingRequests[c])) > (0)}; - nextClient := (NUM_NODES) + (1); - clientsIter := liveClients; - i := 0; - minClock := 0; - findMinClock: - if ((i) < (Cardinality(clientsIter))) { - with (client \in clientsIter) { - if (((minClock) = (0)) \/ ((currentClocks[client]) < (minClock))) { - minClock := currentClocks[client]; - }; - clientsIter := (clientsIter) \ ({client}); - }; - goto findMinClock; - } else { - lowestPending := (minClock) + (1); - i := 0; - }; - - findMinClient: - if ((i) < (Cardinality(pendingClients))) { - with (client \in pendingClients) { - firstPending := Head(pendingRequests[client]); - assert (((firstPending).op) = (GET_MSG)) \/ (((firstPending).op) = (PUT_MSG)); - timestamp := (firstPending).timestamp; - if ((timestamp) < (minClock)) { - chooseMessage := ((timestamp) < (lowestPending)) \/ (((timestamp) = (lowestPending)) /\ ((client) < (nextClient))); - if (chooseMessage) { - nextClient := client; - lowestPending := timestamp; - }; - }; - pendingClients := (pendingClients) \ ({client}); - }; - goto findMinClient; - }; - - addStableMessage: - if ((lowestPending) < (minClock)) { - msg := Head(pendingRequests[nextClient]); - pendingRequests[nextClient] := Tail(pendingRequests[nextClient]); - stableMessages := Append(stableMessages, msg); - goto findStableRequestsLoop; - } else { - continue := FALSE; - goto findStableRequestsLoop; - }; - - } else { - i := 1; - }; - - respondPendingRequestsLoop: - if ((i) <= (Len(stableMessages))) { - msg := stableMessages[i]; - i := (i) + (1); - respondStableGet: - if (((msg).op) = (GET_MSG)) { - key := (msg).key; - kvRead := kvLocal[key]; - val := kvRead; - await (Len(clientsNetwork[(msg).client])) < (BUFFER_SIZE); - clientsWrite := [clientsNetwork EXCEPT ![(msg).client] = Append(clientsNetwork[(msg).client], [type |-> GET_RESPONSE, result |-> val])]; - clientsWrite0 := clientsWrite; - clientsNetwork := clientsWrite0; - } else { - clientsWrite0 := clientsNetwork; - clientsNetwork := clientsWrite0; - }; - - respondStablePut: - if (((msg).op) = (PUT_MSG)) { - key := (msg).key; - val := (msg).value; - kvWrite := [kvLocal EXCEPT ![key] = val]; - await (Len(clientsNetwork[(msg).client])) < (BUFFER_SIZE); - clientsWrite := [clientsNetwork EXCEPT ![(msg).client] = Append(clientsNetwork[(msg).client], [type |-> PUT_RESPONSE, result |-> ok])]; - kvWrite0 := kvWrite; - clientsWrite1 := clientsWrite; - clientsNetwork := clientsWrite1; - kvLocal := kvWrite0; - goto respondPendingRequestsLoop; - } else { - kvWrite0 := kvLocal; - clientsWrite1 := clientsNetwork; - clientsNetwork := clientsWrite1; - kvLocal := kvWrite0; - goto respondPendingRequestsLoop; - }; - - } else { - goto replicaLoop; - }; - - }; - - } - fair process (GetClient \in GetSet) - variables spinLocal = TRUE, continue = TRUE, getReq, getResp; - { - getLoop: - if (continue) { - getRequest: - clientIdRead := (self) - ((NUM_CLIENTS) * (GET_ORDER)); - await ~(lock[clientIdRead]); - lockedRead := FALSE; - if (~(lockedRead)) { - clientIdRead0 := (self) - ((NUM_CLIENTS) * (GET_ORDER)); - clockRead := clocks[clientIdRead0]; - if ((clockRead) = (-(1))) { - continue := FALSE; - lockedWrite0 := lock; - clockWrite0 := clocks; - replicasWrite1 := replicasNetwork; - clientsWrite3 := clientsNetwork; - outsideWrite0 := out; - replicasNetwork := replicasWrite1; - clientsNetwork := clientsWrite3; - lock := lockedWrite0; - clocks := clockWrite0; - out := outsideWrite0; - } else { - clientIdRead1 := (self) - ((NUM_CLIENTS) * (GET_ORDER)); - lockedWrite := [lock EXCEPT ![clientIdRead1] = TRUE]; - clientIdRead2 := (self) - ((NUM_CLIENTS) * (GET_ORDER)); - clockRead0 := clocks[clientIdRead2]; - clientIdRead3 := (self) - ((NUM_CLIENTS) * (GET_ORDER)); - clockWrite := [clocks EXCEPT ![clientIdRead3] = (clockRead0) + (1)]; - keyRead := GET_KEY; - clientIdRead4 := (self) - ((NUM_CLIENTS) * (GET_ORDER)); - clientIdRead5 := (self) - ((NUM_CLIENTS) * (GET_ORDER)); - clockRead1 := clockWrite[clientIdRead5]; - getReq := [op |-> GET_MSG, key |-> keyRead, client |-> clientIdRead4, timestamp |-> clockRead1]; - with (dst \in ReplicaSet) { - await (Len(replicasNetwork[dst])) < (BUFFER_SIZE); - replicasWrite0 := [replicasNetwork EXCEPT ![dst] = Append(replicasNetwork[dst], getReq)]; - }; - replicasNetwork := replicasWrite0; - lock := lockedWrite; - clocks := clockWrite; - getReply: - clientIdRead := (self) - ((NUM_CLIENTS) * (GET_ORDER)); - await (Len(clientsNetwork[clientIdRead])) > (0); - with (msg1 = Head(clientsNetwork[clientIdRead])) { - clientsWrite2 := [clientsNetwork EXCEPT ![clientIdRead] = Tail(clientsNetwork[clientIdRead])]; - clientsRead := msg1; - }; - getResp := clientsRead; - assert ((getResp).type) = (GET_RESPONSE); - clientIdRead0 := (self) - ((NUM_CLIENTS) * (GET_ORDER)); - lockedWrite := [lock EXCEPT ![clientIdRead0] = FALSE]; - outsideWrite := (getResp).result; - clientsNetwork := clientsWrite2; - lock := lockedWrite; - out := outsideWrite; - - }; - } else { - replicasNetwork := replicasWrite1; - clientsNetwork := clientsWrite3; - lock := lockedWrite0; - clocks := clockWrite0; - out := outsideWrite0; - }; - - getCheckSpin: - spinRead := spinLocal; - if (~(spinRead)) { - continue := FALSE; - goto getLoop; - } else { - goto getLoop; - }; - - }; - - } - fair process (PutClient \in PutSet) - variables spinLocal0 = TRUE, continue = TRUE, i, j, putReq, putResp; - { - putLoop: - if (continue) { - putRequest: - clientIdRead6 := (self) - ((NUM_CLIENTS) * (PUT_ORDER)); - await ~(lock[clientIdRead6]); - lockedRead0 := FALSE; - if (~(lockedRead0)) { - clientIdRead7 := (self) - ((NUM_CLIENTS) * (PUT_ORDER)); - clockRead2 := clocks[clientIdRead7]; - if ((clockRead2) = (-(1))) { - continue := FALSE; - } else { - clientIdRead8 := (self) - ((NUM_CLIENTS) * (PUT_ORDER)); - clockRead3 := clocks[clientIdRead8]; - clientIdRead9 := (self) - ((NUM_CLIENTS) * (PUT_ORDER)); - clockWrite1 := [clocks EXCEPT ![clientIdRead9] = (clockRead3) + (1)]; - keyRead0 := PUT_KEY; - valueRead := PUT_VALUE; - clientIdRead10 := (self) - ((NUM_CLIENTS) * (PUT_ORDER)); - clientIdRead11 := (self) - ((NUM_CLIENTS) * (PUT_ORDER)); - clockRead4 := clockWrite1[clientIdRead11]; - putReq := [op |-> PUT_MSG, key |-> keyRead0, value |-> valueRead, client |-> clientIdRead10, timestamp |-> clockRead4]; - clientIdRead12 := (self) - ((NUM_CLIENTS) * (PUT_ORDER)); - lockedWrite1 := [lock EXCEPT ![clientIdRead12] = TRUE]; - i := 0; - j := 0; - lock := lockedWrite1; - clocks := clockWrite1; - putBroadcast: - if ((j) <= ((NUM_REPLICAS) - (1))) { - await (Len(replicasNetwork[j])) < (BUFFER_SIZE); - replicasWrite2 := [replicasNetwork EXCEPT ![j] = Append(replicasNetwork[j], putReq)]; - j := (j) + (1); - replicasWrite3 := replicasWrite2; - replicasNetwork := replicasWrite3; - goto putBroadcast; - } else { - replicasWrite3 := replicasNetwork; - replicasNetwork := replicasWrite3; - }; - - putResponse: - if ((i) < (Cardinality(ReplicaSet))) { - clientIdRead6 := (self) - ((NUM_CLIENTS) * (PUT_ORDER)); - await (Len(clientsNetwork[clientIdRead6])) > (0); - with (msg2 = Head(clientsNetwork[clientIdRead6])) { - clientsWrite4 := [clientsNetwork EXCEPT ![clientIdRead6] = Tail(clientsNetwork[clientIdRead6])]; - clientsRead0 := msg2; - }; - putResp := clientsRead0; - assert ((putResp).type) = (PUT_RESPONSE); - i := (i) + (1); - clientsWrite5 := clientsWrite4; - lockedWrite2 := lock; - clientsNetwork := clientsWrite5; - lock := lockedWrite2; - goto putResponse; - } else { - clientIdRead7 := (self) - ((NUM_CLIENTS) * (PUT_ORDER)); - lockedWrite1 := [lock EXCEPT ![clientIdRead7] = FALSE]; - clientsWrite5 := clientsNetwork; - lockedWrite2 := lockedWrite1; - clientsNetwork := clientsWrite5; - lock := lockedWrite2; - }; - - putComplete: - outsideWrite1 := PUT_RESPONSE; - out := outsideWrite1; - - }; - }; - - putCheckSpin: - spinRead0 := spinLocal0; - if (~(spinRead0)) { - continue := FALSE; - goto putLoop; - } else { - goto putLoop; - }; - - }; - - } - fair process (DisconnectClient \in DisconnectSet) - variables msg, j; - { - sendDisconnectRequest: - clientIdRead13 := (self) - ((NUM_CLIENTS) * (DISCONNECT_ORDER)); - await ~(lock[clientIdRead13]); - lockedRead1 := FALSE; - if (~(lockedRead1)) { - clientIdRead14 := (self) - ((NUM_CLIENTS) * (DISCONNECT_ORDER)); - msg := [op |-> DISCONNECT_MSG, client |-> clientIdRead14]; - clientIdRead15 := (self) - ((NUM_CLIENTS) * (DISCONNECT_ORDER)); - clockWrite2 := [clocks EXCEPT ![clientIdRead15] = -(1)]; - j := 0; - clockWrite3 := clockWrite2; - clocks := clockWrite3; - } else { - clockWrite3 := clocks; - clocks := clockWrite3; - }; - disconnectBroadcast: - if ((j) <= ((NUM_REPLICAS) - (1))) { - await (Len(replicasNetwork[j])) < (BUFFER_SIZE); - replicasWrite4 := [replicasNetwork EXCEPT ![j] = Append(replicasNetwork[j], msg)]; - j := (j) + (1); - replicasWrite5 := replicasWrite4; - replicasNetwork := replicasWrite5; - goto disconnectBroadcast; - } else { - replicasWrite5 := replicasNetwork; - replicasNetwork := replicasWrite5; - }; - - } - fair process (ClockUpdateClient \in NullSet) - variables spinLocal1 = TRUE, continue = TRUE, j, msg; - { - clockUpdateLoop: - if (continue) { - clientIdRead16 := (self) - ((NUM_CLIENTS) * (NULL_ORDER)); - clockRead5 := clocks[clientIdRead16]; - if ((clockRead5) = (-(1))) { - continue := FALSE; - } else { - clientIdRead17 := (self) - ((NUM_CLIENTS) * (NULL_ORDER)); - clockRead6 := clocks[clientIdRead17]; - clientIdRead18 := (self) - ((NUM_CLIENTS) * (NULL_ORDER)); - clockWrite4 := [clocks EXCEPT ![clientIdRead18] = (clockRead6) + (1)]; - clientIdRead19 := (self) - ((NUM_CLIENTS) * (NULL_ORDER)); - clientIdRead20 := (self) - ((NUM_CLIENTS) * (NULL_ORDER)); - clockRead7 := clockWrite4[clientIdRead20]; - msg := [op |-> NULL_MSG, client |-> clientIdRead19, timestamp |-> clockRead7]; - j := 0; - clocks := clockWrite4; - nullBroadcast: - if ((j) <= ((NUM_REPLICAS) - (1))) { - await (Len(replicasNetwork[j])) < (BUFFER_SIZE); - replicasWrite6 := [replicasNetwork EXCEPT ![j] = Append(replicasNetwork[j], msg)]; - j := (j) + (1); - replicasWrite7 := replicasWrite6; - replicasNetwork := replicasWrite7; - goto nullBroadcast; - } else { - replicasWrite7 := replicasNetwork; - replicasNetwork := replicasWrite7; - }; - - }; - nullCheckSpin: - spinRead1 := spinLocal1; - if (~(spinRead1)) { - continue := FALSE; - goto clockUpdateLoop; - } else { - goto clockUpdateLoop; - }; - - }; - - } -} -\* END PLUSCAL TRANSLATION - - -***************************************************************************) -\* BEGIN TRANSLATION -\* Process variable i of process Replica at line 679 col 148 changed to i_ -\* Process variable continue of process Replica at line 679 col 271 changed to continue_ -\* Process variable msg of process Replica at line 679 col 310 changed to msg_ -\* Process variable continue of process GetClient at line 817 col 33 changed to continue_G -\* Process variable continue of process PutClient at line 897 col 34 changed to continue_P -\* Process variable j of process PutClient at line 897 col 54 changed to j_ -\* Process variable msg of process DisconnectClient at line 985 col 15 changed to msg_D -\* Process variable j of process DisconnectClient at line 985 col 20 changed to j_D -CONSTANT defaultInitValue -VARIABLES replicasNetwork, clientsNetwork, lock, cid, out, clocks, - replicasRead, replicasWrite, kvRead, clientsWrite, clientsWrite0, - kvWrite, kvWrite0, clientsWrite1, clientIdRead, lockedRead, - clientIdRead0, clockRead, clientIdRead1, lockedWrite, clientIdRead2, - clockRead0, clientIdRead3, clockWrite, keyRead, clientIdRead4, - clientIdRead5, clockRead1, replicasWrite0, clientsRead, - clientsWrite2, outsideWrite, lockedWrite0, clockWrite0, - replicasWrite1, clientsWrite3, outsideWrite0, spinRead, - clientIdRead6, lockedRead0, clientIdRead7, clockRead2, - clientIdRead8, clockRead3, clientIdRead9, clockWrite1, keyRead0, - valueRead, clientIdRead10, clientIdRead11, clockRead4, - clientIdRead12, lockedWrite1, replicasWrite2, replicasWrite3, - clientsRead0, clientsWrite4, clientsWrite5, lockedWrite2, - outsideWrite1, spinRead0, clientIdRead13, lockedRead1, - clientIdRead14, clientIdRead15, clockWrite2, clockWrite3, - replicasWrite4, replicasWrite5, clientIdRead16, clockRead5, - clientIdRead17, clockRead6, clientIdRead18, clockWrite4, - clientIdRead19, clientIdRead20, clockRead7, replicasWrite6, - replicasWrite7, spinRead1, pc - -(* define statement *) -NUM_NODES == (NUM_REPLICAS) + (NUM_CLIENTS) -ReplicaSet == (0) .. ((NUM_REPLICAS) - (1)) -ClientSet == (NUM_REPLICAS) .. ((NUM_NODES) - (1)) - -VARIABLES kvLocal, liveClients, pendingRequests, stableMessages, i_, - firstPending, timestamp, nextClient, lowestPending, chooseMessage, - currentClocks, minClock, continue_, pendingClients, clientsIter, - msg_, ok, key, val, spinLocal, continue_G, getReq, getResp, - spinLocal0, continue_P, i, j_, putReq, putResp, msg_D, j_D, - spinLocal1, continue, j, msg - -vars == << replicasNetwork, clientsNetwork, lock, cid, out, clocks, - replicasRead, replicasWrite, kvRead, clientsWrite, clientsWrite0, - kvWrite, kvWrite0, clientsWrite1, clientIdRead, lockedRead, - clientIdRead0, clockRead, clientIdRead1, lockedWrite, - clientIdRead2, clockRead0, clientIdRead3, clockWrite, keyRead, - clientIdRead4, clientIdRead5, clockRead1, replicasWrite0, - clientsRead, clientsWrite2, outsideWrite, lockedWrite0, - clockWrite0, replicasWrite1, clientsWrite3, outsideWrite0, - spinRead, clientIdRead6, lockedRead0, clientIdRead7, clockRead2, - clientIdRead8, clockRead3, clientIdRead9, clockWrite1, keyRead0, - valueRead, clientIdRead10, clientIdRead11, clockRead4, - clientIdRead12, lockedWrite1, replicasWrite2, replicasWrite3, - clientsRead0, clientsWrite4, clientsWrite5, lockedWrite2, - outsideWrite1, spinRead0, clientIdRead13, lockedRead1, - clientIdRead14, clientIdRead15, clockWrite2, clockWrite3, - replicasWrite4, replicasWrite5, clientIdRead16, clockRead5, - clientIdRead17, clockRead6, clientIdRead18, clockWrite4, - clientIdRead19, clientIdRead20, clockRead7, replicasWrite6, - replicasWrite7, spinRead1, pc, kvLocal, liveClients, - pendingRequests, stableMessages, i_, firstPending, timestamp, - nextClient, lowestPending, chooseMessage, currentClocks, minClock, - continue_, pendingClients, clientsIter, msg_, ok, key, val, - spinLocal, continue_G, getReq, getResp, spinLocal0, continue_P, i, - j_, putReq, putResp, msg_D, j_D, spinLocal1, continue, j, msg >> - -ProcSet == (ReplicaSet) \cup (GetSet) \cup (PutSet) \cup (DisconnectSet) \cup (NullSet) - -Init == (* Global variables *) - /\ replicasNetwork = [id \in ReplicaSet |-> <<>>] - /\ clientsNetwork = [id \in ClientSet |-> <<>>] - /\ lock = [c \in ClientSet |-> FALSE] - /\ cid = 0 - /\ out = 0 - /\ clocks = [c \in ClientSet |-> 0] - /\ replicasRead = defaultInitValue - /\ replicasWrite = defaultInitValue - /\ kvRead = defaultInitValue - /\ clientsWrite = defaultInitValue - /\ clientsWrite0 = defaultInitValue - /\ kvWrite = defaultInitValue - /\ kvWrite0 = defaultInitValue - /\ clientsWrite1 = defaultInitValue - /\ clientIdRead = defaultInitValue - /\ lockedRead = defaultInitValue - /\ clientIdRead0 = defaultInitValue - /\ clockRead = defaultInitValue - /\ clientIdRead1 = defaultInitValue - /\ lockedWrite = defaultInitValue - /\ clientIdRead2 = defaultInitValue - /\ clockRead0 = defaultInitValue - /\ clientIdRead3 = defaultInitValue - /\ clockWrite = defaultInitValue - /\ keyRead = defaultInitValue - /\ clientIdRead4 = defaultInitValue - /\ clientIdRead5 = defaultInitValue - /\ clockRead1 = defaultInitValue - /\ replicasWrite0 = defaultInitValue - /\ clientsRead = defaultInitValue - /\ clientsWrite2 = defaultInitValue - /\ outsideWrite = defaultInitValue - /\ lockedWrite0 = defaultInitValue - /\ clockWrite0 = defaultInitValue - /\ replicasWrite1 = defaultInitValue - /\ clientsWrite3 = defaultInitValue - /\ outsideWrite0 = defaultInitValue - /\ spinRead = defaultInitValue - /\ clientIdRead6 = defaultInitValue - /\ lockedRead0 = defaultInitValue - /\ clientIdRead7 = defaultInitValue - /\ clockRead2 = defaultInitValue - /\ clientIdRead8 = defaultInitValue - /\ clockRead3 = defaultInitValue - /\ clientIdRead9 = defaultInitValue - /\ clockWrite1 = defaultInitValue - /\ keyRead0 = defaultInitValue - /\ valueRead = defaultInitValue - /\ clientIdRead10 = defaultInitValue - /\ clientIdRead11 = defaultInitValue - /\ clockRead4 = defaultInitValue - /\ clientIdRead12 = defaultInitValue - /\ lockedWrite1 = defaultInitValue - /\ replicasWrite2 = defaultInitValue - /\ replicasWrite3 = defaultInitValue - /\ clientsRead0 = defaultInitValue - /\ clientsWrite4 = defaultInitValue - /\ clientsWrite5 = defaultInitValue - /\ lockedWrite2 = defaultInitValue - /\ outsideWrite1 = defaultInitValue - /\ spinRead0 = defaultInitValue - /\ clientIdRead13 = defaultInitValue - /\ lockedRead1 = defaultInitValue - /\ clientIdRead14 = defaultInitValue - /\ clientIdRead15 = defaultInitValue - /\ clockWrite2 = defaultInitValue - /\ clockWrite3 = defaultInitValue - /\ replicasWrite4 = defaultInitValue - /\ replicasWrite5 = defaultInitValue - /\ clientIdRead16 = defaultInitValue - /\ clockRead5 = defaultInitValue - /\ clientIdRead17 = defaultInitValue - /\ clockRead6 = defaultInitValue - /\ clientIdRead18 = defaultInitValue - /\ clockWrite4 = defaultInitValue - /\ clientIdRead19 = defaultInitValue - /\ clientIdRead20 = defaultInitValue - /\ clockRead7 = defaultInitValue - /\ replicasWrite6 = defaultInitValue - /\ replicasWrite7 = defaultInitValue - /\ spinRead1 = defaultInitValue - (* Process Replica *) - /\ kvLocal = [self \in ReplicaSet |-> [k \in KeySpace |-> NULL]] - /\ liveClients = [self \in ReplicaSet |-> ClientSet] - /\ pendingRequests = [self \in ReplicaSet |-> [c \in liveClients[self] |-> <<>>]] - /\ stableMessages = [self \in ReplicaSet |-> <<>>] - /\ i_ = [self \in ReplicaSet |-> defaultInitValue] - /\ firstPending = [self \in ReplicaSet |-> defaultInitValue] - /\ timestamp = [self \in ReplicaSet |-> defaultInitValue] - /\ nextClient = [self \in ReplicaSet |-> defaultInitValue] - /\ lowestPending = [self \in ReplicaSet |-> defaultInitValue] - /\ chooseMessage = [self \in ReplicaSet |-> defaultInitValue] - /\ currentClocks = [self \in ReplicaSet |-> [c \in liveClients[self] |-> 0]] - /\ minClock = [self \in ReplicaSet |-> defaultInitValue] - /\ continue_ = [self \in ReplicaSet |-> defaultInitValue] - /\ pendingClients = [self \in ReplicaSet |-> defaultInitValue] - /\ clientsIter = [self \in ReplicaSet |-> defaultInitValue] - /\ msg_ = [self \in ReplicaSet |-> defaultInitValue] - /\ ok = [self \in ReplicaSet |-> defaultInitValue] - /\ key = [self \in ReplicaSet |-> defaultInitValue] - /\ val = [self \in ReplicaSet |-> defaultInitValue] - (* Process GetClient *) - /\ spinLocal = [self \in GetSet |-> TRUE] - /\ continue_G = [self \in GetSet |-> TRUE] - /\ getReq = [self \in GetSet |-> defaultInitValue] - /\ getResp = [self \in GetSet |-> defaultInitValue] - (* Process PutClient *) - /\ spinLocal0 = [self \in PutSet |-> TRUE] - /\ continue_P = [self \in PutSet |-> TRUE] - /\ i = [self \in PutSet |-> defaultInitValue] - /\ j_ = [self \in PutSet |-> defaultInitValue] - /\ putReq = [self \in PutSet |-> defaultInitValue] - /\ putResp = [self \in PutSet |-> defaultInitValue] - (* Process DisconnectClient *) - /\ msg_D = [self \in DisconnectSet |-> defaultInitValue] - /\ j_D = [self \in DisconnectSet |-> defaultInitValue] - (* Process ClockUpdateClient *) - /\ spinLocal1 = [self \in NullSet |-> TRUE] - /\ continue = [self \in NullSet |-> TRUE] - /\ j = [self \in NullSet |-> defaultInitValue] - /\ msg = [self \in NullSet |-> defaultInitValue] - /\ pc = [self \in ProcSet |-> CASE self \in ReplicaSet -> "replicaLoop" - [] self \in GetSet -> "getLoop" - [] self \in PutSet -> "putLoop" - [] self \in DisconnectSet -> "sendDisconnectRequest" - [] self \in NullSet -> "clockUpdateLoop"] - -replicaLoop(self) == /\ pc[self] = "replicaLoop" - /\ IF TRUE - THEN /\ stableMessages' = [stableMessages EXCEPT ![self] = <<>>] - /\ continue_' = [continue_ EXCEPT ![self] = TRUE] - /\ pc' = [pc EXCEPT ![self] = "receiveClientRequest"] - ELSE /\ pc' = [pc EXCEPT ![self] = "Done"] - /\ UNCHANGED << stableMessages, continue_ >> - /\ UNCHANGED << replicasNetwork, clientsNetwork, lock, - cid, out, clocks, replicasRead, - replicasWrite, kvRead, clientsWrite, - clientsWrite0, kvWrite, kvWrite0, - clientsWrite1, clientIdRead, lockedRead, - clientIdRead0, clockRead, clientIdRead1, - lockedWrite, clientIdRead2, clockRead0, - clientIdRead3, clockWrite, keyRead, - clientIdRead4, clientIdRead5, clockRead1, - replicasWrite0, clientsRead, - clientsWrite2, outsideWrite, lockedWrite0, - clockWrite0, replicasWrite1, - clientsWrite3, outsideWrite0, spinRead, - clientIdRead6, lockedRead0, clientIdRead7, - clockRead2, clientIdRead8, clockRead3, - clientIdRead9, clockWrite1, keyRead0, - valueRead, clientIdRead10, clientIdRead11, - clockRead4, clientIdRead12, lockedWrite1, - replicasWrite2, replicasWrite3, - clientsRead0, clientsWrite4, - clientsWrite5, lockedWrite2, - outsideWrite1, spinRead0, clientIdRead13, - lockedRead1, clientIdRead14, - clientIdRead15, clockWrite2, clockWrite3, - replicasWrite4, replicasWrite5, - clientIdRead16, clockRead5, - clientIdRead17, clockRead6, - clientIdRead18, clockWrite4, - clientIdRead19, clientIdRead20, - clockRead7, replicasWrite6, - replicasWrite7, spinRead1, kvLocal, - liveClients, pendingRequests, i_, - firstPending, timestamp, nextClient, - lowestPending, chooseMessage, - currentClocks, minClock, pendingClients, - clientsIter, msg_, ok, key, val, - spinLocal, continue_G, getReq, getResp, - spinLocal0, continue_P, i, j_, putReq, - putResp, msg_D, j_D, spinLocal1, continue, - j, msg >> - -receiveClientRequest(self) == /\ pc[self] = "receiveClientRequest" - /\ (Len(replicasNetwork[self])) > (0) - /\ LET msg0 == Head(replicasNetwork[self]) IN - /\ replicasWrite' = [replicasNetwork EXCEPT ![self] = Tail(replicasNetwork[self])] - /\ replicasRead' = msg0 - /\ msg_' = [msg_ EXCEPT ![self] = replicasRead'] - /\ replicasNetwork' = replicasWrite' - /\ pc' = [pc EXCEPT ![self] = "clientDisconnected"] - /\ UNCHANGED << clientsNetwork, lock, cid, out, - clocks, kvRead, clientsWrite, - clientsWrite0, kvWrite, kvWrite0, - clientsWrite1, clientIdRead, - lockedRead, clientIdRead0, - clockRead, clientIdRead1, - lockedWrite, clientIdRead2, - clockRead0, clientIdRead3, - clockWrite, keyRead, - clientIdRead4, clientIdRead5, - clockRead1, replicasWrite0, - clientsRead, clientsWrite2, - outsideWrite, lockedWrite0, - clockWrite0, replicasWrite1, - clientsWrite3, outsideWrite0, - spinRead, clientIdRead6, - lockedRead0, clientIdRead7, - clockRead2, clientIdRead8, - clockRead3, clientIdRead9, - clockWrite1, keyRead0, valueRead, - clientIdRead10, clientIdRead11, - clockRead4, clientIdRead12, - lockedWrite1, replicasWrite2, - replicasWrite3, clientsRead0, - clientsWrite4, clientsWrite5, - lockedWrite2, outsideWrite1, - spinRead0, clientIdRead13, - lockedRead1, clientIdRead14, - clientIdRead15, clockWrite2, - clockWrite3, replicasWrite4, - replicasWrite5, clientIdRead16, - clockRead5, clientIdRead17, - clockRead6, clientIdRead18, - clockWrite4, clientIdRead19, - clientIdRead20, clockRead7, - replicasWrite6, replicasWrite7, - spinRead1, kvLocal, liveClients, - pendingRequests, stableMessages, - i_, firstPending, timestamp, - nextClient, lowestPending, - chooseMessage, currentClocks, - minClock, continue_, - pendingClients, clientsIter, ok, - key, val, spinLocal, continue_G, - getReq, getResp, spinLocal0, - continue_P, i, j_, putReq, - putResp, msg_D, j_D, spinLocal1, - continue, j, msg >> - -clientDisconnected(self) == /\ pc[self] = "clientDisconnected" - /\ IF ((msg_[self]).op) = (DISCONNECT_MSG) - THEN /\ liveClients' = [liveClients EXCEPT ![self] = (liveClients[self]) \ ({(msg_[self]).client})] - ELSE /\ TRUE - /\ UNCHANGED liveClients - /\ pc' = [pc EXCEPT ![self] = "replicaGetRequest"] - /\ UNCHANGED << replicasNetwork, clientsNetwork, - lock, cid, out, clocks, - replicasRead, replicasWrite, - kvRead, clientsWrite, - clientsWrite0, kvWrite, kvWrite0, - clientsWrite1, clientIdRead, - lockedRead, clientIdRead0, - clockRead, clientIdRead1, - lockedWrite, clientIdRead2, - clockRead0, clientIdRead3, - clockWrite, keyRead, clientIdRead4, - clientIdRead5, clockRead1, - replicasWrite0, clientsRead, - clientsWrite2, outsideWrite, - lockedWrite0, clockWrite0, - replicasWrite1, clientsWrite3, - outsideWrite0, spinRead, - clientIdRead6, lockedRead0, - clientIdRead7, clockRead2, - clientIdRead8, clockRead3, - clientIdRead9, clockWrite1, - keyRead0, valueRead, - clientIdRead10, clientIdRead11, - clockRead4, clientIdRead12, - lockedWrite1, replicasWrite2, - replicasWrite3, clientsRead0, - clientsWrite4, clientsWrite5, - lockedWrite2, outsideWrite1, - spinRead0, clientIdRead13, - lockedRead1, clientIdRead14, - clientIdRead15, clockWrite2, - clockWrite3, replicasWrite4, - replicasWrite5, clientIdRead16, - clockRead5, clientIdRead17, - clockRead6, clientIdRead18, - clockWrite4, clientIdRead19, - clientIdRead20, clockRead7, - replicasWrite6, replicasWrite7, - spinRead1, kvLocal, - pendingRequests, stableMessages, - i_, firstPending, timestamp, - nextClient, lowestPending, - chooseMessage, currentClocks, - minClock, continue_, - pendingClients, clientsIter, msg_, - ok, key, val, spinLocal, - continue_G, getReq, getResp, - spinLocal0, continue_P, i, j_, - putReq, putResp, msg_D, j_D, - spinLocal1, continue, j, msg >> - -replicaGetRequest(self) == /\ pc[self] = "replicaGetRequest" - /\ IF ((msg_[self]).op) = (GET_MSG) - THEN /\ Assert(((msg_[self]).client) \in (liveClients[self]), - "Failure of assertion at line 701, column 25.") - /\ currentClocks' = [currentClocks EXCEPT ![self][(msg_[self]).client] = (msg_[self]).timestamp] - /\ pendingRequests' = [pendingRequests EXCEPT ![self][(msg_[self]).client] = Append(pendingRequests[self][(msg_[self]).client], msg_[self])] - ELSE /\ TRUE - /\ UNCHANGED << pendingRequests, - currentClocks >> - /\ pc' = [pc EXCEPT ![self] = "replicaPutRequest"] - /\ UNCHANGED << replicasNetwork, clientsNetwork, - lock, cid, out, clocks, - replicasRead, replicasWrite, kvRead, - clientsWrite, clientsWrite0, - kvWrite, kvWrite0, clientsWrite1, - clientIdRead, lockedRead, - clientIdRead0, clockRead, - clientIdRead1, lockedWrite, - clientIdRead2, clockRead0, - clientIdRead3, clockWrite, keyRead, - clientIdRead4, clientIdRead5, - clockRead1, replicasWrite0, - clientsRead, clientsWrite2, - outsideWrite, lockedWrite0, - clockWrite0, replicasWrite1, - clientsWrite3, outsideWrite0, - spinRead, clientIdRead6, - lockedRead0, clientIdRead7, - clockRead2, clientIdRead8, - clockRead3, clientIdRead9, - clockWrite1, keyRead0, valueRead, - clientIdRead10, clientIdRead11, - clockRead4, clientIdRead12, - lockedWrite1, replicasWrite2, - replicasWrite3, clientsRead0, - clientsWrite4, clientsWrite5, - lockedWrite2, outsideWrite1, - spinRead0, clientIdRead13, - lockedRead1, clientIdRead14, - clientIdRead15, clockWrite2, - clockWrite3, replicasWrite4, - replicasWrite5, clientIdRead16, - clockRead5, clientIdRead17, - clockRead6, clientIdRead18, - clockWrite4, clientIdRead19, - clientIdRead20, clockRead7, - replicasWrite6, replicasWrite7, - spinRead1, kvLocal, liveClients, - stableMessages, i_, firstPending, - timestamp, nextClient, - lowestPending, chooseMessage, - minClock, continue_, pendingClients, - clientsIter, msg_, ok, key, val, - spinLocal, continue_G, getReq, - getResp, spinLocal0, continue_P, i, - j_, putReq, putResp, msg_D, j_D, - spinLocal1, continue, j, msg >> - -replicaPutRequest(self) == /\ pc[self] = "replicaPutRequest" - /\ IF ((msg_[self]).op) = (PUT_MSG) - THEN /\ currentClocks' = [currentClocks EXCEPT ![self][(msg_[self]).client] = (msg_[self]).timestamp] - /\ pendingRequests' = [pendingRequests EXCEPT ![self][(msg_[self]).client] = Append(pendingRequests[self][(msg_[self]).client], msg_[self])] - ELSE /\ TRUE - /\ UNCHANGED << pendingRequests, - currentClocks >> - /\ pc' = [pc EXCEPT ![self] = "replicaNullRequest"] - /\ UNCHANGED << replicasNetwork, clientsNetwork, - lock, cid, out, clocks, - replicasRead, replicasWrite, kvRead, - clientsWrite, clientsWrite0, - kvWrite, kvWrite0, clientsWrite1, - clientIdRead, lockedRead, - clientIdRead0, clockRead, - clientIdRead1, lockedWrite, - clientIdRead2, clockRead0, - clientIdRead3, clockWrite, keyRead, - clientIdRead4, clientIdRead5, - clockRead1, replicasWrite0, - clientsRead, clientsWrite2, - outsideWrite, lockedWrite0, - clockWrite0, replicasWrite1, - clientsWrite3, outsideWrite0, - spinRead, clientIdRead6, - lockedRead0, clientIdRead7, - clockRead2, clientIdRead8, - clockRead3, clientIdRead9, - clockWrite1, keyRead0, valueRead, - clientIdRead10, clientIdRead11, - clockRead4, clientIdRead12, - lockedWrite1, replicasWrite2, - replicasWrite3, clientsRead0, - clientsWrite4, clientsWrite5, - lockedWrite2, outsideWrite1, - spinRead0, clientIdRead13, - lockedRead1, clientIdRead14, - clientIdRead15, clockWrite2, - clockWrite3, replicasWrite4, - replicasWrite5, clientIdRead16, - clockRead5, clientIdRead17, - clockRead6, clientIdRead18, - clockWrite4, clientIdRead19, - clientIdRead20, clockRead7, - replicasWrite6, replicasWrite7, - spinRead1, kvLocal, liveClients, - stableMessages, i_, firstPending, - timestamp, nextClient, - lowestPending, chooseMessage, - minClock, continue_, pendingClients, - clientsIter, msg_, ok, key, val, - spinLocal, continue_G, getReq, - getResp, spinLocal0, continue_P, i, - j_, putReq, putResp, msg_D, j_D, - spinLocal1, continue, j, msg >> - -replicaNullRequest(self) == /\ pc[self] = "replicaNullRequest" - /\ IF ((msg_[self]).op) = (NULL_MSG) - THEN /\ currentClocks' = [currentClocks EXCEPT ![self][(msg_[self]).client] = (msg_[self]).timestamp] - ELSE /\ TRUE - /\ UNCHANGED currentClocks - /\ pc' = [pc EXCEPT ![self] = "findStableRequestsLoop"] - /\ UNCHANGED << replicasNetwork, clientsNetwork, - lock, cid, out, clocks, - replicasRead, replicasWrite, - kvRead, clientsWrite, - clientsWrite0, kvWrite, kvWrite0, - clientsWrite1, clientIdRead, - lockedRead, clientIdRead0, - clockRead, clientIdRead1, - lockedWrite, clientIdRead2, - clockRead0, clientIdRead3, - clockWrite, keyRead, clientIdRead4, - clientIdRead5, clockRead1, - replicasWrite0, clientsRead, - clientsWrite2, outsideWrite, - lockedWrite0, clockWrite0, - replicasWrite1, clientsWrite3, - outsideWrite0, spinRead, - clientIdRead6, lockedRead0, - clientIdRead7, clockRead2, - clientIdRead8, clockRead3, - clientIdRead9, clockWrite1, - keyRead0, valueRead, - clientIdRead10, clientIdRead11, - clockRead4, clientIdRead12, - lockedWrite1, replicasWrite2, - replicasWrite3, clientsRead0, - clientsWrite4, clientsWrite5, - lockedWrite2, outsideWrite1, - spinRead0, clientIdRead13, - lockedRead1, clientIdRead14, - clientIdRead15, clockWrite2, - clockWrite3, replicasWrite4, - replicasWrite5, clientIdRead16, - clockRead5, clientIdRead17, - clockRead6, clientIdRead18, - clockWrite4, clientIdRead19, - clientIdRead20, clockRead7, - replicasWrite6, replicasWrite7, - spinRead1, kvLocal, liveClients, - pendingRequests, stableMessages, - i_, firstPending, timestamp, - nextClient, lowestPending, - chooseMessage, minClock, continue_, - pendingClients, clientsIter, msg_, - ok, key, val, spinLocal, - continue_G, getReq, getResp, - spinLocal0, continue_P, i, j_, - putReq, putResp, msg_D, j_D, - spinLocal1, continue, j, msg >> - -findStableRequestsLoop(self) == /\ pc[self] = "findStableRequestsLoop" - /\ IF continue_[self] - THEN /\ pendingClients' = [pendingClients EXCEPT ![self] = {c \in liveClients[self] : (Len(pendingRequests[self][c])) > (0)}] - /\ nextClient' = [nextClient EXCEPT ![self] = (NUM_NODES) + (1)] - /\ clientsIter' = [clientsIter EXCEPT ![self] = liveClients[self]] - /\ i_' = [i_ EXCEPT ![self] = 0] - /\ minClock' = [minClock EXCEPT ![self] = 0] - /\ pc' = [pc EXCEPT ![self] = "findMinClock"] - ELSE /\ i_' = [i_ EXCEPT ![self] = 1] - /\ pc' = [pc EXCEPT ![self] = "respondPendingRequestsLoop"] - /\ UNCHANGED << nextClient, - minClock, - pendingClients, - clientsIter >> - /\ UNCHANGED << replicasNetwork, - clientsNetwork, lock, cid, out, - clocks, replicasRead, - replicasWrite, kvRead, - clientsWrite, clientsWrite0, - kvWrite, kvWrite0, - clientsWrite1, clientIdRead, - lockedRead, clientIdRead0, - clockRead, clientIdRead1, - lockedWrite, clientIdRead2, - clockRead0, clientIdRead3, - clockWrite, keyRead, - clientIdRead4, clientIdRead5, - clockRead1, replicasWrite0, - clientsRead, clientsWrite2, - outsideWrite, lockedWrite0, - clockWrite0, replicasWrite1, - clientsWrite3, outsideWrite0, - spinRead, clientIdRead6, - lockedRead0, clientIdRead7, - clockRead2, clientIdRead8, - clockRead3, clientIdRead9, - clockWrite1, keyRead0, - valueRead, clientIdRead10, - clientIdRead11, clockRead4, - clientIdRead12, lockedWrite1, - replicasWrite2, replicasWrite3, - clientsRead0, clientsWrite4, - clientsWrite5, lockedWrite2, - outsideWrite1, spinRead0, - clientIdRead13, lockedRead1, - clientIdRead14, clientIdRead15, - clockWrite2, clockWrite3, - replicasWrite4, replicasWrite5, - clientIdRead16, clockRead5, - clientIdRead17, clockRead6, - clientIdRead18, clockWrite4, - clientIdRead19, clientIdRead20, - clockRead7, replicasWrite6, - replicasWrite7, spinRead1, - kvLocal, liveClients, - pendingRequests, - stableMessages, firstPending, - timestamp, lowestPending, - chooseMessage, currentClocks, - continue_, msg_, ok, key, val, - spinLocal, continue_G, getReq, - getResp, spinLocal0, - continue_P, i, j_, putReq, - putResp, msg_D, j_D, - spinLocal1, continue, j, msg >> - -findMinClock(self) == /\ pc[self] = "findMinClock" - /\ IF (i_[self]) < (Cardinality(clientsIter[self])) - THEN /\ \E client \in clientsIter[self]: - /\ IF ((minClock[self]) = (0)) \/ ((currentClocks[self][client]) < (minClock[self])) - THEN /\ minClock' = [minClock EXCEPT ![self] = currentClocks[self][client]] - ELSE /\ TRUE - /\ UNCHANGED minClock - /\ clientsIter' = [clientsIter EXCEPT ![self] = (clientsIter[self]) \ ({client})] - /\ pc' = [pc EXCEPT ![self] = "findMinClock"] - /\ UNCHANGED << i_, lowestPending >> - ELSE /\ lowestPending' = [lowestPending EXCEPT ![self] = (minClock[self]) + (1)] - /\ i_' = [i_ EXCEPT ![self] = 0] - /\ pc' = [pc EXCEPT ![self] = "findMinClient"] - /\ UNCHANGED << minClock, clientsIter >> - /\ UNCHANGED << replicasNetwork, clientsNetwork, lock, - cid, out, clocks, replicasRead, - replicasWrite, kvRead, clientsWrite, - clientsWrite0, kvWrite, kvWrite0, - clientsWrite1, clientIdRead, lockedRead, - clientIdRead0, clockRead, clientIdRead1, - lockedWrite, clientIdRead2, clockRead0, - clientIdRead3, clockWrite, keyRead, - clientIdRead4, clientIdRead5, clockRead1, - replicasWrite0, clientsRead, - clientsWrite2, outsideWrite, - lockedWrite0, clockWrite0, - replicasWrite1, clientsWrite3, - outsideWrite0, spinRead, clientIdRead6, - lockedRead0, clientIdRead7, clockRead2, - clientIdRead8, clockRead3, clientIdRead9, - clockWrite1, keyRead0, valueRead, - clientIdRead10, clientIdRead11, - clockRead4, clientIdRead12, lockedWrite1, - replicasWrite2, replicasWrite3, - clientsRead0, clientsWrite4, - clientsWrite5, lockedWrite2, - outsideWrite1, spinRead0, clientIdRead13, - lockedRead1, clientIdRead14, - clientIdRead15, clockWrite2, clockWrite3, - replicasWrite4, replicasWrite5, - clientIdRead16, clockRead5, - clientIdRead17, clockRead6, - clientIdRead18, clockWrite4, - clientIdRead19, clientIdRead20, - clockRead7, replicasWrite6, - replicasWrite7, spinRead1, kvLocal, - liveClients, pendingRequests, - stableMessages, firstPending, timestamp, - nextClient, chooseMessage, currentClocks, - continue_, pendingClients, msg_, ok, key, - val, spinLocal, continue_G, getReq, - getResp, spinLocal0, continue_P, i, j_, - putReq, putResp, msg_D, j_D, spinLocal1, - continue, j, msg >> - -findMinClient(self) == /\ pc[self] = "findMinClient" - /\ IF (i_[self]) < (Cardinality(pendingClients[self])) - THEN /\ \E client \in pendingClients[self]: - /\ firstPending' = [firstPending EXCEPT ![self] = Head(pendingRequests[self][client])] - /\ Assert((((firstPending'[self]).op) = (GET_MSG)) \/ (((firstPending'[self]).op) = (PUT_MSG)), - "Failure of assertion at line 742, column 37.") - /\ timestamp' = [timestamp EXCEPT ![self] = (firstPending'[self]).timestamp] - /\ IF (timestamp'[self]) < (minClock[self]) - THEN /\ chooseMessage' = [chooseMessage EXCEPT ![self] = ((timestamp'[self]) < (lowestPending[self])) \/ (((timestamp'[self]) = (lowestPending[self])) /\ ((client) < (nextClient[self])))] - /\ IF chooseMessage'[self] - THEN /\ nextClient' = [nextClient EXCEPT ![self] = client] - /\ lowestPending' = [lowestPending EXCEPT ![self] = timestamp'[self]] - ELSE /\ TRUE - /\ UNCHANGED << nextClient, - lowestPending >> - ELSE /\ TRUE - /\ UNCHANGED << nextClient, - lowestPending, - chooseMessage >> - /\ pendingClients' = [pendingClients EXCEPT ![self] = (pendingClients[self]) \ ({client})] - /\ pc' = [pc EXCEPT ![self] = "findMinClient"] - ELSE /\ pc' = [pc EXCEPT ![self] = "addStableMessage"] - /\ UNCHANGED << firstPending, timestamp, - nextClient, lowestPending, - chooseMessage, - pendingClients >> - /\ UNCHANGED << replicasNetwork, clientsNetwork, lock, - cid, out, clocks, replicasRead, - replicasWrite, kvRead, clientsWrite, - clientsWrite0, kvWrite, kvWrite0, - clientsWrite1, clientIdRead, lockedRead, - clientIdRead0, clockRead, clientIdRead1, - lockedWrite, clientIdRead2, clockRead0, - clientIdRead3, clockWrite, keyRead, - clientIdRead4, clientIdRead5, - clockRead1, replicasWrite0, clientsRead, - clientsWrite2, outsideWrite, - lockedWrite0, clockWrite0, - replicasWrite1, clientsWrite3, - outsideWrite0, spinRead, clientIdRead6, - lockedRead0, clientIdRead7, clockRead2, - clientIdRead8, clockRead3, - clientIdRead9, clockWrite1, keyRead0, - valueRead, clientIdRead10, - clientIdRead11, clockRead4, - clientIdRead12, lockedWrite1, - replicasWrite2, replicasWrite3, - clientsRead0, clientsWrite4, - clientsWrite5, lockedWrite2, - outsideWrite1, spinRead0, - clientIdRead13, lockedRead1, - clientIdRead14, clientIdRead15, - clockWrite2, clockWrite3, - replicasWrite4, replicasWrite5, - clientIdRead16, clockRead5, - clientIdRead17, clockRead6, - clientIdRead18, clockWrite4, - clientIdRead19, clientIdRead20, - clockRead7, replicasWrite6, - replicasWrite7, spinRead1, kvLocal, - liveClients, pendingRequests, - stableMessages, i_, currentClocks, - minClock, continue_, clientsIter, msg_, - ok, key, val, spinLocal, continue_G, - getReq, getResp, spinLocal0, continue_P, - i, j_, putReq, putResp, msg_D, j_D, - spinLocal1, continue, j, msg >> - -addStableMessage(self) == /\ pc[self] = "addStableMessage" - /\ IF (lowestPending[self]) < (minClock[self]) - THEN /\ msg_' = [msg_ EXCEPT ![self] = Head(pendingRequests[self][nextClient[self]])] - /\ pendingRequests' = [pendingRequests EXCEPT ![self][nextClient[self]] = Tail(pendingRequests[self][nextClient[self]])] - /\ stableMessages' = [stableMessages EXCEPT ![self] = Append(stableMessages[self], msg_'[self])] - /\ pc' = [pc EXCEPT ![self] = "findStableRequestsLoop"] - /\ UNCHANGED continue_ - ELSE /\ continue_' = [continue_ EXCEPT ![self] = FALSE] - /\ pc' = [pc EXCEPT ![self] = "findStableRequestsLoop"] - /\ UNCHANGED << pendingRequests, - stableMessages, msg_ >> - /\ UNCHANGED << replicasNetwork, clientsNetwork, - lock, cid, out, clocks, replicasRead, - replicasWrite, kvRead, clientsWrite, - clientsWrite0, kvWrite, kvWrite0, - clientsWrite1, clientIdRead, - lockedRead, clientIdRead0, clockRead, - clientIdRead1, lockedWrite, - clientIdRead2, clockRead0, - clientIdRead3, clockWrite, keyRead, - clientIdRead4, clientIdRead5, - clockRead1, replicasWrite0, - clientsRead, clientsWrite2, - outsideWrite, lockedWrite0, - clockWrite0, replicasWrite1, - clientsWrite3, outsideWrite0, - spinRead, clientIdRead6, lockedRead0, - clientIdRead7, clockRead2, - clientIdRead8, clockRead3, - clientIdRead9, clockWrite1, keyRead0, - valueRead, clientIdRead10, - clientIdRead11, clockRead4, - clientIdRead12, lockedWrite1, - replicasWrite2, replicasWrite3, - clientsRead0, clientsWrite4, - clientsWrite5, lockedWrite2, - outsideWrite1, spinRead0, - clientIdRead13, lockedRead1, - clientIdRead14, clientIdRead15, - clockWrite2, clockWrite3, - replicasWrite4, replicasWrite5, - clientIdRead16, clockRead5, - clientIdRead17, clockRead6, - clientIdRead18, clockWrite4, - clientIdRead19, clientIdRead20, - clockRead7, replicasWrite6, - replicasWrite7, spinRead1, kvLocal, - liveClients, i_, firstPending, - timestamp, nextClient, lowestPending, - chooseMessage, currentClocks, - minClock, pendingClients, - clientsIter, ok, key, val, spinLocal, - continue_G, getReq, getResp, - spinLocal0, continue_P, i, j_, - putReq, putResp, msg_D, j_D, - spinLocal1, continue, j, msg >> - -respondPendingRequestsLoop(self) == /\ pc[self] = "respondPendingRequestsLoop" - /\ IF (i_[self]) <= (Len(stableMessages[self])) - THEN /\ msg_' = [msg_ EXCEPT ![self] = stableMessages[self][i_[self]]] - /\ i_' = [i_ EXCEPT ![self] = (i_[self]) + (1)] - /\ pc' = [pc EXCEPT ![self] = "respondStableGet"] - ELSE /\ pc' = [pc EXCEPT ![self] = "replicaLoop"] - /\ UNCHANGED << i_, msg_ >> - /\ UNCHANGED << replicasNetwork, - clientsNetwork, lock, cid, - out, clocks, replicasRead, - replicasWrite, kvRead, - clientsWrite, - clientsWrite0, kvWrite, - kvWrite0, clientsWrite1, - clientIdRead, lockedRead, - clientIdRead0, clockRead, - clientIdRead1, lockedWrite, - clientIdRead2, clockRead0, - clientIdRead3, clockWrite, - keyRead, clientIdRead4, - clientIdRead5, clockRead1, - replicasWrite0, - clientsRead, clientsWrite2, - outsideWrite, lockedWrite0, - clockWrite0, - replicasWrite1, - clientsWrite3, - outsideWrite0, spinRead, - clientIdRead6, lockedRead0, - clientIdRead7, clockRead2, - clientIdRead8, clockRead3, - clientIdRead9, clockWrite1, - keyRead0, valueRead, - clientIdRead10, - clientIdRead11, clockRead4, - clientIdRead12, - lockedWrite1, - replicasWrite2, - replicasWrite3, - clientsRead0, - clientsWrite4, - clientsWrite5, - lockedWrite2, - outsideWrite1, spinRead0, - clientIdRead13, - lockedRead1, - clientIdRead14, - clientIdRead15, - clockWrite2, clockWrite3, - replicasWrite4, - replicasWrite5, - clientIdRead16, clockRead5, - clientIdRead17, clockRead6, - clientIdRead18, - clockWrite4, - clientIdRead19, - clientIdRead20, clockRead7, - replicasWrite6, - replicasWrite7, spinRead1, - kvLocal, liveClients, - pendingRequests, - stableMessages, - firstPending, timestamp, - nextClient, lowestPending, - chooseMessage, - currentClocks, minClock, - continue_, pendingClients, - clientsIter, ok, key, val, - spinLocal, continue_G, - getReq, getResp, - spinLocal0, continue_P, i, - j_, putReq, putResp, msg_D, - j_D, spinLocal1, continue, - j, msg >> - -respondStableGet(self) == /\ pc[self] = "respondStableGet" - /\ IF ((msg_[self]).op) = (GET_MSG) - THEN /\ key' = [key EXCEPT ![self] = (msg_[self]).key] - /\ kvRead' = kvLocal[self][key'[self]] - /\ val' = [val EXCEPT ![self] = kvRead'] - /\ (Len(clientsNetwork[(msg_[self]).client])) < (BUFFER_SIZE) - /\ clientsWrite' = [clientsNetwork EXCEPT ![(msg_[self]).client] = Append(clientsNetwork[(msg_[self]).client], [type |-> GET_RESPONSE, result |-> val'[self]])] - /\ clientsWrite0' = clientsWrite' - /\ clientsNetwork' = clientsWrite0' - ELSE /\ clientsWrite0' = clientsNetwork - /\ clientsNetwork' = clientsWrite0' - /\ UNCHANGED << kvRead, clientsWrite, key, - val >> - /\ pc' = [pc EXCEPT ![self] = "respondStablePut"] - /\ UNCHANGED << replicasNetwork, lock, cid, out, - clocks, replicasRead, replicasWrite, - kvWrite, kvWrite0, clientsWrite1, - clientIdRead, lockedRead, - clientIdRead0, clockRead, - clientIdRead1, lockedWrite, - clientIdRead2, clockRead0, - clientIdRead3, clockWrite, keyRead, - clientIdRead4, clientIdRead5, - clockRead1, replicasWrite0, - clientsRead, clientsWrite2, - outsideWrite, lockedWrite0, - clockWrite0, replicasWrite1, - clientsWrite3, outsideWrite0, - spinRead, clientIdRead6, lockedRead0, - clientIdRead7, clockRead2, - clientIdRead8, clockRead3, - clientIdRead9, clockWrite1, keyRead0, - valueRead, clientIdRead10, - clientIdRead11, clockRead4, - clientIdRead12, lockedWrite1, - replicasWrite2, replicasWrite3, - clientsRead0, clientsWrite4, - clientsWrite5, lockedWrite2, - outsideWrite1, spinRead0, - clientIdRead13, lockedRead1, - clientIdRead14, clientIdRead15, - clockWrite2, clockWrite3, - replicasWrite4, replicasWrite5, - clientIdRead16, clockRead5, - clientIdRead17, clockRead6, - clientIdRead18, clockWrite4, - clientIdRead19, clientIdRead20, - clockRead7, replicasWrite6, - replicasWrite7, spinRead1, kvLocal, - liveClients, pendingRequests, - stableMessages, i_, firstPending, - timestamp, nextClient, lowestPending, - chooseMessage, currentClocks, - minClock, continue_, pendingClients, - clientsIter, msg_, ok, spinLocal, - continue_G, getReq, getResp, - spinLocal0, continue_P, i, j_, - putReq, putResp, msg_D, j_D, - spinLocal1, continue, j, msg >> - -respondStablePut(self) == /\ pc[self] = "respondStablePut" - /\ IF ((msg_[self]).op) = (PUT_MSG) - THEN /\ key' = [key EXCEPT ![self] = (msg_[self]).key] - /\ val' = [val EXCEPT ![self] = (msg_[self]).value] - /\ kvWrite' = [kvLocal[self] EXCEPT ![key'[self]] = val'[self]] - /\ (Len(clientsNetwork[(msg_[self]).client])) < (BUFFER_SIZE) - /\ clientsWrite' = [clientsNetwork EXCEPT ![(msg_[self]).client] = Append(clientsNetwork[(msg_[self]).client], [type |-> PUT_RESPONSE, result |-> ok[self]])] - /\ kvWrite0' = kvWrite' - /\ clientsWrite1' = clientsWrite' - /\ clientsNetwork' = clientsWrite1' - /\ kvLocal' = [kvLocal EXCEPT ![self] = kvWrite0'] - /\ pc' = [pc EXCEPT ![self] = "respondPendingRequestsLoop"] - ELSE /\ kvWrite0' = kvLocal[self] - /\ clientsWrite1' = clientsNetwork - /\ clientsNetwork' = clientsWrite1' - /\ kvLocal' = [kvLocal EXCEPT ![self] = kvWrite0'] - /\ pc' = [pc EXCEPT ![self] = "respondPendingRequestsLoop"] - /\ UNCHANGED << clientsWrite, kvWrite, - key, val >> - /\ UNCHANGED << replicasNetwork, lock, cid, out, - clocks, replicasRead, replicasWrite, - kvRead, clientsWrite0, clientIdRead, - lockedRead, clientIdRead0, clockRead, - clientIdRead1, lockedWrite, - clientIdRead2, clockRead0, - clientIdRead3, clockWrite, keyRead, - clientIdRead4, clientIdRead5, - clockRead1, replicasWrite0, - clientsRead, clientsWrite2, - outsideWrite, lockedWrite0, - clockWrite0, replicasWrite1, - clientsWrite3, outsideWrite0, - spinRead, clientIdRead6, lockedRead0, - clientIdRead7, clockRead2, - clientIdRead8, clockRead3, - clientIdRead9, clockWrite1, keyRead0, - valueRead, clientIdRead10, - clientIdRead11, clockRead4, - clientIdRead12, lockedWrite1, - replicasWrite2, replicasWrite3, - clientsRead0, clientsWrite4, - clientsWrite5, lockedWrite2, - outsideWrite1, spinRead0, - clientIdRead13, lockedRead1, - clientIdRead14, clientIdRead15, - clockWrite2, clockWrite3, - replicasWrite4, replicasWrite5, - clientIdRead16, clockRead5, - clientIdRead17, clockRead6, - clientIdRead18, clockWrite4, - clientIdRead19, clientIdRead20, - clockRead7, replicasWrite6, - replicasWrite7, spinRead1, - liveClients, pendingRequests, - stableMessages, i_, firstPending, - timestamp, nextClient, lowestPending, - chooseMessage, currentClocks, - minClock, continue_, pendingClients, - clientsIter, msg_, ok, spinLocal, - continue_G, getReq, getResp, - spinLocal0, continue_P, i, j_, - putReq, putResp, msg_D, j_D, - spinLocal1, continue, j, msg >> - -Replica(self) == replicaLoop(self) \/ receiveClientRequest(self) - \/ clientDisconnected(self) \/ replicaGetRequest(self) - \/ replicaPutRequest(self) \/ replicaNullRequest(self) - \/ findStableRequestsLoop(self) \/ findMinClock(self) - \/ findMinClient(self) \/ addStableMessage(self) - \/ respondPendingRequestsLoop(self) - \/ respondStableGet(self) \/ respondStablePut(self) - -getLoop(self) == /\ pc[self] = "getLoop" - /\ IF continue_G[self] - THEN /\ pc' = [pc EXCEPT ![self] = "getRequest"] - ELSE /\ pc' = [pc EXCEPT ![self] = "Done"] - /\ UNCHANGED << replicasNetwork, clientsNetwork, lock, cid, - out, clocks, replicasRead, replicasWrite, - kvRead, clientsWrite, clientsWrite0, kvWrite, - kvWrite0, clientsWrite1, clientIdRead, - lockedRead, clientIdRead0, clockRead, - clientIdRead1, lockedWrite, clientIdRead2, - clockRead0, clientIdRead3, clockWrite, - keyRead, clientIdRead4, clientIdRead5, - clockRead1, replicasWrite0, clientsRead, - clientsWrite2, outsideWrite, lockedWrite0, - clockWrite0, replicasWrite1, clientsWrite3, - outsideWrite0, spinRead, clientIdRead6, - lockedRead0, clientIdRead7, clockRead2, - clientIdRead8, clockRead3, clientIdRead9, - clockWrite1, keyRead0, valueRead, - clientIdRead10, clientIdRead11, clockRead4, - clientIdRead12, lockedWrite1, replicasWrite2, - replicasWrite3, clientsRead0, clientsWrite4, - clientsWrite5, lockedWrite2, outsideWrite1, - spinRead0, clientIdRead13, lockedRead1, - clientIdRead14, clientIdRead15, clockWrite2, - clockWrite3, replicasWrite4, replicasWrite5, - clientIdRead16, clockRead5, clientIdRead17, - clockRead6, clientIdRead18, clockWrite4, - clientIdRead19, clientIdRead20, clockRead7, - replicasWrite6, replicasWrite7, spinRead1, - kvLocal, liveClients, pendingRequests, - stableMessages, i_, firstPending, timestamp, - nextClient, lowestPending, chooseMessage, - currentClocks, minClock, continue_, - pendingClients, clientsIter, msg_, ok, key, - val, spinLocal, continue_G, getReq, getResp, - spinLocal0, continue_P, i, j_, putReq, - putResp, msg_D, j_D, spinLocal1, continue, j, - msg >> - -getRequest(self) == /\ pc[self] = "getRequest" - /\ clientIdRead' = (self) - ((NUM_CLIENTS) * (GET_ORDER)) - /\ ~(lock[clientIdRead']) - /\ lockedRead' = FALSE - /\ IF ~(lockedRead') - THEN /\ clientIdRead0' = (self) - ((NUM_CLIENTS) * (GET_ORDER)) - /\ clockRead' = clocks[clientIdRead0'] - /\ IF (clockRead') = (-(1)) - THEN /\ continue_G' = [continue_G EXCEPT ![self] = FALSE] - /\ lockedWrite0' = lock - /\ clockWrite0' = clocks - /\ replicasWrite1' = replicasNetwork - /\ clientsWrite3' = clientsNetwork - /\ outsideWrite0' = out - /\ replicasNetwork' = replicasWrite1' - /\ clientsNetwork' = clientsWrite3' - /\ lock' = lockedWrite0' - /\ clocks' = clockWrite0' - /\ out' = outsideWrite0' - /\ pc' = [pc EXCEPT ![self] = "getCheckSpin"] - /\ UNCHANGED << clientIdRead1, - lockedWrite, - clientIdRead2, - clockRead0, - clientIdRead3, - clockWrite, keyRead, - clientIdRead4, - clientIdRead5, - clockRead1, - replicasWrite0, - getReq >> - ELSE /\ clientIdRead1' = (self) - ((NUM_CLIENTS) * (GET_ORDER)) - /\ lockedWrite' = [lock EXCEPT ![clientIdRead1'] = TRUE] - /\ clientIdRead2' = (self) - ((NUM_CLIENTS) * (GET_ORDER)) - /\ clockRead0' = clocks[clientIdRead2'] - /\ clientIdRead3' = (self) - ((NUM_CLIENTS) * (GET_ORDER)) - /\ clockWrite' = [clocks EXCEPT ![clientIdRead3'] = (clockRead0') + (1)] - /\ keyRead' = GET_KEY - /\ clientIdRead4' = (self) - ((NUM_CLIENTS) * (GET_ORDER)) - /\ clientIdRead5' = (self) - ((NUM_CLIENTS) * (GET_ORDER)) - /\ clockRead1' = clockWrite'[clientIdRead5'] - /\ getReq' = [getReq EXCEPT ![self] = [op |-> GET_MSG, key |-> keyRead', client |-> clientIdRead4', timestamp |-> clockRead1']] - /\ \E dst \in ReplicaSet: - /\ (Len(replicasNetwork[dst])) < (BUFFER_SIZE) - /\ replicasWrite0' = [replicasNetwork EXCEPT ![dst] = Append(replicasNetwork[dst], getReq'[self])] - /\ replicasNetwork' = replicasWrite0' - /\ lock' = lockedWrite' - /\ clocks' = clockWrite' - /\ pc' = [pc EXCEPT ![self] = "getReply"] - /\ UNCHANGED << clientsNetwork, out, - lockedWrite0, - clockWrite0, - replicasWrite1, - clientsWrite3, - outsideWrite0, - continue_G >> - ELSE /\ replicasNetwork' = replicasWrite1 - /\ clientsNetwork' = clientsWrite3 - /\ lock' = lockedWrite0 - /\ clocks' = clockWrite0 - /\ out' = outsideWrite0 - /\ pc' = [pc EXCEPT ![self] = "getCheckSpin"] - /\ UNCHANGED << clientIdRead0, clockRead, - clientIdRead1, lockedWrite, - clientIdRead2, clockRead0, - clientIdRead3, clockWrite, - keyRead, clientIdRead4, - clientIdRead5, clockRead1, - replicasWrite0, lockedWrite0, - clockWrite0, replicasWrite1, - clientsWrite3, outsideWrite0, - continue_G, getReq >> - /\ UNCHANGED << cid, replicasRead, replicasWrite, kvRead, - clientsWrite, clientsWrite0, kvWrite, - kvWrite0, clientsWrite1, clientsRead, - clientsWrite2, outsideWrite, spinRead, - clientIdRead6, lockedRead0, clientIdRead7, - clockRead2, clientIdRead8, clockRead3, - clientIdRead9, clockWrite1, keyRead0, - valueRead, clientIdRead10, clientIdRead11, - clockRead4, clientIdRead12, lockedWrite1, - replicasWrite2, replicasWrite3, - clientsRead0, clientsWrite4, clientsWrite5, - lockedWrite2, outsideWrite1, spinRead0, - clientIdRead13, lockedRead1, - clientIdRead14, clientIdRead15, - clockWrite2, clockWrite3, replicasWrite4, - replicasWrite5, clientIdRead16, clockRead5, - clientIdRead17, clockRead6, clientIdRead18, - clockWrite4, clientIdRead19, - clientIdRead20, clockRead7, replicasWrite6, - replicasWrite7, spinRead1, kvLocal, - liveClients, pendingRequests, - stableMessages, i_, firstPending, - timestamp, nextClient, lowestPending, - chooseMessage, currentClocks, minClock, - continue_, pendingClients, clientsIter, - msg_, ok, key, val, spinLocal, getResp, - spinLocal0, continue_P, i, j_, putReq, - putResp, msg_D, j_D, spinLocal1, continue, - j, msg >> - -getReply(self) == /\ pc[self] = "getReply" - /\ clientIdRead' = (self) - ((NUM_CLIENTS) * (GET_ORDER)) - /\ (Len(clientsNetwork[clientIdRead'])) > (0) - /\ LET msg1 == Head(clientsNetwork[clientIdRead']) IN - /\ clientsWrite2' = [clientsNetwork EXCEPT ![clientIdRead'] = Tail(clientsNetwork[clientIdRead'])] - /\ clientsRead' = msg1 - /\ getResp' = [getResp EXCEPT ![self] = clientsRead'] - /\ Assert(((getResp'[self]).type) = (GET_RESPONSE), - "Failure of assertion at line 867, column 33.") - /\ clientIdRead0' = (self) - ((NUM_CLIENTS) * (GET_ORDER)) - /\ lockedWrite' = [lock EXCEPT ![clientIdRead0'] = FALSE] - /\ outsideWrite' = (getResp'[self]).result - /\ clientsNetwork' = clientsWrite2' - /\ lock' = lockedWrite' - /\ out' = outsideWrite' - /\ pc' = [pc EXCEPT ![self] = "getCheckSpin"] - /\ UNCHANGED << replicasNetwork, cid, clocks, replicasRead, - replicasWrite, kvRead, clientsWrite, - clientsWrite0, kvWrite, kvWrite0, - clientsWrite1, lockedRead, clockRead, - clientIdRead1, clientIdRead2, clockRead0, - clientIdRead3, clockWrite, keyRead, - clientIdRead4, clientIdRead5, clockRead1, - replicasWrite0, lockedWrite0, clockWrite0, - replicasWrite1, clientsWrite3, outsideWrite0, - spinRead, clientIdRead6, lockedRead0, - clientIdRead7, clockRead2, clientIdRead8, - clockRead3, clientIdRead9, clockWrite1, - keyRead0, valueRead, clientIdRead10, - clientIdRead11, clockRead4, clientIdRead12, - lockedWrite1, replicasWrite2, replicasWrite3, - clientsRead0, clientsWrite4, clientsWrite5, - lockedWrite2, outsideWrite1, spinRead0, - clientIdRead13, lockedRead1, clientIdRead14, - clientIdRead15, clockWrite2, clockWrite3, - replicasWrite4, replicasWrite5, - clientIdRead16, clockRead5, clientIdRead17, - clockRead6, clientIdRead18, clockWrite4, - clientIdRead19, clientIdRead20, clockRead7, - replicasWrite6, replicasWrite7, spinRead1, - kvLocal, liveClients, pendingRequests, - stableMessages, i_, firstPending, timestamp, - nextClient, lowestPending, chooseMessage, - currentClocks, minClock, continue_, - pendingClients, clientsIter, msg_, ok, key, - val, spinLocal, continue_G, getReq, - spinLocal0, continue_P, i, j_, putReq, - putResp, msg_D, j_D, spinLocal1, continue, j, - msg >> - -getCheckSpin(self) == /\ pc[self] = "getCheckSpin" - /\ spinRead' = spinLocal[self] - /\ IF ~(spinRead') - THEN /\ continue_G' = [continue_G EXCEPT ![self] = FALSE] - /\ pc' = [pc EXCEPT ![self] = "getLoop"] - ELSE /\ pc' = [pc EXCEPT ![self] = "getLoop"] - /\ UNCHANGED continue_G - /\ UNCHANGED << replicasNetwork, clientsNetwork, lock, - cid, out, clocks, replicasRead, - replicasWrite, kvRead, clientsWrite, - clientsWrite0, kvWrite, kvWrite0, - clientsWrite1, clientIdRead, lockedRead, - clientIdRead0, clockRead, clientIdRead1, - lockedWrite, clientIdRead2, clockRead0, - clientIdRead3, clockWrite, keyRead, - clientIdRead4, clientIdRead5, clockRead1, - replicasWrite0, clientsRead, - clientsWrite2, outsideWrite, - lockedWrite0, clockWrite0, - replicasWrite1, clientsWrite3, - outsideWrite0, clientIdRead6, - lockedRead0, clientIdRead7, clockRead2, - clientIdRead8, clockRead3, clientIdRead9, - clockWrite1, keyRead0, valueRead, - clientIdRead10, clientIdRead11, - clockRead4, clientIdRead12, lockedWrite1, - replicasWrite2, replicasWrite3, - clientsRead0, clientsWrite4, - clientsWrite5, lockedWrite2, - outsideWrite1, spinRead0, clientIdRead13, - lockedRead1, clientIdRead14, - clientIdRead15, clockWrite2, clockWrite3, - replicasWrite4, replicasWrite5, - clientIdRead16, clockRead5, - clientIdRead17, clockRead6, - clientIdRead18, clockWrite4, - clientIdRead19, clientIdRead20, - clockRead7, replicasWrite6, - replicasWrite7, spinRead1, kvLocal, - liveClients, pendingRequests, - stableMessages, i_, firstPending, - timestamp, nextClient, lowestPending, - chooseMessage, currentClocks, minClock, - continue_, pendingClients, clientsIter, - msg_, ok, key, val, spinLocal, getReq, - getResp, spinLocal0, continue_P, i, j_, - putReq, putResp, msg_D, j_D, spinLocal1, - continue, j, msg >> - -GetClient(self) == getLoop(self) \/ getRequest(self) \/ getReply(self) - \/ getCheckSpin(self) - -putLoop(self) == /\ pc[self] = "putLoop" - /\ IF continue_P[self] - THEN /\ pc' = [pc EXCEPT ![self] = "putRequest"] - ELSE /\ pc' = [pc EXCEPT ![self] = "Done"] - /\ UNCHANGED << replicasNetwork, clientsNetwork, lock, cid, - out, clocks, replicasRead, replicasWrite, - kvRead, clientsWrite, clientsWrite0, kvWrite, - kvWrite0, clientsWrite1, clientIdRead, - lockedRead, clientIdRead0, clockRead, - clientIdRead1, lockedWrite, clientIdRead2, - clockRead0, clientIdRead3, clockWrite, - keyRead, clientIdRead4, clientIdRead5, - clockRead1, replicasWrite0, clientsRead, - clientsWrite2, outsideWrite, lockedWrite0, - clockWrite0, replicasWrite1, clientsWrite3, - outsideWrite0, spinRead, clientIdRead6, - lockedRead0, clientIdRead7, clockRead2, - clientIdRead8, clockRead3, clientIdRead9, - clockWrite1, keyRead0, valueRead, - clientIdRead10, clientIdRead11, clockRead4, - clientIdRead12, lockedWrite1, replicasWrite2, - replicasWrite3, clientsRead0, clientsWrite4, - clientsWrite5, lockedWrite2, outsideWrite1, - spinRead0, clientIdRead13, lockedRead1, - clientIdRead14, clientIdRead15, clockWrite2, - clockWrite3, replicasWrite4, replicasWrite5, - clientIdRead16, clockRead5, clientIdRead17, - clockRead6, clientIdRead18, clockWrite4, - clientIdRead19, clientIdRead20, clockRead7, - replicasWrite6, replicasWrite7, spinRead1, - kvLocal, liveClients, pendingRequests, - stableMessages, i_, firstPending, timestamp, - nextClient, lowestPending, chooseMessage, - currentClocks, minClock, continue_, - pendingClients, clientsIter, msg_, ok, key, - val, spinLocal, continue_G, getReq, getResp, - spinLocal0, continue_P, i, j_, putReq, - putResp, msg_D, j_D, spinLocal1, continue, j, - msg >> - -putRequest(self) == /\ pc[self] = "putRequest" - /\ clientIdRead6' = (self) - ((NUM_CLIENTS) * (PUT_ORDER)) - /\ ~(lock[clientIdRead6']) - /\ lockedRead0' = FALSE - /\ IF ~(lockedRead0') - THEN /\ clientIdRead7' = (self) - ((NUM_CLIENTS) * (PUT_ORDER)) - /\ clockRead2' = clocks[clientIdRead7'] - /\ IF (clockRead2') = (-(1)) - THEN /\ continue_P' = [continue_P EXCEPT ![self] = FALSE] - /\ pc' = [pc EXCEPT ![self] = "putCheckSpin"] - /\ UNCHANGED << lock, clocks, - clientIdRead8, - clockRead3, - clientIdRead9, - clockWrite1, - keyRead0, valueRead, - clientIdRead10, - clientIdRead11, - clockRead4, - clientIdRead12, - lockedWrite1, i, j_, - putReq >> - ELSE /\ clientIdRead8' = (self) - ((NUM_CLIENTS) * (PUT_ORDER)) - /\ clockRead3' = clocks[clientIdRead8'] - /\ clientIdRead9' = (self) - ((NUM_CLIENTS) * (PUT_ORDER)) - /\ clockWrite1' = [clocks EXCEPT ![clientIdRead9'] = (clockRead3') + (1)] - /\ keyRead0' = PUT_KEY - /\ valueRead' = PUT_VALUE - /\ clientIdRead10' = (self) - ((NUM_CLIENTS) * (PUT_ORDER)) - /\ clientIdRead11' = (self) - ((NUM_CLIENTS) * (PUT_ORDER)) - /\ clockRead4' = clockWrite1'[clientIdRead11'] - /\ putReq' = [putReq EXCEPT ![self] = [op |-> PUT_MSG, key |-> keyRead0', value |-> valueRead', client |-> clientIdRead10', timestamp |-> clockRead4']] - /\ clientIdRead12' = (self) - ((NUM_CLIENTS) * (PUT_ORDER)) - /\ lockedWrite1' = [lock EXCEPT ![clientIdRead12'] = TRUE] - /\ i' = [i EXCEPT ![self] = 0] - /\ j_' = [j_ EXCEPT ![self] = 0] - /\ lock' = lockedWrite1' - /\ clocks' = clockWrite1' - /\ pc' = [pc EXCEPT ![self] = "putBroadcast"] - /\ UNCHANGED continue_P - ELSE /\ pc' = [pc EXCEPT ![self] = "putCheckSpin"] - /\ UNCHANGED << lock, clocks, clientIdRead7, - clockRead2, clientIdRead8, - clockRead3, clientIdRead9, - clockWrite1, keyRead0, - valueRead, clientIdRead10, - clientIdRead11, clockRead4, - clientIdRead12, lockedWrite1, - continue_P, i, j_, putReq >> - /\ UNCHANGED << replicasNetwork, clientsNetwork, cid, out, - replicasRead, replicasWrite, kvRead, - clientsWrite, clientsWrite0, kvWrite, - kvWrite0, clientsWrite1, clientIdRead, - lockedRead, clientIdRead0, clockRead, - clientIdRead1, lockedWrite, clientIdRead2, - clockRead0, clientIdRead3, clockWrite, - keyRead, clientIdRead4, clientIdRead5, - clockRead1, replicasWrite0, clientsRead, - clientsWrite2, outsideWrite, lockedWrite0, - clockWrite0, replicasWrite1, clientsWrite3, - outsideWrite0, spinRead, replicasWrite2, - replicasWrite3, clientsRead0, - clientsWrite4, clientsWrite5, lockedWrite2, - outsideWrite1, spinRead0, clientIdRead13, - lockedRead1, clientIdRead14, - clientIdRead15, clockWrite2, clockWrite3, - replicasWrite4, replicasWrite5, - clientIdRead16, clockRead5, clientIdRead17, - clockRead6, clientIdRead18, clockWrite4, - clientIdRead19, clientIdRead20, clockRead7, - replicasWrite6, replicasWrite7, spinRead1, - kvLocal, liveClients, pendingRequests, - stableMessages, i_, firstPending, - timestamp, nextClient, lowestPending, - chooseMessage, currentClocks, minClock, - continue_, pendingClients, clientsIter, - msg_, ok, key, val, spinLocal, continue_G, - getReq, getResp, spinLocal0, putResp, - msg_D, j_D, spinLocal1, continue, j, msg >> - -putBroadcast(self) == /\ pc[self] = "putBroadcast" - /\ IF (j_[self]) <= ((NUM_REPLICAS) - (1)) - THEN /\ (Len(replicasNetwork[j_[self]])) < (BUFFER_SIZE) - /\ replicasWrite2' = [replicasNetwork EXCEPT ![j_[self]] = Append(replicasNetwork[j_[self]], putReq[self])] - /\ j_' = [j_ EXCEPT ![self] = (j_[self]) + (1)] - /\ replicasWrite3' = replicasWrite2' - /\ replicasNetwork' = replicasWrite3' - /\ pc' = [pc EXCEPT ![self] = "putBroadcast"] - ELSE /\ replicasWrite3' = replicasNetwork - /\ replicasNetwork' = replicasWrite3' - /\ pc' = [pc EXCEPT ![self] = "putResponse"] - /\ UNCHANGED << replicasWrite2, j_ >> - /\ UNCHANGED << clientsNetwork, lock, cid, out, clocks, - replicasRead, replicasWrite, kvRead, - clientsWrite, clientsWrite0, kvWrite, - kvWrite0, clientsWrite1, clientIdRead, - lockedRead, clientIdRead0, clockRead, - clientIdRead1, lockedWrite, - clientIdRead2, clockRead0, clientIdRead3, - clockWrite, keyRead, clientIdRead4, - clientIdRead5, clockRead1, - replicasWrite0, clientsRead, - clientsWrite2, outsideWrite, - lockedWrite0, clockWrite0, - replicasWrite1, clientsWrite3, - outsideWrite0, spinRead, clientIdRead6, - lockedRead0, clientIdRead7, clockRead2, - clientIdRead8, clockRead3, clientIdRead9, - clockWrite1, keyRead0, valueRead, - clientIdRead10, clientIdRead11, - clockRead4, clientIdRead12, lockedWrite1, - clientsRead0, clientsWrite4, - clientsWrite5, lockedWrite2, - outsideWrite1, spinRead0, clientIdRead13, - lockedRead1, clientIdRead14, - clientIdRead15, clockWrite2, clockWrite3, - replicasWrite4, replicasWrite5, - clientIdRead16, clockRead5, - clientIdRead17, clockRead6, - clientIdRead18, clockWrite4, - clientIdRead19, clientIdRead20, - clockRead7, replicasWrite6, - replicasWrite7, spinRead1, kvLocal, - liveClients, pendingRequests, - stableMessages, i_, firstPending, - timestamp, nextClient, lowestPending, - chooseMessage, currentClocks, minClock, - continue_, pendingClients, clientsIter, - msg_, ok, key, val, spinLocal, - continue_G, getReq, getResp, spinLocal0, - continue_P, i, putReq, putResp, msg_D, - j_D, spinLocal1, continue, j, msg >> - -putResponse(self) == /\ pc[self] = "putResponse" - /\ IF (i[self]) < (Cardinality(ReplicaSet)) - THEN /\ clientIdRead6' = (self) - ((NUM_CLIENTS) * (PUT_ORDER)) - /\ (Len(clientsNetwork[clientIdRead6'])) > (0) - /\ LET msg2 == Head(clientsNetwork[clientIdRead6']) IN - /\ clientsWrite4' = [clientsNetwork EXCEPT ![clientIdRead6'] = Tail(clientsNetwork[clientIdRead6'])] - /\ clientsRead0' = msg2 - /\ putResp' = [putResp EXCEPT ![self] = clientsRead0'] - /\ Assert(((putResp'[self]).type) = (PUT_RESPONSE), - "Failure of assertion at line 949, column 37.") - /\ i' = [i EXCEPT ![self] = (i[self]) + (1)] - /\ clientsWrite5' = clientsWrite4' - /\ lockedWrite2' = lock - /\ clientsNetwork' = clientsWrite5' - /\ lock' = lockedWrite2' - /\ pc' = [pc EXCEPT ![self] = "putResponse"] - /\ UNCHANGED << clientIdRead7, lockedWrite1 >> - ELSE /\ clientIdRead7' = (self) - ((NUM_CLIENTS) * (PUT_ORDER)) - /\ lockedWrite1' = [lock EXCEPT ![clientIdRead7'] = FALSE] - /\ clientsWrite5' = clientsNetwork - /\ lockedWrite2' = lockedWrite1' - /\ clientsNetwork' = clientsWrite5' - /\ lock' = lockedWrite2' - /\ pc' = [pc EXCEPT ![self] = "putComplete"] - /\ UNCHANGED << clientIdRead6, clientsRead0, - clientsWrite4, i, putResp >> - /\ UNCHANGED << replicasNetwork, cid, out, clocks, - replicasRead, replicasWrite, kvRead, - clientsWrite, clientsWrite0, kvWrite, - kvWrite0, clientsWrite1, clientIdRead, - lockedRead, clientIdRead0, clockRead, - clientIdRead1, lockedWrite, clientIdRead2, - clockRead0, clientIdRead3, clockWrite, - keyRead, clientIdRead4, clientIdRead5, - clockRead1, replicasWrite0, clientsRead, - clientsWrite2, outsideWrite, lockedWrite0, - clockWrite0, replicasWrite1, - clientsWrite3, outsideWrite0, spinRead, - lockedRead0, clockRead2, clientIdRead8, - clockRead3, clientIdRead9, clockWrite1, - keyRead0, valueRead, clientIdRead10, - clientIdRead11, clockRead4, - clientIdRead12, replicasWrite2, - replicasWrite3, outsideWrite1, spinRead0, - clientIdRead13, lockedRead1, - clientIdRead14, clientIdRead15, - clockWrite2, clockWrite3, replicasWrite4, - replicasWrite5, clientIdRead16, - clockRead5, clientIdRead17, clockRead6, - clientIdRead18, clockWrite4, - clientIdRead19, clientIdRead20, - clockRead7, replicasWrite6, - replicasWrite7, spinRead1, kvLocal, - liveClients, pendingRequests, - stableMessages, i_, firstPending, - timestamp, nextClient, lowestPending, - chooseMessage, currentClocks, minClock, - continue_, pendingClients, clientsIter, - msg_, ok, key, val, spinLocal, continue_G, - getReq, getResp, spinLocal0, continue_P, - j_, putReq, msg_D, j_D, spinLocal1, - continue, j, msg >> - -putComplete(self) == /\ pc[self] = "putComplete" - /\ outsideWrite1' = PUT_RESPONSE - /\ out' = outsideWrite1' - /\ pc' = [pc EXCEPT ![self] = "putCheckSpin"] - /\ UNCHANGED << replicasNetwork, clientsNetwork, lock, - cid, clocks, replicasRead, replicasWrite, - kvRead, clientsWrite, clientsWrite0, - kvWrite, kvWrite0, clientsWrite1, - clientIdRead, lockedRead, clientIdRead0, - clockRead, clientIdRead1, lockedWrite, - clientIdRead2, clockRead0, clientIdRead3, - clockWrite, keyRead, clientIdRead4, - clientIdRead5, clockRead1, replicasWrite0, - clientsRead, clientsWrite2, outsideWrite, - lockedWrite0, clockWrite0, replicasWrite1, - clientsWrite3, outsideWrite0, spinRead, - clientIdRead6, lockedRead0, clientIdRead7, - clockRead2, clientIdRead8, clockRead3, - clientIdRead9, clockWrite1, keyRead0, - valueRead, clientIdRead10, clientIdRead11, - clockRead4, clientIdRead12, lockedWrite1, - replicasWrite2, replicasWrite3, - clientsRead0, clientsWrite4, - clientsWrite5, lockedWrite2, spinRead0, - clientIdRead13, lockedRead1, - clientIdRead14, clientIdRead15, - clockWrite2, clockWrite3, replicasWrite4, - replicasWrite5, clientIdRead16, - clockRead5, clientIdRead17, clockRead6, - clientIdRead18, clockWrite4, - clientIdRead19, clientIdRead20, - clockRead7, replicasWrite6, - replicasWrite7, spinRead1, kvLocal, - liveClients, pendingRequests, - stableMessages, i_, firstPending, - timestamp, nextClient, lowestPending, - chooseMessage, currentClocks, minClock, - continue_, pendingClients, clientsIter, - msg_, ok, key, val, spinLocal, continue_G, - getReq, getResp, spinLocal0, continue_P, - i, j_, putReq, putResp, msg_D, j_D, - spinLocal1, continue, j, msg >> - -putCheckSpin(self) == /\ pc[self] = "putCheckSpin" - /\ spinRead0' = spinLocal0[self] - /\ IF ~(spinRead0') - THEN /\ continue_P' = [continue_P EXCEPT ![self] = FALSE] - /\ pc' = [pc EXCEPT ![self] = "putLoop"] - ELSE /\ pc' = [pc EXCEPT ![self] = "putLoop"] - /\ UNCHANGED continue_P - /\ UNCHANGED << replicasNetwork, clientsNetwork, lock, - cid, out, clocks, replicasRead, - replicasWrite, kvRead, clientsWrite, - clientsWrite0, kvWrite, kvWrite0, - clientsWrite1, clientIdRead, lockedRead, - clientIdRead0, clockRead, clientIdRead1, - lockedWrite, clientIdRead2, clockRead0, - clientIdRead3, clockWrite, keyRead, - clientIdRead4, clientIdRead5, clockRead1, - replicasWrite0, clientsRead, - clientsWrite2, outsideWrite, - lockedWrite0, clockWrite0, - replicasWrite1, clientsWrite3, - outsideWrite0, spinRead, clientIdRead6, - lockedRead0, clientIdRead7, clockRead2, - clientIdRead8, clockRead3, clientIdRead9, - clockWrite1, keyRead0, valueRead, - clientIdRead10, clientIdRead11, - clockRead4, clientIdRead12, lockedWrite1, - replicasWrite2, replicasWrite3, - clientsRead0, clientsWrite4, - clientsWrite5, lockedWrite2, - outsideWrite1, clientIdRead13, - lockedRead1, clientIdRead14, - clientIdRead15, clockWrite2, clockWrite3, - replicasWrite4, replicasWrite5, - clientIdRead16, clockRead5, - clientIdRead17, clockRead6, - clientIdRead18, clockWrite4, - clientIdRead19, clientIdRead20, - clockRead7, replicasWrite6, - replicasWrite7, spinRead1, kvLocal, - liveClients, pendingRequests, - stableMessages, i_, firstPending, - timestamp, nextClient, lowestPending, - chooseMessage, currentClocks, minClock, - continue_, pendingClients, clientsIter, - msg_, ok, key, val, spinLocal, - continue_G, getReq, getResp, spinLocal0, - i, j_, putReq, putResp, msg_D, j_D, - spinLocal1, continue, j, msg >> - -PutClient(self) == putLoop(self) \/ putRequest(self) \/ putBroadcast(self) - \/ putResponse(self) \/ putComplete(self) - \/ putCheckSpin(self) - -sendDisconnectRequest(self) == /\ pc[self] = "sendDisconnectRequest" - /\ clientIdRead13' = (self) - ((NUM_CLIENTS) * (DISCONNECT_ORDER)) - /\ ~(lock[clientIdRead13']) - /\ lockedRead1' = FALSE - /\ IF ~(lockedRead1') - THEN /\ clientIdRead14' = (self) - ((NUM_CLIENTS) * (DISCONNECT_ORDER)) - /\ msg_D' = [msg_D EXCEPT ![self] = [op |-> DISCONNECT_MSG, client |-> clientIdRead14']] - /\ clientIdRead15' = (self) - ((NUM_CLIENTS) * (DISCONNECT_ORDER)) - /\ clockWrite2' = [clocks EXCEPT ![clientIdRead15'] = -(1)] - /\ j_D' = [j_D EXCEPT ![self] = 0] - /\ clockWrite3' = clockWrite2' - /\ clocks' = clockWrite3' - ELSE /\ clockWrite3' = clocks - /\ clocks' = clockWrite3' - /\ UNCHANGED << clientIdRead14, - clientIdRead15, - clockWrite2, msg_D, - j_D >> - /\ pc' = [pc EXCEPT ![self] = "disconnectBroadcast"] - /\ UNCHANGED << replicasNetwork, clientsNetwork, - lock, cid, out, replicasRead, - replicasWrite, kvRead, - clientsWrite, clientsWrite0, - kvWrite, kvWrite0, - clientsWrite1, clientIdRead, - lockedRead, clientIdRead0, - clockRead, clientIdRead1, - lockedWrite, clientIdRead2, - clockRead0, clientIdRead3, - clockWrite, keyRead, - clientIdRead4, clientIdRead5, - clockRead1, replicasWrite0, - clientsRead, clientsWrite2, - outsideWrite, lockedWrite0, - clockWrite0, replicasWrite1, - clientsWrite3, outsideWrite0, - spinRead, clientIdRead6, - lockedRead0, clientIdRead7, - clockRead2, clientIdRead8, - clockRead3, clientIdRead9, - clockWrite1, keyRead0, - valueRead, clientIdRead10, - clientIdRead11, clockRead4, - clientIdRead12, lockedWrite1, - replicasWrite2, replicasWrite3, - clientsRead0, clientsWrite4, - clientsWrite5, lockedWrite2, - outsideWrite1, spinRead0, - replicasWrite4, replicasWrite5, - clientIdRead16, clockRead5, - clientIdRead17, clockRead6, - clientIdRead18, clockWrite4, - clientIdRead19, clientIdRead20, - clockRead7, replicasWrite6, - replicasWrite7, spinRead1, - kvLocal, liveClients, - pendingRequests, stableMessages, - i_, firstPending, timestamp, - nextClient, lowestPending, - chooseMessage, currentClocks, - minClock, continue_, - pendingClients, clientsIter, - msg_, ok, key, val, spinLocal, - continue_G, getReq, getResp, - spinLocal0, continue_P, i, j_, - putReq, putResp, spinLocal1, - continue, j, msg >> - -disconnectBroadcast(self) == /\ pc[self] = "disconnectBroadcast" - /\ IF (j_D[self]) <= ((NUM_REPLICAS) - (1)) - THEN /\ (Len(replicasNetwork[j_D[self]])) < (BUFFER_SIZE) - /\ replicasWrite4' = [replicasNetwork EXCEPT ![j_D[self]] = Append(replicasNetwork[j_D[self]], msg_D[self])] - /\ j_D' = [j_D EXCEPT ![self] = (j_D[self]) + (1)] - /\ replicasWrite5' = replicasWrite4' - /\ replicasNetwork' = replicasWrite5' - /\ pc' = [pc EXCEPT ![self] = "disconnectBroadcast"] - ELSE /\ replicasWrite5' = replicasNetwork - /\ replicasNetwork' = replicasWrite5' - /\ pc' = [pc EXCEPT ![self] = "Done"] - /\ UNCHANGED << replicasWrite4, j_D >> - /\ UNCHANGED << clientsNetwork, lock, cid, out, - clocks, replicasRead, - replicasWrite, kvRead, - clientsWrite, clientsWrite0, - kvWrite, kvWrite0, clientsWrite1, - clientIdRead, lockedRead, - clientIdRead0, clockRead, - clientIdRead1, lockedWrite, - clientIdRead2, clockRead0, - clientIdRead3, clockWrite, - keyRead, clientIdRead4, - clientIdRead5, clockRead1, - replicasWrite0, clientsRead, - clientsWrite2, outsideWrite, - lockedWrite0, clockWrite0, - replicasWrite1, clientsWrite3, - outsideWrite0, spinRead, - clientIdRead6, lockedRead0, - clientIdRead7, clockRead2, - clientIdRead8, clockRead3, - clientIdRead9, clockWrite1, - keyRead0, valueRead, - clientIdRead10, clientIdRead11, - clockRead4, clientIdRead12, - lockedWrite1, replicasWrite2, - replicasWrite3, clientsRead0, - clientsWrite4, clientsWrite5, - lockedWrite2, outsideWrite1, - spinRead0, clientIdRead13, - lockedRead1, clientIdRead14, - clientIdRead15, clockWrite2, - clockWrite3, clientIdRead16, - clockRead5, clientIdRead17, - clockRead6, clientIdRead18, - clockWrite4, clientIdRead19, - clientIdRead20, clockRead7, - replicasWrite6, replicasWrite7, - spinRead1, kvLocal, liveClients, - pendingRequests, stableMessages, - i_, firstPending, timestamp, - nextClient, lowestPending, - chooseMessage, currentClocks, - minClock, continue_, - pendingClients, clientsIter, msg_, - ok, key, val, spinLocal, - continue_G, getReq, getResp, - spinLocal0, continue_P, i, j_, - putReq, putResp, msg_D, - spinLocal1, continue, j, msg >> - -DisconnectClient(self) == sendDisconnectRequest(self) - \/ disconnectBroadcast(self) - -clockUpdateLoop(self) == /\ pc[self] = "clockUpdateLoop" - /\ IF continue[self] - THEN /\ clientIdRead16' = (self) - ((NUM_CLIENTS) * (NULL_ORDER)) - /\ clockRead5' = clocks[clientIdRead16'] - /\ IF (clockRead5') = (-(1)) - THEN /\ continue' = [continue EXCEPT ![self] = FALSE] - /\ pc' = [pc EXCEPT ![self] = "nullCheckSpin"] - /\ UNCHANGED << clocks, - clientIdRead17, - clockRead6, - clientIdRead18, - clockWrite4, - clientIdRead19, - clientIdRead20, - clockRead7, j, - msg >> - ELSE /\ clientIdRead17' = (self) - ((NUM_CLIENTS) * (NULL_ORDER)) - /\ clockRead6' = clocks[clientIdRead17'] - /\ clientIdRead18' = (self) - ((NUM_CLIENTS) * (NULL_ORDER)) - /\ clockWrite4' = [clocks EXCEPT ![clientIdRead18'] = (clockRead6') + (1)] - /\ clientIdRead19' = (self) - ((NUM_CLIENTS) * (NULL_ORDER)) - /\ clientIdRead20' = (self) - ((NUM_CLIENTS) * (NULL_ORDER)) - /\ clockRead7' = clockWrite4'[clientIdRead20'] - /\ msg' = [msg EXCEPT ![self] = [op |-> NULL_MSG, client |-> clientIdRead19', timestamp |-> clockRead7']] - /\ j' = [j EXCEPT ![self] = 0] - /\ clocks' = clockWrite4' - /\ pc' = [pc EXCEPT ![self] = "nullBroadcast"] - /\ UNCHANGED continue - ELSE /\ pc' = [pc EXCEPT ![self] = "Done"] - /\ UNCHANGED << clocks, clientIdRead16, - clockRead5, clientIdRead17, - clockRead6, clientIdRead18, - clockWrite4, - clientIdRead19, - clientIdRead20, clockRead7, - continue, j, msg >> - /\ UNCHANGED << replicasNetwork, clientsNetwork, lock, - cid, out, replicasRead, replicasWrite, - kvRead, clientsWrite, clientsWrite0, - kvWrite, kvWrite0, clientsWrite1, - clientIdRead, lockedRead, - clientIdRead0, clockRead, - clientIdRead1, lockedWrite, - clientIdRead2, clockRead0, - clientIdRead3, clockWrite, keyRead, - clientIdRead4, clientIdRead5, - clockRead1, replicasWrite0, - clientsRead, clientsWrite2, - outsideWrite, lockedWrite0, - clockWrite0, replicasWrite1, - clientsWrite3, outsideWrite0, - spinRead, clientIdRead6, lockedRead0, - clientIdRead7, clockRead2, - clientIdRead8, clockRead3, - clientIdRead9, clockWrite1, keyRead0, - valueRead, clientIdRead10, - clientIdRead11, clockRead4, - clientIdRead12, lockedWrite1, - replicasWrite2, replicasWrite3, - clientsRead0, clientsWrite4, - clientsWrite5, lockedWrite2, - outsideWrite1, spinRead0, - clientIdRead13, lockedRead1, - clientIdRead14, clientIdRead15, - clockWrite2, clockWrite3, - replicasWrite4, replicasWrite5, - replicasWrite6, replicasWrite7, - spinRead1, kvLocal, liveClients, - pendingRequests, stableMessages, i_, - firstPending, timestamp, nextClient, - lowestPending, chooseMessage, - currentClocks, minClock, continue_, - pendingClients, clientsIter, msg_, ok, - key, val, spinLocal, continue_G, - getReq, getResp, spinLocal0, - continue_P, i, j_, putReq, putResp, - msg_D, j_D, spinLocal1 >> - -nullCheckSpin(self) == /\ pc[self] = "nullCheckSpin" - /\ spinRead1' = spinLocal1[self] - /\ IF ~(spinRead1') - THEN /\ continue' = [continue EXCEPT ![self] = FALSE] - /\ pc' = [pc EXCEPT ![self] = "clockUpdateLoop"] - ELSE /\ pc' = [pc EXCEPT ![self] = "clockUpdateLoop"] - /\ UNCHANGED continue - /\ UNCHANGED << replicasNetwork, clientsNetwork, lock, - cid, out, clocks, replicasRead, - replicasWrite, kvRead, clientsWrite, - clientsWrite0, kvWrite, kvWrite0, - clientsWrite1, clientIdRead, lockedRead, - clientIdRead0, clockRead, clientIdRead1, - lockedWrite, clientIdRead2, clockRead0, - clientIdRead3, clockWrite, keyRead, - clientIdRead4, clientIdRead5, - clockRead1, replicasWrite0, clientsRead, - clientsWrite2, outsideWrite, - lockedWrite0, clockWrite0, - replicasWrite1, clientsWrite3, - outsideWrite0, spinRead, clientIdRead6, - lockedRead0, clientIdRead7, clockRead2, - clientIdRead8, clockRead3, - clientIdRead9, clockWrite1, keyRead0, - valueRead, clientIdRead10, - clientIdRead11, clockRead4, - clientIdRead12, lockedWrite1, - replicasWrite2, replicasWrite3, - clientsRead0, clientsWrite4, - clientsWrite5, lockedWrite2, - outsideWrite1, spinRead0, - clientIdRead13, lockedRead1, - clientIdRead14, clientIdRead15, - clockWrite2, clockWrite3, - replicasWrite4, replicasWrite5, - clientIdRead16, clockRead5, - clientIdRead17, clockRead6, - clientIdRead18, clockWrite4, - clientIdRead19, clientIdRead20, - clockRead7, replicasWrite6, - replicasWrite7, kvLocal, liveClients, - pendingRequests, stableMessages, i_, - firstPending, timestamp, nextClient, - lowestPending, chooseMessage, - currentClocks, minClock, continue_, - pendingClients, clientsIter, msg_, ok, - key, val, spinLocal, continue_G, getReq, - getResp, spinLocal0, continue_P, i, j_, - putReq, putResp, msg_D, j_D, spinLocal1, - j, msg >> - -nullBroadcast(self) == /\ pc[self] = "nullBroadcast" - /\ IF (j[self]) <= ((NUM_REPLICAS) - (1)) - THEN /\ (Len(replicasNetwork[j[self]])) < (BUFFER_SIZE) - /\ replicasWrite6' = [replicasNetwork EXCEPT ![j[self]] = Append(replicasNetwork[j[self]], msg[self])] - /\ j' = [j EXCEPT ![self] = (j[self]) + (1)] - /\ replicasWrite7' = replicasWrite6' - /\ replicasNetwork' = replicasWrite7' - /\ pc' = [pc EXCEPT ![self] = "nullBroadcast"] - ELSE /\ replicasWrite7' = replicasNetwork - /\ replicasNetwork' = replicasWrite7' - /\ pc' = [pc EXCEPT ![self] = "nullCheckSpin"] - /\ UNCHANGED << replicasWrite6, j >> - /\ UNCHANGED << clientsNetwork, lock, cid, out, clocks, - replicasRead, replicasWrite, kvRead, - clientsWrite, clientsWrite0, kvWrite, - kvWrite0, clientsWrite1, clientIdRead, - lockedRead, clientIdRead0, clockRead, - clientIdRead1, lockedWrite, - clientIdRead2, clockRead0, - clientIdRead3, clockWrite, keyRead, - clientIdRead4, clientIdRead5, - clockRead1, replicasWrite0, clientsRead, - clientsWrite2, outsideWrite, - lockedWrite0, clockWrite0, - replicasWrite1, clientsWrite3, - outsideWrite0, spinRead, clientIdRead6, - lockedRead0, clientIdRead7, clockRead2, - clientIdRead8, clockRead3, - clientIdRead9, clockWrite1, keyRead0, - valueRead, clientIdRead10, - clientIdRead11, clockRead4, - clientIdRead12, lockedWrite1, - replicasWrite2, replicasWrite3, - clientsRead0, clientsWrite4, - clientsWrite5, lockedWrite2, - outsideWrite1, spinRead0, - clientIdRead13, lockedRead1, - clientIdRead14, clientIdRead15, - clockWrite2, clockWrite3, - replicasWrite4, replicasWrite5, - clientIdRead16, clockRead5, - clientIdRead17, clockRead6, - clientIdRead18, clockWrite4, - clientIdRead19, clientIdRead20, - clockRead7, spinRead1, kvLocal, - liveClients, pendingRequests, - stableMessages, i_, firstPending, - timestamp, nextClient, lowestPending, - chooseMessage, currentClocks, minClock, - continue_, pendingClients, clientsIter, - msg_, ok, key, val, spinLocal, - continue_G, getReq, getResp, spinLocal0, - continue_P, i, j_, putReq, putResp, - msg_D, j_D, spinLocal1, continue, msg >> - -ClockUpdateClient(self) == clockUpdateLoop(self) \/ nullCheckSpin(self) - \/ nullBroadcast(self) - -Next == (\E self \in ReplicaSet: Replica(self)) - \/ (\E self \in GetSet: GetClient(self)) - \/ (\E self \in PutSet: PutClient(self)) - \/ (\E self \in DisconnectSet: DisconnectClient(self)) - \/ (\E self \in NullSet: ClockUpdateClient(self)) - \/ (* Disjunct to prevent deadlock on termination *) - ((\A self \in ProcSet: pc[self] = "Done") /\ UNCHANGED vars) - -Spec == /\ Init /\ [][Next]_vars - /\ \A self \in ReplicaSet : WF_vars(Replica(self)) - /\ \A self \in GetSet : WF_vars(GetClient(self)) - /\ \A self \in PutSet : WF_vars(PutClient(self)) - /\ \A self \in DisconnectSet : WF_vars(DisconnectClient(self)) - /\ \A self \in NullSet : WF_vars(ClockUpdateClient(self)) - -Termination == <>(\A self \in ProcSet: pc[self] = "Done") - -\* END TRANSLATION - -\* This predicate is true when all client processes are finished. -AllClientsDisconnected == LET allClients == GetSet \cup PutSet \cup DisconnectSet \cup NullSet - IN - \A client \in allClients : pc[client] = "Done" - - -\* Invariants -\* ********** - -\* These ensure that, in all states explored by TLC, the buffers (from client to replica and vice versa) -\* are within bounds. Using the FIFOChannel mapping macro is sufficient for this invariant to -\* hold. -BufferOk(net, node) == Len(net[node]) >= 0 /\ Len(net[node]) <= BUFFER_SIZE -ClientBuffersOk == \A node \in DOMAIN clientsNetwork : BufferOk(clientsNetwork, node) -ReplicaBuffersOk == \A node \in DOMAIN replicasNetwork : BufferOk(replicasNetwork, node) -AllBuffersOk == ClientBuffersOk /\ ReplicaBuffersOk - -\* This invariant tests that message stability detection in the replica is safe: -\* every message considered stable must have a timestamp lower than the current logical -\* clock of any live client. -MessageStability == \A replica \in ReplicaSet : - LET stable == stableMessages[replica] - alive == { c \in ClientSet : clocks[c] > 0 } - IN - Len(stable) > 0 => - \A m_id \in DOMAIN stable : - \A client \in alive : stable[m_id].timestamp < clocks[client] - - -\* Put semantics: once a client has been notified that a Put request was succesful -\* every replica must have the updated value. -PersistentPut == \A client \in PutSet : - pc[client] = "putComplete" => \A replica \in ReplicaSet : kvLocal[replica][PUT_KEY] = PUT_VALUE - - -\* Properties -\* ********** - -\* Logical clocks are monotonically increasing. This property checks that in every state, -\* pending messages in the replicas have increasing timestamps (or the process disconnected) -ClockIncreased == clocks' /= clocks => - \E c \in ClientSet : clocks'[c] = clocks[c]+1 \/ clocks'[c] = -1 - -MonotonicallyIncreasingClocks == [][ClockIncreased]_<> - - -\* Safety of disconnection: once a client has disconnected (and sent a message to all replicas -\* informing of that event), then the logical clock of that client should remain -\* unchanced -- i.e., no more messages from that client should be seen in the system. -DisconnectionSafe == \A client \in ClientSet : <>[](clocks[client] = -1) - -============================================================================= -\* Modification History -\* Last modified Thu Apr 04 15:00:41 PDT 2019 by rmc -\* Last modified Wed Feb 27 12:42:52 PST 2019 by minh diff --git a/test/pgo/GoGenFileTests.scala b/test/pgo/GoGenFileTests.scala index af37d7e23..289eb7e4a 100644 --- a/test/pgo/GoGenFileTests.scala +++ b/test/pgo/GoGenFileTests.scala @@ -4,7 +4,8 @@ class GoGenFileTests extends FileTestSuite { lazy val goExe: String = sys.env.getOrElse("GO_EXE", "go") override val testFiles: List[os.Path] = - os.list.stream(os.pwd / "test" / "files" / "general") + (os.list.stream(os.pwd / "test" / "files" / "general") ++ + os.list.stream(os.pwd / "test" / "files" / "gogen")) .filter(_.last.endsWith(".tla")) .toList diff --git a/test/pgo/TLAExpressionFuzzTests.scala b/test/pgo/TLAExpressionFuzzTests.scala index 7694edcb2..48b104c9b 100644 --- a/test/pgo/TLAExpressionFuzzTests.scala +++ b/test/pgo/TLAExpressionFuzzTests.scala @@ -6,14 +6,13 @@ import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks import pgo.model.Definition.ScopeIdentifierName import pgo.model.DefinitionOne import pgo.model.tla._ -import pgo.trans.PCalRenderPass +import pgo.trans.{MPCalGoCodegenPass, PCalRenderPass} import pgo.util.Description._ import pgo.util.TLAExprInterpreter.TLAValue import pgo.util.{IdSet, TLAExprInterpreter} import scala.annotation.tailrec import scala.collection.mutable -import scala.math import scala.util.control.NonFatal class TLAExpressionFuzzTests extends AnyFunSuite with ScalaCheckPropertyChecks { @@ -59,7 +58,7 @@ class TLAExpressionFuzzTests extends AnyFunSuite with ScalaCheckPropertyChecks { forAll(trueRandomExprGen) { (expr: TLAExpression) => val mpcalSetup = d"----MODULE TestBed----\n" + - d"EXTENDS Integers, Sequences, TLC, FiniteSets\n" + + d"EXTENDS Integers, Sequences, TLC, FiniteSets, Peano\n" + d"(* --mpcal TestBed {\n" + d"archetype TestBed() {\n" + d"lbl: print ${PCalRenderPass.describeExpr(expr)};\n".indented + @@ -149,13 +148,10 @@ class TLAExpressionFuzzTests extends AnyFunSuite with ScalaCheckPropertyChecks { override def genIterator: Iterator[Gen[TLAExpression]] = Iterator.single(gen) } - val builtinModules = BuiltinModules.builtinModules.values.filter { mod => - (mod ne BuiltinModules.Reals) && - (mod ne BuiltinModules.Bags) && - (mod ne BuiltinModules.TLC) && - (mod ne BuiltinModules.Peano) && - (mod ne BuiltinModules.ProtoReals) - } + val builtinOps = BuiltinModules.builtinModules.values.view + .flatMap(_.members) + .filter(op => !MPCalGoCodegenPass.unsupportedOperators(op)) + .toList val cases: Iterator[PartialFunction[List[TLAExpression],GenProvider]] = Iterator( { case Nil => for { @@ -172,8 +168,7 @@ class TLAExpressionFuzzTests extends AnyFunSuite with ScalaCheckPropertyChecks { } : Iterable[Gen[TLAExpression]] }, { case Nil => - builtinModules.view - .flatMap(_.members) + builtinOps.view .filter(_.arity == 0) .map { defn => TLAGeneralIdentifier(defn.identifier.asInstanceOf[ScopeIdentifierName].name, Nil) @@ -191,8 +186,7 @@ class TLAExpressionFuzzTests extends AnyFunSuite with ScalaCheckPropertyChecks { } }, { case subExprs: List[TLAExpression] if subExprs.nonEmpty => - builtinModules.view - .flatMap(_.members) + builtinOps.view .filter(_.arity == subExprs.size) .map { defn => TLAOperatorCall(defn.identifier, Nil, subExprs) diff --git a/test/pluscal/AltBitProtocol.tla b/test/pluscal/AltBitProtocol.tla deleted file mode 100644 index 24ae5de44..000000000 --- a/test/pluscal/AltBitProtocol.tla +++ /dev/null @@ -1,148 +0,0 @@ ---------------------- MODULE AltBitProtocol ---------------------- -EXTENDS Naturals, Sequences, TLC -CONSTANT Msg - -(******************************************************) -(* AltBitProtocol from The PlusCal Algorithm Language *) -(* paper by Lamport *) -(******************************************************) - -Remove(i, seq) == [j \in 1..(Len(seq)-1) |-> IF j < i THEN seq[j] ELSE seq[j+1]] - -(* ---algorithm AltBitProtocol { - variables - input = <<>>, output = <<>>, - msgChan = <<>>, ackChan = <<>>, - newChan = <<>>; - - macro Send(m, chan) { - chan := Append(chan, m); - } - - macro Recv(v, chan) { - await chan # <<>>; \* could also do Len(chan) > 0 ?? - v := Head(chan); - chan := Tail(chan); - } - - process (Sender = "S") - variables next = 1, sbit = 0, ack; - { - s: while (TRUE) { - either with (m \in Msg) { - input := Append(input, m); - - } or { - await next <= Len(input); - Send(<>, msgChan); - - } or { - Recv(ack, ackChan); - if (ack = sbit) { - next := next + 1; - sbit := (sbit + 1) % 2; - }; - }; - print <<"Sender", input>>; - } - }; \* end Sender process block - - process (Receiver = "R") - variables rbit = 1, msg; - { - r: while (TRUE) { - either { - Send(rbit, ackChan); - } or { - Recv(msg, msgChan); - if (msg[2] # rbit) { - rbit := (rbit + 1) % 2; - output := Append(output, msg[1]); - }; - }; - } - }; \* end Receiver process block - - process (LoseMsg = "L") { - l: while (TRUE) { - either with (i \in 1..Len(msgChan)) { - msgChan := Remove(i, msgChan); - } or with (i \in 1..Len(ackChan)) { - ackChan := Remove(i, ackChan); - }; - } - }; \* end LoseMsg process block - -} \* end algorithm -*) -\* BEGIN TRANSLATION -CONSTANT defaultInitValue -VARIABLES input, output, msgChan, ackChan, newChan, next, sbit, ack, rbit, - msg - -vars == << input, output, msgChan, ackChan, newChan, next, sbit, ack, rbit, - msg >> - -ProcSet == {"S"} \cup {"R"} \cup {"L"} - -Init == (* Global variables *) - /\ input = <<>> - /\ output = <<>> - /\ msgChan = <<>> - /\ ackChan = <<>> - /\ newChan = <<>> - (* Process Sender *) - /\ next = 1 - /\ sbit = 0 - /\ ack = defaultInitValue - (* Process Receiver *) - /\ rbit = 1 - /\ msg = defaultInitValue - -Sender == /\ \/ /\ \E m \in Msg: - input' = Append(input, m) - /\ UNCHANGED <> - \/ /\ next <= Len(input) - /\ msgChan' = Append(msgChan, (<>)) - /\ UNCHANGED <> - \/ /\ ackChan # <<>> - /\ ack' = Head(ackChan) - /\ ackChan' = Tail(ackChan) - /\ IF ack' = sbit - THEN /\ next' = next + 1 - /\ sbit' = (sbit + 1) % 2 - ELSE /\ TRUE - /\ UNCHANGED << next, sbit >> - /\ UNCHANGED <> - /\ PrintT(<<"Sender", input'>>) - /\ UNCHANGED << output, newChan, rbit, msg >> - -Receiver == /\ \/ /\ ackChan' = Append(ackChan, rbit) - /\ UNCHANGED <> - \/ /\ msgChan # <<>> - /\ msg' = Head(msgChan) - /\ msgChan' = Tail(msgChan) - /\ IF msg'[2] # rbit - THEN /\ rbit' = (rbit + 1) % 2 - /\ output' = Append(output, msg'[1]) - ELSE /\ TRUE - /\ UNCHANGED << output, rbit >> - /\ UNCHANGED ackChan - /\ UNCHANGED << input, newChan, next, sbit, ack >> - -LoseMsg == /\ \/ /\ \E i \in 1..Len(msgChan): - msgChan' = Remove(i, msgChan) - /\ UNCHANGED ackChan - \/ /\ \E i \in 1..Len(ackChan): - ackChan' = Remove(i, ackChan) - /\ UNCHANGED msgChan - /\ UNCHANGED << input, output, newChan, next, sbit, ack, rbit, msg >> - -Next == Sender \/ Receiver \/ LoseMsg - -Spec == Init /\ [][Next]_vars - -\* END TRANSLATION - -================================================================== diff --git a/test/pluscal/Await.tla b/test/pluscal/Await.tla deleted file mode 100644 index 39e08e67b..000000000 --- a/test/pluscal/Await.tla +++ /dev/null @@ -1,71 +0,0 @@ ----------------------------- MODULE Await ---------------------------- -EXTENDS Integers -CONSTANT Procs - -(*************************************************************************** ---algorithm Await - { - variable x = 0; - - macro AwaitZero() { - await x = 0; - } - process (p = 0) - { - p0: while (TRUE) - { - p1: AwaitZero(); - x := 1; - } - } - process (q = 1) - { - q0: while (TRUE) - { - q1: await x = 1; - x := 0; - } - } - } -} - ***************************************************************************) -\* BEGIN TRANSLATION -VARIABLES x, pc - -vars == << x, pc >> - -ProcSet == {0} \cup {1} - -Init == (* Global variables *) - /\ x = 0 - /\ pc = [self \in ProcSet |-> CASE self = 0 -> "p0" - [] self = 1 -> "q0"] - -p0 == /\ pc[0] = "p0" - /\ pc' = [pc EXCEPT ![0] = "p1"] - /\ x' = x - -p1 == /\ pc[0] = "p1" - /\ x = 0 - /\ x' = 1 - /\ pc' = [pc EXCEPT ![0] = "p0"] - -p == p0 \/ p1 - -q0 == /\ pc[1] = "q0" - /\ pc' = [pc EXCEPT ![1] = "q1"] - /\ x' = x - -q1 == /\ pc[1] = "q1" - /\ x = 1 - /\ x' = 0 - /\ pc' = [pc EXCEPT ![1] = "q0"] - -q == q0 \/ q1 - -Next == p \/ q - -Spec == Init /\ [][Next]_vars - -\* END TRANSLATION -============================================================================= diff --git a/test/pluscal/Euclid.tla b/test/pluscal/Euclid.tla deleted file mode 100644 index 44389d8fc..000000000 --- a/test/pluscal/Euclid.tla +++ /dev/null @@ -1,59 +0,0 @@ ------------------------- MODULE Euclid ---------------------------- -EXTENDS Naturals, TLC -CONSTANT N - -(* ---algorithm Euclid { - variables u = 24; - v \in 1 .. N; - v_init = v; - { - while (u # 0) { - if (u < v) { - u := v || v := u; - }; - u := u - v; - }; - print <<24, v_init, "have gcd", v>> - } -} -*) -\* BEGIN TRANSLATION -VARIABLES u, v, v_init, pc - -vars == << u, v, v_init, pc >> - -Init == (* Global variables *) - /\ u = 24 - /\ v \in 1 .. N - /\ v_init = v - /\ pc = "Lbl_1" - -Lbl_1 == /\ pc = "Lbl_1" - /\ IF u # 0 - THEN /\ IF u < v - THEN /\ /\ u' = v - /\ v' = u - ELSE /\ TRUE - /\ UNCHANGED << u, v >> - /\ pc' = "Lbl_2" - ELSE /\ PrintT(<<24, v_init, "have gcd", v>>) - /\ pc' = "Done" - /\ UNCHANGED << u, v >> - /\ UNCHANGED v_init - -Lbl_2 == /\ pc = "Lbl_2" - /\ u' = u - v - /\ pc' = "Lbl_1" - /\ UNCHANGED << v, v_init >> - -Next == Lbl_1 \/ Lbl_2 - \/ (* Disjunct to prevent deadlock on termination *) - (pc = "Done" /\ UNCHANGED vars) - -Spec == Init /\ [][Next]_vars - -Termination == <>(pc = "Done") - -\* END TRANSLATION -=================================================================== diff --git a/test/pluscal/FastMutex.tla b/test/pluscal/FastMutex.tla deleted file mode 100644 index d00e71f9c..000000000 --- a/test/pluscal/FastMutex.tla +++ /dev/null @@ -1,160 +0,0 @@ ------------------------ MODULE FastMutex ------------------------- -EXTENDS Naturals, TLC -CONSTANT N - -(* ---algorithm FastMutex { - variables x, - y = 0, - b = [i \in 1..N |-> FALSE]; - process (Proc \in 1..N) - variable j; - { - ncs: while (TRUE) { - skip; \* the noncritical section - - start: b[self] := TRUE; - s01: x := self; - - s02: if (y # 0) { - s03: b[self] := FALSE; - s04: await y = 0; - goto start; - }; - - s05: y := self; - s06: if (x # self) { - s07: b[self] := FALSE; - j := 1; - - s08: while (j <= N) { - await ~b[j]; - j := j+1; \* change to j+2 to see a violation of the assertion below - }; - - s09: if (y # self) { - s10: await y = 0; - goto start; - }; - }; - - cs: assert \A idx \in 1..N : (idx # self) => (pc[idx] # "cs"); \* critical section - s11: y := 0; - s12: b[self] := FALSE; - } \* end outer while - - } \* end process block -} \* end algorithm -*) -\* BEGIN TRANSLATION -CONSTANT defaultInitValue -VARIABLES x, y, b, pc, j - -vars == << x, y, b, pc, j >> - -ProcSet == (1..N) - -Init == (* Global variables *) - /\ x = defaultInitValue - /\ y = 0 - /\ b = [i \in 1..N |-> FALSE] - (* Process Proc *) - /\ j = [self \in 1..N |-> defaultInitValue] - /\ pc = [self \in ProcSet |-> "ncs"] - -ncs(self) == /\ pc[self] = "ncs" - /\ TRUE - /\ pc' = [pc EXCEPT ![self] = "start"] - /\ UNCHANGED << x, y, b, j >> - -start(self) == /\ pc[self] = "start" - /\ b' = [b EXCEPT ![self] = TRUE] - /\ pc' = [pc EXCEPT ![self] = "s01"] - /\ UNCHANGED << x, y, j >> - -s01(self) == /\ pc[self] = "s01" - /\ x' = self - /\ pc' = [pc EXCEPT ![self] = "s02"] - /\ UNCHANGED << y, b, j >> - -s02(self) == /\ pc[self] = "s02" - /\ IF y # 0 - THEN /\ pc' = [pc EXCEPT ![self] = "s03"] - ELSE /\ pc' = [pc EXCEPT ![self] = "s05"] - /\ UNCHANGED << x, y, b, j >> - -s03(self) == /\ pc[self] = "s03" - /\ b' = [b EXCEPT ![self] = FALSE] - /\ pc' = [pc EXCEPT ![self] = "s04"] - /\ UNCHANGED << x, y, j >> - -s04(self) == /\ pc[self] = "s04" - /\ y = 0 - /\ pc' = [pc EXCEPT ![self] = "start"] - /\ UNCHANGED << x, y, b, j >> - -s05(self) == /\ pc[self] = "s05" - /\ y' = self - /\ pc' = [pc EXCEPT ![self] = "s06"] - /\ UNCHANGED << x, b, j >> - -s06(self) == /\ pc[self] = "s06" - /\ IF x # self - THEN /\ pc' = [pc EXCEPT ![self] = "s07"] - ELSE /\ pc' = [pc EXCEPT ![self] = "cs"] - /\ UNCHANGED << x, y, b, j >> - -s07(self) == /\ pc[self] = "s07" - /\ b' = [b EXCEPT ![self] = FALSE] - /\ j' = [j EXCEPT ![self] = 1] - /\ pc' = [pc EXCEPT ![self] = "s08"] - /\ UNCHANGED << x, y >> - -s08(self) == /\ pc[self] = "s08" - /\ IF j[self] <= N - THEN /\ ~b[j[self]] - /\ j' = [j EXCEPT ![self] = j[self]+2] - /\ pc' = [pc EXCEPT ![self] = "s08"] - ELSE /\ pc' = [pc EXCEPT ![self] = "s09"] - /\ j' = j - /\ UNCHANGED << x, y, b >> - -s09(self) == /\ pc[self] = "s09" - /\ IF y # self - THEN /\ pc' = [pc EXCEPT ![self] = "s10"] - ELSE /\ pc' = [pc EXCEPT ![self] = "cs"] - /\ UNCHANGED << x, y, b, j >> - -s10(self) == /\ pc[self] = "s10" - /\ y = 0 - /\ pc' = [pc EXCEPT ![self] = "start"] - /\ UNCHANGED << x, y, b, j >> - -cs(self) == /\ pc[self] = "cs" - /\ Assert(\A idx \in 1..N : (idx # self) => (pc[idx] # "cs"), - "Failure of assertion at line 41, column 14.") - /\ pc' = [pc EXCEPT ![self] = "s11"] - /\ UNCHANGED << x, y, b, j >> - -s11(self) == /\ pc[self] = "s11" - /\ y' = 0 - /\ pc' = [pc EXCEPT ![self] = "s12"] - /\ UNCHANGED << x, b, j >> - -s12(self) == /\ pc[self] = "s12" - /\ b' = [b EXCEPT ![self] = FALSE] - /\ pc' = [pc EXCEPT ![self] = "ncs"] - /\ UNCHANGED << x, y, j >> - -Proc(self) == ncs(self) \/ start(self) \/ s01(self) \/ s02(self) - \/ s03(self) \/ s04(self) \/ s05(self) \/ s06(self) - \/ s07(self) \/ s08(self) \/ s09(self) \/ s10(self) - \/ cs(self) \/ s11(self) \/ s12(self) - -Next == (\E self \in 1..N: Proc(self)) - -Spec == Init /\ [][Next]_vars - -\* END TRANSLATION - -=================================================================== diff --git a/test/pluscal/QueensPluscal.tla b/test/pluscal/QueensPluscal.tla deleted file mode 100644 index 0192e42b3..000000000 --- a/test/pluscal/QueensPluscal.tla +++ /dev/null @@ -1,124 +0,0 @@ --------------------------- MODULE QueensPluscal ----------------------------- -EXTENDS Naturals, Sequences -(***************************************************************************) -(* Formulation of the N-queens problem and an iterative algorithm to solve *) -(* the problem in TLA+. Since there must be exactly one queen in every row *) -(* we represent placements of queens as functions of the form *) -(* queens \in [ 1..N -> 1..N ] *) -(* where queens[i] gives the column of the queen in row i. Note that such *) -(* a function is just a sequence of length N. *) -(* We will also consider partial solutions, also represented as sequences *) -(* of length \leq N. *) -(***************************************************************************) - -CONSTANT N \** number of queens and size of the board -ASSUME N \in Nat \ {0} - -(* The following predicate determines if queens i and j attack each other - in a placement of queens (represented by a sequence as above). *) -Attacks(queens,i,j) == - \/ queens[i] = queens[j] \** same column - \/ queens[i] - queens[j] = i - j \** first diagonal - \/ queens[j] - queens[i] = i - j \** second diagonal - -(* A placement represents a (partial) solution if no two different queens - attack each other in it. *) -IsSolution(queens) == - \A i \in 1 .. Len(queens)-1 : \A j \in i+1 .. Len(queens) : - ~ Attacks(queens,i,j) - -(* Compute the set of solutions of the N-queens problem. *) -Solutions == { queens \in [1..N -> 1..N] : IsSolution(queens) } - -(***************************************************************************) -(* We now describe an algorithm that iteratively computes the set of *) -(* solutions of the N-queens problem by successively placing queens. *) -(* The current state of the algorithm is given by two variables: *) -(* - todo contains a set of partial solutions, *) -(* - sols contains the set of full solutions found so far. *) -(* At every step, the algorithm picks some partial solution and computes *) -(* all possible extensions by the next queen. If N queens have been placed *) -(* these extensions are in fact full solutions, otherwise they are added *) -(* to the set todo. *) -(***************************************************************************) - -(* --algorithm QueensPluscal - variables - todo = { << >> }; - sols = {}; - - begin -nxtQ: while todo # {} - do - with queens \in todo, - nxtQ = Len(queens) + 1, - cols = { c \in 1..N : ~ \E i \in 1 .. Len(queens) : - Attacks( Append(queens, c), i, nxtQ ) }, - exts = { Append(queens,c) : c \in cols } - do - if (nxtQ = N) - then todo := todo \ {queens}; sols := sols \union exts; - else todo := (todo \ {queens}) \union exts; - end if; - end with; - end while; - end algorithm -*) - -\** BEGIN TRANSLATION -VARIABLES todo, sols, pc - -vars == << todo, sols, pc >> - -Init == (* Global variables *) - /\ todo = { << >> } - /\ sols = {} - /\ pc = "nxtQ" - -nxtQ == /\ pc = "nxtQ" - /\ IF todo # {} - THEN /\ \E queens \in todo: - LET nxtQ == Len(queens) + 1 IN - LET cols == { c \in 1..N : ~ \E i \in 1 .. Len(queens) : - Attacks( Append(queens, c), i, nxtQ ) } IN - LET exts == { Append(queens,c) : c \in cols } IN - IF (nxtQ = N) - THEN /\ todo' = todo \ {queens} - /\ sols' = (sols \union exts) - ELSE /\ todo' = ((todo \ {queens}) \union exts) - /\ UNCHANGED sols - /\ pc' = "nxtQ" - ELSE /\ pc' = "Done" - /\ UNCHANGED << todo, sols >> - -Next == nxtQ - \/ (* Disjunct to prevent deadlock on termination *) - (pc = "Done" /\ UNCHANGED vars) - -Spec == Init /\ [][Next]_vars - -Termination == <>(pc = "Done") - -\** END TRANSLATION - -TypeInvariant == - /\ todo \in SUBSET Seq(1 .. N) /\ \A s \in todo : Len(s) < N - /\ sols \in SUBSET Seq(1 .. N) /\ \A s \in sols : Len(s) = N - -(* The set of sols contains only solutions, and contains all solutions - when todo is empty. *) -Invariant == - /\ sols \subseteq Solutions - /\ todo = {} => Solutions \subseteq sols - -(* Assert that no solutions are ever computed so that TLC displays one *) -NoSolutions == sols = {} - -(* Add a fairness condition to ensure progress as long as todo is nonempty *) -Liveness == WF_vars(nxtQ) -LiveSpec == Spec /\ Liveness - -============================================================================= -\* Modification History -\* Last modified Sat Dec 18 18:57:03 CET 2010 by merz -\* Created Sat Dec 11 08:50:24 CET 2010 by merz diff --git a/test/pluscal/Sum.tla b/test/pluscal/Sum.tla deleted file mode 100644 index 26ccdf5e9..000000000 --- a/test/pluscal/Sum.tla +++ /dev/null @@ -1,155 +0,0 @@ ------------------------------ MODULE Sum ---------------------------- -EXTENDS Naturals, Sequences, TLC -CONSTANT MAXINT, RUNS, N - -(* ---algorithm Sum { -variables network = [i \in 1 .. N+1 |-> <<>>]; - -macro SendTo(from, to, msg) { - network[to] := Append(network[to], <>); -} - -macro Recv(to, id, msg) { - await network[to] # <<>>; - id := Head(network[to])[1]; - msg := Head(network[to])[2]; - network[to] := Tail(network[to]); -} - -process (Client \in 1..N) - variable a_init, b_init, runs=0, id, msg, sum; - { - cl: while (runs < RUNS) { - with (vala \in 1..MAXINT, - valb \in 1..MAXINT) { - - a_init := vala; - b_init := valb; - }; - runs := runs + 1; - cs: - SendTo(self, N+1, <>); - cr: - Recv(self, id, msg); - sum := msg; - chk: skip; - \* assert(sum = a_init - b_init); - } -} - -process (Server = N+1) - variable a, b, id, msg; - { - sr: - Recv(N+1, id, msg); - a := msg[1]; - b := msg[2]; - ss: - SendTo(N+1, id, a+b); - goto sr; -} - -} -*) - -\* BEGIN TRANSLATION -\* Process variable id of process Client at line 23 col 36 changed to id_ -\* Process variable msg of process Client at line 23 col 40 changed to msg_ -CONSTANT defaultInitValue -VARIABLES network, pc, a_init, b_init, runs, id_, msg_, sum, a, b, id, msg - -vars == << network, pc, a_init, b_init, runs, id_, msg_, sum, a, b, id, msg - >> - -ProcSet == (1..N) \cup {N+1} - -Init == (* Global variables *) - /\ network = [i \in 1 .. N+1 |-> <<>>] - (* Process Client *) - /\ a_init = [self \in 1..N |-> defaultInitValue] - /\ b_init = [self \in 1..N |-> defaultInitValue] - /\ runs = [self \in 1..N |-> 0] - /\ id_ = [self \in 1..N |-> defaultInitValue] - /\ msg_ = [self \in 1..N |-> defaultInitValue] - /\ sum = [self \in 1..N |-> defaultInitValue] - (* Process Server *) - /\ a = defaultInitValue - /\ b = defaultInitValue - /\ id = defaultInitValue - /\ msg = defaultInitValue - /\ pc = [self \in ProcSet |-> CASE self \in 1..N -> "cl" - [] self = N+1 -> "sr"] - -cl(self) == /\ pc[self] = "cl" - /\ IF runs[self] < RUNS - THEN /\ \E vala \in 1..MAXINT: - \E valb \in 1..MAXINT: - /\ a_init' = [a_init EXCEPT ![self] = vala] - /\ b_init' = [b_init EXCEPT ![self] = valb] - /\ runs' = [runs EXCEPT ![self] = runs[self] + 1] - /\ pc' = [pc EXCEPT ![self] = "cs"] - ELSE /\ pc' = [pc EXCEPT ![self] = "Done"] - /\ UNCHANGED << a_init, b_init, runs >> - /\ UNCHANGED << network, id_, msg_, sum, a, b, id, msg >> - -cs(self) == /\ pc[self] = "cs" - /\ network' = [network EXCEPT ![(N+1)] = Append(network[(N+1)], <>)>>)] - /\ pc' = [pc EXCEPT ![self] = "cr"] - /\ UNCHANGED << a_init, b_init, runs, id_, msg_, sum, a, b, id, - msg >> - -cr(self) == /\ pc[self] = "cr" - /\ network[self] # <<>> - /\ id_' = [id_ EXCEPT ![self] = Head(network[self])[1]] - /\ msg_' = [msg_ EXCEPT ![self] = Head(network[self])[2]] - /\ network' = [network EXCEPT ![self] = Tail(network[self])] - /\ sum' = [sum EXCEPT ![self] = msg_'[self]] - /\ pc' = [pc EXCEPT ![self] = "chk"] - /\ UNCHANGED << a_init, b_init, runs, a, b, id, msg >> - -chk(self) == /\ pc[self] = "chk" - /\ TRUE - /\ pc' = [pc EXCEPT ![self] = "cl"] - /\ UNCHANGED << network, a_init, b_init, runs, id_, msg_, sum, a, - b, id, msg >> - -Client(self) == cl(self) \/ cs(self) \/ cr(self) \/ chk(self) - -sr == /\ pc[N+1] = "sr" - /\ network[(N+1)] # <<>> - /\ id' = Head(network[(N+1)])[1] - /\ msg' = Head(network[(N+1)])[2] - /\ network' = [network EXCEPT ![(N+1)] = Tail(network[(N+1)])] - /\ a' = msg'[1] - /\ b' = msg'[2] - /\ pc' = [pc EXCEPT ![N+1] = "ss"] - /\ UNCHANGED << a_init, b_init, runs, id_, msg_, sum >> - -ss == /\ pc[N+1] = "ss" - /\ network' = [network EXCEPT ![id] = Append(network[id], <<(N+1), (a+b)>>)] - /\ pc' = [pc EXCEPT ![N+1] = "sr"] - /\ UNCHANGED << a_init, b_init, runs, id_, msg_, sum, a, b, id, msg >> - -Server == sr \/ ss - -Next == Server - \/ (\E self \in 1..N: Client(self)) - \/ (* Disjunct to prevent deadlock on termination *) - ((\A self \in ProcSet: pc[self] = "Done") /\ UNCHANGED vars) - -Spec == /\ Init /\ [][Next]_vars - /\ \A self \in 1..N : WF_vars(Client(self)) - /\ WF_vars(Server) - -Termination == <>(\A self \in ProcSet: pc[self] = "Done") - -\* END TRANSLATION - -SendRecv == pc[N+1] = "ss" => a = a_init[id] /\ b = b_init[id] -Sum == \A i \in 1..N : pc[i] = "chk" => sum[i] = a_init[i] + b_init[i] - -THEOREM Spec => []SendRecv -THEOREM Spec => []Sum - -============= diff --git a/test/pluscal/TwoPhaseCommit.tla b/test/pluscal/TwoPhaseCommit.tla deleted file mode 100644 index 68b09d2c5..000000000 --- a/test/pluscal/TwoPhaseCommit.tla +++ /dev/null @@ -1,180 +0,0 @@ ---------------------- MODULE TwoPhaseCommit ---------------------- -EXTENDS Naturals, TLC -(* ---algorithm TwoPhaseCommit { - variables - managers = {"bob", "chuck", "dave", "everett", "fred"}; - restaurant_stage = [mgr \in managers |-> "start"]; - - macro SetAll(state, kmgrs) { - while (kmgrs # {}) { - with (km \in kmgrs) { - restaurant_stage[km] := state; - kmgrs := kmgrs \ {km}; - }; - }; - } - - process (Restaurant \in managers) - { - c0: await restaurant_stage[self] = "propose"; - - either { - restaurant_stage[self] := "accept"; - } or { - restaurant_stage[self] := "refuse"; - }; - - c1: await (restaurant_stage[self] = "commit") \/ - (restaurant_stage[self] = "abort"); - - if (restaurant_stage[self] = "commit") { - restaurant_stage[self] := "committed"; - } else { - restaurant_stage[self] := "aborted"; - }; - }; \* end Restaurant process block - - process (Controller = "alice") - variables rstMgrs, aborted = FALSE; - { - n0: rstMgrs := managers; - n1: SetAll("propose", rstMgrs); - rstMgrs := managers; \* reassign, since SetAll modified the original rstMgrs set - - n3: while (rstMgrs # {}) { - with (r \in rstMgrs) { - await (restaurant_stage[r] = "accept") \/ (restaurant_stage[r] = "refuse"); - if ((restaurant_stage[r] = "refuse") (*/\ (r # "bob")*)) { - aborted := TRUE; - }; - rstMgrs := rstMgrs \ {r}; - }; - }; - - rstMgrs := managers; - if (aborted = TRUE) { - n4: SetAll("abort", rstMgrs); - } else { - \* MP addition - nck: assert \A rstMgr \in rstMgrs : (restaurant_stage[rstMgr] = "accept"); - \* END MP addition - n5: SetAll("commit", rstMgrs); - }; - } \* end Controller process block - -} \* end algorithm -*) -\* BEGIN TRANSLATION -CONSTANT defaultInitValue -VARIABLES managers, restaurant_stage, pc, rstMgrs, aborted - -vars == << managers, restaurant_stage, pc, rstMgrs, aborted >> - -ProcSet == (managers) \cup {"alice"} - -Init == (* Global variables *) - /\ managers = {"bob", "chuck", "dave", "everett", "fred"} - /\ restaurant_stage = [mgr \in managers |-> "start"] - (* Process Controller *) - /\ rstMgrs = defaultInitValue - /\ aborted = FALSE - /\ pc = [self \in ProcSet |-> CASE self \in managers -> "c0" - [] self = "alice" -> "n0"] - -c0(self) == /\ pc[self] = "c0" - /\ restaurant_stage[self] = "propose" - /\ \/ /\ restaurant_stage' = [restaurant_stage EXCEPT ![self] = "accept"] - \/ /\ restaurant_stage' = [restaurant_stage EXCEPT ![self] = "refuse"] - /\ pc' = [pc EXCEPT ![self] = "c1"] - /\ UNCHANGED << managers, rstMgrs, aborted >> - -c1(self) == /\ pc[self] = "c1" - /\ (restaurant_stage[self] = "commit") \/ - (restaurant_stage[self] = "abort") - /\ IF restaurant_stage[self] = "commit" - THEN /\ restaurant_stage' = [restaurant_stage EXCEPT ![self] = "committed"] - ELSE /\ restaurant_stage' = [restaurant_stage EXCEPT ![self] = "aborted"] - /\ pc' = [pc EXCEPT ![self] = "Done"] - /\ UNCHANGED << managers, rstMgrs, aborted >> - -Restaurant(self) == c0(self) \/ c1(self) - -n0 == /\ pc["alice"] = "n0" - /\ rstMgrs' = managers - /\ pc' = [pc EXCEPT !["alice"] = "n1"] - /\ UNCHANGED << managers, restaurant_stage, aborted >> - -n1 == /\ pc["alice"] = "n1" - /\ IF rstMgrs # {} - THEN /\ \E km \in rstMgrs: - /\ restaurant_stage' = [restaurant_stage EXCEPT ![km] = "propose"] - /\ rstMgrs' = rstMgrs \ {km} - /\ pc' = [pc EXCEPT !["alice"] = "n1"] - ELSE /\ rstMgrs' = managers - /\ pc' = [pc EXCEPT !["alice"] = "n3"] - /\ UNCHANGED restaurant_stage - /\ UNCHANGED << managers, aborted >> - -n3 == /\ pc["alice"] = "n3" - /\ IF rstMgrs # {} - THEN /\ \E r \in rstMgrs: - /\ (restaurant_stage[r] = "accept") \/ (restaurant_stage[r] = "refuse") - /\ IF (restaurant_stage[r] = "refuse") - THEN /\ aborted' = TRUE - ELSE /\ TRUE - /\ UNCHANGED aborted - /\ rstMgrs' = rstMgrs \ {r} - /\ pc' = [pc EXCEPT !["alice"] = "n3"] - ELSE /\ rstMgrs' = managers - /\ IF aborted = TRUE - THEN /\ pc' = [pc EXCEPT !["alice"] = "n4"] - ELSE /\ pc' = [pc EXCEPT !["alice"] = "nck"] - /\ UNCHANGED aborted - /\ UNCHANGED << managers, restaurant_stage >> - -n4 == /\ pc["alice"] = "n4" - /\ IF rstMgrs # {} - THEN /\ \E km \in rstMgrs: - /\ restaurant_stage' = [restaurant_stage EXCEPT ![km] = "abort"] - /\ rstMgrs' = rstMgrs \ {km} - /\ pc' = [pc EXCEPT !["alice"] = "n4"] - ELSE /\ pc' = [pc EXCEPT !["alice"] = "Done"] - /\ UNCHANGED << restaurant_stage, rstMgrs >> - /\ UNCHANGED << managers, aborted >> - -nck == /\ pc["alice"] = "nck" - /\ Assert(\A rstMgr \in rstMgrs : (restaurant_stage[rstMgr] = "accept"), - "Failure of assertion at line 60, column 11.") - /\ pc' = [pc EXCEPT !["alice"] = "n5"] - /\ UNCHANGED << managers, restaurant_stage, rstMgrs, aborted >> - -n5 == /\ pc["alice"] = "n5" - /\ IF rstMgrs # {} - THEN /\ \E km \in rstMgrs: - /\ restaurant_stage' = [restaurant_stage EXCEPT ![km] = "commit"] - /\ rstMgrs' = rstMgrs \ {km} - /\ pc' = [pc EXCEPT !["alice"] = "n5"] - ELSE /\ pc' = [pc EXCEPT !["alice"] = "Done"] - /\ UNCHANGED << restaurant_stage, rstMgrs >> - /\ UNCHANGED << managers, aborted >> - -Controller == n0 \/ n1 \/ n3 \/ n4 \/ nck \/ n5 - -Next == Controller - \/ (\E self \in managers: Restaurant(self)) - \/ (* Disjunct to prevent deadlock on termination *) - ((\A self \in ProcSet: pc[self] = "Done") /\ UNCHANGED vars) - -Spec == Init /\ [][Next]_vars - -Termination == <>(\A self \in ProcSet: pc[self] = "Done") - -\* END TRANSLATION - -StateOK == /\ (\A i \in managers: restaurant_stage[i] \in {"start", "propose", "accept", "commit", "abort", "committed", "aborted", "refuse"}) - -Committed == /\ \/ <>(\A i \in managers: restaurant_stage[i] = "committed") - \/ <>(\A i \in managers: restaurant_stage[i] = "aborted") - -================================================================== diff --git a/test/pluscal/pgo2pc.tla b/test/pluscal/pgo2pc.tla deleted file mode 100644 index fe9eac212..000000000 --- a/test/pluscal/pgo2pc.tla +++ /dev/null @@ -1,204 +0,0 @@ ------------------------------ MODULE pgo2pc ----------------------------- -EXTENDS Integers,Sequences,FiniteSets,TLC -CONSTANTS RM, \* The number of resource managers. - BTM, \* Whether have backupTM. - RMMAYFAIL, \* Whether RM could fail. - TMMAYFAIL \* Whether TM could fail. - - -canCommit(rmStateL) == - \A rm \in RM : rmStateL[rm] \in {"prepared","committed"} \*If some rm are commited or all rm are commited, - -(** might fail due to \A predicate **) -canAbort(rmStateL) == - \A rm \in RM : rmStateL[rm] # "committed" \*if no rm are committed, we don't know the state of tmState, - - -(* --algorithm TransactionCommit { (*** for pgo arg RM int done ***) - - variable rmState = [rm \in RM |-> "working"], - tmState = "init"; \* tmState's init state. - btmState = "init"; \* backupTM's init state. - - \*if tmState is not "commit", we cannot commit. - - (** - macro Prepare(p){ - \*@@PGODEV does this await break? - await rmState[p] = "working"; \*if rmState[p] is working, then it will be prepared - rmState[p] :="prepared"; - } - **) - (** Is This equivalent to the prior macro if placed in a for loop? Must all state transfers be idempotent? **) - - macro Prepare(p) { - if (rmState[p] = "working") { - rmState[p] := "prepared"; - }; - } - - - (** - macro Decide(p){ - either {await rmState[p] = "prepared" /\ canCommit(rmState) /\ (tmState = "commit" \/ btmState = "commit"); \*If rmState[p] is prepared, some rm is committed and - \*if we have backupTM, either tmState or btmState is "commit", - \*then we can change rmState to "commit". - rmState[p] := "committed"; - } - or {await rmState[p] \in {"working","prepared"} /\ canAbort(rmState); \*If not all rmState is committed, we can abort at any time. - rmState[p] := "abort" - } - }**) - - (** Do the functions canCommit require arguments to pass to them, or does pgo translate that? - Is not performing a decide the same as letting TLC hit a wall on either or? **) - macro Decide(p) { - if ( rmState[p] = "prepared" /\ canCommit(rmState) /\ (tmState = "commit" \/ btmState = "commit") ){ - rmState[p] := "committed"; - }; - else if ( rmState[p] \in {"working", "prepared"} /\ canAbort(rmState) ) { - rmState[p] := "abort"; - }; - } - - macro Fail(p){ - if(RMMAYFAIL) rmState[p] := "crash" \*If RMMAYFAIL, rmState[p] could be "crash" - } - - process(RManager \in RM){ \*If rmState is working or prepared, it should execute until abort or commit if we - RS:while(rmState[self] \in {"working","prepared"}){ \*set up backupTM. Otherwise termination might be violated. - either Prepare(self) or Decide(self) or Fail(self)} - } - - process(TManager = 0){ \*If all rm are prepared, it's time to commit, so set tmState to commit. - TS:either{await canCommit(rmState); - TC:tmState := "commit"; - if(BTM) btmState := "commit"; \*If we set backupTM, change the btmState just the same as tmState. - F1:if(TMMAYFAIL) tmState := "hidden";} - - or{await canAbort(rmState); \*Abort can appear any time unless all rmState are committed. - TA:tmState := "abort"; - if(BTM) btmState := "abort"; \*If we set backupTM, change the btmState just the same as tmState. - F2:if(TMMAYFAIL) tmState := "hidden";} - } -} -*) -\* BEGIN TRANSLATION -VARIABLES rmState, tmState, btmState, pc - -vars == << rmState, tmState, btmState, pc >> - -ProcSet == (RM) \cup {0} - -Init == (* Global variables *) - /\ rmState = [rm \in RM |->"working"] - /\ tmState = "init" - /\ btmState = "init" - /\ pc = [self \in ProcSet |-> CASE self \in RM -> "RS" - [] self = 0 -> "TS"] - -RS(self) == /\ pc[self] = "RS" - /\ IF rmState[self] \in {"working","prepared"} - THEN /\ \/ /\ IF rmState[self] = "working" - THEN /\ rmState' = [rmState EXCEPT ![self] = "prepared"] - ELSE /\ TRUE - /\ UNCHANGED rmState - \/ /\ IF rmState[self] = "prepared" /\ canCommit(rmState) /\ (tmState = "commit" \/ btmState = "commit") - THEN /\ rmState' = [rmState EXCEPT ![self] = "committed"] - ELSE /\ IF rmState[self] \in {"working", "prepared"} /\ canAbort(rmState) - THEN /\ rmState' = "abort" - ELSE /\ TRUE - /\ UNCHANGED rmState - \/ /\ IF RMMAYFAIL - THEN /\ rmState' = [rmState EXCEPT ![self] = "crash"] - ELSE /\ TRUE - /\ UNCHANGED rmState - /\ pc' = [pc EXCEPT ![self] = "RS"] - ELSE /\ pc' = [pc EXCEPT ![self] = "Done"] - /\ UNCHANGED rmState - /\ UNCHANGED << tmState, btmState >> - -RManager(self) == RS(self) - -TS == /\ pc[0] = "TS" - /\ \/ /\ canCommit(rmState) - /\ pc' = [pc EXCEPT ![0] = "TC"] - \/ /\ canAbort(rmState) - /\ pc' = [pc EXCEPT ![0] = "TA"] - /\ UNCHANGED << rmState, tmState, btmState >> - -TC == /\ pc[0] = "TC" - /\ tmState' = "commit" - /\ IF BTM - THEN /\ btmState' = "commit" - ELSE /\ TRUE - /\ UNCHANGED btmState - /\ pc' = [pc EXCEPT ![0] = "F1"] - /\ UNCHANGED rmState - -F1 == /\ pc[0] = "F1" - /\ IF TMMAYFAIL - THEN /\ tmState' = "hidden" - ELSE /\ TRUE - /\ UNCHANGED tmState - /\ pc' = [pc EXCEPT ![0] = "Done"] - /\ UNCHANGED << rmState, btmState >> - -TA == /\ pc[0] = "TA" - /\ tmState' = "abort" - /\ IF BTM - THEN /\ btmState' = "abort" - ELSE /\ TRUE - /\ UNCHANGED btmState - /\ pc' = [pc EXCEPT ![0] = "F2"] - /\ UNCHANGED rmState - -F2 == /\ pc[0] = "F2" - /\ IF TMMAYFAIL - THEN /\ tmState' = "hidden" - ELSE /\ TRUE - /\ UNCHANGED tmState - /\ pc' = [pc EXCEPT ![0] = "Done"] - /\ UNCHANGED << rmState, btmState >> - -TManager == TS \/ TC \/ F1 \/ TA \/ F2 - -Next == TManager - \/ (\E self \in RM: RManager(self)) - \/ (* Disjunct to prevent deadlock on termination *) - ((\A self \in ProcSet: pc[self] = "Done") /\ UNCHANGED vars) - -Spec == /\ Init /\ [][Next]_vars - /\ \A self \in RM : WF_vars(RManager(self)) - /\ WF_vars(TManager) - -Termination == <>(\A self \in ProcSet: pc[self] = "Done") - -\* END TRANSLATION - -consistency == tmState = "commit" => \A i \in RM : rmState[i] # "abort" - /\ tmState = "abort" => \A j \in RM : rmState[j] # "committed" - /\ tmState = "hidden" => \A k \in RM : rmState[k] # "committed" -terminate == <>(\A i \in RM : rmState[i] \in {"committed","abort","crash"}) - -============================================================================= -\*1.2 TMMAYFAIL is true and RMMAYFAIL is false means tmState could be "hidden" and rmState cannot be -\*hidden. In this situation, termination will be violated. For example, when TM is "commit" and some -\*RM are committed, then TM crashed while some other RM is prepared, but they can never be "commit" or abort -\*because TM is "hidden" now. That's why we get result when RM equals 3 that <<"committed","prepared","committed">>. -\*It will never been terminated because "prepared" has no way to "commit". - -\*1.3 Termination and comsistency remain true. The states cancommit and canabort is owned by both BTM and TM. -\* So when TM crashes, the RMs can still consult the BTM and make their decision. -\*If an RM crashed, then all other RMs can only abort. So all other uncrashed RMs remain consistent. - -\* Modification History -\* Last modified Wed Feb 28 17:01:19 PST 2018 by stewartgrant -\* Last modified Tue Dec 05 19:55:47 EST 2017 by lenovo -\* Created Wed Nov 29 17:13:20 EST 2017 by lenovo - - - -\*Group Members xhu7:xhu7@buffalo.edu -\*Haowei Zhou haoweizh@buffalo.edu - From b4261d3b741a910c4f2d012581a40b9cecc0c625 Mon Sep 17 00:00:00 2001 From: fhackett Date: Fri, 23 Jul 2021 14:27:00 -0700 Subject: [PATCH 22/27] stub out replicated_kv Go test --- .../general/replicated_kv.tla.gotests/replicated_kv_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/files/general/replicated_kv.tla.gotests/replicated_kv_test.go b/test/files/general/replicated_kv.tla.gotests/replicated_kv_test.go index 7fdca88c4..1e4e4111e 100644 --- a/test/files/general/replicated_kv.tla.gotests/replicated_kv_test.go +++ b/test/files/general/replicated_kv.tla.gotests/replicated_kv_test.go @@ -3,5 +3,5 @@ package replicatedkv import "testing" func TestOneReplica(t *testing.T) { - t.Fail() + t.Skipf("TODO: implement this test") } From fae2a7dd85e1130fcd76218e0b773fdd83731307 Mon Sep 17 00:00:00 2001 From: fhackett Date: Fri, 23 Jul 2021 19:01:16 -0700 Subject: [PATCH 23/27] apply review recommendations; WARNING: slightly broken --- ...etype_resource.go => archetyperesource.go} | 2 +- distsys/{mpcal_context.go => mpcalctx.go} | 15 +++++ .../channels.go | 2 +- .../filesystem.go | 2 +- .../incrementalmap.go} | 2 +- .../tcpmailboxes.go} | 63 ++++++++----------- .../general/dqueue.tla.gotests/dqueue_test.go | 18 +++--- .../load_balancer_test.go | 32 +++++----- 8 files changed, 70 insertions(+), 66 deletions(-) rename distsys/{archetype_resource.go => archetyperesource.go} (98%) rename distsys/{mpcal_context.go => mpcalctx.go} (81%) rename distsys/{archetype_resources => resources}/channels.go (99%) rename distsys/{archetype_resources => resources}/filesystem.go (98%) rename distsys/{archetype_resources/incremental_map.go => resources/incrementalmap.go} (99%) rename distsys/{archetype_resources/tcp_mailboxes.go => resources/tcpmailboxes.go} (89%) diff --git a/distsys/archetype_resource.go b/distsys/archetyperesource.go similarity index 98% rename from distsys/archetype_resource.go rename to distsys/archetyperesource.go index a65151e0b..b194d5626 100644 --- a/distsys/archetype_resource.go +++ b/distsys/archetyperesource.go @@ -7,7 +7,7 @@ import ( // ArchetypeResource represents an interface between an MPCal model and some external environment. // Such a resource should be instantiated under the control of MPCalContext.EnsureArchetypeResourceByName or // MPCalContext.EnsureArchetypeResourceByPosition. Typically, the former would be clearer. -// Many implementations are available under ./archetype_resources. +// Many implementations are available under ./resources. // This API describes what is expected of those implementations, and any others. type ArchetypeResource interface { // Abort will be called when the resource should be reset to a state similar to the last Commit. diff --git a/distsys/mpcal_context.go b/distsys/mpcalctx.go similarity index 81% rename from distsys/mpcal_context.go rename to distsys/mpcalctx.go index 364d29c64..af1e32a14 100644 --- a/distsys/mpcal_context.go +++ b/distsys/mpcalctx.go @@ -14,6 +14,11 @@ var ErrCriticalSectionAborted = errors.New("MPCal critical section aborted") // These handles insulate the end-user from worrying about the specifics of resource lifetimes, logging, and // crash recovery scenarios. type ArchetypeResourceHandle struct { + // a semantic path into the tree of resources stored in MPCalContext + // the type TLAValue is used because it is easy to use as an immutable.Map key, and resource indices are TLAValue anyway + // in general, this can take two forms: + // - <<"named_resource_name", index_1, ...>> + // - <<... stack frame info, index_1, ...>> \* in the case where the resource is local, and possible part of a procedure call path TLAValue } @@ -84,6 +89,13 @@ func NewMPCalContext() *MPCalContext { } } +// EnsureArchetypeResourceByName returns a handle to the ArchetypeResource referenced by name, creating it if necessary +// this function will either: +// - use the provided maker to instantiate the requested resource, storing the newly-created resource +// - find an existing resource with the requested name, then process it via maker.Configure, in case that resource +// has been recovered from disk and requires non-serializable configuration before use (e.g function pointers) +// the main design rationale behind keeping resource creation optional is the possibility that the MPCalContext +// has been recovered from disk and already contains partially-configured snapshots of existing resource state func (ctx *MPCalContext) EnsureArchetypeResourceByName(name string, maker ArchetypeResourceMaker) ArchetypeResourceHandle { handle := ArchetypeResourceHandle{ path: NewTLAString(name), @@ -99,6 +111,9 @@ func (ctx *MPCalContext) EnsureArchetypeResourceByName(name string, maker Archet return handle } +// EnsureArchetypeResourceByPosition operates in the same way as EnsureArchetypeResourceByName, but additionally allows for callstack semantics +// The resource identifier ("path") will be generated based on an internal callstack, which means that a potentially +// recursive MPCal model can allocate local resources without needing to worry about name collisions. func (ctx *MPCalContext) EnsureArchetypeResourceByPosition(maker ArchetypeResourceMaker) ArchetypeResourceHandle { frame := ctx.frameStack[len(ctx.frameStack)-1] handle := ArchetypeResourceHandle{ diff --git a/distsys/archetype_resources/channels.go b/distsys/resources/channels.go similarity index 99% rename from distsys/archetype_resources/channels.go rename to distsys/resources/channels.go index 4c3a8c9a4..7d4e13402 100644 --- a/distsys/archetype_resources/channels.go +++ b/distsys/resources/channels.go @@ -1,4 +1,4 @@ -package archetype_resources +package resources import ( "fmt" diff --git a/distsys/archetype_resources/filesystem.go b/distsys/resources/filesystem.go similarity index 98% rename from distsys/archetype_resources/filesystem.go rename to distsys/resources/filesystem.go index a5fd38508..334eb2774 100644 --- a/distsys/archetype_resources/filesystem.go +++ b/distsys/resources/filesystem.go @@ -1,4 +1,4 @@ -package archetype_resources +package resources import ( "fmt" diff --git a/distsys/archetype_resources/incremental_map.go b/distsys/resources/incrementalmap.go similarity index 99% rename from distsys/archetype_resources/incremental_map.go rename to distsys/resources/incrementalmap.go index b2ceaa9ac..848b4d8d8 100644 --- a/distsys/archetype_resources/incremental_map.go +++ b/distsys/resources/incrementalmap.go @@ -1,4 +1,4 @@ -package archetype_resources +package resources import ( "github.com/UBC-NSS/pgo/distsys" diff --git a/distsys/archetype_resources/tcp_mailboxes.go b/distsys/resources/tcpmailboxes.go similarity index 89% rename from distsys/archetype_resources/tcp_mailboxes.go rename to distsys/resources/tcpmailboxes.go index 713ff9ce2..b537f2387 100644 --- a/distsys/archetype_resources/tcp_mailboxes.go +++ b/distsys/resources/tcpmailboxes.go @@ -1,4 +1,4 @@ -package archetype_resources +package resources import ( "encoding/gob" @@ -26,6 +26,12 @@ const ( TCPMailboxesRemote ) +const ( + tcpMailboxesReceiveChannelSize = 100 // TODO: this should be a configuration option + tcpMailboxesSendTimeout = 20 * time.Millisecond // TODO: same as above + tcpMailboxesConnectionDroppedRetryDelay = 50 * time.Millisecond // TODO: same +) + func TCPMailboxesArchetypeResourceMaker(addressMappingFn func(distsys.TLAValue) (TCPMailboxKind, string)) distsys.ArchetypeResourceMaker { return IncrementalArchetypeMapResourceMaker(func(index distsys.TLAValue) distsys.ArchetypeResourceMaker { tpe, addr := addressMappingFn(index) @@ -52,7 +58,7 @@ var _ distsys.ArchetypeResource = &tcpMailboxesLocalArchetypeResource{} func tcpMailboxesLocalArchetypeResourceMaker(listenAddr string) distsys.ArchetypeResourceMaker { return distsys.ArchetypeResourceMakerFn(func() distsys.ArchetypeResource { - msgChannel := make(chan distsys.TLAValue, 100) + msgChannel := make(chan distsys.TLAValue, tcpMailboxesReceiveChannelSize) listener, err := net.Listen("tcp", listenAddr) if err != nil { log.Fatalf("could not listen on address %s", listenAddr) @@ -171,7 +177,7 @@ func (res *tcpMailboxesLocalArchetypeResource) ReadValue() (distsys.TLAValue, er case msg := <-res.msgChannel: res.readsInProgress = append(res.readsInProgress, msg) return msg, nil - case <-time.After(20 * time.Millisecond): + case <-time.After(tcpMailboxesSendTimeout): return distsys.TLAValue{}, distsys.ErrCriticalSectionAborted } } @@ -188,7 +194,6 @@ type tcpMailboxesRemoteArchetypeResource struct { conn net.Conn connEncoder *gob.Encoder connDecoder *gob.Decoder - sendBuffer []distsys.TLAValue } var _ distsys.ArchetypeResource = &tcpMailboxesRemoteArchetypeResource{} @@ -207,7 +212,7 @@ func (res *tcpMailboxesRemoteArchetypeResource) ensureConnection() error { res.conn, err = net.Dial("tcp", res.dialAddr) if err != nil { log.Printf("failed to dial %s, aborting after 50ms: %v", res.dialAddr, err) - time.Sleep(time.Millisecond * 50) + time.Sleep(tcpMailboxesConnectionDroppedRetryDelay) return distsys.ErrCriticalSectionAborted } res.connEncoder = gob.NewEncoder(res.conn) @@ -217,7 +222,6 @@ func (res *tcpMailboxesRemoteArchetypeResource) ensureConnection() error { } func (res *tcpMailboxesRemoteArchetypeResource) Abort() chan struct{} { - res.sendBuffer = nil // nothing to do; the remote end tolerates just starting over with no explanation return nil } @@ -226,23 +230,23 @@ func (res *tcpMailboxesRemoteArchetypeResource) PreCommit() chan error { ch := make(chan error, 1) go func() { var err error - { - err = res.connEncoder.Encode(tcpNetworkPreCommit) - if err != nil { - goto handleError - } - var ack struct{} - err = res.connDecoder.Decode(&ack) - if err != nil { - goto handleError - } - ch <- nil + handleError := func() { + log.Printf("network error while performing pre-commit handshake, aborting: %v", err) + res.conn = nil + ch <- distsys.ErrCriticalSectionAborted + } + err = res.connEncoder.Encode(tcpNetworkPreCommit) + if err != nil { + handleError() return } - handleError: - log.Printf("network error while performing pre-commit handshake, aborting: %v", err) - res.conn = nil - ch <- distsys.ErrCriticalSectionAborted + var ack struct{} + err = res.connDecoder.Decode(&ack) + if err != nil { + handleError() + return + } + ch <- nil }() return ch } @@ -271,23 +275,8 @@ func (res *tcpMailboxesRemoteArchetypeResource) Commit() chan struct{} { continue outerLoop } if shouldResend { - err = res.connEncoder.Encode(tcpNetworkBegin) - if err != nil { - continue outerLoop - } - for _, value := range res.sendBuffer { - err = res.connEncoder.Encode(tcpNetworkValue) - if err != nil { - continue outerLoop - } - err = res.connEncoder.Encode(&value) - if err != nil { - continue outerLoop - } - } - continue outerLoop + panic("resending is not implemented") } - res.sendBuffer = nil ch <- struct{}{} return } diff --git a/test/files/general/dqueue.tla.gotests/dqueue_test.go b/test/files/general/dqueue.tla.gotests/dqueue_test.go index 067693d66..1d64c2c3f 100644 --- a/test/files/general/dqueue.tla.gotests/dqueue_test.go +++ b/test/files/general/dqueue.tla.gotests/dqueue_test.go @@ -3,7 +3,7 @@ package dqueue import ( "fmt" "github.com/UBC-NSS/pgo/distsys" - "github.com/UBC-NSS/pgo/distsys/archetype_resources" + "github.com/UBC-NSS/pgo/distsys/resources" "testing" ) @@ -28,17 +28,17 @@ func TestProducerConsumer(t *testing.T) { } go func() { - network := producerCtx.EnsureArchetypeResourceByName("network", archetype_resources.TCPMailboxesArchetypeResourceMaker(func(index distsys.TLAValue) (archetype_resources.TCPMailboxKind, string) { + network := producerCtx.EnsureArchetypeResourceByName("network", resources.TCPMailboxesArchetypeResourceMaker(func(index distsys.TLAValue) (resources.TCPMailboxKind, string) { switch index.AsNumber() { case 1: - return archetype_resources.TCPMailboxesLocal, "localhost:8001" + return resources.TCPMailboxesLocal, "localhost:8001" case 2: - return archetype_resources.TCPMailboxesRemote, "localhost:8002" + return resources.TCPMailboxesRemote, "localhost:8002" default: panic(fmt.Errorf("unknown mailbox index %v", index)) } })) - s := producerCtx.EnsureArchetypeResourceByName("s", archetype_resources.InputChannelResourceMaker(producerInputChannel)) + s := producerCtx.EnsureArchetypeResourceByName("s", resources.InputChannelResourceMaker(producerInputChannel)) err := AProducer(producerCtx, producerSelf, constants, network, s) if err != nil { panic(err) @@ -46,17 +46,17 @@ func TestProducerConsumer(t *testing.T) { }() go func() { - network := consumerCtx.EnsureArchetypeResourceByName("network", archetype_resources.TCPMailboxesArchetypeResourceMaker(func(index distsys.TLAValue) (archetype_resources.TCPMailboxKind, string) { + network := consumerCtx.EnsureArchetypeResourceByName("network", resources.TCPMailboxesArchetypeResourceMaker(func(index distsys.TLAValue) (resources.TCPMailboxKind, string) { switch index.AsNumber() { case 1: - return archetype_resources.TCPMailboxesRemote, "localhost:8001" + return resources.TCPMailboxesRemote, "localhost:8001" case 2: - return archetype_resources.TCPMailboxesLocal, "localhost:8002" + return resources.TCPMailboxesLocal, "localhost:8002" default: panic(fmt.Errorf("unknown mailbox index %v", index)) } })) - proc := consumerCtx.EnsureArchetypeResourceByName("proc", archetype_resources.OutputChannelResourceMaker(consumerOutputChannel)) + proc := consumerCtx.EnsureArchetypeResourceByName("proc", resources.OutputChannelResourceMaker(consumerOutputChannel)) err := AConsumer(consumerCtx, consumerSelf, constants, network, proc) if err != nil { panic(err) diff --git a/test/files/general/load_balancer.tla.gotests/load_balancer_test.go b/test/files/general/load_balancer.tla.gotests/load_balancer_test.go index 7f5bc0433..f18d53734 100644 --- a/test/files/general/load_balancer.tla.gotests/load_balancer_test.go +++ b/test/files/general/load_balancer.tla.gotests/load_balancer_test.go @@ -3,7 +3,7 @@ package loadbalancer import ( "fmt" "github.com/UBC-NSS/pgo/distsys" - "github.com/UBC-NSS/pgo/distsys/archetype_resources" + "github.com/UBC-NSS/pgo/distsys/resources" "io/ioutil" "math/rand" "os" @@ -42,14 +42,14 @@ func TestOneServerOneClient(t *testing.T) { go func() { ctx := distsys.NewMPCalContext() self := distsys.NewTLANumber(0) - mailboxes := ctx.EnsureArchetypeResourceByName("mailboxes", archetype_resources.TCPMailboxesArchetypeResourceMaker(func(index distsys.TLAValue) (archetype_resources.TCPMailboxKind, string) { + mailboxes := ctx.EnsureArchetypeResourceByName("mailboxes", resources.TCPMailboxesArchetypeResourceMaker(func(index distsys.TLAValue) (resources.TCPMailboxKind, string) { switch index.AsNumber() { case 0: - return archetype_resources.TCPMailboxesLocal, "localhost:8001" + return resources.TCPMailboxesLocal, "localhost:8001" case 1: - return archetype_resources.TCPMailboxesRemote, "localhost:8002" + return resources.TCPMailboxesRemote, "localhost:8002" case 2: - return archetype_resources.TCPMailboxesRemote, "localhost:8003" + return resources.TCPMailboxesRemote, "localhost:8003" default: panic(fmt.Errorf("unknown mailbox index %v", index)) } @@ -63,19 +63,19 @@ func TestOneServerOneClient(t *testing.T) { go func() { ctx := distsys.NewMPCalContext() self := distsys.NewTLANumber(1) - mailboxes := ctx.EnsureArchetypeResourceByName("mailboxes", archetype_resources.TCPMailboxesArchetypeResourceMaker(func(index distsys.TLAValue) (archetype_resources.TCPMailboxKind, string) { + mailboxes := ctx.EnsureArchetypeResourceByName("mailboxes", resources.TCPMailboxesArchetypeResourceMaker(func(index distsys.TLAValue) (resources.TCPMailboxKind, string) { switch index.AsNumber() { case 0: - return archetype_resources.TCPMailboxesRemote, "localhost:8001" + return resources.TCPMailboxesRemote, "localhost:8001" case 1: - return archetype_resources.TCPMailboxesLocal, "localhost:8002" + return resources.TCPMailboxesLocal, "localhost:8002" case 2: - return archetype_resources.TCPMailboxesRemote, "localhost:8003" + return resources.TCPMailboxesRemote, "localhost:8003" default: panic(fmt.Errorf("unknown mailbox index %v", index)) } })) - filesystem := ctx.EnsureArchetypeResourceByName("filesystem", archetype_resources.FilesystemArchetypeResourceMaker(tempDir)) + filesystem := ctx.EnsureArchetypeResourceByName("filesystem", resources.FilesystemArchetypeResourceMaker(tempDir)) err := AServer(ctx, self, constants, mailboxes, filesystem) if err != nil { panic(err) @@ -87,20 +87,20 @@ func TestOneServerOneClient(t *testing.T) { go func() { ctx := distsys.NewMPCalContext() self := distsys.NewTLANumber(2) - mailboxes := ctx.EnsureArchetypeResourceByName("mailboxes", archetype_resources.TCPMailboxesArchetypeResourceMaker(func(index distsys.TLAValue) (archetype_resources.TCPMailboxKind, string) { + mailboxes := ctx.EnsureArchetypeResourceByName("mailboxes", resources.TCPMailboxesArchetypeResourceMaker(func(index distsys.TLAValue) (resources.TCPMailboxKind, string) { switch index.AsNumber() { case 0: - return archetype_resources.TCPMailboxesRemote, "localhost:8001" + return resources.TCPMailboxesRemote, "localhost:8001" case 1: - return archetype_resources.TCPMailboxesRemote, "localhost:8002" + return resources.TCPMailboxesRemote, "localhost:8002" case 2: - return archetype_resources.TCPMailboxesLocal, "localhost:8003" + return resources.TCPMailboxesLocal, "localhost:8003" default: panic(fmt.Errorf("unknown mailbox index %v", index)) } })) - instream := ctx.EnsureArchetypeResourceByName("instream", archetype_resources.InputChannelResourceMaker(requestChannel)) - outstream := ctx.EnsureArchetypeResourceByName("outstream", archetype_resources.OutputChannelResourceMaker(responseChannel)) + instream := ctx.EnsureArchetypeResourceByName("instream", resources.InputChannelResourceMaker(requestChannel)) + outstream := ctx.EnsureArchetypeResourceByName("outstream", resources.OutputChannelResourceMaker(responseChannel)) err := AClient(ctx, self, constants, mailboxes, instream, outstream) if err != nil { panic(err) From e0e5085eb90dff0cf97cf119b9c029dc3113b5ec Mon Sep 17 00:00:00 2001 From: fhackett Date: Mon, 26 Jul 2021 19:01:03 -0700 Subject: [PATCH 24/27] Harden tests; fix bugs in channel and TCP resources --- distsys/mpcalctx.go | 9 +- distsys/resources/channels.go | 12 +-- distsys/resources/tcpmailboxes.go | 88 +++++++++---------- .../general/dqueue.tla.gotests/dqueue_test.go | 20 +++-- .../load_balancer_test.go | 67 +++++++------- 5 files changed, 101 insertions(+), 95 deletions(-) diff --git a/distsys/mpcalctx.go b/distsys/mpcalctx.go index af1e32a14..713db9cb0 100644 --- a/distsys/mpcalctx.go +++ b/distsys/mpcalctx.go @@ -17,11 +17,15 @@ type ArchetypeResourceHandle struct { // a semantic path into the tree of resources stored in MPCalContext // the type TLAValue is used because it is easy to use as an immutable.Map key, and resource indices are TLAValue anyway // in general, this can take two forms: - // - <<"named_resource_name", index_1, ...>> - // - <<... stack frame info, index_1, ...>> \* in the case where the resource is local, and possible part of a procedure call + // - "named_resource_name" \* named resources are user-defined and live in a flat namespace + // - <<... stack_index, ...>> \* in the case where the resource is local, and possibly part of a recursive procedure call path TLAValue } +func (handle ArchetypeResourceHandle) String() string { + return handle.path.String() +} + // ArchetypeResourceMaker encapsulates how a specific kind of ArchetypeResource is created. // At its simplest, Make() should produce a fresh instance, and Configure will then be called on that instance // in order to do any further configuration to it. @@ -183,6 +187,7 @@ func (ctx *MPCalContext) Commit() (err error) { // same as above, run all the commit processes async var nonTrivialCommits []chan struct{} for _, resHandle := range ctx.dirtyResourceHandles { + //fmt.Printf("-- commit: %v\n", resHandle) ch := ctx.getResourceByHandle(resHandle).Commit() if ch != nil { nonTrivialCommits = append(nonTrivialCommits, ch) diff --git a/distsys/resources/channels.go b/distsys/resources/channels.go index 7d4e13402..6f6e9e962 100644 --- a/distsys/resources/channels.go +++ b/distsys/resources/channels.go @@ -10,8 +10,8 @@ import ( // to the channel. type InputChannelResource struct { distsys.ArchetypeResourceLeafMixin - channel <-chan distsys.TLAValue - buffer []distsys.TLAValue + channel <-chan distsys.TLAValue + buffer, backlogBuffer []distsys.TLAValue } var _ distsys.ArchetypeResource = &InputChannelResource{} @@ -29,6 +29,7 @@ func InputChannelResourceMaker(channel <-chan distsys.TLAValue) distsys.Archetyp } func (res *InputChannelResource) Abort() chan struct{} { + res.buffer = append(res.backlogBuffer, res.buffer...) return nil } @@ -37,7 +38,7 @@ func (res *InputChannelResource) PreCommit() chan error { } func (res *InputChannelResource) Commit() chan struct{} { - res.buffer = nil + res.backlogBuffer = nil return nil } @@ -45,12 +46,13 @@ func (res *InputChannelResource) ReadValue() (distsys.TLAValue, error) { if len(res.buffer) > 0 { value := res.buffer[0] res.buffer = res.buffer[1:] + res.backlogBuffer = append(res.backlogBuffer, value) return value, nil } select { case value := <-res.channel: - res.buffer = append(res.buffer, value) + res.backlogBuffer = append(res.backlogBuffer, value) return value, nil case <-time.After(time.Millisecond * 20): return distsys.TLAValue{}, distsys.ErrCriticalSectionAborted @@ -104,7 +106,7 @@ func (res *OutputChannelResource) Commit() chan struct{} { } func (res *OutputChannelResource) ReadValue() (distsys.TLAValue, error) { - panic(fmt.Errorf("attempted to read from an input channel resource")) + panic(fmt.Errorf("attempted to read from an output channel resource")) } func (res *OutputChannelResource) WriteValue(value distsys.TLAValue) error { diff --git a/distsys/resources/tcpmailboxes.go b/distsys/resources/tcpmailboxes.go index b537f2387..447497a55 100644 --- a/distsys/resources/tcpmailboxes.go +++ b/distsys/resources/tcpmailboxes.go @@ -4,7 +4,6 @@ import ( "encoding/gob" "fmt" "github.com/UBC-NSS/pgo/distsys" - "log" "net" "time" ) @@ -61,13 +60,13 @@ func tcpMailboxesLocalArchetypeResourceMaker(listenAddr string) distsys.Archetyp msgChannel := make(chan distsys.TLAValue, tcpMailboxesReceiveChannelSize) listener, err := net.Listen("tcp", listenAddr) if err != nil { - log.Fatalf("could not listen on address %s", listenAddr) + panic(fmt.Errorf("could not listen on address %s: %w", listenAddr, err)) } go func() { for { conn, err := listener.Accept() if err != nil { - log.Fatalf("error listening on %s", listenAddr) + panic(fmt.Errorf("error listening on %s: %w", listenAddr, err)) } go func() { var err error @@ -77,7 +76,7 @@ func tcpMailboxesLocalArchetypeResourceMaker(listenAddr string) distsys.Archetyp hasBegun := false for { if err != nil { - log.Printf("network error: %s", err.Error()) + fmt.Printf("network error, dropping connection: %s", err.Error()) break } var tag int @@ -85,11 +84,10 @@ func tcpMailboxesLocalArchetypeResourceMaker(listenAddr string) distsys.Archetyp if err != nil { continue } + switch tag { case tcpNetworkBegin: - if localBuffer != nil { - localBuffer = nil - } + localBuffer = nil hasBegun = true case tcpNetworkValue: var value distsys.TLAValue @@ -104,39 +102,29 @@ func tcpMailboxesLocalArchetypeResourceMaker(listenAddr string) distsys.Archetyp continue } case tcpNetworkCommit: - // when crash-proofing, we need a way to identify repeat commits - // _when an old commit was successful but didn't persist due to crash_ - // could be done by: - // - send a unique incrementing counter on pre-commit - // - commit-er sends this id on commit, and we store this commit attempt in a persistent set - // alongside the buffer itself - // - receiving two commits for the same id can be detected by looking in the set, in which - // case do nothing and reply that the thing is done. - // - starting a new critical section sends the id of the remote's last commit, which - // indicates that commit was successful, and that the id can be removed from the set if !hasBegun { - err = encoder.Encode(true) - if err != nil { - continue - } - } else { - // FIXME: this is weak to restarts, but fixing that without proper context is really hard - // at least, in this case the msgChannel will function as a rate limiter, so - // crash-free operation shouldn't do anything weird - for _, elem := range localBuffer { - msgChannel <- elem - } - err = encoder.Encode(false) - if err != nil { - continue - } - hasBegun = false + panic("a correct TCP mailbox exchange must always start with tcpMailboxBegin") + } + // FIXME: this is weak to restarts, but fixing that without proper context is really hard + // at least, in this case the msgChannel will function as a rate limiter, so + // crash-free operation shouldn't do anything weird + + // a restart-proof method would take advantage of TCP necessarily dropping the connection, + // thus ending this connection, and log enough that everything important can be recovered + err = encoder.Encode(false) + if err != nil { + continue } + for _, elem := range localBuffer { + msgChannel <- elem + } + localBuffer = nil + hasBegun = false } } err = conn.Close() if err != nil { - log.Printf("error closing connection: %s", err.Error()) + fmt.Printf("error closing connection: %v", err) } }() } @@ -149,7 +137,7 @@ func tcpMailboxesLocalArchetypeResourceMaker(listenAddr string) distsys.Archetyp } func (res *tcpMailboxesLocalArchetypeResource) Abort() chan struct{} { - res.readBacklog = append(res.readBacklog, res.readsInProgress...) + res.readBacklog = append(res.readsInProgress, res.readBacklog...) res.readsInProgress = nil return nil } @@ -167,8 +155,9 @@ func (res *tcpMailboxesLocalArchetypeResource) ReadValue() (distsys.TLAValue, er // if a critical section previously aborted, already-read values will be here if len(res.readBacklog) > 0 { value := res.readBacklog[0] - res.readBacklog[0] = distsys.TLAValue{} + res.readBacklog[0] = distsys.TLAValue{} // ensure this TLAValue is null, otherwise it will dangle and prevent potential GC res.readBacklog = res.readBacklog[1:] + res.readsInProgress = append(res.readsInProgress, value) return value, nil } @@ -211,7 +200,8 @@ func (res *tcpMailboxesRemoteArchetypeResource) ensureConnection() error { var err error res.conn, err = net.Dial("tcp", res.dialAddr) if err != nil { - log.Printf("failed to dial %s, aborting after 50ms: %v", res.dialAddr, err) + res.conn, res.connEncoder, res.connDecoder = nil, nil, nil + fmt.Printf("failed to dial %s, aborting after 50ms: %v", res.dialAddr, err) time.Sleep(tcpMailboxesConnectionDroppedRetryDelay) return distsys.ErrCriticalSectionAborted } @@ -223,6 +213,7 @@ func (res *tcpMailboxesRemoteArchetypeResource) ensureConnection() error { func (res *tcpMailboxesRemoteArchetypeResource) Abort() chan struct{} { // nothing to do; the remote end tolerates just starting over with no explanation + res.inCriticalSection = false // but note to ourselves that we are starting over, so we re-send the begin record return nil } @@ -231,10 +222,19 @@ func (res *tcpMailboxesRemoteArchetypeResource) PreCommit() chan error { go func() { var err error handleError := func() { - log.Printf("network error while performing pre-commit handshake, aborting: %v", err) + fmt.Printf("network error while performing pre-commit handshake, aborting: %v", err) res.conn = nil ch <- distsys.ErrCriticalSectionAborted } + // be resilient to somehow reaching this without any sends + if !res.inCriticalSection { + res.inCriticalSection = true + err = res.connEncoder.Encode(tcpNetworkBegin) + if err != nil { + handleError() + return + } + } err = res.connEncoder.Encode(tcpNetworkPreCommit) if err != nil { handleError() @@ -258,13 +258,13 @@ func (res *tcpMailboxesRemoteArchetypeResource) Commit() chan struct{} { outerLoop: for { if err != nil { - log.Printf("network error during commit, resetting: %v", err) - res.conn = nil + panic(fmt.Errorf("network error during commit: %s", err)) } err = res.ensureConnection() if err != nil { continue outerLoop } + err = res.connEncoder.Encode(tcpNetworkCommit) if err != nil { continue outerLoop @@ -277,6 +277,7 @@ func (res *tcpMailboxesRemoteArchetypeResource) Commit() chan struct{} { if shouldResend { panic("resending is not implemented") } + res.inCriticalSection = false ch <- struct{}{} return } @@ -291,7 +292,7 @@ func (res *tcpMailboxesRemoteArchetypeResource) ReadValue() (distsys.TLAValue, e func (res *tcpMailboxesRemoteArchetypeResource) WriteValue(value distsys.TLAValue) error { var err error handleError := func() error { - log.Printf("network error during remote value write, aborting: %v", err) + fmt.Printf("network error during remote value write, aborting: %v", err) res.conn = nil return distsys.ErrCriticalSectionAborted } @@ -301,6 +302,7 @@ func (res *tcpMailboxesRemoteArchetypeResource) WriteValue(value distsys.TLAValu return err } if !res.inCriticalSection { + res.inCriticalSection = true err = res.connEncoder.Encode(tcpNetworkBegin) if err != nil { return handleError() @@ -310,9 +312,7 @@ func (res *tcpMailboxesRemoteArchetypeResource) WriteValue(value distsys.TLAValu if err != nil { return handleError() } - addressableValue := new(distsys.TLAValue) - *addressableValue = value - err = res.connEncoder.Encode(addressableValue) + err = res.connEncoder.Encode(&value) if err != nil { return handleError() } diff --git a/test/files/general/dqueue.tla.gotests/dqueue_test.go b/test/files/general/dqueue.tla.gotests/dqueue_test.go index 1d64c2c3f..4cd841f47 100644 --- a/test/files/general/dqueue.tla.gotests/dqueue_test.go +++ b/test/files/general/dqueue.tla.gotests/dqueue_test.go @@ -5,21 +5,20 @@ import ( "github.com/UBC-NSS/pgo/distsys" "github.com/UBC-NSS/pgo/distsys/resources" "testing" + "time" ) func TestNUM_NODES(t *testing.T) { result := NUM_NODES(Constants{NUM_CONSUMERS: distsys.NewTLANumber(12)}) if result.AsNumber() != 13 { - t.Errorf("NUM_CONSUMERS should have yielded 13, got %v", result) + t.Errorf("NUM_CONSUMERS(12) should have yielded 13, got %v", result) } } func TestProducerConsumer(t *testing.T) { - producerCtx := distsys.NewMPCalContext() producerSelf := distsys.NewTLANumber(1) producerInputChannel := make(chan distsys.TLAValue, 3) - consumerCtx := distsys.NewMPCalContext() consumerSelf := distsys.NewTLANumber(2) consumerOutputChannel := make(chan distsys.TLAValue, 3) @@ -28,7 +27,8 @@ func TestProducerConsumer(t *testing.T) { } go func() { - network := producerCtx.EnsureArchetypeResourceByName("network", resources.TCPMailboxesArchetypeResourceMaker(func(index distsys.TLAValue) (resources.TCPMailboxKind, string) { + ctx := distsys.NewMPCalContext() + network := ctx.EnsureArchetypeResourceByName("network", resources.TCPMailboxesArchetypeResourceMaker(func(index distsys.TLAValue) (resources.TCPMailboxKind, string) { switch index.AsNumber() { case 1: return resources.TCPMailboxesLocal, "localhost:8001" @@ -38,15 +38,16 @@ func TestProducerConsumer(t *testing.T) { panic(fmt.Errorf("unknown mailbox index %v", index)) } })) - s := producerCtx.EnsureArchetypeResourceByName("s", resources.InputChannelResourceMaker(producerInputChannel)) - err := AProducer(producerCtx, producerSelf, constants, network, s) + s := ctx.EnsureArchetypeResourceByName("s", resources.InputChannelResourceMaker(producerInputChannel)) + err := AProducer(ctx, producerSelf, constants, network, s) if err != nil { panic(err) } }() go func() { - network := consumerCtx.EnsureArchetypeResourceByName("network", resources.TCPMailboxesArchetypeResourceMaker(func(index distsys.TLAValue) (resources.TCPMailboxKind, string) { + ctx := distsys.NewMPCalContext() + network := ctx.EnsureArchetypeResourceByName("network", resources.TCPMailboxesArchetypeResourceMaker(func(index distsys.TLAValue) (resources.TCPMailboxKind, string) { switch index.AsNumber() { case 1: return resources.TCPMailboxesRemote, "localhost:8001" @@ -56,8 +57,8 @@ func TestProducerConsumer(t *testing.T) { panic(fmt.Errorf("unknown mailbox index %v", index)) } })) - proc := consumerCtx.EnsureArchetypeResourceByName("proc", resources.OutputChannelResourceMaker(consumerOutputChannel)) - err := AConsumer(consumerCtx, consumerSelf, constants, network, proc) + proc := ctx.EnsureArchetypeResourceByName("proc", resources.OutputChannelResourceMaker(consumerOutputChannel)) + err := AConsumer(ctx, consumerSelf, constants, network, proc) if err != nil { panic(err) } @@ -74,6 +75,7 @@ func TestProducerConsumer(t *testing.T) { consumedValues := []distsys.TLAValue{<-consumerOutputChannel, <-consumerOutputChannel, <-consumerOutputChannel} close(consumerOutputChannel) + time.Sleep(100 * time.Millisecond) if len(consumedValues) != len(producedValues) || !consumedValues[0].Equal(producedValues[0]) || !consumedValues[1].Equal(producedValues[1]) || !consumedValues[2].Equal(producedValues[2]) { t.Errorf("Consumed values %v did not match produced values %v", consumedValues, producedValues) diff --git a/test/files/general/load_balancer.tla.gotests/load_balancer_test.go b/test/files/general/load_balancer.tla.gotests/load_balancer_test.go index f18d53734..9c48327d2 100644 --- a/test/files/general/load_balancer.tla.gotests/load_balancer_test.go +++ b/test/files/general/load_balancer.tla.gotests/load_balancer_test.go @@ -39,21 +39,27 @@ func TestOneServerOneClient(t *testing.T) { panic(err) } - go func() { - ctx := distsys.NewMPCalContext() - self := distsys.NewTLANumber(0) - mailboxes := ctx.EnsureArchetypeResourceByName("mailboxes", resources.TCPMailboxesArchetypeResourceMaker(func(index distsys.TLAValue) (resources.TCPMailboxKind, string) { + makeAddressFn := func(ownId int) func(index distsys.TLAValue) (resources.TCPMailboxKind, string) { + return func(index distsys.TLAValue) (resources.TCPMailboxKind, string) { + kind := [3]resources.TCPMailboxKind{resources.TCPMailboxesRemote, resources.TCPMailboxesRemote, resources.TCPMailboxesRemote} + kind[ownId] = resources.TCPMailboxesLocal switch index.AsNumber() { case 0: - return resources.TCPMailboxesLocal, "localhost:8001" + return kind[0], "localhost:8001" case 1: - return resources.TCPMailboxesRemote, "localhost:8002" + return kind[1], "localhost:8002" case 2: - return resources.TCPMailboxesRemote, "localhost:8003" + return kind[2], "localhost:8003" default: panic(fmt.Errorf("unknown mailbox index %v", index)) } - })) + } + } + + go func() { + ctx := distsys.NewMPCalContext() + self := distsys.NewTLANumber(0) + mailboxes := ctx.EnsureArchetypeResourceByName("mailboxes", resources.TCPMailboxesArchetypeResourceMaker(makeAddressFn(0))) err := ALoadBalancer(ctx, self, constants, mailboxes) if err != nil { panic(err) @@ -63,18 +69,7 @@ func TestOneServerOneClient(t *testing.T) { go func() { ctx := distsys.NewMPCalContext() self := distsys.NewTLANumber(1) - mailboxes := ctx.EnsureArchetypeResourceByName("mailboxes", resources.TCPMailboxesArchetypeResourceMaker(func(index distsys.TLAValue) (resources.TCPMailboxKind, string) { - switch index.AsNumber() { - case 0: - return resources.TCPMailboxesRemote, "localhost:8001" - case 1: - return resources.TCPMailboxesLocal, "localhost:8002" - case 2: - return resources.TCPMailboxesRemote, "localhost:8003" - default: - panic(fmt.Errorf("unknown mailbox index %v", index)) - } - })) + mailboxes := ctx.EnsureArchetypeResourceByName("mailboxes", resources.TCPMailboxesArchetypeResourceMaker(makeAddressFn(1))) filesystem := ctx.EnsureArchetypeResourceByName("filesystem", resources.FilesystemArchetypeResourceMaker(tempDir)) err := AServer(ctx, self, constants, mailboxes, filesystem) if err != nil { @@ -87,18 +82,7 @@ func TestOneServerOneClient(t *testing.T) { go func() { ctx := distsys.NewMPCalContext() self := distsys.NewTLANumber(2) - mailboxes := ctx.EnsureArchetypeResourceByName("mailboxes", resources.TCPMailboxesArchetypeResourceMaker(func(index distsys.TLAValue) (resources.TCPMailboxKind, string) { - switch index.AsNumber() { - case 0: - return resources.TCPMailboxesRemote, "localhost:8001" - case 1: - return resources.TCPMailboxesRemote, "localhost:8002" - case 2: - return resources.TCPMailboxesLocal, "localhost:8003" - default: - panic(fmt.Errorf("unknown mailbox index %v", index)) - } - })) + mailboxes := ctx.EnsureArchetypeResourceByName("mailboxes", resources.TCPMailboxesArchetypeResourceMaker(makeAddressFn(2))) instream := ctx.EnsureArchetypeResourceByName("instream", resources.InputChannelResourceMaker(requestChannel)) outstream := ctx.EnsureArchetypeResourceByName("outstream", resources.OutputChannelResourceMaker(responseChannel)) err := AClient(ctx, self, constants, mailboxes, instream, outstream) @@ -124,10 +108,23 @@ func TestOneServerOneClient(t *testing.T) { for i := range requestResponsePairs { requestChannel <- requestResponsePairs[i].Request } - for i := range requestResponsePairs { + var receivedValues []distsys.TLAValue + for range requestResponsePairs { response := <-responseChannel - if !response.Equal(requestResponsePairs[i].Response) { - t.Fatalf("actual response %v to request %v did not equal expected response %v", response, requestResponsePairs[i].Request, requestResponsePairs[i].Response) + receivedValues = append(receivedValues, response) + } + close(responseChannel) + time.Sleep(100 * time.Millisecond) // make sure the model isn't replying more than necessary + // if so, it will crash due to the channel being closed, assuming it would reply again within 100ms + + // compare received values + for i, receivedValue := range receivedValues { + if !requestResponsePairs[i].Response.Equal(receivedValue) { + var expectedValues []distsys.TLAValue + for _, pair := range requestResponsePairs { + expectedValues = append(expectedValues, pair.Response) + } + t.Fatalf("expected received values %v do not match actual received values %v", expectedValues, receivedValues) } } } From 44da44d42081b366f127b634013262abc4c5cdc5 Mon Sep 17 00:00:00 2001 From: fhackett Date: Tue, 27 Jul 2021 15:51:44 -0700 Subject: [PATCH 25/27] Document invariants followed in tcpmailboxes.go --- distsys/resources/tcpmailboxes.go | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/distsys/resources/tcpmailboxes.go b/distsys/resources/tcpmailboxes.go index 447497a55..a13e446a2 100644 --- a/distsys/resources/tcpmailboxes.go +++ b/distsys/resources/tcpmailboxes.go @@ -31,6 +31,36 @@ const ( tcpMailboxesConnectionDroppedRetryDelay = 50 * time.Millisecond // TODO: same ) +// TCPMailboxesArchetypeResourceMaker produces a distsys.ArchetypeResourceMaker for a collection of TCP mailboxes. +// Each individual mailbox will match the following mapping macro, assuming exactly one process "reads" from it: +// +// mapping macro TCPChannel { +// read { +// await Len($variable) > 0; +// with (msg = Head($variable)) { +// $variable := Tail($variable); +// yield msg; +// }; +// } +// +// write { +// await Len($variable) < BUFFER_SIZE; +// yield Append($variable, $value); +// } +// } +// +// As is shown above, each mailbox should be a fully reliable, ordered channel, which these resources approximate +// via a lightweight TCP-based protocol optimised for optimistic data transmission. While the protocol should be +// extended to support reliability under crash recovery in the future, this behaviour is currently a stub. +// +// addressMappingFn is responsible for translating the index, as in network[index] from distsys.TLAValue to a pair of +// TCPMailboxKind and address string, where the address string would be appropriate to pass to net.Listen("tcp", ...) +// or net.Dial("tcp", ...). It should return TCPMailboxesLocal if this node is to be the only listener, and it should +// return TCPMailboxesRemote if the mailbox is remote and should be dialed. This could potentially allow unusual setups +// where a single process "owns" more than one mailbox. +// +// Note that BUFFER_SIZE is currently fixed to internal constant tcpMailboxesReceiveChannelSize, although precise numbers of +// in-flight messages may slightly exceed this number, as "reception" speculatively accepts one commit of messages before rate-limiting. func TCPMailboxesArchetypeResourceMaker(addressMappingFn func(distsys.TLAValue) (TCPMailboxKind, string)) distsys.ArchetypeResourceMaker { return IncrementalArchetypeMapResourceMaker(func(index distsys.TLAValue) distsys.ArchetypeResourceMaker { tpe, addr := addressMappingFn(index) From e7c552aff28640ee0e7f71f2d1cdca7d462cb902 Mon Sep 17 00:00:00 2001 From: fhackett Date: Tue, 27 Jul 2021 21:47:41 -0700 Subject: [PATCH 26/27] Implement more review recommendations --- .../{incrementalmap.go => incmap.go} | 9 +- distsys/resources/tcpmailboxes.go | 210 +++++++++++------- 2 files changed, 134 insertions(+), 85 deletions(-) rename distsys/resources/{incrementalmap.go => incmap.go} (84%) diff --git a/distsys/resources/incrementalmap.go b/distsys/resources/incmap.go similarity index 84% rename from distsys/resources/incrementalmap.go rename to distsys/resources/incmap.go index 848b4d8d8..adc1c53cc 100644 --- a/distsys/resources/incrementalmap.go +++ b/distsys/resources/incmap.go @@ -8,15 +8,20 @@ import ( // A generic map resource, with hooks to programmatically realize child resources during execution // ---------------------------------------------------------------------------------------------------------------- +// FillFn maps from an index of a given map resource into a distsys.ArchetypeResourceMaker for the resource +// intended at that location. It is assumed that this mapping is stable, in that, for the same index, a maker for +// a resource with the same behaviour will be returned, no matter when the function is called. +type FillFn func(index distsys.TLAValue) distsys.ArchetypeResourceMaker + type IncrementalArchetypeMapResource struct { distsys.ArchetypeResourceMapMixin realizedMap *immutable.Map - fillFunction func(index distsys.TLAValue) distsys.ArchetypeResourceMaker + fillFunction FillFn } var _ distsys.ArchetypeResource = &IncrementalArchetypeMapResource{} -func IncrementalArchetypeMapResourceMaker(fillFunction func(index distsys.TLAValue) distsys.ArchetypeResourceMaker) distsys.ArchetypeResourceMaker { +func IncrementalArchetypeMapResourceMaker(fillFunction FillFn) distsys.ArchetypeResourceMaker { return distsys.ArchetypeResourceMakerStruct{ MakeFn: func() distsys.ArchetypeResource { return &IncrementalArchetypeMapResource{ diff --git a/distsys/resources/tcpmailboxes.go b/distsys/resources/tcpmailboxes.go index a13e446a2..2cc846cb7 100644 --- a/distsys/resources/tcpmailboxes.go +++ b/distsys/resources/tcpmailboxes.go @@ -4,6 +4,7 @@ import ( "encoding/gob" "fmt" "github.com/UBC-NSS/pgo/distsys" + "io" "net" "time" ) @@ -27,10 +28,18 @@ const ( const ( tcpMailboxesReceiveChannelSize = 100 // TODO: this should be a configuration option - tcpMailboxesSendTimeout = 20 * time.Millisecond // TODO: same as above + tcpMailboxesTCPTimeout = 1 * time.Second // TODO: same as above + tcpMailboxesReadTimeout = 20 * time.Millisecond // TODO: same tcpMailboxesConnectionDroppedRetryDelay = 50 * time.Millisecond // TODO: same ) +// AddressMappingFn is responsible for translating the index, as in network[index] from distsys.TLAValue to a pair of +// TCPMailboxKind and address string, where the address string would be appropriate to pass to net.Listen("tcp", ...) +// or net.Dial("tcp", ...). It should return TCPMailboxesLocal if this node is to be the only listener, and it should +// return TCPMailboxesRemote if the mailbox is remote and should be dialed. This could potentially allow unusual setups +// where a single process "owns" more than one mailbox. +type AddressMappingFn func(distsys.TLAValue) (TCPMailboxKind, string) + // TCPMailboxesArchetypeResourceMaker produces a distsys.ArchetypeResourceMaker for a collection of TCP mailboxes. // Each individual mailbox will match the following mapping macro, assuming exactly one process "reads" from it: // @@ -49,34 +58,29 @@ const ( // } // } // -// As is shown above, each mailbox should be a fully reliable, ordered channel, which these resources approximate +// As is shown above, each mailbox should be a fully reliable FIFO channel, which these resources approximated // via a lightweight TCP-based protocol optimised for optimistic data transmission. While the protocol should be // extended to support reliability under crash recovery in the future, this behaviour is currently a stub. // -// addressMappingFn is responsible for translating the index, as in network[index] from distsys.TLAValue to a pair of -// TCPMailboxKind and address string, where the address string would be appropriate to pass to net.Listen("tcp", ...) -// or net.Dial("tcp", ...). It should return TCPMailboxesLocal if this node is to be the only listener, and it should -// return TCPMailboxesRemote if the mailbox is remote and should be dialed. This could potentially allow unusual setups -// where a single process "owns" more than one mailbox. -// // Note that BUFFER_SIZE is currently fixed to internal constant tcpMailboxesReceiveChannelSize, although precise numbers of // in-flight messages may slightly exceed this number, as "reception" speculatively accepts one commit of messages before rate-limiting. -func TCPMailboxesArchetypeResourceMaker(addressMappingFn func(distsys.TLAValue) (TCPMailboxKind, string)) distsys.ArchetypeResourceMaker { +func TCPMailboxesArchetypeResourceMaker(addressMappingFn AddressMappingFn) distsys.ArchetypeResourceMaker { return IncrementalArchetypeMapResourceMaker(func(index distsys.TLAValue) distsys.ArchetypeResourceMaker { - tpe, addr := addressMappingFn(index) - switch tpe { + typ, addr := addressMappingFn(index) + switch typ { case TCPMailboxesLocal: return tcpMailboxesLocalArchetypeResourceMaker(addr) case TCPMailboxesRemote: return tcpMailboxesRemoteArchetypeResourceMaker(addr) default: - panic(fmt.Errorf("invalid TCP mailbox type %d for address %s: expected local or remote, which are %d or %d", tpe, addr, TCPMailboxesLocal, TCPMailboxesRemote)) + panic(fmt.Errorf("invalid TCP mailbox type %d for address %s: expected local or remote, which are %d or %d", typ, addr, TCPMailboxesLocal, TCPMailboxesRemote)) } }) } type tcpMailboxesLocalArchetypeResource struct { distsys.ArchetypeResourceLeafMixin + listenAddr string msgChannel chan distsys.TLAValue readBacklog []distsys.TLAValue @@ -92,73 +96,11 @@ func tcpMailboxesLocalArchetypeResourceMaker(listenAddr string) distsys.Archetyp if err != nil { panic(fmt.Errorf("could not listen on address %s: %w", listenAddr, err)) } - go func() { - for { - conn, err := listener.Accept() - if err != nil { - panic(fmt.Errorf("error listening on %s: %w", listenAddr, err)) - } - go func() { - var err error - encoder := gob.NewEncoder(conn) - decoder := gob.NewDecoder(conn) - var localBuffer []distsys.TLAValue - hasBegun := false - for { - if err != nil { - fmt.Printf("network error, dropping connection: %s", err.Error()) - break - } - var tag int - err = decoder.Decode(&tag) - if err != nil { - continue - } - - switch tag { - case tcpNetworkBegin: - localBuffer = nil - hasBegun = true - case tcpNetworkValue: - var value distsys.TLAValue - err = decoder.Decode(&value) - if err != nil { - continue - } - localBuffer = append(localBuffer, value) - case tcpNetworkPreCommit: - err = encoder.Encode(struct{}{}) - if err != nil { - continue - } - case tcpNetworkCommit: - if !hasBegun { - panic("a correct TCP mailbox exchange must always start with tcpMailboxBegin") - } - // FIXME: this is weak to restarts, but fixing that without proper context is really hard - // at least, in this case the msgChannel will function as a rate limiter, so - // crash-free operation shouldn't do anything weird - - // a restart-proof method would take advantage of TCP necessarily dropping the connection, - // thus ending this connection, and log enough that everything important can be recovered - err = encoder.Encode(false) - if err != nil { - continue - } - for _, elem := range localBuffer { - msgChannel <- elem - } - localBuffer = nil - hasBegun = false - } - } - err = conn.Close() - if err != nil { - fmt.Printf("error closing connection: %v", err) - } - }() - } - }() + res := &tcpMailboxesLocalArchetypeResource{ + listenAddr: listenAddr, + msgChannel: msgChannel, + } + go res.listen(listener) return &tcpMailboxesLocalArchetypeResource{ msgChannel: msgChannel, @@ -166,6 +108,76 @@ func tcpMailboxesLocalArchetypeResourceMaker(listenAddr string) distsys.Archetyp }) } +func (res *tcpMailboxesLocalArchetypeResource) listen(listener net.Listener) { + for { + conn, err := listener.Accept() + if err != nil { + panic(fmt.Errorf("error listening on %s: %w", res.listenAddr, err)) + } + go res.handleConn(conn) + } +} + +func (res *tcpMailboxesLocalArchetypeResource) handleConn(conn net.Conn) { + var err error + encoder := gob.NewEncoder(conn) + decoder := gob.NewDecoder(conn) + var localBuffer []distsys.TLAValue + hasBegun := false + for { + if err != nil { + fmt.Printf("network error, dropping connection: %s", err.Error()) + break + } + var tag int + err = decoder.Decode(&tag) + if err != nil { + continue + } + + switch tag { + case tcpNetworkBegin: + localBuffer = nil + hasBegun = true + case tcpNetworkValue: + var value distsys.TLAValue + err = decoder.Decode(&value) + if err != nil { + continue + } + localBuffer = append(localBuffer, value) + case tcpNetworkPreCommit: + err = encoder.Encode(struct{}{}) + if err != nil { + continue + } + case tcpNetworkCommit: + if !hasBegun { + panic("a correct TCP mailbox exchange must always start with tcpMailboxBegin") + } + // FIXME: this is weak to restarts, but fixing that without proper context is really hard + // at least, in this case the msgChannel will function as a rate limiter, so + // crash-free operation shouldn't do anything weird + + // a restart-proof method would take advantage of TCP necessarily dropping the connection, + // thus ending this connection, and log enough that everything important can be recovered + err = encoder.Encode(false) + if err != nil { + continue + } + for _, elem := range localBuffer { + res.msgChannel <- elem + } + localBuffer = nil + hasBegun = false + } + } + err = conn.Close() + if err != nil { + fmt.Printf("error closing connection: %v", err) + } +} + func (res *tcpMailboxesLocalArchetypeResource) Abort() chan struct{} { res.readBacklog = append(res.readsInProgress, res.readBacklog...) res.readsInProgress = nil @@ -196,7 +208,7 @@ func (res *tcpMailboxesLocalArchetypeResource) ReadValue() (distsys.TLAValue, er case msg := <-res.msgChannel: res.readsInProgress = append(res.readsInProgress, msg) return msg, nil - case <-time.After(tcpMailboxesSendTimeout): + case <-time.After(tcpMailboxesReadTimeout): return distsys.TLAValue{}, distsys.ErrCriticalSectionAborted } } @@ -205,6 +217,36 @@ func (res *tcpMailboxesLocalArchetypeResource) WriteValue(value distsys.TLAValue panic(fmt.Errorf("attempted to write value %v to a local mailbox archetype resource", value)) } +type readWriterWithConnIdleTimeout struct { + conn net.Conn + timeout time.Duration +} + +var _ io.ReadWriter = &readWriterWithConnIdleTimeout{} + +func makeReadWriterWithConnIdleTimeout(conn net.Conn, timeout time.Duration) readWriterWithConnIdleTimeout { + return readWriterWithConnIdleTimeout{ + conn: conn, + timeout: timeout, + } +} + +func (rw readWriterWithConnIdleTimeout) Read(data []byte) (n int, err error) { + err = rw.conn.SetReadDeadline(time.Now().Add(rw.timeout)) + if err != nil { + panic(err) + } + return rw.conn.Read(data) +} + +func (rw readWriterWithConnIdleTimeout) Write(data []byte) (n int, err error) { + err = rw.conn.SetWriteDeadline(time.Now().Add(rw.timeout)) + if err != nil { + panic(err) + } + return rw.conn.Write(data) +} + type tcpMailboxesRemoteArchetypeResource struct { distsys.ArchetypeResourceLeafMixin dialAddr string @@ -228,15 +270,17 @@ func tcpMailboxesRemoteArchetypeResourceMaker(dialAddr string) distsys.Archetype func (res *tcpMailboxesRemoteArchetypeResource) ensureConnection() error { if res.conn == nil { var err error - res.conn, err = net.Dial("tcp", res.dialAddr) + res.conn, err = net.DialTimeout("tcp", res.dialAddr, tcpMailboxesTCPTimeout) if err != nil { res.conn, res.connEncoder, res.connDecoder = nil, nil, nil fmt.Printf("failed to dial %s, aborting after 50ms: %v", res.dialAddr, err) time.Sleep(tcpMailboxesConnectionDroppedRetryDelay) return distsys.ErrCriticalSectionAborted } - res.connEncoder = gob.NewEncoder(res.conn) - res.connDecoder = gob.NewDecoder(res.conn) + // res.conn is wrapped; don't try to use it directly, or you might miss resetting the deadline! + wrappedReaderWriter := makeReadWriterWithConnIdleTimeout(res.conn, tcpMailboxesTCPTimeout) + res.connEncoder = gob.NewEncoder(wrappedReaderWriter) + res.connDecoder = gob.NewDecoder(wrappedReaderWriter) } return nil } From e6b891bffa11a13a6f5489475c00b206abc0922d Mon Sep 17 00:00:00 2001 From: fhackett Date: Wed, 28 Jul 2021 16:00:37 -0700 Subject: [PATCH 27/27] Even more review comments; fix broken case for .String() of an empty TLA+ function in Go lib --- distsys/resources/channels.go | 4 +++- distsys/resources/filesystem.go | 3 ++- distsys/resources/tcpmailboxes.go | 34 +++++++++++++++++++------------ distsys/tlaplus.go | 5 +++++ distsys/tlaplus_test.go | 7 +++++++ 5 files changed, 38 insertions(+), 15 deletions(-) diff --git a/distsys/resources/channels.go b/distsys/resources/channels.go index 6f6e9e962..c94031148 100644 --- a/distsys/resources/channels.go +++ b/distsys/resources/channels.go @@ -6,6 +6,8 @@ import ( "time" ) +const inputChannelResourceReadTimout = 20 * time.Millisecond + // InputChannelResource wraps a native Go channel, such that an MPCal model might read what is written // to the channel. type InputChannelResource struct { @@ -54,7 +56,7 @@ func (res *InputChannelResource) ReadValue() (distsys.TLAValue, error) { case value := <-res.channel: res.backlogBuffer = append(res.backlogBuffer, value) return value, nil - case <-time.After(time.Millisecond * 20): + case <-time.After(inputChannelResourceReadTimout): return distsys.TLAValue{}, distsys.ErrCriticalSectionAborted } } diff --git a/distsys/resources/filesystem.go b/distsys/resources/filesystem.go index 334eb2774..18414836d 100644 --- a/distsys/resources/filesystem.go +++ b/distsys/resources/filesystem.go @@ -45,9 +45,11 @@ func (res *fileArchetypeResource) PreCommit() chan error { } func (res *fileArchetypeResource) Commit() chan struct{} { + res.cachedRead = nil if res.writePending != nil { doneCh := make(chan struct{}) go func() { + // FIXME: this is not atomic. see: https://github.com/natefinch/atomic and potential need for flush ops err := ioutil.WriteFile(path.Join(res.workingDirectory, res.subPath), []byte(*res.writePending), 0777) if err != nil { panic(fmt.Errorf("could not write file %s: %w", path.Join(res.workingDirectory, res.subPath), err)) @@ -57,7 +59,6 @@ func (res *fileArchetypeResource) Commit() chan struct{} { }() return doneCh } - res.cachedRead = nil return nil } diff --git a/distsys/resources/tcpmailboxes.go b/distsys/resources/tcpmailboxes.go index 2cc846cb7..551f8d853 100644 --- a/distsys/resources/tcpmailboxes.go +++ b/distsys/resources/tcpmailboxes.go @@ -43,20 +43,24 @@ type AddressMappingFn func(distsys.TLAValue) (TCPMailboxKind, string) // TCPMailboxesArchetypeResourceMaker produces a distsys.ArchetypeResourceMaker for a collection of TCP mailboxes. // Each individual mailbox will match the following mapping macro, assuming exactly one process "reads" from it: // -// mapping macro TCPChannel { -// read { -// await Len($variable) > 0; -// with (msg = Head($variable)) { -// $variable := Tail($variable); -// yield msg; -// }; -// } +// \* assuming initially that: +// \* $variable := [queue |-> <<>> (* empty buffer *), enabled |-> TRUE (* process running *)] // -// write { -// await Len($variable) < BUFFER_SIZE; -// yield Append($variable, $value); -// } -// } +// mapping macro LimitedBufferReliableFIFOLink { +// read { +// assert $variable.enabled; +// await Len($variable.queue) > 0; +// with (msg = Head($variable.queue)) { +// $variable.queue := Tail($variable.queue); +// yield msg; +// }; +// } +// +// write { +// await Len($variable.queue) < BUFFER_SIZE /\ $variable.enabled; +// yield [queue |-> Append($variable.queue, $value), enabled |-> $variable.enabled]; +// } +// } // // As is shown above, each mailbox should be a fully reliable FIFO channel, which these resources approximated // via a lightweight TCP-based protocol optimised for optimistic data transmission. While the protocol should be @@ -64,6 +68,10 @@ type AddressMappingFn func(distsys.TLAValue) (TCPMailboxKind, string) // // Note that BUFFER_SIZE is currently fixed to internal constant tcpMailboxesReceiveChannelSize, although precise numbers of // in-flight messages may slightly exceed this number, as "reception" speculatively accepts one commit of messages before rate-limiting. +// +// Note also that this protocol is not live, with respect to Commit. All other ops will recover from timeouts via aborts, +// which will not be visible and will not take infinitely long. Commit is the exception, as it _must complete_ for semantics +// to be preserved, or it would be possible to observe partial effects of critical sections. func TCPMailboxesArchetypeResourceMaker(addressMappingFn AddressMappingFn) distsys.ArchetypeResourceMaker { return IncrementalArchetypeMapResourceMaker(func(index distsys.TLAValue) distsys.ArchetypeResourceMaker { typ, addr := addressMappingFn(index) diff --git a/distsys/tlaplus.go b/distsys/tlaplus.go index 4238c1554..7a87e7d71 100644 --- a/distsys/tlaplus.go +++ b/distsys/tlaplus.go @@ -1051,6 +1051,11 @@ func (v *tlaValueFunction) Equal(other TLAValue) bool { } func (v *tlaValueFunction) String() string { + // special case the empty function; a concatenation of 0 functions looks like `()`, which doesn't parse + // but this trivially empty function expression should do the trick + if v.Map.Len() == 0 { + return "[x \\in {} |-> x]" + } builder := strings.Builder{} builder.WriteString("(") first := true diff --git a/distsys/tlaplus_test.go b/distsys/tlaplus_test.go index e3571e86a..148ad2542 100644 --- a/distsys/tlaplus_test.go +++ b/distsys/tlaplus_test.go @@ -26,6 +26,13 @@ func TestTLAModel(t *testing.T) { }, ExpectedResult: "FALSE", }, + { + Name: "[x \\in {} |-> x]", + Operation: func() TLAValue { + return NewTLARecord(nil) + }, + ExpectedResult: "[x \\in {} |-> x]", + }, } for _, test := range tests {

    l(`vJ1FW+a%nx@4b#Jj)2D@lTgWNRla20 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

    9v*R@bWUk=rYuTp;FZqeQziBUl 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

  • !ah?<2;Ys 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
    _mGK(%Jfu7e${ zu!~j2A&DoKbQXDwm^7M9a9@OXE~}}enhJ#gSn>^Dn;Ma`@?689A|%5#$#$((ZM>m- zXC$MRRCP{}xYL4ZJmg@pq5uJnEydae67o7c7}>fb##NN{#!YVOraJP~tfTw=9BvY< zd?s1Ad?nrdgsbD_i{Nh$S`%lIIj@d%gyv=OG#$n_VLDQH3u}LBfYGOVN6gBIQZBp9 z8h~KD`mu6g@S&$latc`3rIUJWEJ`?l+kNzw#krRIlHkB>pCX!{P%3LMJ4QT9(4-m2 zEnTn#CNP_vebJ>b!}5xxVg#C{*PF;w{P(ky*-F4Ay_l=BeayYk1@n#v&y8etAVZp4SDvLKOj?;D ziLfC)QOaznlFUqbGc~D^yDYofxA7b!sZf@zncMtqSiP*0oOZ;g-N&5t>SS_KSq!>s zEu$y`$-9NHIpTh0aW4M;?Scp+|+wJ$-pW zxWa{U^B5yb5cMc4%dxm-CsEJjc`#xtqL80KWBwE~(J`~e%i-?e(N8W+{?lI+9Fxs$Hpe)#KHB6!}&MU(Z%);8=Nxq)W8&YfCyB&w6LeB%e>V0`$Jz%qPdG{XlA#5(CsRMVcDomChv%=hm5KWX()aaQ|czW{1Cw zGWAN5?l7~)L}~+0*9AMaV3x|zoyd=KHr$N3HpZK++7I{Z7L6Rp@mQAR?=uKipCPIA zmBbJhB-h6Zx~gz;f6T0)9%)i@t!r9y#=MfGh3|}ts!*Zd5TKBFjm994 zqMNM}Gzv}l67Mxv#k=G@o4zBexU}emhk-0%at?XvB>NPG;jwFXlh|SAmbiCV=vRNX z(fPZba@-DKHL5hQPc=Iky|-K&Bhnu_Dihe*5Zj z2)+bUGo}5enNWsm`+E)iW6Pj8RQAyp8%czCubGSW{ba~cvFXaH1a&t{0$%U_#nh z9JjIiiv8=+kbj5+lidp^2G;Om+jBm5C~ruNHik^J7Ym5^dpVYRd(GlO#IaL+3=CRxB2) zZsTEf#|-`ZWrZrF0$eT%6JX5bH_u$ub6?cc2|Zgv_{|sp^=}=UBL|Se{bxyK(eUKAB+knzB8)vR`&J^4m&a z`6xo004pgsNa@GOU!TDy`a(~^hYPI60(rr4DG|AyviHd;kpQn?hyBmisIhb>9Z7^< zK_{ON`3Z`Vsr|fLaCDV<3JFFhL{f;++Mq=@<;kDE-}Go4Dqi9J*<|ItuEr_eJmLThB)jR zfU}`Zn4J`_?c#S*ukU6<*;b~rBsqiMUYX}U@Et;)(Dt$^ujSA74d=Bld^ptY+F7ox zJ<`PJU5Tw%V?jdioCt@fR10`bi%9OpTA?fa%#DTjxyN0#roJbiXDn)tn~q^;TFiQd zX0CMhkYSEU=V*tPD`Tk|?+`fZe;9)y`$RuSVfY!gQh`v7QKEL+WX4N_0UA{*XI>>C z=1n-|!j)n%H@oVXhgsSM0CU}fSh6)}xe5+eyT7=KRgtbY_I1|2;BO=m<&flJgDYQU zM{pDGI#U%fsQBz+sTeLi=07vn&P#fQ_LI|y*Z9jg2DxJhL z{8y2tGFmpD24PBobpncOiFiZnv!UbP1{8 zFitk=pFD2|@=r7KGka$``nMt=y#3r9eRt*oE_OsZ(PE|U;eoUH1n$e6;}NA$Y6n;c z%;0r1vMfp<_Q4Z=m&86*c@K5h zOO}DKN=%V-!IR*X@4<__fxVSdH#LTl+YhK&9}B_DKfeq7%Awc z-aqN15%-SmqI-(@!qudI*`;K`{!a1sYwF!E@;P@2|r)CL9_@+7G zP(>s6Rad{~jZP9X5*o(BZc6!BqGBdhw%SHRzSJ$uRv8ko^N>}(!O zg@%dpoVA=K9863gNB($3Ruk%s_f*^Q z_7`JUn}0qmC09JkFo6pw>*g*-O|=)C4#fRpj`stLKq7bZhj7gl9RN|ZQ@$a5oOJgg zUB;9MtSfVfZbcSvF>)g+PZIAi0s(*z$Iz?~lSBvWC(}_l1HhZfbfmMgg|Xx^;dDS{ z%MoV)ZP$_WF2{yCqi>lo>1(cxRT8)&6$^%(O5wTqH`N>5K~=3zu!&hXZJ! zrJ0VXiB?l6n~$)IR+F==#Gi%fDip5A;Wz4Wp$>=VBWBKZD&ewm*^>7TjcPDXtAaT?;J~Zqc z$kG@8N0f+yWiDPKj8A%>O9lyrTe5I7UPP1#$TAi`6wW79*b`3~&L?KtOs;_bf(7PI z_RSb(6+P6xr2}7~q*;u(h<3}Ec9U-bZ~4IDGWsO9et;pJTL73Cg}Wy{CG2G9JMf-6Wf}9nlf} zE@fIq?tuP+2{uda6xr7UjM00=4%dWN*6#ZOev;PD#v_OQPL_-${|UVH0aVbvK!OF( zwCqN5!hWX>OC|eC?lX!mYTjx9h*7m{MutS+#Z9xwb5LG*#cB-=oT>yse}b&vPvDLI z0)7b&MWz6|RWh`SMcYU0efq|lnsepM5VyLh(x^vsPRO z^Gm3+RNO*+lTc@^xC#CyvB*+!2PGgOZ^W^H{Z7Cgz2a){$#oyWoYjwX8a%{Y@dPC# zF=@QG4IdPfIbj>ah{EH{(BRdrcs%?vj_23&@eeC+4>l5E+m97t13}k)fVo_E-0|?h zxcohom;{5-;yHX|jP9sy8Y2^rGj{`K_w?~_(zv#7&kVRCwdyfgLL$50Hkwh8$C9~h^AWaXtsogZyY7#S z%ilmLN@S0ovl+m+?VpTKUPCEKWRINF8Q{3>%bQ!gL6iZfjNGdk6M1g=%#Ypz%YclA z?s<%vJhuRI>^F#VAfu6c8Dk;OEsJ@|TVOe`#?ZZpv6APO#$4kKq5@cBhh%3N3;=(l##P8)DY`&XEjq-S)G_ zA76#5fLF%uEsV=Nw?yVoue~3iChk8Ow|Qx>9{41O0j+!xRg$IL_W#5B~BMa zJ~6nI&V)p7M6B`$#zZ~=xRfsVe2)ND`6CYRb8_>{=>h&npn2vjIo~4-tNdv^kxvqC zi5qq7pF~_r_beixXxtL_48BJmR{6_WBA+1K5)a(iu7N1@PKMa7i71s$``E6&sD#c5 zBA?g~nL8c6$8W6i_s!ntkmi}Ec6ZBHsZRAR8z%mSgD0Cvv46sGDSat@&PB{KZ?ksm zezNQpUa7|VjYrLO&+$FNvL-w?-D8&cToWVw9l1t8evjPwiJN`Wqk#J!x}!z(o3U>S z=kk902;rxpXLE2wgCIF>_MVVDBqkHzQcxyz`KP`+zTxm(I2OLGpiJ0u-4JZgI2EC! zscT_mXNFR5=FZ`uOoZ}p2#k*;7D45VeKLH*C%Miz`lmvZ&}yiCV|>G~c{~w22Soc( ziipOZ!O+~~suHZ7vq72Y<;EczUU3P+>`^-lMEjMBgnid|$j;iO;)?dM3Z-Cr=!MeI zh2uYm$bTC!vCCyibvVs`zL=a1w*D1Iuh~_UGyx8-v%fCuqxM#FA4&)M24XZ7M zjX~o~@BH47z}Uj|=RmzgGy6OWT*75`t6CzTeZn@}kSX4#Le&&4Am^ZgKJJq&s8%js zesjn_(@8ml?Q+M!dTV;ez+V5IUr6ZOtr#)}e?y0+5{sWDNH}8_d}Kf*s`{plqWhH%`Io zakmdkT1 z4v{u{?PwMUCpU#ewT2Zk?$5XB)sbJ9{00{w)fx$A^^7DVg0Pe#2t)GFM!4E-eAIYJPXom6NskqgP zY%=M|V8*gd<=08VA9nR26m;PruW#rXQ4eoZ>{NzO&|6^A?IZ_M>lV9G<1aU479rtO zSIe|k8RBBX(!yQlmTy;cnlkk;JsDIPrM}WrSGGE^uNO0AR_AMO-ZA&+&>Jbj%P5KG zNJ4qsAzWTicZG@{bBa(Hgn6Pu@>8Dz2w~ej1sUNe>ZPmFu(0FlHLSDAdB>acVn zT-6QbkZ9Z^y%3euDQfcgrj!{ixFIZ{|592Yqz26{#Fx-rbI&GHNuJK1t$Krl#tTv< zE7Tx z9?fR5s=biv8vh+MD9LM>$13LdOYX9dpHVJ_+-xHuv3W` z;@jLWlNMlc?L zRNK*4DNOn1?{l~Jwx|*^E{7}W7HPy}u({9ZHM1ww)tV2$oyVr2Mc9bkX*WEk9}}eG z{KJk~b;}+L@H?oL7S7xsc7X0!2#LZy95qs9y!~2ZA7;#c@2Bj*oC4vDpRKrSuj=p$ zP<%4b5ED_VgGa!MJsn%;Joi@9lxwHTj>@}awZ(R1{W7cpO_b6QNp2uN{dk)^HVw)91NW5PlpaQKzY`xcmRfY! z!QyTfYBkt{Ic_B=(3kq{&Wu2%xPk+u1JBRsTf{#X=(W^i6{X#Jx{X(@)7r!IMm%SP z^H4}ik(RlZy6HR|~bQhRYT z`1FjTA^IMPHqJpX$CG<|E9$i^keQ zW^+7tdqs=?WJR9{dD`24Z0YKMBz|P=168b>W0ek2$l+pMY%+rD5O|kgmE*;t#Ig&@i=J69z{#n zm$)SehP9?Ubq&uEA~PAM9K}hnEMT-rk6KI>*^?kLwZ{si)G_$BeioLF{pg(+B><(H zmZ_Mfvbi;@AZ2a4mGa&Bm!qcB##YliW77s%wYR6tcv}eLz)J2C+6=h^RD0y~o=}2B z_o_c3p41Sf?iqkUG@I*jLF-bdrQFa~)}(KctDb|-jKXj&RdiD{E$`NVC*=3k;<1DV zhRcfsVxpxgh1_he7?onq!vUIXQt)+d$I~YNQ|8s%B)7*y zh5uh)bU|c$D~s&Uzb%Kv1b7@rBBdDhZ$*a4i5bRRq(f*~bRR_e*onJoB2#R<4%@Lg z_pL^m=tV{&aRuCWl8OtTR*ZL=g-OyT zw1e}a+FC8?ojWY$E$D(TD+=0rZEMmvRb12^Xj*FH#uy&W$IopYSaf_hbu)P_4tec} zOFU_kbVji-Rh9Faxio6Aj-1nQq5LT_c`_J~s5}9B32>{5_8~oZ z5_4KMwpK=~G`e)54!9FVf z66f2IC%nngpwh0Bft}#a&coM;K*ppotO?iTn?Uf4m&*!WC{9jxi}HYqalR+l>)+DC zS%hv|^JLq=oV$@}41>IGH1B#_Z4IrTh8qlX#*S08kH#^i$81?yb@om!i!^YXrc3gh z(Sd3lPs?p(d#&UVJ(zXQyf$6xO%q977bA=_4?B|1(DdCT%fj|)$9}HoC^NTEHd+zn zCTW$>e?LIKxO(x~__aa$F7JN5PpAY*c``fO$$w2LOeWIPdV0@i1C!{HwxqRQjCoSj zEH_xvsjy~ORvKhD9kdbVb~9HDjFOg#1+lnsZ$EcN1cHpR@o7Q|=vM2Mn16_HRib#U z(?L6af`)u%;eqso$buu(sU1vaNxN%vZMMYJUH_aZ?EguIi|7}N{8yBe6)o;>fefD? z@m~I39mC13CHx{ted$axD>qrd)KxzMSE|7et_Ks-=h`{=4d{AF7y9mBx>)S!4TXZCNlxNO&$nQQHIn_&d^5lqY z5a-!Lc9bq&BA?Wr=-RsE`blTtdLn~0eGG)*t&mZXtdLR8^+nEjF|HxCE~G4Ji+)xn ze%HZ#MLGNY%pBY?H7y{*N|YO&hh!AJzcgZm8MIuRM`-d4NjHbiCH1xeO3gI{?8edV z#_6JcSs$M((HaEo{*WQAK>epF;zbAx?wZ&6mA~T6glz{MbOX)u z3S9B;HGWQrw)g?ouA4HazkO;Oel3l{h%)UQUyzxyu#-z~CEAtUd$V9Z-+l)N@xBkV zuF+&AMV{7D}(#Wo* zf$zgT)gu%7gVj9G;@0Gh%bagx2>09plqDG=Hg*^G!S}jJtg_ROVRF_dj?-`Rr$G! zy`3_Bf=;Q+pV%fV_F4<&w|Q3f7p&+iK6jQ)wn{%Aj%#Kx#M4B}>*C{bsjz!E^L^tM$b)OzbRqgdMR=4~((a2($I=G&W`Bm6f1HPNh@%ZWLMrNq^4cz=%!<0s#b9+h+Tzm3v*w2`*<`AQS{YDK8( zcb7xc63u8Lms=drNt1BcbP*lcwhHKtNq?b!6OTLeq-_7^k)5^ugumuPEtm=EpNatL ze<<-}9ZZaD&HjIK!O`k3DmqIaRX{T(5i;=Cxgq3W^Zl>EYCAOiT|5;^(yx^C`Veex zM6)7jSZIsF2yW?x@=pVH?S)cno-%vQQt0@cbfj{#C$ju=R{qBvf4cmI+6%KLUDvZ+ za^gTJNCh)`Q~XEkSG-5-PZ_)pU66*9-^+}#A!uZys9|Ve${b0y#Z%v$>?ccWfxT$x zaQXKAsu(8mM;2}2cWin2kWx_8m=5__$D?5~dMqb0;BPZ~MugC!B zO=h42^>gztasR1A)EJxs)CPe=&Qe6mc!=zGCzH`*N%B50lKu%=>2L}Gn^Y~EL>yM3 z?oU+2;;7s-F1`(X8L@<$lO$)zK~rpAsZ*Lsu z`I6Id*!PB3AOoCF`lWzGhhE+@V1!_F2%R^R8^cg$t7j4OPyr5R)JO^*fN6f;?e8yM zU=r;0k<=!V+6fzOs-mwW6_&MQDe!@b1+4D=ma#vMlM1@#DdL?T%@?dzBT|*nE)w!P zOgl1iqcypPj4hNCuvV)!7m|G|a2>^FCzG+AD;s{qyOq(yrkaS;#OsFiqJrhsaDpKU z)^!9$+LTCGM%5*?>x>kJvm618iC<{og_vZ^flz^E4}HV+>u5%w2YRCd^OqeyXau7p z7U%?3!GVf8&DOBkW*{o__CH`(Pbk=w@gcmYv#5-_RSQ%`>Y0 zjAK^Q-_(p8$2*nI{B1SFnjH%~_dOuq;}5hvx{3oKAS$4j-IpN8P^`wr6OxndT%;s0 z1JB$^#;{Mio9#Ej)ZJnR-r@2opN;;n{1Bh%HfjC^6hsFjslK)6;J}YjOOa1snk#`f zDL3FV-=ovZK9(MID%PWEq~FNm4E?0$6f*J5mL`vS?zQ!g*k6^5{w)}{8)25e`mH3nANhduBIeUT0dEl{{!dYT1#5qR0 zB^$TIseG(9N-b93OvVL9!&1@d0^0DTlfzHk<2FQg_Y;)vIg0?3XptV=bd^l~W6#xK z7~1EFa#x5>%dUIMrbN~Y0}%C;hs7@>q&7%hgWwA=di}U0{ZKCm>M@p2ck+or20sx? zTJxrQ7WJ+=zZi7Ap=qD-kE+>f2l`pU#^iZ%jp?~4N=l{$`4EX+oj!7xKAj+0BXf90 z(U#g?kL!w90b?Wa_*ogZ9z475SUBkNJS7>I4walmJmLXUCo&!_QZ7w%N+;Ku-BEa6 zs~@0uq76@Y;$)vo5VUnkf~a?OZbr#HXdp`N?*jeZb;s+R%pC+OjD50pmOudpj2<9kxSL;*^0P&hxt##2% z{irYBB|7|jF*b+L1G}q(p;_}Wj|SxVs9&!W3;&Q<{gj%LL$-2_yBE8k9UgJrGvN|O z8`xD^kAbLX6gXIE^eEIrokSe@7T* zDoEks;GoeONoSOyx%eEiuFiHV ztOp6|4XS>;5UgpgSUCyUxe18}ozkU-?@La`yHEY=#M^_!N9k3WXK0yAx6iLONCws+H4@B;i;khbMO-~?T5RADbNo#a8UHmqP*}^y zbXvaV`-IoeZ#{#LVvTUR1Kp28yO2m-i=j}YZv!(V>FR8=h+Io((4>Hgii z;4m)#%af>Odu5>_n!6OEVyA_HWC+=Gh3?`ng8MFi{s%JpnNn>Wxfb$ozVx$$@qxhp z3v{B=-=g!jAXe8ZYNG^?b(yDSh0I$*!ewEbK8!1Oo~=mK5sHoY5BQlX&(|kvG4)J= z-h?z_R#P`M*Z~R)ws-f2y_TyHE|Ml(Oa>2YZNt#Zhn%jv$uO^w5!H+e{h$;B(-H%J zhK{CAMAhhL>0nr?$dALld{n2pG!m;pR%00?Iy+oVqTyf8bdY0E5c7d%5pbA&yTurq z-@SjIklfJ=QGOXdc+{~R&3eYFHTlfT-D=~I$MD9dCdJ1qd1D{3#c%4$*qInR#=L?c zW{zhuSIT$rSKwbTsS9djG9JvQPv!qOp5UJZq~sl3rTztz{tF;AGyOM+G)aBR1N~#t zp8ni#(_FTqqQ=~vkAAsERM9W+3-Qe;bav!+pFcaLcNeR~r*W|gnHJbAy>qoYAI

    zQZ&nn$S`ublFI9Rx5Z)mc)@CdU zsnk4K)D?JBYp2N7aJ+WFr+rRb*=*-EmbeMGhehXVk?GaaQ;CR=Pbja?h?%gjjqR_H z@3s&IwURXDH+P2Xd~+ERbc0(LE)ef}E;)p4hPp?6<{}-pe>kIUR(~$JPkq}D^50aF z{hiM3WM*I?Z)9v_Z)9y?^m~s&hSJujulzGwCDl02k%B}PKQ~04K|BZWyT28Ue!eWV zRn9bJ!LhSL8Z~j7o{K_pm#xSUZx6;MwvMaAbPORk`)C-`JHoVD=>iy+P23Re|0XMYLrwcQzj=*gMWa`E8g?r_HKu zL@o4H?#D@saUKCJyap5Uv2AH5-=$D=_<>=O*4Vv?rwZnQo}cv`h0@r4{hnIq!7`A( zCO)J7N+K_1HPgZ(^;gMdMR(;PRLcmWa4SyMJhCA8#>$?U8{Bty#Z`C+@)CQJ(}4y!Q)of6yU!pNZ8P*G5Y8g5P~)q%zhI%6(hhAMPmel zP)W=%;;>3y3inSp>=9e+WVNdwSouGcy#ssY;g%;_v2EM7ZQHhORVvy^#kOtRwo|dq zip`tT(>p0pg)+?mnL>l}5ZA9M=Y|*9bQfLirbE>FSGcgqS_!DMOOh5Bp4FJh zqj3WeteMsH@lveoy~e4-GvcdEgr;VdbayYba5u+aPw;(caV&^!OS5uA97R`;= zImgprWmE8V_K(2^xjHJ8;>5)$N^Zt&m?Yle@4rHQ$*JJ)Z6&nDY{@D-@m-AGZ;RZH z^zNxtuiJQc{?Ze?F1iNg-}eaAPb8I<$}G(Q(cKz%yBAuE_Yq|gFnaR4(2`iRx#ceJ z4~O{aoi|rt2wtg9X}vi$Um6 z)`&mY*YQivu{g?=W133-=dgr=bk<)?Sd^2lKWP`fzpMh*Q&kNxK!1wZQqJRa zPchGtGF3!g5hCNO>L-kiQuCWq+QbID0gjvt6|mE;u;*e3>rfrFN%#^j5nui7 z{{Ul}w*0sA7~Njncau$iiL&l34mYA=4sGMOo>f(`=9#X)3<$rk=a zQe3&ucLEzEPYU{ER^bV*ZZ>N>V^bvpfZ1+JBhgM&Cr-*UVBd7KPLBNMGsjRbu7WLl z91;(7I?WFZL2v_{%zyY{nn_|=^99~vGh;3|L5om33sE`Y;wuLi6;0=JzhjQ(UV4=@mpsA~W3{_=lLmj7a)rHn zmzv;fupzrg?d~x-E#7$!JhB(ky^NcLUP*FXH?;OSO4VTx1&Yv(o`>Y<_D7o%%@qO5 zUA}WB3{b#YtT)+8?!HDjS0M2(IHDZxpXaD7_q?;8UKJ~i(9u%+^Oszr`SPqB!luM1 z^*jt%T2LUyFE4wb0*_fQv{dE=G69eZRzCXXPC?X_)vMy4l5*uo2bzBQdK$tkZ{0ro zJxF+HyZCjZ+c`MJUBKG5!fhwV<+e2=iT3YS*k`uy@#rJQGkody=s!qlZB+4!2COjW zHVcKD-!IK-G%7R^$IetdMJ#>XNAA#?`H3~Sg+I-48tJc&aNQwZW%#{ea!m1M`b2-b zb^jfBCIOVq_sEY>Vu_`){*;@c$_K6jcT753KGQjSl+_z_XJ=VCyD&A@4l zhdL#{zo`@%mq0P}3zkS7hV>^+{pohByxTazIdJ7sisYpjI^M8|cU9e_<2pY&}l%f45Ge-x5jx1K#()dE@^S&AwCYqgZ z9O#(P*?j_Ur>VZ$5UN`XP8)_)bA4?}l1nIUMrF5&%Qn=o)2kAcujdDI2U-@*f@TIa zm)p~6OT;Mc>U0B@%^mrO@eY_eeT+2%*sgSZJ8(Wo4y@$Qc*lZOwFb>{h6yf zEX|iIaaLO58F(8n$EvGaKlU59RkhHh97W5~oEWYRSS5ZCO%|gyUnhcy7 zio?8gbVQb-x)-&qNw63HbPmhv&~!Bolw5pomZUgRP=C_WU-T(sb(hyH8Qq{-pXK$1 zS{0SaoR2pe9~kU+ZHO!x8oGycGvtB7qnc3NuLMUnh>rWe?dZ@rh8*0xLS^B|iBOZ0 zbu01eiu5Az4w0TD?J=!r9Lcs$`N(S2)U|`p&3QcwHE)@k=JNVOq)(nEK$Y;IfzEb} zJA;dwg~*?WliR67aza`1ONwqfZ-6HG%EYvqAvWOE`*yX6`%qvz5Wn=^Kfk%m-M53) zm?IYtQkxsLXPMg#PleSG(rc-gX1NuoL==w(64gGU%{^I8>Q4A>0 zj{Zu!ywz-DBy^8 z8p7OwX0I(R?X-YT?L@z1k&vBF6goGTioYE65CBhoL3BWBhdP@%AAns`+w@7KPSfcG@=_p2WDl&isxLW(Eo$?n?9zyU2!4tVMQ_~^7oO@;(X85W8bQJAOQ zpKaHE7f&HDT3%Pjd%|`K!9^HH=ZIV=c?X!aW@YvElrq1sAg*HvpMowRx2mgc%znCU zb24T=*U}bzc%~jo_0XjaX7iiqE|QBmq7o!w`bDP7C;rx%d$QJZ4hWQJC7ZB*5Nkyk zEnCdH{M4sIB+B8ZpTiucNNsSOM6q`qmZrdG`|yp#IZe%Rf>8!g^M||@@x-7=@J-$; zcC@9{`|$@*9JVNABx3f=pUB}+rN2mt9_Awj+*jf0w4iZ0roWC)OyF^{Tyk0(SMM}T zYDu2o`S`7I^PxsV()N&ImrQPJWvVcR-!*Pge7Nnn@Txic_ZUKa1|IA-+y`;Rgi_U> z%)cAn_(IJ{mF957g|`sH>@#G<`VO%oew__2Pr~|TZMjRovZy2=g-SpS1;0KDx5BC9}6$t!Q``gN3(%C_V`%=n4EA9HPg^^o$a?zc)tP z!M{gUR6)ldKLG%VMK=iVD#^n=VZyzfx~2L#3NWD&)HF0;*z{knIl#${d`TwW71T6Y zD-nLSr3d)T9OEQ7OtD^;knUJskhi5MGVU2t9i87$_KXaIV%AfjslmzgG=8JyL<~-^ zhjJOOh_*-{8z<|H<0?%5Yh0Ko*a|*r8eQX*MjpqBg^_&8s1F{`E<)hgPo?T?gn_uUW5WvuHrw5sn-D95HS`_b%&9tiVRd2L~1M)SJ32dY{d z^vUOZ{VM(493sGi+59ehA^#IB#5&x@)umBT!ZnbQY?^!&o zbml%-|LoPyY>5J<@{Uax4K8n!1Ua-TGha-;mpuyJs1>ZIPpx5YdM7N3$smr?9glN8%lyUky>%J=QFv7?Yi^!3^dUm?vYEdH!`_`i+iw^ z6N_}`*sEz{QnzVd*+eoP`GqR5zrl6(&Q-O#daSX7@l00LB@N%%&jrSCOGwODt1@6N zBExOhjHS&iO0wK7ZBJ=T<<=8v&_|z~-~-4k6$_xEXft7q%S5TTws{BW@-nuVMHUv?6)R_j&@*vY(~D}^M?9ZeIU}|n%@^vUZQC6PBQcp)nOvc zzs6b~-ih;yc6y<=K>MNvE5&$a-;ELoHy`8PYC#Psrao*_JeBe0zs|SvKR`C!9GSAU z`%MN`u2a*0E+8Ih4(_cR6nI8mIDc$jAQpcvr%StpJC7GUKVjNU!mF9x>*c2AeuVy( zz35dFhhWcAggf0&^!a0*n#KjMeC4n1iKgy(dST!-Hdna+P*|pzEuw0 zzI776MJfLsfDtVx4I+dXVnD%^@Ed!dT0@eZy&6pqGC(jeBA~T;GBFF@gu~SvwC1QE z#FMga9tqT+u*pko@#$>wZR8y1mrN#=tS_UtoPybo-5&rRL^%IRJ`?I?r%z*X-0uha zAZ1MZlQdVk>65obz(i_Z72~U%!G&N*X89S>%BWEO@ST5uv1)kdMPJ33vh&~*o1UZY z+u4sdeA&mloX09&u55n+fdoSB#mtk=+F>PIV496jF+GB0--PN1nC;;BlIEjoVHmuN z@=c`^Vh~ZE(S%1Q*btP}W=HBxLN|$=f1S@4dIvCwzqL}Mz9GT?hwa@zSD*j(tt9?K zQ1ahfb~QZ>6b;l(4lGP5aL|JSO&K-C_#fcf>-l{M;rT0wwRJ+Z+M%YB!{k`Yrt{+n zCov}s*JTKL6^mjW>KZxg1al*g8hlMezO0F{SFPTB~xwSX&LPy!ZE`F9vC;;C6NPv9-ejJKjKbobcL|y2qq5 zv)xi=VsAgtg7GU`nud0rvWAM>Gur@_R><1AiB|x<`cu9ZTUG_|t|o8EF6S$WB4h7( zdaO)y)s>Vk8U-f~kt#`m%058sm3#|`ee zLyh_n=P8PeA!jnb=StagGhl%eW$2BQW_I1375JD(W`e{tko|>w=i;1}%R}QmmxJuy zWF;2@MR|R0=~Z1y_OU8Lz;mVASbQh7kl_YQ-1sJ$U+dv76&yxvq%pb+ko0M{?8Qd1R(ql1S)S=Ml)KGo5DG?y|id$@SN2ymm^wf(&YqSXLX%p&xfUyi24jM z&u9ymlP3_)BiWFcziWE`En78IX_B!>tTt)L7f7=LNf`JkGX(GBu@;BTFQJayijiBb znN0Hgkk>c^Sg+&IyQ_pJxaE#-ejfQtZ>ur%4)~^Z)x$>bMWC|80&P@2lAM<8;?U}su_sI ziY0W9J?=gyWeyu8?@^8{B=&L_-8sKE)Qh0=A1f`9RF<91K^a)`pF^`tGO%Bfb4RWh z5*&`91xIarqymI9H8Hz8izeFr!BgZ*VJ*idW2>ao zOv?G<8(m=Y-J&ox^GIPPc!a}<4kEhbdvMywsYlwxKaZs$WD)K34eiVcav*(UjO0E2 ze~u){8b5+n^Z7r-$fCNVkYPF_>(TpSQZML@#Ag`h$N2*1w3k7{trnWCmh6u;i(kP` z8xIKJ1a)wDG2=H0oGuJ~6Q5dQ)`3s0ayEw>XD*{jJBI^HL(k*W9`uGSf`I91SWL!Y zHtKQ{EP78H3Qz^VR`LYn*CfnGxVz=fY z_7j0x6=vwr+vQ>)S|?zdeoN3^GP$=^FrK0JghnCL=t>b4!>4f0tM6&VpKQzJm*^>P z!YP+v7Z$^_S^Ul>&p0_}M;61VIQ}nJ7A0AvZN~3aV9+-mk?p@P%m1!Bt7&KZ&)V$p zPk586-aouH`Bb!Qve$<--U9R7OMB&bPOC`*F``2it1}PSH}ClJU?H^ z{HL&n*Y{Xw#}GaE^vy6wHMGl8Oj%Sb^iS5mZPAj2k@aA+$}d4lP*k;x=(3UVvYZMF z>{(=w)_HO2JV+KpFuk$3Z|6J^qSM1jL{=rJm{8Y2@Tiof%LJVa=vwoM3XMJEYeccN z=~LKj)Lx=1lRhUFsMjlrkG)Gp1-)4ATP~}n`E^zr#Z<9O zn#j&jgX;S1q+jHaL10fm?!f_)x;NAZ^ka^lO#q2=hL9@h0tV&L-OArAnC6lzNGixA zuoUnL8@*rvQ@K*MOTf3|3Q>C`zH3qJh$RPoey^ePIy#WsIOxN;ZwJOtNIbn4%wajq z)=5X_uTR~R)+k^PlzEjlI06y#U|UwxaKvtuZlNn4le9j% zOrHpxRnMb$3*B%dZl&j6uIx8ZOFWrbmm5NlFYw_rElg=?Yx%vPbULZ4!&wejP>l#d ziPxumuWz6{kw6Y!bLki}{kBD!v z=>I|Y=l}f){_jPdFRmKaSI<;kM}k!Px1SBz8ayAzI_bJPRehqc6b`oS+Wb;86>6$2 zc}7tO&%~r{2Bo4{cz8GjwIXUQwHhy#D~PBL?^ysbG_fa4_>&(E^yl^@=_;;{;oU@c z%az~N+voPj*1(K_Cv30t9QCZVc9~~SwwyNL@1TnKbgk=12lPX*YLm;nIT?3&#Hqcn`&K|?7994sj{ zk2u&76Nt53QSsZ~4D_g{6G~;VSTsA!q}zR9BcBV?&F7%t z#5@{M`MXXkxFN`JkE2_#k^LiPhYVYZnXvthPJ2SDgG16V7EtpP=E6l8_ZiewroaLh zm9b$h)g*r0hq&I(1fIAp9-N9oo@pdaC3eyY%%zAHoP9AA ztGGvoN|GnW^#8f|gFLTA$bo zIU=9b<#Sov(6#B<4_c9~p_7SP(~>7_l<5mos2F+R9WLLLKzm)7SsBI+y@*oJDhY#b#D^)Tmx>Iw}sY+?-A+}h@mRmq@|?z(Rq+?G7z?2rk!a1lyt zoZ5Em32`FsfNV2VT_~DJ-mvRQHuZ6NOZ}hCk9Fi$`c2k<<#f^=1PWRf7d2R5;8BF_ zLlh~?h{!gARwxiBCqiW9hX~tIVRxE2T&>;{rDZHL+)4~wWc}4#G+3owm>DmN<#a%kumPUAlAeU?7Y!djzb;{)?5*#*|_DOixQY(l$^$inY^T_$0wCOa>Gt zvoO(8K_v;^h*wdw%r*MrDU#I@%v7DA&GYdgx6-(DnnckKWrp#fw`tEHk1V;RrjAj5FIz{3M%q zLcXzFMp!SA^ggmGja^+{&dC+ei2Rj1i2VIJ+1WEVT^Sq=si}o<1Wia>#A3MfinzoRT=`6S> z#hMksO(6{sQ7Roe+n`*=y~HzZq%oAIi2Xj3-ren znF|;Jr`TMExH=;+pj49j@_YG|f@@q=(*NKxg+coW4PQu!R}i zoyk!&r*!WT&q;BRe(4qNwLE79ZtpzBpSy%M?rJP`!4Bf9-IM?e$P=7w!XlW*?SLMzK=nUcdN8 zglp_16{7jFEkE~>W~fW5GCfFG=TisX{(ee@MABe3S<_YOOv1MAFW&1`pmzHIQ>{aO7eK1^g(pGVMnj$102>+7GUtLRa?EM z^}UaB4Ml*@fLmKc8|uMeu@j5~b)WWqfxlE9R|@f;ZN@R!c^vGgny>}KxrXI=O^vjJS-f#nBu0yavUFe< z2@PYy^_^0vd96MXR6n6snM6Fr>pMWz=m*Km#E~jGw3FdUR^;TCQJwlk#nQ#SIE?tX z$EZYWG4>X_iQVWIm8+W-0~$nG4)|JtX>O=V!+r_vOl&IP$gGhi@?= zi+gxXAksTM;Pjgz^g;>(mr(-Mo1%^)-xG-u8m(0mXvF$OR-Bzkd*e2$>GFk|b1sLd zOO?y%t_DRyR2Wn2%0mpQ)S2}0)P6x`0=mRH<)by;_J8{O4g^1NyzT?}`z{23v^?+Y zP*nD85^V3rT8Rjwdb=+2>4XxBMma(IlCYryU-?8S_=3x~lNqr5S0`rX|2u3;2huFBogx>Cm0?Wtx+B>X_fuo@n5~-IEnD{VhE68#^(^OMM^Os6e+B+I<-9^qJ%N^?}# zF~&(>kNm^N%Noz5J?OV5(7rF9Njr+2>`;>I@S9+F&QQq%`59ZkG3N5!t zd_BgxM74;JpUE03_Tvm@i}oM3)MGopVpV}uf1|hjfojRVz57o)%YPW)D9a#-IDFH7 zYQABJ9RK}r{BOo8qGsksZnmz{M(#!;wni>4B1R^b|6ysLXy-7mh&u9x5euCNv1)2^ zw&9x!#y*~ju#iRuViMW+_d6IDiy?Y>g^dk~Lw*%$mgub525)(h$LQ>sBoU;4|Ni}k z98M4PwD^Di`~u7U1qV=DFFS|ZD(A}od*)^Y7245U;J?-)aLzC!vBk8>@gAEZyJer^ zSw)1(2oO!MZ6B*@?^dx3Pp{~mQEY`>s(%V8i>a?>oQ#4?NI}9(Om7Th7wNnhx@ZNI z^&CPZ`do(?VO^338BD0E1|va{{75pguDxY*;Lz1)qf(`fd4m4ma zlQf|Z)Y>o{l|$6-qq7b@T#W0~1Q&U3)TR;>nz)eD)Vz+(z-#kRpMZtZs+UW+Ww(t` z?uqbWet3gj*jK0Y6xc@$Fi{?^Sw|LcD#7Iscrv#lBmD6+4M?0%O z2J5Y4%u2r}pQDlgFrS{>NuMkko0EEFtmS;?iWftghA&+YAv<5XV9*G$k!So3b@7Ix z_qZ92c?y!o@SbjX&;NKoxM0ejEf;#Ag60zGKHjoFB>3la`44lg=8jwViSPWy|Mm>~ zAEYJzEr}b?WV>KzD@Kr?)iaB%j#VXiRU_5~G^BYIq`CQ#69Bm(ya?o2gS#Es2f%(0k~pI72)@(~q4mo%%9+ zGD{qzikTFWa1Ty5G}ikH2&rgDk%FVK0;*WZ$~-i@f$YYaWDWg?R?tPcl(AA1YVUy0 zrK<_RU}!D&pl~Sxx0k2Llm>ZI_YUi z9W96Df1=zr*yXg1SJ0zga1A6)x+nPp$JHsH(~X=j0$jEC(a@pg)E(;sWrtdxtHHK+ zeDHajw5xX{@WY(O4+AVISY34YJ0czGY3kz;Fb3u&8ekT@*HS>c)=fqk-CXO~&xM{= zo5xy!aw6PrtKEINIXAK$5Fe?R?Rv$V1zZwEf3XN!JVUJwDAXOkqS*RHMmx@!*dBXQ zjC9}^+{Hy)!>rS7d7o{7v>G5A>~!-i_qy{`o#a;ISst61ak#f(KdI+A`6po)Sqx!! z_(u7ZIx(6C6L5f zXktXu?#q&PMtT++3YI`*J{|Ic-*7KB&%P0L_NmR6@~0q;tl*bCQDBy-L@EnhC9(MG zWDZHeUegTsa6Z9030#S6KNoZ#3w>M3Z=q6p2(*rWz}UW=T_f49QC3|zZyF4X0Ssw> zF$#>NIEipCqwel(e&5dA4mZ#GeOMz$Sdy$#A2)9$8HEE44kpQvubDlf+s0A4Z-H_^ zrv1j#Xs!VtD(q=JcJ9{mN+P zI|6-xWbY+~i13XZeDsa}z_IxQIUkvnSCjZZ?xKtXS0njg;t>wLXiZ~Q4sh8H@Y-yX zzR=ZAA6+Wkq&XO7Le5{nTMa;W?}6P>6suncxxQ0;rl3@qpw;0vBW$RR|CjcL+n3FZ z;Jdxq|K9)q|M_bWbubZjv$Flqyym!nTl@pIfn1IBUW$pStF@baSLmdTjiWGBHEr`eGpM#jk6v6R?Nr_IFzMIr($HuM>ps7TD^#C!sjUncMT;U( zr|m#72WJsq5gG4OHdaS!V}K$VVL6##4`C1^WJt{|XEqn~QjIEAXSx!&J$`XBPiD5Z zZ7HcY4^@0P#L98MU8M#J5sG;E7w|_VOaG6 zSC`O9v3_06C4`G@E_w7V*gNF*T=%phj@nhBv3)jB9mDIcDP!|qplI7ed;}hfrkIWG zIB?g!U?n%PMrRJn&N;`vsEi7D>Aa`yY`#mh_4Q7<7tOWI#mA+m!Op|y+()P29Pu0~ zH`8*kByMGc+9jK)#TYj@?Iy-^hu{_A_*Kcbv?y4@-j_hJI;_K+ZwuOhw^z&OR^j6? z_X*c&k~^3jC$~??f}Gn-=qaGX)(s}&A2O`Ca2GsND5)1nOJy-6llTR-UXiC$B)SAW zPGRdXp{)uNMA8zP&yS(nC+6Q+>XtBxLGInJ+{h8H?of(0;N<1mC!BwFBLC>7W0aaC ziN4cK|NFB2f0=H~|Em+pQr2@o{=PGTB%*2NDz5KwP*a0lu=_E|W$+vaCaEKMflnqv%T&hT#t!Xd<}bAXvr}GR_vKwt~T19GF^@@k8=nFfHeE`0LeAp z>NyCuWP!71PzsdzujAf_&k#!}{Cfz#Z=Z_o(TYuKAdyDyIr+&GUD-|Rn;7nvgkz2l z*wG|thu`&u&BFlFj4!_WWK>Xjv=??@gLJOmoG>5B!$z3OfbS@KA9|>EiJxSOTZH>! zBDYzXP5~?}G5?&skYYd%@biN;#6rFO4^x~NeGn)#`7}{MmlnWOZ#$LJBCa1-MEYr< z))!i-N$re+WnMHrE>G1#Vj=M-X+WzLW)I1F2Lgia4Rd0*#SXB@{?~671y7$Tje1d=cKdyOTO4;SfK=C~45jl7Iq8G7(D*lMU*_W2qInKg3c= zsX{(2jv2RX%fRMg=QPY0JhG2)UhaWnk3rPwal#;U^;+ZdqD{|W|C(@5r|a{6-*6Lz z@A@YC|1rM(qxJny_3huMIWcEv2WLqmdsEy0a9Ai(p7;k2rBa{G#+Vg*yC!IdNXZdY z2qBKJTM>$yvQ2^Agt`85a5XB-|4`~W*F!-1LN5pz@y2PT`ZB%xEX~|NpCIQ)rE#_* zdoxk`?RW!qq^Jnk`1q)%lO9LQp5)f3-o9N+lYxf2lZM`CGr?ain~MP0v+jEOFh<`o zzy1^P>M7Hn!ZR_H7pMvXe{$Q;PYKlvxc0D9e? zFhuKm#q4gm1}`5^MFJmnzBZN-H^|jINec zsw6XVRV$GJ+IqM~e-Xsr3-MHrZ4PLL6Mm}Q&U@`1I}sjGb1RPgtw^uOBX==hTT*%B zrmqhLidnfa!z@RHarBgeS3WuRp9C86+2e-8SfUm1r=-|Qi)NlCXB_j(!N+%L7?Z+wiS(Mrg}t6+^?)^GO!^7(ui;IQ zMQEG)4lDn6i245S!ux;5H7cr3en1dW)Iy}Tj!C)jT^Krdv?wqT9#UG7G&c4m=5D;s z>~bHgAM?B=a`*>*WZ7 zd-X{ap37xSKBN@?@t>?D|510%Jk*)wzb$MHzuy4k|J8T;_xVo;%2#!9QQ+7-o+Ax5 z_6HEaPhpfaST2z;;v#^QG6TGln-m2zb#gH6H?6vEZ@bR<_`LNwdSkfe7^v*#TDe|j zQ&V%(QdN_|qIQ*xM$47|rB8#oB=aAFZ()dzr)dd~4hbcT1X{SzU?LN|0pdN1 z#t;XvAhHw|KwN01KnW~p>R#xz#n^v1I?xtisZE)&0|UZ5e1ff<v z$$cV9j4CV=I41wph|}bGil zY~;0nUkvH19z)C-{rHROO4XnjBW)s4h1&{G@F5Uy;pcoCvt?$&@T?|8R0$Mg={!o@ zWT6{y!JtsMbee746u)IYFU+Gk&nWpx1oF7f5tIYK8Lr%M)--*mFhDgE0aRrN=C@W! zh;TMuzC}V#v|ld%0MqLwj~m}H?e+#g^Ue}@!|rq=yAKDsZ=f7Y^$eFPz%`} z3^;5%HTn)yk+<1=FB>FJ#{9r^SkikU2<{$GrQdKX#>yj%xv zO98)#GR)ZI#@7#?X-hGy^@BV1^hc&zRulNnpl&+!hpaz;$|d01VLo^H2pk1fovZ-Q zwOdk8vt97*8Ee0QQqKjeTA0Qdvs`m97k{?rP+?5BxKLd3Pkae3m8RQILH$(MP3TJ> zOd62#zRD=)`QuT1SPf?j2igKgyYN>Gz9z}0GlX-#sIcsz5fjx-F|_beGMV02_=PTj zptb7WZBpp(J!QPR#}6IXRc);3U~L>?qlHk#FwA>D2tIPNX*A^rUU3D%WSp)HUnZ)o zc|MI1pb9FV@SlWQ$^DaOj7!6j_J^Vf^S=Oxd@SiHI>7Fup*bv@(?>D3>Z2kw8pUdfp&G`k-=kjJ>RR zq15b0FAQ@Ir0AbZvQQ-%a>=J&3^INdCr^fqFrT!DYs#OoM^8-LjY!=`xf-W#4S;%d zCN(oNUMOAcql|kArRy9;xnWQv=Ua<}gf9_rsf1rb4jEdx*!1Yuw(de_+zfbAD1Q$UK0A5$F^F4(n zUXh z9N^MCH02*#F~XS(T7lo~=uU&EviG8O3f>A)UL5$Mgb$#)+8Oss>8EW$fXrI^3g(t9 zmM$t{KJ5#ighZr*gG>`MNJ0_4Lx7N12x)P#t6>p2BoMR}Fk2yy;`V}oIWR2{_MJ!B z!n0Syl1&+v(@p&-T3YW!+RChYg83Wd6*hY*TrHWuDN1K1Z(cv;q{tf?3Nu8qb0Ia6 z^4$4Ti;wrtnlEywz_XDS-z0h9l}<&D9DE9mqJNtcpW&TI4$Tu-YDxdkkhGyG|5%CC z@E?l;c)gov?b&!pTH`pW>7|~E3Mr0MV~_%$`X8LaF0!`+?QuNDwh3f=c_SE%*BSRC zz;`FK$kOOo(EiBSUs(O0Ezdw-wKO@b?TAQ`B0NWmLIiR3W~^Ua-;Z6 zp2raw$1w5Nm*F=Wl3CtBLo7?)usn0lbF@yw+8`fg`f>v!)*P@n=FQyI-9t63H3bqb z%+J$5F8Gu{te zUme&vGInleBkU;b^uzZeo|=o23}Qxpb`Vlwa=jR16Ulso3OqUs5Z&`SCKO4o>9_2n zvoE2Dc8Hd=3Q{r(3|Jbjs2vK~P#LG*rJ3&ZB9E4lq`m#3G*y4qBt=jx@enXTW52sW zZ1;8?0;7KODmfylU;cQ!8RB-Jf>B`p_3gxY%azgAc2D7D;9w$D{)RO>Z4)@At*HkQMzploML zU({Z+^j|i#FWjE=7c%0(E&S29lp#1JeJp;q=&IN$Lax#69=zJDM)(c;>6OnckDS{m z@eTtaFvDq6F80E3fQGe#$^tB3jRhDis)1-3yaX&?wF?5qI?OwrzyM=*_?!BNW`}6{;3%`vCcrDAP7F zX}|5Kih@}e2TEAy5ckN%&xXPZDQTwFdNeQ-vt;1_`1qDX*pOy64rJYqa&YgkrV1d3 zLSzSX9<}Om7s?D~WS_dax(kw!@z5hQY+ap%Ekf5J4kQq|DkRF)b1U}EMMXbjSM3wn zMTB?+;^nkE#q(rx_PB%}zmA9(xAUMEf1KpA?kDbFWS1I;o>hSNd6M)Et;b~om|7^e-v19}?-V3juw{!@)h^q%ZQHhO+qPZ1Y}>YNTf1!RvT^Hl z_w9H3y!*P}{m6*5BG%80%#}HF%rVD6LPh7p7ARegQ)Q%)!#YhV6xAE6bZc()_|QTy zG9KpCTO;EFFkEz6@-{eW%IT>-g@v8s&Mb~H>{VlP7X}K|B>uy(nvYsZV!qiB(2N;U zWycjB0iIi%l})11%4a@ zmQu0u@Dd~8oFVO@=$yr}n!aAP=aYdXt}GX2$a#8t1#l6`a&60~wOdnevDh}XHU^Zm z7sC3H^*li^`$}FfUX^_GKuXrL6h=O5I{uKDKCtM;{ z`EvYsMfJ1)fr<=Bg~E8Lq|PYJQP3`{*MQ5PD}>SwNj&5-nhCm-mN#pT$2vM!$66pt z@_S8Vx=+WF+wS=Ie0W&vKTzCXmvEP>Tq>0vdHf{F=Aqf_Sf0w}W zjw7Oeqd$$Mq6sAw&QGj}b0c7#8-{fVdwZH&M^dCNNu=g0iw8FyGEBleu`k(z?4ejg z2}F^GA7sT2Ox4P(O?*^7?3uw2*LQ@DOk`Sxq*)or$@JTIp-l6)Ea~>E>Z9vAc{ebO zAH#WKHmjLBglD7Tr-_y}7wN=3FVoa#^FfIyRvVRVVq4aRuO&-bO=NxU^I}MmDD~|) zm;E}|^28fnG_P^1;8K>?_0ytVg-ozgiVd7XVs>HsurR1w-a#jih(-;FUP-riUN-OS zSf$pt{AsI3tW&~CV!Tjw$rair%J;DLWXm}t=PZ@rjdohb4)dFm@8S2>V?}yTQ^a>k zf0V)U{M9_3Uoysi%)TO_1xI)gelIw^u~BTWyt019=fcB#R5~ zMC=E#S0yWX$_$EYMWVXR$3dZ@xta zG=q*QRkd+j8R>YFIi|59ad5$9ZU`phscu?X*2OYf7QOY;rEeC&Bb-_8?~N%N0dk@+ zmm2h*(Ev*cRyFRgvM#H1%Z?Mrv|(YY@vRiQu;rQ&=l1IErpZM^?bN!sFRK}uJ83yt z*aT$M{OIrC$yH6sC0Kc5s}qaaV-JSE%T+>(6> zlRe)I5nG$|&aNQtqoYyq9}${6oI+C(ImMp_SVz;1NE?*69f@I-;T8*(c9WVdSjfNi z4x6ceNyD?D{F!dh0^A)9*l0WWkwAzYKxKbPaP|3Tn+B8_{$|E)@gjIgF4Vw?LMYH_ z)0Or)LyXpiWTpMJwOw~8Wx=Zx%R*D2G%ZTw8=)8}?0QXpD3ez{ z-=o>12DGiBEUp$*x7{=f)I9*SJ^M+0bY}q7zY1Flc#Q_OCC9ra4(N^3){BeS4){!E z^7 zxdS-S^9veGV4la{kB^=Y5zP~fn5ZFrRpRQA5buM)+qq9T&Q;#bhKwh4bo7F9mrE{1 zh?6gHDrb0Sw!)egD>(U=h5#>xD1^Pk!ih!^9O&lk{A_jJEB7Z5wJg{f9X|joCrYm` z#l8gNgpm3@yeVF&0uB;e+CytdbiVI zl}bybtY`BdlZ!mIf`^ph(i_4-KLp#tht>*iZN4qB(hkRWzb)DCsdNiutQu~0$q1_2 zwKP=|wp3^+KI0h|oh%wQ- zE=CPKe-9t7Hop*c3gv;Iis-ELC&SK3fD%9x+QK#7>VlxK>-t~kdJG1}$vkGJz79Q; zwz73-Cz(ih)euINcTT39kvKKpPJ+JmLZs4L2frcaJ{nO9T*4*|EW7(u?A5yfG}3~$ z1bbVccUQw14KSxjv>{no6*=Sro3ZM;*E+Qh{`yJ}wnP7g7G5KG%g!EEmwWB%^K_gO z)}66MmxEQg5u^KfXux1b9gQa^)K#p*v9`rM(86qs9%7AYb;@Y_=2?>^;zE)`3%mPZIhW|Dnqv_A2yrPTL1{Gv#OtvE@74h(JK#ylXBo#8a) zN=f^pzQ_+*SpReV?059Z_{l?ZJ$j^}3%z01O%H`X^D|r_$56L-mC|_|pU8hV#7dP9 zo9>IR$vo7Op7AG7!>B6mrot*KqajoCHF{d- zPN0NSu-z$dgoQi8&xXOv;R;ZDV85UDPXC<_6elU$+rbOpT5gEBw2m=>44=3yekEjI%65-HpSR7k} z&Ar737>J`x#IdDiP&q1njhIHQH*hrEPF1cXy;D5?xv_U~ix;zPGK5?o!G4y@xh2*! zOL;l<=QEFWLKMbNq^ktfDB@&%dVjBX^;Fk6UqzPi!$*7Pi$@W@bdtXF@N}c@GRLkz zR?=;l%P40w;Sd2Xm(GiVP`?zqU7uF_P@^=ZSAsFyGd)`&XmHH3|3G+(r3m8 zPYJ)Wdi}qX=UzWZf|H;+(+aINxgRizkf}sMQx*}ci2eYmWXTNfVv&sLD!ph2Yr;(% z(V4G{N3{i{5EWJ*k-8s}K8R)R#cQ1k3P)D1!9hrIxkH_Uo0LlrE2FABl~JCGnoLA+ zGHRG`Eh&6f$=68nIYv#i_IdV)sxOo^$S$|y=79-%-*YYLbHj!hETtS67<+W=#Y7Te z6^oY718@MBkTu9h$cE4bYFrl}cso#fvWN~pAslOJA4zO>(06xFL>Y}Qg19ISPIbn+ z7Bl0P8lJgEpm>EwwU6yEun1(#e2y*&GiO&Ie=qR(xi8>`P*hOa^Z54=u5hGLc;_t7 ztt5%4XxPkbAsj8Vro{amD^yPF@={(;hvFb-u4d=XREk_-`SeJw*Whm&!+NrcYzC!? zE=ZH)y(Q(2DnKp5uf5VXX0M{aZ<%FqJJI@nP=Pnq%%HO*U8%=6yubDGNzLG=lwX-F zl$E40mzh5@|ILO2;78rcaTpl@D6mfFQe8>w-+RS|k9B#b#eSDVH!WGba@q;Tb(g6Lf19wjC zoR$aRs+kC#L%?@#A#H*WmTdrc8HI4MVhxsWtwBP0U{TD*By%p3y$;JS7RxIpDudtL zgH%WY5i5(13!LJxtP#27q`F3PRqTChfMtl;8yp0YZOO3TpsA@gUtVzmR)&I8L0TazR;sS72Wn9jTfu}BJ~<`g zFoZ-sbSFy$3Ng5>QNdeG?u$$O0Yu#k;Hn1-c(Du`6NG$ z(NcH9(Xp#%o~Bg4M5Q|GG5)(RWoL9mYpz%P0HMUWOj3|8MUc7uI5)IixD&Zpf%h8s%$9&}!xaeVuhQ`JP_z*{<0T`cUQvz@mZqr4-}rYX7T<@14? z^u)GAfyeKFN9f=a%)4jAz7lqd!doEuB^>6kF5iR7aZKvcDDwU8PDaU7sdR;Mv8}dP z4hv4yy6T8y{yCFabm&W_eN)3KICZJ~yfixDupH{B{ouuST{iXuPUn_Q#K^cE@hT8t ziTpx{mt3lT)0J5$uAX}qc4LO%brk2x*e!J; zbcF4}nNo;$Mg`XJ^`-)<%HZmw^ICu0)Q7Q3u#Xa`YL#iwvzkktXi*;ql-fDuE+!G= zg4HLFpLzQeT4p|7*e9;MWy^6L;izP?g2Kgi?TpCNh@o}gelyk1et=?#eN-M#hfboA zQx+${2$Es(U`SeS<8kS_EVM8iN5E%U9JA`jt7i%O$P!vc^}xI$17K_vm{;(r&@&|F z(9a|FyMBivfP)UNeC4Bdtm~8Szt(UGFHhl;e`=DwKjXh~Lj5;(s*;I;;}56W@!zYG zKGF4%1OF)48c8d|e}F^TbUma5hJd4uvVoJ;e~@0(-i45VMA)taVPm62ff0cR zBQaA=OaNmT3P^{*4E@dXFs1c=2)NO(oyMkh`gmu9yonF-J&O+}iyLlE^uv*1yD*f8` zD{mCb2YaG{HVZyYnD(ZnGi(KEu^79rSCD$v2{yCnnV2i1eroNaq}lHJ56mE^DR)}| zHi|*yM~XLEDS@=`xY-TXB9ccn3(Yg>lD9qdErmLQq`<1_J@2?8d9{zCkOs~LQZ;`F z<{X`7F|UoaEf%?sjf=bai8nNJ9O?pbuLo?iCE7AA3XcRP6~=QhBr!26=;k`Z3+}!IF(TWH6H2YINa63!=yuga6o%rq>Q-|Pcag>sBc7KZ-z`*2(+JJw*q-@S$PZyB^3BxT{AxID2i zjY+bmfnh6nQ5y0D`%`{!<&O4za|bkkW7}cqMCaH{&=F2ne&}_}i}Sbt9b+~4tY{kl z`4!D-f7wY{n*s8cft&XJJ$NVfo-WIopszaJt z;;Qf^t?0?Ywq7B(p5L3}c7AS}s!}zxh*)UvIr`v^`ZU<7V2U`a#Tps(D5I#2le+HO-g|X42RjRcC1*bp&o`^-)SG5CFikzjQuLJJr^%9o zJ5^Y#&Il-MCi|8<#x&HR%tuR z0MIi+$uPLxv;+^h*aHES_nyEtJGFf_rG0P&R)>-h)l82+HY2*CbP~@XMY(xs5*^is z-y<)}P-~oFd+{wVBQ+XX#Dh|6_~Sg(baw0>J%PxzXi73|+qqp4j7wRnb%$UbvXTA`t%IrH8D}I?FhHv|!Ji z+ytm^QuB_9$-xfob9fsD7z~MluPrHN$n7gVAex2vV#V~PUBGOrm7ltda4{fM7?Agm=b+8YP{&$e@UOoZ-6Y-TwB;^xJb3Lu*Mn(tdcz!yz zuXjSKUIVAG%Ez0xIC6cw2!g4iU(im14AI~hj&JRRQ6**EZ^;kt+A_%?^0H0cNY`L+ zpCNY1_jir{Zs}nFhPAq1zPfYP89=^|fW0!2x%&^fh9Lu6Lw|J2v>4_4PQ420ao5A!YM{|C9z*uwEg$Jx%&!_C0j%EXaQ_F>wO>yJkjO%=nXX$Kzci$s-(?Ld!s$T8{S zUMVpb6jHf}^!h7>+NfaId+)vMl#(FmCNBEm2Lj%${B09n&jk*`fKdG2>o8LiHw8yqG9S_EGu9S_bYc$)0sG)k$KmO|B!*k1K0& zQ(JT6FhW-qLU3+lFmi~VVGwV*quUzarw6##Y7S^{V@LUg)jB35(=#5HpaWxR^j;c* zX`)HP+Ai%WU8O@{oeWbVj3{cdI10jn|G8u{N5 zZRO0LAg;nUa}{=8BEvwiKaR|0g-5YjJ%wG&_{smQUaRg$R29 zs!>b#!@8FJ(GwH=9~glD(^~ltPT+sajA5rm`xEHTD~br*3qZ?5s*tPZQ>^)mFr(7g zgc3x5GLGtry2h>-zCTKO|rgCq>Ia0X}KUL+OANA0v4f zanVi?X5ZPQq+29S5FfV3umE(b#lZ2I@|IU|1}9D=F!O?RWOnIGkDwZp2>R@r;a}PI zZ?~#0_5UMiaGG~ioi&8*7bXGn6cAw$jXt(76hNA4T2x}Uk2y1;^hW|)IhT_c(cC!@ zGrMZv*b*-5>?Uih_TYz#>mY>x)uKHLOr+WTq46%EzmF6>L?6MuUUlPNv!lK}JAzzN z{D&r>U#NubcTis6pNi%kz-|#iQwOe43~yR`$D#9ihcIi~u^4U^2Q)IHv{4?wy&Jx1 z<>VEf*_x$ORCG@3e9($dM6h^SNj6J%;2PX^Ky#AdG5IP-4m?Iy$J3ky`Q@ns6xq!~ zKoPkW8tQRD3WpiIZmZ(VwYzITDvJV5Q@s(W<%AmE@Q8~ z2nIc!XGvFG7#k-|*$jx)JD*K4HZQ${Qt|=3lQK<*hP!Qm^L^r6s;zCIB*Z+P?vRxS zsUftMxu?L*DX1*pnwsjnbp@pXu2bM8NlX;`wpc2$Y3~g4J-Pr@$(dd2(|xdx=(}v6 z2wF|QT7I@SLC(gI>xWwQ?vOuItc*Z@_*{u+n*!cXR}j)x$kI_Kz5zFPNDzuvS-^Ps_96rA+It zHoxtCmxhin{8$+T-LE#=DCje{M@oTa=Z1&Pfcy-PGgitGF13OA1iX4)-|Qf|(feu5 zl(4U9fL-zQ$Za|6`P&o@2{NAmXF(yZIB_cg(A?T|hEhMEn%^L04EzVBG3;f1>D_xX zUFqysWjH`F#A7{lGtt zuC&`1v(%q$sPkw1PsHti-Ht>ptW8ucoGgA$vwz=-WTF{h1Nq@azVQRq&uE$)uBb1o zrKzP))zbP18yxtTDmB~z;7qoP9V5rPQu)5`eYydw;^A3UAyv+$NVi-oc0)znRF_y< z;gYfTrsnT!E|{V=(leA6F-r~M4OGu`D>d0dII}3xVi+8s=vwX|1Q)y>a_IFg!`O_% zdaf8rq~o4QF}z~I0R><3f5Q_zp^@5xp@07i1$&n+v?t*w+M1ui{xkkR{6_x`3HU!m z?EJq$50Ypu*a3cM;ZXu&Z_G9jX7u?5B?5)Hd720$L_yWGn@&s+uwD7^?Onq|vfkU1 zch6sGg>vfZ)35rn5fjCG+Lj87>PJqNcv+~F5rrq)%3=z-C@MslLEwc8ThMAHGaij} z*(ilV=wC7Ee24{ABm?dZwvPjEXboA{;6c^hmV`M(g8uNn)!PIXywB`6T>xQ7k3uxHT+793SSZvh>i(h;#`z_vPQD|f zmJ#gSzJP2`plwV~^jm~B4A~SSy{!~1Snly#C&*?;W(XzmiL*heT+<}=QBDk-8XjA3 zc(b7v{QhV{ryEG_W=RBM*0#zm!R03Kw~B$;jm~Jd7w8`p_mEXuUBh@VV}~tDKP8OO zUQryAXN+c(xg^m^)jZcKf~ggkvX-#V6h?_58)2bE)h9jb`(wu4`d68Cl{*#5`oH@K zo2}j(`%aO)wvTLg%gcJ?SGZ?r z;Ioybr6a>(gLii2XZlrta?<}sOz_{9xuuJ( z#Si2qFQIJW-g8w}7PJ!Itog5Cf7ZA;n`n zciN~{haAuy^g@S!h-yluy*3bo;Q0Ek#0W2pe?-1(=OkqzJ`m2oqF z;re^)@RRk(6(n~q84?K@XA;=pRM7-eZJCpJ>}oy4PaV}t`Jwr&GCZ=m#7kgztVrOp zwQ{YmB*<%frzV7OF;A!e{J~z*Ii#oO z8R_CPjQM?~kjdIci`lI0=_u>(IxySOWZ^}d0{x0ZqQXpLgjQP&V@gE(;25Q|S{k7C zikrqd(VcI<5MeK{&u~j)rD@crbTo0N^y-0 zka}^;^3Ovv?Xs<_g4TuNW`)g_-(MfQ6zM<+-&e-_KiwxeUSHqT&s!dse($)z^g=0+ zlt#BP{WAG0C2h&#plq57RJf8O`~6IrMmYV`SM&Ca>fIGJ@rf+?!AGIsBN=-s?q$mx zs8MzhC1&@)AsG8AnL=7ZfxG@sX`G8OK>gtxC^0TER*%FvqCh-~O)7nE48zfAUw~^4OY8$tm*B>LEwOPWiL2ZjI%u@L zOufhjaS|n`uN9~;xZCr61)j9lE&IiJ5Mx0uR99S?HEhQ1sn12@^FH)DbNfW3jAW!X z2IEbsu1Cn}B9qTZC~W3io(?6(+fXcR>I8rE()v={yRk@s?5d_CF**9v78>4kk*RMC zxMA-Nu}SCRi@PJyLCHKAP<{LBjH_CREQSm7#~ReLGQ>DCi1JTI@K=KivC5z9r4=ko zAwk13GUXzhM>DAfggl{)-UGLqO~71at*X`|%@d+!ZC!v%sA44{JPMPU2c74p78({o zD=M%7iz@`}MbG+HV5K!3G{Y(BKncii)NyQ7l@=^XyVnhd<`dI6bpE>#34(Pb5aoGso1PZZ$L~iOavno3|La!9jGn6Z}e~UJ@ZxNvoxd$ z5o(Nk6u%v)u_Dy7HYO##EYG_EDE_YO0n^2fo&YDRHMQE-?SH99^^V)`%2`J?i)DOb zQTG;CM1W16l~^y^Rw=)Sx~X?WF2C9nVutFY$SQu#4Ud%z8%a7Pmet5&I54VK!fOek zJOB`+tRx@Z9Smw_RVe3@fHmeO+BVa7f6 z-`z&BiqRch>uRhF7<;=mzw+L$(nexE>{b6J{kG0-(oS?JJn`C{esdOH!A6|m;8^;5 zSu}C)@JUF!IFI$ z6Dw6tBo!;j=TnVR%FM9GM8!RX2o=+7Hq?=zsiPD*wgSXjrwQ6#)I>v+QcY#lU9=4Z z%R0r;AT83J-af;X_*}zxAZEUa0oB4~S=-cclm^>|X9qZwUc@p72x+SJ? zc(?*(M6IaqH&Fc#O)Lf^^KRd_%mN%G#*|9Mf>=pB>`A7}%`GBTs#F<=UU`1j z8wmH@zUA;;eOQXJLMED}Xet*Eh*FNA0A^grR%;Zo?fkk1aO$gk^J);ZAsoM?^JCbJ z#9aVg>#^s$2dW4TclMqk@9@-jlw>EXdT>7&Diy3*oZ3ad)01bZr?S0>3SlHQte&~c zpE<%D?K^MTLQ4qye}tivlCxJfhyVU{AB}3grBz~pVd+G;-Sz2LwgcVjiRuUIdiBhH zY+w8~wA##A6IVOlAWZWzw}F&vLXNZO8?+%^Byz>;AxzQ6j4ky;*gbO9U^k>0^HmB< zp>rCVri>%l173BkRQK+*eUN(`#~;6s43E-EaNIzPY9gyv$v-5`MZN*p#a@-YRpWFP zHj?-*nNyAGQdjUB+qpD<7~5S+UZ@W`!EUw;f@1PTt~-JB%F(mM7(p6q?=4T7=AOHh z6^AqlRtuFvAOPWEj7)j{?J#Lx8?ErzTUVO9r8oeD+qywW;L?e$qp7sGNe9WO3wuAo zp3V=T((&8F7!jh#0w%?Yg{SLp;%2+zyKw`ytd?;k#~reLuJj_G+86?{nj2WhRUFg% zv~xPNN>gg4;vD=U?sG)kAUbjKOf6GKY`P7WkyaJCot;DLO(>lTZu)rOR_(FM_by>$ zH>1!oyuMNuPsY+YB5!&WC<|{~{X&&CyZE-}=<0Jjm(IDy8uC0}n8)5qZ@@DBwaUOy zhG6`1zB_vpfgwu;Tt_u8cC)nZ2GO4-IkgJd46g3|;QlNR(l*k2ekVX^i`ovQdy6z* zT%h=2?@Sn!Ykpr3w9r3;VFHfOd_JbX2L{`p)Ojlt5z+)qn957wiO9>5x2EI0ed#vi z_M3I80#V)>Tx~qaNL>vWdrMpjtYdJY((3)0Rw5?4G^mzRtya9%Od=|=m=;i{7&O~A zsrmV)kC7|}4QFs9td8ef+CQcS8H{hpdE1+ckzPTm3l16Bp+^^vEoW%8?i>j!>QrHQ3I79lMAWd(dbq)T6~*20xgw$&P1UP`akq zXWF}q)LYTX;syUw*Gu=k90|>)Z9hs(ZP=R@=K2{@wY@W7%a3^qH`q;@Jf`1fn)MO|x@e z6`2ms*~m%(Y;Zkcixywf)rNJVHJmYSr}N3^d86Q>^Csp9MZ}BK;XVUW^K+X8MWppS z)!(CCrki}8c58d?c1V#FP9n<7jt* zW1c^iU5N&q+358kMt!BlD}+V*UrGlILrHCvNa&tFmbz3|tJ02=+N>>N&@EZeV{|jK zWB%S;mw&6J`CJdoxb7R7^ciHX>zMdS{!EvrwXF{U6McAoY|Z#f-KI?dBpHN}P8Gcw zs^r*Xk=UIq;v{t@25*a$ca~q_qK0^B09+3`wB=$fj;n8kLDlCXUl&%x#Sck&k=%}3 zBj#R8>?`F444Hun@4qoebVOq#M$DFod)LSz;uRhqczXsq$|Veyl0Pyx^9Uj4l0?kL z51mNtLlNJaB)mXMc&E4Yh$6Zbi&q&lC=p+iM)WQayB-|*d*~{RpUg_{)beHbM2OUK z0CQe4#Iv~6nku20vAC3NW*6AHMRri#V99KgYX|RGo|oub!MfPV-^r}hw30uoMVqAZ zgj~4-{H-hKj(T;E1DkvA;`Qmvcp{h?5tF`vbHMo$JFk&eVB0LQg)8^s;ri13i{a<@ z1`YgG%m>`FE(gTL2)>m_XfGGpXC)CC(Jdt&6VZ(gWJ1rq|ARLMGVBiuV}vqd#HK5T z7a9Y{CKF2f0IMvzkr|t0c*TjaPGJO92^o~l zsDQP{Ch9z~B%A(+q&OR~ty2uDi@p$qR-VWa=($S#%7el}^>Y)tqPAj(j%j7%JvvE4 z$MNv4YZ!@=^N3vSUItzCCg3gG7&06M<` zvkX_y85A(*`=74w|B#BiuuY3E{6TI2er!SiC-la~&e+8IKN%~6Klk^4C}@b-I$Jn< z{0DDES?eFB0AD54Iuu&AsFu}vBKjvsDgH=xaS1I$uimor5X}K)vV08FCA_&nvfATw?f%*>Zc5Qb6{cVJv zkn^aaYl*WmL13(t2|YxB3!%e6tpzA9vvuc=bah7DBf;zJp;|@nxZKYP0fa8m*AF-7 zKr$p{L{&V!5&$AXr7l`N2bCaz(>}l7Q`xYlqEL`l3)!+f%}7(+Ar)zDp26r`t7r9CWp6-^Wdk$e5sB!%W|{XDdAm?e)-}MD z?kp=FkJ4xKQE^ocIu~C{G7JA%<%Bk&S=Mfs^zIPvv{`_)+Db#&=64;2tpT&B%UEUB z^#a==FB_l>8vu!ma6HD~73+8iT`DPDBF^YG>-hR)qLcAo143Ed!c7Pl)eKI7eA>P- z3+5SBDiVf8b_yR>$u%S7^r25z_4TN_r8LZX$Y2&(1gv4ys*m>mCc|y-nk}=_IBISB{NxH~zo(`F`XObDat|*^Oy4~j@{X%~Je3Dr*mEe)&wrlC@1}7eF zq;$2jGys!n1lA**H|GU=R_n~V_(bI)5zTH2QMKKo+KKsU6|6C+J?nAjic~}u`P}eo zhHQ)zTgLps%R556Y9-)Kd;_U79K=PdDn(PE1T4MwmxM9Wu&|!svE`Md`O05rNLIjX zzmLU%wb)SRe+O5;HY`60B7pqKpQnUekwx{*Z$x@G5HvK^%Ut&kv-N}G`9xY4;k)B- zHt^q!L%f_*qa>)@h?&3)ki9H>AqXz+EqB;vEv*v0jJi=bHz9K~h9S^Xjjz&Xtx$Ah zY#)44e0P)!Sx7$;K~e#)2_m&yTrbn`mW}#vWu}tV+l(ZN_-u zGzOa@8*m=D_-Eaie{6GM$e2_0Kb6plAHN08|Eqca*DbDE4aN(38O4`u-Iy#>rjNv* zpTEvObDJ0nftnyu3t!<=x0@;3_vcA6K zPa_{qKf*#S*D5u+GmL3jGsDeK z)p(16;02=LGw@{BOyaMhh~#LSSzAHf9o?o=hlztQncdJ@UhQNbX+p~>4z;v!-IU>S z`nD`J!`z_8ir|eubGI{veGpqJq&!{{Gt*q`-AoKp=05J;*xK$tKitzZ~vDVT{ zAy|>EAPD@;bt{4mr^&2`0%+kuv2@~=+IvrXZ7Z`utzl8gF<8pK0d6`;Rr3#^pxf>~Dl zbKvvioug5mseiNZXQl#v64cY>x?l6&0n5in1q z0xHY2HWf3i6koUkMB#bx=9hiAH8ptvRFXQiDZv;*-692Up(M|gdHUQM^Py5MLMd}L zNHv93TxKN;wZPJA8{9L3+741wkREnTI87PdL&2_n%mTRF73@rxwMOY9$ls^kyL%TO zlI1D^-v^|IpM+Dy=?9bH3V)pG33C@JLfBj!-^0gsHSHC&zG#qUC%KGw4E`oXC3cyN zt5t|GjTkD^&oT3)@*WR-;lzd7Rp6Et((<5~vNK^?DzeZ2Jx6P}q<~CcWi6U2;f@58 z*N#NlGgxV&zJ6a-j6mFFwnbm)jph}C@q{o~w*u>$DH>>o`5Omir*xV&UYuZ8YQ znRd!NH6g{$XXTbhXdjik3V!d1VTt>8oD#EguIcb2PV}E0eK!`}QH%IY4uzMMqnxQm zccDwJQK;#}4^`pRY7=X#AcE`9&4Foyk67|h>1G$*DP-x?(R*&Jg9#1h>8=CSTf-VD zI8($9Z%rxcJZy-DnqlBu!SDPcMRK*Dh6jay;GauZB^ww`INx3nz*jgQQ&H7rhSoX_ zIf+qRvg`i9@)N55kR-2e3-3cj5((vsvmjGvQ#8T(?qdPLr|j|Ri@slLj)NJ{42LSC zyN{DOG9G%fwNJs1K#d;hImW9A3VCl6Zf|3ITrt@u9EWC%-0E)sL&@y6^)=+E3~yZpC_FxKaU16l!ehF6Xsb`9aRU0R{=b&}+;i?Yq@bYY)kvq@R26+3pNuLQhdNLUcGDrE>$m z`b@h=f_^%{B!aa)1f=Gog(&`n1JO|iI{Gv*GD&{ORy}5Gd(xY>qzl5iE|MK*%sFX> zr40rwsySN!?`7pMt|HR;&ctp;%gSNSaT#;C@lPp^O-Uo#19y&5?=_t2pYApYdsW~C zj1is~{^o(!udH^H}6wMsjK}E zhmWRg-0`lsfohG;JxK9~Cxf3H&e9p&qs@wtpae~bLMl)S`3b{`k8s8X)_WYj;R zRImk5aE8Agw_--sxv%!l8`q*w9N=^fQ9P0^3Wa$?fM@tiOXv=3?6b6iGv^?z4@KS# zOK;vkKfV{zT1(lvw0kIdUXHN!$c`QyR`eA&2NrE7Jd?F?E-eGvm6$tWQT$a;qUCjf zGxl+$mDc@d$trke$lZbUT>3Y)Zz{we&~x+yse@}K1k~bn5}|N@TLood>`$?olYrT_ zL#bgz;0j0)sG7i5Dw5uMR~alI5A{aawX3_et1lAHTPGOoqY`M+B~FJ5zF2U)Shy!R z-&fn?O?&bM?E}vEVs+}EKy6!J#|1xO4=d3j7s>f4ym^OTJ$DT~rxN!>T`lVF^HEED zD74JFM|_tN-;%9;tx0|GOYF-vd`6_c$VnmY3_h9Z?$f0Ze<5$?dPU&P0qNq0EMs%Z}1}aqzZePK)T}lXpopQ`j=4{Jn1!jc#_9>D3a# z&w`}?k?`Bv+ByG|D`~N+ zh7*Q@b#L<%xj8nHeQDFHz|i2=!FJq}rmL|2VJ5qablO`!BkikwW z#*+=GDTVGaU`4o6D5YhN`z{&%w@KRHt!wdyrGCo0Jg>NGo)fP3v-kV&o^OOc+z%-N z9p}4r5F>_@G!wQ&Hk(C;t%5`j9zE_v4eFW9kf}5qG@ZfbNLO@8g98bp@iAm*uH1IN z>!Nh0L31^94ZP8^{Uw1J%#cV7(b56Z7%LQ}#S$Y7kP8W;n!e0BLAe+o`84F3r7o0J zO5<4c;_UxL**kV;8m8N#v2EM7ZQHhO+qPM;?Nn?#sn|}%)=96`Yp>n?<@6roeg424 zx88|shTE)a!Vy>28%~R2IEKpkR?Y3vrOSkhxcN$(k8xHb&}y`Ds%qvieO`?@0S*hcw7pRwq2o0t1$Y#T=phgCAQG2l9h$B^C zuo3(w8|{WNPH0TKcrB|pjlC@PmkZ!s!xjc(r+#4D33sG!YB5MDb7?)j7Ixf><2GuC zb#HXD@$Eh%a?^c8_JkN5U>^`Ul6~fL=8RM1jN0qVa?5nXotz106bl|Nm*$UyjDMsH z)%fEQ?}a+zl`Ch0Evh|!UeaZw;pBngE{=Kay@p=8ik{sBIL$)C*A#DAS2aStCc4O#MNRpM{x;No(iyWs-yR2tsdYU zSbNAoUn`*^msy=EE8D5b82fn+J4m5PPAAu!n1<7R_^}~SZL>vV=Iw+P9-}iugXmkD z8UvnQsM=b*4rI*glD@PJmq*TzioW6fNlxyH|h^#z?8LAmP%g6U>W|DZK+OqeV zeCpD$e>gRm_7N$+4)Y+=Pmw;&)ao4MeuFLql6#t(4u;?U`>u12Tc6l#r}~-A)8FAb zEa`UkQCa}D09TjCm&y}xmCRq@`xd(Wi>GyU40n9Vb2CFGfAsI+aojzIgkSg-KOyx7 zm7S8tFs;v->yvA(QT_mVyJq<()VH7w#S*&Kuwdb6_<#^T5*G`K@Gm*9h`+#)p0kQ(*tPutwI|fptS)O!q$;fG4O)+f*sgzB>8LMrIM$}?7)hvLcf`}d-o{-c<9p;S5beX8|Wrf)xOft}cB8z|eVRyGvZ? z!L%J017FXwVd%(%gxPv}{EgmViq=BT^Ot+B##)X%k$3%6%zZi5u6M-B18KDEra7Md z{2GG=;kX&UL^2|)t_0u7%m5XQ3;;G^5;(727zC+yoX@`x~K|gA@3k~UVXV9wJ z&2huhNC=MPa`is$u%pjf5j|WPv86xDmBcH9C2yhHP5Sn8WPK1k=*fk?zhsHpjpXPD zR1d*)9+5@4uzz@6&7T?&mj8(G5HdBiQ*g3(Fm?JL zHa9k@-|oki74|KwMD8lPSZqnzJO{SEPf`MBu0Seq4p;(Oq4*cuJhfBmvT>W>O^qNh zf#U{%2gPWmHAuC3Bt7%d<0RkS?CCi_zZby8amWE@tigG_tQMuvX=DIBsY-wgU%cPk z94lsM$dkDJTM%qjs4|-gV{jeydngz3d35G|FV#U6Q#4HLZM&goK;iCHg<;A2n~5&v z;p0|149Z;>F)WZIV%sRnz1V?l$&}&O=ABFF188M|U2R2Bu5h6|JLRg!(Q6);;adIo zs1+>7viP3Nw=D8^s0>~JRVKD?TqPcX-G9CUwYu(cFZ7GLXdAO{@mcBtMaXMpxC`#7 zqD-pZP!qjke`UAlTW}p>zLq?(SNms9YC19`E)t2MSSD-@1e3gy05Y*mJ=tOy!x@WQ z4KbKK*he?FOu*rp2H4Pp{ULnE=)xSI9v=5L$=|h9L!a*IoRgMvZ;)RHNBJ`g!l?se zl*RqR;R$^h(VVYbjC@4%`EM+0@7|eg?T>(<_VcLv&lcN%)g{ST8aWv{{f~5@ z{%-ukt9_Z_XEJ1lB!u({#Uci7+2BcAD#Azv4pUs2DIy6+mgio|H3BDZad1ZyK1p7@ z&sX{i?$l(dRft-n5iPHyw|>EYc6^JTxto)9HD$-Pd=fId&*pglBwkm4zn<<~_rM#V z^CdB;)SDr3+Oip+iE=X*ow!OjL96X2+8FXNYLA_p5m{Od8%<<1vRvfAND94MUR9?t zw0y|yuPs^f8c#wAJb#+DU0#6lCX8X))623SrPo>75Y_9s9U}||1qRwQeSTB2NG3Zs;rYqXjwN6QB zasu<#LH*cE8mH1Wq_jNr3e;L>FC?UGYhv=i45F3hxOuvBeC(~iQye7-(_#PsIWpyP zDY4cJCXk!RxWRPC3}<64yKm~#3hEs)?wa}`eX8+WRmizCp^cSTUuTdFw_BK_9h_*K zxs&(!_z#1nqjnK)Md}+W*SpGQBrufl7pIY9m$3LiT#Nh9Yx`Dna`fvRnkshpb|8Hl;VQ$I-<+Sw`#F?ALB2o z*K-5v$Ad|XBt*{ocFeo=`X5u0gOCsh#~Bt2j`fIJ;3`upIU}Wh^jm<)6@Olxth|-+ zLqSmZNHZ(ibLXrA4j{9Ay&gGw0H@dC{Sy@g6Y^%~K%jtl_fh=`+uj zvp#>x*d1i8v3`V^95Q8d64pVJ#>=28HT*d!2RzV**um2k4clQBDhEaZn$YSYllhZB z8ltGA#UZCOqGF0Rs*KlBGmNrdoUn2Dyh;>D zP43g?51bnmho(NdLh`EAS8~*FzOY^i%l&PpqotW1jRz^dk*5gHkgsuT59cH@#CS>lK%d+5_31 z(Eun{95lQbUUK*vbS~Q?JXAu;m{qo|u(oMfumob#Zn<8)5~}vpBF}ZKcC|%QyvzCM ze%`o;&O3c`b(8!6UgW8kd6e3KY8zcW;rT`!wJu5(z<>XgEn~F?{{Un*l;j#<|Axkd z#aXB+rx61k-Z7r(&a0D!yF@!rq@sPCN~O}A)Q->q0!J01NLa_k!|@V99kT~`pJ?#e z(^1jUuZ{Z}?fia!=w#=`8c(n`U}Il>4z)MzZ?by5B_twUo6~Cr>BCU4^y$&H?T7CL zlAB8Ud>c;J>Z^(_bwpwOHT>%;aOUjRLtT8kqm3ZH-7zQD$(9NH(Li+j$#C=oQQvdn z_hj@7_u71Kj4ohKIoHw^)&mYwl{|OBK#MI5s>3^0?bWd0wj4<<|3Qa)NNWgdsstj@ z)(U`R4M9b7_o}c`j{Q6412<&{@L=9BbKY>dxuZV-Is%+-)N{Jy&D+HJnCn=fXh=}{ zdEYP8`f~W{Y*hfR9jV5P#33>+yncw@yVgU%?_^EOeQk0F7tCh~3|tK{Eus$$^ifiu zfLj;;Q4!3tpssM?RR%w&8!SAda{RcE_3&-6(wI!98JDR$#Svn41Nd;_Jtn;00c^K= z?E$3{FL(Q~t0j}DZSV*WWStKfJyR;;n2~jJR|sPBk#$OFX2o)MrH`!Pd3uFq@24G_ z(vG7Pwk4KF80ydaf}5ik;}}dlMWl{x&J|MJktF4E$yV^jA1(o#dAPU+9^iD*S&pY= z;Jk0(Ki@2TI8h<|e6z=aej-BC4Q~H67Z)yb;tf*|_7G%0!i0kdq9LDMw|Fg}nLAMO zOW3_1#?C`Ke%VfV1LDr$^Y}dqDSsb)$3hP3;!LN^?yp5EUYYa=A%z#+$bn|`P&U0v zKM`s`ay()i0)>Tf`5xeaGJMu4v(unN-t?u|(<|J|r*W`@C6-+Uzf zJU9QCe2*hSE)f=|rt-gD7wxekpp$u{MgMrFK` z!{v#92}L@GFpGv~qE_g^TP8o<5z^Ie1fAgxQyR}+VH}jlV9T+Swhc09n~>4^%ocQG zP&lSzq>1*00PzRp8wA&@6URIrk*_+VO!@S1?tL#!Mf{f&3`<>tIOgq%7iV56d(aYe z|9*Ym6k0h`{{AS>q?#`j*Zkw&hFOOw-tb=T4#-_BYQ+J59Pc~-e~Y@*R33_}{wS#Y zKZ7s+|DrDcO{)B}YvZSV!^YG_#nAkp{%#dndt^xjUtDfS8!&L090Y;{P_#=&gGNH1 zPylHpJ|MzskO@!F zZCOExOYeO?XWX3{)m-o+^2T3E5)dhFfh&QSC}Yn-`OED<<5^vlpiWh|S>aSSR?E~t z!LvHODv0b<7>01&OD=K-{o9=BE$(2ji zQhe$__f?J_1hv1Vf) zL95!SR?{l(%?dG9^9-;ngGkpUYr54wg&4|e(B6s5uWLZepZ5$UW*;DSV+5g=Z2f6z zU77n#(IXkSCIyzOzrw(=rlDFaMN@^gusm&-lj2_U%sXuHEScetW(tXI zJo@|WdZI`;27a8p5AGTcjQX{5?)y$z`qfPCapOO z#l8-j%u0clK%@yrn&kv#tUuwdPuJ$CWBoM59hgCIOFOx5N9w0rklry^@e8jiiPymD zL*KkChz%{fqB3!uR4GjU1ZC^9-Hhz$9RE^hpLGRwH_nOweSYB+dy&;3<@cp8GL8MEyjA`TwK;h5x=)#eSyM{KU%td&jmY>&h=FAn-QfFV%GQ{eqw(*oDqd z!_aRY5)ptg1BRED@F8kD(vs@5ZTC*^%fD$mjV8%@0e(>o>DXG36*!RE7d9_tcAw#N z=BK0c{{X5FItf{ggvt?~ze}~TCQoQk5h9=90*+UL@y#A*8TWC}S zlC7{1ZkWBx_LnC{8e^ZX&{U7mC)4_2#M%mVB=9|ZYDaR%)3zqVLbmxx{I5U$g+hLZ z_WdVB&&t75TOIpx6NAjn*E_+PW6WCl0U&-nTNk@ic7IL^&oaoQ{J!18@!x6?ZYbl9 zElW=&M2qOTOY1rRjVCHFMw6ld$+X@XQD&|EXbbsr1&_o{*05`NV)SIwOS1*Vo=q6y zNK7z_z-tEnZX)lVZkznu{K34nbo3d=Z)|W-nWh@Iu z{BnOS9W6ZC+=IPUoI};NjKB;Flz62KtPu{X;&~3dCNgB+er2^k#8o9G$e4e?#h5Rs zprfT#KH@6y=3UwnkX4<2Nr^21*EHqIa@SD*Z)E2mWVx${0z1{uVtM}g82_`y@~;Pa zsN$p?&`)y`pb09d;JiG8v<%L*$8Dwsf-Hj`&oo`G>)2%+Toc$Q3%p+dzNwAc5HN{e zDOqY|t=!|u>N|LV@FmoxcKVoj>PXy(9$8AF@;28iPcw4nIw7W~nX&Mf94TOkfOD~4 z3JaC=p)AXGs|f+xD%tm-wui$EOoyPder23?%lgKt%)w|?%NIkG&-4S$Kmo<#}IFxP!jlP`g>xijio2&)Dn zQ6ZGyH3UJS2eSq=unoG}plFB}^~th8+Za~$**585DEjC#U$y(;v6K7|NC5|*B+amas zxQlS3I}4Ry;5J164~SikXF0i1OCQ{xiJ&h_D#>hruQP6OAKjkI@{y096vsq=b>k)y zA6OCpwN$db&MUm;&U>XD>ruV6-4Wk~J@z9P_4N$f9Nl|Lh*go$M(0!2OHwtAZvtLn zFdfA2k5swz`fy(Z#`jDFxMQ4Q`u|1jALrVydUc7kAHGZOKjyn6?MzJVT!elSsQ;6+ zO-1CmLoB7(?JUq}`7r z+Oix!2O2<6)OEp^_j-y@|KRXti@8~i{rAPr#rrJ%4#3oIPha!Ja%@iuDy{Za`r z@1i^JLCaAOYpaelTP*2lQe1C+R|Da1iVy*>MIU1<*~JQM`Ks*3V{t^ZF_#nBDwM!4 zs~a+gZXcbdbMIDV`=e>d2Ti99dx!|qz;fc}G+XhzE6}PF+tDX{s1WHRR#+@L5`_K$ zfiD{klrs<}jJdgZ3mifi%Lu|+H_pI_oqBf=v$XFz;}VD2CSR+GRIknq>N-e^mayvI zT9%Tl3JP4p?NeY=SGH#wK+5K-dFGK})a{j69b(w!9`$W$TPbME^Ppk;j$|n2Njbx5 z9n%7aK$50Wa-nW>l>$>qxi#0V96*1R=yNwMF`~GIYh@{;S!Bmutj(OKA8eY|Q)ZWl z5|q-aFYQ!IR=<)oT-|?X`IxYij!+N{NWw7RO|(N-KtmI;GK~-{{dWF6-8MRf62tik zLHS9|bRmwxBcKM4Pw>r2(KV=QO}a-EhIxI5X;8>T7Q|QVkYoLMYEySvR1ugxKHOTW1QX&1H0(t+tm>n@{Vkb6#F zlW`Ujbe;&TBKMsC_l#eY4tfVzME%o!UUZPaSYE;1#FuK-uM&Q zEaevJ+p%ChLsKjjTX_q2f2B-0MgzTw|K(R$`COu+eV3kz?-B3F;63QyJA4L|HB@!C z-^lw1b@)~mROEHUat}1>p|ozeEEqCpAmlDdqo^Hena=d(SMUGV$?%VL9#SJ?XoC#^ zu=rE#^`9Nd|1hxq7v1*XH+GE{xKGN_=l5q`Oqb3!Oyig!kYT7pI)hNe*g`!^MhI#_ zz=cHIAp!6;-PoK~s+PEQ%?hB}#=26omg!iDgs3*H%7sPE%6w;6bB%3HtD5$wzyIv} zws*R8K=c>?{_olMn4P@Y>`{KdT?j;3wWf^jt^QWYtDc#(0)CXdrQ_>6aNoVZyT#C2 zU2QVwmv)ctGFpclm)Wa((4ja(GG)0R0$ZI59H-WhtL`oD!GZPmy5af;G^bGD1KPML z11zQp8tE@VU$ynY3mJ`9A!<`0mZK;+E>m&}4g|TlK0L69i zFWev=rJVHuvNC9MLY$x+acG8H@B(41STrQG+yYKuodaLHZ)p6;b%23^b3wIva(%EN z=bfFMgFOxfUC_UvgiR1s%gvMd%V+mV=Q=6|cOX-3jI$D8jHLhm0fL!$5X|`^Adr=O zx{=anAP_4Sor9fd3+caygx{E&VSYZaD5Y?VtTQdDgXNKxQZiZroHr`(BBwy&W;|Y- zKl19$$w57Z3OQjYQIXNGRN#ztSEN#9Kpoo9S{3uJ(#Q$sp}SKG6$CRiP54C>>@+=3 z5_~s3k5YPf7;;ij0hX#zk&^|s4^Hj`o(nWiYoW8y{np)SI(e>!?LrkhRdB{KSb)f+ z#3Bt-!V3_q2D<Oe>xqNr zV{pp2#tMqEsHibgv5A{An+6shIRX-H`3uI^5vLT$Dw{Ebj(NKDL|cuSCrpa07$t0g zfWyMGpR8wuft+)Nj)Uc}#~af{O&#OaW}}qd?sKi0v;hOw(#|Nsod1dy(rO!5^<`-U zjBGPvXsF@%YVKW5BL?*#NyCmLYyy=q}`v zo}t~_mvSurm%@3$GzsTd&Vetu&H2MiBz0eeoDPP5rV2$=*|wlMa5~v!0ll-<+NLo^e2)%aO1lAl0mwMv_=IH(H|E+jW9SaY#zl)9|9-~2Maok@<7(<7lWA`L98|q zM00(BBGp7dfhCd6+WW~UUtMg|t+NQIS7h+2qx;hmV)lW4i1{oFDQ4?xnwb6QY8ZWM z>y(w`;%dJks6(4RX6r+W>2V;&gIJ3LNiQjsXO?}wa>mnim!6CRW-wFbxc1d11Ca@X zt&Rmt8&B`CvPQm;QGReZHfHPsSaKG3>J=2^(+ixuN#0qsz(66O5GS;dhJfRKuE zrvpwg#jaLfBO$5#J@VKrA$KCa{!G&(wFRb?a%d*aAZWsvvc@3W`Ub5=;A)~d&408= z8w9YV4?q@nGM(0cf#HO*bDqK2ude;E_3iE}cqVC~_Sz|MKg(x&W4Ex2p1)iGr_q#= z#4@bLmtbPbdck?n59TY5*LmQ7TO%1NPP1I!oxr@uxRL);cd0_0TO z1O&rT0uJ_6p-T{PA2sXM)JZ1~Mcki8tq=(NTJbc?U}}#U0P;;)RvN;0xWPb=7d4#< z8#nC$B+?W^1&iNJ%uJcVBg9b25Mlum+UY(O74X{-$ekVkDAT_%z7feI86yM!)*x5M zW|3Jv(iv3Y2e^OCA9!)Oo@}A$ctKhG#wu!~Q%<5!x?;)2g0f-8PW1{lzoQ|c$%91= z>#EUCgc8~Mf*l8N2Fo8Qo4nenzT zC7)Y4f_?@8wUz@?qO`MtG8IM}v%k}~xNtlhAHylO2%R(2BW&*XU^`8i$!Df8d0WDo zv(}q|bm&04cP)^x2TtE;6}_&}n&KiQM$kfnv3V-=-o3YAoxtVGx1^|c=)ucrB< zGu7+-!wSp_+a0HUNHd_IhOdU(jTc9?s@x-hzS)CIiqa+ttj>&)cJf|A1w}k!XTs&~ zkh)o53hjRB;t1{@sN^N)gewC<-z92k-XlyfLmKNpH95RYRp~=%lBDeP8_6#a* z*N`9d8ybURBhJE@y=J%G+aE8` z?jB0+9@86Hr;dsjI18^}Qd1WCeeYe(tSefACRT)pN%T?+Mw2AU8WG=KAWAl5Q*u&- zO75A*`z*nh=9|^77duMJzk)&<@s;dxS^aGL)>C{gwL7aVBx|utsBkaI*TM&Jwz-tN z=1yqaCmH?Tp1ly?0h+O+^lWczh6^)MT-Szh=5S6TGY?Oaks3}ngjY4VyaQs6`CWCM zTNdBiBqu<9hF^+gKTPz~D-qJh-flS4t0Cpzq;{ql@<09jiNUUte%9y2P~hJvPtA0S z0GyDUgU1KYLlGkbw`;tqCz0KLc}wmJzCMoi%lHp%R+)Tf`(-X|B%ra8%iTp+a9AJE zO^vT5%c|NJX8BLlXN+F2nv0ZZ;3uG;6fD2IGt$&aZl2DF6oUjmv+~i+^aZ3z(e>F% z=;x8?{6hQ})0J+ig7wqh-}L;3yV;me^or0;zAx@_`^>r<$Z1Yt{T2`3-IX2)4Moeo z4TxTer3Pgk8~d!g7m~V;rEls`6msV<#I$1qxng>6^oNIb06Cp>QyVM5%gW##xFkKk zcilm^`DJgXuLh?-!iimUy;OJ`@eiMWn*s#CLdnH zs8xm(d`k{<%UjRbO|BaLc%t8Hm=J?nFsw@ZvawXaPpQ!tC)ifaI_XR0j9|WUX(?Fb zwC2sh?v=NtlHo#ftbiI5ITMq`LKg|>@$Sx`g;Q2%bN*Ze`4xJtJ#?8n#Yfsf%Cd%7 znA!J#^ij!1_!u~rRf3rwP2;k_oK6J&28`Ifj!tczn?5A$pj}?Gy|`8*i5_CCd;F2l zX^J5qbm{J?oDB;G<%<-gN|745kCLVNh>-Wr8uK#WDh}Z>9+qD~e#Jd)(d_K-aEi6IQatu%--Jfi_J+f@berfDS zSEMbOm!WV+GZ=)XSt9~W)XX~Z)AE-8=~LVX$*eU$-f#2h8$8MRaNzZuEje1*qu0=p z-I1^2F(4PZFoVp=JzSHo@ea+?JsdIqq;v4&Z^18`+UqiLOr>ePmfiL39QGzV#0ap= z>V^ll`z1C-7bcTtaIKW^8wN=a(28wNEIP{*japbh>O^rOMLdM<>gYG54Q!L(Pd5wgIj(+b$L8VwqXDRCVO+nAplI;bn zgjOGMsO#6m+zAXD_!*OaP5NTmtonvDk%ire!QB*yWQX;dwZeUqCd3O|jkBOZ_d%pC zgM2}Ob+HXut0fu%U{)PkwlB}ujwNfWiA?ubJStSx@t0_C0=`q}5&d;xOHXytQ>{Oq zxOu-Ci&S=}ySB4z;^$cMK1P4s0%4 z*uUmBHGFeoC$>Exuy0=y$%vo#A$UoOGW_#mciSPqXgd`jjJtVbc2GLeJO9Y?_it`w zc!%H(Z{E*y&Wvu#7Y?FiNVwoXAUrz7v@R%4F4!*^x-vI=5(fR`D3WY%9-|HaIE*-8y-nb=?JgxeUiOV`2rW&&##_#J-D8iU<+P#=2^R4eReqf%gJ<;IH z|BLCDutFwQ=fdq(a$#b8ceG&r-oFai=VfD{agqa}<_J^`VekmFasWK|6aLcp3!(uJ zuwvNv#>s2guVwk;8y@iVCsaG;73o!iaPmpWlMc}}8KnEAFZ@n+$#eB74)9J`d=$Rd zzz-I8as~=L>O`#!%euvI!SK78>$>gt!-Q}W(K>P>OiLon@*gffTArwgC*{jv%=sz> zr(Xg9bx$Hdi8lE338MlJ2LX>gf- zAHoA!?!_Td9J4$xM6wX|V^^o{13rOR?ul6LksP{Z{qZ8Ud-EdnD8u*9e1REuK&stO z?ScE>Mk5U*B~jro;sYMZ`@GQetOmHYl!Op9zE>3|lEg#!)`a24_V6RMD9_7KZ^XYF z3WrsoFv!)1J|62uYkOPIVfl><2kL|=7cb|B!{ zEBY|3Nsm>20wl<$5I`ByS6qKlq=_}j+{DlEq+}(lPa59<$H5a2c@}`2YV5cmLLEcI z#j8>mq?V|3fGlG-BTSZ~Y2m(3>OpTCO=c+a+%_Al1dRMLYXOkGeYkrF=8-){4oo9k$-5*42T`Vp znJ_nketAV}z~fkQ9<@jjU*+NnKNCC`MM_fFA zUtK%aT&r!1T3+Adw!Aac1GuFL;mnUT_f0Nqgo0sJQx%=J&VhGE{<;F~m42hz0eC3s zmT}K5=@e$wPA|t?y1VNs;msGT@ZrML5eF@>;Gi#{^Z}D96ZJ_G-PvHkvTRRN1>A~J ziEmrTU7xJFY4sAz;)dnBlB-&m%~aKpK-MDeb`$fGswtY=lM9DUZ(oGQT^6U*W*bBB zcH=M@upbh-V=~By36q9dE!-(WpBtE7Bu+{1 z>sw@vM@FoPz^2SaS7xIJjh|*oQt#_iA4FVPaOva0otqi(pnUIhXI7K#$p>U9EFmmm zYhh@C%9*O8lBq$CKOByn*5A1ZQikoTc5Afo#)hn zi-udkv@N0cw?K1K61v_E&4DqTW1WN+1g-&&oCQj(b%>^7DyOZ1d-_;gtQ*y>WPj5M z+u-TO4EoqMfKpa5ReVEA%2vxTi(3^ale>kXW?fqoYcJYeDa>!9ix`&4lebnhCwLGu z;*BVP1<*KI!Sv^sR3M%o&KQju!#+(gQ(YG@QCCdpgSzC)I^;tt;#gzGFLkbDfIw&- z@Tqj;Z>cXo5ERQZD3)hPJUf?{fTI zpbZhfk8O7FU%&muB5DSyP}7qF#PP!Bb`Vc;)4Q#L1E#M9$F+}rbJHgE;NDFT_*W@G zf#z8#4dx%W!`c=T@m6k}%%xl~xP>~!mSi?B5(|#qsAATsn+LVB=}8H5j@^l(Muc*g zY9aTu3sKpX2wo(`Ov-x908AV52+Q~t%~W}7eAi}eQG+qv`&t}K#_A#gfo;LAWwar7 zj5*ts$j7WCI-%I)n5bVdFXIqQWw9KtE>1IChu*K~p+Vo)-KRf68|Kh<`89REX+2D* za;MbLK$B$~h6(Xnj8=qP5c}eU=S3;A{K40JVnwfzR43#WN%>+tU!c>+=9Y;3;^z0! z&2j#~UVhT(w^c5by<+UUzU1F{Rvl2K+x)@5O-<{^(@@|FG}6^I8=2R%$!87h34?#b zo_%2ceSoXi9n^2F*ELI}J5pF`nO`u?s8#E+N~448&TyT?=V;KOY?(}T(*AXnCbF1- z>=ek~qvMHwG~rF5z8y~f5iMrGlg1CiyDE9HSf{vGH~uMHt+qKdTRphQ|> z<5Z4=Rq14z^D~%{Oht;UmA$1tQtk9@A)A|VpzAngTP}Y+DY!ocuWvca_#~RsI80^Me zoAIqn5yjE(?%5!=KaF!P@JyqhkxVkzd3(P<21h1@eL^ZErT*X# z4!tG{f0TQYQ#4%E<5l|c%N5nxPHb>wejMfwvUwE|OG&E;6qVVW{84OCv zF*lGUdUct5gyajzexfKXEy{N0ArsrzG+%U>yDfNl^05_BWDpaKt9 z=+cF=YYT1MLX(QG^*JO~DMO2=OzD8gDqazyFjsEnivO8*$0Ae{e9^3sYE`1O47O@n z#;g*MRsq|rWn1i884XmKEwt9FD(HSU3Y$jOmd(D#G6GHdC7bdjp}fpU#WNLOU3+=d z%kD{CxcsbSp}HK&LJ87{2RR5urYob}UoYvBC<566O7=U}X~_-27co|;yzIqy$TK-1 zb7eSp@E}z5i+r9KmyIc04AK6Nx|P6pD*&re?~7(!8A$6{tW&B6@W~p0vrK>&$v}Kn z;Ib>gXCdwiK9EJEyL3%bIiO=V-@tb)*@)BO0A|Hsm5`EncO^WqF2s-6gNqVVxR}!g<#R?ra^op;a$XsHjF9M?w zvWDH*{_rkakexm76qHoUPR5cbca|=;rm7;QlA)1c(y){=TawXKB?U{VW>s*ych1FU=`gFD3Etl$f^6C zA$WGwevpLLw*1kuhSU^8l1jyctojwxlBFuyHBF^&s*&o&s*|?lE3x#xn*&avza?+? zD2!DFH!t!?T&XC2%JPVib8nc#Eo8k^R6vVu$?K*_@}z3`XVJn|-bkQQAZrdp+sjlR zziIpzkZO69K&ns~4r?}4b`g|`c5)Gvth3HhNt_@rzi^5#j@iBQ%P}KXUGXuMm|L75 z7|UXO&(1BMj8v_silh-(lryzz6bs&US#QX|*3<8KJLp}ji|ukj|8tchH^skxtSfJS zA?fe32D6EDnyuhv`>LqK^E2zH4*ldkO}4Y^s2&%8!q7)o&bKB>t?Op z646We;fDMbC;~iD25zDlxRoP_N5298RiZwnln>bc5%p_-M18jZ$W8Hoq&s25pAxM9 z*6;q0q)*CNbc_CgkQtlnt46jf6hsHM*pmRTguZE_sAD4)1j44-VCKKic0YVDD3it^w4*(Q!_v)94 zajeCYEv^XP!TuMqfA~+J*)Y=Kf6$Wt5%$^t-w;zUbox>E{|TAGq}+f23U9Cmf{MZi z*rFYdPLmQ6`p-C`kT)H#2M-ia1FB985?c~E-iWfOZ7^6o0K;v9(s+ztzcrt$5Z5M|*MsQB6 zN~SDKFA1sbb9>sWhE_cOReG}G9q3i@N?e=;HN`_H>Sz3EIew_W9+>hOjcMmGld7!R zyG9pVU&wTG736xPl%7DaEQ-8!l)HtX46O|(^})4+zBn8_BD040;+MPGcRPK5$^R8& zLVWW1sUOqC1&+2r& z=z8|ssiFJ&yq^6D4();m7GK0(Adi@gFyHs^*>RPcztooLPj{|9NU~e6zd;&LoHodC zV+SIvH9Z6p7kTb5GxhLzOx@D@lLc7?u9V2bWh57sqW3cehAFK*QGbvs9Lyfd{Cc2= zWfqwY2C}9dy`vp$t;Oy+;u@_z@*tVj2fFoxtlS7=u7!WgJBnHCeM;bQ&?x9^vDF9; zd&97rBM_F?@C?jF4WToY?N+UUE^3B_7P%|+U&vr#5PY1){cfpAev63I_y#qI54U^DZo zj35hj7-|LItY$UK)YBV8vq^)rLtWF;ltbhpMR?o_zzIyPHUl)paw}jByRtyG@b8u( zmVlyB&a_&ibd@R0qBvBkByzM!(>|v7%H3)1ArO<2XTkrMgV4 zE(7!1KwEzfUa;v&qO#J#Cvn7VLVTWFnU9cQ6Z~2Of}%dmL3}#K*5h0bPU|3U51mIj zD2_*jP}4LRr(EH)`A9y+D@agGg7kJF%ytKSNk)0+7ke+~clp-x5#&^)FJ0LEow9=Y zk-Yax%3iiq86qrkJB6iZ;#L~88^ww#l<}ccX)>w=Z%hqnsR9Zt{a`|a7--t0My>q* zRCSmQLb#)G2PZXgLrc*Eb96n_9xz`tX?XG*hod&3%u~lyXzCqf z&afIne2)4etI^`ncV(({!dZtqw0H5rmcDRyp5s}~vuCPRHNUl%Nb4qJJ^0OS0$b(6 zL_K?}wE*&?k&USsBUo&=!0l@=^;@#glGXPlkf?2e@Wo5TQTYwAyvhqy-?T$_4P1gE z{5@mLtK=wsZdZmNZ5t`EYs$5!sZ5~vP~UXezXK;stFt$t&bIOU)IF@xkQ4GkS$%h0 z?U;jjY&??~Ez^XY5G+skT=_I(>h#S+U|T`yjNW6YY|Ix}3J^1@cgU0KT~dDH9M;YE zq5Chi>bW_fC#I3y79Xk|zUW-@5vUgXAH3frhy*II{UicBAg79i?eu_1<3wuHMb&U_ zLMX4%_^f%!9x&pbK#{*M~^ocJ;OvKtUX zFL3@HCUarzW!dRISeroh$r-eP5C5}5mgH}s>{-38RK1=s<~iKPyaJ~cx33YA3fF+8 zX={IHui{9x|EfPBaIId34@_twU>bBFnF9rAALexNoY3h2UIw0Jj+h!{FFn1OrPN$1 zq}AbRrq@t_`=BI%YtATfL&1El_Bt_#jkvcaS0xwAecF|M>6%o-D`P?b89vupz^bvi zP~#YI01eM6lbFu8Iqlf)l8>igwNsQ5mHJnyKn1=bezDP*4sl*k?{H?zn?v4+{-G&L zx~W`#M4yVt`LDT6p`i>W8IUkCY~2)5T8z9DusUbU-GHiKP3hpWYl|1H&Xz(|+aVPu zSn*>n(RLB#7hpIMAI-*Ra|Hd--&Gu>%6KWc9Q$-tfA(s=s11{=?D{w4LpYmy3hl~7 z*%mnSHAM4@GXyuqv`>yvfA5*(d_*tZ;zy*>NsOat%YFek%*}o3S8N%gnaYgBe}AxC zC`vZSA^+GvY5vn$3IBMo$eOxX*#GlxXwic9QCZIX?wMjv#+Cqz40#rIWJ(677X$_o z0)S1r0ShLANhZY1m>SB&CLrKbM%6DL7BBy0>bkgfj;4!QOwqZa*1E2y-J;cY<%Ylh zciq;v=3=Gw={wiioXL|Q`KgWnaNBu?cjw@v_XN}PEPjVaRAli*uk=o%yQGqJ4lO1e z$xKz60xJr9N~8O{@_6lUWvhlWg;EPmJ@Xs_leY0Rolz;Md0F{Z7Q;bcfhN8!?C_wO zfi($F=h!yaCLq!X^WNJJn?tMiC?rXxGcyO*v zGn1mM90p%JMC5f`n3n9ljB@p~t381XbdX5QYlwYjWP6Y*k!oT*m}NtB<-`>Zq=;6P z8peY?i)erbW`w%fHi0B(Jq|23>kOOi#z(MR;UXTBGNsaq!orJRj0&cbgA*;X+1BcH zwYE$aI7i0|8d&xT+G3n6iI!GwI=U>G<2`<&pGLtmCEYq%LMNDqiHdN!vn))DQ1iHj zW(}dy6Fi4SO2IG_>9I#Ls=_QG(Nvei(Lcd8OaAfFAVp-tE({lRu2=`gyeA-z0xf;j-;_ikQ)C!f@+3+4wx~qhJPhO=GWyx6LmW_6W;|t_u`^w8u+$)bj{NTO@s7o|gtJ z&1@!GwCe2%Mn>Ig2M;>kVH#YGxgMFKsZ#?%7n)YP zd3bL=z!|_fcx4d`Ugws{B=1XKH$=fbto9s21nJX<%5^LjOjj_Q$AwcjatdK&$ICXF z6tiO_KbKZ14Tk)j=^oZ0JcS60kg*|_l08SG&N*6;)C<+g*}ae|1Z_CWFh28-hrVw! zCkiXNtIY=3&`_W`e5TdGNbG(Oce!j|91t~vn}|%QrLgHRixzGH8wLz1(q7FT#Q#Ux zJ4I&}{9C(8I<}3DZQHhO+fFAPJL%ZAZQHi<#?{lv9cTqR1F4m~AY82+0 zzh{nX30HD<(&9$opq7M%0VVG*H4kgJ%x3*96t>?QJ76Q|6zfLK*e>+CRDA9P zgR-0F#Sp*gu-DO`#05PhpeL6e&|dcV*m*%$BvRxTANYyM53Zpzsw{(&0_otvh*t@} zs*b1?pQfghfN+M{9l}@v$reDKu#W0`!5OeoJacs__zdHmxuXVYf;ty?QOmjFr;K%X zJ49B3+8ALXOkq(1&iCWn%roP|b?^9EdxjoDq!g_Ibksof+G1*W$QZBScxVayPzl1+ zfnV8dk{~|VwYD>;;hy>S%M{OMSu7%3hQF^9*e~?ZvZnT&IbD?SQ?ME}G8seV!tHe_ z(+Ta@jI>*xZH+4*z%i@>m786uSo4(iCPm)U($PqiQrST#4Xh!hSp!LKE@J&%I(F#| zYZaLeE#Im$Z%75=-F#lDs#5L79SWBP@>Sc}1ATLaPtkx6(0u%v-EE?S0>M8e{xvLE z8!W~<1-DE51{PD*Ofqu>69o$W6X;8$)fH~V04jv>37Q*<@~DVwr2QN6&$niySB5Wi zpycMzy0Bw|GP!Ua*Mq(>QAF-{kHy3{h$K;_!$OZ_tP%L0nbEJkS6E);n|A~+aUf3& z2QY2_6v}E9eKqshniKxR2|vc@lcLH2{7q>R)i15n_G&z;B`{>dEV8~^_6Kc*PxdYZ z`CtF+-u{)?-=}63+F5D-;eWi)C^e%(fNRKs|ZEN%F z0KXq_sGxCfW?-938fWEr25#8ISn*}xNQ0@^S=a}ro@Lt0LHyYCX$nZNov`>Z{_$o) z*qaa^B9}X>*ydRgc&3JiPUxD?834gw&VqNeAvPZqd2rg9nEl3;#pF>URiT@vs-54| z@qzd9&!gNm!W}dN-_=DEX2Brt;o7KVGJ=QShIV7qqEt7q zh&5dlED?d7Pn)N}ung{-*Hp*M(qZx4Bj!g;M!_xoR?7b3^F-W>$u1mYd99z|sGdxe z!bvZ4LRWUZWID>vBLPffgEeYp_LSv59E(Z%iD32^;Nu@^9?5EkcZq~C&zXk4~S5_@W>U0Om`AN<>oX;;Oy;uc3?zL{{T`Nmi zn~#wwbVjq&nm1*u;O4SV`qARyjogbe0JImb%=xhsTexfMT!~?#ZXxNa z?=^l@a&8idbn7W=Qmio}lzCH|^LJzkusB(*XX*>06`)sQ%OTjVY z6E{T1@oEKXiL3F3vfluVA;Lu;?o~Xq=(HoWwROV2CrxTRk;0dbjm+iq9xhM1*fBvC z$V#DEh{p%Rqq1!x9^Mr4U2x;-*M=-QT`;8zU6B?+Ui(_*+oV={;C#ok6h_@J4HRn( z+7X6IrK`V>K2aj1K`U{SC1O?EQGW=r9x9z)_Q=Uq#w_6_A>B)43kzp_R zQ6mX3GsqUy>xY66uU!l|)4^`OqiAbO$rtB@+z{8N!v8Ms$t`_rKuFX5)dZp)dLXiG-i}Xo$v;_ zna)m&V;BrNA%R9)XauL-IKE_)UC;TdIhbhlm8qHCr6hsS^wevHZi4h4WFXL(We)@2 zR&xl#$;>DwWx^=Gx&){l&Vpk-rtDArQwDtuKk7Zg02z%u;Yp9=t+0$Hy#zmO;i#mS zJjb?S-5;07%bPpgHzO&78nwM5!ypsyu-UwS?bxIqgP_9LT@?ZbJ6dE(Rc`WkT$h|R zZv{KD$V@emfS?5pYD%RK0APSjlCE|n1tjyO0Znsq|9$k>Q{#hloY*%f)eAO1&mG*D zk?TYPy2uR^)rrL0J8t9a*|L*Ys`LXoD83yla%&%l28w-iBkeb6Fj^^IJ46Li7NNw5 zx-9m&HBiRyIM4{SSZuY!KE;5Lp3f%HJ*Q7iEyOX&lb)*e3AAl4SS2J2W=#o?MddbA z;f}-$rCiZ>L233MLG>$RmV9SL!P;J?)xSP5rHqtKb>lSnEcpO4)c^(f)J>HQxcK*+ z0Cihw*1H6enTH`p9|_pSUrFA2bgWj7A#{iNgs8_~@yjH9if+~OOCr2I?lpbo4=hU| z9KORGMX;ql=WLKTJb)}zYU3a~C@x&T=rP${a7DZ>~Q%*>u^ou?pz_+BX=WQRXFMM;Za^+9u z-iYxGAhxDFT@dX4JPYmrY|9gCLL6CxHn)=P*qqljIDgQLhu3#q&?L`Jaq?Fa-8zk2 zUDOJQp+VV&6#v$h6(A`4f1p+Jg@HUGy6uG+g=bo$fuz_+eRBNywBWyXD++FH{1+wQ zi8?c488~Fot~#Z|mr;d4jAvdA?D*u$gF)2I;t4kxE>MDyw!OhWnrX?J$yHzuy0!px ziRr;B=x2VrZgq=&EuPCmYPsYW5F;sPD%o(;vJo@)^u;t>Vj5LKk|{qyffQO`e!~NN z(G3+OPsGUw<2h2t6?Wy^E#Yp7z~t(O@1qY?gR;Asvyy7OcqiH!F@H4M*$t+*171VD zTOWZj<1b0V`TQcEF!0p+4K{8m(B*?(%JW`ZX>hk`Np(|}GO;b})b>i1jq{#E~%c3V`v=UV3Bwnh*lf?Bn8Y-3k7l#)zoI`0z#M+Ket-SM4aEqEg{q(2Z#qahmE;`By^`(4;}@-En!Ur-(T zLMxBFF48+A+3FUg`Oc9aE|N9=XRab|IAKQw3%VXV;{3qh3%T>bev|>S{Uew6Da5Gy zS4&FlI9H8!b`^Z%C*BM$av=>p30Dwu3+}YaJ+NM!TV&J&+8#M%v6r0bAR^;9?J!A25VkC zJ8C_4C7(6@QElPRT>ebpm(N>=4OX!_a8$71i9QHti6fr_;X`=;QupF7l1L~T1$FrD zu>(b_A6DeyOL&5yS{n?Gb^5kqH2j+?<>ZKl#e-*_Be?H@{`ASG>tol%Q%z>BhkYf? z!n0p!cif3jHO7#!;SUB8$utu!$;3M_{WVlG>?HPzfmq$hY{fk}GL4Nr1!E8zd~mFl zKJ3a8c(`k)A!)uFy4&g`=p&?4HIavvj^Em|bU1vERoVXV87N*RJp#jn{r%YQK<;D#MWm<{ zg2F2g6$_{%`R4(Hs4y1YqN+-&w6(aH*)ecR#jO1Q~Ym5h2KaOlj zP=8;N2TPM7Hs%I(Y*T}O@R$gUvzB}K_*P}K3lmS9+rWkLC4~?Nab>_|f+Chan46~L zb`vN%dBH``|DT2^#=Vu+lyzzNiqhW|#h?}C0QT7?AFRuf51{Uy3H4ry&qAsTUJ;$3$b$s|h8?CpH?UFK%7t!e6 z(T65&R*+3_n|zJ57y+!Hl|uSG(jI%0yLRZ#J&iOwglXSWcpmo>#IZDxe{th& z0Fs#y@fl6{zZD&pseYg{(s%uEye@QVXAk4ZT}nYoMO%rXNzx`@3(}8`g7TyTV=lpu zu1(q1O~p75jbrIQ#0&NDMfgC{Y+U>f(s->80JvbU&J-433g#t3m8CjtnZ zwBTp!tZpG{Dhplyy9f{1z@*ui2M3@${UK6pfwF^!@Ug{GXmLh!Au7S5x>S*LG|jXAn6IKMZN$g<7Q2ugw;vcDFmffvbx(%nk}#mGTp?W3AMy1yR# z65w$Wa?hMO_pWo{w!nU~*5EYlC@0CgPunMvzrGDKhN=)B%ih5`1mmbca9ohcT4ML< zj=UBRM|`PwmpArO(JDmSiNQ|^`esJaq?tF_lpF7g2- zyqNtEDmA=k7H~dR$n`{+-2~~G>)Z~)I*hN^9D=1XF0gY^=6Bq!!r4N#S%TkXTk5Y` zj03SV5v}XO=wRhdj0{#9!Cpe)PXaE|q4NPc0P1zx?X6Jx2icjiAZ0H%(6JW4p0fOF zyMHn!bw~XCo-kr>Y*4OIrP!q&rz2rIu*9QX@14h*n~XN}f@LZMiBmbiODk*xcSPR22c> zA&7j@8^0qtH}Z_MtgW}#KKJ^r=P$qKZ10)2SkH&cf{`$b=29eRhp9p);B z67+?=a?`r#a2h+afS(? zQ=>LOuPmAheCwEVe3RqV-xEsayyVIjR!CWL=8(v?0TFxEt`jDIr}L9+@Y96~4nNAb z(u;=L;Kt7o!EubSjkqWVzB*h3S!D> ziw1eg^GqRh7%JeKOoJK?+gQp-1z|IFqiY8W=~Wzi23eo!@K)w5OAWCg-I`PPog zb^+AQ;*Izt@9UF4*H;(bCZ=az2jooEO{Lh@=f(7>C+g5<|Mk>n#h7x%SW9c~jt$OS z2V8?!`XX7K9?j|0iEwEA#?TF_riR}EpRfTE0zb_LCH@O{b=~V#$3+ji<5-FA8$&V0j*JMyU6bLWaNHg zFxlfxr73NHIwjW_|NbdsaMXh0;_e8P8t>f_RA;*U6Cjm_&hFLNxT;psBVGAi!0jc z{pv4bQpYAj`dL7HRn+`ow#h3pyl9uM-hDN_WfbaktpN{1>Xek%D7K`>!|T?vX_+X?daXQifvpHbou%Xy(z_jo#qR_{l1KO`g|~)s2ho za=hh7?+7-o46AYWvLr6ZO;45CdX~cSS13Atwa~v|eV7k*a!|(aG>*Bap}ayodwO$K z*l99JVFp-G%ss~sO&I>pZ8bdLx!{8E3z znfQ)rx|Cxh*q_5@HiE|o*pF+zVW^nh4W{KR2@i2Pcp#FW(hh$@q>SK)vOc3KI2DC- zE}NM@yY(9cArdoS#s#WgIu>yFWGY9~TWVI8j-tFq(bVd@!uzKzxVnTJc}oTN)j zW=`B2M4{AmjW#$G*sUv*ONnAlh)r-KVC;iut|Mwkary*ir8sJkJ*i*S38^^6?lWwt zLD%tF{|2{)*UQdOp`IT?D7)uzV%~?f8px(2i;(0QrUF&T>C%VNy6X`jb%tgxF-mBH zg;E$~dG9AICdNDTN@B4S4_l(#{emPba4O=WBeB^vU4*&y1ZZLx&Z{dB4LLLx4?Zoup%Wj z@~jY7#*uKcP8=9yl(YXp$95mBTwj;9ANHn@*1_(G%`cMD2s#>Zh?{n^ecXk8T zo}v@jW$jwsLWBvUn6q}^b{<`H@v@DvJxt%WhE{^*T>KoJ@DgoCsz-}cwAbt!Qekd2JzQDe&wZ8Nh zbo`&<0go*k5I4E_;t{&(>IuvOD~09vA!XMgTe2%&&tJE@+t+o zKc7J!pT1*XPW=!o381_;<-Z3E{vcf#`@W3?J{Hx=|8yW%62QC{=6sd(z1`Nzzn}Wy zSLVQa2V~!RDts_)1@5V5`iwz<;SYiZ?9k54JM*>f6c6y`tgeyJf#T}9ew0nYgl60j z%megfHiJm*$Q&B}dWY*hVQuC7JnCD!7@h*QqjRX4x8^H&m*(0$_t0*4JO&Ci$Mj3M z$J*kb2W;p1!S~UE#1NR+ztIi#EC41Gi!6X*2uyz#9fHk`Q-^DZ+%^Yl|9$RIMB+|I zB6c`<${c=BcVGvP`r8sV0v$sx9i;3lyG^d$mrKNKZI1d5@%Xl2&lWaRE~*qTW| z=;U;qLwA9Y-^eAzk4`$?GND_2s5#<^9K>Vt?%`6t4sj~JiL&=?9TCjG?D>emO<7y= z-S=}C99s7zHH_FI(%=hw>*NkoOT{} zGYO$Ei)q4Z*ypZm=a%Db_ph(#mK|W5ep0YYOJ^FkYWZQ=fqG+Ov2g}hZrkCQ*utNc z^c0C0%Ugy&?|Nx}3=B~d~H zR#$R7`1CQIv-_&R6vy;rLLLgI>_1QL8{rse0Hf=z$sHHechagU=rgPur@u+ol^aPy(v~hL1bU0uW1$$u zl9Q}=KsJ{mKJ*asaEDewpjOfn(?|FU%(!&iR>RK)vSODr%KK=NgGrF_{&G3Zj#r*M zPBpxCJZquY)T$0BXRT5YUdrBcatqR?rn87v1)0aHMifS_|6Bcl!5H{R#*VJRT;%VN zLlH`Gm1X8G-pb@9tyhsN#YUi@P!$`+u>s9C1^1&96&9i?>i zqsE8M!?B4>Ps1zNGc1lFOk%Ki@aPX?ei-<%QMvPZ)hY}Ai*`Rl4OJC2WPYbny>^+g zYv&$D&BoG-GoZyPRWNWy+&MC{*R6*kihR}Km3I{A0O(??gg zFfE~gNS0$>QXeHVfcP|a`- z$uY<|DCDwxF^rLw!z)8@sYGzZ0a6@EondBt{Br;fEE>?=&D0M;NVq*z%OgkEsZ1KXO z6A>K*rRnG96aheEpv<#ZW~s3GG86qx&WmmFWLEcEBuTli!8$40IA!@0#H=RqS8kZN zL>?k=+jWKX(V|x*Mt{BwoP8^+XTp}cC9-Pg)bLEJDil{3?0V|>zaDTDcKdt<;-y4@ zH6yU<@NH#wqZz~4VP{0Fr?1!V8=)-6!`98^8%jPH0E$mFfcPQeTt7bJG>rgL4}sIY zN-kq*znyh^0*EEkz2N~a7;B{?Y3U^=&^f}#_3sa# zU&*4?1$=uw!6DWb5iiwwoK7gTq1DExtTf+4oL|K1Q>w$zl?V4Ae$gy&EVJQSSIdr7 zBT7<3qf|4aZrHcCWn%f`u9dXCtnEe!a@&LML%{Hy-cwOl;lG;GzhP2k8TfN5j_){- zyFwnpxT&{LJh>})x$l~R4Xwh5NE=Dx)AA|}F|8fvI7=ipJOqbcP=gE()GK?m;`0m? zL&|Z-z^mtc#F`bg`zxp%7iA?>x97?=p~8_nqT|^bQydFVr(?q2#LTk}B^GpIATuKH z+EP}Z73-n!OmQu{oy5i2oG(da%7|%c4u86{BJobip46nS20jl1)_E|J8)X=m2L{jb zez3t0wctFJ>lP%Tmr*vJ58!UE4z;MwYzW$sTONafRgS4G3AG)gfUU&4{D<5Gy=zxd z$PP`5#DQJYN<`wj4u5jAO`&Hv+#3J_&rnZ=XgVh@U6q@pogy+}yY%9w`T1Kjg zbg@o~Y@N~3KiA3w2G(8I3;ge2{viSz*BCbn+QPZap~|{_N58i`PHC1o>CK%ybme*u zJHp=FIJa>NQ|u`95GeS+pUu5HQW$blYTaMdA&qhH&Wy;mi|z&891*sO<4oMLZ-uOl zfUddos(KmtdN+95fJ1Kyolo5Rb+2WX&C6bKU1J=cDb{LG+%eygj)UD3DKSYwuA%AC zO2Ubf!bI~^kYIJfzk;!qPGP_whe$y`)${#&*?&V>ImbUNaUy|3f9}KAXk_a#`b0N? z>JL}u6ilkKgp!XQ8*5Bf_+jzGt~+LW9pA&PpR!ssX~)=0dpCNi#hSHgy~eEw+s3hZ zs#d*cA3jJ;lqc8MS)y-7>i9V|2K>(i*Z=51sJs&#7XAgag6;S6jCa%@V1a2S zR-bZK-`ecFj&V3W71`2clpM96ri;%f*ue@J+&PulR3EgNZD%k`D*@B|49go|Smd|o zsQG|XlMLczG)?t1^(+wye6#ju#0xPg)VVFZ>uR3o}4=|=>? z8e1fo@q%-ekzm(-Ho?7aIn*kx*1Rw`o37@AT9Nzi1xyrMnu3A+_iEXx*_M!`zy-8O zNmc&g6!auZmJo0BLv!!N_sx#1z4eJ0lRx@HX*#ZkjQt0HB3C?gt{us2gfASFjy3s- zH#SRWkzF8mb%FF&h(<)f!}7;AiSnt~mLj;eZ=ee{%T|7=kDJkY;cP;=(4S21L{EFF zt_lGBwz`fohiBXaNmnBOtfG8eACU&3k@JV-GXt@mxc> z#LvA217ll9Xf8ooo(Pnb?~(^mFZD;WGef9aSh;agNltB;g}XARPmj49NIl=ym7hcj z98m#`Ut|VQi&0*1HT~Tx8b9C84Gw?GV|d9^!Tq<_fz!A>-&Cp!L!oH$^>?`}ZARmb zbH;x-X?$_m$qw2@O_OO1v9YFcVB>|@J_4@gKpBH-wdK1%IGQ|;WmX!BQBfO6m*54> zSD@6#E|vB)w4%+?MWv2d!RDK$av<%xf9>_&f%M`?-)geB>Sp??s_1B`NeGb*7^^-b zRPx8Reh8Lf1-etqDAoQ30Uhd@ot8Z@%|)Qcc0*L-O$h~=F2b@#3!IMkcX_7Luqe4` zm7MDi!i0C%#iExW-v?wj@^W>4P6Rg>xqsNVi&$2jB#2{${$b@w^W?&`Gjy=?8G7SX?I0t0^?7|M%8=d&el8V(M z6Jrf4uqU|>#x6@|8(dW_HW!5Ic)c!)$7;9YiLrT51+jg)!+t116@iU2B!Wb~rTa?R zm4Q#Q)4Ssr9@Il;v0GMIEwkPs(^hz4ox=K=`n=>9m+GSR>ta3{H!}`mx-N-!iC*G$ z@5{mbk_lQHawT{!z+igUvNFuT_Mm8lCx*$F(h>orn5( zEUSWqMf}9Us>2T#Hkr(*o*~T}_nvtFk`EjQSf^S`+aN3}BZNUYP$m^Z+)N_Hv>c>67Ksgi&)`&JyarIk9(m1;WPC2i2%gKHKo`tC3N z`!Cj=D~-tked9+6fog|Hl53{Z&PdcJ%zrD;|2cQtUpAv^!2}v$Z-$rrGdr(bBhUM^kwj6BCUmr?;@erk$QhLW@HM z4X-k2o$tI`rGPp|Nared+{p$u^gawT1Vi6>3&g+ktT#^r*Z5xG+4Jn(vvch2=ewg% z;Q5qb4osuOjRtZnqF<{|07)KYLbYl>7!{NqK_0;VFo*yFvBxXM;t|bP={^*SY&ZZ` zq~Q7Qy6;C_hOxWkvj|eA<3P2VT$A8gH61TwA>+S zV$3oi8ZxHbcZkr|cQAL8uV~8Fu4tvh$7Azy!^dLLdUWWCyDowM^REK;Co@ARn3aH8 zsn6QIG4g#`#3*i&%h%pwlU2|Ob==L6Y$Bl4g^RFzuO1W4xmzHlI?wogzcxWzX3VS!}fe&5w3Xz+D{(lxTri4*sRoDJ3z)9X1#O+7&~* zq^?vmS%Hh4s-=Z^CB7NI-%{g;sbVbHuO*7mm9RkHe7LqHk}gS^SJ>@@L1J(O7H8z{W-}A&=X-%$(M5B8pJCU2tG3!Bu@@yy3pL1)kwt4 z8XJ`j8KWVDWB*ME67M+@-n1A@C`N?V($pfIceF76bhD@vDr9X=@~4V@R&W+ zwa5J}YU2PnbYUAXMH&dQVTq9>@z?iP_i|vi`++R$pa{w^gZGrLPhdfouO&t zC3H5wEI0KfQpskA@P(BVnu*xVtv#|tSKZCz#NU6-(IlQZPpu{ES0c`upM;tP*dP@790YO8AS#LmwS4dv1 zIM)Ve?2S^XJ0b2+R~>B>W}BGNgRLiBPEoi6?<|9i6pOF^HsnG@R|_{*onpn;IR~6+ z*5;9<55n=<2(zmyo8=5}2oY8zH%LroL4JhzctN-k#bg-KJcQWWBo?GEt^KGSum84% z4SgBA>BQht4w}g6d;%oqfluQ!oFe-+Ukh*MEHe!?XS={gvE(SkpmK&a*Iuy9++wT< z%`AzE#aVsO3-aHNA$d4Nc2!0Hl2e|+yyS;*(Z>|Sjse3nZ>54G6iZn0$D7l2s9|*X zyJ9)B@{l$AqUjsslSK8E(iJML%&u!aIDCM2pY}0ylS&Tc;%=`~uc0GHe8P8A=X8@l zuq9TRb^GvB+JW1bB@QPRf(ys!Z}x}^adZ~ z2KOsf%ok_VE|S_-@TAM2JCN5YOKG#`9f0WbLeXl-9V#ZO9_sDV(}cbAf7xx8P1&h> zY{Q16vE#&O^sivZ{)^-eYNF_9R2bJPWZ+$hG~;faY(bZuQodiiF9l1(C1@EgO5LvZ z}bvY?_s8}Ax<2nyg-i-YUg($RhMiGZp_i>fPL zH5+6Fl>Ql`X$6DAC||-~q5(TSiy6TJq-s|ou^mtzUhu^;ZJtTR^nZHwS1o6tF)ZR8 zR_cg(6*%%9s^Ju=Mmst*kx23^A1B{ev8>IAxK_|+;>L)3ZI%ZTpAr_9M29|}(D5S0 z`DtAw60|Yj`&{8-pRgf6MU_lp%3vC5$rIgZg#UK`HEH(B^{NieKF+9{ioeVK?s-3k zlly8yZ_8J4>CWbTl<>@RKbDd6dJr5lGm(1`4^`BBXNyP5;HP-X9jNKO$hjE17oj-m zC*f9V`>|Act??IJ!1h?f0_;Xvt9LNn+L#nj+x;R2Al5UOp+L_TaRMlyj$|*>vUMby90Yg^6=!w!_WoGeTO%ChQ3~PHQ&KLHTlURut@mIE%Tw&$P;jygp841^4d!drkM0wmH8-?l z7ZfQf>X%n4VRS5J%3fDPtcK9Mrh&(%hK2_9Ccke0<@UZvDFS0yQD3WyDKHsQ#ZXWm zTfH$8<;$42hPN@h;+#WqP3-ajVm86-flX2;Z=8yJpvspuEK8JFASC|cgsb?Iq$7jj zvaHX(&=hK|7m>0y@3t1Q`1;3kQ>t-@a~YSmv6#+U7SC?rvY9nG%9o2$$Qr)h0A3Ls z=bZ>0uZdR6M%#tCXtcs-T+7A9DAK5rLM{^AQZc|ea ze|z4e1eRKR-U9)wTmK6)!kZiS9ORhM&usVNUE#V0KTgy?P5N#b-?cRE82^}w*5OIl zVNIKV^;82;=}LDneA*=E?Q2-&43$H`cXp6W&iQtdYP~#%HetCU$s_W|-awj?`1Ve> zxyf!bJQiTM-kj*E(x*db2ztbf&gzhgziRFDF{R@PWBsaj)LS7zD&BU)CU)%>e}uRB z&gHa_RT#ZekhQ%b_D!3~USo}0Us4!-txQN zvldl9zTFI3b$Qjv;CI~SM1p0I{xt?$0FIB?C@h2v+gtb&)cQf;X_w|J<#C(AEPY4H3e=3}H5cIP1c**5voeRh~y55hO-(j!xRWhOOF{^sBX?EX>x zpkRjq!fyoEC!+0{d^5DDi#wgi2o2se1M!y2TDOu#)rsB8Y&)9neoH%9&6K=$OpM_e_sCu= z$=T5pVL)>5Z}i!d=N7E4bD4me8ox21t@G+=zJLz>CZn^+7=A~dRXMeq$0a8tJeg%; zg|ys!%ST6+af`-z?*`dfPC11^#FU1g(y~O-5;;gosTWDLPcaQEhRpH>6-VGupv}oB znMxR?Mpip9gGMhVMezwQ@dkW)r-&;2YsF^Dwi&Bwc$z<5$ul661*8PKp^s=Ky|SBC zO)E;Zz8nydW3HIP@CXiX((tBLhRAAr8Rb2D;Xe8A?qcF|Aiko*yrMoEvk?AXvh-Hyx^$6hBT4Zk9v-E8*SXvDt~55no9w$p=> zN2F}8TB|xI&&()0J(x{(=E{<7eaYuS6{c4I)$&nUbN#$NcGk1IG2Ioo+Oqu1q&Z@V z<{r^=T}B35RU+~p+S?3m5OpY7bxO_I1{gR)UD_wOLmFCAm3BXyTBUfSJB7NiSiKzn zUPm1cItxa=f=raCBOs78BFV?OA%Ra_nlwQ^ck`U2FDaVmc>s4$LoC%x1?9`lOHG(q zuKbW}t$Om!xk$@!VaN$zqGiK{G1L>GDZ+m0!3u_c&l*YL98pExC|oP{usq4zH=Nuy zDP?uI{W1(A{Q}?IiQBz;Qfyz!+ph|D7eis%BC6Lo=P1~qX}`Cb*;38ap0B`c9Ed$z zamrgvbz;CHk-U$k>8Vj`#BCH;KZ$w!AG6&Ami;)E{WO+-0<+x=mb;d*rGwL50?WA} z>vCOF`an!~xUL^FLW3;Npqs+sFOs7`lTgF?S|wdGuf%VH|L;we=>z?x`bQf(|7mpp zD~(Ln)Yj;~#4+2bI`{wvR8e~*K~u-s7noKJck$?iVgISBUg_XOwq>IaHVFRSSf*r- zlU-dsr=7Or*LHp&nmC5SVJTl^S;N!4RuWk?4&&E07WVDbc+?%`goNlm%;Bb1=<1;4 zkAEvFt(d$a2f{S%f2`+)_IEvT$11M z1(S`_1gO@nfJzfzDYl=jZwu;9=uHpM8w0FL&_t&CRnZ8yhh3#GsueM97R_= zI06_-1S)a?o+`tL1aeuTmGjiHsO5*89@s)(Xwy^(z-U4?7cPbLhx)_e`wLJUIMUhQK|W>?>QcW@5Kr4Hnc zZaPBvCElF4R;cfB(RmudkVshVlrZvAf-1QDzym3oN^ia0Z-Q}X2;jJurs3UP5KEv; zc5}$r*fzApSc^4IXPU9(8#T-9x75473B!R?^*BObE3mvhg{*-o+9NmN+c&CfjGQ1K zqmkyX@}?1M?+47M&M>i+6G^fzJB%Uhc3N`Se@8OM_S0uRr{42PCovvjUepB-bA0*! z|FXf#E43k?k$`|o=>NCbp#O6M{=WuAEvTO|;sZ6jcEt>9s|Zctk{CSs;HP zRsjL1eBemA_zV*VCMaeUP^-)QJvH|Vp{lC&->n*B{P3&uV5n7+R^H{K~Ye@7W3`Wid*11HekS!{ema8`G!=0mO zFR_DV#E9YRaS(by}B` zHOR2x&F*5@m;MxZb5i=|M+r_A#^xkOp~fX(59$ou!r)@Spzm z4lpGzF5~S2(pghj#Odoe!aw|21Qw+?x4v*JisnXyq;_*(2HYrG)C2UCN{mF)eO-Do zGt})6Gu2u`gC0_TKm{|vprZ`~ zDqghQ$$<=Iv%+(;hf086wp_p{c1&w%1S*ub01|x+re&jL=s}>&NDU$@d)1nIH)_=m zi52}5lWaT(oe~95EQ;edS18oWlp+ZJW!oH##?cPMsxkIpQ)hgYNxGr#te~L#qll!K zgptxwW7ncru->d7j?@!9?z!}(eyK2Im){%GE+hT2knMv?J1}Y28#m#dR+*Ys%7qTO zT*|VAa})W^iq2+GuzqM0V7VAmC57{dx5V+zn#r$c20K`N5UmXa~$Nc z)9RRv9nZ69R+h; z*m-?+P$56Q&caF+b`hvU=>`hm&ep-uEUQT*%(CImsC5LPS`2m6U8&5f$>}9@!~ThX zI<~p{*pF{=Iuja@$U?+Z{$kt&D-}D@z)+#7edyyDTOK6MVE%wFWOT@DYZg>o%-8Z zh2|Ry{Drny6ru(w{pw-RUKAE;C=f>N4$xzh6d(AE@^l$DIAcK=dBdLk9bgC!({;%R$g;} z>85Vj&Mw*(KO9H2oW<4lL@lRQ?S!)>@`%}-@7rvhY;Cc=%eV*qheu3iikLU^Ytv|@Y z02bOpd*-9R1j8(1e$lru)M@%S4KZb3ALx<(NwtarSqLbg@)t|At=N(*7u?ia&I^6? zN~~tWLgi1kX}$4qGr8Ht6^V4y$MI7j%* zlASc;0Z|(yzf*si8s0UDG1u{vASRk*+R@y+kNqNYt#tnfdE}RkSioEl4<)F_uxVny z4?bH6J&C1)CFtjL?f9u_F#hK_-bl`|SoO~vYcQ$tp~d3@hw>f1QQM@T{$C%g>wyHV znd6GKEs%OjiEFW}a<7G4w`>}hn_=8^|7ucr;&9WLKymXR$tC=CtA@Wlz789QzdPez z;i(r)+7al->U2&Fa)+o#xXDqTuSVjL&B{=IbM%M}qkwz4j2_F%dbz0fcxsSGzCOJhnhc1kAI?-jGPb-1&rN)x7? zKAQ8_@(B;IAvwaLJfm1M7~{;3BHg9X&%$mlj624TXD!=BP+^z=&*`d~yJEmVPHwE% zA+h~8)P!3w%s*2mol-PqX`ClXW@vg>&1ATAY-wS?ZYL>%;#?)Nl@QlvR8gEnd%8HN zPpA#iY0G^OqZ#NOXR~k_$apyyujlZ7T)y>1AjqtGg~UUD1DLr(>uVqAm(qea?^z(o zfYR;)PN;dkiSyYin@@(gR8VflfDNITfB_fYPm=bjM^Sz$;7pj>5)vv_r=$Nz&0_js z=U6Yi|b^Q1{z<0`I7@$3`1M zb*{fJUYkYCeY~1RN~53vYA*6%13SOPOw)-JF5@k6pNnEao-+oTgx!7U%2P-o?vyo4 z8j!^O;6*n6qJ?W|nC_=gLW(JFyS-$=4&g|~Yy?0|{_J8;z`k`MtI!~UetgOoC zI6_C}E`H~G=AlmA3#Gf343zaV+{o8;GnTNQ@oWlEGK_7%DoMo0+Z2#a^y6MX+oVx0 zow5uZws#URAU%Em>cz5JthA)87dE%{&CKmb5P$K~{ZM%W6ZlNfYypk;&%?)$L-+l| zkQ+w5nVcodWx;~{&fdxZ3^-B@nK=g^MqHJhcU_NR(~`?smN052hi(gY`#SIP7t zZN>}xE<=1<7g{onJ5bPKPQt7Jy^4t?gwX!>-U>)R%rq;Ce0bKQw~tPDxq!Y;!y#fz z$eHKUvO0o3co-6-tW~UXvh@O#bd9(0@rT-aeAoY#Zok|))L4)ji0|GbEBMJuhzRx* zKOOu&i$wQr+ToW-Rt2>PP`a}5xD#zO`;^0l7fSSw6YX;p5b|foNHg2;9uMPSH&VjM zqoJb@N3rYPvJYo=<*v`wt>S7F&La(+M?`nBh(GK&TF(`cE+vCt%zq`jo~h_#D*5Q1u7}u(A78-tsme_bh@(9 zmUM&6zj67iVh5%*g_mWi2u9Ig!3iDxDV- z=X5)*@Wjybgwb>2%qfalO_W5#JvGI$+LSu6>5ShW!@{W;SmK{kfiBSn6!w5SPcOwE zL=K`i1)nvMt}G}?5#W?X|D4^-YIt0vw>}+nHHkl$diHf}z`HTYF?J+qAZ=UGO^vAV?%Po#e0okrU8e4lUZdd?IncWsYqyw%j zFSmmA{Wk+7LX>p?arbQ>AMs-_@XEv%U*R%9VkAD&o7)tr!<$!Kdof5KMlA*BCG=XU zh{DZwGqr5zh z?NFN?haK?5jVR} zmu-AG1kSDRy7gB#w%)t^Yy((7>LnZ<4Y=E7f!6gFIH)OaiGDmsoh92T;MRpp7yV_s zBALFX>@s;8ks11oCpmF>4cdg?P6%+sN7-sjS|SCrGb4?!c@I4bBhzlXB7YyjXOb2S zGpHMXMd7N`j*g$P{jJmM4X&pAfGfVNwW~-_Z$SX@2R<{pUQ#>8%sSTKp- zeNu#dn$8H=s+gSU5b3AJI2!d}>T8}RYDe1UD~Gf7!S%TVgYs}(E_nOT1q zS_D{~K`}i!_-?2})EhB*MG_;BL(lZ-_x#0^3Bj6a!`UU5 zrx0oh@yDD}SUl``W3Dqyx`np0WlZZ_~2Pi-K18UtKQpmB{bCNs1n_5$dNCimLPj9Dt( zAK$=d2xk$j!$Gbf9%e#PAmJ}yLF6s4W@O+VO=q82^Q_9HHDZ+CPbc|BX76UOEA>p~ zWXISnYZdPJQF#txT_fA{?xL_DyZXJxO9r0&9t7y>s>aplQ|`FA4qW1Y}dIz?itWo(_9!0fIyAvjuxB z5`V~Ph+>C2_%fJ=7RtK0k;H3`XIq8Wcgu}69U<=OH zE;Uia*mD(%z|6fB3q6n0gLQF96ZuuV#=$Nb%G98Yksdh1qd~d%O60{5uO->Z0psaG zO93?6Q^kY)?#WNqOOEsM;|-qX7eyu@enqRzpW1Dg})Sd@1} z`rdZPvMuFZBFa;~p;Mx3c>b@UAha?Jtj0WD8hZzJheP|N?4-xM;LJvqdvYjIv~f-o z!RstznURwRx#cs-dR~1bjQv3u!45$u(U3DR`N!vwemN+Wul+@aJ(n0Pj6N z6Om(G7%+ky8S6dTCb`ZGFmr(2Ui9gs7N@VIbJ~4n#!PfH)#)mms@QdONdw$BzO_#V z-$z;d(4cTt+!w8fWiscF$w@mqWi~3NK}BlEI})W_-qB}aAv4dfw1qGJrq((>TWbmT z&ZOB&x@@gTtuTiL$nis%L0S&Y0v9vbQ#n!IR$B0)(0&&*q*oV@B=UOM% z5-OrvAIR9(HFLVY>XQEPU8WPLa=B-Nu~*naUCo)FWq8D;qnNG|h|6iyidM23y-xi) zm`Y4Wi6UT}7chNjaYYf0G{ZLgb%F1O#Zc0AH5B~E9Gz}s@sePWbG2*nnG=f^;Y?(9 zRiy;RSv$>b_)Y09nt8I-mamW^q4FzR$m1dYtUj#L3q#?05jI(OJeFk$4y7q-m#EFq zuJd!_8$e6GU&%vLk81$$c3+jl6=7M13(W^=NSdrz3S-Wb{}|Jth<3mev?3WiAqV*z zQ&YNpYt-sJaeDzGWm|lz0X6ejpOWp&LwD1jOKtiE_teAlO_D4m=-k6{+1AxnbMQKd zJEHxA2S67yBaZ!n^q)%RUv8uAC3U9^klUz?1PlyxkPghw(VW4;(8k!&)XAB_+|<_8 z(GZkN&EQ~S=gwgBmxjrp;$i>y4Oa~hZ=D5~j|3! zeus#P#}kaDVt--8jBP=Wul%Q9O z>1@&)Emv6!SJK(X+%CL4abrxhZ>ryzE;rm#oVx0Bco;q&j?F(cl*jhnIGcTK<6y_0 zN?p-$?vYJP)1c1^ySP-?A|#M~%osVEgb*o4lFqZ%w#mt)^|ZaqiI=Fv||-DAs6aI;BM=VMjZ(Y<9JAB?vC_Kn<#bMTCTnEo{FHd zIXA;6wK;lF;P@OpglZ{bPY^DI&^R3c4h~_wR@?<@RPkGZ7}O}Ef_OyPuk}qx#Z4xH z7PxPDa3&M7tQlkQKqt-0mx+UH8Ne31mma^4TI7Cd0+9HnlB~y`J}%Ogtgf{Yih71L z0^XnNu<98(kA}2P8!FThy5Yi>aXQcfCLM?I$^;Esj&H*<7ooz$voV$irKr)#w5JeS zmED!y1w$NeMK4Ss7R~Bs*zSPifeV#%l6-XPJM3j^4M~nfWlH`6=phbp(ICn-xKp$v zUa;Gg-}p^C1Y5!Ixk~tu^~1TWOHoa7By?i;<2F@BKDeYu_oXG;5tKYn`s)1Z|IQj^qQ-IL()W)s3=2C)50ciO7}O#H=VD zyeb8qY!$}!vpqqT`G|oI*4g)#4hQm+3@vJE$unHF2##8E(g)IU-wJCLR(3h{RO<5$ z=*bn^ZMqhzGY6JaIpX$yc@ijFF_mIX&3E1wnq+*?#H$y6ugx-zC{kx(7pO-#mMSu$ zv3@2=j!~7Vh>#AI8{pGI=TG+)XjvgRU3^z-qjHw9TMgSc=Ed*g1@kA77G7!^z-Pjw`tc=Fd zH5en17w%|z`YS-B&PCuO(F@f?&I^$Ors&1n8oh~ivO#kN!x&=Vz?}P?DMC>n?O_g< z#hzi4tmRTUHK#eXS_LAslJ7A=kUl088uGcK^x@1=?OWy%rw81b zz}NFf)7R!zvF|6xq4uKq2c>6IHF)SxS!y0>B*sv%QU~L*YP6+A-YO5Xku>H6cKrC} z36?3Ey;H?*;uoS4p7=y`y%JYUMv5!B{&_&T|U8* zhu4=;rjNF}4iM%h9&p)ej5jQ~!p^R(F{A5Ic)@e^Y9FUNIQ9C~HoOM=-O-j4%sk{% zJ07*mSSwD4dmF4XYt4F)t~)UCZ_Hi9q`)+QnbT}&ca2hB_L=mZsS(aZ3 zxF4{;zGu6iqY~^GA74718xj7Eu2$Og#z zZH$pU-FXbOo{-*3Xx~%ONRCCji3E0vyPUZ#hm?HZRE!=3C-3&m@dqD=n0?;@ZQNb$ zxD#&o)broap}P-$FlXUj?fq$KqezQ(xM>!h&LK35e_+YqA*da-S0rwa$ovI1uCVWV zW0Mv3je<|uag#S=)@1bH-Qyr_q>LXxt;Aoh`%E??qmVFBuW#uau-7~#e+auYg?cm2 za*(&8=<8#EU9K`wq+G%5xf~nKE!X>K0n<~J~OWotyj45_{2 zm%J|vldK-U>O#5ruR1~haTLTxTBMbot`<}5KW*+xf5HsE=3e%c3kfrt_Xw7G(-(P3 zlf|{AL<8f|#Mh~iiW93uN6&Bw&sbOW|xRzavZQ4plchZH_$#PGkG+%#|XD z$rtdexZxt?;Z9l7K1XJ%jy>zxoDV2XD2Vq79mid{9>>``oyKinm1216448kOQO{3Z zKaBO`Di7-vFVHkAcxH1Oo{ZyVEvXR(yWY@nqfvA~CIq^AWc5mi6fEP{@zbk6@#>T~ zgtTvHAG;hx8(SWsSJjwNcbeBM4idL^4Bcw#EO-r9$iH1A2}^Mxi$QDIvoS@ClSKd9 zXT4T&jCXgKH=e>NV(~#(T16)9lv97IS}fD<>-*p`fK2i#YseIP$gwh1u8D9{wu-PT z>bnMCC|%=(v3oyhTWsTj0W-eriydv0)Ssx&&ElxjEZ=rvtmy3;TCK?lgwBydtQN4F z`2a3inbb=p-e41>$v>%dA4+dqQA6AQrLEaI{)mz@dL1);2c2bf^ID|y40^JV%^KxJ zY>3uWrRRNFH8r8p*S}&3A>%q$d9L< z68abgE@(EX-%|jm7Kuos^OVs9LS-MmrLU0TY(wfKhv0Wijr`USk=$SfCUjt(>rOF= z^awTC?Y(2=SUKBW6sZjYQW06C(+b~jbI2R}5nG_G?JM&)fb@|U{fAlrlhU+~v=ku1aXTg9|%{JKV6iqzwVl#&>po!)OWacekS2Z;(|G<$?{(fxm8ToKG`36GjR^Mo6+57gu9s)Z?6Q6 zzxtHp*_ZQLZ}5wyAL#{1Msu8|7$^rATKCk~-A;s;FH(D4fu~V&&xWN&DivV)<&YIg zN4FxJM#gx%Fuj;YLb>W;5-t&=#Aq`Zzbz733S#80VJiGX@zvp&z90RNEsMC)oNOh} zl26K$oDd0vb$pN9W3Xu&c~@f;P(EV*5U!}8=J%*1T3$Rd^n!0i+jKM?= zK8pG;DuMZDB4up|F4SRS`1-}OkON~42o~qRT>@ecFxb63mOhIgX=*DZn?SSWwPJp| zr=OG#mT?vKW_` zs;=B-v03G`Y88`w-(&IqPJ1GOd!@IdKCZG^R2jvu`50<>Ot?*DO6qHl3#;qmY%1Zx z=@+NkhRuFe4zxk_MykrSA4p!#rR~G}w&)dJjG?Q)zCRKdUi2rOFjgrc<;w8=%vgA3 z%-@WGcRlR| zk1v^LZpA-nz9eh-`mVutOsf9o^^Z+1o=XEPDQKCm6Xt*FmiVj5RWo$7G&HjQTeDlF zs;i8qj_oUtD*2_t0`iBp^e37Fh@W4zXcQqu2LUlRrU7bgq|iF%D~0WN&|VWnN0nHU z4IG=RWg%J;B^)lr@1Hu4{VZQIH_)dwLbuPxpWUZC1hNl(w(9-f-p8E4N@|Ixm1~w} zoA2*4=?FMF$>}UlZF}YYvKTbU%gV>s@O8R9v63F}DPT28cx03ZJnWsCrYO=7=YlL?!d>liJiCh(9pBz6 zpppGboJDNIwJ^(7r#;arDFPB?v%iq!?^3yZzIy;Ww@sw-qOS(9c|{&oi|4Py6+Z z(Qv^C=FXi*n`mE#&?0a*`(N+fvFIQVu(u=?c#HEeh^QShnAO!o!MNS)$aMpXpEQh+ z;zyErm`m1ugA=3+lyj@40eohA1Hzv-lAJK_VGnfEu%6iUY(nrGm>;yKapNV$q$E=W zqYU@=0shz|UKch&Sq^P4RpGyqWu5wH$_@0YU`;lQX;OD|dL8$nlwA(MM89~evmM&4 zB`r7>%@cRxAU#Qkokh(K^=gMLi&_umR=^GB_uv8K^;LkKMP9ut@ra2>~wbX z?p|*zrm$(`9^Hkn1cHD8SK5hZWI^wR4XfkzB%EydF$_O)OH5p0wpZMdrnI!Mq;S^B^STfhcoGwG#Oi%;XHuIm}PXFc; z5r}@J3YHG6D>ZWmL?Q1%mkMZ-q3IZh4M{jTY*7~eL+=R2(D-YBlmBvrg%$rWxv^>ny-%KwiJh)?!ey5mRsVX7@FKs zXE$!ZW>l<|q?Dx>`@Zliw@-i_f6!oLTt_!CcH^nxZ4@CtrXrmg@`rP+lSc4=;wyyU zl(MAo;15CkLHcx`uyH$2WO6aonv?fHeE%8K^=lCqO)eWOu)=#@<;o!$qxEM|onr>Y z9t4UvpeN=@DQSE&6MwhVi{0wuzZ}r`%OnVwsbgCRG6|A`j%cv{kEAtqkUh}Y(9z^S zCAK0JZRI&Z^p7UGhG3;!;n)b+{M2H}?;YSu&>fNTKnJMeNIUvtrQP5{Tcts0{dYd@ z0%vh^@4H^2efOp?$9r&IlgHm@TwBjw34G5Vd$;Ofb1nUh`(x>iy&N`Ffz#zM3X+5` zv!0sw&A;TjsdcOt94gpT7Lqtz;-HLEpWNipGfa*)viR-;yLaJVPM6*MD&&y^_PkCK zzv-)eN*?P>Z^V}dR!lH8Oz~u+(KC`p35NtEF;8Q^LPjyUy3y*Gr z?%qk?LEZn`u=$TaP2blKF$)5<92nzM}pmo!WfNcokRP>%!Vra+9-}BAOsKtyTB_oKL;U64NXcd z+&W(L)W%c$s{q?4O_r?{(Mgk>>Dz!!v{cp2BlynYIerNRL@6yV7@AP|8|q)mOlo11 zs0}3(#8$#v0W&0S@CCmHUZHbHA^Y>hNH zLwUl{L}*NN$~#0Qtvb@2&M5lCFS{Qlm9v8E~Gg93F1w0h^w9E z3oAbuX#!V5nq61gEy2_M>#G77Qte=kArC_5h_7^Kt7?yD?_%Ztkc>RXi#LCh2 zv+y_Th2y$#4@xFcWYeE5as~b0Q!x{U#?Zp4PUuA(*v;UbqGv2nLAjwwy1*J-cp9xX z(#MjF^&dyRiOdOmwOO{E^cJsU@P-pP*TV2HzZfYIc9MAmt6{9k!>Qw2&_%wa;3Nak zAE<%(C)6$FMkq2&I{hwfcAK_v6+^LejQLBykbFxb!C*cbNm*85Uscv zR=$7QnFpcd4ej!@d*dw z2Dvxfr|c9s_)pcalP#ZL*LUc4V1Ws}E!5C!)Z@hTpA}SjhY~omcb-#!1S0-Xosgjl zQ@_LB`cAUyIa1|VKTZ&&F6%&w&~G$SGho}SiXx93MzE?|LcNJo+(QjR1O6Q5KSBgk z=fT}6k=o@SKXM>%e}UKf4Sl%yjnU|*mnp1DW(n~zT`X1~`Lj~>S5Bf>LP@Z88Hcp? z2Z%5vik8&lJ!vA27Y(`fZz4dikJ^}5eP}+_Zt|nn<8Lh0a6tfPf8AW`6}I$=OkpHL zjhwqZh)KnlM|V+Gk;2b)&PbnTg?f};L-(ol81HJCwx2odp_FX`Ed#A*#?oIQ{t?e| z)&m;lnC9+6yceF4bNBMhI6jCo(aw6(MK(wA{u==Rp&=URu2@Nrc1$P zPGfbt7r0GDc1Y_s75|@j=7|2k9?y%)itEKb(~!`PY}AWyA8w}MONCk(Hn`^&o{BgG zK{w)*&k!@&5%mGo!_!trBmFX?uSAnH3agi-443jU(r}2~OC2sjE81kB& zDlqqpYn<2A`nnUMQ~YDh5(k*Jh9T#dhOxE$wb?rJ78;+j5E$0(R`?5dj+R71tS%yK zLzV5@4ThEy@4QQesy!FHNW(f3+s}`|mp2J!5>1g&q$2k@PzXEsMN#PeqjpspdEbKe zM`-%LSH$c#OvKKP+9XVCs6LO*V-rdjNJS6Pb7038Ira-7?rCbI+Q*8M2SJh(m>8?% zo@O+iFyX&1oqH802AxYQ#}IE&B}pK#$r+V6R4wvXvY?*`$+#orC0Tgh@Y2FRx83YJ zbgw0Pa*kww_SuLJ9Zguo-IxdW!8r+IgnaQrGlZN^V4dpCYZEMiOQ$G1q+z)Gg~X`3 zf}Q(>j)GZMHB`+Mh4WQ74?p5NWoi%V4){udyc+A6Au)66;QBN`8HuZGl%<%kdmzi5 z6CEjJ2rvtOD-a*ymk^9))~S19}msK!bq^{p)|Uh@sQp0zZpXtQ2sC zK!Kl>Un+*fo0=LI_|GnkbYFe_=OyM83S$JN-Z*!ES{bC!!&&}O%}|N7nI)PgTDU`O zp9wF86mdKRWwlMUK90lteSEwj7~t4pGe>JPxp`Ecg#*mhg6VWFxT>B#)}D%vGzYJhe2T?K$Re(S%c#}tVvzmt2^6i#qzEF* zuUc5}S|3Jl#HME00BzLxZ%Yy*D|9H+l8be83_yeX312Sh&H={4W3tb%L&jf7^1g=8 zCAdBdDCMYH7R`k{|Q)VQl97L!DtDluxS$O_=5ik4oTc%@GedC$<)=_hw4`3uf z{0OMS#oRZ&^M0HleOuobBuOpGSc%U_cwzF!Z`q0d;A>O0hjVgRAK)dBAG7lp?fOLz zFU4Jlw7$=_1H-}Dp17!7eY~g9>qOUHx4FK8QrQ2F%}R=$iW%~4s!|W@fxSOJ`I4TC zY3&as>kcuYWG)#X)ep+;P zim_ogb=^%hEbWazb3<1(-M*Gvg+1S)e6WD(M%Sf^A!dn<>M@3SnchgZ0~M#yYuRRc zy;u%AKG%;Bq*9=oWS9OCrTUz2Ns!kP$W&L+uvQrPO$%-46M5tvzlyN~QQ0LrtYOqy z<{up8R4DH3U}FLWa6rxGC!~a^1l6Nc?4e_z{bzLu+ypgE7V9_vm-8<=*Fm42Jf{g_ zNqK^-_`;R3uoU7tqw$0slIuho#OH>-*@oKd2%H0B$Rl({WrKRyl#7&*$=pvNH&w6Z1kzjz$%Y@M79|DJ(cq-{)AtJcsbFAbJ+=!&y0Y3C;lDV;es9?K29ut4;J_hG8r#k{0MMI_$W)=vh}W?WJvoI{9mY)43;z1 zZw5$Nev<N{FpZBkoA1yFTOT!gmP*+W72EEl_3yMNI31muXDd< z|I41_UoFwtueWd)5cH-%Es@B-4n0vzS4)%sP$NNI5omP~FiSt%h-H0UrBXqU)xK$` zQ+^+x8oSsahelMw*uy$TZ;O?$@ImI2S4RE;=9hRqJ}I5V4(f_1SU^Abkmt}FLcq`G z_0u+@8qR3;R)cnj?(Lwj0Y?apH=%pid)|dl!BJ)0yHvQw{0P`irg)|Sty=jsX^K#wHdm1GqTa~1N;DX)eylD8Y#;$VB z;>&6;Z+~#n8gGIqEF8SJGUP(+wi7sBM1C0SBsoey7oe2{7O&ka9}~O9zzEYxN@svf zi|f)kSlgUZ1IWXRDhm}3=Ap0g zm)u6$IDnOM=RwcrPMWvjg!P*?U%8IB=pNJ&8pQjspfY{9I?POONUyWoGMb5oRSBF1TIg!Brt_t7ghl&23LA{qki6LS_nJ{>~7r>z(LA}PeF zYY6>f$zo*rK6ry1gY)9fzWoez09QW6oO~a51!Y z`db01x@J2kh|HH!>|!s+kcZ$VndhGooc>xV1uG^d9IiF5lH|T#hzCqEE{Rs|MeBxS zD1${M>XGylu1;7M&?gbz7dh=(I zMJJeo8H3j!AB|mbZCS&hDKKR?$4>PxCJ93qVYcQb04x|XsfN-({tg!({!SQ$-|xP? zEC((f;>!k)KV_E6l0xkmoIJ+2rlc1>4*#;)76r&97-x=5E1!Vlo=r8LwnkAS{;S_7 z4ToZGDJ2PzfoB1tvs-!P6aHv1GQefwuG+<|%xqrkTQj9hrQqRQN&MkYz1|}y#Vcbx zku1G}ZaX7b8bZf~2N4n8Lx6*(TDByX;kibrry&o_Yx%=j7Hu)TKO@NY`>233HbrQI zQ6;n(pXL&M2nx1EAdENJ@)|lElFoO2g>ifqmjBAXS(GwR5+P{!Z0Z+h_z){E)76(4 zifi;Kr~x!}PGw$(LPouK_f4g50O!GKC$~^&#OhWfZCt={_+D6)Z3TJYa)J80?RTt8 ze076>-$}vV@dh`CfoHHAo5qoPf@Aw|p`4FV(J<&EW=VM5ymB*C0jOC; zKZNXIW4jWtU4!13U9X{MiIA9bPInxUmb^41x5!17+D}&dJFDN*0i$77$;2j@s)mfU z=*C!7T559pP7*b!oRd?OemPFzA993Bi%hfVnyVs_4H)&Te+)f>58?SbPHx{$IYY`k z0xi?6xx#V(`SK&(@F=7Y2-im-Tuc7zY%S()Z0+J?>1wLr_;+yIDEw6`G@(}|C!~az zKB=MKQw~3WEGl6P4itWZ2tL9}*l(kgsd97ivbjp|lj=^)4HM`gGR^GdkqH?>vdNG& zqhOihWqGxJJ$-!40lV1d>JP6jf1t1Cl4b>Or{>Lb-==w0UfF84^3`l%f8-SaaW>zp zDNuLAZQV?yX`qd{2V3oRKr@a|J!k1uu`S>mAT3)r`N2JcB@(@mB8a#jt76`K%;th! z%(v#`*#?b-5wy@f7z^)e8nolmovLem05gG+8hv5?CFUNbC4}`KuI~;^Z==_%>DT;j)4gxVi4a$X*Ip-QaC=dGOBr2+Vz(aHRG^N9VgT^?>SHPCKo5iNY- zpK0U3wNMC@dUCamQVYl2ff&_cf~DUvfvT%3dWOigIPM0!gcmWppo>@_v0*V`pmCPx zMDG$zQoW?K%BV_68k-yw8Wl#R7A^c6b+5WF?mTl$2bH-5S^}(@#&JLXNz)2e2v4U3 zwS`5X4f6j*Ei7(nYHgxqYW6pLtJ^5!En)apHFyeH>zdofd%PSn!t$U3FKzg$YSlZ6N$bYV!|bpy>BSU` z@zPZ4xlTR4#w3bPxM@)>BTF@4mI5VBW+k zW<|rg)P_BVr8}i}hwkb42;^Z@e2`Y##A_IRa8hyYyT`YaI+KIp4+(OiL=iei+(*^2 zUCwI2!a%PTf5l(Ae!3<~-mAW^>Kfy00+0KzN*y(9F&zePFnVHdyAVq@2l219KGFNnD(Ye(V z@zDFyM+95BJ3J&q{&L;W;*fb=qpMWxpvr|K^M@b@j@-@EToQcvtHyH&A8=3us765O zHi~$8zX>;5twwzL$6MOiJ$a$+s{p&W#?D!?kb1oeL}S?DRgyS72@swBNf15SZ}W+g z^|{tup0~ZQea6#F1?4W6LkKoU@u%0|%-4IEQKZVIBz{=i*4or%0CbVKUhd)zpH|EQ z+RUEWBjMPZyvLk1}kk>Rric&SPoJ~_Gz?5J>I>y3#Z1442c5di8^X!}L?hqYz2;H*oLWfNk^C+OpDzv23kT*2+FqkuN_kJ;j(&>b)LdK9~DI^Q|V>6^29+uWZ?%<3XzS7!OgdleBi zpPag4+(<(%N1N5WloV=zXp-|Wu)nv3MKp9yRy8nQCf-(CEeUnaeP}$d_>i8=x zkdHj5FNh1+s4y`lzg%QM!K9VRu)ksl%l^Pz0kvHGgmgo`yG&b+%y-K-z(q=+K1CXw z{cN<`5#`7;-FJQXcF!}D7u?iv&2h#{WGf$4W#Go$5Xg5t4*T%_`E|-X9mzX* z5*CqArX-TaPwv;(j1S}$dy9c1JB5utlA8*?`c9dtA(Iq`qQDaIv0$ia!R*oX!SAH;zaN=2^Nr6TZ|>Q0xCOXMv(07cS`6Aod%0UN zOg$*N3PkTQMLKo;M3lW29Z{#VXC2dYh(;do5>PQr{V+4offu`M6qKh`p<+S`+!ul7fHA%YwpwY^PZ|68<(YErA9X-4ThE>7Ll^t#%@I>3C^Z}gh93xD|Wx=AC_e3oeM8F`T;Og(PE0hT03coulg z+ST^$03&i!-~h-Ky&$Qf+c#y;J9cI_{?PggCop!+s|O$a8U!X9@_x8TdD>1?*+#U0 zanPPKZ5}^=*y@ybGDwE1Ccmm0?dyGxs8x=>`-d<7SjWsKcnt#W8}nOuRmh{Wp-f(O zvIH)iZ=(5br7D|CnhWV{ySiLsm6D8heBiiULu307n#SJ6i1kiM?UcK;Z(FH7i*}YW zS_;i4OiB{Oba4;boUu~PqSUEX22DUoTsM@?sDna9q1M2nb;sZ=5I-1C_;%asXSG3y zvf8ObtVN|bh)@*c=`Rross*(v2d8OUS^$PxWAGszLNqVQc_i?1NYA}9&U$It6s|Au z@2_+Z_tX&ShA6KCf`9wGX&ou{HeVXp)r=O+rP+Vy#OP=X%s8&O>qT<7rLU^i8(kMG z`1J>o0*gNx_F}8=*ttA#N!}FEH?mnImU6u}t`KGN4MyN7j1(uUDBFUW`e0d1%#IsJ z?%743%^eS6>>Jdnn~^h}j``7#c&S^Fz1n~eWC5dX+ik^8tfB;nCnjaeUe53wd(+ss zLuY>x_(yc#@SNisUwehmk+<4lClS|hD+5dNs0@ma#3F7G64)QU{LE0-uzy57Fc=Kd z)NGaJtXcp|RQFJJog;J2Ew}8xBMRr$?w1@5RZlWCzz^tul%)pc&%gVEs?A$awJH6t zSDO-!rl8cAWGBXSL3mBExG9^S!U5FgHZdtq|K8{u8W2J2 zOH@ssYk@KQS9_WLCtYfcnZlJOsHK#JI?Bs0B?iP=&JLX45x8DN9~O4dpBcUJQ=b(H zvU~J_ycgt5p`YV>eFeiz7|)8a$&ZCMoks8iUtU*_QhvAvJsYBz?8HSwyQdBq^ByNC zE$?(Ic@~@8WES3~<1!UW+lH)}($jU>M9_ik+%m}|i>pyK-})tu=4{5oH5#o0a8R}3 zPr?Gqwvg*0oIOJ+JN=V0G6Z_k?0$>KQe?pNNq#*}v7B~D4o~C|*Mt0glLQd5|Mb;| z?b{jdpz6gLQXxP7ws%#K41vzM0l7;8Jb@iF5b?tM{9!&Qy~ey(!ps*73StGBM`5Mh z%A4Np3rnD$5BE-6D~zXsqO%@R9s+c@i6B5 zueg5_UzH>)(men7J=Nb(u3}+m`}dy8>Mt3L527K$`5c1ghmT@q+vl?v-=zFSby-O( zE#bSpM8q)=#BEc=1wiHiI61a!kN_L$=88;>EKn0GYi4`Fceu`DzP)sLDe!5%PZ{7c z)jSSmx9D9}{QpmXbC_d0~di|kv}tBVl1vyjSp z+BEh)l|h$O^=-0-G2YZPhR7Z;l7GG`6t)wgNSIJJn$@HcrPislzyw1V0vQhw>VHXL$@o#xWP^Tk#lfVF=@yDsN!JsmmurcS zF{BH~6Rqe7Dk9N(zyRLJJ5WPa>q6AL{pFk+wuLK%S8ezcv@{~u*ONr-gCpimha8U2 zwV_SeARCA0Af?%yy#kP6J*&@$7u#MjWv83ola%fzmGBUb*hn&^6W6VLz49YTcwq=1Q61VsZ zmL#OCMm8uqL50+9t|7uO>S4C~E9YlPq++;sA&^Pn4&oRolr!seTL&78M?+S>C?tAm zp*9Fl-z&4N{MfN7WSG{(kg;ZckY1_DMDD;zg3I%{C?*0RL z1y+s2Ze5bc;Zbq&GrEE!m<<17HQHCDUf`Inom@6cJNevksfNzScsp6Nq~2$K-%R3@ z@p3k@+1y_anC5?Tz|h86)wvFPWg0daXaKZLp7N8(&omCq)PI*$$fu}|3x|CRq!byj z!6g7xN->2hAHa;GyQJiC5(oisfEKJUlqajNRmK_!05Uq=c&m9iTQ+9_>9moVWwT~I zEN83;kOhY59%O-`W%_pujNKP&>i@97U;@xxX+r<9z~mbd!ZGO#vbDMX%>pwiZ|_R! z2XI@H33=#xT=-N05 zN(142@cBHjO9%i+Xmk8UJxt@OzwHI0X%{8I_;TQ33|0x4XlGSB4iW8O)H$=M#l^Un zbq#SVsoe8-Q3!z`O-x)A-TA5dr=Da$2dIcwBms#2rwQgOLccf21S9|NCYbZJzf3T= z#XYbiwBXO8J--#8S9r5FzsWM>n$)!#XTFNte)(KSB@l_dtCt3jaabnl>GV6KM!rjh z;mag+;U$^>MqbOf?t8!h&{${uu67-G&##8sJTiS<<#)EXxg?~pPz~c* z9zJU(>lJxryKC186kT;YSQ*asMuKEO_}ODDi{pdpTJ+)jjAdVF=?ME3Aha#mGoYAC7*q$1$w z8gm=`+MH4Ld@2Q{GOG??*ZKzg0KZ^`IJeY_s3qEv4M(lPS&Cheqjh24he3=S=)=<~ zE;5aujMJB{f7FVNs$uv&y^qcVTpx8=7FCtB7FXm87Iv~Y>O*;G{sDDM;lG)?hA?os zK{E_h^I^*b3|Y*5EJ64sdtF!s#cyT8)ZuvZNaY6lP2z)XQ+_f4cMx$OeYe~{<`_G| zMF$ag_tz6A2lnruaXhhnJkoUV0guWNg!EffA>wRk*RzRdXZW^S!JEXfi zr9ncv8-$zgPNloMk?v0E25BTDegCYro@ej9-tRlv>pjpT27`g~o?gGJ=1*CM0Y{Id z%8(Eer5dZ1GP{8dHI;;XLrprIq{Wl^(r#G3YRK08*<>54CdowN7%!Cr|>o&SHaxNXfXj18@Y z{$=v|Um-&h5Hc`^*@MtB;Ms3=W)d18V5u#YblzMvNpYO2M-k{222lFIeo)3F6Yz@` z9{o;1E!X=ZWGuZ18MS{28BNjbVCRL}QSY@f_pM1z`c0VVhYE9_vQ_|?=wLSt5e!^6 zGwKcKp0$`R#If5{@;U>!(b{f1;jJVHja(s2INs>C=lt5jGv`^9L@eF%DY( zRL!F8+>m1op^auw2HJY=;4@jo$ExMrh4Wv^*y?Wm2DyGC#8hC(*aBGSzYvT|HRgB=7HfLX& zm{C$ReKv$d&Ba0s^Hl0XeP0#}!i?!*NV!WbO&e9*iu3XZK%{HvdN)Leblv-H7FgVv z0M!cufcFS?ls({HWX2dO=wXUWK^SH`0Nh@~>F*f9YL|%~LUts?-i)ZnSOD;zegWRw zMirlfkSbiOQUJj-D)oHv+iK-%mWL+#wJu_e)@0B(K|rKaZukL+bn*uMlcisfxAn$h z?}Ob1)%f$M0rw*6w0!S0SKlSn1c=9NX%_${e#KJ*Y+?-Y~ZMp@Mb* zX`CXUlZLVQRVeaCF3R?zv_(4Q+xMg6QRWjFsr(NQ6VdvwIL_0mPTn@S)3vA*KMdF9 zQ$l7xc0I0K0D?m&sh$eZRU7EwHL;S_B)9HDw|RO;^Y+~_Mc~~==*E!`K$Qj^^#DUoObYyB405JOl9W6w7q)j%q*w72v+7|yZO7P-A|rwLhCd&kP+w%lmV1iHQot@}%VsJKa!iGTM6tU$K zPA}?H7ZFsF*M1Wkxw;_kW-@fpS=m06)1m+C*W+`MqPZ2kaG(t zWZqIAl`mE6%uVV(B=`9q_yx?~7IG&h32(h%_$*=brlGQ5E4A}K$IvTz*6ro}w+`S3 z@qd7i{~W`ADQZ><=t?O3jTj9{i4tPHu1d4{V)M7*%2nd%@nBqHxkoqZ#u4)6RgYHk zw3uJXS2D1Fdc&Jrtx6|xKbS`+G^;F|Y_YhTP-puT6JE{hi?!pZ8LE=U7U=Sg#WPdoNp02&S_KLnMM32tfjB zH)ey!A5mMV zp#HsNa5fLqQP%VQIY)J1>-L~=>bx(CQuZ}6FA3N}yO+1ZO$16fD2U0OLhia^g z6dn284nO*0Copge?swuOD}D4nS+<612#Ly#g}Pb=*}8pS0|!F9>0xN3i?Kw}V*J|W zatXznq=rG3Xi}h0oWZ^8=NG})DDXqq;BIo1-5xCgI#tY=xJ@22;foO>DelT5KpwVi zTFVL>3j6i+0$PtvjQ#+Fm&D!^>i9lS)8e-|q&-&7p~-6(r<0BGWE(kFKryZW57L!& z8yGV8Gbq+oqz&&!8B$J;e2IM21LQQvW(6(&JXpX90kU8ug(1S()DC0UhQ;5)gJf{ z>q1T`RrrB>vn7li)&Vx?xlIliBNQNM=OJjLhsb@CAq!BAGzyBDNQ6H zM7juUC&|i+ycpwR{kD#~IR%q`jxd1^w2NkbD1Q`W52~fTzp54>u+mhx>H}6Rr@@oN zC-;U*39VG${~W@qQw*vXJI+6RqRBa1J6YISyZ;Zr_U|^cve{PEQk(1-0^%in6HsnJ z8yc+wIsj~D3?jx~9%b%@RpcIDKT~a|uF`+B0N!ZwX7b~A9cQ}Gf4$Mln9AIIR@ZhT z!x*)PE8sPL>AH73760&V!26)~;xbdPC+A=Ia6-6VPe7hN?*F>~+(R&i{m|jJK`ss$ z4`i5fQmFZT`ys=yj99NY3_-ta+Rw}Mv`);Y={Tq+lo=$|8*30!s<&jMNr3UQsh>}X zJEs5?)-z-bx;FJr_Cp(9R_<^*LSUT-+BK$JnsgdP7{v+{?&rVPr+wv?WsT4@%-)Za zGz5Puf>(osdLfU=(j<*JLO~2nve#tR$H$>zEOtY^WCd|e5wvVhYu0d$!&M)zH74~{ zHDA4Ca_IR)f=p^sp==c27X`?z;-dc~`AtuN7Nbg&BbEONxkIal9I%;584AtrZ`pl? zuDN2kxz6{s2MHk1wX}K_7I9RE0Nd3t)U1;TE_(@inFwrw+v9oq6Rg;cjJ37nzvnRXE)?gY(4$kMfFa9ISN*o zl07%NmM-ZeHsnIHGXPwD(yNr(WZN>xAk^tsy2enP!cCp?Y{bbs%(NUaEjBq$0WpNZ zaM$+qX};LWEq4$CNU>vkFpC0zOu)VI%wa{fT1oiyqqo3EXazUZ;LVX) zZ4@N4c|4oB_jTG-Idvh0ROl={RQw7iYZWLpeCv?eq8gUPTS5wF>v=jujR-pdc>bhq z1&S3P-7l%w0(ZejBke+s6udpkuld=4k^l2a9ptM%(d$^mPYzj<{>NL{ZB`i<{wlJSEP ze&YS#h}{v6d1!ZF_WmJo1!nL6ht~z%yJhuj0I&P?Wv$lD|Hq#5WJnDuX?TPs$$PwiUE{h5y=LTf&8uRPQ(z;&~W;v`ATYQEpn8)wRF#FxPW z3E=fH!zVSZqBalJ%#ahzOrnL5jHAROmX1~NGnjP_;TtaHP~gDDUl^xcmU(>k+nVN& z$pTb4tVky%Ie;8c;e=!qW5~SzmKx+sd_Ot+~F zfl9|ZicEE!7%eJh*_309^b;0fb-(l2)(5JXYO;cPK{hlW|1dg=@rfDBm0Ra+HHiVZ z^=8i6sSFzGv^O!!K@=iR(>}v%c67U=CUeD8uf|%}~?Dpz8PeZ$uN@-w99>UEFgsiP49M~Yt zXWDFRX+lORVcQ}Uk(vYbCcUk!zL5qlRj^^jM{c9W89I2zD>9^&C=FCwdL4rxQLN7% zMg~7zKU+uHoT21nPqHl4qh~xw55QcSsQBZ-j{dU1b;>9tb56@wfx>fA|NiFN8^5di zz^c|Ajq1|%*hjm7@Ki#ETf6q)#GOwpPVIQQo=vy;`YOl{-D!9NEI&(`K$5|W?qTX` z+e@R=qcG5SGX9+t-15E*$kbMTY%)nVDDO^!=^{Hdv$nWJkSp)`eshU4v4c}6hOi!s zir4=WGRR)iAKL=M-3q+Q-v9TD_1~UjFG*eg^`@-ikf12ry z#%`MYl%&^2CyI{#JI?1XQ@Z`>DV!$mdmyUY9G~hqKAQQL-pr82TGm=)ar#qTE-cEN z<4?WWr>K=^Ea@-KtI51M>ds+9Jr5cH3f-4-Bb%2h`2=}ZDTbQ3Z}fRL_{W(v>hMQs znZ1~Y(OFLHTWR5D)XZ<3Muoyj!$2al%Z)q;=*H?M{({z1=OF1BSmTsLb;mD$Mp>=f zQX>{Dba<&XxL+(B3oW3PhGhw&Ke^x`3f1Zxr7#CzP4ve0vV5M$_^^ciE1;_&u81_q z(O%Rp%g~-GTbUn)U7<&e0A4d<8;xPc`KOBxmovDHdF`8-%odVO`Yk6A0(6~0TGUkpa@LY9+brsQGp<0YSf&F zp7>*MTONYDY|8rs|sj-j7Cq&GW&|G1?4j8fPUizgIo%>zRk6{uezG+;rayvFB_Y8_MAfC+{DYWgRP zVIx(AgN85h-7|`Lt+(z0kkq9e!ZSH=qvg7>e>n0}LADegMz^YQR3a1T6Uzurvzioharr=Ul=lfB-l8BoNaLP&Sseh_fD=NPGI* zqL%DChB5_aIR=jWkD_{xWB+wmi-$i7!~`{In_GyfC+ zLhTGi8Ijcrn&`mL3LY6Mwf>8G zc}bhasFP%v^yUl2I~tO#5e+#I6CxSYC*gq|GNTl7vPbV$IXC{2Xh}>iyLN^rOU1zb z=Eo+}NpIJYTkAsk6!Y)v4bU`SG(#*Ic|1L*XY9Upy(@rCn6VFqr_rWAJVsM@_?#l- zAgIM@|3(Az<4~_VUC})~D@)~ensPE`qk263mnwdb+~bC^{c%y$2>N{uT;!5Xj_6Ms zpTI7W=N3DQxsd14__8}nDZ)r%0rQC6TbrOp?Lclq_8Z2u>EsVwj^>4VME*hb)MWOY z)6eHmzRSM)?Dwzr6O-}LN%ZWka+EN$=v{Cfba1+@`&@QfX`2meZl5i8^(#&UWSrV(d1-?h;u6fHBpSk3H%){myob4(+Cd6!!p;Jijd zzon0UluZ%`o10ZAwU8tXHQpW`(tl5#E1y%_5Ch{p2Vh>Ye=yE~1^wR`g?JsuX+@NQ z-!lHaYz=Q{=REpolfTdYz$2*pei2%onQhuXAi^a#0}Bg=%v~?(m{c-EX)Jf}Q!*mdLtMVk$s z*7$9I&I3-pfd#?9b{rCk4w(06w_6_(;REXr5z-5ds9=@|7F^Xbt8^?!Q!2;-=$oiR zQ8S5NqvtfkzLpfbOC#PcZKSN$)taAd|8wb(NnzONu zUz!f^8ZhwrP2Fw&_!X!{CEGl=3RfP}XDA%fGrfmo%vEMah@9^x<&t(K=fY&X#%lIx zrhDmEIAXd9x`)?S9!^v&Xc2E^0p#1|jgh<4C)x371fXok1$6Dxl1L?9qgoFk5>@ao{_IL=CG@Wsw#4u}7!$mgzJl zCRvBE-mDir2y383CKb`NY3lHLf6!o>;uc}X1oP=`{F*F`?};sk7BTEuvO(uj)!aAi zY)SeWU!&ukI%wY-z8V`EYe3)BaEr#bcFdgAJsC&E%^7W;@FDcV z){`1F(ryvP6xMj>X7K#mx!5@IMSg!cJ!h=Huo@I*gm-qSIJ z$mlA2nzz&9gX!!h7h|$mkLluRySMnvSMQN#qhEQkKH2Z5pem-NmXpI3PY`T9D;9tM zVz{PhiW*|8*n}1_T4(e(tY05zqGI2)se5b8o_^%Y)-P$#%SJ$Bn7;Ws7Ej+Xcma@Y zqvZ(3T%NR2IU06(z(7%oT4{ifFvA2e)h(-?L@c)6vGH)Hk*1qj?zo5JBMp3bDuVsVAyWU zf6bfG$$|WiUGxd3?=5612e-(D4Ul!cGtqi#uh<#A+mQ-$l7w_fbdh2EjrhIQcy#cG z0@Hw9;Ddx)oY5330_ox<3oDRyZe zQmI9l)mlZb?SFnq)Vj1JUyKoJ0POe&)UUGXCqoMx;56j_MY{o=H}l$OK)SQ;kN2Sw z8#76{1s)pF+mvaGB)tp<(f_2~FzZl=Ud6?y#yfVL@h1C!>FjuVWrvK1ke+3^__j?; zWoxhzuNyP$A*<&7YAt+iYM+HJWCpxqcUZW6ygJa`m2BA}~l9yXIrrrlsBvmTljL`OsC2Let#Vr69u zvoy;>a264%ev7h+4Bd_SorDA{X~{m7GkqhjPw!6lzqFg%S7?VT7M^<+6GspYY3XU@ zI?5`Ax;~|OzH>glbj@2Q+V-jl57*N@F{1X42jZQ<3k;`ThxTcP^1aQ3#I=5Z#yb`3%;d^; zTSFBg88i+7R*SFK6u*t5wxfK5?o$!EXkrh zq39`zEiR%?!)i=7+sGfBEvj6xVuSi*6hvYPm6;_)9I6IgPVJRLh6|A%niGXFPLA>o zx92jZd;B@OC_abbK(pHc0^2^cVVsx1kcep~@&c(p9S-*^oQ9nms=|!sOrH@?locC_ zrJ=@{_<*?J1~}}ZboMAmr2Ry$l71->;}*H_D=Ds%1&1P{mIqtZtZ9G~$Wo=2@P{pg zErI*W2SKFty60R!xN_flSmv_HcWd^^jX{*U`slf61hN%e;nQqsNDI;VcT{0w8voJqSy=V(R>U$3Io0??s~t0U-&+` zHGy4Jn@q+NCe}qHsb8N?;XEZf+8i>=7auSq8_UL<$oR~z{B38eGQ=OfaC-mHtog@e zD_fX<{QGF<>*ZN7YEF3oetY=EYad#%WpQ-$>9mI8iwi+yyEIemWXLJX-*Fw2s_4Fc z?}xd}U4y=(5gBl%j;4-!{T$1%-Tc#x+#>^KpQv1NUMu>QlYg8Bn2{6rmx*rM67#UT1CuA^wNwr-VTV0k6mCrcjrJNkSD<#GWkxVY>s`M3Tx@;%>T} zc~nb=yj^^G(`F1QHz8F3N5@v9G~m=I$#4`-fX#W}EH3z=T^l1)Mokysq>hvmu;&S_Ll;?%zEFI*|l zhs3SIg^i$GY^Iv#N0M+iRni^mj4%vPfK@YKHLq!0 z@6mrYSR`Y@g?YVijsZ&<5Th?#+>W=#7d|MkmW6s$Ko8O#0Ae(CH-losY1*J^G_bcT z6@o7afmnXeN@0lr5MOQq_BOAP1%a`9U?GBD+rh;n9;j=Urw?%afc|gC54!SH{{I6V zP{rBE$-&V0-)9@Bn}Gg^ZFus=>PW9d4ckNOjFYOKJ?*7#qCPYlQr0lt6uVI5-`DoV z=qXkmoA+Nj;JEAf9kkEyy9@X(Z$JqARb#{HR!h^@QFGLd9!IPH{fp(ZdF$aqpq1mq zPfU%dv!&A2ZS~e1vPv4rh|MuSVymcu-Q-AhkPY!T(~Q26#f!;)DrcL!r1yLd@LAXf zw|-IrG4M7T8)1mU!II&im24ifmLY|?uNeD()vYcCN%u?{gJR{|g#@K`ZK)64oWazz z8uKD`dZ%+IlQOY0l-^b+t9nA7DJCI0hPl|vg9c$QLLd@M$2%ZJl9tjh3&*T$1f)n7 zi;iK-3u!6(nPa;FFI)akbs0By@SD=k&(8(j&_&&dE3>_|vyv{%>Am!6Z=I`(C5(+2 z%6uh)p~OnmrgG*R-fAS(o++;QCUk>8j^}R*BJLdO;UCC!+5tkKYzu9Nie|cIml5ty z&74)DK+%u4J>$WKar5U{GHV#pgMuiO*Gri?_MlW8H)|lVoPPnOpm0E0VprgkWo6&? z)%-3Ej@e|`C$W`Rm#1wj?9(Su|40<&{PI{>Oe|&nZlkGMo3pOJR-7ipef+DLP8<_> zC(mFmAhrCy(=Nnu{SYJ)Yt7+A8sroMq?X;Krwf^R`l@8j%XLw7VI&pE1N106qcR^t zM+Zc7M_uijKOYf{n%Tr>AFZB$|JH81nr4=QKBtQmqooKS5(dD_2G}ezCWyX8WhcKU zxNpsfziPbntMLF*%NBr_&8&C&K6n>3i`nVCX5{ChJ)BBuG+?u!4#B;H|4*#F_>oFQ z9@yK+0M-`$?;oTu<*NT1S}srcWIL^hG4LCE5l(LaBrocffs8(!_w(+J$%Ww(ZB9Qb zn*N93AZKd&Bw?WQT2yPc7kML?C2QFQWT;eg7ck?AeEU59o3HM@kIxg50lWgJL9f#4 z_-EE(sK2dK5GmhjYt}`@Ne8Egjm{#pEB?ZM$1YEQ?NH4{Hse}I6hwav_XerW;>saz zrS{wIE6iRT%R(~FW_}DfERX~1CJhUkNOvK%B4}FVYL}|Qso~}%TzP~0`Br({!^-@{_Ma6|fg=Z3B1A%%2}LcW z&8Zd#T5LoUy|8KQ3DwO|1g;ha;@J_bvg`KFAob$P%H{#jZtM?}8;9;`s`M8Deh5n~ zRt~L0{Nat(Q!!w}d>ihq-Kqt&4?9Y?E7|5@dLvkxg{~B@f6zV|U6SWiPC%5a(ZzZT zw(4CD92EbMkUZL*81%~1LqHzd>-Mb*qeCep^WQ`*p9zVVL)9avwb-x1Vn*~}!IAnM zIJyZ{7&Hz;NfPc)DVHS9)Y2wWnBRDgc-JV=M1^ClORz0|gO$q6Q4ku0W0Z7EfI(_R zFU_nq-}x1-XHzv`NGd=ot^<=C6qi@x+4P&J9&=CtNuIj%Z>ISJePRY>plR<7(6sjt zqJ3)rUqyT0MLNR^u`xLx@n_Gio z7=59V0bE*gNvRBbLYRiAtfQHF)4K`>)MGDB#0_IzA= z&EI-3(mSSZxAf7b1?p!Q8$!L$ap)u_4N8yV+F_UC;oI1@RE1z=dYlK2ELw$|0L3&) zwk%j}QUZ|)nfIf_*2dvm0&4svh{G;Nkh}ATyd{;z1@hHds|Ih`iN(JAZ~EEcaED}r(T7^-Po(JS zij|*7^qnJhRNgGh-Rx%R=1-*9&kCL+b~?eWOct3^ZJ_l+b-)a~8IV37s(6dJxwLW% z*_Vjm^&mFjz0a9{6h3Swr#=UEvKoG6>^4Wa5_aYO%e@`75D#ROayVygpL}Kyj?KBs zcK~&0<_qxJI#!Y=L6>GNb1*}YhO@CCSg6IzfjOUyTohVGzh)KDK$|n=AoOHIn+z5i zs02;B;uMrM$9*U~v0ty>rZSZ$iY%`yQ4?}y9bz)+BmFY`E|?m+2eSkN)l1$0Qi+W@ zl2t3uF3E5!ru%-pf-1g$JRLM3iiK?#Tk(Yxx4V*wPIDFA2^kYvkbq%3j3TShd52(N z$lNZGLzq<*_?hrnn=0aSICg73PTJ`_mCACE?>Ao2(e*%Vp7 zijLi3j!)6-Dpwjcj>V|PjwcmEXki6QwWKxj?Ko$Pf`)dAEO}e$klqPE-pZ}?wJQOj zk+ejb=Sp?Xm_CK_N>g8%6s${43(y84Qxy)hftc;V zzpYZ?D*F<(O)!pgPun7*7W_vW2wGlbVE#4o2qd4;$8C$?{q-(p*>Z*g?i%?7_Q!wo z*Swqn4E-@JTMtY*C$Ou8|NCiIH?(&CtDP(}svYUI5Ju2MmCF+w8DT*GfdyNMoMgx| zE~k~LD|kuk!Ws^FBfGauxLT=steN{R?u<|W_N^ba2ZWVSDp`3XX)-Q7_PVQt)(~o-;BQflIGjV#iW^FG24NKgO%X~=a+Ek_FBgbqrN>Hc zdgY0+etSJWbP(C`ya~1Wzzyk*iun7f)BXhY3zji1jE}^E&XHZwqENrAbGPvn)cLjl z_DF=s*Y<4y7B>UHe*Xhv?~h-Kti``7G=Yv3H4Gmc7&5XEnHdb!d&|DPNSksoRVsQ_ zo!sR*m;y#=XDJ3lULdl{k;)U**{$H?+F$7`erN!kc`NDcz6dUwSk>zmJeOfjU1|3` zT>|=0xc9T(|Gs;A<0tb=d!yxu{YuWUbZ@Ajk~5E#f5w&nDZS-Eblu@-dR}h8-g~A| zS3>{Ty0l<54m@{-jslSzJ=RdXTre|vR`x!LUHbuQ&-0u7SAB!W5I<}+I{$AsS^k@m z#6Ba9)_PidP|$ny1DDuPQTs?ld!-QG&0cCEaN2P82o{n?b|}mdFuhN5rPNg>S2PGx z9}y2VZY|6l?rd_T*7YvL}>Z@k(QIR@$jZ)HtI3@naPMdWQ+o+)0da0 zi{TR-R+&}@Nrp4P@m%?S^61}^q;8KHMg6zc%f0jka3Kei3wbM{)Nn*z?3PDimin~$wY)fbwP}92c_lRG_ybc~gunp#6 z)k)1KQLVXb_4wty)-=yuikh^fFi+7I2>5n?3cK*oy15ZlJz7O?=lRU}_cgMnUUB^c zzY>CMf>pVEJk%sNK#WUzGpvndrI?Bv`RkS2Is2*WU^!3DAXDe1vmzgyF1T>Bd3SyJ zotDFr=LdYXx%ykE`(=_-VTI`!>lGxnsP(V3Zv!^xWm_#hlA3Ks)aqd(KuM&u<>k(Y zVo9@M%a@jyKpr7uJ0a||T)(e)Bt6ol)}<5Qe1=OOAgtC|~lQ}}{2;<>vKG~W~z zM9I}}i+YR^&_#M0JT<^B=M>pMq8&|&XZXVl4zu{2R{V?0M%^Un8+D9-7t3&>2J`(d zWQc(~UC*eCw-e_rN~5x;8>8)8NaOlyeyxM>ss*mu@Q)!w?_AGdjtwZzhet~WCVoGc zKPo&2X6JmrT5x637}bsR!@7~e1Rb+Ew}6j?#H~=<$&Q*s$m51r-ktn_3o+LBh8HO>t=`mWf3ZKFDY?{E*FW? z1VijL1DAI4hyv0eYA32?{RLQga#k3`ax!S%q_y=5iVfA$RE0k@VxmMP!&~5C8{y z$p7dWqHf`60bEx7i||igQbrfT0RI+;>I?G56w>_`^vzpHC}~5EDdv@SlA3zFMO*=x zFeNo_W3KJ|wHMXMP$;Y7m;oYx^WYcNmfyDbSKOW>p&Q&|IF-ka>>((UqPd8=&6zL*+tg? z#KrE`!W@-dxc1BA@hIREYnj|0;uo?E0p7#~BEuv@#q9*kW&eSZ*F6QybeED6y5-#d zE3Q#BD5TLQMxEliNzNAV;5g>W!x&k-sgGayzCmt&QUzo$%LqQhc!mo1%?G(6ciopS zE)+M>lojF0im@S)sknr!V97VxiIv5l39(v1r*Ul}686$wa5b(nOB^Md{-v{09NKo( zLvD)`Zyay3=hwf&^&MNRx~Ixe_R&1nMnfad&Ke@^%<|GPa2)z5V99>;MEIbT+ZWkh=p58tJ^($Mix%nAyk&Pr6-JIQEiWW0>yoq#7fI?33?on_Jui#;)%d(Pq{@lveac0z+9s-#Jg<39jfV)wnxcN zGdRWHd`+%He#(Ockr8w=9m3eeL~T(Vg8HRw4Fj$?PGi>k_@^J-1bITKr-R)@??DQZ zg@&=?8`Ouae3ah)$$6FMX;+AAaUDH$hn`-XX&7Cwui zu)@p5dG$(L|G)U8h`9iG0=NocWBwnXls+9;H`O^zfqmx9pk#kR7=L0J6G}3uWMNoO z2qj`D$!;`V14)XZ4HJq{*_fifH<+K`!`_hi(PGinVJV@b(1e7kFKZ{4%&M1`m#vw1d< zz;HiS1YEl?FW)MkN2xN!y!%q7> z=%S1)y)Y=mpNgODp%7!?Vd21Jj8g1;I%%{5UP{d6`8p2aqzpyIBO5QC+~0zrFvyFZ zPh-lQ|E=K7Yu{X66iYK2qQnCs7cF8i&yds;l}>KQ>=z3MmNZq|SB%XirK^$IND#lY zc4VQx#zRkSu;EH_%cjkxS{$dk!&lg_F^`1=V{H3nQP@(o%sCkk<7Sep#DC5jf;~&} z2r!&abj3PK6DG9vS40?ODUKG0+hx8Eu~C5?DvoxpTs*rr@>0ZCwZK=oC1&$jCFxX< zWJScoj1~*n&y?A>a6-zA9=sa%;Wswj;3HTY-V=}T5Qb!+x{iqaYKtBjEp4~eUC z*EhOzB!Y>$kz(ML2( zoyfM%^I*D_Zjt8O#A7Bv=OV4xp3B*0mmMCgE_NcAwj3m?Kx2{UyA}O%bO=4QFK&`0 zsy>|hL=l;GV79XcsvIr)wt=;nr8&u8oepebLT z9om{ea=op*)f6H`IAR&{`*!HT~F zrmr>=I18mXNQhEX>%8)3k#rSq7m4`C z8+yj_pr%ht&OfJKP7KP=!Z2I66K{yGA*jx`D$dZ=%PqpNhjQyAv>7EnmrQxSb67`@ z#Z!{Rx_kQ2h~lQ7aJw6BmOV@xX$6)M_=?;*WpV$OW-bmVA5#U(MKBQ=wKxQ1^9JP;(F6mJ*gU4rRNtUUJ#FpXq{MGaZo}EYf9_~0AJt` z*01*(LLlz-x4JkBMFbdl-9eVxc@AM?MFvuahDfo9lHQmErznTS%p9*Kwe8at$kOco zMMK?1t=y1(IkB1H7|ne0p7g4y@m)F1(&1FxThzA0cnn)vT4v@xKjQgZhv%x!Pi94u z2>z>)Mk2+-=7**D-eXzI*#W|X@(!1Rgn1XQ2uIm+jJ;I_bk;%WKht!dzevFvTMwKo z5*A#b5F)jT7}`zPg>w<=7~60}{5V*_U+X@=-geRoKhUuXKRHVRCz82%*;*Za5+~lU zOnUIisJzgu&Sm0X3NGQ3zg6qiWD)PPg}ZF_%Ie=gzl*_252zKnk5{bfl?q;-wBl2c z%!PRNaC0P+7vB};YFfjjbF4(8~29fNGIXh2D248xTR|JA9Yj3%|*l8wanq+snSgPTbNL@+X zvb)qkR=xzM=xRrPy=q5gb8-xf5TCSaoJ%XHn5kHKMe2uT*gnu~XwejeoH|cIQXS$y zq}HITW^D%3NtN6@(uJ6jm22$o;#Q*kDnt48aSf(5ocG%?)ZnipzBz_UgnY6X=6WX< zmVyt7M{E_?gR}4^8MN1Z5wghg9kO)(3bmX#31uX8;mWD+XJM&?Mz90Wu1eapxBZIb zT7LzW59N@^Mt+Hj?7#Cjp)gUAGNL<{Z!XYIT(DfBgPEa&$qkX3y`eL~!He$ai>{>B z+${b{{ux}H=QzbQSK<}fzuRQRg$vZk5 zY(r*h*paP;BKWpV$*N9qL}0YpErD5UW$O?jlUyEAnd$nas(5N+=kCRRnunGP{6s4L z#p=7B>}&L(DjlY;I$bQ^T^4mX20kk*ofWfxcvyPdr#jvIHN{eGt?wql+`evQUXWpa#6tDkWd(S>n0ftx} zhS;NJtE}N^dP;Y!x1&F`z5#b>skWcKK<}Z_{@tw8sZ|C{AI)#gZSyyL6L4<#O=!s7 zH>D|q%)OMR7_^3riweU9apQ8sz(0-tK!fo$M_1!H4Q!Rw{ahmG2A2FMGsp>~LPqb1FrL zH@1OnRe$Pu{9KkjtXSM!7HBArCY%Z4-CC7ATNEKQyRHzV@qL#T zW*RSydxv2r4IB2^rx*YQ=G)WLTAQlM2^EvYMLEVnYt`xEAH+WU4FucB+b1Yxc&I8; z7Y_C)7E3E=mJ#JjtFfdkVtfD4c;7=EMciWK#Yaw!&AQu*?)*Q!uTcBmA62N}aw%y1$%H z*EP}geuGuTYj|9vy9vX~+;J(TO`WH7GWLW^YTR1l)R0FfyXFzHp!=t@kY08huCPe{ zur;oDPqt)s2U~!+GWOzkboD5TU@yC*<0a&irH|b34aj~w23KSG%wUrADH+MgQB0Se zWczH=-(;ry@8#dn?~DR}2Sv5d(*H*BmRkf_%}dUd#TIChBG#%7`!jdbMM6)zr5U8K z!_Y%%VLIRN&$dB~$uD<^ z!-_l=q=u|C_2EYt@6VfQhLACf>~iCs1&T+SIo`x!dDEO3h<26KV^y%cGYaiO-*CQW zK8j9RxSDjebckH=qOzWKF@_FBFT;Fal2o-R%7}nuau^uXqbI*+bK2b<%Y*yAXfUWc zzD+xnb~005kv$_{GH?71mS|8DFAkT&Yk?WRQKuF^vq?A_3Zk(*L{(uO`~BBxA_~el zL)Z*pMr zlZ{bm?bJjr>*|>UTgf{^lZ;^UtIXz*egrd~A^iwqB(fe!Y(SL!sB`#Xcqmb1RGzE1 z*_dv*_G({p7|psg0jsvI>3u-TV03G#;ip&g;0-W^wyc$u4JGcp4Qp9ux@U-ba+Lp= zCz<*8-C5n$E@cY?2+Mvvt_3EhH$IIBvn1_st_$D3mZHWlC=%*P>`!^5Ax1GpAmNIu z8-avX#!)Rxc!ZNR>ZiU(&}v((rl_}Y81pk|TZrI!|I{3fcO2E6m@?*n*Xj-bWj)9C zNI}tKli}5N^Q2pP*3{mnLuu^FWsF=ysC67u;4Mr~o|2^GvY}kZ^P5~am78ga936{anerj>up7yl!;$i>*Yd3z4O4_u7P$urerz=}%DFQF z?K1)zcu#^(+B7`m206#7R!$y@XIC3x93GlZxE_JpatioiKYKTgm#DE2ahdh$MKeMp zz6f)sX-JHgb_Q3vHMt{?!?Yr6L<^@;M;4Aqs!@e^QjpfeBkokksUvkTt!T8k)9mr* z=$s$x2nCNx9_YkOHU`Kp$ABAV#_B%1%*cC0oPJ$6kiYjk-8*$cj?Q`bYQdQ0lHg;4 zf^sN@M)RhJ4|U`WBi@wy3W`OWY~*J9C-siBw~brBffmK=1VR`97z_!U9>4= zp*YAG9~1}V&t%bx-1V`^NF>Po(zkvd0dSRmG-os0ldp(o6b=fZxuZyUxqD~*h1%H| z&khf!p5J}@_f@1Pro4=NWO6T{zd+m*yGwFy(XkMs;jg~{fvP%tMXO! z$$h)cMe@ARCc?ZxXH#kAkwm}8V4Gc+u(%s&z-cH8C!Q>b-cakwBhnh$EVnSL+8mv*Oudlr|<`&@TXi@0ei*FdAH|$5pcNu z+BuLv!8*!Pp1da(2955myy}m8mJC;&7^{4w$elQs;jaEZ33!s_KGJzl4LW`@ojTyW za*{zpILT)LWjbBT>RD{`X;uio&MQurskaGq&w#dL9`{w_c%3FsvliRQ2h%LLst^Am zvpfPz9Of(JFQVTyR7eXP8BzvJ6iMj6p;a~sCu;GaIj(>E(x=NN`n6Ir!}y8?le8B| z@KZ8lpkYHs<$y-ze2<7xF_5C<0VJUXqi7y%xFK^?N>S!fL$wg+JBs{hUK}hyLt7^eml|6 zMm!Ioopa?F^R5Zn;N^N^=o>%a&x^C$6W#8t77+y(5s4QO(~JGuK;(MBF5}!AC!B7j zvPJjsTcZYfY`9(!c;vP|mblxqtiNLj|5XS6)SBoQfn3k`fh@NLM6nG=;g2f!$)3}N zEZ2iB_lb~m4ncPx^NEo|>ojWR@yD3UQ*~u5e&G}YCzYXh8bYsJyS*^f>oB|?ZWIqc za552#nF(5kl%8VkI&q$Ae?=gdY)5%4r6Tjx?vIUz{KMZI4lRwdtt1Zz&+{4+;lXIAly8dzFdg7>Kpge+8*Kx85Ipl zJRSc^=6uCrd7W45`6(%Lh@_XkEoXOTtx|Vb+hrI_sY%?$*qeL5JW~-Xt^HCq3!#Ya z4t6uTtcFQ?02^DmCg^&!gmHHk;tB2}L)bOJL3$F3=x3WyL(xr+DuL-mu`%FfIUwH$ zDX%2&mnCK_$QYVmI`ocLyO%%j^@(k}pT7X?7nrw~eu_T{J-KaUe1|s?Q8&+#y_>Bq zvpsv(__%XP2<%S2-Ldt<$I!dy9CKItkb5B09BePN0--#EQ5OSv#SFD!Dq?&cV8D?T zpbOgvX2~H6%nrteb@LbKTpj3K7U&T-Yua8J{VUDq-Ft1&AMD5WE*s_g=$4+_9Q}K^L>XessUcFJ==KZ@n`(Yy^tb9e3r5 zt>r;oUpCJ_=3q!o(fsXeGul!#$AO4E;GM&p6d9b-{oaFw$B~IxlT97N{#(Ra3TsM< za8_NxDmZ6wvgsoq1peTgHqdMBFNojVRDiIesZif4TszF*DmdlsQJ)LmG7qXJT~1p{ z0k7gUV4bN_XOgIXDvg_B(;8#y%TBx6sCk*$DS}4FNv$M{>h)5o`y62v;T|j~zt=(Ho)}f`kujijc6Eq;34foKskN~X7Bc`BVlQOAIMnW7wgDaJV;nP$XMJhdP+AB>y7U#915?1F$hdo!&J77H|n^w^~`W&y;spy)XNa09`HCKdIK;Bh0>vEqO4u}MAROtDhTK`P(iIl2GJM{ z3djxAdy($lH^ZpEucj`i&(Gz~T+H6h-Q2dauimzv{CYimIqpWCN8&&|0yStG_%m^A z@aG=~mA$wZxGS=~q$U8$wce0PZ(2_P$a|4$v#hb0G^Qjo>w1EjviaeNEj#^nvl95N zf*(*a8?~_(wa`;|Hk)0}zX)b1E6_Atwa^Ggjls;~r@Lg5U}AI)GsMhNf0*7C*)pjZ z=R{FgfT(5?lhQR5@)RYuLd#$!mdi!=t(g&CPs7_rcSzTgoF^>=DljS? zsF;0;*=iUlITLVYGojRWEn*1clUHYicm-;yCkKhGu@{jwa(`GlZLTKD04SxTVhf>_ ztr@`=z|Ok8C^Lu^Y)zc3z;SdXaBr6*Szw#28Bv|V&c@f#Cs7r`n(xVd^@p>D@R@P~ z!Pzq6LvutII&`+rcXi;VGyrccP&H6EHuDhR(kBrZ@qY&n&YoDx%cFGaHRBAiwX7Rb zR>PUno@5gGcyIk6;uue2(vLx^)X+*NBL$v`#CW3WKs4tx4;ouRh&)WiB!915fCYLXzQx6cw_Cd}(6 zW>G=AU+Wl~)cdeZAKg~b0?lX4kTTSm10JY!_eqQWCH95)iu#NxgKh|h*RK0uS}RxR zDV#fVCS4UR=`BNYU z8a&2Ama>2vOQBF2^1CfN|jphEA5``MttFEg)je#40~j6BH9uiBsUwg<7Tl^pcU^ zUlIPP6?eZ5Vn*Dx4NRg!s)3H4vHcP0LF3mE%UbTBeeKl-w8s~~W@w1srA4F`@tCv5 zy-Yty62IHRS+K|Ef$uJN$qrsmArxeed+s~g%p6kGJ;~PA3Sr-e%eA@Xi`G>MVLvS7 zxzkf($x0dMNE&z6vP<_^u{PzP+KKJDWY=irUmg|Ae1S0DT)kK_xFgy^6@7-ir7C;8 zRg<;@;V!3}!bb7Ud@kdtFec>IP|UyEr%M2Aue5g_(_% z83|)BmydVWHSTq#vcn5(c9oj%rGY__r?h8QkjEp#qS)j?(ml$oAjw7Wwh zRKp1G=b@bq>!eM`3>ND^n_;lX-!S;IL~}=N-%o|4&PzhRPKgO{q!M@8 zv2kZj&z|QnIUn!!La>X1N2#S^uL;Vp=A@G4qLQtY((nR(+a0B2K&fH>o9mfD@>?*n zRl>mm{atQoVLqw6l+0L(Yb?+@lw=6RSz2b*YWzWrkdpnlvF|9Q*fYDCnAr#1U-c%2 z^)I&NpHO6KhOZQbij!b}Db6K&z)5*XKf=K_bzZ6%FHLMlMQSC&yX)_*;FO-6s}0O! zmQ}2|LnGYxLmy5MVKa}cSW0EkvGa# zLv+RBsElSxa=NS<&oRVz6Sqa!#q^aXvg-0j*n5c9VUX)qvJ-W8SS93SXZtJeq@w_0 zh7l1^wW=aL*2V)9VSnmso~umbBC2KX)FBS-PEI}byL+8GxIk#F(`!(F>zUX*7PZ$? zwdAXdRexrEW;(DUlA}tao*J+bYceJEFs1RcLQ<;U`#-J}?bsV-rEs?9LRaaK zubZ|RuVv?Xxn9)%q8HL;%8uO=5+@naFe-uuv;kc2wZoiHj^tl0xA{9)8EJ2d&LI@& zMVTWSmn8nyz&|67jcaL^c;iMw-lvu|8o)Gt2yxZbBBesUbWuFA-s^mXtqc$@*BjV<;0DUZ%Z z*6|LszpEP-rWmQNXrODv!`^Ce{Vls|17^5UXrEJTAIl$~qEBtAbV7KWA{9n#%}E>A zyKh&aKln+g&8MPwP|>xLKaNkIN~hAE@sXCaTiP}lyvrQE>*NoY6}?N#oHONjoM1?? zM*!D}7bfTrCrlr9H`MMuFI~}_}>{isTcBNj(Wb7Rl>{eK;wkc+X8@H~3ffjeJy3Lc37I$Tr zpVpWQE%@gnKZd*=lOYFcza1^!8M_Dx9hh|FAYwnTD%#+Gc{BQq8nz7}4um_FM;j)< z3IF5oy3Y}i1LF8$@h{G&4bi^=!bu-kGn_&3-he@h55S;r+jc6FX1|``sJx>f73PPf z_`Ugi1b-Z)Zc#npRrP#?(Ja7kTKFFGBf<{~u~USQ=zJ;U9i`_S_(j#9pZ6@ND=lFe z`Id?Ia(7@EpRi|lCfvTmr!DVHgb;8Z8}d%jb4C0b9(O|c zg8X6pK1lXTUbH>w_bX|){5cbHfB`Q||JCpr-S5JvEf(%q)AqL&6h!ZX!E^V(HKYKX z|6sljoO{wP{bOe~od2*sFV^P~;Qw{@aVib?#>?fsfz`3BRt4DCF} zJvc&a3XF)*x)|@ES@~P3=q||df5jBx_;v82e&cd;zDYoQ|5iKc>SAfbAn)`|t~WK2 zHFN-o+PVC8KfQ|#&KP_Q;9{%C%SfuFh-qeM z>u;M+gQE+_8nraT`}yGDA&GoR!V16gtKW9auQf8@Tzge-3)6mgHxG}YN~yN85ANu$ zsVt&Um~!fmW*5WpB^Eo1)6IcHr~^8P3XuzmHY}19!e4=`W=RTv|5>YO&78o63$FY+ zNYQf9-1PQ)$UHpqHMEEmsfItG_zJ>5;~2MU8&_CbU}M`q@OTlERIGeSvl^2JweyObuOVQBiJnd>Bfm#%0rWz$;GQ-^%L-FMB0}PQkz(7(B zNd00|4tO5EGW?Yfwv!SDRSRS1&Q_Gel(e)IG12(yX{+B8kz8z*UO@a6wDgZUjG?Ek z$@r!y?)Hde(Jg)ts}3=?1=4GYa#(PB3ENN&*8lce$SsBE7raHt#h~gZ^ZDt^I^yL% zhZB8O^g)+t#VFV~;kFNu<02}D4%1x2p0{F@^oke--|7I3Qd-|P13CC z^z!OoMR`dN*g+a3U*Il0&kXqQCRgen+kN|MmmeTk%^578z=mN@5#3_h6>`UI&X4WC zcHC^$?-OaC5(mku_`#A#hx72hw-)sJPw~uIfJwSU%E8o z;u%I&I9?!wHTfg}u35e$xW-zBBIMqXztIw*6P)DVzQ`lT=aH`WxxW z#}T>e(rIZdu=h*N);cMunkWJQR!R+4-+VN-Un}k?DZ3;6VhmpD$~N9mb5Y?F7<6Ze!DGsCB2Ym zN$}*7QlI)%0EJ=s&PCk{Rz!mjtzHzOgF~trB~MPl#Zu&cQ=n@Lik1 zEM}(SGr#xtxI+17-;n`)I{YO}pi%$)6_Hx&)R`>9qevTr3Xxdh220=< zZZ;{QJOydxZB#d|d@2PY#L*rc$)h0;nj{J8ma366@Ln?f!Q{q@bDfRTAMs3UrVQ+u^Bj)uGB4;s?+wdue**p3t%0qj0 z%g+SFp|SIB^O*_fJm<^yY=O_$3-@n26ba*&1C82}9z*;5U2Rm2^ztKaU5lojjrQNz z#u`o8?MlsPJI#*9E(3cDBoOobHEp*EC-n#OcV0L+&BiA1tSNsbJ zND+`lefML6LXMKJI7%R1Z@NSeBGel{E;H@bg@;mp7_C+EeBuXMkaybbpn16r&Q=SH z*8_uYQi(W-5gn=H%NrPd4jyCxR?Qr^llg{;JLXCb)yhmORv)5T+8$NX-YfUB&K=Pw zsw4y~wxagc38fw#3PCj<4>q*RS-w${TXU-s&4IrhZ@{A%6c z2WqzH)49xYp#<0+;7N7cqTsSeNzyO0lwt18xto6nMCM4bNa}!Y8%=?gOj&Nt_$2NKFnGJ0NlRXY@HW4!&tPh>>~#f>)4`mY}zVKcIr7` zY|NWA>eeuek!`5FM8ziMX1nT!?_EnySShOOTuvW7^}u!-mbEzF)S;i+qfD}+RD7Ct z04k0hv&tQBRc7X$ckd7>I{5tC1i|%*ij4BExX(4!{t2lR>^|#_)3zs|rz5^cfA$O2 z6`A+Qs`;EV8u(KGhHD7RAffFzl0}@SULnHVQT@~L&iww0066js5`b(G)`qZm!T1d6 zHQ0_hxxpV6^&*_Z^5k#>-n_JN!e56+g!?;cW$KDp0DB_-($L40@z1nVF*?4P;=HR2 zm?uoL>?}u>hk@g++u+hJMTzy5>iBE=9A1OG{lu$ z??>XNt&^t}ET?cj>(?hU7R5AJ3rEFqbJ)QV7V0j)0YMRkI}}|jC}~G%e0)78 zTyxiT1Qt{YL(t?!@v0EY#9%B~TQad-zltdSkfZ_GpybX3DQECAcZ0~aY{T#k-4nkQ zPCmf@tjLx4fKO}j&_t*x%yAB&l8W%@alZts2JewOB1 z4W?_;_rg32`m=;PGX9~ZGn??h0B&2e#^Xz_ryTFR;~eLw8GpZ5@E@?3G!{&?9u`9R zaats{;d>-hw43a;voe!8h_cyCiBP6Cq{uk4`|7SVbhHd;;Aq$5;%|8-~|5r1yM#GzLX-7K|?~a-I8Xhf zrDe`sMpu&A{DQwZf|a&L)joJ(m#JcsAuXqnUactXXk zUN>}c+096ZPPNXMtk+D*c}v(?yiBr6GHjuT_ppm4rBXq8R|qr`NlbNQOQBhg*r}Q$ zl0E1j6;fjU5EA7ECRKT2;A|^34ZGS|30G*yA&3Hh*Xas%FE7SD-u)b z3N_3efGR9Iv3gqfad&Pxw9qdK3eq!Uh1pv)jiVch{NVibHEk6;qEAQIAtXEFj!!R{pukEHyVC!M@mJK zdFp6r%GTq@Vk|l&N=mFSGe;NljxLzE4bOjdLnl%xaj|Qf;x{4+%zvQlntE-Bdno>n z$&;m&G8#?vw`&|9JSD%Tz{dleCk(s93Y%@W55*0#xoK?_qA;w>a0)WB}z6viW1WNv>ME-x|19g~qi+{*J3rh9-HwDP*|sSNpwt zhvhCKND9u;YzR?u+K;+|pcyAC_kyUu-4%m^by*6rYF=&y5XUb}(8ie6O}M1*E*pDw z(2FFYz8S~Md!UQE{9JURO#=mheR~hQum^NJTs<-C=WEoQ6HBdr%ZpV~9lKY8T;${0 zJK`uzN2R*n-A|&gyrrcj^OT48tC?{KDp0}GC(;gHEG?Z6L*!88{)5^m#f<~bP6utx zaK00hHDGcku_7|{y4OhIAd?@6D(s4SZ|~4yX^c{6 z@`v8#ouAgo=*VsZQ|KEwby)gh_v*J!Z{{*0Sru|{;JVGWy#AzX2sSf@cw zO<@|?<0O7Lh(FtdShp`CM4ovT3!+{8D6OxYu(|47xl?#WGLMq(pdNm^rfqx(b6pKB zZC7}hBNIrD>!x?ie3H68T|35gu;A@$u@AkS8zAy{$1RfZiwld(q7NCBQ4(>wIEN6Zs8^SrCW<%@p5$9(!C zU$Zbvg`#t|i~em3gKhoMzm_B^amETUhl`IdLy&)yyZeqbA;)P_12N&?e?hF&*mtX8S=*s}RBMrEF>EPY&jvcie6jcJ>LIv=5y&h|uN!_I`xQkR@= zZ-n9l&NNG@6{?aw3H)4U3cJ9VsR52F**8ptPmlhE76K8LSN`3) z6>F`e>MD28`f1szp6&*^?M^kii#tiQJETHH&`~kh0LBm$gP$>m;d*hT6`VCji@R9E z_;LrFkyPOe8IGLU`*=tA^ajWwhm*q>Y3D%=M#ubc|LVdAs6>!!34x z_A~35oLqhyp$PEaK!PER@mdO}cEC+F91#>JT&#SQ#CNsesz^c&#}m;wf5=vgbrZAI zf7BVm6Yg(Dtm(iuTya35O~dWCCH$pl+d5OZXWYDX*hXZMs0`RZpSbnkr-%4E2};a? zC;c~r5&7XD`|dZgS$Eyb-13#voxLHA+3`%_UW=`V3>J~FdT|V6*n6zCW9GF8xANp5 z620mC%@V^*XO9U+5NM3wzvzrK-wFxnd=pYr!T#TCtN#l5|LC1WJ&a8qzWsXtOXWIM z$@W|28qJU1yBOJk)osfyEPogACYam? z@SlcS&g)#W$dUTfo?e%CIm@5VFAqEct~M+-D@C=0xSL@+an--theCJPg#5Rg_3(F))!QDKk<-8s`2wR*xxk1I#^14kp}HN*F0vCY8tf_c;_zurQ=s{9!Okh@_p> zi$|G4wlHL>k%r*IDy-jZ!rJFe5R@<*XqPxt2MY!nL)WSMBP3kJMHj`%v}(O=xZ$$j zzI^4^>`UIfKN8v9pSnrsgid9cUbpadsV^O#W-p^5>NV-I4L=))=BUt)K_m;o_V*#& zFUs7FI}KgV!Wd(V5&Ws(g@w|5x2^~rnW8BDewLes8)ufm%?scX$?v0PB@KAzVF>es zi5;ttZ57wY52n1^UcfQ`76yO(*D%3`_Xz*dmR_sTFneizXh`$GAK2d#;(sQOwNK zIyq%(-)v$048Rj*KjlxJLKo0q-9TBTi${M2|L4sB(&3d=hVOta`L5BD|6XES+B(=U zNQv2)di+O<1GK#Uajop~ZF_GkX=i5tpW6eqNz(SHOlYC;n}Fn!g_36Y*;yq5I#$$^ z>l1_!Fyh1@5K+2u65VgUxSXU}6pP@}I}Jcgf>whxt&8vr-0>nZWDy@F?fh+(Am6)= zkI=8z7jg%}j(HKJ<%%G}P<~AD_cejA=SN8}dCR6&`Mg<%R(-Q=iUWB( z+Vt8eaXzT{>M*N~tTekB3b%c6!YnxMPze2M#t@ZkHTw}`{b^KeXviOIrQJaB*1xr1 z*BLI(m0GjqYe!mw@^EWHo<%$fGxt9b*KU1YOnA?w*fhtkz>JrY;pOGe%j6}kL78yI zkUtD_U?3V7E6q;C(6c#NB10u<1rTxQ)SE z<|~IaFQgD(u-QsO-qtR-xB_FR1$IXVo|XI0R>wC0dfA1qVhk3aLEVKM@4n*iOYF?GM6Vg zGodd8h=fF_0tDieyiioA=sp037#ay4x=i9{s9q@)MwAPb#1AbL?p4Vk(p3}~DVNbFC`Q4*fe}}erYux>Q z*W@*^9GPI4U}8Mvq~@mUCMc%p&)&_|yua`ro1vkZVcviH$#VQU?k06=IxaVvnW3M> zI-b097&gY{b7r|UdyvV#ad0zB90p8tZ-cSIhV^TTfKC#C#Wj_DYwV<`FSCZmbk}h@8%^1z8mk;go*$0E&g0I*AmLg-9gdYI$i&HDvLI(;v-RnJK4@0SvW(31 zMkObQla|KGXG}6PnO=0<9|0kX-S`t3hD~T5cYlAdcyKcYO~neV#cNDn5+iRH#1A8W zC5^?y%f>`TXURHslCuh}F<%k#ll8k8N?HztL2~>ca59)1$TU+F6UH@{vzG9%kQzb* zBs2Tmax${!u&ghdOmAdJ;Uqh3H@~4Ii6IgWYnn&}ga4T1@@#@|dXo}|Q*Vn^Pj!fN zc8`gP>kq#UWZmBv_SEN(7`fwVpS;@rxiQeKbLckJVCln1*ynxs*@f5}{VOepH%t5) zBPzZ#hySwS#Y288>1i)A07SvIeR}*uPw3%2avnu&Mpsd;wrcHn%C?awhiru|5IQRy0 zjXpfVO;+GCFo`C}L)sy*5F=QHq1s5ZRU0^IvKtM+YUOfY86Md2&k(sBDGW#E2OB}u z#!TU#)W~~4P@zZ?Wdxykg4x3N5suO0KqLJr4+Zd6f?}r3sJQq|nJ%JQkLaH^3gNQT z)`C|4FcINus>F6;K37?L@!KES!q+lv-*SkX8xV4a>If97GstU)!IchRgCjW401 z<}lXw53HONtl_8E8ssr%RVJ1#w4g7QWUZ03d1iHJ)=K7c7Dy(lLL_0JU5HW?$vKg2 z!9ww6AKws08;K<_kc_$zZ^{uP5{fNpfY7dB;Q$oaOP4G>#P@gU z1ll!W$IFO;*fr6wwG;p@gZCBGnLqd+y|C%lBc+go#Io68t6enBWI>|fSlMAT>IxtR z8|v%%eooUNGLrdLAI1t{B>TFdfW&8NsLrRgVgt;A_v+(D$ygsAv#OGG^8HzaF5FNa z(NL76wUjH*(9TzdRR}BW3PU?_!s*BGAc8WWr07|0qe7wP)vRwN5a%}gJ77Z~WQ|J$ zhJ7z0uiQ9k>V)=GVlC0T9Bk5(p;KVyHbPjrC~2okqzZlM3?+JK%rWOg;J9M?Dl&?I zb|QNW+DeNTPE^dbJR<5C@~`ZiCYGhDq|Ojjo-b>uUwmGGw^OQ;-1BdIof@l3K2P}d zKN>IEfa6he0{Oq3L$-)^q6%olkS<`f8131PM#8)53rDp zd@&ySIl!^LU|9Z)rZKw0FxARRI-Z@DXpGI92$O*il*T$pk&rZONx0PHgeqkK0HRpr z0L7@VbF!6RC|Q=>oc^d*&5m+k6pq-Tq@IcwD9dfRJPA&m?Z0&;xJg8gP{y>0z$3-< z=A|^~f3>taQem8mYvP4CxC4|1%@F&lJRIO5S z-`>K-Jrr-aejICF$qXQ+q;=Z0l;N-V#jr#^3d> z8MG1t4c7zja|GNF8@yvM@`J?01MeprALYpdAG7p*D*y%5odcK9cmtn}^Y?W$65`h3 zH56>hv@3ORO&1^oRF4ZPqNxwap&60WUXMeSrH~f- z!G@EgW#u}qz6J0^50oqYu9*uMztyL^ECPF-FjVxo#L@D$&FS=rs2NaF(`nn6QUm5Y zL<^ejm?~sJBx^g=`zfI5jfF zKdI72>^Nf&sOyL=pY&96*lZG6Coj6-D!TBTReJ)Nd)U)b{&3a)p}na#tNaU|b*=>o9Q2{muG))oG|Db4tVJP8Wclwv>t$OwdvgT>@ z0P@o-v7#N!>P-5F><0-@mA=j&pjtmkmIz_#k9p<7`Fec_n6vcYpx4y2)Iaqg=nvI` zq8~Uob>Qd^Ga4XO`jAp*%fU&n@FHVkMF*NiCa6FD*pnyB01JQIfjxl-b%Hzm{e?1V z3+But=ox8n2{ied3ueFUCJp(}>8{CKyWKRC)cvD#IZ5k-U#Ka67LSOvG~|e=&@*!u zkDS#sgwOOOW(J) zk*3yH+9i6v5PkJ^px4!ZYb$@Wcl^E`t;Vgr_IS{&Vn^^cYT+99gy_9E63od&&A2qJZG-Ll_1>^hIE>p0@q zUC15CZWmb2vQ)s`T2bmzrFC@R-5SbHSF4LNXoK}cg_hlJS1SqFOiSup%`=Hub-?x7 z8S^)Rn`rvH4RR!2Rsw${lVjGl4Ott$FlQJe6psYPQx=VRlv3)2v!yn1>Ur=uwUr%5 zIc_2E7B|K&`J^~{X3{BPMlla{r1REp4^&3}fbDmTShSEFs%>!>IW=|O_9huYL&7%D z-@Xb;{t9Wd#vI~N2MFaj78Ax&PA3w=KQxJrINC)4i4rd3iasVfXoR8c*h3+<7k^M+ zy5mIn*HTB7Q$+a1On4=n9JXYfQ4&wUh=H#L;}m_82F~Ss_@c_!i=WZ>+2&G4K%ZDg z4+Q~y3w?iGQo{Q<=J5}>`18r zP?jdVl)5*1!DJU5&gu)!CwiT*x`hVa*)H|TdgxoOTiOi~7$Cl^aOzG)%Ktp}8bVs! z3G5dYdqlk~-;^mCLX+TKuzMFs2*&OipplsJqcLf*_XU0y=Lot#>P_aeoh^U z1K{$M75VB>`6Wibf^PFY`xZvNiufi$0@s9=)W{~Ow{kyin>%!2nxrOs4({0sox=+j z0)NY8t&)XvN$Q+G&POYp$%35bMpO|#UG08$-%~zZ{f+YKgHizvpY;&nga3H@=?-P} z1-xr+@m?zY0crCY%*s9b5gzu6I6pA)#r#Bw0g3CD=JUXv`FWv|zEGZ6Nm{85?A^!*h#U#+oj($w1IqjP zGPCx6d;*%)tAr;o^MTp+RrJHLus!!acijI*Y_5H-6JTOhO;4<|L?+xn_R9-7MZKFd zXS(p$8QJu;no>8~z?tdpBD_F_-d0SiO8soMU^6pb5fp8KxKg#AY@SxP8RL@msj0>X zoMoNYCS}z!g<^MLh<^8+_(Kz5;7s;HBwt0LJComBRe&Sq?08I}DxX5Q(l1Y@@D&_* zcL+JQrr9gHmPRnqNQT$5{pLd_6H-n85g;^GJuxsy8O6JV9y}#+C}0y-6_UVT zUw5!n4hb2IDJYQq<6%{&YNmzkjf-Jpvxeawtwrv))Fe@rLa!pAod(IaBp;3qANpC; zuo*LSP7h7YTM_GG$j;EzVQh{PEVE5Cp%rPnA}=e+EJ$&xs4QJ#YR_yF)vH<)<dcS;n>E+c3|yUNacHNh z^&f1tAcdySFfd|X4%{qb=VFb9C0=Q6RJPaV>LX3rdtp#n24plX_I!tCq{^^bv*dtQ z$sg;00$Y?>_Dz|UqOq*0xCAV;VW2!%bD#)Swi)pdO$Vc0@LKH99xQsR+5R*KSSSrP z?E!FFr4e?K-&q%r0d9I7&=(1j-?$YKw=meul2+X$xs7 zeU|T`cLLK__#5>O31Li*6lt@RD*O(4%3nu?kAdQtg4By3hX5Um6G0nW9EK4=J9zm! z+aO(~xhs>Wbht}-R7tNVQaknsJ_006y0~m6fkJ;`b^%OxR`I3TkM5#qZz2E~fDJ6j z*bo#Ld-}#9O!(5Ve~VQj*9J6Uz} zI2Ws<7Y!e_|weV(C#}br&W5$05I_%dfQ<~>-11(orAHKiGjnth}agItjO^V_rX;#lb? z_$eirP%(rxp(*`Ia~Ll|)y{6JwcTwaGWx|~-pc^qRplnmSzi>I%YnIQ?apSd-8qHE zoRAuUHa{-QI%hvkA;%uE`dE*g-$!w@K}!(4X-RI#GJ;WAYcr$cmvGM|WsT?l9o6VZW z9Yt!T<-#x^Mjl7BxAEYp?u|SKH#H-H)l2JY@E|bEEYT5FuKyv&xDGdEQU~k zoy!sAgO`QdW#yVU|0BBRi;MFZp_7vPwGm5sPQhj)tY<3A8Em>hV2i zGDgQ51QIpce7YofIuv%q1dTT-*Hzz-Sftm%P{~nH&`mE9iyJ&5h$Lt%(|EUk*HhC> zU$=pXgMvZZh1uL3C;>nBePfTy6U13a(MSu%+$V|+rB{X=$dWYdaDfXlu#AuaG3))vJG!$UlrV(md-aLvIjVb zH^Iy#RTtCq+X~`(845jW6CK`YU-i`Fp%BYF9m<;Q_!Al8ObP|pr%oebh8P*A|Ws~%V05U(G1QAj<7VB zNRTt1fecs7?F@iCn#dZ;c|)Sx{|3h~CVN#gR(u<2-XXhr{KP8&F5{FRKZ$D&=|aN97j zG`j-)V9;PB^;Sa&NNFk#sRMC?kA@#iZGUmDrFY>^L^3fKKnVgOH)9x`4h`lP!=R5~ zKD24zqK$9R*{d=2xSCy=apY}@!_+qN@tCeF^Db1u%Fo87(W>aMP??&_-k zF8ZtQdEZE3&MA_j zd?N7GVZC-uJu04uybX9cL{{+?m`6Q})sAT+696m&?$xiRGM$2U;myY?2@1@JcbQ8* zcIwOntj{;4Q8Sx-sCeO71aG5(K)6H;6=a6rCOa-nFH>6|A} zyRbj>>iZwblBg_d9O}DFKOC%+B1qG{Y;w6h>7|}kd z3}!g~?dDqSTcuzmbmQM;*dGKafv=xTP#Kr-EKtQdgZGI)vAY2PZrnVhdSa6N2Wd!L zqvr(#j)^OIb}d5`u-9P7_up(rhl}tlgL>0UT9p-na>2vdF8L$R{ow8ba8lC{Ax-xC zM{{~XCVM3QSj1U^KkLC3i;UVo5P4@g*HDs+B)Oxna~_k4{#7mfv)Dx)G69(f&Ya@% zEkiWS8Cl4|@EO;4oRpTqr#U<)1g&|GtiS$jcH+PGtpG+%r5;0eQ85_w{ul`%%*kdLMaXA8Wp5-F(?{YXdEgj#PdsZ zA^2fdgN1%bG0&r)XLt=vZL3tD3ZvwyVeN%tX66!>C$Fb=wPh7h%goTK5lVD4Qsql_)(r zOk`&+BBC^ruz&WfMCPNyltm}7o<0-K3mW|qEsui{ z)QZ^*iP`+Q#bD|SH*zgH()M$U*whzy1pnXAWQ*F=7iuI|bVQ#i4i4L6xLtRwowr;x zqtG9I!n=Vt_`#1!LJIZaZpFJV;pqztss02iYzk?_GlE@^%~SyNa7e6Mc3q=;}H{wX0Qj#u;y&>yQS;3-1?Jk5b?}qR~!kQ;{Z4iBw z=7t2VkJf7YzxrVVVA^mM@b?P6jseYsCB0pRH@}YG`CD7bsy{k?I)EA*POIU?f%~?q z-ic8+@VCV6x(qS-1H5Lhz3Ry55Q- zd!(_+!%V_D9TGU$2C|yRH^~APTmaQ|fL%`l_8x#7oiIhsS4qV$IH{ABs-l)S=|X7Z z2qoYe7?aNJMfN~~Z9Q6~#YiyyMr5^m{?#rl6Y0-Vk|Lzy{oI$7WQV0{H<-E25#(h{ z`tQ(`ou(@rOI7M8XbVHxmP=!~t8HBQYW=yP!XOF`HmddlVITqmti7X>BY05IB`!%j zSHiR{v|=k->DmZW8GWjkofX}RJ7L$hyWpiQ?&RC%NP}?e-CD;v<&-TO%x%ZFLO{G| zfTB= zRzl?)b43%)#X+cvuSMg?hqn2$W>ZEP>i!J2Etrk75Dbqf{G>8YK=C$+l<=qX+MyYz zOO6239?%Fs4_ZdrzQ*Z8OYe=^{bv+kPfl+Ct(uOWEuhMlW`9K(rcHtgZmkGc$2=)o zT-qLklsI9IcVHlK2u)blRS!8bhaDj0%?9T10}o%MUMU+5CZB$ecXWo+>33QKi04nj zB^?SP6XfjWqG}i*eK17ZQ0z*^UfL8x%g@dwoOVXY>7RT{Vw8RXTIxV+)q@#k|IRl4 zD$}~urpnsUETda(tgCiPLriU1@G#wg0)89nZCLnpr_&6qFI!`(xGGbJ5$WSAwVb~M z?grEr4x{78SLs48_TJ<^bvd7~a36dpzvMRsiZ4hj1qv=$D=*4iv%lXKASy zjI5+^>)x&jFfdomE9Awvxz|)XRgR)HDCkn_Bqtg5zY+Ht#41EV%Gtkk8AvoFsoVhX zxVBjRHI`+2h%dYg3f%)*4k(AV5vDz2G08Y2*(v>K)QMIqKU|~+GbC|lbYw}jB(2CU zX=8tW7Mte0|Nb0=r}E{wUC0A53|{|qfx-GW_CbihcbUS$}y{uFd_0Mo@IWHTW=lGO>2^u@8i*ARF15S`wF*Wy-Lxt80v(5D)<4l_y;g$> zi|pc#EAn&YR#lpxJ|#chwY+2SlTR8@7r-<~=}ps1%0x++$T=-)gaqbc3+(p1^&l$z z)8Mdu-7?Q9ih4_p{~5MqSWCAO*96pRvZOcT>{}y5r><}eV4%8w=9a=VIR$)FxlAS6 z!+c4qE*H}mh)@MdYTk38cYl&u{s;k(LU23j<%A&9K$j4#=6{wFurZtoAHLKGkJ?LO zwl(LvrMfp5EZDCYZVZM=`K(h}5#rKbLp9(B6;{-fT%*ati@5-9)Q0h>o%9v&cp=!! zJS|9|?Jy5aI$3hB5C^#m5$!Y^<(jw0sOH@%?dP89PJ6Nz_=XF)e_;Q)m}=I%B&e$~E?ou@L^|P9w^-7+(Om_qisP$fn~&_HyD)p?!i}jyz}BZndOZ zIa4Q>l%|)ShRLGdKoStD?ZeXgJ~6WsgSE~fR~qc2iNbkAGwr5q3kah>!6+wU^9zKC ze`2IBO45nEVQDWe@N?jF(Fu{sBH_G zTBlvsij*VDQQVf%Ujj^NUC}l6>SAgVtqCKZ9YEIerTtq8M^K!!~jl6IT;>vpIU@BtuR}YagHm`z_yc26ymy=M+o$ z;~vC39f~ELFQX;N81B()DGG#?-pPx&)xI21%hZt|+ zG5?iN49@kLkCtNyCjj*ZrF&%P6g32nLvGHzl>zNdu5k*l?Z&o6zq};-5?Nm_d`xmO zpe%))BQwRS(WluDuGaa&-Llaj>JtC4B$^KIumsV-n?LvYRDAOB)*9e^+)Ln>j_!K! zq+%oygNe+1hN(GTHp&Zbt4jj%FhA3uR*q{VcBz{n4x^F)kJmVi>*O@g0w4+@Am2gp z2%60gm@CS$5Vp-96#WVA=69%HLN`s)FA>b{G>-_YG0!q=MH1#45)guHk|b$4EsBcU z?{*y)tIhwj*-~@&oIiqt49c2%z_c0haeLUhn{|U)ko=|)6KXb!vk?Ezxp~pVf5HSa zdwJnfRSvc=_IirIE`? z!8du#wO{osQ#z6hSJdk(Q=&ap)n0a<2_K40y$1Gk;eHM)oYOsAe@@J+s->jKu0z8Y z{z;&sb{sz-!yn;Ouz)YdufJqBSm2qr53JXxf$$Vhu?Q(!ZBFyeXjWsYPRs}UkXDNp zDz?t#58qp8#;C6TFM<-<8G)#0+^N23ua_`TfmFFEw;{Zl&M#2CdK)Oqg>K7uA%+Gm zf57{99P^n=yRyBcbpNZ~Rq*v@`p+Kv8ItC9T|UTqGv#p_Jj9FhUzsrOeii0K;)T(}k+zIY(|>C8or8UI5kn zhJ*EV8d%90lg`Npas$Z0Lq9IaQ~ao)2NiDjLvnJ}sp<+p5Z@p^A&*RiT1OyKu&MTT zJz>pQVeR3;UjvjQolyWESP5-5NE5_p)g61R3}ahQ)UdV#Pn>J?S33y1?z_T@j~Kr0 zfZ1HN%2BUZeY27`J6GxBOj;K!@|nfXB+QhH&U9I=vT()J(>quLzDW0(qL)_~@oPmH zd_&KUuIeQxz&v%l2<`P1k-PU6#Gupqq?>K~(Q(aO4x(^Nzt}PAru)b^`o|rYJp6CF z{=MV2{WTKCzXjTsGZvArGZ|xd_f%}G-QAd36%gqH@-TlAoK60!-wkwj4wA?-DPOcF zrwJ6J--YhEFvbtRt|?LcL6%dyrp zq1N7v{v40I&Fcgcim|Uu4)0$k+iaHxG8m#*_2axIhDxV7RJ5eC4SrgVgp`* zaM~Bg?!t1bc<^p!g|A0CD9k;Xh80kmkZBq1`A}dJM_}bffHbydi)ND%X+7FR z$qw`Cz??QxjkaHWNy`|)6mMMQVS~n~GPE@j@Lv8ULKtHi!+)@ukiM&|QTf$^l4Ayj zm>K-$6rt?30sUxK--m%KxH|%=d}!4a%`MGKD`O1L7O1-w`slb!rfR`vQSh$kDMoFB zE|N2ht|!uxV;S2|sP<1^j*dqCrfWWhpWr|}_U}Cd*AA+KEn996AIx-(!487_CGJ)s zySW)?aT5rMB?`k6jGxxS8H8%Z-}^MPk_pLzKQQC84xU~(Sr?FRh4LKxV9|2)&Wi$2 zuKAZ{9T-=cIR(5r#DTTfmJ1_jhQJ1px-EfLp6bHNRZbpito^Dzk;pnnxqdmxpzid&=N^y^w z>7xa&vFW=(C-{tg=+n5IYpS|azgaS4p<`DDf{SZ}XVX@EUa8nwVloBWa;0*JcH1hZN^J~t8;=L-=>ytN<$!kk}n{1c6`F6t?4~y^N!f=1@Ls<4d zT5o#zz^3zhe6h0X#q-$xI@byI*>6x#~RO6HkBFwf{0b5OBSskAKzKFLdQ4p zUmizVu6TC9O)qdM%D%B6fO{4M(I+)QQ)cF+BMmsWCX6Hml-QZ+Pj?j+d3mroctp$C z>34Sngk1B>9EG>Id&zSXsL(%3WO|E&f-8YqX;Tq2?MMD_9p$f@20KmFDXW|ZtIdL6 z8guF*-65LZUJf~2D`!Il4?`S`H{mVQ1_F@NtOm9D+60wd39Ro^tWA77-;|s>N8fj` zkgR6mA+YNNj5l%Sx>%!BW|Ja4_#9(V-QDoGkV(0XJhCjW-!Xvf7=Voe4D(*X zm+VKxXht|rtHp0H?VqgKKzO{Ym$d2}{sAAKuzF|d#UG!_dHZ}Xu_L`R^gcd&hjI_c zr@b>kIlk#x+MO*(ceDR+)bl~@MQBKNb1Hi*>f7?cvP(pGGCL{x;{HmtOWHSpG%@<3 z{K_RrowtX6FZ~M=v_MB-a5s7OKK|IH+n~3^ zBh0()qcn@GuO=?RzhZ~BuPQEaSCjP^X({vGVJZB0x6hi48HTJSX8~foo67)8V8qa3kRH>SxA0mlOQ%*-4g~smAW%ECU1uF^!Tme>XO1 zimvff(0nM(V)zxLoBpbgY`jyWUV*1ZK0}x#`6aQef8{6H&#ITM{lGnKIq~x{Zq~$g5B(i?MRc7m^M!SjUK(mQ| zL&eA~pybXYpzh9HOVfqlr}@nNRe9y{p~}72UW>P2H(|V8l5#F^9I>OpUD~FpaQ2y^ z`UX-WLRgryf|}Cw=6KvKAk$G^My2kZb+9^0&Hg5K+$f;$r9P`+u;`M)`KWg+|H*tz z@0WSs+AHx|(yQR5>965s=&$f9v|IHdA(;Q6;jjIwC0OWNnWrJJ$VjE>+NV-xsB!Vc znPT(yK7sjGms&?jewmGjm?KnOWhTGi+V#(u;FU2Rv?+vpd(T zX?3<&GReta(mI8+);-mD!Z<~I(m1t$;y5*KDS8O;?t19n7=Nww4u6nusd~V)_Bh3~ zRy@TEnZYVhVEUs;iGBFb*Q=3dIipg*QckrDn{^4ER5RC@uhbkT zdWp`YBg?K@!vg1W3D2bHE#fYRXVg=9nzOYk9*1{X#H3Eg7EkFEdvxhlqNB5)t4P2; zM>CIYM>UT_KnW8&uTnOK$1U@&qjTUzMc>S~sFwMwT)@P)td{eu)Sm5^5+}A`Rp%#*+F0urnxyE zoO3QK*p++1`N#4J=?}-ncl+UzVCQ?KzcZ5h z_Z30u*EGM%=MKNlCos42Ym#5#bDm%Iv+dnDw&T>2<1e4QJL8htUzO=U1_kGT*t7Nx z$~v~Y*y4TaFwO<4TO0`&3%Ag9WdCAMpZ4arxNBP3ZQWR3Z}lx~bO|o;vp;O%oTHT=iH@ZoX{V)!_~X(6X_)0FiAqZsDTU1^ zsdIB6ilR+0X_}=diH4OZX{*&=v8&Y|Bs9&%5f2-;5jb|HLsdG?L$fXOC=NCzBs|w3GYfc7!Lk!ghcpTCX;-Xl=x(DER$Lxd9&GNNv^W+3D7U1R+;&{SvK+A>BLzC zJV#j6bBrceAN!~@OY$RG1Ab%c6j+pM9A(x_KTOSIgnfh#&II@U+NU4djl$}>u<|fa zOfPPB#THLoTu?`omzHfS@>D}ll}ObWJs%6ZA+Dbj>p48n^g; zlCE%1UG_Swa6f(lcsA`^3et?1P1n8Ma5|TP`}+5n@LjX|dXxSF`IM$Qa+tbOaF6Ke zk88TFPU;zDxaFwcct(C-FJ0j6z{bu|`Gr9D}e2_T$3H%Uad zb^o`n)E9+x(=^8hPTi9ZyLFZ&#r&RZ2@(B2U7&;{s9lOp=FG;-*rw!#FFL~FyLC#cM^F>>^Tvh=a_k^6biNumO%6sciV z=X57GJ$i&uo($kjVX1yjM4ohy8GX3dlVgxnEOcg0cBiJ6r&R>`Q}uhgOs>u(myqR5 zDM{cctV?hHMVmy1Z}ARBu?r@rsyn0ZQg~(uP(QBcWAY#0PWzK|SmSLcJgCide-&p1 z&hZ2{z3zf7nktTL0d$Sk3tumH3wHsjH2;{7OZ<%qulyYC=t;kl=EiJzMjWr?)o^va z(O6j6_F*MkE!2F-s|1x55jII<(ne@z}5S{G<}@Jmu>(Ok4XGT5EViuL_{VeLKI*mg&0w41RGRnG#uAMRQNNp zhX@n}_j%_%THm+9!+`d6c1pnG@7A%%!{1l`*O#fQshOG9_4ReX-_eX${%6V~YeYo} zO`uN*vQP|F>LPs7gZ1JYHZ7#@O%Z8zmEHl(Gg;M!vdFECT$>R@|(xGELNP* zX=xx=)RyS+wYp!p49$|q)n*DyhCrr{Z0GjRubJ0OAuR?Go7A+$<(p1*)DLhUkM|TQ&y+T_8gHyrFmGADwAozIjPP*^(yF3v+Y8Kdo$6H@YDcLa#kJbFV`~yM&Pf(?nxU_-T6Pa?TXyB=6a(T*p(Uma(>yfL-P(X*& zu<)eC6b-}lEdBJXXjrJ31$xSHii$Rpl<1~xi7Vd{OGQ3a8FD0q?WUNejRFI;0>nH? z0$ov%bVBs!7=11q`1wC1ko;J@L)9D|GjLx?pIV6Z@9syCWqV^mCRmiywb6mn#|=2#azCPfrsHd#d!xFxT|aQSvJ8B}M=U zMkrFr5X7gUjKhTT;Fv=Ep)btC=&v$!C1S13S?){n$kyj6@e75eQ`G6_5e7!Ok{y45 zDwqp5Ezu(Cl%X@2NRMN8pz=}rIYLPU3i3I4uu_JhiV6>TIN4iJ+IZ8wv55JrcBT@v zcu?sg(whSuAX8f@({K^l^f6r8v7BTlKxs$m2qA>#;dEe3F}#ARlm@E6P9YpfJx)FG z?_VzLgN;T*M>Rn?f{bTWnKM?9UoZV4!34cTYU=;IFmwQJl^?H%1$!)MqLfFl(W*&yVK-wX1C_ zlX+32OlEVswTYyx*9@GaIjMCEI`LX^?)!yHq zbGyh!mmOoy|5nyihC6_HAib7O*q)2oc*NP2A+&|c3~wwzE2K-|z~t0iRWoj=7NzD; zmJt=kv`1&BlQ`Sy5x-IC)JoI^QTY3vb_k zlU4l7PG41*G^{UQmG*A5SzR8=q1Bi;Ex*hT4p)VnO(a-bSX)c*{B`lxnN$j!1Fe|= zF1!qSSyNMYzYISGGZx(INhkl#s$oBKcvzmQ&ZZ_yi|^B}^C5nHQpn*$#W!<80(ak%b-`0U zTwYygRU0bop}eI@Wv30;q|}nF3O!&eEV${!C!%<=>Z5y0>(FL%kz@{S35Dn+&mYvZ zQOQu-g>OnEgVS6^$^j)ep26`&Z!y_IrnOQ=78W*5K^E>GDj(B}i^<~QjQ{zrkBn}7 zw%A;av%zu36wJf&BykoK-PvyG6&ZfOPB79EJ`>6~;b|#7o*fjZPK0 zc=2M4B8g%hE!4fUx(?fR&B`hd?^HOSNf)C7m@0b>)_Tvg|!w;sy0 zCeufbhJ)tCB+kP!vyWi%?#u^878TQEUu8gwpp<-up$J19(OP2KK|m2v#DqXZMs>xO zWN_KyvR>eNX#-oG;$r-=nZm&OfrUPq{(jL9ZXura5SNpHI}ifYf(rq|o*M-pM-b(X z0As8304#AYOvfc1!s&KdR;J(QkUv}10Vd-2O&a)YPq%0tM_20az&Oo=-$2jxI4`F< z^Cv#)e~pQ*1->(5KMjWE@G%?+2KqD@Xz#|TPE~O~JaOyE@@*ZC8R^+F#fvjw3`cL% z<(e6tns;hbX3{j+No+ix4caC6?VRgEK1)baCZ`mT#|LS14Gf~TNYz5EbLoH<&GW=5 znN&AVFL-n7+CMYDLv-~apAdjWl*mtReQ5m-e9#R1gQ!r$E$=*k-04MLH-MM7yFGVx z8YCxfhFXhV&+XxMm}9o=n6Gc3d_EY|;dk0$92f6$XZGRAcD)6jr9iI{5D0HuC*R>} zInuAh+t3TDkQM9Yl5>qGRLk?3A4&862S4jNw z<3U1KS3y*Cm}cur{#R{uUbwT*S~`_SVD_hGDT8xU&lRnl{*}3*>`saObF7^HFHihO zNhpfGh2gq^w_dZ|g5Neqvk0v=GUA6U5kKU9)kHgpRotv2QMJH;Mb^izA91$7#8N%b zz9X2~J2!pTZ)bE4PYak58dn0U38sjU{u+1S%+a0htHja%=Ur2rXA zwmuBB&=WlJ@NMc`Z94$Nue7v&lg!;Lui!aP+-gNEUbHW8N+&0qUJ`7(BZOk4VHwNQ zga;;x4X9YL_0QWMC}|jgnM-A=eH%;1htcDmJ~$k09slk+2HdUZWcz0VAHw%rHaz(5 zZ3usi6{P%A(AONNkfLdm^6dO30txe5;^th5`T1i_A)tzuB{E6Jt4$+m-QWSZ0mHDY z{a5Kx@36K^h$wCyd zZTvkKlb`{WBQk=pm9~7=pu+Q=Qk);!V_s&!E#G)r-Y?&QTBJt z_S&RBu-j0`)5&j{hI2Q3qW0iBm~^$khbj3RlmUy!PH~`oFe{{=8N}j=@ymnlJNX;@ z(mYbFlnxYGRok#_V0G>&UfmmCrJ4=$(;EQBC!?XxI1HkAlMF{(pgWHa&Vdd1x$_8? zkx_!qZeVC)Htd|&w$LZ;Sd1HZ7<* zI&%GSq85Ogd~eBFBVy?a#t?0eFm0%F3Vb$h7S5^K;W^vEtI2QO^Ges?eYH-Lh7OT) z>;)R#vWmx%nr1JjB7SY@#Dhg<`;xk($cZ=LT7op1Q9wGL74XpaNfWX?MPNcm?-ipI za&QX%$Aprc=nX2#^NeLBWA&)SBiC3!KHAs=PJxjYyfP9(s4g~X7aztwY$ywXEs}T- zJ8}zK!1NLaCx@5th7XC9kI(Ak^GfhG+A{%B3QT=!h=vgjYC|{xKUR`p1%lWWEjHZN z^9VHaLW6=@>Xl&74P-&{kfC8}E>&U=a2LL>q&!C zF}pZJ40=gLchKKNWG8NWZYV-7Fe{H~7#meDc`tksq+^7cFhYq(7I2EHpVY&q z6T0|bHaf32?I~@k9(O#gl@koZ+Rw(JGQf%Q;Tu{)qiABGSg?OKW|KgLt%-13L1#hd z2MMnA0X9F9%N*G2i7F_E=S;Mht?Bqg`+r)}fcrqK=AYDVm?ComD4m=8Ail>c&oqXU zb-+;zDR%Ugi4i&29_)DZi|d;;YuH)qi@uAhE0%7u_u8| z8k(@j{_TAn0sa6%1m1bV`vn&OolwDtnU8WxGP9*VfNPZl-hufy=q`gAqKKPoHkF#X zcl?AI!js!FWuSoi=w`Ziw_SChFX~`p7%X(BpPLd}l))6InkEOmHp7zTTB0%CzySSs z>N;N=PSMB!ws7nN)Q>=)U#d@HRd*TtLCnFWlaqH&C^a|8X~ta}hp2v=fpt*r!%27?1aUD@_6(cWlLLGjW<@mRj{tT-3x zqSbv-O-WKGPjy@HY#P_K&;27Jw>VTfF?$@AQ&mEqKR@&*eZ#frHQ|*(zFE>nL0~^n)+<@3KQ;AGW0uMCEX& zw1*q-6je>LN>aTGsU`L|Xt(|P825_xa+3p;i!noO?Zqu<1%%XCw~9k0?PnC4A_M$u z70Uc1C&`UM)GS(S9C^1w*=ccpNo!v5C;4CMuMBPreOYXVCPjv;Xz4luo%eA{tESFd z2*2DG^{k02dEX4#YFxF&b1N`9mJa+)VB80b8#5W)R{F3%e#C^r`N{UHr*$r^msjpV zt51jNyISSeMXAkH8g#yOFHhPSK~=a`sDGOipQzWB*WPDd{7CP7++7=>GqeNrA_JgQuT|pTIdii? zdn+NTfol6_i4Tlz;OBFfde${M{zpC82KuKCi!cl=pz8P)|-#=wEx|WicRk^ZVi#1f{_kv^XxX}i69aQxXRaOtU zVgyA(*P65)pOqC)t9OZ!La(MW8J^&us!2J$Iw{L0Ry&qlZbzb#kT1L>YnfJi3t5)o zwq!C{pyGlq#Emsa-BSqe05Ff|KhwPnyd!lpE2ah((mPTUC#dA~_ceHE^_kpKb)}V6 znB5RU{yrv^O>m+Za+I$w$kMtM=~gIV6b(^u5{hctT_C(*r*|J?T$uavH^9zVTui@+ zkFju_z&>ek@u?qXUT}1VRO-?!@e+mpl@J;BaF)F-RVn}5k0Q2H3G*ZXy#j0-2+Llq zZ|=Z|GvyMDwReMiXNkH|CjS?ar)ccTd!R|p+(twboo z>?;^vcf5T;nsj$2oFlfj@1fu(kG^yKVhCOl-?gOwa`fWQy>tDc|-`J>xTnX zg&n6N;`e-83G;q1u9oLf!AON||IGSM4r_i&?%QUt3;)!ytZ8(%gt?@7T*BRx=3Z6z z@Y^%N7hG^FfZNuw%7OTl_34_b7sD{O<~SSK7vXTf%BB|m0_vrZ2Ep^fo@06aX~H(d1_m^Cgm+*6;U6qM>cJ6%ON1nny< z4iiw=9~EmSdF#UC3d;8AFHx|e+{;`$E2ockDUZ`i(}9v2ObwjtvJ+#K7q@Dbk*m16pLj_(ADRiR&6z3# z7CqMY*OTlUBXAP0rp(9y*a-(2xfAq+UY%$33BaXVGXjRea_H432E}67#uyz!@aoj# z0i6Mpn6`~ZfFOBP+fJk5plP&fvHJC(X_RWc`qv zvM-z((jJ7+1>&L_93|_Q|EzH8d7vVRYv$t2H#w<9?VLTH|!5d(OTK!I@EZ|3} z6#sgbwp4UVJ5c-cGM_y68%F))yWw9CcP+MOp)BG<+#K;OsV)-iSth#&=QajY`bk~T zGmy#I7_&IpGopPurV`i!C#>2mDrV`Bc!xNA#G7LVSl-7<^}eGeVm#3d`R#)fogSR$ zi{vXE0U+a08kHz_m{4FN`DG~s3wQl5)Qq`!d>ZoFFJOt#%4^Fj1R`U= zT)+htlZVTZfQIET2!$JGMu=x`7#iWh#+ax$Vu=kb*A}qXl8#&j-3f>=*A{&&TVr4r zx&@yXd%W`YgjZvrzqGpF4ELW$)a$3(9xM!`yD_aVKXnO$(wlm`SKF$J?N6wDl=G6T|r>432Go z=t@FcDZACewSk6E?#1hS)&4_tjhPYR5Eh~M=#f)@k>n(C_M7Kee_~);j=gknXD=mM zn*O?lir(-12`r=?2wMnGzgm{B%5lcXi5xtpA&GYxy1zq~YCaAA@v56#4=ASmXCI`@ z2e$ZSX91O!9kC=6>tZbnOO=tl4vP4gEN1 z?cw2CKE}6Syya}aW(RsX-lMS5H8$EK=Z7)Rk5xKq*WGfH`#5s+_Ly=}-l85x@OV3= zxj5p_7!paUEuK0qi`mOlwC6wj!h0S0L|#lp-I8eM981#u2#gdQ6%42ZHL41)jQTb0 z527DTWP479$;Pp&&KANIMw}zh9pD?Tjdk6&8pb#kCx!cU7xa7~;mC0*R`^tBYhGj!y-9@;;7pF%#w}#2=u`5?s1UH z&0*W8q^!@loDvoaiUd-dig=e?%Vl7VIb(~5P@s9@AiYs?po0&d+XhAQKu54lC9zQW z)E9R4KkHVv%{Rq%VJFep5_TIptO>9v_ z@W<&x67#)9Ysnu?xMkbc137pfFh$!w^7JfxM87uz=BoBg@uv`8!2u$MV55yjr4Nia z(01Ch!62f?Ly^Y8FV~0&y5r+U&|E{Tf z6)e7w23JqS&rq0xx;;8#KDam1$5fQ&eIn@3VrcHQf3tB)NU@c3ilGAG7USp0Z#rCX z9MTy2rX1_;SAEy>ie(QMj$9@e7AnpV6tiK|j8u8o;%diL)mD0cs#4N%17D!vOx(o> zRXT;m5aMd|&rSnM2$a(2W)G`X-)V}=+5W_C>N*{qkBQDL!MQ+53$D1+FE`wTep?(wkZOi)>;Cp4TWM$D~ve5>8oA z^yF1TE3;rdjwj?7uI&iEd3bD={t+V66$my*xQBAIq;d33V3CVyL;qd@S=1b@WVPJc zU!V${F`(2u+RkR5TbReQI+?uHnFDVZ+VeO%P+Yy2{N)X*EoV<2>3GlKD2J2(je|=x zEZxcAVxLgn`5C&5`E~=@{Ex7suJE+`=ks;K7jg~(&sZ@gU`L1Wiv)#?@Puw86K?R0 zs(tdGi9q`tVR%Aok)98QXx2T%kR)Q{TpQwA#a^gt5#71xG}U8Szqd#fVfPs8p2t9k zvBV=@^#OR4C%C_^)ET4W%4z=qu#cDQF`Wz7xqM+p$6((Ui<`aACE8N7R!4~6K_@a{7_54-W?85oB>mM9pk)!bg% zd+%BBjhJmzkKCiS{2ii=czc#w`PG&z&dB=o8F+FK|7KeY1XGu`cSOL3y}Fs15KRjd zRXChFn>V>7!eSrXvn{-GjbIDK*sq%@hsRP74b>-^Lo|kVEsmp8x=vc&o3tB5nB*nn z6^qX?OG2np#cEK2>kVY1;{qd)i~c^QPqiwe|5xsyDI!5)F*;FUx9YY@I7h{`1xQU1 z?_cLKgqi?cd?OBVGmSS&__F>icIM~`#u=={c5h!Up0sAlXXkO^U|;%#yo9YWZ!gM< zbMr{-WESD*o(qk0<&|J)&O!-Sljody103f_YSWp}y5pI}60~MJmj`1!A5>d#t|2IBAGqzSIa_A;(oDcV`a7%gpP+SEc_XmG;=y}Z^p&p02$z+9L0qO4P}N_JdT4_ zmIxX_=CcZK!cX1!Imm^39uEf29QGF)L44yJETqZf2FHsx-Fx#jjJl|?I>8_tiXZs5Z2GF3lu1PU~jCI zGsZEwvh^&?%--+&C$7ykGlH?Nb^W{jqi$-@56IuAoSOL&M)B4Wj<@*pVR!NfIm0+P$2ws!bo7= z^}z&Sk4jMd@Mrso-Vk%7_>WZilDucO`J-HC|BI}z4vM4sqQ%|a-QC?5cLIEPaCevB z&Jrv*gy0@LxU?;m_QE7q0UA&u z!vGC9ktM(pbnaCFBeeJmKm)p?51;|>|1*LE&c7pq1EymcFb(Bj7Lf<<6&t|;@81%^ z0qdU_k%#Kl9+8K57l_ymb!oyY?R_isRBlSXdhf|O#a%?T7CwjaW zDzOPzf-*iUI18=yof!|4009J{HjWE&LS1}jSVJXd0d;Wx=@Amh$EoCZ4h0(SGvzSd zU_c%GGaq7*$c(MfF>jc}I3OSWP6ROsW9CTY_%>8x3t$R$7lrXmQ?Mj@92eFz2rxyt zv&MM#D5!Ir(Sr#}kLV#eb|kw)D5&$EAr0%90=U9F`y&Ry&IpPePfBg=7q}uk6Ceh$ z&ah)V3lzBe&iFzFl}GfT9(R)8iA!yr6LqC5`hmrZM9Ic@4JDWB^R0M)o zz;(-yI;6cedrRc+ujmC^O;4^XkIo9>S5R**ilSN&PLqVU>Q~m6glmaa1-yGn z(hrv_%aG-lnS6owad607&wkVqWecT0AFU` zJPMjEkD6~D<1Hp47@urxtZkZZ_EoK#ZsxB~V-SB+PR-ff*FST7;f^pKgzr?~JEzDs zTRKMn3|lzI8!+?jlYGcE7cBp=Bgj+FXo*gmUAvBNHz8JoLc+UUE0ycQ%zWnM)r57L zGgV~93F^haygF`}k)9Yz9JKu};j9TeU={g4gn*rNoG_EY+o@&L8N$g}YA&{fQQ4jdm*$pExN`1?bC(o>r1lQGbCS#noCN#e=D|!23fcyX ziK0yAP}%KCSYax;V`zO9c7FxKu@)zy0cHVP-Ielg{}m%Cu1DT z^#0mYyspH!Qrd2o%@(D=uk6H~Gz1RTS!*IoiR-#&#SIgZu- zzn6evtG0o(KKW%!t-kD2_W7M3r?b{m3iXs2`jpUlFHW!_FY6C;jRUDEPwiYpmkn$j zAn#xUe0F4p(seTDbs zo@tma|4oBWmCb6WREiTK+mH09tp8desW0#`QY0!V#yWhSkcGm4uxF7t-7PcZ)13I* z;8#4Ow`repJzJNfa+}q&W_>3~!8Gg3~S#8^f}=Q8qX zr&H83g{VOg<#UK=@4)4UUw|L_`o8|-E-wr_x0$8S+TKaOn782E0w!Q7H`#k5NT@>s z+BiSFHUI`AnC|T@Q0Ot7wl@Tpx0&GBrA;!)z1pB_-Rd+1&Zmcf1W{A-lya*%}m1|xOS z#CypSd1zkDVt~JOnx#RQgV+KbpG8avNbZ%@QXyBn0>kmW8R?^JHQ@aVSTuSIL;n(D z6}OOYkp9eiTiFX3&4fj5UcS@?tG_#ZlUxZC6iSV46<(X#3Se`(=7ovK-$6>*&w4{1 z+d86L9=kHXxi?R7?v;B3TwUtEyMNTY;wqZ-Mub$>3%|WMA8a+i5`i!+)s%a_T%S+OY|Y6AzkOfSe+!kr!6cqIpMFCSoZS zZ3)P2OmLoN(zP(J0xRe&aY<84j3TxNVeR(S*u<3tbs6Lgb^&tL3yt1wu-b#sJT4H%aj&Q~pWEci#YfIXweC+W zn}w#{K}62Ij=8fx#kClTglH*;u%-P9&{102JD*MEruRJAr;+p+?l)waBuMDIwRvy|nBnJo6 z1OT7!7MB7=&u0UfRHiBM%IK@pyOy6Y8x1T@LGxf(Sw?h%Th@n}P@?g)S7MV_K`>G= zM>b?pS^R4t$R1(skh>yPgGyRXK2&CJqFdr^U22Fapl~)xU>BsHzL?3r@Z3n^3?&L6 z9a*%CSUFk!(xOfZUUVE-!Cz%+(IlO8nFrS!H8q?=JCm&yl27I>Fx0m;ligQl3^z6@ z1y%@TC(V@IxUcd_09bcZn=K@Ca)xXj=)3-7-MeiT4lEQ%dTDwJ%x?Lyw;e#84TYowPMu9~l^_#Gy*1S?QUE<*F&RLm&BMz{Z zPCaL|{N-!#>SQ%35Zx1K&%^*@;bP&U7p*ak(&9lhVI^61voMC#fqz?GfF71X>1c#7 zsKz7cM>3}?L%H~e?}G1|+O{5fHQTABC6Rr8Dk3=HKl#yMcZ}wOa*@fcx^w5THgq;@ zEd}kd^z4HDP-<#F`g#MfMIXuXn65gFW-4#*j7+wa4j%l1QPZYbqM>cBl z@c&`@1d0*4V0*U`MR#%h2$x3?3I4eO;h%S(xR^X-=7j;7GKk1u&=7^Im?Lpmnp`L^ z8g-JaAM-nv`LO5IIm6v{Q%v~sq7AEB>mrtEf1l%daZ^3gt!RYz%3$_%%1xM|WaFQg z96Si4&Z8vSwKN0zvc#Fm?n}+pe@d7^W~7E>$nmvHsy2}Ex6pID5k&$d`3j^BoCM8y zC%AKezM;F#p)ri5ZG^JeN!dtFYQChL7$|<#SQ)Pm3N-kZf$}oqbMSa=*TpsSM>@a( zp+OyGGf2ew24J@*GXu_@0V}LfUAPM*Z zHrF&_8GV&Y11c^Snphm(BwF(y1~v>#=yITo0_6KpG_gAt*4J`#Yx?~nBXf?2Rc3Gp1+YiazRJPW!9d~mjX_Ikpo+Gjkxtt@9P%tsEE7b;9d+qZ=Y z*+yxo+>U-#e<-e>(H%1Ii15#^=<(QC&MJ#Dl`P1y^%Qs6UcgZE&<)A>Ha0GLwf(=9 zbTSKmJJJx2^a-r~b)WwaN2@mK(D=w{lmDDW=tb+9O~{t@tj^k&cB^>91J|fquAL%w zCo2H9D*YKDTK#Lmg`kC0^|~y4_$0)WOeUJprgSaMXy435XKEP^B*wRkCKSSITVZMR zNcp9jz9~CuXOaxp?r?j?#s^h>{GGU-kLpGJD^|fh--Z4!vu)Cx71wM8 zb-s;H^1fpitiP8pSqApC zHdXyrMfBwL-08o|0#x`bI26bvrC&$%S)AC%M}65cGJ3Zrmiyu}daqzFEq&^IM+xwK zzs#nlEXxhfP3bhJApA2ZiHTf7gBRe|V8A%$@QR$?%OybC1k}fTs(_{*#uffpMHq1 zt(f%lD?mT=@*@B>66C4ue1oE>7><<4=^fyvMb8Vq#_MmyqOi+>%C$fhbM3!nwbWF) zmXalh?-Bh?l6Siu=BYeSdmRX;K{^OW;TPQpdxTB+OY$pWzbC60X8&!6Q`MOxxCo%f z_jr7)bG?p+c?=B3&&%Jr#{71vc|8$>=+#!pemTA!#_iLKjya(@p?SRzg1rE?Bjp9` zd_&K}+<|`M{)o_rKm8tcKj;H`M4*@`3Kx5vGc2rv$4Gf3he=BgNu*+nmq{t$j zhFtgk@-w5n4Pe(&&TzH#Cqn zG|_05;%RUF=1k;Fx36L%-#|@*rN)=|YRx@{l7eUc9 z$}gyXp4a>>MY`|$aYs1&%bSy?1Ygtnp%OvCfRhfzKzAz$+yP_Ej1Y5^pb(r#TJT2g z>*DWoM~Ig+G!QG;8RAzV*D*01biG7yM!8SV)LYDRrl9nyG~sYsd#4#eN~i z##E7}-ZfFOlXc371PtP*V9EZXMJB{%ROwffB{$)C8n%dWV0KcE)1h#`uZiu8e#R2Z;^fIT;sF5>&>!N2Gs}YIqAKu z=oCL%Q|nYg=#qTX^&Xp5g4o>~X}E{sYgE4x&$kTza~xK39OfPnZs={^3*=Z^?-iR% z`?}^~a70m#h%H?A;sI+(nvM@oVQgU!%Lv&RA-tt$ea=&TtAjy4eT4wfeVb*l@ zIw)j>fNejVHdU1Q3`E`xZLktgF(`Rfkr@BtrvaN>4tWtPlV#+D{>g~G9C5BSc=Rvt zDRmwA-vZr|^)L-J=Z&@Yf89u-73QfB^L>!GbZ8zmZ2^ma_76l=B;JSo z3w+roB;k}rPv$q(r$95E{|DMHo&TPNB%K+99NUc@S&K&K&l5hgup^!G$%%wSXebxZ zm+GOxGZJc}Rv4+-?SZve`>irjboSF>8swR=w{ z%CFDae{IV9+eF$tV{G?Bgm5wbik}|f7^8&jg(-)$AfqS2PhA0U{*Fj|cMN_7iKrDK zMFfUZl*?Gyimd_@xEXOme5fI-vJnjN`0ktTs+Ug%7Ly#{%qWm(HV%ru0k=*EOyw_4 zLW+8Z`jQwq)+>9q^)oqF6J|oDOVHSV%>I`CRo+9E)wyJN*IF;eb8(#*p&Iwjs3(>5}{SD(E`IMp8*AGAZ=1!d;!c?P$2Od~XL*{80ld5Nl z6y(zo!v)MyOz38rxBtuw^I0QFX#QI)GRoeOPb&!SG2WOfx^UF%%Wv!)_{C_IxG8be zBE@Oclz@1Wc`k`eOiexranb2LuZUq^l@&${Fefr>+DUo*36w~A%mAVpoMD103$&xk zHL>-cLIK^M5Ap*&xG}{v5=-HM^iHD?<}nt@ePp-!SeJd# zWg?pVXAH^Shr{nE&DXjXhgo*C3rZR$RrRrWFZw=&B8*pA`syg=}wZx-1XSBaX<$*I# zPPzco+iL!d!9~G%k}?lBHU7Tuk(&{{MGyORC*6-Z{tO>d)4TbnZ%=~HQtxpRSs%5S zd(O{DLo*62(v&rHCo9T%66)DyNqXuFNxD;Wj7*uQ!eab!wLwSzAxF(~j<7 z4s?Qk-Xxk-bd?h_Q=SfuQ3SQz)R>e7)=g^$&yA-`{`>a3bXu?T74wBJ)eZ>lCyy_ zlB2I*C0AaxBo|)ud%&;Sk}_G(2K}Y^tSSF)<$eYyAD7k<2K^f!^m;?#mgzNQ`&)+{ z_b*|W=1s&sHaNmhs#nu#&K2ABgnife4Fl2;T>hxqtM^*8#d&{XRGhU*QhJIhKXfcw z#P+sR;q{hWG4;Hs+5OL0Gy7RvbKtJLSpIZc?%;S@;oyW*4*!HxVRGIy?q^*uMe~;s zR)_3&pLxi0fac`$ize&84bAd1O8MN<5FGFHcl&vSx44RcJ8{j2GgCS7vJmoSg%1IT zx_8TY&S#BU{Wro)g{`C0+K=f4m5(`o^^b9WfU74y@q~^GQ!RY-&Tn4TrFQwWGnj#k zRja`^7e2Nn*y!QrNkuPlXS()0UM=G*68l=rc=g)4_^Db~^tv<7;ws19Sy~bBF|jjo zP>}*rP_Y83!K`-t`|MmiV0Hn#eN1Ahe>V!gKGsgqoFz?|on0ceEWY9f%Wb);0)rPu zVuJ@p;@;;+lHU8Xc6H-nT3zrua1%~0@hqbQ+PLS$$C$h|1Z+CXNjx{k<2@cAV3>z? zF!v>DyyeCc3I3&;eEN&|z)|po{^9#fg-?jZeA@$QGxxeag=d<(w5nh+vrYXh8SjKX zG4HrOKJS`7`JCM^oW_2AQqOjG!wDU5Hg_wD?a;c*FWlQ|cb5rNFg$la0;**XH%H>r zTpQgX<=)LQ+TQnN4)8*QWrCwcl7Il1!tyI&K()KfIm#Y*SqD7XaF$?X!O8Cu*FD=N zes8l^yBrhWX-Ua_85cCyCV5Y8>3AMo%%4b#2}bAf8ARu&NHlU1!#U!mNa~zf#`kT2 z{I^~Mo^x*{ogNam6QgXM^JBi01dqE@64wn~2%5CEK{6H={MJs*yKE1LuZ&U?HWs^X71#eM9R!+pY)`F+xrD+Z9# z86$q08*%t3dtlEthjurKUjZzbRlJuo=?<~YQ5ep5JOrCM9}b&35)8U>mk+i6l!Itw z4?(7XHts%T(?deCtdaYFrD8cxsSw#uX^aREGE4{%(ogUcGV=XQM`oR%NB;a#j621h zq|)|ROk#(mk;6RBAb-X|fUe6zfT7E!R&m)mFYCJDn^ynT;V5!Qwj++^WOHop#2juC z&$RlvYpn{IMP823dKZ=Z?{DV2Ubnl0Lx=RS61U$6MQ+CiJ7O!ErT zn>d=}`^9{d+10%T4;mjH4rWf|;7D@2D!s0Eu|qU&?*~IBI#X~aJ5#kLUQ!UU9vIOD zS{c;1jZ(|9MN^a~bCo9cn8*WKGj;xJu+V%>`1Q zXx<)_98Kt@nDCiu_^$=ho`~OGlw3{trUdhCX)I1+rbIoNd)VFOS5_EL@|G}cOyZN;lQ&P!qUFHyx8 z*B+CrOS3NW9g8i}7|Skl9rK^%Jka9iIxyrGvQ8z+^XMc>z9}Kfz9}P0zsV-by-6KW zx3*Aqh$qVV$pS970mfE}%bGa2a?^VQnH1Uaw6$4>n&uHSvpVEeHN-XW%1xM*wd(Ln zD+Ry*na>&OnhzLy{nY;mpVt`Vu9O5uRffdL*_Tx)ddB{4Dvso=$D?dSx1TdZilpdgar2 zq<_bUnolGexVz=QX7*@(&F_(4{}J5LCj3U@uJUYIME{2G9`KB~n;6gJZX2zzo<6Iz zJ|0Q%I686)xf90_{ni^3^yKzm`|q@LM+bv;7jI5hK`L{@jj=I!m~kpaG!>5`qz)u` zBXOvXnmi~=B(Px+G#I<7+5}2mm!Z#(71ay|BwHofM^{DJXBE!8C>2_{2o-9ti_+&6 zP7Eh%pa6aDaKrkv(24Xy7&?gx zZhYa$OgWawp}5G0hMG{fNQXuop{YpfEk)4k)cR)a(CYL;li#8B72P`UQR{(b+#q6I zvc7CMTWmIJePy>6YiKrFp_uKj;ao;gN7%nK+`{lNuZhA@kvVAms?(wB!?!KM({*Y3 zSi&X3RjTPiRggJo_0_J0!iRCIsr6Or6V1dy2XGqoDbNB~PV-QF)OO$`ElSv~zdY-9TbIj?knjM)VoV@vV` zyNL9NV?!n9CI+ew^&&N0O4%hNTSB`9} zidT%RuVFX#hP9fUS1UjItT@gF>uiuNb~8wX)*27lEB#yS zZr0g=#RlMJ<}s`zcF~7o)7o#TyFyt?gE;IUCvW+?SlN6-ZLA=M*&|*0B2Kzh*kfq+ zq5GANi^d)9zWl6uE;tShSZFPRWKE>6NJX<}ZPbbh7@#rI(M@pDzZGt zqgHg@Eq$V&Na}L+^0bo5*L>mS zxMC68+52kKTBC8l|HhK+%QC-w4L`y@3RE_gIzeR)!Y*CXezpkD#5&Rn&rI$Zj}3t@ zt>YVY#5r1_a3l4wVI=%_6J_H8vdbgo#44n6e*FWSaT3X0lZ&nplQ&KFcqEUkqW)%{s4 zy>2Cq>fLb9iT=?fC?Zvl?-gdob_}O!Psv5>6@iCft5va{6u!^Kzl{u%m?6}HW6Grt zr^bW-3=-yo8^De)=yRllwyx5$JExQ%0G0z zn+Z&a`zz_Y9W$C+7nTqH@_@U=noy_@?Z2?(YR3Z6oZ;Q2FIFD2)$kv)gLn&j;g%vP za079lRo&E&`D+%A1sb+_9Pyvk9O*^W&t&g@Euwhk>heCTpV4{cEsh?GYX%C3<6`ld z+1cAju+a?UdAX(lt-~Yev8SNCv4w|#7cJGLXo2n1omt#I-6Vrp+uoG+7 zyw2HIjQvIdxQfCq^c$eQmd|9vcAPhUHPQ?KM&w9zb1= zf)TyWqT~!UESre`3#VPzO=bTph&wp|en}QX7ePXBgy=|qVaEb_(@7^eDV=(nqBQ90Ken8@ zHN$PuKK6K%JsFBQSo|9(Iu!XZObFC8oLEo0Stq0f3 z@Q4m_MGjWD4hWaTdQINefD6fRzvbk)e*1L)do>p?BCKlZ7QeRtmg*Bap=VZyZU zq^e{P$-xaw24EXH^HkqgY|kRRa25bM16+f88eoQwsoFtSQ?{*|9#|CXX7mqeQH>zm zpo?B4H1_BC%doiYAg*fYP?Qih0og9yE(31l_N&8SrEDp-Dq|L)9v3ua#suud^2P&j z5+Ux^F7n83RF?uf=5`Vv3TSDrlv28p?irS2%uMwYfxNM&3S4n!A@zuZus{+;H!Kjy zYjax$NTiHtCJ_(Zfl~;blM=&ON7&We*2hXhaE%noDFKJN(@>zcMEa2}WA8%Dbbv_= zmB?_ONa~StkwSzS*t=p}euGbGqOsdn`s%=PEFCH%5&S@Oi)CjCS+uoDMqqjB7i^G4 zIIr0Pb)FL5xsWS02lem&SR#y%Xa}taBaM&v2R&o^OXK_~G;hsMXiT8S31CuCYgj_W z!sUyN#<^*Pq3b3{uE)^!5F+l?Qd@8VMk;vDyd0|@MfNZ5a{{22J_j z>?GqdUkt+6r*RH~Gw2=~t*+CEie}{VmCa>HoY06$XZ|$snAvfwLyr$g!Gn=$@#{^{ zbj-5Ns$onJBJjDazw2^|oYrdBhd-!`GjATtg($AMrIDFpn50fM17_XWvHTatfo53PXK_ zMKkUj;r0RLz&o;SQtR*8g;ztG-m8o4TWXNa-ie0#luNk4MO-#)QQUJ}@r9ECIL-^H z_P2S`Ilj=F1p3-1wT>k4CQ(g2H789}+$rr)w8S2gi)dX!efo!n#N$qb`q5}}Ea}iw zPWsw-)7Mj<$R?T&bvBoUor1C?(YGX8=+hc(L+FA*5ZDHDH9?1jg3#G4<6X=a%=}=- zvv)~1^LI%l3eKTx8p%nj?!`mPohyUBovnOuWEI(lkggWlek|F=v#ipmcMfKDoue}*%(q*ZR7Css zxK=i8UNeOTGWG^&#Y91EwjUHt-23B>Fox{KqlU9_Vb0ysEzPQ{i=}^C+!hby*xAkR zOcrI~+L3Pl`%@`8Q^qAs4E@YnB}E@#76;dym|m7NtJ+GwkOqz~Ivb_=2lE zyJpmw9F{oxvpD6VX(;ugNsW4qn$NTdp2Yy8lu)?|$zYhKLaLq!Kp+0;2*9aev8CJo zu+FNLcOwhm!=9(Akoyu-usIjan0G+Hv5vd%UJA`ig8k{7%GbkyV!fsel&DLZzgx(j z(V?K%q%u!6>Fy2v^hOyh3srA6gsu%6L4UY!_OP`spG^!A0r4W`o!Fm6F83Jy2tY7W zm=}hdPM7$VtDp|IYvDo3m4Nkyst0RVdXRARM}Rm9bW_;a>MS?lr3m03^q~U_szNeR zyZ%&m#9qrphZDrOG?WN7#Nlf(S*=`oDOjSx(~n__Pv zP!sL0)x2PBKttp0iqV zX@Ws>hXAK7z2&)Qo=6*@DRpg-HDCs#$XaM-je?&LB1(`Ox!Iial;$h~6AHUTeQP(4<#G}jQzrmbcMBwCZ?O+OjO#qXidRKAtIn(_o? z8IguWIYQAm#r7m08^!iC>VY2w-a%l=Rn`MW(hpVi=cw&ExRBz1=$4A}A4u;QAiiBm zyYaAO$oU5`#5C2omZa3NWphAx=&lUOQ~oj#$?qI}M5ciR5P$)DNMj z)bheeWO|`U{jN~hC3aym;MIR0bbmBOQJk>u9-8E05Co9+jVWQiEyO7Bztn1=NAlI9 zFqJ*Ia+QJH^i1wYD?Gc((IaTS?ZjODritM*OD7-VbI@08{D_(PA&-u3Z{@076GAh@ zcmD6syut5K1yq+z+okT*gZ=77!sJQaII8<1kt|H=^zJUp|y|P zHqEkHzpx~2t1NB+P41g&0A$oqkfzx+&lig6o*|JDH3|??7$V?>AgLfI_NZ`jDJ0=Y z)2%KvROSf{LXjj5Sjwb`>i_xSkJll%d8T=t2MjvU?4W*MEsmFcO;9Loecbvy)ciIz zz+CXOIlwIc1{w&Fel3m>q{;TXBvAK~vS zBI+N2ke%JTi4BAOgb-jGDBiiiI5(T4;VXlFFy~mbC`7^W%+;M-71vGVxJazWxyC3P z0;T;(8BeC{G*G<#ofYbNEr77&{yE(k2z(FmpDuzPkuwz7CCzyAi(#sP;_WCc%A~)- z(giy^ZH}Tn^-^3T#eTGrBoyyvk@~P_bCLlb&GWY=XziKH9J`r_Dkpl z&{>|hU!$|{`*O(0_vIivxx2honJc$FdR9P>j#|m@>-*M(2_#oVZ7LTkQJORc&5owu zXv@|!8OM&JQ+FaAs6ktPc@^w{Pti`Nm=Z93UDWfE8-(>c0h)_r=RtdYMDLB@| zrElcNf)i6FW*@UN)7fLW>v@0FVDqcDSc(N(M*H@Snl++%Ih~>h-FQ<{Hjz$6m&XVl(n9`!ll2%T+Ht zKLXGtS{J|RP<+VauNLLn3?Ubk?OsZoWq0HFS^TT;X}$~I10^v`5j7#@)QE1)t-87r zri*ojVPi#4E49ihLqmNIXW3%x*a9=47Y+8WgTaEk*Lzc9`5I~!f`Fq`vxoAjo%8%$ zn3?c7gSFRij05R@JfCuq+Op%*PN|nSV?PC=9evMn1Xgxt+N>JoCNPhU^Fen!^QnA$ zToNg{^49TOZ`$#q3OMJc28egsiq56h=sj2c7HDm|;@UOcvXxd_4BpOhQ>Wz4QxSwb z8Z#I(<#L)zm{NU$$+XIp&Xm6{lQWMqgL8$m@FC<}iw_V;J#~VAdQdM+(-Use-@tm3 zK;5a_W7ADy`ns2y{pkP0`N!3Nb?KbOg8dw^k0PA`Ic7)Ff#Q+PK-U81ej&rnC#RMt z!BI>{myG=Rb(l`#U893fp`QjjESCspT*yVsjp#mMmhae7k1v2O{?X+RV;Az^x1k&< zVZH|t1Mo3ebbrHwHAJdM($WahiSnwSDq*wE;CkF5QxN_LK+?gwD&QqBfgKz3S$#Ao zm9*GXaDL57plpS3kV=~GF*?7dCFHk2cm;wN!P6^`-=2Ct=_fnii-O*sQ{q*rh%$o$ z{k;uX{WDCDz>%IeeB z->HvepPu|zJSS-aIdJ@@v~)Gc%GbgLw4Dws$3ID5Go6;HIb}YTkw?Z=Ddd6M^Z*;HM?Yyap;xP=rsSxGUJpg|8H>0661KMR5Z#O(}|1~8S&OR z$?A3HY|yoKZcI}6NcxZQbRYA2Y_1*NC$IP5SS!zKIEmfBod!5t zs0WX_u{2UvQt5w6n`Yg@yzud-OOPGSm6S=_aqXVm1qpEe>BVPifuNC2H$m7)Gnd=u z!Hv#eZT5r(-ai~fZu`i8UnNQMdLB0DNF?Pbmqwk_&>6KzuRPGu#Y(3HF(Xqe-Tx4e zq*GdL%4|}iS7NzHDG9o*37-DeyVWb%Wx8=Rc?3b?aM zP4cHE7Vr4kdp|`9{)YZ{saS%HEva^BS)Jqb?8K%0Sj1%=vkqJ#iC9vnfR`EPVrJbF zH&pOXD%bXhU$KyWml7GxCL0EROzglA_O7CPnvfwGZK7OBavb=8v*MP(IKe2n9xtIh zz4gf{h~sDI0`%;~t2>QJ+$^2AZ)$R5X58gWa(M-`#=`JAUoP|3!>+XIQubwk4);%x z_Ig6oiygx)+aw?0wr)c1+4<_SSr#c_#uLzxcIMPmWjc*tgkZD$31i6fPEsFa#b#55b46VrpvBx->+J}-sRxr2J3muQldQ-NfM{YhH#&7KIb4x)^;_2 zFh877%5JqEn@)X~|8URXo7!fjBUEVfc8@nAWNh5-gqVL$yYvkk*x_vNh zJlXy(Sl^F8aHmc!Rt2aMYa{Df1n*AlE*y>H;jThpgk2LWAZt{8^?j{jKJQq{tE3@U z|Fk+_3qHwdJw06yOAluQcsZyei&?}t8^>Ay=s*yFyMz@4be!!42N`rE9xL1pGf8vw z`xPj!_fwZC}eq6Z|4{cjQF>ZzuQz0AA{+)hIRWaN;+!T43*}rJBDoB&8 zP;AA%BY%h3dA&f00(%d48&p+*!w{xctX7^;E{bXU>_>r1zOc4jQZ+h;+0#+B4S=e7 zu(Viu`W#R+_GHj_5N+4Rg25egj&IL^ZHnO#%QN^q>@D+9dk}B;`fWh|IKo%?J9%k&D z{u)up;9uxnOPDz&NI4rB9akY9Evp#VODn$m`jJ&6y6Kw8euw*S|DLOXd)8y3kaVC1 z8GSHSBDNxCQi#Ql?JnW2-mYMz7vzfV4e+Y;D%bjMb0QSRT=Gb%`=;`WNJmUVV?je5 zFZJCo#kvqnGmA+YPYzc7dxIB@J55-7Nr@0DJlx+w+>%(vEG1>G)U>onOJs%=9925{ z5iAYmhFz~+v|ZIAK6e6l0e6i5oq&dF9eWG(ko`8essx|Gf|Cv$^QuBo(LtVIreDz4 z$!!a*0L;^IHKbALiGiB5!tF~-FsjaQ{sEt5VFRD(2^;5s*vV2Uh}ri`Yr|-(AeUv} zsIt?KU}_l7uuibjXXz<()ulCA$T=3F&t}*un0YXtgkGh>HL4)nWTs42UrBq>*HUqH zrg>Qwin`;^Mo9d#sw8yhZ@HTM?Ff_@Y?d|M6>(a|%$HCK!K;ng?0beDl(N8br)?pc z=vN!W+O>J+Pb)PabaRpn*P)Ho9JI4Q<0c?Y9JsmIC%|)wO0<1*9)#QVfjL1Rr6XX# z^~KUYUivSi3|rAdv8?fw!veuwkULfCy9^I1Dj3&Fh)!`<_3%#~W&CKM1#}o)j1@I% z9B^nb=*|&YMFqJ;gl^m*>T8S@y>2?Aep4FN0yW^bO!$8>aFrOy8Eo`tZCm~pun?*+ ztC)Ri0s(AH+?_96E72MSsP-o#1Jl zY3ym-uYCDkBY#x}#|K%f*Fb-(;8G}Y=p^a%htj&j3V*?M>xRpzj&fW+2{h#R#Yo*- z-%y|i03Twz?@nMd?y(g^6z>~Ro-jwDUxUKokg<^ctN)kcP~qI^AwO5`qh3DHhk2_a zi&XEEvK44xG#nc3azV(AMf(3fz-92#OV*>DW#f41BQNsOD|##bIQ{Ye8h9g$(32wB zwv`X3%S%7vt(Z7RdiUR`Wc5epBc@IUV3dXiY%0rD;!AWx&Nft$V7-%q-!GMce>f!v zEUK0PM^Nv9en89^8z`7Dqtg(_A>}x-+j)$*`r}sReatcn*2fjqcxM{6=mfkg*{?Nx zVUdV3{SnkVpcy3tVv+wc0`e5nid7B_^ujo(FF-5}D300HD2~59>TZ$u#r3@}1E9ku z5M>S{7Iv{`WDJ}sppDb0Z$YOXnf`Ddl-1A=?OApsxg^*LkXdszBsNPPuP@OUV?P^; zglEI02(2^sST_uJKe6+P&+_W_CqC`fPkZWuSAK5datTf{PSsKe|N7NJA6eNb_Q z`8-wtqCZq<23XN-NN30w@N$^e-Gxh1FH&_;H?$Lv*fy_7jqh;1p!h8_flwkK(_e%J zFIw)bwpgNY+O3KHFBU}HWR@`k;ibus?=6}{iVd^N&S=pX=;Ub$5k(<9cNzi|{-k)U zj_99TP%8DmsUQBfirtOOL<~)ppRoUgD7UKJ+$Vg^vu13}vSu#9T!oW^T!n?UJk>SL zD?~I+!k=jW#J5j8eFFXy0o<~7sNCD;|F?G!;#e>@#Ote9Q|aPV0bgPl21zWODU9|O z#ta@mda-snGuRFjP@g7Q;=i4;9af^c>$Y$$juC?XbJ0{?BG~gk$K`6;W9DQ|!T+IT zNH)L<5C5*6sQp3DrJ;}2CX5(~qU@2q!W@-c6?&jnZmw8Sfaj=w?3$j9F}|v=-e(VEWFx{M z_@a}0yGpnn_oo2i%)!EyfLBC3dgli^IPs4p1L7C?x$_5>sF0YRzu>P)GM?3nGi%%Z;e=a@(# ztKq+ZN(`qL@OW9ZWJv7^ZF6U?3~6pE=6vW#^trRFlst47PhH|1MekaM)fdE?gURc< z7E2{Gk-C97b=l>o?3dY^h>t83d*O27`ITt}2c|%kx2T`hCh|}miA`7qHa4zG^q33Uo zMyNQ+pfE`=8!zhrq3o@q8ts~OZJ?oXcWB(*-3g7mYeVDiu8q5UUk8+V7so#5{J z^Nqd!wZ^+n_I?lUB+r;h4rXdzvuf6pDju~Yt$v!$aYK6LTZ(sCZOs5Odl%JAt~BJ4ZuELv;4yuNwj4k0l4{i5t8))eey%KgFe=WT7T( z$PT*8Z1~JsAIw7#Y#AvEi%i!5`d1MFMT$`&2xGrz42mQ**R- zOP|RM?)yv+tP5@h+slQ9?6oa;Q-L-TQQ&cxaYrsL1gqj97TPJuRmsan3K z*8`49)VsZ}&mUiZkY}$8`)$nLtrwlVHIKG8t@8mlE*#zYZnBRbhA$qH#Tqn*K7`jw zjL(o4-tVotV_U_^orKR0KkMXr=U1jF@F@T02`d3V$+7#% z<;~#NrPR(%?pty1pn11Bl0%jmHtAgh+AhrwCA#JRHg|JbkR6(H%l}$={}h=Ws=q&E zw{vm*fh>URckJ;fb9Q4VfIM`^|Ee(6C*(=^uEzHi`(;E)JTj7$fhs~xUX}BC*Q!8q z($J;`B*YxqQtQj~=LHvY;eLQ!#t&kMvjE-0FF%pn4-FF(C8gSPf6Oz!@uL83R0GMn zW@f~?CVS}gjDt7$Q^}u-KI5PrxId08uDv`!XkH4l8hV?;%v`w?p`Ahw4Kc z?rKSitifVq@N0*x?+?Zgo#T!w=T7Yt-liFcmGU+DrM%8+0JL6c3=k>HnSl3%*LlX} zu>8b6xVkSHh_voZ0K5@E(WB`09G=PsPIWrJSL~bF33APFTo)j3e#sWtz6dU@xo?lT z$SWn3H_J?ddX{R_|WK)`z5kf{AsOo9Hy|KE?Jc zEWc@m7CyX4p{_}aE4)(|4=1Lb{90D#WEnU*B&L?=^+3zCQ%Y~T$)J(0r?3@)Jcyf` zna*pgyjIBvkGhm^8znak@kBCD@6jn&Z}<$L7cT9*lSbt;FU-yEnK$WRtt$H89M@J= zkH1=DE;h|OS7yEzRr8l(6hwP}h$DY~#AepTQ*&y_w1`|FA7m7{K^1%4s-yOSvm0cd zfn_3Cy(^gaa$R_wqx@u%+_D?X!fB>lc-@cBqAwy#xBs z19oTrGlAt&O}XBMYP+x8*|SU23Du^OhmrPS*a zx~IFQ*Jp8Gf&~4|(VD*N6TT-GF<&31?wHXUqP-;+iuTu1S0>UjZMrXXR;;!IzTCD|?3nv=L$ZE*Vej56uwq3Tp5a}K@ zKjaS8oPGD0W0HuZLOzYmAX`P zOJk#m_17X=ZA$8b{T=agtk*wr+q53GP}c()Jc;-tT6)ym?s247b7KKHaT*Gv6(xHM zbJv#b9iHMp1n6qA6E&uGshNh$u=nR>9FI+S?jkZ*NJ@SrtMKj5Th(8MwKYUlF=}k=`JlDQ@XJZaJhkg^@+Nlet3oC)}bxHXv50OL-C4R-&AiS{=;$|wh74izg6txVK z1+sd}$V$=f4C`dIL$^emdN={QYsg!vLzU^0yw$v^;c_#R1*iIB53Rd^$(Q_7Pbt?< z`t~0)>2AZ-8YWBf-`+S5Po}wyF`rlV7!Db;-fXgbS|;CPCf^yGJrzJ31y0>HP8Z2G zM2BlH&gaN=OTM3#r=_8t?_-rji88$51Yo{@{Lb~0>xxs;A1$xBr1Si{hfe^Cvwl|R zBuJ6l94RKNKk{03#_;+e&WOniBIJC6eP+AGKCGGE%^e+ca{mv1JLdLsRcVYCf>#!p0IDb2 zl6q;$2;po9>v>2 zb#V#$ikqyG8w>ii(UVe4)#|WLb~M{$rSg2`&%nbws{zll;$#^6aG2xLO3s|&EktnM zvLfim{IT%KaoU~p`150vzi+2zH>YY_{Al!3u#Mc~r|Pgh6#>YW6OT4F6Sx&R@Po%8 zKjs-hlHpCCH|RC(eCps++n?J1)b6J~$6U5P^*QeHIqq^G8SJth7Vokj7JpS!dw}p( z<`U={`UC0={OmvRCz0j(y>DT(6Vpj^iK(%MjB(L`zj(%kZ*89JbH;Dkv zxQ=5G4)}&_cld@vw&=NTo|^M4{reu-m+fPaS7FwZ<6qzFl)hcm&;0d5kO)N-DE*8{ zKiF?`{u7frL)^MjKg)fdW*~Ha;SDb6;Y|KibU}|Rm4v?yuY~^@V+_P9!l%~1K{cm; zi)Ow}=Y;3YAZy|bCF|i#{Z#Cya>$yRf06aLGD-Zh$y=EsZOR$26nZFoqgQ&-D!*@# zJu_=tnSyJ|NwyTKnD;%`c+sl5ZxBB-t7^%qdS71MUp6;>AlH1FTxU356PWlIJNUpH z{h-VI(AWxwV8YDR>@O;nVM#^Tm3QVDDQcDRmzgXIlCkGmE-DIUOd>#alEVo}YQ z3*(#abGz<^W8fHAsy}0(uB|ifsbk_8N@|8)2oS*u_nh^QN#PiE>I|ci?jSJAscm3i zJ@tyQrA>BNhS7=7nbaB0ne`Uw5aUqwko_=g`e?d6mo3)~U?zIuKN&C?GU-1VJQ+9{ z%J^#oUJphOQV*dM83+l)03rat0U>~BKsZk!XAWmXXNFtwL*7Hr!>@;d)6vtRxf!|0 z04@NLzpcL@+&Y{O0ub?;`}VVh+;mB<0-yzu<1YyBgY?XQ3w0Pdotn!8(Dy(8)djZ> z>x1~rdy9COG2N2eo@)ni18n+t!TTTsp`QhvnQp%v3Lb_|zfH&HLgx|zg#3L!8S;kk z%ySEWm^xjPs}Jb*Ck*g~7eILXtgZJfa7%p)eaLbcJDrm&1n~2JhkHYO=DS5c%$e@a z^#jBLKA_*ApP6ojmZ-l(2dLQ(_R{j+Tcc+f34UV|5|ZOk8$d4wr#MG`8`0* z4GYoLzd^GWZxTIV!8seJGUcYw0Gl@wy5fu;#x&c5Y7i;#3#Pdr5N0sO9|qI>r!UN) zf&Q1Zh+693)4IUh%m_DFNJAd?u#(c;je{hUI0WItn#(s=R@Q5{qrj4iIC|&VLBg zyxJFIaN)UyY8@L&*n97JiE5n_O4NJr1%`I|E0nlb@QRrHuLv?Az~|gwvX)5z1NOcN znyeSegB$I%7Mi>_#$6Kav=o}6H^xH~?UV{xHsEb1PpWp4pBwf*G?c3M{ThtouLH7D zz}v2fbnOSfEG*$MCOf>vPM)-+3bMMW_HbWv9M;t@ioyYYW7wl`!p5M+)=&nL36Cwb z*{wVoNg2;ev{@AaZ&(W&WCKypkWgk4hBFaa$*Fs0%0iGQG5Tyh;b>4}CNvvK)z-GG zB%Oya`e#ea*`Ql*WJ^))^}gS6iN z(Ure_nQ@$V!c>K+o~7us2ZX0Vx2(u+qARmsvg4ZXypX*_S7yHC#JS#2 zQx)n7Ji;C&6TSyEwnGb(oNbdRN_u&qV9ah1ehqGng%%|_JIPa&eDPq$m^~5r26qI8 z945*;49Jf|y3eI91n|?t9VsG5iSn)i3gTjJx2OvX1o+{OG%qM^k&hTA!$}A(GBIXh zCr3!K4m-#S6SGuAc?Wnn3gr-ylhH6o-$3gmS)feZS*S@b zQQ$NWU14Na0|401LsdAI=>!1&;bAJQ$h-jnSK5dRt+F0MoU@#MN^)^y2Rj!yIY@Hx zT)-chf)e6v9T*Xh)Is%ewoZ)5N9dE7BtD~Utc9yt6{63TH}7$R7rF$q*jZMh&-G3= zl5X5YFh}wrU|iR^F3~Jk7QQHO?8!jVjgKqjRu2RqS>Ij5nC+Yl1pueocnV*#VuNmf zImt*0ISAs-22NIyysbTHN_IQj!XGV74goxepTs1Q`En4BP(dmr0>|FGg+rOEfak=U z^tksOZ_dJQo*eiiqDc_oIrSzuj?k?OXVx#1Dfm_hG)6Ke%wUWTiiwlUstK_s0Zqm+ z?07R6NAl<+FQaGK1z9_QGDtF-cd60xXRSXQxC^(Rl!8&1uYMP=?5D+ZD9G(WF9P>SU#i0xi#` za{y1#OLHsyt=r>|_BUbk)bQ?d9E3k*Cm#KyA4Di+5=+b_L=bihu(~D3BN?7E4QJ1e zZA;~_XuE1kKN*t!ZkIA*jXEwtcy5(#{Hp^UGNdyjICL)-h>pd)c}SlMJkqx_`R zmf*J{sze;|8=aAuC+Y!sOVY`Rqm zvDB-+M<2dEI9Q`6^6z_$J~%j{i(iu@giCw`^WwD)t=m-QSn3&~{ zAYC$-xK9!Gc^9lPCL;bMUGU@OC-{U*(*}$exm!%X zw-VK8Ee8l%z1m#byyC*oyyy3DR>ROIx73l>hNG)TiS#1+3)&v2hffc2;eob={It}G zHYrbhUM1%Zae_znztXY-Lfp23DvA2rVo8NDIZP|HGU2>@!e;rc9Meuv1%Im4{!PML z-MN`3OA#g$+qhx+=ZYtJwuo8&T=8VkU|>A|Zp8zve>yq+_ma<2-BiI>!+2+emHKN7 zH5<^lg117u7rHE5q<&Px4wYBz&q*U$l|s?x|5?|2eVx0C>7BsmN=g4&ksy!Fb?|Cg zX!NSR9llUAYbLZ4ER%l(G~~!C!)8S6Ouo-jd)5IL1Le?DeXLYEc7fyKC`Ol) zpkd-HFZ-;1zx=J$dq=AMib0_2US6iT=nPd%Elv0|!bE3-!++S=^ZO8=y9NNm3^K0A zi&vgl@Rwi|JOUBr59W1-#hBfW5P0r_U2^fHC1?mLq|S&KBSE!qJ8AQA>b?c;I!`7p zQBbHv$K06aAu)3zRWt)OV>>@hM?ZECJa*E&*En=!nOT>e^knc?>(3{OiE3pem{?+B zUBfWAlf;^zm?&2U87@AAxEhM{ZB6%ZP%N$cxQ_vnd z1rT^m-drKw_|5F?L$4G$)fYSf4yiUIEoCMbdxyG}`JU*+>9DQca` z1uH*luH4jK1!7ES)96z@EFnCP4LXv7``BZrl1{M6$KX$!`Tgtsq${&^hg=2b?$yWD zQ==olzR8rQE^D(8jIEiE{MMeQtF_iTYUV0L*KV{dIho(@SV+JDVSImjnC8}HxzzX- zD&~Vjyy#hr*R?C)9_L;PO;vUUu83{f?=ymWzpojl5PaQufn796)qh8qe}R(sRd=GJ ze_58bDbgujqqX)P?c%~P!1A}HDRvvc>Rpk+IN?is+WSb!HHU_PWJu&=*fnZ*gYOLF z7}B)?ppZ2R!@^AJ1&s!tV~!;KBAr6?iTQ=^`Fzip1l!l^@fOz>T@GFDobCi7`hm`Ag@9a)#!_PP^qx$r4s)$S$;eST31D+Dz0L-dYd=>)(Df!{N(1zD#-xw zvMissAvt^pes)|L{A-6{AlguXn6rgY@!CW%35p_z=twQEM1y6Mbu!rqckwBGBcgYd zj=uh=Wo(()$%G?AcLU(Ufv;M9zvBen)g61||8XqH_~?#o#f0=X>Z_V4C#Qb3AU{*FWj$uDm@T0da`Vm>r<;A*#G1O>Ym9HBqSJE+`s3A zxP^(e@qhCo`M-E!idx&9FoxE zv08?QZ`ye}Tx_Lk0^lvS;u~C#cq^(i;gvhWkz2AzUN2^`8`0kXts5&0Bm0e%*)CO1 z<2g^nKf6<`AmaeLSh)1(Vv#U^jaY#xXZc|LiDvXMhRt~=!wTabGI+}$6jL*2xAkhx zlN9IQ5E8Gq3`^y>W3xqS6`C%~=Gv}-rgf5T6>XNh8kyw@LL}}Z)obW5`ptMLd}JuH zMH()*q}3!rg5Y8-xnxn2ToBxp(=P}=d#!CzC<2z)5%Ls5Lo||>YGcwaK7f|CeWdgK zKYy?8#@vPOucv4k1^CYk9^0mHnk;8YH@yE95hZg64AEpRUQ&u@H@qmJ7P1$zBm*@On8Hwx!E8h$-V^x@@vu*!KNd&%_M5&S!T-N6t-p2uijz zPU?=te45clu$v-F9V)+{{X~p}hQ3VAscdx%=HN8q_Mo}c2#>A&LM!^nR4t>ScRJB& zb9%1H=kw%2y$Mj!|6u-(z^5xdi?f0VXdx02I zabmjDQTFA6gm7ETf7}97ESXNFY%M~gZ9{uE)jF`#h1*f$Iw*Yk)_V2 zNKMlVR}1JN-s70bKEeGHM%pmL!67BbD_r%RcNH{NUjPBx{2AJYX}jJdl*)#|;1vU7 z;%%ryeruqw2U9>5fc;P90w73kBGi?3wwWNi(jH;wOum~?cKIN}?GnH$@<`(LgI-xp}D z%TE`?790$W@87v1vUWy4olX7+E?F^k@_oW6VrIMjU(qFpiKfA!Bm$|0*+nEJQ899F zK{q?PdyiY*;;&ekXi!8w5+sY10ojITW)cMpFRz{-VD?e4+x<_X47a21)q%9FhBbjV z$24wC$4W21JIe#@WJ?#uaS6D)_d+4XaG35I)QhU&TrwDzgCJ3V-Y)T4!Ur`rVs5fm zL<#s;!(O#jS+^34y+GfPaMq^h$0ki9!|R~Sn|%cECPJ&Evi+P5+1K@|Xh^uwvFP<> zS(New;n_WorbG$c27#l9_De3xPm8(jDX$|UAZ^y((H4isA6`-=buxI-qq|9w16P~A zZvKmiLN>ly-rS!9KFthl2 zc`{e3tOeWmw`>eHWs_39n+B_E2l;BAVzqpGa)}-BdTVfp&>;^ewUp6~x->(rNOj+= z_X5)q=Rv4|@N*slIqp1?AX9L$%j_8Kpc9lHDgWK}^cuWTQhQE{ELZl{*lK z?ds^wHkB2EK{I9BjrDvXye1EM!Z#c0$%MnN^5blHXrs*=k?HfO0}casC=DviuzrWk z(QCLRmMPwvED=%DNq^ZUP9o`8K~c^PGBbf}NCo;J*6f8#maq3&UO#>!Sa64e6X3;A zC-w0fnk#<0xg+x3`WdzGQp8x(^uk&b zBGcx`Xyg0_*mIA6Vp6O}A&1VC>k^Y;T?7U<@6lxf-_S1X@&ZpS>WQrLBCP|gAFz~1 zwy-??@>RenKY-X^K9Y&mmsS+2P&{H`c)jeX+L^V=LFDtnR|%0nwM%#2rQafin?X=c zHx-8VUkZ|Vsa;eZe82c40jXWulrxnhlt+^dlRRne1OeQQ;fnT|5%4vrb_zh%tk?vC zbwNMYuJC-XM|=d67YOV`LI)Kyf%T%LFv^y;Z8`QAOMTG6`K@yz?SSa)SixTKy6)MO z8(#8l#2tQ7>)2ybRcS9#tEk?ulV<_J-T45omB0NrrrC|#SSvpZ(EWB0I^DV6a0T;A z@I)3*Hb6ftBrwZJ3k>Mpv&I?S1=b`~1YO_{*M+$yW2gVze7Tu8Pq(Y8kh+?B*$;FF zoDd(m)z~L`U4N(C-_OiY_`a*QmaT9W=;DUXQMX8YJ_S8AKQG}Y%#Nv}7*PUV_cXQX z)v=Pqi7972ruSpsRwIT1Sn`9!i80ZQLv5JI%`yyKM@XlwzXC;(`puHmeKdrr;j7vb z)H%)L#&_l(5`=sxz}liyBlnbaD2qbm3r^k}wKNVOcxne-x4*^P9g47Z+43FgpM=Y1 zWMdou+$PjNBiDbqRVe;6vifOe^51@Fma?4PoG?b_ghV3HRs}!dS}C`Pn1kkzE=s6+ z=dUy%MjdwT86HdndWE=E$jeP1Cj z5n`dTsdz7A_Wmx>a{S0OEGm*}bYqq6avxGIk@hN^LEkLg$h#F95$;qbvO@V-T#@s( zm}j5R%Z}MIqfrds*Mx0dKRy1=iqw%k^Yhy&9Q|pqgZVww?^VB)RUiLr*LJ%C zq%lz_8Hk`UPAo+oF<8Wei~?p%_nEhvpGUcO*xP}!%MpJxJF}vorQyTA;B(E4i|II5 z$y2gQgLJ#`qmt}gSBW6iK{QsaM!Q(HI<1i|^2rF|-FAiM#iv)}1SMYS2saB3LrVI` zib$k)g7CV|ZU;5Pnw`e^K6kuP7@S9qe}w!O8*EUM!;dwM*Y?ih?$D+dCV5U{+8w1E z`!1u~&;#{Z93!y8`PjUyD}$O7^;M3o6m+zE{x2f|Do06yAi%)JpuoVm{@pgH`qS*c4J27*Odeec=Utx3 z8AqI^s0xM@pk%?9>`xluh#3W2d<+3GgE@CUosxtkTN09b3BK0mv@444FNVIm63Y4x z8rMXL8_qBJxO;hDeSN*VSDO`&+WJWQtr7t82T zgeTpu3s&dxMLZ6-Y?3TNe3!-g1T8a|Vzv`J-kBm&NI3vBX%@^@`PYHOd<4tR#Vsan zzVGMEwU~%3w{RM|%osu#e&Seic z0JrSIkb!t#?EwRF2ugjf4lfrh&m%!+qoX)U9E% z1X=C;JY;N)9d0SDa2=z$Drw>!Vz%M>Eb|2>n@KDs`;GW5R4V^&u3cDrJvP!T)}F%Z zTP|M)pRj`KC0O_rt6%&^C3YZrHMlZbnyfSg2QdZE5b`Q*kG$>|KZzlluExxFK{?ik zr}3#_d<-QmGHh;$Q{Y9-O%I70NDt2()0^&;H`Q zoFUR%XusQj5<(lC(6qOCN;yvh!Lk6F1W>s2bcrOiPcmGHc{Q(%Wm+KyCL2WJb4CgQ zqg3Uk-9G_~i2~E5@VR!tKHbQFnFvtzu>T*rCM%EGe$rI{z1`&mI8h+w9-MGV?U96s z(w5rlzZFhh%0$txAoA8*uh57`TSiMn2Q5`u^(M}ZZFDd~-|6Jx_+`7@Ays?+KG zjt8`{w{%gn3APqIVZVv|^*%1v%O9pl03{oy_4dn4?nQUQg9l1P50VM<(a7|MPd8I` z7}r-EfNB4xB0AaXITDArX9tuGeA**_R=FYnC)0Gy0C{tIjz8 zCLDDS1^Lz&ZXDTCVoY>3)~gouqgK~dSPCDWkLjy#Z4-)>?{aJ9E;x;rRYtvkB47zD z;BT0*;zbw#KwzmgOK#MY%nmC(qgEt@O)Xr!;)ZO*TtO`t_2 zSaP)K9$H62{euJeZx*sWnG?N0YU-QKD=CJH}jI{T=t2OpxV#B zr%t37LF9cepQ%aF^b~Jhk>YVxR>8VQBVm}y%mWdP zmA@@^OH6XrnuNKOq~4-a5WDZ6=6(t8O}%R^A~l_udUWc|)@?`m_UP>eZ69P4va5;w zRD}bjO&Nl0Lf*t&cYqxD7`_RgB{_j!FxNxg@#4+oB}zAgyx-PA^NS_vqQ77(FD&G> z-jC{wif~LG?~f;O%4LDJ98 zcdy17qu~YoPBi``{#H#!l2}nxB=36mmWbS{$&ZUdsQdTJEd4p#+OYh)s)P$I{$cs( zFQ~qKKu+dI0?d&}=lN7m?W^h?Rp|OE(QrM8)?2S{%wEtYi9B zPL}fOCv#8)GPtFT5Q5p|ev4Xsf%=BM00WM!*!u;WM!8?6;MT*+ZvA@EvW4&(N;jX16!gB@9yEjV9DN36ZBXc^Q6~Bz5-S=-c5C z)p=Nj7&VvF!e1G5H-(U{q2$dEb~L+w5vZu`t8aJR#}Np3pFPQtU&Gi`XGfB^rR;q7 zuo0qnzdf9dgu$WXN<7EsEzS|F#Yy^6%9CHBf8)k+q7e z$?Px@# zC9-P-e|G`KZJ zLKz09SN1*0doOv1R(-X96XV^52+!e@CC1m?EBUYFLm+GnZKrE~p5cd*o8vVU_*dHhw$0lWLva?fUkvJ*@OQe%oZ#Stcklp*)XIxA1a>kh(d za*<~-D->k@5wez6xF7dim|k~U*oIlp*%alL2vezO3XfQ+JV~%NvD&uhA~(X*_k4u0 zIZNa{rez#`N_jp(ZTr#PD%YH7lI;7xa@T)3E2NHG;p@Fvvy)q60>tx zHF0t_aU^H?ue`OAl@+=OhQM6qy6O6Dd~+93op^YeGdc<+(f2aAxU%fu_^XJdtzN@%SgLd9LI{T5Ew zg7V0P;Xg`MUDc}7t{ub;&SQsvn_#CghS1iu9M-ah4}?~F7qY5V!Z+e4CT|>tq=~de z(F8#hg$O{WA#VMY?`a5u)JAt$TxC}kY-Vawz|u5#)_q8F704~_*|``$xW7>%-NceM z6HI|RmnYrd?GUEG9o^fac%t_Ti`0a(2Tz5B97yH+P|O#(h`!-`Y2m=z?CyIXfhmZ?98wU`lRx-MMg4rPL=NxG%&t3n1_@MteG$*ftdh;ag;aSS6y*?t1JD zRc*T477d0l$a=K0?d;uR%~CC@eMO6&pl(W#8vgK*4;o?*gRL3MwvT_AjMT(qJ4Myo z(YEjvGr419^!wG~a{P-eiHD1_0u{rtGoV7gmbJL4-Ktf-1G99N{W2|CL9=}_qC{*d zi-M>nlVJOp#~0$Cdxiu|>ei1>&>Vc8jfwtSD*@QqI@wv9D4W>ZIeuEr|FM}OHLK6W z=jRz2%-)VRu`YdzVPzHKc0&FDJh7!knMGa^gKrN!YD@KOHJDZSxJ&g2R8HH4E@TpArbOBGvO}zmkt-o4iJu9L#;S^%3S0n( z1{)}KsVM+oB(dkv=c$Uv8q2&2Hl)bTzxTxfOC(9~I1WzC$~aNY6$)s|zXeQAZ*ZB* zaGvs?IY5t;u;`o|oi;RRfP*Sdl6x-LN~%R`=; zIBzNOwn{8Bo62g^Urc^l)L{FtHjZC}y+0|tNtj^RIVj!)VhS9-iAWQFHt|ODDwypy zGfac~TJ%ANlb?ZEa9T+-{Kz!~nS{9D+IW;j`oJYgoMDrcB<%Kf7JfY%ar$w^Ej}Y> zePoQG(7<&(7-EVBGAOt{ZM$BNqI1VGnniaC2c|HgAIhFJ<(@mGB>|_#ti4QZnd&!3 z_7)|hI#_7T+wm?X(i!g3DQNfzQ8H=a?GP0)W2Bh5IJge~D%HkjHgtp-9P~ax}1d2+w3wprAZ*Ih$-lzItFw z^2a>3$gZHorZwRGIjqdGA7d5=hSZf!V#_AqJ@ndbCiKA`<6Y47 z{0lDR&8QIT`;|)o^{iWf2N)6SABiO2@n>(*EUHW6tp_es@&b^X{fGa|0G~VUl`Itc zmshn*Q79@`8TsqxmVmi%`tZO6Zkc>4T@_O)QxgYMtKpazrSd0G;46ho%sRZsyoa(J zA%}#8yM~J(#RD$g4bP+@eCj2X&8h>*@D62F;reiA1I{gcN-7vOc~3B2PvJ!_oP8mj zJ!E97Xcb->6YK$9z|(L2J-f%ycZR!ab)CBwuGXGKq_qAfAY7NU*xrj~d*^2>k8Nwf z&t7asb_`2@9g9x#rj&DKnaYIHoa8FK21gjBu5Pl|i#9}|S}>sHmx)4uFq>d5(?vcpdt=RNcXpZYqj6?4?&3yF9P;Iq<|CCJ+Q#y<(*R_Ko=1Gb0!(07VkLVz`)!w!N6Gmix4 z(1NIHW?}=Wu2y6f8{ANUsJBO0G2G#B5GwsoXge>dgna%?AtiI^niHLUrl8U?ve&bm-hL> za3F{JsN)h`BZt5c^KUPx@{HeJE|APR0K|jCH2?Iw(m(wEcwDw7Ff&O}Y}HQr4s4#6 zmUNv1%hufZRY4kKoeXE;A)lT3Q z><}J&@6dV+$g2VFZO2bAwzcQCkmsel<-G;@DWTdR=s8; zTgfyj?Fnkd>cyF;X?FI!?*`hV-yGrRAQ~hHQdn}jQb_0r$RM1k=ncLE3Y_*i`s02n zUX7PFTPIv%i7pf_ENiHLJU$>bHGy+(M8h8WuE&2Y8QiNy$5G3;y2+&FTNa|0MwXje za1OwCDEP1?vxw0TDN#7Fx)epM5c#oyd(@a75nm~X4n=kB*=4Z}*C7eiry|CBuKUpk zXEAZHlARfYErVTA8_tN79<$)5NvzuYePCav*>*4)k7q?|GA|(vc^#r@CMb)=#X7lv zBcS5&LlRuW|H%xHnch6=#8zSmLm%xsaExmtC1)S&u8Wz*HS=A>bVF-c+Ns=rQ3vVC zc#NCsETc}TO@z#0+L`owXLf14v=rLuLajo|Xn9%M(NC-@lEHG|ev_Cohl9{PdWHu zjQSJxNmZx>yf{Uz^$rDn&&cUW&*JKgixwSfVxxO{$cc$pIv-xK#*3+Sh6S~MY6F7? zb=J%gzE+@|8N&sb?V>&Uk6v>b(QM0~?`n84I}3#Co~M=Q6vi5|Nm=Z4QhcVA^P~Lm z*19zV430l*j7ZGtXG+sY4&A>P&gE`L{{WpfDi^O1@;Z0m+RfNQwy+{hHm-(Svli`E zZ5*ybvd6g2gs}7o-Xbku$85Pa8z*N*ha?a4HZJJq74!1aE-e$dmqhLB(M!)cSew;1 zmx(tI5qM4it>M%qxaiGNe(OAChaMzPBJfo%9W2&&Ex*Mvg{{m~?ItBC!d;EdkWWwN z$-+F8>ZOfrS2WmB*4mNk%imcmUQZ^*cM?0}8OQ2{d*()$d>n0mQ6EjcUsBl0_FRkJ zJH*Nzz?ljxDz8#cz zQ`edWqDGH-1W)<0Nh%)F{rtKhj+UfjW;N}~{lhxSGLqkbySFsUFjItfAQJ}+rWM0E;P)@718luGURNv$16>78VsLD8U<{AY7WVNdnpBz_MK4B*>-5D=Pourfmb{8iepP z$W-YnoOo34A{YD0b$=tP4bkdsUnuB*~+oy!+T zqk@NhY`=f4#U1Y_m#z<+jyser*2`-;sA8+-{}vZRY@a}xI*J@j9Skxz(Z>VE33?%w z{2kJzlV)FSs~A={k%$(n+18wWbbacx9-S!Q%UHAH4MwdpkHnqsuo+(cxI^+_R`i`f zz)C>k=qT2Rujt96-x>2tib{u|8l@8;1NaJrF^DEkCfyhT>#7vAp|G&}Ko zX<}9mgfHZTOU_LPKX0M($quKs!Gww*P~VM_mXdprJ!uCNvHNI(fMB?-NeSRzRm(LT zZdr>fqI;WSVM%omb|_a8>)~&3l0*<(g313@K{l&xm%EIC>ei~l9I+=-0rsGTmSbAgY(VzjphH{$HTqP{eHjmF6TY(d$w;VPpj(q z=5w2JEK;jjwMR{o9)ABD{YPu$l9)11NC>@3^+V33ITtH-Lo9Y{Sl-g##`bu)iMf zH!5-Jlgl5kI{&dr)n^FC%rKe`oyOQDj(b#newEzB4696gFFDRog?}+4yL{Uu;gOc^Ex1hy#;S=1dlk5z3+S zm~2+F2~+gi=NJFQ#zFWx80;z3Chj*u%hJcb9HkuHG{7E5FOK{5-ST?fF@)rz?kC@0j8oxQUm= zt}4lAju~C?q{F*ek6k(*9$sa^4(hP1&w7&=U9UL39L#lAAFMii@prcys}}D`sd-7u zp1$GVL2pc5LIw#2`&(`I<9%E-=eDm7eWyxTDKq8RUPjpFyslcMvUSmQ)6|a}^JDFE zUnGn@lGA~{*ZZWh;yGrw3hsf_NvC7Hf6E`r%Y94RKi2vE-fcUl$K~kumtWw|8oPGb znp_i;?A2#emfRh7Zq(sznqk$Om%I!!aICI#9@WunnDgth zkjEEwru}f4>#yGXyR6P-g*l-@13l*#%HO*0+*`ZRwd!cbtIhpqAH2Q(^p6!mz2^L> z4ZCQ6Gw4%B<)-uN%MHevZ+pdx-CP>1b|g-=dPYZsa@ny%)8D1l{R%$yHKly;r32N~ z*$YehY~ED)&Y`!aPf?z}d(6<#)6M26k>#@V4{1b#<&wd2Iz-EjLuRuim~C~1xvYcI z#na+;$5za+F5CZYeZl_1Wrmf=Xe#k#@}_}WA<-eP z4u8pfT(`2!S|+}nx9W2KqRu9^Q_kfr@2#o7kgun^ePy@j>)-^|0fT_e-d|}K%zqUa zOfK7Z-zsCoOu2pW=hwm~(=%>ID)%Zr?Yq4!q`?03lz271#-k7Lq0*m6HLpDBkAeb|wzaPGmFh24f$WFFYqe?XWcvy&@h%jN7VQx?DZ z@Pe58GtYLb`BmmsIz7Qu@@fwsVlV`hwqQM>@^x zK)a^ymF}^(YIFy2=jWh-Ak*J<38VTXbPGjyib$kd`j znH2W)RPCuvUcVCGs^qKg*~{)#u5H8raJ=Jz#5JAb`7wWwC%Y`!y+EPc-+>8Fw8nY$ z`|&Jk{OW)sy*#gL3xvt*dQ3WWDfiFc>qA~F@DEH+&iisSfERLDIorFyQA2L}>QBix z$4|1?&51}!4GjFE{LbNgpZ#u+uj$fehdA5!?WOAD8=BlZ#k|(y%!3E>98D7Ai8X8`6rac*Fnp#BKQ9@0{j#uwNEz0Wl}quz7%O zjG7L?^r*(E-Q~UkUa%bSCu@n>V>8vkFLkXy9-GeSY;L42$4<_A?bJ=VmsZxp?IyP# zhn%u{Hs%LhRJ{5E3Y}Xtj!l;To;z}A==C3`zhrWw7ySM4L;j52mawANvx?pnoxQXD zdGzKLF)Hbcc0D`LQvuF!ZF{yQ@mG&4{bw9Xm>_>IZq~=HTj|3-{$T8-A9MUQ#3}#j z+UW!CB%HOld7G(!eBAv1@-OV|a6T~0dg7#v&IjL5w)>S-iLtfIidX*T zn%8F!nMt#IkX$%3GRma(o^I!@=7z^APk82z^BcKecav~L`JC_`KA}pH!;h{BvQ4Xa zx%K4H%a8MF51bhMZq|rj0{TBmzw`Y6#uohw_dBsmVI@7U{|=?^D+1v8AIv^m34|32;@yTM}5Gl3v!%G#u{ay@#4$41POJKSSv ze{aJp`ASv~V{%ly6HPRxTdZ;F?qwNRHE0#Te?s)UVv~X_**Wc`_T1ioz z>%ov5hp=78v-;}3a_{^`Uw^kz@UpB^m$rMDjCkHX;ZaSz*NwC_yLRxG{^_KwcQeT* zagN}dao#-VwbAx9>JfuumbyOqE!h2Io%@7o!aAk>XVg0{?{%${%j;otRTd7LYHw|s zm#TcxCbNgX*M~KO{MUG{T5hX8@pQJ|rMJ#y8-^C{{JU*gWa665`j4(gM%ZR8l?~r8 zX`z3_zk#z|H)r+tShA+4ox**UlkC^lE0vZ#UB*e{S@xb^u-xFL&`qge-@w}5WsbSl zYtz4ubIT113#ihOTcNb_>9*uOgIAjP*_0)23a`vs`Z4ib!Ja_Yf6X>Lq0uEjVoX{X zc)JF8yNNV!uODe}SNCafb<=&1@AY9CZ!=9%drg}vUo78g(QZZmuiFHYc(e_zNN^j)a;M`pp=&)2@r2&lYzJ%fAtOTw$XFTYAlXUf!+-^@Cdv)`$gCm-dFD(>0OhM}^wk4Zp2 z+j`u&QI)%F;o7+sSKeNJbo52R+dF-o7>Y@S!{S%HzrrZ;KX@=Wx-8F>y>esby&}tX zZ~gZ7Ij_F3tMkQ|TV9r5dg!#H^yAfx-IfLi_l#9Z89F0$imO`q?^I1bYjUdMu8kH2 znb!>Es*2ox_X@mmbqC|$NpAg=1GzS*UY}e)J?{SKQGVyQs%)D-zBq8o#uYc0c|Nqd zs5w3|Sa?(+<3jGY1&g`{DUYv7QyjQBH?hRx*s8!O8dp9R6;9l5rN7KQuFs`WcA@E- zTC)4Y-#BXgW{#-%E__zEK)C+Fw|`;^@2f^n{o@)wV$Y$+3cX$C?7J0^_R-_?>A3rS zGOepUekwWqqdVc+>V#!>2cKoDE9G|_d1c0#7*Dk^`hpp|dzk3DR77=IY%}%Dxuu4V zp-FZQqc?_Z_&G3hv@L%}Z76q)()W9>R@~^Ow9?7lkJ$aC<)$~2J z{wJL#t*ObF7=P1Go>4e()u{`qiZgph+$jD}C&PQDfpbla@%69`d#C5c_@+Bw)Vtq1 z#EYYL!)(s^q(^aEeJ8Ktk8@R2zWnoorOLc*OSN(~k6i#`Y=@4jvM})q>uWZpZVKRjr@4yJCNF6MuVWgwLjzgj;)zf7NSZ9n?IV31ZtzZ)K*U@-jE_^OA4 zr<)7S$Jflmr3pbs#)?2Lrk0UGaUortr|0t$=Y2esHWVN(3xezzt@iR*4t7jmHys&98g}H%E)M8NM)K5 zNE}9kT^njtqA_k~RNegn5*9$yv@x)&`b023m&cBj>L$CNFP!ij(4GUD5r)XpT6N53rx^QM8rm|>{Sg9xb2I)$DmKO&;pzmsE+9%Fmw1hiOA zqLcIo^bg<{1~L8aZ=@%9_{*#+J4#~ ztX|W9ab)wtq^h9e_OQ**fh+{b95Aw8liEr~WAb2@P%2&Bzc!vLfXW_*W@C)bZ%V7^ z$es8@c;6#$0M-~Xk%1WOpy_0=4V{7!>_9PIoC;x9XanFT@HE^r`~t}UY0(U-p!6(T zNV^B!K?X8aJc{IokU_aoG-+M3>pC<|`v|-YcmC7i31(8+XOD8wI-o zED02-hZ#2@mK@BD#pTgiK@6%MX89*&Mh&P^8EziHtxHQFM}#bjym89*duaOrDhV`+ zXN;VGD4<}xCdYcJXtN$oF@2L5r2Q9>WBJe{8RS?(gU^g$@VYDz5!Eo_M<}pPB*XFv zgMElWd|pH7piZ|3UQO)!83M*b05=e$!f&DAMKUR{XwYbI7z)=;UibXaYrs4zfvJ&7 zjY(q#b0}qCOtYKx4BDlNBu9oJt(=HgxAtx(Es`0R^K8QSl=b)NZ6g#}krC^awtM z`+lGNVW}Nx!~(hkI&dd`gn}-aZ2+gz4}cOXa2U259#pfZLlKCjK7kB6i`%RQmIQ$6 zrWwE$B0x}M?8H!P2+e4kd_c|kOGIJuBLf+nHXvATBM8C{42KXd6#<`72qGfz7_rjd zR~9QmG?|e`d_Oi4pG-j0jW_;zW?TZY?+cWXf#R<55em)`UvKD0B#{J}^bz~E%WQDS z3J81nSW$G8pow~uy3)Dc9Cj2exscQp2yv8lO(iPhjiD3aZq7g15+aIDA}1%CBS7HC z-2aUq0^sAIxj48+LF>VXNOpe&Uas@tnJ&bse3)*4BCqig3ewNC8k`(D%Kbnc%4vc@ zDf*4TXb|XpnG{;AV?Q2~Wbi|+%{5dpzYCCg067YS9B`Es5{-RgSdo&s4qQF)f1nJv zh|1)#Zu}8Q?8^HP72{djYASNY3?KRBunWYjGd+lk@wiWbZWa;TxT0uI4(a@2|IT!X z;!2R);y!ZkNsExu5;dfXdnx}e4}td1?^%Cmn^^HMi}$<@;BG9)HN7~bV+Eo~5bT*@ z12oSd?H?}YfZswvY;~Jxq;O2ya+47U4rC3M#ofKr#}+wIPxWEWB^ixS^RII5b{Wv% z?r4Xv_z?<utWGn>9P#CrBFiMjy?WH7F);EO-tkKX1 zen3CQh5Mt>Rwhw5sF%!#!C^8eMnjIN;^LtoTpo-7=tf5IBNS}y)hGNyqLevp^o{;N1Z8oCEPs>vV78@~7KrxQBhZ^xkFc#(8W zj{x0}c{ws+{ws(XNsn-fU~?J1Y)N30(rGNNPPz>mF@=sXP^@+MEfi=QlLNbPr2;B` znsp!^oF@SSC_bk)3}z^?RJEa{A{PO-hk`B&PA7B8mQPSqFDFdOxeA%KC!`?ySW|xt zAs{#8j*v3>vVBBV4Y~AjTU6XKLHeH{{U8jo%W!f?kRCOY$AnOW>JD<;;Z=KS=rXFa z5FYTRz8gV>3llReo(qQ^Ne&sdt!uwuAiW7V7!G-IGyzhS_quUKF;|-Own?%hnIL^0 zC=_?9ItL0!H22{K6XmE-bb>W6^0pS;=v(j<#PPt4DL(|f4BpnKv1hZqMLN;|C1j%hJqy(-BK~6A3!-H^7 z0WP!+YYFiUyrz5H@J4fKu-8oqgpg=ABkVD)o)CLoqR~W*rnytpXnRTwItwpPi8u!0 zrijYZSW28=CI>2ISZj)*N6aP^-9*f$l}^;Qd`ir4K8q>6bvV*DN~B13Fr#@L4Py;K z=Z2V^7SpM8UXMhFJJ)&Q9m3+x5t5)yy%!0}Zvm7K)t*$p=#RDW2qhehV6ZDvDpXVc ziCXrtB`9WOl=P$ilii=n@50lhv5v<=gImUNBQcjA^XO|f=zTZP#y zFc9I1TZs%Y_;am-7lnwHfCpm0@^tCCXy}nGff`|;-mL=_g^iYw2V=+^TZb$TAT5F8 zzV@mG@cK}KV|JAp4nsv%4DVJH1QA$|6J5(C4k)nYEl?uwAx~XIeK`uUnyC62RH#Fn zf>u`LL0js{NJ$5w%kmqM9}Psw_2r-W}>9c-0)0-k)kJ{p?u4EaCadxq?4D+jrf zgp~;<72xGt!DH~5({l$Y8GQJmbPg1*kks(&PsNdg-#&9*O&4mVQPGIhAeDKWJFWb*_57{`1W~>8_YB=gH#cZjE`U+AVs!F zP9Z4+Dm5mKS9D@S$2tfuim%W{U!WuqjTmqpDxDv}8wcl}MBjaJqQl`rNfK0o9y?Xj z6WzHw04j4l*w|i{PSS)9TUB7iQW75tVLQ)?p#?&qjhr~XUrEdO&g>vZK3p3|9v=|? z$_YnZbpRh-6NTenC~Xry$r2yJud9A|D*;?z5!&yJIg-__HsLqegvQ~pIj(e8a0J2=?| zR$K>y6v7WaK92oim2M}96h^`JR8u_uH=N6gVi|M&kf zl1rHW`FrRF;5h|9xSN%9=qS}XL*Unuk~hjx9L56HN9OqQPh}1^gBYvSr)G;=>OKVa9@3lw5Njj4r(gT|%W^EJ=^7;gA;_y=1rHvGl4uB&6TUPq&ouDfjNKbHm zF?vfUs4s=Z9SI#FL6L{X;xWm#cpzb_JUYBv0{SuoebF%61gp1&%Z&w5fyqNVaivir z@sd>gUONPRsThW5Ta41ZZ(Ar^;@Nj*h*LUb8T+8Rzy}~dy;kuwP76w!38}8O7tK}^ z%rq4SX*|OlHMlkSjwJ7H{#VDR9&cXBzLyR5o+1Dp&kV2!~n?l+=6EDZ^`BpGrq zeyq3kARw!QAAG53;mB5zQOknh)86atdIU0{6D7FDe!-?aX=7)7=WJ9Jr4Yz2J8~zx zq7BcU624_Rx-~3ruy>KgbA)h7HC8X)?@o_^{bsiz!@$+l+o3fKsP~EdOVSERfY-)e z|2zRT9RM}qCDx5;ZGxAQAb*a0<7^ zs|nXr$jsJ~h(6gS36J#jc7od>Pnb@qgOzPONC_CNg|DA%A;)*!xolV-l%XsGVzAYU zYa6~ZBZ3hMpNEp8Pe`5dxUW`sZFcc1Sl(|QX(_>9T; zEv>=#V4xkakS2uH&>abB>)nf#yt z5;JGH(uZ77>ITTO95CYQo9!ls@_}SHL3C-oxB5V0ErZU>(J;F2ciK+}7izE^^6{QL=)l41%E_%NA zMxW{U0)mdi1YHTAXlgk=l16~B95@fm;7C*OMAy9;b4eAyS!akh1~;5w6@1wf`?E>4`yP(Rmy0#3Dbc0Oh)17Uh5ce@Usjsn75- z6*Le100hN3eSWo@(}T(4bA6bh6rP*=LDdLFKuISm|F8X=uyDYPiXb_wgH#*t@ps?= zpv(s`?J?En$;h@hG*BAy>hODVP(P3u(oFXMVUyM~-D^zWp;ebt;5_&&g1lV2IjOwH z_2RouP=Lv-0y1|@on>9yO(v={X|YjoF(sGuP8VdziJy#F+Q57l3`xV7v*g>)3_}^U zyKde4I^ZHu>ccFMBSvZ5v)z;v_@u|ek%)e0rn;gS`vjDWcS%p>cJobSM8dIb(qlM? z^RGp*H{z5GJw~eS=JW|;hVa}OArzUHuUXn#)Jr4>u#Rf~ALm3S?4%{n5qeF$xr;pZ zJk@AFDL+uOHbYKX9%kg@334ieJz+Yj@evCC?bmKfRLfB&La%3Pn@xmrp)-^Vcp?<8 z)ow<=maB!tl1*I&AgKc6eO`@nqB2DfE`(}l0_Ml!!brjh7I_neWl;^A{N|SXQ6RMj z!5uMj6}@(oQyfG_T}Hm2|AJ$nU^55{csDiF|Nr>hnPl}5k}=w;*tQ51JRMfOaaVFM zZa=5AHLz6%vo&|ZwZZ-~iHx&N+Q>+YhEv_Jk(d=Kb=58Hb@rkcFb@#|E4v<;9iv>@ z$T*P^#OI(QrKzBoO5Jzgc21VSv-f2pY3&8adx+Xpw91V+sEq6_VXylPjZ@>x1-!L$H z!1fY+nr)?jt4Uy;1Tq2G)J@Lua(YP!+SqU$gaHp}e1w9ES<*S8>bHtFOyiNGhpZbh z0IgrZAuqxtWDb1tO`4h-(A^oaR4qSJ<2VLp_hr_>L>q2`TS2YD7O9068^oZv^A1I& zftSkfn*)gu)Z^Bu929~Vg|v!9w2yV1O9UfUB#NH@T=cgO56a+3H&zJAu{K1jZEL4) z4D))6!ieiW8gSyN6?!Akl3VBXr-TjLL8y1|gZo!HoGNQAOTBkdtzYv_^!k8y8K!}i z@b%Z_&{x~YA!Ycu+jCK>8y{}zR_Z{Q5WTmptvuw~Qc`)pc{8}dBZy}BTHGACDytQe zh&LXi=-K$C>gF45k>z!MGFRLOmVpph@ROuLecQw$S}vocQGUVr(FshlN`fYBK$~bp zQ%ICFBW1fx{RG~{0uO*o&Ke(~;Dc_PXx!OBFl`h}Nwh7#Lr=8eD}?L;cQb34h;M^& z>X)}Dd59me7fU1*Xc)JNhxkc*q8|`Hgx*9ndT^VFntv9ZNJ9K#bQ8&3v$l~y`b?=a z;wOKbShOtL%pzVEp=2X|nYM|oYDk;dnlF)1vJpRE+QepRC7q4xbEZTa5kG#}#NcDy zMh4ii!& zzxl25&6|l}h#&3{0|^Cct^}CI^A6Nk=O9Gl2PK*iZ@Li>$v!VZY#{NQ2TgDZjbL};%0K2H12u{58yb0XgTM9VI73kjMJHv1ccRj#AoBZM4 KlZh}0$ovmwdV<6N diff --git a/dev-lib/junit-4.12.jar b/dev-lib/junit-4.12.jar deleted file mode 100644 index 3a7fc266c3e32283a2b21fe12166ebdcc33a1da1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 314932 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