public QuantifierExpr RewriteMatchingLoops(QuantifierWithTriggers q) { // rewrite quantifier to avoid mathing 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[i+1]; substMap = new Dictionary <Expression, IdentifierExpr>(); usedMap = new Dictionary <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))) { IdentifierExpr ie; if (!substMap.TryGetValue(sub, out ie)) { var newBv = new BoundVar(sub.tok, "_t#" + substMap.Count, sub.Type); ie = new IdentifierExpr(sub.tok, newBv.Name); ie.Var = newBv; ie.Type = newBv.Type; substMap[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 }; } else { expr = new ExistsExpr(expr.tok, expr.TypeArgs, expr.BoundVars, expr.Range, expr.Term, TriggerUtils.CopyAttributes(expr.Attributes)) { Type = expr.Type }; } } return(expr); }
internal void ComputeTriggers(TriggersCollector triggersCollector) { CollectAndShareTriggers(triggersCollector); TrimInvalidTriggers(); BuildDependenciesGraph(); SuppressMatchingLoops(); SelectTriggers(); }
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 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); }
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(); } }
/// <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) { var pool = quantifiers.SelectMany(q => triggersCollector.CollectTriggers(q.quantifier)); 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(); } }
internal void ComputeTriggers(TriggersCollector triggersCollector) { CollectAndShareTriggers(triggersCollector); TrimInvalidTriggers(); BuildDependenciesGraph(); if (SuppressMatchingLoops() && RewriteMatchingLoop()) { CollectWithoutShareTriggers(triggersCollector); TrimInvalidTriggers(); SuppressMatchingLoops(); } SelectTriggers(); CombineSplitQuantifier(); }
/// <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(); } }
internal bool IsTranslatedToFunctionCall() { return((TriggersCollector.TranslateToFunctionCall(this.Expr)) ? true : false); }