private static bool MatchPredicateCmd(PredicateCmd cmd, PredicateCmd toMatch, out List <Tuple <Dictionary <Declaration, Expr>, Dictionary <string, IAppliable> > > substitutions) { var match = false; substitutions = null; if (!ExprMatchVisitor.AreAttributesASubset(toMatch.Attributes, cmd.Attributes)) { return(match); } var mv = new ExprMatchVisitor(toMatch.Expr); mv.VisitExpr(cmd.Expr); if (mv.Matches) { match = true; substitutions = new List <Tuple <Dictionary <Declaration, Expr>, Dictionary <string, IAppliable> > >() { new Tuple <Dictionary <Declaration, Expr>, Dictionary <string, IAppliable> >(mv.Substitution, mv.FunctionSubstitution) }; } return(match); }
private static bool MatchAssignCmd(AssignCmd cmd, AssignCmd toMatchCmd, out List <Tuple <Dictionary <Declaration, Expr>, Dictionary <string, IAppliable> > > substitutions) { bool match = false; var substitution = new Dictionary <Declaration, Expr>(); var funcSubstitution = new Dictionary <string, IAppliable>(); substitutions = null; //CONVENTION: x := e matches x1, x2 := e1, e2; (the first match is taken, as usual) // --> i.e., we treat a multi-assign as if it were several assignments for matching purposes // but we make at most one insertion for a multi-assign --> TODO: revise Debug.Assert(toMatchCmd.Lhss.Count == 1); for (int i = 0; i < cmd.Lhss.Count; i++) { var lhs = cmd.Lhss[i].AsExpr; var lEmv = new ExprMatchVisitor(toMatchCmd.Lhss[0].AsExpr); lEmv.VisitExpr(lhs); var rhs = cmd.Rhss[i]; var rEmv = new ExprMatchVisitor(toMatchCmd.Rhss[0]); rEmv.VisitExpr(rhs); if (lEmv.Matches && rEmv.Matches) { foreach (var kvp in lEmv.Substitution) { substitution.Add(kvp.Key, kvp.Value); } foreach (var kvp in lEmv.FunctionSubstitution) { funcSubstitution.Add(kvp.Key, kvp.Value); } foreach (var kvp in rEmv.Substitution) { substitution.Add(kvp.Key, kvp.Value); } foreach (var kvp in rEmv.FunctionSubstitution) { funcSubstitution.Add(kvp.Key, kvp.Value); } substitutions = new List <Tuple <Dictionary <Declaration, Expr>, Dictionary <string, IAppliable> > >() { new Tuple <Dictionary <Declaration, Expr>, Dictionary <string, IAppliable> >(substitution, funcSubstitution) }; match = true; break; } } return(match); }
private bool MatchCallCmd(CallCmd cmd, CmdRule rule, CallCmd toMatch, out List <Tuple <Dictionary <Declaration, Expr>, Dictionary <string, IAppliable> > > substitutions) { // question: why do we have a list of substitutions, here? // answer: the reason (right now) is AnyArgs: many arguments may match, the current semantics // is that we want to make the insertion for every match (example: memory accesses) substitutions = new List <Tuple <Dictionary <Declaration, Expr>, Dictionary <string, IAppliable> > >(); #region match procedure name //if (toMatch.callee == BoogieKeyWords.AnyProcedure) var matchCallee = rule.Prog.Procedures.FirstOrDefault(p => p.Name == toMatch.callee); if (matchCallee != null) { // procedure is declared in TemplateVariables if (matchCallee.HasAttribute(ExprMatchVisitor.BoogieKeyWords.NoImplementation)) { var hasImpl = false; _prog.Implementations .Iter(i => { if (i.Name == cmd.Proc.Name) { hasImpl = true; } }); //no match if (hasImpl) { return(false); } } } else if (toMatch.callee == cmd.Proc.Name) { // procedure matches by name } else { //no match return(false); } #endregion #region match out parameters //if (toMatch.Outs.Count == 1 // && toMatch.Outs[0].Name == BoogieKeyWords.AnyLhss) //{ // //matches anything --> do nothing/go on //} //else if (toMatch.Outs.Count == cmd.Outs.Count) { //TODO.. --> match, make substitution.. } else { //TODO.. --> match, make substitution.. } #endregion #region match arguments if (matchCallee != null && BoogieUtil.checkAttrExists(ExprMatchVisitor.BoogieKeyWords.AnyArgs, matchCallee.Attributes)) { //var anyArgsExpr = (NAryExpr) toMatch.Ins[0]; var anyArgsExpr = toMatch.Ins[0]; var atLeastOneMatch = false; foreach (var argCombo in cmd.Ins.Zip(cmd.Proc.InParams, Tuple.Create)) { var cmdArg = argCombo.Item1; var procArg = argCombo.Item2; // also match param type and attribute if (procArg.TypedIdent.Type.Equals(matchCallee.InParams[0].TypedIdent.Type) && ExprMatchVisitor.AreAttributesASubset(matchCallee.InParams[0].Attributes, procArg.Attributes)) { var emv = new ExprMatchVisitor(anyArgsExpr); emv.VisitExpr(cmdArg); if (emv.Matches) { atLeastOneMatch = true; substitutions.Add( new Tuple <Dictionary <Declaration, Expr>, Dictionary <string, IAppliable> >( emv.Substitution, emv.FunctionSubstitution)); } } } if (!atLeastOneMatch) { return(false); } } else { if (toMatch.Ins.Count != cmd.Ins.Count) { return(false); } for (var i = 0; i < cmd.Ins.Count; i++) { var arg = cmd.Ins[i]; var emv = new ExprMatchVisitor(toMatch.Ins[i]); emv.VisitExpr(arg); if (emv.Matches) { if (substitutions.Count == 0) { substitutions.Add(new Tuple <Dictionary <Declaration, Expr>, Dictionary <string, IAppliable> >(new Dictionary <Declaration, Expr>(), new Dictionary <string, IAppliable>())); } foreach (var kvp in emv.Substitution) { substitutions.First().Item1.Add(kvp.Key, kvp.Value); } foreach (var kvp in emv.FunctionSubstitution) { substitutions.First().Item2.Add(kvp.Key, kvp.Value); } } else { return(false); } } } #endregion return(true); }