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 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); }
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); }
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)); } } }
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); }