private void TryElimination(IEnumerable <Variable> extraDefinedVariables) { bool Defined(Variable v) => varToExpr.ContainsKey(v) || extraDefinedVariables.Contains(v); bool changed; do { changed = false; var remainingAssignments = new List <Assignment>(); foreach (var assignment in assignments) { if (!Defined(assignment.Var) && VariableCollector.Collect(assignment.Expr). Intersect(AllIntroducedVariables).All(Defined)) { varToExpr[assignment.Var] = SubstitutionHelper.Apply(varToExpr, assignment.Expr); changed = true; } else { remainingAssignments.Add(assignment); } } Substitution sub = Substituter.SubstitutionFromHashtable(varToExpr); foreach (var assignment in remainingAssignments) { assignment.Expr = Substituter.Apply(sub, assignment.Expr); } assignments = remainingAssignments; assumes = SubstitutionHelper.Apply(sub, assumes).ToList(); } while (changed); }
private static void SubstituteBackwardAssignments(AtomicAction action) { foreach (Block block in action.impl.Blocks) { List <Cmd> cmds = new List <Cmd>(); foreach (Cmd cmd in block.cmds) { if (cmd is AssignCmd _assignCmd && QKeyValue.FindBoolAttribute(_assignCmd.Attributes, CivlAttributes.BACKWARD)) { AssignCmd assignCmd = _assignCmd.AsSimpleAssignCmd; var lhss = assignCmd.Lhss; var rhss = assignCmd.Rhss; var rhssVars = rhss.SelectMany(x => VariableCollector.Collect(x)); var lhssVars = lhss.SelectMany(x => VariableCollector.Collect(x)); if (rhssVars.Intersect(lhssVars).Any()) { // TODO throw new NotImplementedException("Substitution of backward assignment where lhs appears on rhs"); } else { List <Expr> assumeExprs = new List <Expr>(); for (int k = 0; k < lhss.Count; k++) { assumeExprs.Add(Expr.Eq(lhss[k].AsExpr, rhss[k])); } cmds.Add(new AssumeCmd(Token.NoToken, Expr.And(assumeExprs))); cmds.Add(new HavocCmd(Token.NoToken, lhss.Select(x => x.DeepAssignedIdentifier).ToList())); } }
public AtomicAction(Procedure proc, Implementation impl, MoverType moverType, LayerRange layerRange) { this.proc = proc; this.impl = impl; this.moverType = moverType; this.layerRange = layerRange; CivlUtil.AddInlineAttribute(proc); CivlUtil.AddInlineAttribute(impl); // The gate of an atomic action is represented as asserts at the beginning of the procedure body. this.gate = impl.Blocks[0].cmds.TakeWhile((c, i) => c is AssertCmd).Cast <AssertCmd>().ToList(); impl.Blocks[0].cmds.RemoveRange(0, gate.Count); gateUsedGlobalVars = new HashSet <Variable>(VariableCollector.Collect(gate).Where(x => x is GlobalVariable)); actionUsedGlobalVars = new HashSet <Variable>(VariableCollector.Collect(impl).Where(x => x is GlobalVariable)); modifiedGlobalVars = new HashSet <Variable>(AssignedVariables().Where(x => x is GlobalVariable)); // We usually declare the Boogie procedure and implementation of an atomic action together. // Since Boogie only stores the supplied attributes (in particular linearity) in the procedure parameters, // we copy them into the implementation parameters here. for (int i = 0; i < proc.InParams.Count; i++) { impl.InParams[i].Attributes = proc.InParams[i].Attributes; } for (int i = 0; i < proc.OutParams.Count; i++) { impl.OutParams[i].Attributes = proc.OutParams[i].Attributes; } AtomicActionDuplicator.SetupCopy(this, ref firstGate, ref firstImpl, "first_"); AtomicActionDuplicator.SetupCopy(this, ref secondGate, ref secondImpl, "second_"); DeclareTriggerFunctions(); }
public override Expr VisitExpr(Expr node) { if (node is NAryExpr nary && nary.Fun is BinaryOperator op && op.Op == BinaryOperator.Opcode.Eq && VariableCollector.Collect(node).Contains(choice)) { return(Expr.True); } return(base.VisitExpr(node)); }
private bool TryElimination(IEnumerable <Variable> extraDefinedVariables) { bool changed = false; var remainingCmds = new List <Cmd>(); foreach (var cmd in newCmds) { if (cmd is AssignCmd assignCmd) { var lhss = new List <AssignLhs>(); var rhss = new List <Expr>(); for (int k = 0; k < assignCmd.Lhss.Count; k++) { var lhs = assignCmd.Lhss[k]; var rhs = assignCmd.Rhss[k]; Variable assignedVar = lhs.DeepAssignedVariable; var allDefinedVars = varToExpr.Keys.Union(extraDefinedVariables); if (!allDefinedVars.Contains(assignedVar) && !VariableCollector.Collect(rhs).Intersect(AllIntroducedVariables). Except(allDefinedVars).Any()) { varToExpr[assignedVar] = rhs; changed = true; } else { lhss.Add(lhs); rhss.Add(rhs); } } if (lhss.Any()) { remainingCmds.Add(new AssignCmd(cmd.tok, lhss, rhss, assignCmd.Attributes)); } } else if (cmd is AssumeCmd) { remainingCmds.Add(cmd); } } Substitution sub = Substituter.SubstitutionFromHashtable(varToExpr); newCmds = remainingCmds.Select(cmd => ApplyOnRhss(sub, cmd)).ToList(); return(changed); }
private void PendingPropagate(HashSet <Variable> allExistsVars, Dictionary <Variable, Expr> existsSubstitutionMap, Variable eVar, Expr eVarSubstExpr, Dictionary <Variable, Expr> pendingMap) { var usedExistsVars = VariableCollector.Collect(eVarSubstExpr).Intersect(allExistsVars); if (usedExistsVars.Count() == 0) { existsSubstitutionMap[eVar] = eVarSubstExpr; } else if (usedExistsVars.Except(existsSubstitutionMap.Keys).Count() == 0) { Substitution subst = Substituter.SubstitutionFromHashtable(existsSubstitutionMap); existsSubstitutionMap[eVar] = Substituter.Apply(subst, eVarSubstExpr); } else { pendingMap[eVar] = eVarSubstExpr; } }
private Expr CalculatePathCondition(PathInfo path) { HashSet <Variable> allExistsVars = new HashSet <Variable>(firstExistsVars.Union(secondExistsVars)); HashSet <Variable> usedExistsVars = new HashSet <Variable>(); Dictionary <Variable, Expr> existsSubstitutionMap = new Dictionary <Variable, Expr>(); List <Expr> inferredSelectEqualities = new List <Expr>(); foreach (Variable v in path.varToExpr.Keys.Except(postExistVars)) { var expr = path.varToExpr[v]; usedExistsVars.UnionWith(VariableCollector.Collect(expr).Intersect(allExistsVars)); IdentifierExpr ie = expr as IdentifierExpr; if (ie != null && IsExistsVar(ie.Decl) && !existsSubstitutionMap.ContainsKey(ie.Decl)) { existsSubstitutionMap[ie.Decl] = Expr.Ident(v); } else if (IsMapStoreExpr(expr)) { inferredSelectEqualities.Add(GenerateEqualityWithSelect(expr as NAryExpr, Expr.Ident(v))); } } foreach (Expr expr in path.pathExprs) { usedExistsVars.UnionWith(VariableCollector.Collect(expr).Intersect(allExistsVars)); } InferSubstitution(allExistsVars, existsSubstitutionMap, path.pathExprs, inferredSelectEqualities); List <Expr> triggerExprs = new List <Expr>(); List <Variable> quantifiedVars = new List <Variable>(); foreach (var v in usedExistsVars.Except(existsSubstitutionMap.Keys)) { var triggerFun = TriggerFunction(v); // this call populates existsVars[v] var quantifiedVar = existsVars[v]; triggerExprs.Add( new NAryExpr(Token.NoToken, new FunctionCall(triggerFun), new Expr[] { Expr.Ident(quantifiedVar) })); quantifiedVars.Add(quantifiedVar); existsSubstitutionMap[v] = Expr.Ident(quantifiedVar); } Substitution subst = Substituter.SubstitutionFromHashtable(existsSubstitutionMap); List <Expr> returnExprs = new List <Expr>(); foreach (Variable v in path.varToExpr.Keys.Except(postExistVars)) { Expr withOldExpr = MyDuplicator.Duplicate(path.varToExpr[v]); var substExpr = Expr.Eq(Expr.Ident(v), Substituter.Apply(subst, withOldExpr)); substExpr.Type = Type.Bool; returnExprs.Add(substExpr); } foreach (Expr x in path.pathExprs) { var withOldExpr = MyDuplicator.Duplicate(x); returnExprs.Add(Substituter.Apply(subst, withOldExpr)); } var returnExpr = Expr.And(returnExprs); if (quantifiedVars.Count > 0) { if (first == null) { returnExpr = new ExistsExpr(Token.NoToken, quantifiedVars, returnExpr); } else { returnExpr = new ExistsExpr(Token.NoToken, quantifiedVars, new Trigger(Token.NoToken, true, triggerExprs), returnExpr); } } return(returnExpr); }