public void Extract(ArmadaSymbolTable symbols, DeclCollector declCollector, List <string> stepCtors) { if (!valid) { return; } ExtractInternal(symbols, declCollector, stepCtors, false); if (hasUndefinedBehaviorAvoidanceConstraint) { ExtractInternal(symbols, declCollector, stepCtors, true); } }
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; } }