Exemple #1
0
 internal QuantifiersCollection(ComprehensionExpr expr, IEnumerable <ComprehensionExpr> quantifiers, ErrorReporter reporter)
 {
     Contract.Requires(quantifiers.All(q => !(q is QuantifierExpr) || ((QuantifierExpr)q).SplitQuantifier == null));
     this.reporter    = reporter;
     this.expr        = expr;
     this.quantifiers = quantifiers.Select(q => new QuantifierWithTriggers(q)).ToList();
 }
Exemple #2
0
        private static bool AllowsSplitting(ComprehensionExpr quantifier)
        {
            // allow split if attributes doesn't contains "split" or it is "split: true" and it is not an empty QuantifierExpr (boundvar.count>0)
            bool splitAttr = true;

            return((!Attributes.ContainsBool(quantifier.Attributes, "split", ref splitAttr) || splitAttr) && (quantifier.BoundVars.Count > 0));
        }
Exemple #3
0
        private static bool ShallowEq(ComprehensionExpr expr1, ComprehensionExpr expr2)
        {
            if (!TriggerUtils.SameLists(expr1.BoundVars, expr2.BoundVars, SameBoundVar) ||
                !ShallowSameAttributes(expr1.Attributes, expr2.Attributes) ||
                // Filled in during resolution: !SameLists(expr1.Bounds, expr2.Bounds, ReferenceCompare) ||
                //                              !SameLists(expr1.MissingBounds, expr2.MissingBounds, SameBoundVar) ||
                !TriggerUtils.SameNullity(expr1.Range, expr2.Range)) //TODO Check
            {
                return(false);
            }

            if (expr1 is LambdaExpr && expr2 is LambdaExpr)
            {
                return(ShallowEq((LambdaExpr)expr1, (LambdaExpr)expr2));
            }
            else if (expr1 is MapComprehension && expr2 is MapComprehension)
            {
                return(ShallowEq((MapComprehension)expr1, (MapComprehension)expr2));
            }
            else if (expr1 is SetComprehension && expr2 is SetComprehension)
            {
                return(ShallowEq((SetComprehension)expr1, (SetComprehension)expr2));
            }
            else if (expr1 is QuantifierExpr && expr2 is QuantifierExpr)
            {
                return(ShallowEq((QuantifierExpr)expr1, (QuantifierExpr)expr2));
            }
            else
            {
                return(false); // ComprehensionExpr is abstract
            }
        }
Exemple #4
0
        internal static bool WantsAutoTriggers(ComprehensionExpr quantifier)
        {
            Contract.Requires(!(quantifier is QuantifierExpr) || ((QuantifierExpr)quantifier).SplitQuantifier == null); // Don't call this on a quantifier with a Split clause: it's not a real quantifier
            bool wantsAutoTriggers = true;

            return(!Attributes.ContainsBool(quantifier.Attributes, "autotriggers", ref wantsAutoTriggers) || wantsAutoTriggers);
        }
Exemple #5
0
        internal static bool WantsMatchingLoopRewrite(ComprehensionExpr quantifier)
        {
            Contract.Requires(!(quantifier is QuantifierExpr) || ((QuantifierExpr)quantifier).SplitQuantifier == null);
            bool wantsMatchingLoopRewrite = true;

            return((!Attributes.ContainsBool(quantifier.Attributes, "matchinglooprewrite", ref wantsMatchingLoopRewrite) || wantsMatchingLoopRewrite) && WantsAutoTriggers(quantifier));
        }
