private void ExtractInternal(ArmadaSymbolTable symbols, DeclCollector declCollector, List <string> stepCtors, bool ub) { var nameSuffix = MakeNameSuffix(); if (ub) { nameSuffix = "UB_" + nameSuffix; } if (formals.Any()) { var paramsFormalsList = String.Join(", ", formals.Select(f => $"{f.LocalVarName}: {f.VarType}")); var paramsTypeDecl = $"datatype Armada_StepParams_{nameSuffix} = Armada_StepParams_{nameSuffix}({paramsFormalsList})"; declCollector.AddItem(paramsTypeDecl); } stepCtors.Add($"Armada_Step_{nameSuffix}(" + (formals.Any() ? $"params_{nameSuffix}: Armada_StepParams_{nameSuffix}" : "") + ")"); var extraParameterDecls = formals.Any() ? $", params: Armada_StepParams_{nameSuffix}" : ""; var extraParameterArgs = formals.Any() ? $", params" : ""; var paramDecls = String.Concat(formals.Select(f => $"var {f.LocalVarName} := params.{f.LocalVarName};\n")); var validState = ub ? validUndefinedStepBuilder.Extract() : validDefinedStepBuilder.Extract(); var nextState = ub ? $"s.(stop_reason := Armada_StopReasonUndefinedBehavior)" : $"{paramDecls}{getNextStateBuilder.Extract()}"; declCollector.AddItem($@" predicate Armada_ValidStep_{nameSuffix}(s: Armada_TotalState, tid: Armada_ThreadHandle{extraParameterDecls}) requires tid in s.threads {{ var t := s.threads[tid]; var locv := Armada_GetThreadLocalView(s, tid); {paramDecls} {validState} }} "); declCollector.AddItem($@" function Armada_GetNextState_{nameSuffix}(s: Armada_TotalState, tid: Armada_ThreadHandle{extraParameterDecls}) : Armada_TotalState requires tid in s.threads requires Armada_ValidStep_{nameSuffix}(s, tid{extraParameterArgs}) {{ var t := s.threads[tid]; var locv := Armada_GetThreadLocalView(s, tid); {nextState} }} "); var stopping = (nextType == NextType.TerminateProcess || nextType == NextType.AssertFalse || ub); var nextRoutine = new NextRoutine(prog, symbols, nextType, methodInfo, armadaStatement, stmt, startPC, endPC, formals, nameSuffix, ub, stopping); symbols.AddNextRoutine(nextRoutine); if (ub) { undefinedBehaviorNextRoutine = nextRoutine; } else { definedBehaviorNextRoutine = nextRoutine; } }
protected override void GenerateConvertTraceEntry_LH() { var cases = new List <MatchCaseExpr>(); foreach (var nextRoutine in pgp.symbolsLow.NextRoutines) { cases.Add(GetTraceEntryCaseForNextRoutine_LH(nextRoutine)); } ExpressionBuilder bodyBuilder = new ExpressionBuilder(pgp.prog); var ls = AH.MakeNameSegment("ls", "L.Armada_TraceEntry"); var entry = AH.MakeNameSegment("entry", "L.Armada_TraceEntry"); var tid = AH.MakeExprDotName(entry, "tid", "L.Armada_ThreadHandle"); var locv = AH.MakeApply2("L.Armada_GetThreadLocalView", ls, tid, "L.Armada_SharedMemory"); var threads = AH.MakeExprDotName(ls, "threads", "map<Armada_ThreadHandle, Armada_Thread>"); var t = AH.MakeSeqSelectExpr(threads, tid, "L.Armada_Thread"); // var t = AH.ParseExpression(pgp.prog, "", "ls.threads[tid]"); locv = bodyBuilder.AddVariableDeclaration("locv", locv); t = bodyBuilder.AddVariableDeclaration("t", t); var source = AH.MakeNameSegment("entry", "L.Armada_TraceEntry"); var body = AH.MakeMatchExpr(source, cases, "H.Armada_TraceEntry"); bodyBuilder.SetBody(body); var formals = new List <Formal> { AH.MakeFormal("ls", "LState"), AH.MakeFormal("entry", "L.Armada_TraceEntry") }; var validTraceEntryPredicate = AH.MakeApply2("L.Armada_ValidStep", ls, entry, new BoolType()); var fn = AH.MakeFunctionWithReq("ConvertTraceEntry_LH", formals, validTraceEntryPredicate, bodyBuilder.Extract()); pgp.AddDefaultClassDecl(fn, "convert"); }
public void Extract(ModuleDefinition m, ArmadaSymbolTable symbols, List <MemberDecl> newDefaultClassDecls, List <DatatypeCtor> entryCtors, List <MatchCaseExpr> overallNextCases, List <MatchCaseExpr> validStepCases, List <MatchCaseExpr> crashAvoidanceCases, List <MatchCaseExpr> getNextStateCases) { if (!valid) { return; } var entryFormals = new List <Formal> { AH.MakeFormal("tid", "Armada_ThreadHandle") }; var commonFormals = new List <Formal> { AH.MakeFormal("s", "Armada_TotalState"), AH.MakeFormal("tid", "Armada_ThreadHandle") }; var overallNextFormals = new List <Formal> { AH.MakeFormal("s", "Armada_TotalState"), AH.MakeFormal("s'", "Armada_TotalState"), AH.MakeFormal("tid", "Armada_ThreadHandle") }; var caseArguments = new List <BoundVar> { AH.MakeBoundVar("tid", "Armada_ThreadHandle") }; var commonMatchBodyArguments = new List <Expression>() { AH.MakeNameSegment("s", "Armada_TotalState"), AH.MakeNameSegment("tid", "Armada_ThreadHandle") }; var overallNextMatchBodyArguments = new List <Expression>() { AH.MakeNameSegment("s", "Armada_TotalState"), AH.MakeNameSegment("s'", "Armada_TotalState"), AH.MakeNameSegment("tid", "Armada_ThreadHandle") }; foreach (var f in formals) { var flattened_type = symbols.FlattenType(f.VarType); commonFormals.Add(AH.MakeFormal(f.LocalVarName, flattened_type)); overallNextFormals.Add(AH.MakeFormal(f.LocalVarName, flattened_type)); entryFormals.Add(AH.MakeFormal(f.GloballyUniqueVarName, flattened_type)); caseArguments.Add(AH.MakeBoundVar(f.LocalVarName, flattened_type)); commonMatchBodyArguments.Add(AH.MakeNameSegment(f.LocalVarName, flattened_type)); overallNextMatchBodyArguments.Add(AH.MakeNameSegment(f.LocalVarName, flattened_type)); } var nameSuffix = NameSuffix; var entryName = $"Armada_TraceEntry_{nameSuffix}"; entryCtors.Add(AH.MakeDatatypeCtor(entryName, entryFormals)); var validStepFn = AH.MakeNameSegment($"Armada_ValidStep_{nameSuffix}", (Type)null); var validStepMatchBody = AH.SetExprType(new ApplySuffix(Token.NoToken, validStepFn, commonMatchBodyArguments), new BoolType()); validStepCases.Add(AH.MakeMatchCaseExpr(entryName, caseArguments, validStepMatchBody)); var validStepPredBody = validStepBuilder.Extract(); var validStepName = $"Armada_ValidStep_{nameSuffix}"; var validStepPred = AH.MakePredicate(validStepName, commonFormals, validStepPredBody); newDefaultClassDecls.Add(validStepPred); var crashAvoidanceFn = AH.MakeNameSegment($"Armada_UndefinedBehaviorAvoidance_{nameSuffix}", (Type)null); var crashAvoidanceMatchBody = AH.SetExprType(new ApplySuffix(Token.NoToken, crashAvoidanceFn, commonMatchBodyArguments), new BoolType()); crashAvoidanceCases.Add(AH.MakeMatchCaseExpr(entryName, caseArguments, crashAvoidanceMatchBody)); var crashAvoidanceName = $"Armada_UndefinedBehaviorAvoidance_{nameSuffix}"; var crashAvoidancePredBody = crashAvoidanceBuilder.Extract(); var crashAvoidancePred = AH.MakePredicateWithReq(crashAvoidanceName, commonFormals, validStepMatchBody, crashAvoidancePredBody); newDefaultClassDecls.Add(crashAvoidancePred); var getNextStateFn = AH.MakeNameSegment($"Armada_GetNextState_{nameSuffix}", (Type)null); var getNextStateMatchBody = AH.SetExprType(new ApplySuffix(Token.NoToken, getNextStateFn, commonMatchBodyArguments), "Armada_TotalState"); getNextStateCases.Add(AH.MakeMatchCaseExpr(entryName, caseArguments, getNextStateMatchBody)); var getNextStateName = $"Armada_GetNextState_{nameSuffix}"; var getNextStateFnBody = getNextStateBuilder.Extract(); var getNextStateReq = AH.MakeAndExpr(validStepMatchBody, crashAvoidanceMatchBody); var getNextStateFunc = AH.MakeFunctionWithReq(getNextStateName, commonFormals, getNextStateReq, getNextStateFnBody); newDefaultClassDecls.Add(getNextStateFunc); // predicate Armada_Next_{nameSuffix}(s:Armada_TotalState, s':Armada_TotalState, ...) { // && Armada_ValidStep_{nameSuffix}(s, ...) // && s' == if Armada_UndefinedBehaviorAvoidance(s, ...) then Armada_GetNextState(s, ...) // else s.(stop_reason := Armada_StopReasonUndefinedBehavior) // } var s_with_undefined_behavior = AH.MakeDatatypeUpdateExpr(s, "stop_reason", AH.MakeNameSegment("Armada_StopReasonUndefinedBehavior", "Armada_StopReason")); var target_s_prime = AH.MakeIfExpr(crashAvoidanceMatchBody, getNextStateMatchBody, s_with_undefined_behavior); var s_prime = AH.MakeNameSegment("s'", "Armada_TotalState"); var s_prime_correct = AH.MakeEqExpr(s_prime, target_s_prime); var overallNextBody = AH.MakeAndExpr(validStepMatchBody, s_prime_correct); var overallNextName = $"Armada_Next_{nameSuffix}"; var overallNextPred = AH.MakePredicate(overallNextName, overallNextFormals, overallNextBody); newDefaultClassDecls.Add(overallNextPred); var overallNextFn = AH.MakeNameSegment(overallNextName, (Type)null); var overallNextMatchBody = AH.SetExprType(new ApplySuffix(Token.NoToken, overallNextFn, overallNextMatchBodyArguments), new BoolType()); overallNextCases.Add(AH.MakeMatchCaseExpr(entryName, caseArguments, overallNextMatchBody)); }