Example #1
0
        public override void ComputeFreeVariables(Set freeVars)
        {
            //Contract.Requires(freeVars != null);

            foreach (var e in Rhss)
            {
                e.ComputeFreeVariables(freeVars);
            }

            foreach (var v in Dummies)
            {
                Contract.Assert(v != null);
                Contract.Assert(!freeVars[v]);
            }

            foreach (var v in Dummies)
            {
                freeVars.AddRange(v.TypedIdent.Type.FreeVariables);
            }

            for (var a = Attributes; a != null; a = a.Next)
            {
                foreach (var o in a.Params)
                {
                    var e = o as Expr;
                    if (e != null)
                    {
                        e.ComputeFreeVariables(freeVars);
                    }
                }
            }

            Body.ComputeFreeVariables(freeVars);
            freeVars.RemoveRange(Dummies);
        }
Example #2
0
 /// <summary>
 /// Add to "freeVars" the free variables in the triggering expressions.
 /// </summary>
 public void ComputeFreeVariables(Set /*Variable*/ freeVars)
 {
     Contract.Requires(freeVars != null);
     foreach (Expr /*!*/ e in this.Tr)
     {
         Contract.Assert(e != null);
         e.ComputeFreeVariables(freeVars);
     }
 }
Example #3
0
    public override Expr VisitOldExpr(OldExpr node)
    {
      Set freeVars = new Set();
      node.Expr.ComputeFreeVariables(freeVars);
      foreach (var v in freeVars)
      {
        // Note, "v" is either a Variable or a TypeVariable
        if (v is Variable)
        {
          FreeOldVars.Add((Variable) v);
        }
      }

      return node; // don't visit subexpressions, since ComputeFreeVariables has already gone through those
    }
