// write an application that can only be a term.
            // if the expression is supposed to be printed as a formula,
            // it is turned into an equation (EQ (f args) |@true|)
            private void WriteApplicationTermOnly(string termOp, IEnumerable <VCExpr /*!*/> /*!*/ args, LineariserOptions options)
            {
                Contract.Requires(options != null);
                Contract.Requires(termOp != null);
                Contract.Requires(cce.NonNullElements(args));
                if (!options.AsTerm)
                {
                    // Write: (EQ (f args) |@true|)
                    // where "args" are written as terms
                    wr.Write("({0} ", eqName);
                }

                WriteApplication(termOp, args, options, true);

                if (!options.AsTerm)
                {
                    wr.Write(" {0})", boolTrueName);
                }
            }
 private void WriteApplication(string termOp, string predOp, IEnumerable <VCExpr /*!*/> /*!*/ args, LineariserOptions options)
 {
     Contract.Requires(options != null);
     Contract.Requires(predOp != null);
     Contract.Requires(termOp != null);
     Contract.Requires(cce.NonNullElements(args));
     WriteApplication(termOp, predOp, args, options, options.AsTerm);
 }
            private void WriteApplication(string termOp, string predOp, IEnumerable <VCExpr /*!*/> /*!*/ args, LineariserOptions options, bool argsAsTerms)
            {
                Contract.Requires(options != null);
                Contract.Requires(predOp != null);
                Contract.Requires(termOp != null);
                Contract.Requires(cce.NonNullElements(args));// change the AsTerm option for the arguments?
                wr.Write("({0}", options.AsTerm ? termOp : predOp);

                LineariserOptions newOptions = options.SetAsTerm(argsAsTerms);

                foreach (VCExpr e in args)
                {
                    Contract.Assert(e != null);
                    wr.Write(" ");
                    ExprLineariser.Linearise(e, newOptions);
                }

                wr.Write(")");
            }
 private void WriteTermApplication(string op, IEnumerable <VCExpr /*!*/> /*!*/ args, LineariserOptions options)
 {
     Contract.Requires(options != null);
     Contract.Requires(op != null);
     Contract.Requires(cce.NonNullElements(args));
     ExprLineariser.AssertAsTerm(op, options);
     WriteApplication(op, op, args, options, options.AsTerm);
 }
        private void WriteTriggers(List <VCTrigger /*!*/> /*!*/ triggers, LineariserOptions options)
        {
            Contract.Requires(options != null);
            Contract.Requires(cce.NonNullElements(triggers));
            // first, count how many neg/pos triggers there are
            int negTriggers = 0;
            int posTriggers = 0;

            foreach (VCTrigger vcTrig in triggers)
            {
                Contract.Assert(vcTrig != null);
                if (vcTrig.Pos)
                {
                    posTriggers++;
                }
                else
                {
                    negTriggers++;
                }
            }

            if (posTriggers > 0)
            {
                wr.Write("(PATS");
                foreach (VCTrigger vcTrig in triggers)
                {
                    Contract.Assert(vcTrig != null);
                    if (vcTrig.Pos)
                    {
                        if (vcTrig.Exprs.Count > 1)
                        {
                            wr.Write(" (MPAT");
                        }
                        foreach (VCExpr e in vcTrig.Exprs)
                        {
                            Contract.Assert(e != null);
                            wr.Write(" ");
                            LineariseAsTerm(e, options);
                        }
                        if (vcTrig.Exprs.Count > 1)
                        {
                            wr.Write(")");
                        }
                    }
                }
                wr.Write(") ");
            }
            else if (negTriggers > 0)
            {
                // if also positive triggers are given, the SMT solver (at least Z3)
                // will ignore the negative patterns and output a warning. Therefore
                // we never specify both negative and positive triggers
                wr.Write("(NOPATS");
                foreach (VCTrigger vcTrig in triggers)
                {
                    Contract.Assert(vcTrig != null);
                    if (!vcTrig.Pos)
                    {
                        wr.Write(" ");
                        Contract.Assert(vcTrig.Exprs.Count == 1);
                        LineariseAsTerm(vcTrig.Exprs[0], options);
                    }
                }
                wr.Write(") ");
            }
        }
        /////////////////////////////////////////////////////////////////////////////////////

        public bool Visit(VCExprQuantifier node, LineariserOptions options)
        {
            //Contract.Requires(options != null);
            //Contract.Requires(node != null);
            AssertAsFormula(node.Quan.ToString(), options);
            Contract.Assert(node.TypeParameters.Count == 0);

            Namer.PushScope();
            try {
                string kind = node.Quan == Quantifier.ALL ? "FORALL" : "EXISTS";
                wr.Write("({0} (", kind);

                for (int i = 0; i < node.BoundVars.Count; i++)
                {
                    VCExprVar var = node.BoundVars[i];
                    Contract.Assert(var != null);
                    string printedName = Namer.GetLocalName(var, var.Name);
                    Contract.Assert(printedName != null);
                    if (i != 0)
                    {
                        wr.Write(" ");
                    }
                    WriteId(printedName);
                    if (options.UseTypes)
                    {
                        wr.Write(" :TYPE {0}", TypeToString(var.Type));
                    }
                }
                wr.Write(") ");

                WriteTriggers(node.Triggers, options);

                if (options.QuantifierIds)
                {
                    // only needed for Z3
                    VCQuantifierInfos infos = node.Infos;
                    Contract.Assert(infos != null);
                    if (infos.qid != null)
                    {
                        wr.Write("(QID ");
                        wr.Write(infos.qid);
                        wr.Write(") ");
                    }
                    if (0 <= infos.uniqueId)
                    {
                        wr.Write("(SKOLEMID ");
                        wr.Write(infos.uniqueId);
                        wr.Write(") ");
                    }
                }

                if (options.UseWeights)
                {
                    int weight = QKeyValue.FindIntAttribute(node.Infos.attributes, "weight", 1);
                    if (weight != 1)
                    {
                        wr.Write("(WEIGHT ");
                        wr.Write(weight);
                        wr.Write(") ");
                    }
                }

                Linearise(node.Body, options);
                wr.Write(")");

                return(true);
            } finally {
                Namer.PopScope();
            }
        }
 public void LineariseAsTerm(VCExpr expr, LineariserOptions options)
 {
     Contract.Requires(options != null);
     Contract.Requires(expr != null);
     Linearise(expr, options.SetAsTerm(true));
 }
 public void Linearise(VCExpr expr, LineariserOptions options)
 {
     Contract.Requires(options != null);
     Contract.Requires(expr != null);
     expr.Accept <bool, LineariserOptions>(this, options);
 }