Esempio n. 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);
        }
Esempio n. 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);
        }
Esempio n. 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);
        }
Esempio n. 4
0
        private static void InjectCode(Implementation impl, int anyParamsPosition, QKeyValue anyParamsAttributes, int anyParamsPositionOut, QKeyValue anyParamsAttributesOut,
                                       Implementation procSig, InsertAtBeginningRule rule, Dictionary <Declaration, Expr> paramSubstitution)
        {
            //TODO handle anyParams in the OutParam case
            var doesAnyParamOccurInRhs = false;

            if (anyParamsPosition != int.MaxValue)
            {
                var anyParam = procSig.InParams[anyParamsPosition];
                var oiv      = new OccursInVisitor(anyParam);
                oiv.VisitCmdSeq(rule.ProcedureToMatchToInsertion[procSig]);
                doesAnyParamOccurInRhs = oiv.Success;
            }

            if (doesAnyParamOccurInRhs)
            {
                for (int i = anyParamsPosition; i < impl.InParams.Count; i++)
                {
                    var p = impl.InParams[i];
                    // If attributes for the ##anyparams in the toMatch are given, we only insert code for those parameters of impl
                    // with matching (subset) attributes
                    // we look both in the implementation's and the procedure declaration's signature
                    if (anyParamsAttributes == null ||
                        ExprMatchVisitor.AreAttributesASubset(anyParamsAttributes, impl.Proc.InParams[i].Attributes))
                    {
                        if (!procSig.InParams[anyParamsPosition].TypedIdent.Type.Equals(p.TypedIdent.Type))
                        {
                            continue; //skip parameters that don't match type
                        }
                        var id           = new IdentifierExpr(Token.NoToken, p.Name, p.TypedIdent.Type, true);
                        var substitution = new Dictionary <Declaration, Expr> {
                            { procSig.InParams[anyParamsPosition], id }
                        };
                        foreach (var kvp in paramSubstitution)
                        {
                            substitution.Add(kvp.Key, kvp.Value);
                        }

                        var sv      = new SubstitionVisitor(substitution);
                        var newCmds = sv.VisitCmdSeq(rule.ProcedureToMatchToInsertion[procSig]);
                        if (impl.Blocks.Count > 0 && !QKeyValue.FindBoolAttribute(procSig.Attributes, ExprMatchVisitor.BoogieKeyWords.ReplaceImplementation))
                        {
                            impl.Blocks.Insert(0,
                                               BoogieAstFactory.MkBlock(newCmds,
                                                                        BoogieAstFactory.MkGotoCmd(impl.Blocks.First().Label)));
                        }
                        else
                        {
                            impl.Blocks = new List <Block>();
                            impl.Blocks.Add(
                                BoogieAstFactory.MkBlock(newCmds));
                        }
                    }
                }
            }
            else
            {
                var sv      = new SubstitionVisitor(paramSubstitution);
                var newCmds = sv.VisitCmdSeq(rule.ProcedureToMatchToInsertion[procSig]);
                if (impl.Blocks.Count > 0 && !QKeyValue.FindBoolAttribute(procSig.Attributes, ExprMatchVisitor.BoogieKeyWords.ReplaceImplementation))
                {
                    impl.Blocks.Insert(0,
                                       BoogieAstFactory.MkBlock(newCmds,
                                                                BoogieAstFactory.MkGotoCmd(impl.Blocks.First().Label)));
                }
                else
                {
                    impl.Blocks = new List <Block>();
                    impl.Blocks.Add(
                        BoogieAstFactory.MkBlock(newCmds));
                }
            }
        }
Esempio n. 5
0
        public static bool MatchSig(Implementation toMatch, DeclWithFormals dwf, Program boogieProgram, out QKeyValue toMatchAnyParamsAttributes, out int anyParamsPosition, out QKeyValue toMatchAnyParamsAttributesOut, out int anyParamsPositionOut, out Dictionary <Declaration, Expr> paramSubstitution)
        {
            toMatchAnyParamsAttributes    = null;
            anyParamsPosition             = int.MaxValue;
            toMatchAnyParamsAttributesOut = null;
            anyParamsPositionOut          = int.MaxValue;
            paramSubstitution             = new Dictionary <Declaration, Expr>();

            if (!ExprMatchVisitor.AreAttributesASubset(toMatch.Attributes, dwf.Attributes))
            {
                return(false);
            }

            // match procedure name

            if (BoogieUtil.checkAttrExists(ExprMatchVisitor.BoogieKeyWords.AnyProcedure, toMatch.Attributes))
            {
                //do nothing
            }
            else if (BoogieUtil.checkAttrExists(ExprMatchVisitor.BoogieKeyWords.NameMatches, toMatch.Attributes))
            {
                var nmAttrParams = BoogieUtil.getAttr(ExprMatchVisitor.BoogieKeyWords.NameMatches, toMatch.Attributes);
                var regex        = nmAttrParams.First().ToString();
                var m            = Regex.Match(dwf.Name, regex);
                if (m.Success)
                {
                    //do nothing
                }
                else
                {
                    return(false);
                }
            }
            else if (toMatch.Name != dwf.Name)
            {
                return(false);
            }

            // if the procedure name is matched, it may still be that we are looking only for stubs
            if (BoogieUtil.checkAttrExists(ExprMatchVisitor.BoogieKeyWords.NoImplementation, toMatch.Attributes))
            {
                foreach (var i in boogieProgram.Implementations)
                {
                    if (i.Name == dwf.Name)
                    {
                        return(false);
                    }
                }
            }

            if (!MatchParams(ref toMatchAnyParamsAttributes, ref anyParamsPosition, paramSubstitution, toMatch.InParams, toMatch.Proc.InParams, dwf.InParams))
            {
                return(false);
            }

            if (!MatchParams(ref toMatchAnyParamsAttributesOut, ref anyParamsPositionOut, paramSubstitution, toMatch.OutParams, toMatch.Proc.OutParams, dwf.OutParams))
            {
                return(false);
            }

            return(true);
        }