Example #4
0
      /// <summary>
      /// Performs lambda lifting (see <see cref="LambdaHelper.ExpandLambdas"/>) by replacing the lambda's
      /// free variables with bound ones.
      /// </summary>
      /// <param name="lambda">A lambda expression
      ///   <code>(lambda x1: T1 ... x_n: T_n :: t)</code>
      /// where <c>t</c> contains the free variables <c>y1</c>, ..., <c>y_m</c>.
      /// </param>
      /// <returns>
      /// <list type="bullet">
      ///   <item>
      ///     A function application <c>f(y1, ..., y_m)</c> where <c>f</c>'s body is defined to be the result of
      ///     replacing the free variables <c>y1</c>, ..., <c>y_m</c> in <c>t</c> with bound variables
      ///     <c>b1</c>, ..., <c>b_m</c>.
      ///   </item>
      ///   <item>
      ///     Adds a definition and axiom for <c>f</c> to <see cref="lambdaFunctions"/> and <see cref="lambdaAxioms"/>.
      ///     Memoizes <c>f</c> as the lifted lambda for <para>lambda</para>.
      ///   </item>
      /// </list>
      /// </returns>
      private Expr LiftLambdaFreeVars(LambdaExpr lambda)
      {
        // We start by getting rid of any use of "old" inside the lambda.  This is done as follows.
        // For each variable "g" occurring inside lambda as "old(... g ...)", create a new name "og".
        // Replace each old occurrence of "g" with "og", removing the enclosing "old" wrappers.
        var oldFinder = new OldFinder();
        oldFinder.Visit(lambda);
        var oldSubst = new Dictionary<Variable, Expr>(); // g -> g0
        var callOldMapping = new Dictionary<Variable, Expr>(); // g0 -> old(g)
        foreach (var v in oldFinder.FreeOldVars)
        {
          var g = v as GlobalVariable;
          if (g != null)
          {
            var g0 = new GlobalVariable(g.tok, new TypedIdent(g.tok, g.TypedIdent.Name + "@old", g.TypedIdent.Type));
            oldSubst.Add(g, new IdentifierExpr(g0.tok, g0));
            callOldMapping.Add(g0, new OldExpr(g0.tok, new IdentifierExpr(g.tok, g)));
          }
        }

        var lambdaBody = Substituter.ApplyReplacingOldExprs(
          Substituter.SubstitutionFromDictionary(new Dictionary<Variable, Expr>()),
          Substituter.SubstitutionFromDictionary(oldSubst),
          lambda.Body);
        var lambdaAttrs = Substituter.ApplyReplacingOldExprs(
          Substituter.SubstitutionFromDictionary(new Dictionary<Variable, Expr>()),
          Substituter.SubstitutionFromDictionary(oldSubst),
          lambda.Attributes);

        if (0 < CommandLineOptions.Clo.VerifySnapshots &&
            QKeyValue.FindStringAttribute(lambdaAttrs, "checksum") == null)
        {
          // Attach a dummy checksum to avoid issues in the dependency analysis.
          var checksumAttr = new QKeyValue(lambda.tok, "checksum", new List<object> {"lambda expression"}, null);
          if (lambdaAttrs == null)
          {
            lambdaAttrs = checksumAttr;
          }
          else
          {
            lambdaAttrs.AddLast(checksumAttr);
          }
        }

        // this is ugly, the output will depend on hashing order
        var subst = new Dictionary<Variable, Expr>();
        var substFnAttrs = new Dictionary<Variable, Expr>();
        var formals = new List<Variable>();
        var callArgs = new List<Expr>();
        var axCallArgs = new List<Expr>();
        var dummies = new List<Variable>(lambda.Dummies);
        var freeTypeVars = new List<TypeVariable>();
        var fnTypeVarActuals = new List<Type /*!*/>();
        var freshTypeVars = new List<TypeVariable>(); // these are only used in the lambda@n function's definition

        // compute the free variables of the lambda expression, but with lambdaBody instead of lambda.Body
        Set freeVars = new Set();
        BinderExpr.ComputeBinderFreeVariables(lambda.TypeParameters, lambda.Dummies, lambdaBody, null, lambdaAttrs,
          freeVars);

        foreach (object o in freeVars)
        {
          // 'o' is either a Variable or a TypeVariable.
          if (o is Variable)
          {
            var v = o as Variable;
            var ti = new TypedIdent(v.TypedIdent.tok, v.TypedIdent.Name, v.TypedIdent.Type);
            var f = new Formal(v.tok, ti, true);
            formals.Add(f);
            substFnAttrs.Add(v, new IdentifierExpr(f.tok, f));
            var b = new BoundVariable(v.tok, ti);
            dummies.Add(b);
            if (callOldMapping.ContainsKey(v))
            {
              callArgs.Add(callOldMapping[v]);
            }
            else
            {
              callArgs.Add(new IdentifierExpr(v.tok, v));
            }

            Expr id = new IdentifierExpr(b.tok, b);
            subst.Add(v, id);
            axCallArgs.Add(id);
          }
          else
          {
            var tv = (TypeVariable) o;
            freeTypeVars.Add(tv);
            fnTypeVarActuals.Add(tv);
            freshTypeVars.Add(new TypeVariable(tv.tok, tv.Name));
          }
        }

        var sw = new System.IO.StringWriter();
        var wr = new TokenTextWriter(sw, true);
        lambda.Emit(wr);
        string lam_str = sw.ToString();

        FunctionCall fcall;
        IToken tok = lambda.tok;
        Formal res = new Formal(tok, new TypedIdent(tok, TypedIdent.NoName, cce.NonNull(lambda.Type)), false);

        if (liftedLambdas.TryGetValue(lambda, out fcall))
        {
          if (CommandLineOptions.Clo.TraceVerify)
          {
            Console.WriteLine("Old lambda: {0}", lam_str);
          }
        }
        else
        {
          if (CommandLineOptions.Clo.TraceVerify)
          {
            Console.WriteLine("New lambda: {0}", lam_str);
          }

          Function fn = new Function(tok, FreshLambdaFunctionName(), freshTypeVars, formals, res,
            "auto-generated lambda function",
            Substituter.Apply(Substituter.SubstitutionFromDictionary(substFnAttrs), lambdaAttrs));
          fn.OriginalLambdaExprAsString = lam_str;

          fcall = new FunctionCall(new IdentifierExpr(tok, fn.Name));
          fcall.Func = fn; // resolve here
          liftedLambdas[lambda] = fcall;

          List<Expr /*!*/> selectArgs = new List<Expr /*!*/>();
          foreach (Variable /*!*/ v in lambda.Dummies)
          {
            Contract.Assert(v != null);
            selectArgs.Add(new IdentifierExpr(v.tok, v));
          }

          NAryExpr axcall = new NAryExpr(tok, fcall, axCallArgs);
          axcall.Type = res.TypedIdent.Type;
          axcall.TypeParameters = SimpleTypeParamInstantiation.From(freeTypeVars, fnTypeVarActuals);
          NAryExpr select = Expr.Select(axcall, selectArgs);
          select.Type = lambdaBody.Type;
          List<Type /*!*/> selectTypeParamActuals = new List<Type /*!*/>();
          List<TypeVariable> forallTypeVariables = new List<TypeVariable>();
          foreach (TypeVariable /*!*/ tp in lambda.TypeParameters)
          {
            Contract.Assert(tp != null);
            selectTypeParamActuals.Add(tp);
            forallTypeVariables.Add(tp);
          }

          forallTypeVariables.AddRange(freeTypeVars);
          select.TypeParameters = SimpleTypeParamInstantiation.From(lambda.TypeParameters, selectTypeParamActuals);

          Expr bb = Substituter.Apply(Substituter.SubstitutionFromDictionary(subst), lambdaBody);
          NAryExpr body = Expr.Eq(select, bb);
          body.Type = Type.Bool;
          body.TypeParameters = SimpleTypeParamInstantiation.EMPTY;
          Trigger trig = new Trigger(select.tok, true, new List<Expr> {select});

          lambdaFunctions.Add(fn);
          lambdaAxioms.Add(new ForallExpr(tok, forallTypeVariables, dummies,
            Substituter.Apply(Substituter.SubstitutionFromDictionary(subst), lambdaAttrs),
            trig, body));
        }

        NAryExpr call = new NAryExpr(tok, fcall, callArgs);
        call.Type = res.TypedIdent.Type;
        call.TypeParameters = SimpleTypeParamInstantiation.From(freeTypeVars, fnTypeVarActuals);

        return call;
      }
