Example #1
0
        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);
        }
Example #2
0
        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);
        }
Example #3
0
        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);
        }