Esempio n. 6
0
        public static bool MatchSig(Implementation toMatch, DeclWithFormals dwf, Program boogieProgram, out QKeyValue toMatchAnyParamsAttributes, out int anyParamsPosition, out QKeyValue toMatchAnyParamsAttributesOut, out int anyParamsPositionOut, out Dictionary <Declaration, Expr> paramSubstitution, bool matchPtrs)
        {
            toMatchAnyParamsAttributes    = null;
            anyParamsPosition             = int.MaxValue;
            toMatchAnyParamsAttributesOut = null;
            anyParamsPositionOut          = int.MaxValue;
            paramSubstitution             = new Dictionary <Declaration, Expr>();

            if (!ExprMatchVisitor.AreAttributesASubset(toMatch.Attributes, dwf.Attributes))
            {
                return(false);
            }

            // match procedure name
            // Positive filters: AnyProcedure, NameMatches, ByName
            if (BoogieUtil.checkAttrExists(ExprMatchVisitor.BoogieKeyWords.AnyProcedure, toMatch.Attributes))
            {
                //do nothing
            }
            else if (BoogieUtil.checkAttrExists(ExprMatchVisitor.BoogieKeyWords.NameMatches, toMatch.Attributes))
            {
                var nmAttrParams = BoogieUtil.getAttr(ExprMatchVisitor.BoogieKeyWords.NameMatches, toMatch.Attributes);
                Debug.Assert(nmAttrParams.Count() == 1, "Expecting exactly one #NameMatches attribute, found " + nmAttrParams.Count());
                var regex = nmAttrParams.First().ToString();
                var m     = Regex.Match(dwf.Name, regex);
                if (m.Success)
                {
                    //do nothing
                }
                else
                {
                    return(false);
                }
            }
            else if (toMatch.Name != dwf.Name)
            {
                return(false);
            }

            //Negative filter: NameNotMatches (can be multiple of them)
            if (BoogieUtil.checkAttrExists(ExprMatchVisitor.BoogieKeyWords.NameNotMatches, toMatch.Attributes))
            {
                //get the params from multiple matching key
                var getAttrRepeated = new Func <QKeyValue, string, IList <IList <object> > >((attr, name) =>
                {
                    var ret = new List <IList <object> >();
                    for (; attr != null; attr = attr.Next)
                    {
                        if (attr.Key == name)
                        {
                            ret.Add(attr.Params);
                        }
                    }
                    return(ret);
                });

                var nmAttrParams = getAttrRepeated(toMatch.Attributes, ExprMatchVisitor.BoogieKeyWords.NameNotMatches);
                foreach (var nm in nmAttrParams)
                {
                    if (Regex.Match(dwf.Name, nm.First().ToString()).Success)
                    {
                        return(false);
                    }
                }
            }

            // if the procedure name is matched, it may still be that we are looking only for stubs
            if (BoogieUtil.checkAttrExists(ExprMatchVisitor.BoogieKeyWords.NoImplementation, toMatch.Attributes))
            {
                foreach (var i in boogieProgram.Implementations)
                {
                    if (i.Name == dwf.Name)
                    {
                        return(false);
                    }
                }
            }

            Procedure dwfProc = null;

            if (dwf is Implementation)
            {
                dwfProc = ((Implementation)dwf).Proc;
            }
            else if (dwf is Procedure)
            {
                dwfProc = (Procedure)dwf;
            }

            if (!MatchParams(ref toMatchAnyParamsAttributes, ref anyParamsPosition, paramSubstitution, toMatch.InParams, toMatch.Proc.InParams, dwf.InParams, dwfProc.InParams, matchPtrs))
            {
                return(false);
            }

            if (!MatchParams(ref toMatchAnyParamsAttributesOut, ref anyParamsPositionOut, paramSubstitution, toMatch.OutParams, toMatch.Proc.OutParams, dwf.OutParams, dwfProc.OutParams, matchPtrs))
            {
                return(false);
            }

            return(true);
        }