Example #5
0
        public static void ComputeBinderFreeVariables(List <TypeVariable> typeParameters, List <Variable> dummies, Expr body,
                                                      Trigger triggers, QKeyValue attributes, Set freeVars)
        {
            Contract.Requires(dummies != null);
            Contract.Requires(body != null);

            foreach (var v in dummies)
            {
                Contract.Assert(v != null);
                Contract.Assert(!freeVars[v]);
            }

            body.ComputeFreeVariables(freeVars);
            for (var trig = triggers; trig != null; trig = trig.Next)
            {
                foreach (var e in trig.Tr)
                {
                    e.ComputeFreeVariables(freeVars);
                }
            }

            for (var a = attributes; a != null; a = a.Next)
            {
                foreach (var o in a.Params)
                {
                    var e = o as Expr;
                    if (e != null)
                    {
                        e.ComputeFreeVariables(freeVars);
                    }
                }
            }

            foreach (var v in dummies)
            {
                freeVars.AddRange(v.TypedIdent.Type.FreeVariables);
            }

            freeVars.RemoveRange(dummies);
            freeVars.RemoveRange(typeParameters);
        }
Example #6
0
 public override void ComputeFreeVariables(Set freeVars)
 {
     //Contract.Requires(freeVars != null);
     ComputeBinderFreeVariables(TypeParameters, Dummies, Body, null, Attributes, freeVars);
 }