Exemple #6
0
    internal static IEnumerable<Expression> SplitQuantifier(ComprehensionExpr quantifier) {
      var body = quantifier.Term;
      var binary = body as BinaryExpr;

      if (quantifier is ForallExpr) {
        IEnumerable<Expression> stream;
        if (binary != null && (binary.Op == BinaryExpr.Opcode.Imp || binary.Op == BinaryExpr.Opcode.Or)) {
          stream = SplitAndStich(binary, BinaryExpr.Opcode.And);
        } else {
          stream = SplitExpr(body, BinaryExpr.Opcode.And);
        }
        foreach (var e in stream) {
          var tok = new NestedToken(quantifier.tok, e.tok);
          yield return new ForallExpr(tok, ((ForallExpr)quantifier).TypeArgs, quantifier.BoundVars, quantifier.Range, e, CopyAttributes(quantifier.Attributes)) { Type = quantifier.Type };
        }
      } else if (quantifier is ExistsExpr) {
        IEnumerable<Expression> stream;
        if (binary != null && binary.Op == BinaryExpr.Opcode.And) {
          stream = SplitAndStich(binary, BinaryExpr.Opcode.Or);
        } else {
          stream = SplitExpr(body, BinaryExpr.Opcode.Or);
        }
        foreach (var e in stream) {
          var tok = new NestedToken(quantifier.tok, e.tok);
          yield return new ExistsExpr(tok, ((ExistsExpr)quantifier).TypeArgs, quantifier.BoundVars, quantifier.Range, e, CopyAttributes(quantifier.Attributes)) { Type = quantifier.Type };
        }
      } else {
        yield return quantifier;
      }
    }
Exemple #7
0
        internal IEnumerable <TriggerMatch> LoopingSubterms(ComprehensionExpr quantifier)
        {
            Contract.Requires(!(quantifier is QuantifierExpr) || ((QuantifierExpr)quantifier).SplitQuantifier == null); // Don't call this on a quantifier with a Split clause: it's not a real quantifier
            var matchingSubterms = this.MatchingSubterms(quantifier);
            var boundVars        = new HashSet <BoundVar>(quantifier.BoundVars);

            return(matchingSubterms.Where(tm => tm.CouldCauseLoops(Terms, boundVars)));
        }
Exemple #8
0
        private Expression QuantifiersToExpression(IToken tok, BinaryExpr.ResolvedOpcode op, List <ComprehensionExpr> expressions)
        {
            var expr = expressions[0].Term;

            for (int i = 1; i < expressions.Count; i++)
            {
                expr = new BinaryExpr(tok, op, expr, expressions[i].Term);
            }
            return(expr);
        }
Exemple #9
0
        internal static IEnumerable <Expression> SplitQuantifier(ComprehensionExpr quantifier)
        {
            var body   = quantifier.Term;
            var binary = body as BinaryExpr;

            if (quantifier is ForallExpr)
            {
                IEnumerable <Expression> stream;
                if (binary != null && (binary.Op == BinaryExpr.Opcode.Imp || binary.Op == BinaryExpr.Opcode.Or))
                {
                    stream = SplitAndStich(binary, BinaryExpr.Opcode.And);
                }
                else
                {
                    stream = SplitExpr(body, BinaryExpr.Opcode.And);
                }
                foreach (var e in stream)
                {
                    var tok = new NestedToken(quantifier.tok, e.tok);
                    yield return(new ForallExpr(tok, ((ForallExpr)quantifier).TypeArgs, quantifier.BoundVars, quantifier.Range, e, TriggerUtils.CopyAttributes(quantifier.Attributes))
                    {
                        Type = quantifier.Type
                    });
                }
            }
            else if (quantifier is ExistsExpr)
            {
                IEnumerable <Expression> stream;
                if (binary != null && binary.Op == BinaryExpr.Opcode.And)
                {
                    stream = SplitAndStich(binary, BinaryExpr.Opcode.Or);
                }
                else
                {
                    stream = SplitExpr(body, BinaryExpr.Opcode.Or);
                }
                foreach (var e in stream)
                {
                    var tok = new NestedToken(quantifier.tok, e.tok);
                    yield return(new ExistsExpr(tok, ((ExistsExpr)quantifier).TypeArgs, quantifier.BoundVars, quantifier.Range, e, TriggerUtils.CopyAttributes(quantifier.Attributes))
                    {
                        Type = quantifier.Type
                    });
                }
            }
            else
            {
                yield return(quantifier);
            }
        }
Exemple #10
0
        private void ExprVars(Expression e)
        {
            Contract.Requires(_vars != null);
            Contract.Requires(e != null);

            var expr = e as ComprehensionExpr;

            if (expr != null)
            {
                ComprehensionExpr c = expr;
                foreach (BoundVar bv in c.BoundVars)
                {
                    _vars.Add(bv.Name);
                }
            }
        }
