示例#1
0
 internal TermComparison CompareTo(TriggerTerm other)
 {
     if (this == other)
     {
         return(TermComparison.SameStrength);
     }
     else if (Expr.AllSubExpressions(true, true).Any(other.Expr.ExpressionEq))
     {
         return(TermComparison.Stronger);
     }
     else
     {
         return(TermComparison.NotStronger);
     }
 }
示例#2
0
            /// <summary>
            /// Simple formulas like [P0(i) && P1(i) && P2(i) && P3(i) && P4(i)] yield very
            /// large numbers of multi-triggers, most of which are useless. As it copies its
            /// argument, this method updates various datastructures that allow it to
            /// efficiently track ownership relations between formulae and bound variables,
            /// and sets the IsRedundant flag of the returned set, allowing the caller to
            /// discard that set of terms, and the ones that would have been built on top of
            /// it, thus ensuring that the only sets of terms produced in the end are sets
            /// of terms in which each element contributes (owns) at least one variable.
            ///
            /// Note that this is trickier than just checking every term for new variables;
            /// indeed, a new term that does bring new variables in can make an existing
            /// term redundant (see redundancy-detection-does-its-job-properly.dfy).
            /// </summary>
            internal SetOfTerms CopyWithAdd(TriggerTerm term, ISet <BoundVar> relevantVariables)
            {
                var copy = new SetOfTerms();

                copy.Terms                  = new List <TriggerTerm>(Terms);
                copy.variables              = new HashSet <BoundVar>(variables);
                copy.termOwningAUniqueVar   = new Dictionary <BoundVar, TriggerTerm>(termOwningAUniqueVar);
                copy.uniqueVarsOwnedByATerm = new Dictionary <TriggerTerm, ISet <BoundVar> >(uniqueVarsOwnedByATerm);

                copy.Terms.Add(term);

                var varsInNewTerm = new HashSet <BoundVar>(term.BoundVars);

                varsInNewTerm.IntersectWith(relevantVariables);

                var ownedByNewTerm = new HashSet <BoundVar>();

                // Check #0: does this term bring anything new?
                copy.IsRedundant = IsRedundant || varsInNewTerm.All(bv => copy.variables.Contains(bv));
                copy.variables.UnionWith(varsInNewTerm);

                // Check #1: does this term claiming ownership of all its variables cause another term to become useless?
                foreach (var v in varsInNewTerm)
                {
                    TriggerTerm originalOwner;
                    if (copy.termOwningAUniqueVar.TryGetValue(v, out originalOwner))
                    {
                        var alsoOwnedByOriginalOwner = copy.uniqueVarsOwnedByATerm[originalOwner];
                        alsoOwnedByOriginalOwner.Remove(v);
                        if (!alsoOwnedByOriginalOwner.Any())
                        {
                            copy.IsRedundant = true;
                        }
                    }
                    else
                    {
                        ownedByNewTerm.Add(v);
                        copy.termOwningAUniqueVar[v] = term;
                    }
                }

                // Actually claim ownership
                copy.uniqueVarsOwnedByATerm[term] = ownedByNewTerm;

                return(copy);
            }
示例#3
0
        private TriggerAnnotation AnnotatePotentialCandidate(Expression expr)
        {
            bool expr_is_killer = false;
            HashSet <OldExpr> oldExprSet;

            if (cache.exprsInOldContext.TryGetValue(expr, out oldExprSet))
            {
                // oldExpr has been set to the value found
            }
            else
            {
                oldExprSet = null;
            }
            var new_exprs = TriggerUtils.MaybeWrapInOld(TriggerUtils.PrepareExprForInclusionInTrigger(expr, out expr_is_killer), oldExprSet);
            // We expect there to be at least one "new_exprs".
            // We also expect that the computation of new_term.Variables, collected_terms, and children_contain_killers will be the
            // same for each of the "new_exprs".
            // Therefore, we use the values of these variables from the last iteration in the expression that is ultimately returned.
            TriggerTerm        new_term        = null;
            List <TriggerTerm> collected_terms = null;
            var children_contain_killers       = false;

            foreach (var new_expr in new_exprs)
            {
                new_term = new TriggerTerm {
                    Expr = new_expr, OriginalExpr = expr, Variables = CollectVariables(expr)
                };

                collected_terms          = CollectExportedCandidates(expr);
                children_contain_killers = CollectIsKiller(expr);

                if (!children_contain_killers)
                {
                    // Add only if the children are not killers; the head has been cleaned up into non-killer form
                    collected_terms.Add(new_term);
                }
            }
            Contract.Assert(new_term != null); // this checks our assumption that "new_exprs" contains at least one value.

            // This new node is a killer if its children were killers, or if it's non-cleaned-up head is a killer
            return(new TriggerAnnotation(children_contain_killers || expr_is_killer, new_term.Variables, collected_terms));
        }
示例#4
0
 internal static bool Eq(TriggerTerm t1, TriggerTerm t2)
 {
     return(ExprExtensions.ExpressionEq(t1.Expr, t2.Expr));
 }
示例#5
0
 private bool SubsetGenerationPredicate(TriggerUtils.SetOfTerms terms, TriggerTerm additionalTerm)
 {
     return(true); // FIXME Remove this
     //return additionalTerm.Variables.Where(v => v is BoundVar && !terms.Any(t => t.Variables.Contains(v))).Any();
 }