public QuantifierExpr RewriteMatchingLoops(QuantifierWithTriggers q)
        {
            // rewrite quantifier to avoid matching loops
            // before:
            //    assert forall i :: 0 <= i < a.Length-1 ==> a[i] <= a[i+1];
            // after:
            //    assert forall i,j :: j == i+1 ==> 0 <= i < a.Length-1 ==> a[i] <= a[j];
            substMap = new List <Tuple <Expression, IdentifierExpr> >();
            foreach (var m in q.LoopingMatches)
            {
                var e = m.OriginalExpr;
                if (TriggersCollector.IsPotentialTriggerCandidate(e) && triggersCollector.IsTriggerKiller(e))
                {
                    foreach (var sub in e.SubExpressions)
                    {
                        if (triggersCollector.IsTriggerKiller(sub) && (!TriggersCollector.IsPotentialTriggerCandidate(sub)))
                        {
                            var entry = substMap.Find(x => ExprExtensions.ExpressionEq(sub, x.Item1));
                            if (entry == null)
                            {
                                var newBv = new BoundVar(sub.tok, "_t#" + substMap.Count, sub.Type);
                                var ie    = new IdentifierExpr(sub.tok, newBv.Name);
                                ie.Var  = newBv;
                                ie.Type = newBv.Type;
                                substMap.Add(new Tuple <Expression, IdentifierExpr>(sub, ie));
                            }
                        }
                    }
                }
            }

            var expr = (QuantifierExpr)q.quantifier;

            if (substMap.Count > 0)
            {
                var s = new Translator.ExprSubstituter(substMap);
                expr = s.Substitute(q.quantifier) as QuantifierExpr;
            }
            else
            {
                // make a copy of the expr
                if (expr is ForallExpr)
                {
                    expr = new ForallExpr(expr.tok, expr.TypeArgs, expr.BoundVars, expr.Range, expr.Term, TriggerUtils.CopyAttributes(expr.Attributes))
                    {
                        Type = expr.Type, Bounds = expr.Bounds
                    };
                }
                else
                {
                    expr = new ExistsExpr(expr.tok, expr.TypeArgs, expr.BoundVars, expr.Range, expr.Term, TriggerUtils.CopyAttributes(expr.Attributes))
                    {
                        Type = expr.Type, Bounds = expr.Bounds
                    };
                }
            }
            return(expr);
        }
Example #2
0
 void CollectWithoutShareTriggers(TriggersCollector triggersCollector)
 {
     foreach (var q in quantifiers)
     {
         var candidates = triggersCollector.CollectTriggers(q.quantifier).Deduplicate(TriggerTerm.Eq);
         q.CandidateTerms = candidates; // The list of candidate terms is immutable
         q.Candidates     = TriggerUtils.AllNonEmptySubsets(candidates, SubsetGenerationPredicate, q.quantifier.BoundVars).Select(set => set.ToTriggerCandidate()).ToList();
     }
 }
Example #3
0
 internal void ComputeTriggers(TriggersCollector triggersCollector)
 {
     CollectAndShareTriggers(triggersCollector);
     TrimInvalidTriggers();
     BuildDependenciesGraph();
     if (SuppressMatchingLoops() && RewriteMatchingLoop())
     {
         CollectWithoutShareTriggers(triggersCollector);
         TrimInvalidTriggers();
         SuppressMatchingLoops();
     }
     SelectTriggers();
     CombineSplitQuantifier();
 }
Example #4
0
        /// <summary>
        /// Collect triggers from the body of each quantifier, and share them
        /// between all quantifiers. This method assumes that all quantifiers
        /// actually come from the same context, and were the result of a split that
        /// gave them all the same variables.
        /// </summary>
        /// <param name="triggersCollector"></param>
        void CollectAndShareTriggers(TriggersCollector triggersCollector)
        {
            List <TriggerTerm> pool = new List <TriggerTerm>();

            foreach (var q in quantifiers)
            {
                var candidates = triggersCollector.CollectTriggers(q.quantifier).Deduplicate(TriggerTerm.Eq);
                // filter out the candidates that was "second-class"
                var filtered = TriggerUtils.Filter(candidates, tr => tr, (tr, _) => !tr.IsTranslatedToFunctionCall(), (tr, _) => { }).ToList();
                // if there are only "second-class" candidates, add them back.
                if (filtered.Count == 0)
                {
                    filtered = candidates;
                }
                pool.AddRange(filtered);
            }
            var distinctPool = pool.Deduplicate(TriggerTerm.Eq);

            foreach (var q in quantifiers)
            {
                q.CandidateTerms = distinctPool; // The list of candidate terms is immutable
                q.Candidates     = TriggerUtils.AllNonEmptySubsets(distinctPool, SubsetGenerationPredicate, q.quantifier.BoundVars).Select(set => set.ToTriggerCandidate()).ToList();
            }
        }
Example #5
0
 internal bool IsTranslatedToFunctionCall()
 {
     return((TriggersCollector.TranslateToFunctionCall(this.Expr)) ? true : false);
 }