//////////////////////////////////////////////////////////////////////// /// Abstraction functions //////////////////////////////////////////////////////////////////////// protected override void GenerateConvertGlobals_LH() { var ps = new List <string>(); foreach (var varName in pgp.symbolsLow.Globals.VariableNames) { if (hiddenVariables.Contains(varName)) { continue; } var v = pgp.symbolsLow.Globals.Lookup(varName); if (v is GlobalUnaddressableArmadaVariable) { ps.Add($"globals.{v.FieldName}"); } } var fn = $@" function ConvertGlobals_LH(globals: L.Armada_Globals) : H.Armada_Globals {{ H.Armada_Globals({AH.CombineStringsWithCommas(ps)}) }} "; pgp.AddFunction(fn, "convert"); }
protected override void GenerateConvertGhosts_HL() { var ps = new List <string>(); foreach (var varName in pgp.symbolsHigh.Globals.VariableNames) { if (introducedVariables.Contains(varName)) { continue; } var v = pgp.symbolsHigh.Globals.Lookup(varName); if (v is GlobalGhostArmadaVariable) { ps.Add($"ghosts.{v.FieldName}"); } } var fn = $@" function ConvertGhosts_HL(ghosts: H.Armada_Ghosts) : L.Armada_Ghosts {{ L.Armada_Ghosts({AH.CombineStringsWithCommas(ps)}) }} "; pgp.AddFunction(fn, "convert"); }
protected override void GenerateConvertGhosts_LH() { var ps = new List <string>(); foreach (var varName in pgp.symbolsHigh.Globals.VariableNames) { var v = pgp.symbolsLow.Globals.Lookup(varName); if (v == null) { v = pgp.symbolsHigh.Globals.Lookup(varName); if (v is GlobalGhostArmadaVariable ghost) { var p = ResolveInit(ghost.initialValue); if (p == null) { AH.PrintError(pgp.prog, $"Introduced ghost variable {varName} must be initialized"); } ps.Add(p); } } else if (v is GlobalGhostArmadaVariable) { ps.Add($"ghosts.{v.FieldName}"); } } var fn = $@" function ConvertGhosts_LH(ghosts: L.Armada_Ghosts) : H.Armada_Ghosts {{ H.Armada_Ghosts({AH.CombineStringsWithCommas(ps)}) }} "; pgp.AddFunction(fn, "convert"); }
protected override void GenerateConvertStackVars_LH(string methodName) { var smst = pgp.symbolsLow.GetMethodSymbolTable(methodName); var ps = smst.AllVariablesInOrder.Where(v => !IsVariableHidden(methodName, v.FieldName)).Select(v => $"vs.{v.FieldName}"); var fn = $@" function ConvertStackVars_LH_{methodName}(vs: L.Armada_StackVars_{methodName}) : H.Armada_StackVars_{methodName} {{ H.Armada_StackVars_{methodName}({AH.CombineStringsWithCommas(ps)}) }} "; pgp.AddFunction(fn, "convert"); }
protected override void GenerateConvertStackVars_HL(string methodName) { var smst = pgp.symbolsHigh.GetMethodSymbolTable(methodName); var ps = new List <string>(); foreach (var v in smst.AllVariablesInOrder) { if (methodName != strategy.MethodName || v.name != strategy.VariableName) { ps.Add($"vs.{v.FieldName}"); } } var fn = $@" function ConvertStackVars_HL_{methodName}(vs: H.Armada_StackVars_{methodName}) : L.Armada_StackVars_{methodName} {{ L.Armada_StackVars_{methodName}({AH.CombineStringsWithCommas(ps)}) }} "; pgp.AddFunction(fn, "convert"); }
protected override void GenerateConvertStackVars_LH(string methodName) { var smst = pgp.symbolsLow.GetMethodSymbolTable(methodName); var ps = new List <string>(); var lowVarNames = new List <string>(smst.AllVariableNamesInOrder); foreach (var varName in lowVarNames) { var v = smst.LookupVariable(varName); ps.Add($"vs.{v.FieldName}"); } smst = pgp.symbolsHigh.GetMethodSymbolTable(methodName); var highVars = new List <ArmadaVariable>(smst.AllVariablesInOrder); if (highVars.Count() != lowVarNames.Count()) { for (var i = 0; i < highVars.Count(); ++i) { if (!lowVarNames.Contains(highVars[i].name)) { var v = highVars[i]; ps.Insert(i, strategy.InitializationExpression); } } } var fn = $@" function ConvertStackVars_LH_{methodName}(vs: L.Armada_StackVars_{methodName}) : H.Armada_StackVars_{methodName} {{ H.Armada_StackVars_{methodName}({AH.CombineStringsWithCommas(ps)}) }} "; pgp.AddFunction(fn, "convert"); }
protected override string GetStepCaseForNormalNextRoutine_LH(NextRoutine nextRoutine) { string nextRoutineName = nextRoutine.NameSuffix; var bvs = nextRoutine.HasFormals ? $"params: L.Armada_StepParams_{nextRoutine.NameSuffix}" : ""; var hNextRoutine = LiftNextRoutine(nextRoutine); var ps = hNextRoutine.Formals.Select(f => $"params.{f.LocalVarName}"); string hname = hNextRoutine.NameSuffix; var caseBody = hNextRoutine.HasFormals ? $"H.Armada_Step_{hname}(H.Armada_StepParams_{hname}({AH.CombineStringsWithCommas(ps)}))" : $"H.Armada_Step_{hname}"; return($"case Armada_Step_{nextRoutineName}({bvs}) => {caseBody}\n"); }
protected override string GetStepCaseForNormalNextRoutine_LH(NextRoutine nextRoutine) { var bvs = nextRoutine.HasFormals ? $"params: L.Armada_StepParams_{nextRoutine.NameSuffix}" : ""; var ps = nextRoutine.Formals.Select(f => $"params.{f.LocalVarName}").ToList(); if (nextRoutine.nextType == NextType.Call && ((ArmadaCallStatement)nextRoutine.armadaStatement).CalleeName == strategy.MethodName || nextRoutine.nextType == NextType.CreateThread && ((nextRoutine.stmt as UpdateStmt).Rhss[0] as CreateThreadRhs).MethodName.val == strategy.MethodName) { var highRoutine = LiftNextRoutine(nextRoutine); var highFormals = new List <NextFormal>(highRoutine.Formals); for (var i = 0; i < highFormals.Count(); ++i) { if (!nextRoutine.Formals.Any(f => f.LocalVarName == highFormals[i].LocalVarName)) { ps.Insert(i, strategy.InitializationExpression); break; } } } var hNextRoutine = LiftNextRoutine(nextRoutine); string hname = hNextRoutine.NameSuffix; var caseBody = hNextRoutine.HasFormals ? $"H.Armada_Step_{hname}(H.Armada_StepParams_{hname}({AH.CombineStringsWithCommas(ps)}))" : $"H.Armada_Step_{hname}"; return($"case Armada_Step_{nextRoutine.NameSuffix}({bvs}) => {caseBody}\n"); }
protected string GetStepCaseForUpdateToUpdateNextRoutine_LH(NextRoutine nextRoutine) { var hNextRoutine = nextRoutineMap[nextRoutine]; var lowStmt = (UpdateStmt)nextRoutine.armadaStatement.Stmt; var lowExprs = lowStmt.Lhss; var hStmt = (UpdateStmt)hNextRoutine.armadaStatement.Stmt; var hExprs = hStmt.Lhss; var pi = GetMatchingLowLevelLhssForHighLevelLhss(lowExprs, hExprs); var bvs = nextRoutine.HasFormals ? $"params: L.Armada_StepParams_{nextRoutine.NameSuffix}" : ""; var ps = new List <string>(); for (int i = 0; i < hExprs.Count; i++) { var failureReporter = new SimpleFailureReporter(pgp.prog); var context = new NormalResolutionContext("L", nextRoutine.method.Name, pgp.symbolsLow, failureReporter); // Add the pi[i]'th rhs from the low-level update statement var rhs = lowStmt.Rhss.ElementAt(pi[i]); string newRhs; if (rhs is ExprRhs) { var erhs = (ExprRhs)rhs; var newRhsRValue = context.ResolveAsRValue(erhs.Expr); newRhs = newRhsRValue.Val; } else // rhs must be HavocRhs here { newRhs = $"params.nondet{i}"; } if (hStmt.Rhss.ElementAt(i) is HavocRhs) // If the high level is a havoc-rhs, then it needs to be given the values { ps.Add(newRhs); } } string hname = hNextRoutine.NameSuffix; var caseBody = hNextRoutine.HasFormals ? $"H.Armada_Step_{hname}(H.Armada_StepParams_{hname}({AH.CombineStringsWithCommas(ps)}))" : $"H.Armada_Step_{hname}"; return($"case Armada_Step_{nextRoutine.NameSuffix}({bvs}) => {caseBody}\n"); }
protected string GetStepCaseForUpdateToSomehowNextRoutine_LH(NextRoutine nextRoutine) { var hNextRoutine = nextRoutineMap[nextRoutine]; var lowStmt = (UpdateStmt)nextRoutine.armadaStatement.Stmt; var lowExprs = lowStmt.Lhss; var hStmt = (SomehowStmt)hNextRoutine.armadaStatement.Stmt; var hExprs = hStmt.Mod.Expressions; var pi = GetMatchingLowLevelLhssForHighLevelLhss(lowExprs, hExprs); var bvs = nextRoutine.HasFormals ? $"params: L.Armada_StepParams_{nextRoutine.NameSuffix}" : ""; var ps = nextRoutine.Formals.Select(f => $"params{f.LocalVarName}").ToList(); for (int i = 0; i < hExprs.Count; i++) { var failureReporter = new SimpleFailureReporter(pgp.prog); var context = new NormalResolutionContext("L", nextRoutine.method.Name, pgp.symbolsLow, failureReporter); // Add the pi[i]'th rhs from the low-level update statement var rhs = lowStmt.Rhss.ElementAt(pi[i]); if (rhs is ExprRhs) { var erhs = (ExprRhs)rhs; var newRhsRValue = context.ResolveAsRValue(erhs.Expr); ps.Add(newRhsRValue.Val); } else { AH.PrintError(pgp.prog, "Havoc RHS not yet supported"); return(null); } } string hname = hNextRoutine.NameSuffix; var caseBody = hNextRoutine.HasFormals ? $"H.Armada_Step_{hname}(H.Armada_StepParams_{hname}({AH.CombineStringsWithCommas(ps)}))" : $"H.Armada_Step_{hname}"; return($"case Armada_Step_{nextRoutine.NameSuffix}({bvs}) => {caseBody}\n"); }