예제 #1
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);
    }
예제 #2
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;
   }
 }
예제 #3
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);
            }
예제 #4
0
        private TriggerAnnotation AnnotatePotentialCandidate(Expression expr)
        {
            bool expr_is_killer = false;
            var  new_expr       = TriggerUtils.MaybeWrapInOld(TriggerUtils.PrepareExprForInclusionInTrigger(expr, out expr_is_killer), cache.exprsInOldContext.Contains(expr));
            var  new_term       = new TriggerTerm {
                Expr = new_expr, OriginalExpr = expr, Variables = CollectVariables(expr)
            };

            List <TriggerTerm> collected_terms = CollectExportedCandidates(expr);
            var 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);
            }

            // 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));
        }
예제 #5
0
 internal static bool Eq(TriggerTerm t1, TriggerTerm t2)
 {
     return(ExprExtensions.ExpressionEq(t1.Expr, t2.Expr));
 }
예제 #6
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();
 }