Exemple #11
0
        public override void Visit(ComprehensionExpr o)
        {
            var    name     = "bounded-expression-ghost-" + o.tok.line;
            IToken endToken = new Token(o.tok.line, int.MaxValue - 1024);

            var symbol = CreateSymbol(
                name: name,
                kind: Kind.BlockScope,

                positionAsToken: o.tok,
                bodyStartPosAsToken: o.tok,
                bodyEndPosAsToken: endToken,

                isDeclaration: true,
                declarationSymbol: null,
                addUsageAtDeclaration: false,

                canHaveChildren: true,
                canBeUsed: false
                );

            SetScope(symbol);
        }
Exemple #12
0
 /// <summary>
 /// Collect terms in the body of the subexpressions of the argument that look like quantifiers. The results of this function can contain duplicate terms.
 /// </summary>
 internal List <TriggerTerm> CollectTriggers(ComprehensionExpr quantifier)
 {
     Contract.Requires(!(quantifier is QuantifierExpr) || ((QuantifierExpr)quantifier).SplitQuantifier == null); // Don't call this on a quantifier with a Split clause: it's not a real quantifier
     // NOTE: We could check for existing trigger attributes and return that instead
     return(Annotate(quantifier).PrivateTerms);
 }
Exemple #13
0
        private TriggerAnnotation AnnotateComprehensionExpr(ComprehensionExpr expr)
        {
            var terms = CollectExportedCandidates(expr);

            return(new TriggerAnnotation(true, CollectVariables(expr), terms, OnlyPrivateCandidates(terms, expr.BoundVars)));
        }
Exemple #14
0
 internal List <TriggerMatch> MatchingSubterms(ComprehensionExpr quantifier)
 {
     Contract.Requires(!(quantifier is QuantifierExpr) || ((QuantifierExpr)quantifier).SplitQuantifier == null); // Don't call this on a quantifier with a Split clause: it's not a real quantifier
     return(Terms.SelectMany(term => quantifier.SubexpressionsMatchingTrigger(term.Expr)).Deduplicate(TriggerMatch.Eq));
 }
Exemple #15
0
 internal static bool NeedsAutoTriggers(ComprehensionExpr quantifier)
 {
     Contract.Requires(!(quantifier is QuantifierExpr) || ((QuantifierExpr)quantifier).SplitQuantifier == null); // Don't call this on a quantifier with a Split clause: it's not a real quantifier
     return(!Attributes.Contains(quantifier.Attributes, "trigger") && WantsAutoTriggers(quantifier));
 }
 public override void Visit(ComprehensionExpr o)
 {
 }
Exemple #17
0
 internal static bool AllowsMatchingLoops(ComprehensionExpr quantifier)
 {
     Contract.Requires(!(quantifier is QuantifierExpr) || ((QuantifierExpr)quantifier).SplitQuantifier == null); // Don't call this on a quantifier with a Split clause: it's not a real quantifier
     // This is different from nowarn: it won't remove loops at all, even if another trigger is available.
     return(Attributes.Contains(quantifier.Attributes, "matchingloop"));
 }
 public override void Leave(ComprehensionExpr o)
 {
 }
Exemple #19
0
 internal static IEnumerable <TriggerMatch> SubexpressionsMatchingTrigger(this ComprehensionExpr quantifier, Expression trigger)
 {
     return(quantifier.AllSubExpressions(true, true, true)
            .Select(e => TriggerUtils.PrepareExprForInclusionInTrigger(e).MatchAgainst(trigger, quantifier.BoundVars, e))
            .Where(e => e.HasValue).Select(e => e.Value));
 }
Exemple #20
0
 public override void Leave(ComprehensionExpr o)
 {
     JumpUpInScope();
 }
Exemple #21
0
 internal QuantifierWithTriggers(ComprehensionExpr quantifier)
 {
     this.quantifier         = quantifier;
     this.RejectedCandidates = new List <TriggerCandidate>();
 }
 public virtual void Visit(ComprehensionExpr comprehensionExpression)
 {
 }
Exemple #23
0
 private static bool AllowsSplitting(ComprehensionExpr quantifier) {
   // allow split if attributes doesn't contains "split" or it is "split: true" and it is not an empty ComprehensionExpr (boundvar.count>0)
   bool splitAttr = true; 
   return (!Attributes.ContainsBool(quantifier.Attributes, "split", ref splitAttr) || splitAttr) && (quantifier.BoundVars.Count > 0);
 }