Example #7
0
 public override IExpr /*?*/ EquivalentExpr(Element /*!*/ e, IQueryable /*!*/ q, IExpr /*!*/ expr, IVariable /*!*/ var, ISet /*<IVariable!>*//*!*/ prohibitedVars)
 {
     //Contract.Requires(prohibitedVars != null);
     //Contract.Requires(var != null);
     //Contract.Requires(expr != null);
     //Contract.Requires(q != null);
     //Contract.Requires(e != null);
     // BUGBUG: TODO: this method can be implemented in a more precise way
     return(null);
 }
    public LinearConstraintSystem(ArrayList /*LinearConstraint!*//*!*/ cs) {
      Contract.Requires(cs != null);
#if BUG_159_HAS_BEEN_FIXED
      Contract.Requires(Contract.ForAll(cs) , cc=> cc.coefficients.Count != 0);
#endif

      ArrayList constraints = new ArrayList /*LinearConstraint!*/ (cs.Count);
      foreach (LinearConstraint/*!*/ cc in cs) {
        Contract.Assert(cc != null);
        constraints.Add(cc);
      }
      Constraints = constraints;
      FrameDimensions = new HashSet /*IVariable!*/ ();  // to please compiler; this value will be overridden in the call to GenerateFrameConstraints below
      //:base();

      GenerateFrameFromConstraints();
      SimplifyConstraints();
      CheckInvariant();
#if DEBUG_PRINT
      Console.WriteLine("LinearConstraintSystem: constructor produced:");
      Dump();
#endif
    }
    /// <summary>
    /// Initializes FrameVertices, FrameRays, FrameLines, and FrameDimensions, see
    /// Cousot and Halbwachs, section 3.4.  Any previous values of these fields are
    /// ignored and overwritten.
    /// 
    /// If the set of Constraints is unsatisfiable, then "this" is changed into Bottom.
    /// </summary>
    void GenerateFrameFromConstraints() {
      if (Constraints == null) {
        FrameVertices = null;
        FrameRays = null;
        FrameLines = null;
        FrameDimensions = new HashSet /*IVariable!*/ ();
        return;
      }

      // Step 1 (see Cousot and Halbwachs, section 3.4.3):  create a Simplex Tableau.
#if DEBUG_PRINT
      Console.WriteLine("DEBUG: --- GenerateFrameFromConstraint ---");
      Console.WriteLine("Constraints:");
      foreach (LinearConstraint cc in Constraints) 
      {
        Console.WriteLine("  {0}", cc);
      }
#endif
      SimplexTableau tableau = new SimplexTableau(Constraints);
#if DEBUG_PRINT
      Console.WriteLine("Initial tableau:");
      tableau.Dump();
#endif
      FrameDimensions = tableau.GetDimensions();
#if DEBUG_PRINT
      Console.WriteLine("Dimensions:");
      foreach (object dim in FrameDimensions) 
      {
        Console.Write("  {0}", dim);
      }
      Console.WriteLine();
#endif

      // Step 3 and 2: Put as many initial variables as possible into basis, then check if
      // we reached a feasible basis
      tableau.AddInitialVarsToBasis();
#if DEBUG_PRINT
      Console.WriteLine("Tableau after Step 3:");
      tableau.Dump();
#endif
      if (!tableau.IsFeasibleBasis) {
        // The polyhedron is empty (according to Cousot and Halbwachs)
        ChangeIntoBottom();
        return;
      }

      FrameVertices = new ArrayList /*FrameElement*/ ();
      FrameRays = new ArrayList /*FrameElement*/ ();
      FrameLines = new ArrayList /*FrameElement*/ ();
      if (FrameDimensions.Count == 0) {
        // top element
        return;
      }

      if (tableau.AllInitialVarsInBasis) {
        // All initial variables are in basis; there are no lines.
#if DEBUG_PRINT
        Console.WriteLine("Tableau after Steps 2 and 3 (all initial variables in basis):");
        tableau.Dump();
#endif
      } else {
        // There are lines
#if DEBUG_PRINT
        Console.WriteLine("Tableau after Steps 2 and 3 (NOT all initial variables in basis--there are lines):");
        tableau.Dump();
#endif
        // Step 4.2: Pick out the lines, then produce the tableau for a new polyhedron without those lines.
        ArrayList /*LinearConstraint*/ moreConstraints = cce.NonNull((ArrayList/*!*/ /*LinearConstraint*/)Constraints.Clone());
        tableau.ProduceLines(FrameLines, moreConstraints);
        tableau = new SimplexTableau(moreConstraints);
#if DEBUG_PRINT
        Console.WriteLine("Lines produced:");
        foreach (FrameElement line in FrameLines) 
        {
          Console.WriteLine("  {0}", line);
        }
        Console.WriteLine("The new list of constraints is:");
        foreach (LinearConstraint c in moreConstraints) 
        {
          Console.WriteLine("  {0}", c);
        }
        Console.WriteLine("Tableau after producing lines in Step 4.2:");
        tableau.Dump();
#endif

        // Repeat step 3 for the new tableau.
        // Since the new tableau contains no lines, the following call should cause all initial
        // variables to be in basis (see step 4.2 in section 3.4.3 of Cousot and Halbwachs).
        tableau.AddInitialVarsToBasis();
        System.Diagnostics.Debug.Assert(tableau.AllInitialVarsInBasis);
        System.Diagnostics.Debug.Assert(tableau.IsFeasibleBasis);  // the new tableau represents a set of feasible constraints, so this basis should be found to be feasible
#if DEBUG_PRINT
        Console.WriteLine("Tableau after all initial variables have been moved into basis:");
        tableau.Dump();
#endif
      }

      // Step 4.1: One vertex has been found.  Find all others, too.
      tableau.TraverseVertices(FrameVertices, FrameRays);
#if DEBUG_PRINT
      Console.WriteLine("Tableau after vertex traversal:");
      tableau.Dump();
#endif
    }
 public LinearConstraintSystem() {
   FrameDimensions = new HashSet /*IVariable!*/ ();
   //:base();
   CheckInvariant();
 }
    LinearConstraintSystem(FrameElement/*!*/ v) {
      Contract.Requires(v != null);
      IMutableSet/*!*/ frameDims = v.GetDefinedDimensions();
      Contract.Assert(frameDims != null);
      ArrayList /*LinearConstraint!*/ constraints = new ArrayList /*LinearConstraint!*/ ();
      foreach (IVariable/*!*/ dim in frameDims) {
        Contract.Assert(dim != null);
        LinearConstraint lc = new LinearConstraint(LinearConstraint.ConstraintRelation.EQ);
        lc.SetCoefficient(dim, Rational.ONE);
        lc.rhs = v[dim];
        constraints.Add(lc);
      }
      FrameDimensions = frameDims;
      Constraints = constraints;

      ArrayList /*FrameElement*/ frameVertices = new ArrayList /*FrameElement*/ ();
      frameVertices.Add(v);
      FrameVertices = frameVertices;

      FrameRays = new ArrayList /*FrameElement*/ ();
      FrameLines = new ArrayList /*FrameElement*/ ();

      //:base();
      CheckInvariant();
    }
 public override IExpr/*?*/ EquivalentExpr(Element/*!*/ e, IQueryable/*!*/ q, IExpr/*!*/ expr, IVariable/*!*/ var, ISet/*<IVariable!>*//*!*/ prohibitedVars) {
   //Contract.Requires(prohibitedVars != null);
   //Contract.Requires(var != null);
   //Contract.Requires(expr != null);
   //Contract.Requires(q != null);
   //Contract.Requires(e != null);
   // BUGBUG: TODO: this method can be implemented in a more precise way
   return null;
 }