diff options
Diffstat (limited to 'Source/Provers')
23 files changed, 9196 insertions, 9196 deletions
diff --git a/Source/Provers/SMTLib/CVC4.cs b/Source/Provers/SMTLib/CVC4.cs index 0ac2ec20..999ac7b5 100644 --- a/Source/Provers/SMTLib/CVC4.cs +++ b/Source/Provers/SMTLib/CVC4.cs @@ -1,71 +1,71 @@ -using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Diagnostics.Contracts;
-using System.IO;
-using System.Text.RegularExpressions;
-
-namespace Microsoft.Boogie.SMTLib
-{
- class CVC4
- {
- static string _proverPath;
-
- static string CodebaseString()
- {
- Contract.Ensures(Contract.Result<string>() != null);
- return Path.GetDirectoryName(cce.NonNull(System.Reflection.Assembly.GetExecutingAssembly().Location));
- }
-
- public static string ExecutablePath()
- {
- if (_proverPath == null)
- FindExecutable();
- return _proverPath;
- }
-
- static void FindExecutable()
- // throws ProverException, System.IO.FileNotFoundException;
- {
- Contract.Ensures(_proverPath != null);
-
- // Command line option 'cvc4exe' always has priority if set
- if (CommandLineOptions.Clo.CVC4ExecutablePath != null)
- {
- _proverPath = CommandLineOptions.Clo.CVC4ExecutablePath;
- if (!File.Exists(_proverPath))
- {
- throw new ProverException("Cannot find prover specified with cvc4exe: " + _proverPath);
- }
- if (CommandLineOptions.Clo.Trace)
- {
- Console.WriteLine("[TRACE] Using prover: " + _proverPath);
- }
- return;
- }
-
- var proverExe = "cvc4.exe";
-
- if (_proverPath == null)
- {
- // Initialize '_proverPath'
- _proverPath = Path.Combine(CodebaseString(), proverExe);
- string firstTry = _proverPath;
-
- if (File.Exists(firstTry))
- {
- if (CommandLineOptions.Clo.Trace)
- {
- Console.WriteLine("[TRACE] Using prover: " + _proverPath);
- }
- return;
- }
- else
- {
- throw new ProverException("Cannot find executable: " + firstTry);
- }
- }
- }
- }
-}
+using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Diagnostics.Contracts; +using System.IO; +using System.Text.RegularExpressions; + +namespace Microsoft.Boogie.SMTLib +{ + class CVC4 + { + static string _proverPath; + + static string CodebaseString() + { + Contract.Ensures(Contract.Result<string>() != null); + return Path.GetDirectoryName(cce.NonNull(System.Reflection.Assembly.GetExecutingAssembly().Location)); + } + + public static string ExecutablePath() + { + if (_proverPath == null) + FindExecutable(); + return _proverPath; + } + + static void FindExecutable() + // throws ProverException, System.IO.FileNotFoundException; + { + Contract.Ensures(_proverPath != null); + + // Command line option 'cvc4exe' always has priority if set + if (CommandLineOptions.Clo.CVC4ExecutablePath != null) + { + _proverPath = CommandLineOptions.Clo.CVC4ExecutablePath; + if (!File.Exists(_proverPath)) + { + throw new ProverException("Cannot find prover specified with cvc4exe: " + _proverPath); + } + if (CommandLineOptions.Clo.Trace) + { + Console.WriteLine("[TRACE] Using prover: " + _proverPath); + } + return; + } + + var proverExe = "cvc4.exe"; + + if (_proverPath == null) + { + // Initialize '_proverPath' + _proverPath = Path.Combine(CodebaseString(), proverExe); + string firstTry = _proverPath; + + if (File.Exists(firstTry)) + { + if (CommandLineOptions.Clo.Trace) + { + Console.WriteLine("[TRACE] Using prover: " + _proverPath); + } + return; + } + else + { + throw new ProverException("Cannot find executable: " + firstTry); + } + } + } + } +} diff --git a/Source/Provers/SMTLib/Inspector.cs b/Source/Provers/SMTLib/Inspector.cs index 362502f3..13a2076e 100644 --- a/Source/Provers/SMTLib/Inspector.cs +++ b/Source/Provers/SMTLib/Inspector.cs @@ -1,157 +1,157 @@ -//-----------------------------------------------------------------------------
-//
-// Copyright (C) Microsoft Corporation. All Rights Reserved.
-//
-//-----------------------------------------------------------------------------
-using System;
-using System.IO;
-using System.Diagnostics;
-using System.Collections;
-using System.Collections.Generic;
-using System.Diagnostics.Contracts;
-//using util;
-using Microsoft.Boogie;
-using Microsoft.Basetypes;
-using Microsoft.Boogie.VCExprAST;
-
-namespace Microsoft.Boogie.SMTLib
-{
- internal class FindLabelsVisitor : TraversingVCExprVisitor<bool, bool> {
- public HashSet<string/*!*/>/*!*/ Labels = new HashSet<string/*!*/>();
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(cce.NonNull(Labels));
- }
-
-
- public static HashSet<string/*!*/>/*!*/ FindLabels(VCExpr/*!*/ expr) {
- Contract.Requires(expr != null);
- Contract.Ensures(cce.NonNull(Contract.Result<HashSet<string/*!*/>/*!*/>()));
-
- FindLabelsVisitor visitor = new FindLabelsVisitor();
- visitor.Traverse(expr, true);
- return visitor.Labels;
- }
-
- protected override bool StandardResult(VCExpr node, bool arg) {
- //Contract.Requires(node!=null);
- VCExprNAry nary = node as VCExprNAry;
- if (nary != null) {
- VCExprLabelOp lab = nary.Op as VCExprLabelOp;
- if (lab != null) {
- Labels.Add(lab.label);
- }
- }
- return true;
- }
- }
-
- internal class Inspector {
- [Rep] protected readonly Process inspector;
- [Rep] readonly TextReader fromInspector;
- [Rep] readonly TextWriter toInspector;
- [ContractInvariantMethod]
- void ObjectInvariant()
- {
- Contract.Invariant(inspector!=null);
- Contract.Invariant(fromInspector!=null);
- Contract.Invariant(toInspector != null);
- }
-
-
- public Inspector(SMTLibProverOptions opts)
- {
- Contract.Requires(opts != null);
- ProcessStartInfo psi = new ProcessStartInfo(opts.Inspector);
- Contract.Assert(psi!=null);
- psi.CreateNoWindow = true;
- psi.UseShellExecute = false;
- psi.RedirectStandardInput = true;
- psi.RedirectStandardOutput = true;
- psi.RedirectStandardError = false;
-
- try
- {
- Process inspector = Process.Start(psi);
- this.inspector = inspector;
- fromInspector = inspector.StandardOutput;
- toInspector = inspector.StandardInput;
- }
- catch (System.ComponentModel.Win32Exception e)
- {
- throw new Exception(string.Format("Unable to start the inspector process {0}: {1}", opts.Inspector, e.Message));
- }
- }
-
- public void NewProblem(string descriptiveName, VCExpr vc, ProverInterface.ErrorHandler handler)
- {
- Contract.Requires(descriptiveName != null);
- Contract.Requires(vc != null);
- Contract.Requires(handler != null);
- HashSet<string/*!*/>/*!*/ labels = FindLabelsVisitor.FindLabels(vc);
- Contract.Assert(labels!=null);
- toInspector.WriteLine("PROBLEM " + descriptiveName);
- toInspector.WriteLine("TOKEN BEGIN");
- foreach (string lab in labels) {
- Contract.Assert(lab!=null);
- string no = lab.Substring(1);
- Absy absy = handler.Label2Absy(no);
-
- IToken tok = absy.tok;
- AssertCmd assrt = absy as AssertCmd;
- Block blk = absy as Block;
- string val = tok.val; // might require computation, so cache it
- if (val == "foo" || tok.filename == null) continue; // no token
-
- toInspector.Write("TOKEN ");
- toInspector.Write(lab);
- toInspector.Write(" ");
-
- if (assrt != null) {
- toInspector.Write("ASSERT");
- string errData = assrt.ErrorData as string;
- if (errData != null) {
- val = errData;
- } else if (assrt.ErrorMessage != null) {
- val = assrt.ErrorMessage;
- }
- } else if (blk != null) {
- toInspector.Write("BLOCK ");
- toInspector.Write(blk.Label);
- } else {
- Contract.Assume( false);
- }
- if (val == null || val == "assert" || val == "ensures") { val = ""; }
-
- if (absy is LoopInitAssertCmd) {
- val += " (loop entry)";
- } else if (absy is LoopInvMaintainedAssertCmd) {
- val += " (loop body)";
- } else if (val.IndexOf("#VCCERR") >= 0) {
- // skip further transformations
- } else if (absy is AssertRequiresCmd) {
- AssertRequiresCmd req = (AssertRequiresCmd)absy;
- IToken t2 = req.Requires.tok;
- string tval = t2.val;
- if (tval == "requires")
- tval = string.Format("{0}({1},{2}))", t2.filename, t2.line, t2.col);
- string call = "";
- if (val != "call") call = " in call to " + val;
- val = string.Format("precondition {0}{1}", tval, call);
- }
-
- val = val.Replace("\r", "").Replace("\n", " ");
-
- toInspector.WriteLine(string.Format(" {0} {1} :@:{2}:@:{3}", tok.line, tok.col, tok.filename, val));
- }
- toInspector.WriteLine("TOKEN END");
- }
-
- public void StatsLine(string line)
- {
- Contract.Requires(line != null);
- toInspector.WriteLine(line);
- toInspector.Flush();
- }
- }
-}
+//----------------------------------------------------------------------------- +// +// Copyright (C) Microsoft Corporation. All Rights Reserved. +// +//----------------------------------------------------------------------------- +using System; +using System.IO; +using System.Diagnostics; +using System.Collections; +using System.Collections.Generic; +using System.Diagnostics.Contracts; +//using util; +using Microsoft.Boogie; +using Microsoft.Basetypes; +using Microsoft.Boogie.VCExprAST; + +namespace Microsoft.Boogie.SMTLib +{ + internal class FindLabelsVisitor : TraversingVCExprVisitor<bool, bool> { + public HashSet<string/*!*/>/*!*/ Labels = new HashSet<string/*!*/>(); + [ContractInvariantMethod] + void ObjectInvariant() { + Contract.Invariant(cce.NonNull(Labels)); + } + + + public static HashSet<string/*!*/>/*!*/ FindLabels(VCExpr/*!*/ expr) { + Contract.Requires(expr != null); + Contract.Ensures(cce.NonNull(Contract.Result<HashSet<string/*!*/>/*!*/>())); + + FindLabelsVisitor visitor = new FindLabelsVisitor(); + visitor.Traverse(expr, true); + return visitor.Labels; + } + + protected override bool StandardResult(VCExpr node, bool arg) { + //Contract.Requires(node!=null); + VCExprNAry nary = node as VCExprNAry; + if (nary != null) { + VCExprLabelOp lab = nary.Op as VCExprLabelOp; + if (lab != null) { + Labels.Add(lab.label); + } + } + return true; + } + } + + internal class Inspector { + [Rep] protected readonly Process inspector; + [Rep] readonly TextReader fromInspector; + [Rep] readonly TextWriter toInspector; + [ContractInvariantMethod] + void ObjectInvariant() + { + Contract.Invariant(inspector!=null); + Contract.Invariant(fromInspector!=null); + Contract.Invariant(toInspector != null); + } + + + public Inspector(SMTLibProverOptions opts) + { + Contract.Requires(opts != null); + ProcessStartInfo psi = new ProcessStartInfo(opts.Inspector); + Contract.Assert(psi!=null); + psi.CreateNoWindow = true; + psi.UseShellExecute = false; + psi.RedirectStandardInput = true; + psi.RedirectStandardOutput = true; + psi.RedirectStandardError = false; + + try + { + Process inspector = Process.Start(psi); + this.inspector = inspector; + fromInspector = inspector.StandardOutput; + toInspector = inspector.StandardInput; + } + catch (System.ComponentModel.Win32Exception e) + { + throw new Exception(string.Format("Unable to start the inspector process {0}: {1}", opts.Inspector, e.Message)); + } + } + + public void NewProblem(string descriptiveName, VCExpr vc, ProverInterface.ErrorHandler handler) + { + Contract.Requires(descriptiveName != null); + Contract.Requires(vc != null); + Contract.Requires(handler != null); + HashSet<string/*!*/>/*!*/ labels = FindLabelsVisitor.FindLabels(vc); + Contract.Assert(labels!=null); + toInspector.WriteLine("PROBLEM " + descriptiveName); + toInspector.WriteLine("TOKEN BEGIN"); + foreach (string lab in labels) { + Contract.Assert(lab!=null); + string no = lab.Substring(1); + Absy absy = handler.Label2Absy(no); + + IToken tok = absy.tok; + AssertCmd assrt = absy as AssertCmd; + Block blk = absy as Block; + string val = tok.val; // might require computation, so cache it + if (val == "foo" || tok.filename == null) continue; // no token + + toInspector.Write("TOKEN "); + toInspector.Write(lab); + toInspector.Write(" "); + + if (assrt != null) { + toInspector.Write("ASSERT"); + string errData = assrt.ErrorData as string; + if (errData != null) { + val = errData; + } else if (assrt.ErrorMessage != null) { + val = assrt.ErrorMessage; + } + } else if (blk != null) { + toInspector.Write("BLOCK "); + toInspector.Write(blk.Label); + } else { + Contract.Assume( false); + } + if (val == null || val == "assert" || val == "ensures") { val = ""; } + + if (absy is LoopInitAssertCmd) { + val += " (loop entry)"; + } else if (absy is LoopInvMaintainedAssertCmd) { + val += " (loop body)"; + } else if (val.IndexOf("#VCCERR") >= 0) { + // skip further transformations + } else if (absy is AssertRequiresCmd) { + AssertRequiresCmd req = (AssertRequiresCmd)absy; + IToken t2 = req.Requires.tok; + string tval = t2.val; + if (tval == "requires") + tval = string.Format("{0}({1},{2}))", t2.filename, t2.line, t2.col); + string call = ""; + if (val != "call") call = " in call to " + val; + val = string.Format("precondition {0}{1}", tval, call); + } + + val = val.Replace("\r", "").Replace("\n", " "); + + toInspector.WriteLine(string.Format(" {0} {1} :@:{2}:@:{3}", tok.line, tok.col, tok.filename, val)); + } + toInspector.WriteLine("TOKEN END"); + } + + public void StatsLine(string line) + { + Contract.Requires(line != null); + toInspector.WriteLine(line); + toInspector.Flush(); + } + } +} diff --git a/Source/Provers/SMTLib/ProverInterface.cs b/Source/Provers/SMTLib/ProverInterface.cs index 8ded5f10..e93ecee9 100644 --- a/Source/Provers/SMTLib/ProverInterface.cs +++ b/Source/Provers/SMTLib/ProverInterface.cs @@ -1,2588 +1,2588 @@ -//-----------------------------------------------------------------------------
-//
-// Copyright (C) Microsoft Corporation. All Rights Reserved.
-//
-//-----------------------------------------------------------------------------
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Threading;
-using System.IO;
-//using ExternalProver;
-using System.Linq;
-using System.Diagnostics;
-using System.Diagnostics.Contracts;
-using Microsoft.Boogie.AbstractInterpretation;
-using Microsoft.Boogie;
-using Microsoft.Boogie.VCExprAST;
-using Microsoft.Boogie.Clustering;
-using Microsoft.Boogie.TypeErasure;
-using System.Text;
-
-using RPFP = Microsoft.Boogie.RPFP;
-
-namespace Microsoft.Boogie.SMTLib
-{
- public class SMTLibProcessTheoremProver : ProverInterface
- {
- private readonly SMTLibProverContext ctx;
- private VCExpressionGenerator gen;
- private readonly SMTLibProverOptions options;
- private bool usingUnsatCore;
- private RPFP rpfp = null;
-
- [ContractInvariantMethod]
- void ObjectInvariant()
- {
- Contract.Invariant(ctx != null);
- Contract.Invariant(AxBuilder != null);
- Contract.Invariant(Namer != null);
- Contract.Invariant(DeclCollector != null);
- Contract.Invariant(cce.NonNullElements(Axioms));
- Contract.Invariant(cce.NonNullElements(TypeDecls));
- Contract.Invariant(_backgroundPredicates != null);
-
- }
-
-
- [NotDelayed]
- public SMTLibProcessTheoremProver(ProverOptions options, VCExpressionGenerator gen,
- SMTLibProverContext ctx)
- {
- Contract.Requires(options != null);
- Contract.Requires(gen != null);
- Contract.Requires(ctx != null);
-
- InitializeGlobalInformation();
-
- this.options = (SMTLibProverOptions)options;
- this.ctx = ctx;
- this.gen = gen;
- this.usingUnsatCore = false;
-
- SetupAxiomBuilder(gen);
-
- Namer = new SMTLibNamer();
- ctx.parent = this;
- this.DeclCollector = new TypeDeclCollector((SMTLibProverOptions)options, Namer);
-
- if (CommandLineOptions.Clo.PrintFixedPoint != null || CommandLineOptions.Clo.PrintConjectures != null)
- {
- declHandler = new MyDeclHandler();
- DeclCollector.SetDeclHandler(declHandler);
- }
-
- SetupProcess();
-
- if (CommandLineOptions.Clo.StratifiedInlining > 0 || CommandLineOptions.Clo.ContractInfer
- || CommandLineOptions.Clo.SecureVcGen != null)
- {
- // Prepare for ApiChecker usage
- if (options.LogFilename != null && currentLogFile == null)
- {
- currentLogFile = OpenOutputFile("");
- }
- PrepareCommon();
- }
- }
-
- private void SetupAxiomBuilder(VCExpressionGenerator gen)
- {
- switch (CommandLineOptions.Clo.TypeEncodingMethod)
- {
- case CommandLineOptions.TypeEncoding.Arguments:
- AxBuilder = new TypeAxiomBuilderArguments(gen);
- AxBuilder.Setup();
- break;
- case CommandLineOptions.TypeEncoding.Monomorphic:
- AxBuilder = new TypeAxiomBuilderPremisses(gen);
- break;
- default:
- AxBuilder = new TypeAxiomBuilderPremisses(gen);
- AxBuilder.Setup();
- break;
- }
- }
-
- ProcessStartInfo ComputeProcessStartInfo()
- {
- var path = this.options.ProverPath;
- switch (options.Solver) {
- case SolverKind.Z3:
- if (path == null)
- path = Z3.ExecutablePath();
- return SMTLibProcess.ComputerProcessStartInfo(path, "AUTO_CONFIG=false -smt2 -in");
- case SolverKind.CVC4:
- if (path == null)
- path = CVC4.ExecutablePath();
- return SMTLibProcess.ComputerProcessStartInfo(path, "--lang=smt --no-strict-parsing --no-condense-function-values --incremental");
- default:
- Debug.Assert(false);
- return null;
- }
- }
-
- void SetupProcess()
- {
- if (Process != null) return;
-
- var psi = ComputeProcessStartInfo();
- Process = new SMTLibProcess(psi, this.options);
- Process.ErrorHandler += this.HandleProverError;
- }
-
-
- void PossiblyRestart()
- {
- if (Process != null && Process.NeedsRestart) {
- Process.Close();
- Process = null;
- SetupProcess();
- Process.Send(common.ToString());
- }
- }
-
- public override ProverContext Context
- {
- get
- {
- Contract.Ensures(Contract.Result<ProverContext>() != null);
-
- return ctx;
- }
- }
-
- internal TypeAxiomBuilder AxBuilder { get; private set; }
- internal readonly UniqueNamer Namer;
- readonly TypeDeclCollector DeclCollector;
- protected SMTLibProcess Process;
- readonly List<string> proverErrors = new List<string>();
- readonly List<string> proverWarnings = new List<string>();
- readonly StringBuilder common = new StringBuilder();
- protected TextWriter currentLogFile;
- protected volatile ErrorHandler currentErrorHandler;
-
- private void FeedTypeDeclsToProver()
- {
- foreach (string s in DeclCollector.GetNewDeclarations()) {
- Contract.Assert(s != null);
- AddTypeDecl(s);
- }
- }
-
- private string Sanitize(string msg)
- {
- var idx = msg.IndexOf('\n');
- if (idx > 0)
- msg = msg.Replace("\r", "").Replace("\n", "\r\n");
- return msg;
- }
-
- public override void LogComment(string comment)
- {
- SendCommon("; " + comment);
- }
-
- private void SendCommon(string s)
- {
- Send(s, true);
- }
-
- protected void SendThisVC(string s)
- {
- Send(s, false);
- }
-
- private void Send(string s, bool isCommon)
- {
- s = Sanitize(s);
-
- if (isCommon)
- common.Append(s).Append("\r\n");
-
- if (Process != null)
- Process.Send(s);
- if (currentLogFile != null) {
- currentLogFile.WriteLine(s);
- currentLogFile.Flush();
- }
- }
-
- private void FindDependentTypes(Type type, List<CtorType> dependentTypes)
- {
- MapType mapType = type as MapType;
- if (mapType != null)
- {
- foreach (Type t in mapType.Arguments)
- {
- FindDependentTypes(t, dependentTypes);
- }
- FindDependentTypes(mapType.Result, dependentTypes);
- }
- CtorType ctorType = type as CtorType;
- if (ctorType != null && ctx.KnownDatatypeConstructors.ContainsKey(ctorType))
- {
- dependentTypes.Add(ctorType);
- }
- }
-
- private void PrepareCommon()
- {
- if (common.Length == 0)
- {
- SendCommon("(set-option :print-success false)");
- SendCommon("(set-info :smt-lib-version 2.0)");
- if (options.ProduceModel())
- SendCommon("(set-option :produce-models true)");
- foreach (var opt in options.SmtOptions)
- {
- SendCommon("(set-option :" + opt.Option + " " + opt.Value + ")");
- }
-
- if (!string.IsNullOrEmpty(options.Logic))
- {
- SendCommon("(set-logic " + options.Logic + ")");
- }
-
- // Set produce-unsat-cores last. It seems there's a bug in Z3 where if we set it earlier its value
- // gets reset by other set-option commands ( https://z3.codeplex.com/workitem/188 )
- if (CommandLineOptions.Clo.ContractInfer && (CommandLineOptions.Clo.UseUnsatCoreForContractInfer || CommandLineOptions.Clo.ExplainHoudini))
- {
- SendThisVC("(set-option :produce-unsat-cores true)");
- this.usingUnsatCore = true;
- }
-
- SendCommon("; done setting options\n");
- SendCommon(_backgroundPredicates);
-
- if (options.UseTickleBool)
- {
- SendCommon("(declare-fun tickleBool (Bool) Bool)");
- SendCommon("(assert (and (tickleBool true) (tickleBool false)))");
- }
-
- if (CommandLineOptions.Clo.RunDiagnosticsOnTimeout)
- {
- SendCommon("(declare-fun timeoutDiagnostics (Int) Bool)");
- }
-
- if (ctx.KnownDatatypeConstructors.Count > 0)
- {
- GraphUtil.Graph<CtorType> dependencyGraph = new GraphUtil.Graph<CtorType>();
- foreach (CtorType datatype in ctx.KnownDatatypeConstructors.Keys)
- {
- dependencyGraph.AddSource(datatype);
- foreach (Function f in ctx.KnownDatatypeConstructors[datatype])
- {
- List<CtorType> dependentTypes = new List<CtorType>();
- foreach (Variable v in f.InParams)
- {
- FindDependentTypes(v.TypedIdent.Type, dependentTypes);
- }
- foreach (CtorType result in dependentTypes)
- {
- dependencyGraph.AddEdge(datatype, result);
- }
- }
- }
- GraphUtil.StronglyConnectedComponents<CtorType> sccs = new GraphUtil.StronglyConnectedComponents<CtorType>(dependencyGraph.Nodes, dependencyGraph.Predecessors, dependencyGraph.Successors);
- sccs.Compute();
- foreach (GraphUtil.SCC<CtorType> scc in sccs)
- {
- string datatypeString = "";
- foreach (CtorType datatype in scc)
- {
- datatypeString += "(" + SMTLibExprLineariser.TypeToString(datatype) + " ";
- foreach (Function f in ctx.KnownDatatypeConstructors[datatype])
- {
- string quotedConstructorName = Namer.GetQuotedName(f, f.Name);
- if (f.InParams.Count == 0)
- {
- datatypeString += quotedConstructorName + " ";
- }
- else
- {
- datatypeString += "(" + quotedConstructorName + " ";
- foreach (Variable v in f.InParams)
- {
- string quotedSelectorName = Namer.GetQuotedName(v, v.Name + "#" + f.Name);
- datatypeString += "(" + quotedSelectorName + " " + DeclCollector.TypeToStringReg(v.TypedIdent.Type) + ") ";
- }
- datatypeString += ") ";
- }
- }
- datatypeString += ") ";
- }
- List<string> decls = DeclCollector.GetNewDeclarations();
- foreach (string decl in decls)
- {
- SendCommon(decl);
- }
- SendCommon("(declare-datatypes () (" + datatypeString + "))");
- }
- }
- if (CommandLineOptions.Clo.ProverPreamble != null)
- SendCommon("(include \"" + CommandLineOptions.Clo.ProverPreamble + "\")");
- }
-
- if (!AxiomsAreSetup)
- {
- var axioms = ctx.Axioms;
- var nary = axioms as VCExprNAry;
- if (nary != null && nary.Op == VCExpressionGenerator.AndOp)
- foreach (var expr in nary.UniformArguments)
- {
- var str = VCExpr2String(expr, -1);
- if (str != "true")
- AddAxiom(str);
- }
- else
- AddAxiom(VCExpr2String(axioms, -1));
- AxiomsAreSetup = true;
- }
- }
-
- public override int FlushAxiomsToTheoremProver()
- {
- // we feed the axioms when begincheck is called.
- return 0;
- }
-
- private void FlushAxioms()
- {
- TypeDecls.Iter(SendCommon);
- TypeDecls.Clear();
- foreach (string s in Axioms) {
- Contract.Assert(s != null);
- if (s != "true")
- SendCommon("(assert " + s + ")");
- }
- Axioms.Clear();
- //FlushPushedAssertions();
- }
-
- private void CloseLogFile()
- {
- if (currentLogFile != null) {
- currentLogFile.Close();
- currentLogFile = null;
- }
- }
-
- private void FlushLogFile()
- {
- if (currentLogFile != null) {
- currentLogFile.Flush();
- }
- }
-
- public override void Close()
- {
- base.Close();
- CloseLogFile();
- if (Process != null)
- Process.Close();
- }
-
- public override void BeginCheck(string descriptiveName, VCExpr vc, ErrorHandler handler)
- {
- //Contract.Requires(descriptiveName != null);
- //Contract.Requires(vc != null);
- //Contract.Requires(handler != null);
- rpfp = null;
-
- if (options.SeparateLogFiles) CloseLogFile(); // shouldn't really happen
-
- if (options.LogFilename != null && currentLogFile == null)
- {
- currentLogFile = OpenOutputFile(descriptiveName);
- currentLogFile.Write(common.ToString());
- }
-
- PrepareCommon();
-
- string vcString = "(assert (not\n" + VCExpr2String(vc, 1) + "\n))";
- FlushAxioms();
-
- PossiblyRestart();
-
- SendThisVC("(push 1)");
- SendThisVC("(set-info :boogie-vc-id " + SMTLibNamer.QuoteId(descriptiveName) + ")");
- SendThisVC(vcString);
- FlushLogFile();
-
- if (Process != null) {
- Process.PingPong(); // flush any errors
-
- if (Process.Inspector != null)
- Process.Inspector.NewProblem(descriptiveName, vc, handler);
- }
-
- SendThisVC("(check-sat)");
- FlushLogFile();
- }
-
- public override void Reset(VCExpressionGenerator gen)
- {
- if (options.Solver == SolverKind.Z3)
- {
- this.gen = gen;
- SendThisVC("(reset)");
-
- if (0 < common.Length)
- {
- var c = common.ToString();
- Process.Send(c);
- if (currentLogFile != null)
- {
- currentLogFile.WriteLine(c);
- }
- }
- }
- }
-
- public override void FullReset(VCExpressionGenerator gen)
- {
- if (options.Solver == SolverKind.Z3)
- {
- this.gen = gen;
- Namer.Reset();
- common.Clear();
- SetupAxiomBuilder(gen);
- Axioms.Clear();
- TypeDecls.Clear();
- AxiomsAreSetup = false;
- ctx.Reset();
- ctx.KnownDatatypeConstructors.Clear();
- ctx.parent = this;
- DeclCollector.Reset();
- SendThisVC("; did a full reset");
- }
- }
-
-
-
- private string StripCruft(string name){
- if(name.Contains("@@"))
- return name.Remove(name.LastIndexOf ("@@"));
- return name;
- }
-
- private class BadExprFromProver : Exception
- {
- };
-
- private delegate VCExpr ArgGetter (int pos);
-
- private delegate VCExpr[] ArgsGetter ();
-
- private delegate VCExprVar[] VarsGetter ();
-
- private VCExprOp VCStringToVCOp (string op)
- {
- switch (op) {
- case "+" :
- return VCExpressionGenerator.AddIOp;
- case "-" :
- return VCExpressionGenerator.SubIOp;
- case "*" :
- return VCExpressionGenerator.MulIOp;
- case "div" :
- return VCExpressionGenerator.DivIOp;
- case "=" :
- return VCExpressionGenerator.EqOp;
- case "<=" :
- return VCExpressionGenerator.LeOp;
- case "<" :
- return VCExpressionGenerator.LtOp;
- case ">=" :
- return VCExpressionGenerator.GeOp;
- case ">" :
- return VCExpressionGenerator.GtOp;
- case "and" :
- return VCExpressionGenerator.AndOp;
- case "or" :
- return VCExpressionGenerator.OrOp;
- case "not" :
- return VCExpressionGenerator.NotOp;
- case "ite" :
- return VCExpressionGenerator.IfThenElseOp;
- default:
- return null;
- }
- }
-
- private class MyDeclHandler : TypeDeclCollector.DeclHandler {
- public Dictionary<string,VCExprVar> var_map = new Dictionary<string, VCExprVar>();
- public Dictionary<string,Function> func_map = new Dictionary<string, Function>();
- public override void VarDecl(VCExprVar v){
- var_map[v.Name] = v;
- }
- public override void FuncDecl(Function f){
- func_map[f.Name] = f;
- }
- public MyDeclHandler() {
- }
- }
-
- private MyDeclHandler declHandler = null;
-
- private VCExprVar SExprToVar (SExpr e)
- {
- if(e.Arguments.Count() != 1){
- HandleProverError ("Prover error: bad quantifier syntax");
- throw new BadExprFromProver ();
- }
- string vname = StripCruft(e.Name);
- SExpr vtype = e[0];
- switch(vtype.Name){
- case "Int":
- return gen.Variable(vname,Type.Int);
- case "Bool":
- return gen.Variable (vname,Type.Bool);
- case "Array":{
- // TODO: handle more general array types
- var idxType = Type.Int; // well, could be something else
- var valueType =
- (vtype.Arguments[1].Name == "Int") ? Type.Int : Type.Bool;
- var types = new List<Type>();
- types.Add(idxType);
- return gen.Variable (vname, new MapType(Token.NoToken,new List<TypeVariable>(),types,valueType));
- }
- default: {
- HandleProverError ("Prover error: bad type: " + vtype.Name);
- throw new BadExprFromProver ();
- }
- }
- }
-
- private VCExpr MakeBinary(VCExprOp op, VCExpr [] args)
- {
- if (args.Count() == 0)
- {
- // with zero args we need the identity of the op
- if (op == VCExpressionGenerator.AndOp)
- return VCExpressionGenerator.True;
- if (op == VCExpressionGenerator.OrOp)
- return VCExpressionGenerator.False;
- if (op == VCExpressionGenerator.AddIOp)
- {
- Microsoft.Basetypes.BigNum x = Microsoft.Basetypes.BigNum.ZERO;
- return gen.Integer(x);
- }
- HandleProverError("Prover error: bad expression ");
- throw new BadExprFromProver();
- }
- var temp = args[0];
- for (int i = 1; i < args.Count(); i++)
- temp = gen.Function(op, temp, args[i]);
- return temp;
- }
-
- protected VCExpr SExprToVCExpr (SExpr e, Dictionary<string,VCExpr> bound)
- {
- if (e.Arguments.Count() == 0) {
- var name = StripCruft(e.Name);
- if (name [0] >= '0' && name [0] <= '9') {
- Microsoft.Basetypes.BigNum x = Microsoft.Basetypes.BigNum.FromString(name);
- return gen.Integer (x);
- }
- if (bound.ContainsKey (name)) {
- return bound [name];
- }
- if(name == "true")
- return VCExpressionGenerator.True;
- if(name == "false")
- return VCExpressionGenerator.False;
- if(declHandler.var_map.ContainsKey(name))
- return declHandler.var_map[name];
- HandleProverError ("Prover error: unknown symbol:" + name);
- //throw new BadExprFromProver ();
- var v = gen.Variable(name, Type.Int);
- bound.Add(name, v);
- return v;
- }
- ArgGetter g = i => SExprToVCExpr (e [i], bound);
- ArgsGetter ga = () => e.Arguments.Select (x => SExprToVCExpr (x, bound)).ToArray ();
- VarsGetter gb = () => e [0].Arguments.Select (x => SExprToVar (x)).ToArray ();
- switch (e.Name) {
- case "select" :
- return gen.Select (ga ());
- case "store" :
- return gen.Store (ga ());
- case "forall":
- case "exists":
- {
- var binds = e.Arguments[0];
- var vcbinds = new List<VCExprVar>();
- var bound_copy = new Dictionary<string, VCExpr>(bound);
- for (int i = 0; i < binds.Arguments.Count(); i++)
- {
- var bind = binds.Arguments[i];
- var symb = StripCruft(bind.Name);
- var vcv = SExprToVar(bind);
- vcbinds.Add(vcv);
- bound[symb] = vcv;
- }
- var body = g(1);
- if (e.Name == "forall")
- body = gen.Forall(vcbinds, new List<VCTrigger>(), body);
- else
- body = gen.Exists(vcbinds, new List<VCTrigger>(), body);
- bound = bound_copy;
- return body;
- }
- case "-" : // have to deal with unary case
- {
- if(e.ArgCount == 1){
- var args = new VCExpr[2];
- args[0] = gen.Integer (Microsoft.Basetypes.BigNum.ZERO);
- args[1] = g(0);
- return gen.Function(VCStringToVCOp("-"),args);
- }
- return gen.Function(VCStringToVCOp("-"),ga());
- }
- case "!" : // this is commentary
- return g(0);
- case "let" : {
- // we expand lets exponentially since there is no let binding in Boogie surface syntax
- bool expand_lets = true;
- var binds = e.Arguments[0];
- var vcbinds = new List<VCExprLetBinding>();
- var bound_copy = new Dictionary<string, VCExpr>(bound);
- for(int i = 0; i < binds.Arguments.Count(); i++){
- var bind = binds.Arguments[i];
- var symb = bind.Name;
- var def = bind.Arguments[0];
- var vce = SExprToVCExpr(def, bound);
- var vcv = gen.Variable(symb,vce.Type);
- var vcb = gen.LetBinding(vcv,vce);
- vcbinds.Add (vcb);
- bound[symb] = expand_lets ? vce : vcv;
- }
- var body = g(1);
- if(!expand_lets)
- body = gen.Let(vcbinds,body);
- bound = bound_copy;
- return body;
- }
-
- default: {
- var op = VCStringToVCOp (e.Name);
- if (op == null) {
- var name = StripCruft(e.Name);
- if(declHandler.func_map.ContainsKey(name)){
- Function f = declHandler.func_map[name];
- return gen.Function (f, ga());
- }
- HandleProverError ("Prover error: unknown operator:" + e.Name);
- throw new BadExprFromProver ();
- }
- if(op.Arity == 2)
- return MakeBinary (op, ga ());
- return gen.Function(op, ga());
- }
- }
- }
-
- private void SExprToSoln (SExpr resp,
- Dictionary<int,Dictionary<string,string>> varSubst)
- {
- Dictionary<string, RPFP.Node> pmap = new Dictionary<string,RPFP.Node> ();
-
- foreach (var node in rpfp.nodes)
- pmap.Add ((node.Name as VCExprBoogieFunctionOp).Func.Name, node);
-
- var lines = resp.Arguments;
-
- // get all the predicate definitions
- for (int i = 0; i < lines.Length; i++) {
- var line = lines [i];
- string pname;
- RPFP.Transformer annot;
- GetDefun(line, out pname, out annot);
-
- if(pmap.ContainsKey(pname)){
- var node = pmap[pname];
- node.Annotation = annot;
- }
- else if(pname[0] != '@'){ // if not an internal symbol
- HandleProverError ("Prover error: got unknown predicate:" + pname);
- throw new BadExprFromProver ();
- }
- }
-
- }
-
- private void GetDefun(SExpr line, out string pname, out RPFP.Transformer annot)
- {
- if (line.Name != "define-fun")
- {
- HandleProverError("Prover error: expected define-fun but got:" + line.Name);
- throw new BadExprFromProver();
- }
- if (line.ArgCount != 4)
- {
- HandleProverError("Prover error: define-fun has wrong number of arguments");
- throw new BadExprFromProver();
- }
- pname = StripCruft(line.Arguments[0].Name);
- var pvars = line.Arguments[1];
- var pbody = line.Arguments[3]; // range has to be Bool
- var binding = new Dictionary<string, VCExpr>();
- var pvs = new List<VCExpr>();
- foreach (var b in pvars.Arguments)
- {
- var e = SExprToVar(b);
- pvs.Add(e);
- binding.Add(StripCruft(b.Name), e);
- }
- VCExpr bexpr = SExprToVCExpr(pbody, binding);
-
- annot = rpfp.CreateRelation(pvs.ToArray(), bexpr);
- }
-
- private RPFP.Node SExprToCex(SExpr resp, ErrorHandler handler,
- Dictionary<int,Dictionary<string,string>> varSubst)
- {
- Dictionary<string, RPFP.Node> nmap = new Dictionary<string,RPFP.Node>();
- Dictionary<string, RPFP.Node> pmap = new Dictionary<string,RPFP.Node>();
-
- foreach(var node in rpfp.nodes)
- pmap.Add((node.Name as VCExprBoogieFunctionOp).Func.Name,node);
-
- RPFP.Node topnode = null;
- var lines = resp.Arguments;
-
- // last line of derivation is from query, skip it
- for (int i = 0; i < lines.Length-1; i++)
- {
- var line = lines[i];
- if (line.ArgCount != 6)
- {
- HandleProverError("bad derivation line from prover: " + line.ToString());
- return null;
- }
- var name = line[0];
- var conseq = line[1];
- var rule = line[2];
- var subst = line[3];
- var labs = line[4];
- var refs = line[5];
- var predName = conseq.Name;
- {
- string spacer = "@@"; // Hack! UniqueNamer is adding these and I can't stop it!
- int pos = predName.LastIndexOf(spacer);
- if (pos >= 0)
- predName = predName.Substring(0, pos);
- }
- RPFP.Node node = null;
- if (!pmap.TryGetValue(predName, out node))
- {
- HandleProverError("unknown predicate from prover: " + predName.ToString());
- return null;
- }
- RPFP.Node cexnode = rpfp.CloneNode(node);
- cexnode.map = node;
- nmap.Add(name.Name, cexnode);
- List<RPFP.Node> Chs = new List<RPFP.Node>();
-
- if (refs.Name != "ref")
- {
- HandleProverError("bad references from prover: " + refs.ToString());
- return null;
- }
- foreach (var c in refs.Arguments)
- {
- if (c.Name == "true")
- Chs.Add(null);
- else
- {
- RPFP.Node ch = null;
- if (!nmap.TryGetValue(c.Name, out ch))
- {
- HandleProverError("unknown reference from prover: " + c.ToString());
- return null;
- }
- Chs.Add(ch);
- }
- }
-
- if (!rule.Name.StartsWith("rule!"))
- {
- HandleProverError("bad rule name from prover: " + refs.ToString());
- return null;
- }
- int ruleNum = Convert.ToInt32(rule.Name.Substring(5)) - 1;
- if (ruleNum < 0 || ruleNum > rpfp.edges.Count)
- {
- HandleProverError("bad rule name from prover: " + refs.ToString());
- return null;
- }
- RPFP.Edge orig_edge = rpfp.edges[ruleNum];
- RPFP.Edge e = rpfp.CreateEdge(cexnode, orig_edge.F, Chs.ToArray());
- e.map = orig_edge;
- topnode = cexnode;
-
- if (labs.Name != "labels")
- {
- HandleProverError("bad labels from prover: " + labs.ToString());
- return null;
- }
- e.labels = new HashSet<string>();
- foreach (var l in labs.Arguments)
- e.labels.Add(l.Name);
-
- if (subst.Name != "subst")
- {
- HandleProverError("bad subst from prover: " + subst.ToString());
- return null;
- }
- Dictionary<string, string> dict = new Dictionary<string, string>();
- varSubst[e.number] = dict;
- foreach (var s in subst.Arguments)
- {
- if (s.Name != "=" || s.Arguments.Length != 2)
- {
- HandleProverError("bad equation from prover: " + s.ToString());
- return null;
- }
- string uniqueName = s.Arguments[0].Name;
- string spacer = "@@"; // Hack! UniqueNamer is adding these and I can't stop it!
- int pos = uniqueName.LastIndexOf(spacer);
- if (pos >= 0)
- uniqueName = uniqueName.Substring(0, pos);
- dict.Add(uniqueName, s.Arguments[1].ToString());
- }
-
- }
- if (topnode == null)
- {
- HandleProverError("empty derivation from prover: " + resp.ToString());
- }
- return topnode;
- }
-
- private Model SExprToModel(SExpr resp, ErrorHandler handler)
- {
- // Concatenate all the arguments
- string modelString = resp[0].Name;
- // modelString = modelString.Substring(7, modelString.Length - 8); // remove "(model " and final ")"
- var models = Model.ParseModels(new StringReader("Error model: \n" + modelString));
- if (models == null || models.Count == 0)
- {
- HandleProverError("no model from prover: " + resp.ToString());
- }
- return models[0];
- }
-
- private string QuantifiedVCExpr2String(VCExpr x)
- {
- return VCExpr2String(x, 1);
-#if false
- if (!(x is VCExprQuantifier))
- return VCExpr2String(x, 1);
- VCExprQuantifier node = (x as VCExprQuantifier);
- if(node.BoundVars.Count == 0)
- return VCExpr2String(x, 1);
-
- StringWriter wr = new StringWriter();
-
- 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.GetQuotedName(var, var.Name);
- Contract.Assert(printedName != null);
- wr.Write("({0} {1}) ", printedName, SMTLibExprLineariser.TypeToString(var.Type));
- }
-
- wr.Write(") ");
- wr.Write(VCExpr2String(node.Body, 1));
- wr.Write(")");
- string res = wr.ToString();
- return res;
-#endif
- }
-
- public override Outcome CheckRPFP(string descriptiveName, RPFP _rpfp, ErrorHandler handler,
- out RPFP.Node cex,
- Dictionary<int, Dictionary<string, string>> varSubst,
- Dictionary<string, int> extra_bound)
- {
- //Contract.Requires(descriptiveName != null);
- //Contract.Requires(vc != null);
- //Contract.Requires(handler != null);
- rpfp = _rpfp;
- cex = null;
-
-
- if (options.SeparateLogFiles) CloseLogFile(); // shouldn't really happen
-
- if (options.LogFilename != null && currentLogFile == null)
- {
- currentLogFile = OpenOutputFile(descriptiveName);
- currentLogFile.Write(common.ToString());
- }
-
- PrepareCommon();
-
- Push();
- SendThisVC("(fixedpoint-push)");
- foreach (var node in rpfp.nodes)
- {
- DeclCollector.RegisterRelation((node.Name as VCExprBoogieFunctionOp).Func);
- }
-
- LineariserOptions.Default.LabelsBelowQuantifiers = true;
- List<string> ruleStrings = new List<string>();
- var recursion_bound = CommandLineOptions.Clo.RecursionBound;
- foreach (var edge in rpfp.edges)
- {
- string node_name = (edge.Parent.Name as VCExprBoogieFunctionOp).Func.Name;
- string rule_name = "rule_" + edge.number.ToString();
- string rec_bound = "";
- if(extra_bound != null && extra_bound.ContainsKey(node_name))
- rec_bound = (recursion_bound + extra_bound[node_name]).ToString();
- string ruleString = "(rule " + QuantifiedVCExpr2String(rpfp.GetRule(edge)) + " " + rule_name + " " + rec_bound + "\n)";
- ruleStrings.Add(ruleString);
- }
- string queryString = "(query " + QuantifiedVCExpr2String(rpfp.GetQuery()) + "\n :engine duality\n :print-certificate true\n";
-
-#if true
- if (CommandLineOptions.Clo.StratifiedInlining != 0)
- queryString += " :stratified-inlining true\n";
- if (CommandLineOptions.Clo.RecursionBound > 0)
- queryString += " :recursion-bound " + Convert.ToString(CommandLineOptions.Clo.RecursionBound) + "\n";
-#endif
- queryString += ")";
- LineariserOptions.Default.LabelsBelowQuantifiers = false;
- FlushAxioms();
-
- PossiblyRestart();
-
- SendThisVC("(set-info :boogie-vc-id " + SMTLibNamer.QuoteId(descriptiveName) + ")");
- foreach(var rs in ruleStrings)
- SendThisVC(rs);
- FlushLogFile();
-
- if (Process != null)
- {
- Process.PingPong(); // flush any errors
-
-#if false
- // TODO: this is not going to work
- if (Process.Inspector != null)
- Process.Inspector.NewProblem(descriptiveName, vc, handler);
-#endif
- }
-
- SendThisVC(queryString);
- FlushLogFile();
-
- var result = Outcome.Undetermined;
-
- if (Process != null)
- {
-
- var resp = Process.GetProverResponse();
-
- if (proverErrors.Count > 0)
- {
- result = Outcome.Undetermined;
- foreach (var err in proverErrors)
- {
- if (err.Contains("canceled"))
- {
- result = Outcome.TimeOut;
- }
- }
- }
- else if(resp == null)
- HandleProverError("Prover did not respond");
- else switch (resp.Name)
- {
- case "unsat":
- result = Outcome.Valid;
- break;
- case "sat":
- result = Outcome.Invalid;
- break;
- case "unknown":
- result = Outcome.Invalid;
- break;
- case "bounded":
- result = Outcome.Bounded;
- break;
- case "error":
- if (resp.ArgCount > 0 && resp.Arguments[0].Name.Contains("canceled"))
- {
- result = Outcome.TimeOut;
- }
- else
- {
- HandleProverError("Prover error: " + resp.Arguments[0]);
- result = Outcome.Undetermined;
- }
- break;
- default:
- HandleProverError("Unexpected prover response: " + resp.ToString());
- break;
- }
-
- switch (result)
- {
- case Outcome.Invalid:
- {
- resp = Process.GetProverResponse();
- if (resp.Name == "derivation")
- {
- cex = SExprToCex(resp, handler,varSubst);
- }
- else
- HandleProverError("Unexpected prover response: " + resp.ToString());
- resp = Process.GetProverResponse();
- if (resp.Name == "model")
- {
- var model = SExprToModel(resp, handler);
- cex.owner.SetBackgroundModel(model);
- }
- else
- HandleProverError("Unexpected prover response: " + resp.ToString());
- break;
- }
- case Outcome.Valid:
- case Outcome.Bounded:
- {
- resp = Process.GetProverResponse();
- if (resp.Name == "fixedpoint")
- {
- // only get the response if we need it
- if(CommandLineOptions.Clo.PrintFixedPoint != null)
- SExprToSoln(resp, varSubst);
- }
- else
- HandleProverError("Unexpected prover response: " + resp.ToString());
- break;
- }
- default:
- break;
- }
-
-#if false
- while (true)
- {
- resp = Process.GetProverResponse();
- if (resp == null || Process.IsPong(resp))
- break;
- HandleProverError("Unexpected prover response: " + resp.ToString());
- }
-#endif
- }
- SendThisVC("(fixedpoint-pop)");
- Pop();
- AxiomsAreSetup = false;
-
- if (CommandLineOptions.Clo.PrintConjectures != null)
- {
- ReadConjectures(CommandLineOptions.Clo.PrintConjectures);
- }
-
- return result;
- }
-
- class MyFileParser : SExpr.Parser
- {
- SMTLibProcessTheoremProver parent;
-
- public MyFileParser(System.IO.StreamReader _sr, SMTLibProcessTheoremProver _parent)
- : base(_sr)
- {
- parent = _parent;
- }
- public override void ParseError(string msg)
- {
- parent.HandleProverError("Error in conjecture file from prover: " + msg);
- }
- }
-
- void ReadConjectures(string filename)
- {
- try
- {
- System.IO.StreamReader sr = new StreamReader(filename + ".tmp");
- SExpr.Parser p = new MyFileParser(sr, this);
- var sexps = p.ParseSExprs(false);
- Dictionary<string, RPFP.Node> pmap = GetNodeMap();
- foreach (var e in sexps)
- {
- string pname;
- RPFP.Transformer annot;
- GetDefun(e, out pname, out annot);
-
- if (pmap.ContainsKey(pname))
- {
- var c = new RPFP.Conjecture();
- c.node = pmap[pname];
- c.bound = annot;
- rpfp.conjectures.Add(c);
- }
- else if (pname[0] != '@')
- { // if not an internal symbol
- HandleProverError("Prover error: got unknown predicate:" + pname);
- throw new BadExprFromProver();
- }
- }
- sr.Close();
- }
- catch (Exception)
- {
- HandleProverError("No conjecture file from prover");
- throw new BadExprFromProver();
- }
- }
-
- private Dictionary<string, RPFP.Node> GetNodeMap()
- {
- Dictionary<string, RPFP.Node> pmap = new Dictionary<string, RPFP.Node>();
- foreach (var node in rpfp.nodes)
- pmap.Add((node.Name as VCExprBoogieFunctionOp).Func.Name, node);
- return pmap;
- }
-
- private static HashSet<string> usedLogNames = new HashSet<string>();
-
- private TextWriter OpenOutputFile(string descriptiveName)
- {
- Contract.Requires(descriptiveName != null);
- Contract.Ensures(Contract.Result<TextWriter>() != null);
-
- string filename = options.LogFilename;
- filename = Helpers.SubstituteAtPROC(descriptiveName, cce.NonNull(filename));
- var curFilename = filename;
-
- lock (usedLogNames) {
- int n = 1;
- while (usedLogNames.Contains(curFilename)) {
- curFilename = filename + "." + n++;
- }
- usedLogNames.Add(curFilename);
- }
-
- return new StreamWriter(curFilename, false);
- }
-
- private void FlushProverWarnings()
- {
- var handler = currentErrorHandler;
- if (handler != null) {
- lock (proverWarnings) {
- proverWarnings.Iter(handler.OnProverWarning);
- proverWarnings.Clear();
- }
- }
- }
-
- protected void HandleProverError(string s)
- {
- s = s.Replace("\r", "");
- lock (proverWarnings) {
- while (s.StartsWith("WARNING: ")) {
- var idx = s.IndexOf('\n');
- var warn = s;
- if (idx > 0) {
- warn = s.Substring(0, idx);
- s = s.Substring(idx + 1);
- } else {
- s = "";
- }
- warn = warn.Substring(9);
- proverWarnings.Add(warn);
- }
- }
-
- FlushProverWarnings();
-
- if (s == "") return;
-
- lock (proverErrors) {
- proverErrors.Add(s);
- Console.WriteLine("Prover error: " + s);
- }
- }
-
- [NoDefaultContract]
- public override Outcome CheckOutcome(ErrorHandler handler, int taskID = -1)
- {
- Contract.EnsuresOnThrow<UnexpectedProverOutputException>(true);
-
- var result = CheckOutcomeCore(handler, taskID: taskID);
- SendThisVC("(pop 1)");
- FlushLogFile();
-
- return result;
- }
-
- [NoDefaultContract]
- public override Outcome CheckOutcomeCore(ErrorHandler handler, int taskID = -1)
- {
- Contract.EnsuresOnThrow<UnexpectedProverOutputException>(true);
-
- var result = Outcome.Undetermined;
-
- if (Process == null)
- return result;
-
- try {
- currentErrorHandler = handler;
- FlushProverWarnings();
-
- int errorLimit;
- if (CommandLineOptions.Clo.ConcurrentHoudini) {
- Contract.Assert(taskID >= 0);
- errorLimit = CommandLineOptions.Clo.Cho[taskID].ProverCCLimit;
- } else {
- errorLimit = CommandLineOptions.Clo.ProverCCLimit;
- }
-
- if (errorLimit < 1)
- errorLimit = 1;
-
- int errorsLeft = errorLimit;
-
- var globalResult = Outcome.Undetermined;
-
- while (true) {
- string[] labels = null;
- bool popLater = false;
-
- try {
- errorsLeft--;
-
- result = GetResponse();
-
- if (CommandLineOptions.Clo.RunDiagnosticsOnTimeout && result == Outcome.TimeOut)
- {
- #region Run timeout diagnostics
-
- if (CommandLineOptions.Clo.TraceDiagnosticsOnTimeout)
- {
- Console.Out.WriteLine("Starting timeout diagnostics with initial time limit {0}.", options.TimeLimit);
- }
-
- SendThisVC("; begin timeout diagnostics");
-
- var start = DateTime.UtcNow;
- var unverified = new SortedSet<int>(ctx.TimeoutDiagnosticIDToAssertion.Keys);
- var timedOut = new SortedSet<int>();
- int frac = 2;
- int queries = 0;
- int timeLimitPerAssertion = 0 < options.TimeLimit ? (options.TimeLimit / 100) * CommandLineOptions.Clo.TimeLimitPerAssertionInPercent : 1000;
- while (true)
- {
- int rem = unverified.Count;
- if (rem == 0)
- {
- if (0 < timedOut.Count)
- {
- result = CheckSplit(timedOut, ref popLater, options.TimeLimit, timeLimitPerAssertion, ref queries);
- if (result == Outcome.Valid)
- {
- timedOut.Clear();
- }
- else if (result == Outcome.TimeOut)
- {
- // Give up and report which assertions were not verified.
- var cmds = timedOut.Select(id => ctx.TimeoutDiagnosticIDToAssertion[id]);
-
- if (cmds.Any())
- {
- handler.OnResourceExceeded("timeout after running diagnostics", cmds);
- }
- }
- }
- else
- {
- result = Outcome.Valid;
- }
- break;
- }
-
- // TODO(wuestholz): Try out different ways for splitting up the work (e.g., randomly).
- var cnt = Math.Max(1, rem / frac);
- // It seems like assertions later in the control flow have smaller indexes.
- var split = new SortedSet<int>(unverified.Where((val, idx) => (rem - idx - 1) < cnt));
- Contract.Assert(0 < split.Count);
- var splitRes = CheckSplit(split, ref popLater, timeLimitPerAssertion, timeLimitPerAssertion, ref queries);
- if (splitRes == Outcome.Valid)
- {
- unverified.ExceptWith(split);
- frac = 1;
- }
- else if (splitRes == Outcome.Invalid)
- {
- result = splitRes;
- break;
- }
- else if (splitRes == Outcome.TimeOut)
- {
- if (2 <= frac && (4 <= (rem / frac)))
- {
- frac *= 4;
- }
- else if (2 <= (rem / frac))
- {
- frac *= 2;
- }
- else
- {
- timedOut.UnionWith(split);
- unverified.ExceptWith(split);
- frac = 1;
- }
- }
- else
- {
- break;
- }
- }
-
- unverified.UnionWith(timedOut);
-
- var end = DateTime.UtcNow;
-
- SendThisVC("; end timeout diagnostics");
-
- if (CommandLineOptions.Clo.TraceDiagnosticsOnTimeout)
- {
- Console.Out.WriteLine("Terminated timeout diagnostics after {0:F0} ms and {1} prover queries.", end.Subtract(start).TotalMilliseconds, queries);
- Console.Out.WriteLine("Outcome: {0}", result);
- Console.Out.WriteLine("Unverified assertions: {0} (of {1})", unverified.Count, ctx.TimeoutDiagnosticIDToAssertion.Keys.Count);
-
- string filename = "unknown";
- var assertion = ctx.TimeoutDiagnosticIDToAssertion.Values.Select(t => t.Item1).FirstOrDefault(a => a.tok != null && a.tok != Token.NoToken && a.tok.filename != null);
- if (assertion != null)
- {
- filename = assertion.tok.filename;
- }
- File.AppendAllText("timeouts.csv", string.Format(";{0};{1};{2:F0};{3};{4};{5};{6}\n", filename, options.TimeLimit, end.Subtract(start).TotalMilliseconds, queries, result, unverified.Count, ctx.TimeoutDiagnosticIDToAssertion.Keys.Count));
- }
-
- #endregion
- }
-
- if (globalResult == Outcome.Undetermined)
- globalResult = result;
-
- if (result == Outcome.Invalid || result == Outcome.TimeOut || result == Outcome.OutOfMemory) {
- IList<string> xlabels;
- if (CommandLineOptions.Clo.UseLabels) {
- labels = GetLabelsInfo();
- if (labels == null)
- {
- xlabels = new string[] { };
- }
- else
- {
- xlabels = labels.Select(a => a.Replace("@", "").Replace("+", "")).ToList();
- }
- }
- else if(CommandLineOptions.Clo.SIBoolControlVC) {
- labels = new string[0];
- xlabels = labels;
- } else {
- labels = CalculatePath(handler.StartingProcId());
- xlabels = labels;
- }
- Model model = (result == Outcome.TimeOut || result == Outcome.OutOfMemory) ? null :
- GetErrorModel();
- handler.OnModel(xlabels, model, result);
- }
-
- if (labels == null || !labels.Any() || errorsLeft == 0) break;
- } finally {
- if (popLater)
- {
- SendThisVC("(pop 1)");
- }
- }
-
- if (CommandLineOptions.Clo.UseLabels) {
- var negLabels = labels.Where(l => l.StartsWith("@")).ToArray();
- var posLabels = labels.Where(l => !l.StartsWith("@"));
- Func<string, string> lbl = (s) => SMTLibNamer.QuoteId(SMTLibNamer.LabelVar(s));
- if (!options.MultiTraces)
- posLabels = Enumerable.Empty<string>();
- var conjuncts = posLabels.Select(s => "(not " + lbl(s) + ")").Concat(negLabels.Select(lbl)).ToArray();
- string expr = conjuncts.Length == 1 ? conjuncts[0] : ("(or " + conjuncts.Concat(" ") + ")"); ;
- if (!conjuncts.Any())
- {
- expr = "false";
- }
- SendThisVC("(assert " + expr + ")");
- SendThisVC("(check-sat)");
- }
- else {
- string source = labels[labels.Length - 2];
- string target = labels[labels.Length - 1];
- SendThisVC("(assert (not (= (ControlFlow 0 " + source + ") (- " + target + "))))");
- SendThisVC("(check-sat)");
- }
- }
-
- FlushLogFile();
-
- if (CommandLineOptions.Clo.RestartProverPerVC && Process != null)
- Process.NeedsRestart = true;
-
- return globalResult;
-
- } finally {
- currentErrorHandler = null;
- }
- }
-
- private Outcome CheckSplit(SortedSet<int> split, ref bool popLater, int timeLimit, int timeLimitPerAssertion, ref int queries)
- {
- var tla = timeLimitPerAssertion * split.Count;
-
- if (popLater)
- {
- SendThisVC("(pop 1)");
- }
-
- SendThisVC("(push 1)");
- SendThisVC(string.Format("(set-option :{0} {1})", Z3.SetTimeoutOption(), (0 < tla && tla < timeLimit) ? tla : timeLimit));
- popLater = true;
-
- SendThisVC(string.Format("; checking split VC with {0} unverified assertions", split.Count));
- var expr = VCExpressionGenerator.True;
- foreach (var i in ctx.TimeoutDiagnosticIDToAssertion.Keys)
- {
- var lit = VCExprGen.Function(VCExpressionGenerator.TimeoutDiagnosticsOp, VCExprGen.Integer(Microsoft.Basetypes.BigNum.FromInt(i)));
- if (split.Contains(i)) {
- lit = VCExprGen.Not(lit);
- }
- expr = VCExprGen.AndSimp(expr, lit);
- }
- SendThisVC("(assert " + VCExpr2String(expr, 1) + ")");
- if (options.Solver == SolverKind.Z3)
- {
- SendThisVC("(apply (then (using-params propagate-values :max_rounds 1) simplify) :print false)");
- }
- FlushLogFile();
- SendThisVC("(check-sat)");
- queries++;
- return GetResponse();
- }
-
- public override string[] CalculatePath(int controlFlowConstant) {
- SendThisVC("(get-value ((ControlFlow " + controlFlowConstant + " 0)))");
- var path = new List<string>();
- while (true) {
- var resp = Process.GetProverResponse();
- if (resp == null) break;
- if (!(resp.Name == "" && resp.ArgCount == 1)) break;
- resp = resp.Arguments[0];
- if (!(resp.Name == "" && resp.ArgCount == 2)) break;
- resp = resp.Arguments[1];
- var v = resp.Name;
- if (v == "-" && resp.ArgCount == 1) {
- v = resp.Arguments[0].Name;
- path.Add(v);
- break;
- }
- else if (resp.ArgCount != 0)
- break;
- path.Add(v);
- SendThisVC("(get-value ((ControlFlow " + controlFlowConstant + " " + v + ")))");
- }
- return path.ToArray();
- }
-
-
- private class SMTErrorModelConverter {
- private struct SMTDataType {
- public string Constructor;
- public List<SExpr> Types;
- }
-
- private List<SExpr> ErrorModelTodo;
- private SMTLibProcessTheoremProver Parent;
- private StringBuilder ErrorModel = new StringBuilder();
- private HashSet<SExpr> TopLevelProcessed = new HashSet<SExpr>();
- private int NumNewArrays = 0;
- private Dictionary<string, int> SortSet = new Dictionary<string, int>();
- private Dictionary<string, SMTDataType> DataTypes = new Dictionary<string, SMTDataType>();
- private Dictionary<string, SExpr> Functions = new Dictionary<string, SExpr>();
-
- public SMTErrorModelConverter(SExpr _ErrorModel, SMTLibProcessTheoremProver _Parent) {
- ErrorModelTodo = _ErrorModel.Arguments.ToList();;
- Parent = _Parent;
- }
-
- public string Convert() {
- ConvertErrorModel(ErrorModel);
- return ErrorModel.ToString();
- }
-
- bool isConstArray(SExpr element, SExpr type) {
- if (type.Name != "Array")
- return false;
-
- if (element.Name == "__array_store_all__") // CVC4 1.4
- return true;
- else if (element.Name == "" && element[0].Name == "as" &&
- element[0][0].Name == "const") // CVC4 > 1.4
- return true;
-
- return false;
- }
-
- SExpr getConstArrayElement(SExpr element) {
- if (element.Name == "__array_store_all__") // CVC4 1.4
- return element[1];
- else if (element.Name == "" && element[0].Name == "as" &&
- element[0][0].Name == "const") // CVC4 > 1.4
- return element[1];
-
- Parent.HandleProverError("Unexpected value: " + element);
- throw new BadExprFromProver ();
- }
-
- void ConstructComplexValue(SExpr element, SExpr type, StringBuilder m) {
- if (type.Name == "Array") {
- if (element.Name == "store" || isConstArray(element, type)) {
- NumNewArrays++;
- m.Append("as-array[k!" + NumNewArrays + ']');
- SExpr[] args = {new SExpr("k!" + NumNewArrays), new SExpr(""), type, element};
- var newElement = new SExpr("define-fun", args);
- TopLevelProcessed.Add(newElement);
- ErrorModelTodo.Add(newElement);
- return;
- }
- }
-
- ConstructSimpleValue(element, type, m);
- }
-
- void ConstructSimpleValue(SExpr element, SExpr type, StringBuilder m) {
- if (type.Name == "Bool" && element.ArgCount == 0) {
- m.Append(element.ToString());
- return;
- }
-
- if (type.Name == "Int") {
- if (element.ArgCount == 0) {
- m.Append(element.ToString());
- return;
- } else if (element.Name == "-" && element.ArgCount == 1) {
- m.Append(element.ToString());
- return;
- }
- }
-
- if (type.Name == "_" && type.ArgCount == 2 && type[0].Name == "BitVec") {
- if (element.Name == "_" && element.ArgCount == 2 &&
- element[0].Name.StartsWith("bv") && element[0].ArgCount == 0 &&
- element[1].Name == type.Arguments[1].Name && element[1].ArgCount == 0) {
- m.Append(element[0].Name + '[' + element[1].Name + ']');
- return;
- }
- }
-
- if (type.Name == "Array") {
- while (element.Name == "store") {
- ConstructComplexValue(element[1], type[0], m);
- m.Append(" -> ");
- ConstructComplexValue(element[2], type[1], m);
- m.Append("\n ");
- if (element[0].Name != "store") {
- m.Append("else -> ");
- }
- element = element[0];
- }
-
- if (isConstArray(element, type)) {
- ConstructComplexValue(getConstArrayElement(element), type[1], m);
- return;
- } else if (element.Name == "_" && element.ArgCount == 2 &&
- element[0].Name == "as-array") {
- m.Append("as-array[" + element[1].Name + ']');
- return;
- }
- }
-
- if (SortSet.ContainsKey(type.Name) && SortSet[type.Name] == 0) {
- var prefix = "@uc_T_" + type.Name.Substring(2) + "_";
- if (element.Name.StartsWith(prefix)) {
- m.Append(type.Name + "!val!" + element.Name.Substring(prefix.Length));
- return;
- }
- }
-
- if (Functions.ContainsKey(element.Name) &&
- type.Name == Functions[element.Name].Name) {
- m.Append(element.Name);
- return;
- }
-
- if (DataTypes.ContainsKey(type.Name) &&
- DataTypes[type.Name].Constructor == element.Name &&
- element.ArgCount == DataTypes[type.Name].Types.Count) {
- m.Append("(" + element.Name);
- for (int i = 0; i < element.ArgCount; ++i) {
- m.Append(" ");
- ConstructComplexValue(element[i], DataTypes[type.Name].Types[i], m);
- }
- m.Append(")");
- return;
- }
-
- Parent.HandleProverError("Unexpected value: " + element);
- throw new BadExprFromProver ();
- }
-
- void ConstructFunctionArguments(SExpr arguments, List<SExpr> argTypes, StringBuilder[] argValues) {
- if (arguments.Name == "and") {
- ConstructFunctionArguments(arguments[0], argTypes, argValues);
- ConstructFunctionArguments(arguments[1], argTypes, argValues);
- } else if (arguments.Name == "=" &&
- (arguments[0].Name.StartsWith("_ufmt_") || arguments[0].Name.StartsWith("x!"))) {
- int argNum;
- if (arguments[0].Name.StartsWith("_ufmt_"))
- argNum = System.Convert.ToInt32(arguments[0].Name.Substring("_uftm_".Length)) - 1;
- else /* if (arguments[0].Name.StartsWith("x!")) */
- argNum = System.Convert.ToInt32(arguments[0].Name.Substring("x!".Length)) - 1;
- if (argNum < 0 || argNum >= argTypes.Count) {
- Parent.HandleProverError("Unexpected function argument: " + arguments[0]);
- throw new BadExprFromProver ();
- }
- if (argValues[argNum] != null) {
- Parent.HandleProverError("Function argument defined multiple times: " + arguments[0]);
- throw new BadExprFromProver ();
- }
- argValues[argNum] = new StringBuilder();
- ConstructComplexValue(arguments[1], argTypes[argNum], argValues[argNum]);
- } else {
- Parent.HandleProverError("Unexpected function argument: " + arguments);
- throw new BadExprFromProver ();
- }
- }
-
- void ConstructFunctionElements(SExpr element, List<SExpr> argTypes, SExpr outType, StringBuilder m) {
- while (element.Name == "ite") {
- StringBuilder[] argValues = new StringBuilder[argTypes.Count];
- ConstructFunctionArguments(element[0], argTypes, argValues);
- foreach (var s in argValues)
- m.Append(s + " ");
- m.Append("-> ");
- ConstructComplexValue(element[1], outType, m);
- m.Append("\n ");
- if (element[2].Name != "ite")
- m.Append("else -> ");
- element = element[2];
- }
-
- ConstructComplexValue(element, outType, m);
- }
-
- void ConstructFunction(SExpr element, SExpr inType, SExpr outType, StringBuilder m) {
- List<SExpr> argTypes = new List<SExpr>();
-
- for (int i = 0; i < inType.ArgCount; ++i) {
- if (inType[i].Name != "_ufmt_" + (i + 1) && inType[i].Name != "x!" + (i + 1) &&
- !inType[i].Name.StartsWith("BOUND_VARIABLE_")) {
- Parent.HandleProverError("Unexpected function argument: " + inType[i].Name);
- throw new BadExprFromProver ();
- }
- argTypes.Add(inType[i][0]);
- }
-
- ConstructFunctionElements(element, argTypes, outType, m);
- }
-
- void ConstructDefine(SExpr element, StringBuilder m) {
- Debug.Assert(element.Name == "define-fun");
-
- if (element[1].ArgCount != 0)
- TopLevelProcessed.Add(element);
-
- m.Append(element[0] + " -> ");
- if (TopLevelProcessed.Contains(element))
- m.Append("{\n ");
-
- if (element[1].ArgCount == 0 && element[2].Name == "Array" && !TopLevelProcessed.Contains(element)) {
- ConstructComplexValue(element[3], element[2], m);
- } else if (element[1].ArgCount == 0) {
- ConstructSimpleValue(element[3], element[2], m);
- } else {
- ConstructFunction(element[3], element[1], element[2], m);
- }
-
- if (TopLevelProcessed.Contains(element))
- m.Append("\n}");
- m.Append("\n");
- }
-
- void ExtractDataType(SExpr datatypes) {
- Debug.Assert(datatypes.Name == "declare-datatypes");
-
- if (datatypes[0].Name != "" || datatypes[1].Name != "" || datatypes[1].ArgCount != 1) {
- Parent.HandleProverError("Unexpected datatype: " + datatypes);
- throw new BadExprFromProver ();
- }
-
- SMTDataType dt = new SMTDataType();
- SExpr typeDef = datatypes[1][0];
-
- if (typeDef.ArgCount != 1) {
- Parent.HandleProverError("Unexpected datatype: " + datatypes);
- throw new BadExprFromProver ();
- }
-
- dt.Constructor = typeDef[0].Name;
- dt.Types = new List<SExpr>();
-
- for (int i = 0; i < typeDef[0].ArgCount; ++i) {
- if (typeDef[0][i].ArgCount != 1) {
- Parent.HandleProverError("Unexpected datatype constructor: " + typeDef[0]);
- throw new BadExprFromProver ();
- }
- dt.Types.Add(typeDef[0][i][0]);
- }
-
- DataTypes[typeDef.Name] = dt;
- }
-
- private void ConvertErrorModel(StringBuilder m) {
- if (Parent.options.Solver == SolverKind.Z3) {
- // Datatype declarations are not returned by Z3, so parse common
- // instead. This is not very efficient, but currently not an issue,
- // as this not the normal way of interfacing with Z3.
- var ms = new MemoryStream(Encoding.ASCII.GetBytes(Parent.common.ToString()));
- var sr = new StreamReader(ms);
- SExpr.Parser p = new MyFileParser(sr, null);
- var sexprs = p.ParseSExprs(false);
- foreach (var e in sexprs) {
- switch (e.Name) {
- case "declare-datatypes":
- ExtractDataType(e);
- break;
- }
- }
- }
-
- while (ErrorModelTodo.Count > 0) {
- var e = ErrorModelTodo[0];
- ErrorModelTodo.RemoveAt(0);
-
- switch (e.Name) {
- case "define-fun":
- ConstructDefine(e, m);
- break;
- case "declare-sort":
- SortSet[e[0].Name] = System.Convert.ToInt32(e[1].Name);
- break;
- case "declare-datatypes":
- ExtractDataType(e);
- break;
- case "declare-fun":
- if (e[1].Name != "" || e[1].ArgCount > 0 || e[2].ArgCount > 0 ||
- e[2].Name == "Bool" || e[2].Name == "Int") {
- Parent.HandleProverError("Unexpected top level model element: " + e.Name);
- throw new BadExprFromProver ();
- }
- Functions[e[0].Name] = e[2];
- break;
- case "forall":
- // ignore
- break;
- default:
- Parent.HandleProverError("Unexpected top level model element: " + e.Name);
- throw new BadExprFromProver ();
- }
- }
- }
- }
-
- private Model GetErrorModel() {
- if (!options.ExpectingModel())
- return null;
- SendThisVC("(get-model)");
- Process.Ping();
- Model theModel = null;
- while (true) {
- var resp = Process.GetProverResponse();
- if (resp == null || Process.IsPong(resp))
- break;
- if (theModel != null)
- HandleProverError("Expecting only one model but got many");
-
- string modelStr = null;
- if (resp.Name == "model" && resp.ArgCount >= 1) {
- var converter = new SMTErrorModelConverter(resp, this);
- modelStr = converter.Convert();
- }
- else if (resp.ArgCount == 0 && resp.Name.Contains("->")) {
- modelStr = resp.Name;
- }
- else {
- HandleProverError("Unexpected prover response getting model: " + resp.ToString());
- }
-
- List<Model> models = null;
- try {
- switch (options.Solver) {
- case SolverKind.Z3:
- case SolverKind.CVC4:
- models = Model.ParseModels(new StringReader("Error model: \n" + modelStr));
- break;
- default:
- Debug.Assert(false);
- return null;
- }
- }
- catch (ArgumentException exn) {
- HandleProverError("Model parsing error: " + exn.Message);
- }
- if (models == null)
- HandleProverError("Could not parse any models");
- else if (models.Count == 0)
- HandleProverError("Could not parse any models");
- else if (models.Count > 1)
- HandleProverError("Expecting only one model but got many");
- else
- theModel = models[0];
- }
- return theModel;
- }
-
- private string[] GetLabelsInfo()
- {
- SendThisVC("(labels)");
- Process.Ping();
-
- string[] res = null;
- while (true) {
- var resp = Process.GetProverResponse();
- if (resp == null || Process.IsPong(resp))
- break;
- if (res != null)
- HandleProverError("Expecting only one sequence of labels but got many");
- if (resp.Name == "labels" && resp.ArgCount >= 1) {
- res = resp.Arguments.Select(a => a.Name.Replace("|", "")).ToArray();
- }
- else {
- HandleProverError("Unexpected prover response getting labels: " + resp.ToString());
- }
- }
- return res;
- }
-
- private Outcome GetResponse()
- {
- var result = Outcome.Undetermined;
- var wasUnknown = false;
-
- Process.Ping();
-
- while (true) {
- var resp = Process.GetProverResponse();
- if (resp == null || Process.IsPong(resp))
- break;
-
- switch (resp.Name) {
- case "unsat":
- result = Outcome.Valid;
- break;
- case "sat":
- result = Outcome.Invalid;
- break;
- case "unknown":
- result = Outcome.Invalid;
- wasUnknown = true;
- break;
- default:
- HandleProverError("Unexpected prover response: " + resp.ToString());
- break;
- }
- }
-
- if (wasUnknown) {
- SendThisVC("(get-info :reason-unknown)");
- Process.Ping();
- while (true) {
- var resp = Process.GetProverResponse();
- if (resp == null || Process.IsPong(resp))
- break;
-
- if (resp.ArgCount == 1 && resp.Name == ":reason-unknown") {
- switch (resp[0].Name) {
- case "memout":
- currentErrorHandler.OnResourceExceeded("memory");
- result = Outcome.OutOfMemory;
- Process.NeedsRestart = true;
- break;
- case "timeout": case "canceled":
- currentErrorHandler.OnResourceExceeded("timeout");
- result = Outcome.TimeOut;
- break;
- default:
- break;
- }
- } else {
- HandleProverError("Unexpected prover response (getting info about 'unknown' response): " + resp.ToString());
- }
- }
-
- }
-
- return result;
- }
-
- protected string VCExpr2String(VCExpr expr, int polarity)
- {
- Contract.Requires(expr != null);
- Contract.Ensures(Contract.Result<string>() != null);
-
- lock (gen)
- {
- DateTime start = DateTime.UtcNow;
- //if (CommandLineOptions.Clo.Trace)
- // Console.Write("Linearising ... ");
-
- // handle the types in the VCExpr
- TypeEraser eraser;
- switch (CommandLineOptions.Clo.TypeEncodingMethod)
- {
- case CommandLineOptions.TypeEncoding.Arguments:
- eraser = new TypeEraserArguments((TypeAxiomBuilderArguments)AxBuilder, gen);
- break;
- case CommandLineOptions.TypeEncoding.Monomorphic:
- eraser = null;
- break;
- default:
- eraser = new TypeEraserPremisses((TypeAxiomBuilderPremisses)AxBuilder, gen);
- break;
- }
- VCExpr exprWithoutTypes = eraser == null ? expr : eraser.Erase(expr, polarity);
- Contract.Assert(exprWithoutTypes != null);
-
- LetBindingSorter letSorter = new LetBindingSorter(gen);
- Contract.Assert(letSorter != null);
- VCExpr sortedExpr = letSorter.Mutate(exprWithoutTypes, true);
- Contract.Assert(sortedExpr != null);
- VCExpr sortedAxioms = letSorter.Mutate(AxBuilder.GetNewAxioms(), true);
- Contract.Assert(sortedAxioms != null);
-
- DeclCollector.Collect(sortedAxioms);
- DeclCollector.Collect(sortedExpr);
- FeedTypeDeclsToProver();
-
-
-
- AddAxiom(SMTLibExprLineariser.ToString(sortedAxioms, Namer, options));
- string res = SMTLibExprLineariser.ToString(sortedExpr, Namer, options);
- Contract.Assert(res != null);
-
- if (CommandLineOptions.Clo.Trace)
- {
- DateTime end = DateTime.UtcNow;
- TimeSpan elapsed = end - start;
- if (elapsed.TotalSeconds > 0.5)
- Console.WriteLine("Linearising [{0} s]", elapsed.TotalSeconds);
- }
- return res;
- }
- }
-
- // the list of all known axioms, where have to be included in each
- // verification condition
- private readonly List<string/*!>!*/> Axioms = new List<string/*!*/>();
- private bool AxiomsAreSetup = false;
-
-
-
-
- // similarly, a list of function/predicate declarations
- private readonly List<string/*!>!*/> TypeDecls = new List<string/*!*/>();
-
- protected void AddAxiom(string axiom)
- {
- Contract.Requires(axiom != null);
- Axioms.Add(axiom);
- // if (thmProver != null) {
- // LogActivity(":assume " + axiom);
- // thmProver.AddAxioms(axiom);
- // }
- }
-
- protected void AddTypeDecl(string decl)
- {
- Contract.Requires(decl != null);
- TypeDecls.Add(decl);
- // if (thmProver != null) {
- // LogActivity(decl);
- // thmProver.Feed(decl, 0);
- // }
- }
-
- ////////////////////////////////////////////////////////////////////////////
-
- private static string _backgroundPredicates;
-
- static void InitializeGlobalInformation()
- {
- Contract.Ensures(_backgroundPredicates != null);
- //throws ProverException, System.IO.FileNotFoundException;
- if (_backgroundPredicates == null) {
- if (CommandLineOptions.Clo.TypeEncodingMethod == CommandLineOptions.TypeEncoding.Monomorphic)
- {
- _backgroundPredicates = "";
- }
- else
- {
- _backgroundPredicates = @"
-(set-info :category ""industrial"")
-(declare-sort |T@U| 0)
-(declare-sort |T@T| 0)
-(declare-fun real_pow (Real Real) Real)
-(declare-fun UOrdering2 (|T@U| |T@U|) Bool)
-(declare-fun UOrdering3 (|T@T| |T@U| |T@U|) Bool)";
- }
- }
- }
-
- public override VCExpressionGenerator VCExprGen
- {
- get { return this.gen; }
- }
-
- //// Push/pop interface
-
- //List<string> pushedAssertions = new List<string>();
- //int numRealPushes;
- public override string VCExpressionToString(VCExpr vc)
- {
- return VCExpr2String(vc, 1);
- }
-
- public override void PushVCExpression(VCExpr vc)
- {
- throw new NotImplementedException();
-
- }
-
- public override void Pop()
- {
- SendThisVC("(pop 1)");
- DeclCollector.Pop();
- }
-
- public override int NumAxiomsPushed()
- {
- throw new NotImplementedException();
- //return numRealPushes + pushedAssertions.Count;
- }
-
- private void FlushPushedAssertions()
- {
- throw new NotImplementedException();
- }
-
- public override void Assert(VCExpr vc, bool polarity)
- {
- string a = "";
- if (polarity)
- {
- a = "(assert " + VCExpr2String(vc, 1) + ")";
- }
- else
- {
- a = "(assert (not\n" + VCExpr2String(vc, 1) + "\n))";
- }
- AssertAxioms();
- SendThisVC(a);
- }
-
- public override void DefineMacro(Macro f, VCExpr vc) {
- DeclCollector.AddFunction(f);
- string printedName = Namer.GetQuotedName(f, f.Name);
- var argTypes = f.InParams.Cast<Variable>().MapConcat(p => DeclCollector.TypeToStringReg(p.TypedIdent.Type), " ");
- string decl = "(define-fun " + printedName + " (" + argTypes + ") " + DeclCollector.TypeToStringReg(f.OutParams[0].TypedIdent.Type) + " " + VCExpr2String(vc, 1) + ")";
- AssertAxioms();
- SendThisVC(decl);
- }
-
- public override void AssertAxioms()
- {
- FlushAxioms();
- }
-
- public override void Check()
- {
- PrepareCommon();
- SendThisVC("(check-sat)");
- FlushLogFile();
- }
-
- public override void SetTimeOut(int ms)
- {
- if (options.Solver == SolverKind.Z3) {
- var name = Z3.SetTimeoutOption();
- var value = ms.ToString();
- options.TimeLimit = ms;
- options.SmtOptions.RemoveAll(ov => ov.Option == name);
- options.AddSmtOption(name, value);
- SendThisVC(string.Format("(set-option :{0} {1})", name, value));
- }
- }
-
- public override object Evaluate(VCExpr expr)
- {
- string vcString = VCExpr2String(expr, 1);
- SendThisVC("(get-value (" + vcString + "))");
- var resp = Process.GetProverResponse();
- if (resp == null) throw new VCExprEvaluationException();
- if (!(resp.Name == "" && resp.ArgCount == 1)) throw new VCExprEvaluationException();
- resp = resp.Arguments[0];
- if (resp.Name == "")
- {
- // evaluating an expression
- if (resp.ArgCount == 2)
- resp = resp.Arguments[1];
- else
- throw new VCExprEvaluationException();
- }
- else
- {
- // evaluating a variable
- if (resp.ArgCount == 1)
- resp = resp.Arguments[0];
- else
- throw new VCExprEvaluationException();
- }
- if (resp.Name == "-" && resp.ArgCount == 1) // negative int
- return Microsoft.Basetypes.BigNum.FromString("-" + resp.Arguments[0].Name);
- if (resp.Name == "_" && resp.ArgCount == 2 && resp.Arguments[0].Name.StartsWith("bv")) // bitvector
- return new BvConst(Microsoft.Basetypes.BigNum.FromString(resp.Arguments[0].Name.Substring("bv".Length)),
- int.Parse(resp.Arguments[1].Name));
- if (resp.ArgCount != 0)
- throw new VCExprEvaluationException();
- if (expr.Type.Equals(Boogie.Type.Bool))
- return bool.Parse(resp.Name);
- else if (expr.Type.Equals(Boogie.Type.Int))
- return Microsoft.Basetypes.BigNum.FromString(resp.Name);
- else
- return resp.Name;
- }
-
- /// <summary>
- /// Extra state for ApiChecker (used by stratifiedInlining)
- /// </summary>
- static int nameCounter = 0;
-
- public override Outcome CheckAssumptions(List<VCExpr> assumptions, out List<int> unsatCore, ErrorHandler handler)
- {
- unsatCore = new List<int>();
-
- Push();
- // Name the assumptions
- var nameToAssumption = new Dictionary<string, int>();
- int i = 0;
- foreach (var vc in assumptions)
- {
- var name = "a" + nameCounter.ToString();
- nameCounter++;
- nameToAssumption.Add(name, i);
-
- string vcString = VCExpr2String(vc, 1);
- AssertAxioms();
- SendThisVC(string.Format("(assert (! {0} :named {1}))", vcString, name));
- i++;
- }
- Check();
-
- var outcome = CheckOutcomeCore(handler);
-
- if (outcome != Outcome.Valid) {
- Pop();
- return outcome;
- }
-
- Contract.Assert(usingUnsatCore, "SMTLib prover not setup for computing unsat cores");
- SendThisVC("(get-unsat-core)");
- var resp = Process.GetProverResponse();
- unsatCore = new List<int>();
- if (resp.Name != "") unsatCore.Add(nameToAssumption[resp.Name]);
- foreach (var s in resp.Arguments) unsatCore.Add(nameToAssumption[s.Name]);
-
- FlushLogFile();
- Pop();
- return outcome;
- }
-
- public override void Push()
- {
- SendThisVC("(push 1)");
- DeclCollector.Push();
- }
-
- public override Outcome CheckAssumptions(List<VCExpr> hardAssumptions, List<VCExpr> softAssumptions, out List<int> unsatisfiedSoftAssumptions, ErrorHandler handler) {
- unsatisfiedSoftAssumptions = new List<int>();
-
- // First, convert both hard and soft assumptions to SMTLIB strings
- List<string> hardAssumptionStrings = new List<string>();
- foreach (var a in hardAssumptions) {
- hardAssumptionStrings.Add(VCExpr2String(a, 1));
- }
- List<string> currAssumptionStrings = new List<string>();
- foreach (var a in softAssumptions) {
- currAssumptionStrings.Add(VCExpr2String(a, 1));
- }
-
- Push();
- AssertAxioms();
- foreach (var a in hardAssumptionStrings) {
- SendThisVC("(assert " + a + ")");
- }
- Check();
- Outcome outcome = GetResponse();
- if (outcome != Outcome.Invalid) {
- Pop();
- return outcome;
- }
-
- int k = 0;
- List<string> relaxVars = new List<string>();
- while (true) {
- Push();
- foreach (var a in currAssumptionStrings) {
- SendThisVC("(assert " + a + ")");
- }
- Check();
- outcome = CheckOutcomeCore(handler);
- if (outcome != Outcome.Valid)
- break;
- Pop();
- string relaxVar = "relax_" + k;
- relaxVars.Add(relaxVar);
- SendThisVC("(declare-fun " + relaxVar + " () Int)");
- List<string> nextAssumptionStrings = new List<string>();
- for (int i = 0; i < currAssumptionStrings.Count; i++) {
- string constraint = "(= " + relaxVar + " " + i + ")";
- nextAssumptionStrings.Add("(or " + currAssumptionStrings[i] + " " + constraint + ")");
- }
- currAssumptionStrings = nextAssumptionStrings;
- k++;
- }
-
- if (outcome == Outcome.Invalid) {
- foreach (var relaxVar in relaxVars) {
- SendThisVC("(get-value (" + relaxVar + "))");
- FlushLogFile();
- var resp = Process.GetProverResponse();
- if (resp == null) break;
- if (!(resp.Name == "" && resp.ArgCount == 1)) break;
- resp = resp.Arguments[0];
- if (!(resp.Name != "" && resp.ArgCount == 1)) break;
- resp = resp.Arguments[0];
- if (resp.ArgCount != 0)
- break;
- int v;
- if (int.TryParse(resp.Name, out v))
- unsatisfiedSoftAssumptions.Add(v);
- else
- break;
- }
- Pop();
- }
-
- Pop();
- return outcome;
- }
- }
-
- public class SMTLibInterpolatingProcessTheoremProver : SMTLibProcessTheoremProver
- {
- public SMTLibInterpolatingProcessTheoremProver(ProverOptions options, VCExpressionGenerator gen,
- SMTLibProverContext ctx)
- : base(AddInterpOption(options), gen, ctx)
- {
-
- }
-
- private static ProverOptions AddInterpOption(ProverOptions options)
- {
- var opts = (SMTLibProverOptions)options;
- opts.AddSmtOption("produce-interpolants", "true");
- if (CommandLineOptions.Clo.PrintFixedPoint == null)
- CommandLineOptions.Clo.PrintFixedPoint = "itp.fixedpoint.bpl";
- return opts;
- }
-
- public override void AssertNamed(VCExpr vc, bool polarity, string name)
- {
- string vcString;
- if (polarity)
- {
- vcString = VCExpr2String(vc, 1);
- }
- else
- {
- vcString = "(not " + VCExpr2String(vc, 1) + ")";
- }
- AssertAxioms();
- SendThisVC(string.Format("(assert (! {0} :named {1}))", vcString, name));
- }
-
- public override VCExpr ComputeInterpolant(VCExpr A, VCExpr B)
- {
- string A_str = VCExpr2String(A, 1);
- string B_str = VCExpr2String(B, 1);
-
- AssertAxioms();
- SendThisVC("(compute-interpolant " + A_str + " " + B_str + ")");
-
- SExpr interpolant;
- Outcome result = GetInterpolantResponse(out interpolant);
-
- if (result != Outcome.Valid)
- return null;
-
- VCExpr interpolantVC = SExprToVCExpr(interpolant, new Dictionary<string, VCExpr>());
- return interpolantVC;
- }
-
- private Outcome GetInterpolantResponse(out SExpr interpolant)
- {
- var result = Outcome.Undetermined;
- var wasUnknown = false;
- interpolant = null;
-
- Process.Ping();
- bool onlyOnce = false;
-
- while (true)
- {
- var resp = Process.GetProverResponse();
- if (resp == null || Process.IsPong(resp))
- break;
-
- switch (resp.Name)
- {
- case "unsat":
- result = Outcome.Valid;
- break;
- case "sat":
- result = Outcome.Invalid;
- break;
- case "unknown":
- result = Outcome.Invalid;
- wasUnknown = true;
- break;
- default:
- if (result == Outcome.Valid)
- {
- interpolant = resp as SExpr;
-
- Contract.Assert(onlyOnce == false);
- onlyOnce = true;
- continue;
- }
- HandleProverError("Unexpected prover response: " + resp.ToString());
- break;
- }
- }
-
- if (wasUnknown)
- {
- SendThisVC("(get-info :reason-unknown)");
- Process.Ping();
-
- while (true)
- {
- var resp = Process.GetProverResponse();
- if (resp == null || Process.IsPong(resp))
- break;
-
- if (resp.ArgCount == 1 && resp.Name == ":reason-unknown")
- {
- switch (resp[0].Name)
- {
- case "memout":
- currentErrorHandler.OnResourceExceeded("memory");
- result = Outcome.OutOfMemory;
- Process.NeedsRestart = true;
- break;
- case "timeout":
- case "canceled":
- currentErrorHandler.OnResourceExceeded("timeout");
- result = Outcome.TimeOut;
- break;
- default:
- break;
- }
- }
- else
- {
- HandleProverError("Unexpected prover response (getting info about 'unknown' response): " + resp.ToString());
- }
- }
- }
-
- return result;
- }
-
- public override List<VCExpr> GetTreeInterpolant(List<string> root, List<string> leaves)
- {
- List<VCExpr> result = new List<VCExpr>();
-
- string vcStr = "true";
- foreach (string str in root)
- vcStr = vcStr + " " + str;
- foreach (string str in leaves)
- vcStr = vcStr + "\r\n (interp " + str + ")";
-
- vcStr = "(get-interpolant (and\r\n" + vcStr + "\r\n))";
- SendThisVC(vcStr);
- if(currentLogFile != null) currentLogFile.Flush();
-
- List<SExpr> interpolantList;
- GetTreeInterpolantResponse(out interpolantList);
-
- Dictionary<string, VCExpr> bound = new Dictionary<string, VCExpr>();
- foreach (SExpr sexpr in interpolantList)
- {
- VCExpr interpolantVC = SExprToVCExpr(sexpr, bound);
- result.Add(interpolantVC);
- }
-
- return result;
- }
-
- private void GetTreeInterpolantResponse(out List<SExpr> interpolantList)
- {
- interpolantList = new List<SExpr>();
-
- Process.Ping();
-
- while (true)
- {
- var resp = Process.GetProverResponse();
- if (resp == null || Process.IsPong(resp))
- break;
-
- SExpr interpolant = resp as SExpr;
- if(interpolant == null)
- HandleProverError("Unexpected prover response: got null for interpolant!");
- interpolantList.Add(interpolant);
- }
- }
- }
-
- public class SMTLibProverContext : DeclFreeProverContext
- {
- internal SMTLibProcessTheoremProver parent;
-
- public readonly Dictionary<CtorType, List<Function>> KnownDatatypeConstructors = new Dictionary<CtorType, List<Function>>();
-
- public SMTLibProverContext(VCExpressionGenerator gen,
- VCGenerationOptions genOptions)
- : base(gen, genOptions)
- {
- }
-
- protected SMTLibProverContext(SMTLibProverContext par)
- : base(par)
- {
- }
-
- public override object Clone()
- {
- return new SMTLibProverContext(this);
- }
-
- public override string Lookup(VCExprVar var)
- {
- VCExprVar v = parent.AxBuilder.TryTyped2Untyped(var);
- if (v != null) {
- var = v;
- }
- return parent.Namer.Lookup(var);
- }
-
- public override void DeclareFunction(Function f, string attributes) {
- if (f is DatatypeConstructor) {
- CtorType datatype = (CtorType) f.OutParams[0].TypedIdent.Type;
- if (!KnownDatatypeConstructors.ContainsKey(datatype))
- KnownDatatypeConstructors[datatype] = new List<Function>();
- KnownDatatypeConstructors[datatype].Add(f);
- }
- base.DeclareFunction(f, attributes);
- }
- }
-
- public class Factory : ProverFactory
- {
- // Set programmatically
- public static bool UseInterpolation = false;
-
- public override object SpawnProver(ProverOptions options, object ctxt)
- {
- //Contract.Requires(ctxt != null);
- //Contract.Requires(options != null);
- Contract.Ensures(Contract.Result<object>() != null);
-
- return this.SpawnProver(options,
- cce.NonNull((SMTLibProverContext)ctxt).ExprGen,
- cce.NonNull((SMTLibProverContext)ctxt));
- }
-
- public override object NewProverContext(ProverOptions options)
- {
- //Contract.Requires(options != null);
- Contract.Ensures(Contract.Result<object>() != null);
-
- VCExpressionGenerator gen = new VCExpressionGenerator();
- List<string>/*!>!*/ proverCommands = new List<string/*!*/>();
- proverCommands.Add("smtlib");
- var opts = (SMTLibProverOptions)options ;
- if (opts.Solver == SolverKind.Z3)
- proverCommands.Add("z3");
- else
- proverCommands.Add("external");
- VCGenerationOptions genOptions = new VCGenerationOptions(proverCommands);
- return new SMTLibProverContext(gen, genOptions);
- }
-
- public override ProverOptions BlankProverOptions()
- {
- return new SMTLibProverOptions();
- }
-
- protected virtual SMTLibProcessTheoremProver SpawnProver(ProverOptions options,
- VCExpressionGenerator gen,
- SMTLibProverContext ctx)
- {
- Contract.Requires(options != null);
- Contract.Requires(gen != null);
- Contract.Requires(ctx != null);
- Contract.Ensures(Contract.Result<SMTLibProcessTheoremProver>() != null);
-
- if (UseInterpolation)
- return new SMTLibInterpolatingProcessTheoremProver(options, gen, ctx);
-
- return new SMTLibProcessTheoremProver(options, gen, ctx);
- }
-
- public override bool SupportsLabels(ProverOptions options)
- {
- return ((SMTLibProverOptions)options).SupportsLabels;
- }
- }
-}
+//----------------------------------------------------------------------------- +// +// Copyright (C) Microsoft Corporation. All Rights Reserved. +// +//----------------------------------------------------------------------------- +using System; +using System.Collections; +using System.Collections.Generic; +using System.Threading; +using System.IO; +//using ExternalProver; +using System.Linq; +using System.Diagnostics; +using System.Diagnostics.Contracts; +using Microsoft.Boogie.AbstractInterpretation; +using Microsoft.Boogie; +using Microsoft.Boogie.VCExprAST; +using Microsoft.Boogie.Clustering; +using Microsoft.Boogie.TypeErasure; +using System.Text; + +using RPFP = Microsoft.Boogie.RPFP; + +namespace Microsoft.Boogie.SMTLib +{ + public class SMTLibProcessTheoremProver : ProverInterface + { + private readonly SMTLibProverContext ctx; + private VCExpressionGenerator gen; + private readonly SMTLibProverOptions options; + private bool usingUnsatCore; + private RPFP rpfp = null; + + [ContractInvariantMethod] + void ObjectInvariant() + { + Contract.Invariant(ctx != null); + Contract.Invariant(AxBuilder != null); + Contract.Invariant(Namer != null); + Contract.Invariant(DeclCollector != null); + Contract.Invariant(cce.NonNullElements(Axioms)); + Contract.Invariant(cce.NonNullElements(TypeDecls)); + Contract.Invariant(_backgroundPredicates != null); + + } + + + [NotDelayed] + public SMTLibProcessTheoremProver(ProverOptions options, VCExpressionGenerator gen, + SMTLibProverContext ctx) + { + Contract.Requires(options != null); + Contract.Requires(gen != null); + Contract.Requires(ctx != null); + + InitializeGlobalInformation(); + + this.options = (SMTLibProverOptions)options; + this.ctx = ctx; + this.gen = gen; + this.usingUnsatCore = false; + + SetupAxiomBuilder(gen); + + Namer = new SMTLibNamer(); + ctx.parent = this; + this.DeclCollector = new TypeDeclCollector((SMTLibProverOptions)options, Namer); + + if (CommandLineOptions.Clo.PrintFixedPoint != null || CommandLineOptions.Clo.PrintConjectures != null) + { + declHandler = new MyDeclHandler(); + DeclCollector.SetDeclHandler(declHandler); + } + + SetupProcess(); + + if (CommandLineOptions.Clo.StratifiedInlining > 0 || CommandLineOptions.Clo.ContractInfer + || CommandLineOptions.Clo.SecureVcGen != null) + { + // Prepare for ApiChecker usage + if (options.LogFilename != null && currentLogFile == null) + { + currentLogFile = OpenOutputFile(""); + } + PrepareCommon(); + } + } + + private void SetupAxiomBuilder(VCExpressionGenerator gen) + { + switch (CommandLineOptions.Clo.TypeEncodingMethod) + { + case CommandLineOptions.TypeEncoding.Arguments: + AxBuilder = new TypeAxiomBuilderArguments(gen); + AxBuilder.Setup(); + break; + case CommandLineOptions.TypeEncoding.Monomorphic: + AxBuilder = new TypeAxiomBuilderPremisses(gen); + break; + default: + AxBuilder = new TypeAxiomBuilderPremisses(gen); + AxBuilder.Setup(); + break; + } + } + + ProcessStartInfo ComputeProcessStartInfo() + { + var path = this.options.ProverPath; + switch (options.Solver) { + case SolverKind.Z3: + if (path == null) + path = Z3.ExecutablePath(); + return SMTLibProcess.ComputerProcessStartInfo(path, "AUTO_CONFIG=false -smt2 -in"); + case SolverKind.CVC4: + if (path == null) + path = CVC4.ExecutablePath(); + return SMTLibProcess.ComputerProcessStartInfo(path, "--lang=smt --no-strict-parsing --no-condense-function-values --incremental"); + default: + Debug.Assert(false); + return null; + } + } + + void SetupProcess() + { + if (Process != null) return; + + var psi = ComputeProcessStartInfo(); + Process = new SMTLibProcess(psi, this.options); + Process.ErrorHandler += this.HandleProverError; + } + + + void PossiblyRestart() + { + if (Process != null && Process.NeedsRestart) { + Process.Close(); + Process = null; + SetupProcess(); + Process.Send(common.ToString()); + } + } + + public override ProverContext Context + { + get + { + Contract.Ensures(Contract.Result<ProverContext>() != null); + + return ctx; + } + } + + internal TypeAxiomBuilder AxBuilder { get; private set; } + internal readonly UniqueNamer Namer; + readonly TypeDeclCollector DeclCollector; + protected SMTLibProcess Process; + readonly List<string> proverErrors = new List<string>(); + readonly List<string> proverWarnings = new List<string>(); + readonly StringBuilder common = new StringBuilder(); + protected TextWriter currentLogFile; + protected volatile ErrorHandler currentErrorHandler; + + private void FeedTypeDeclsToProver() + { + foreach (string s in DeclCollector.GetNewDeclarations()) { + Contract.Assert(s != null); + AddTypeDecl(s); + } + } + + private string Sanitize(string msg) + { + var idx = msg.IndexOf('\n'); + if (idx > 0) + msg = msg.Replace("\r", "").Replace("\n", "\r\n"); + return msg; + } + + public override void LogComment(string comment) + { + SendCommon("; " + comment); + } + + private void SendCommon(string s) + { + Send(s, true); + } + + protected void SendThisVC(string s) + { + Send(s, false); + } + + private void Send(string s, bool isCommon) + { + s = Sanitize(s); + + if (isCommon) + common.Append(s).Append("\r\n"); + + if (Process != null) + Process.Send(s); + if (currentLogFile != null) { + currentLogFile.WriteLine(s); + currentLogFile.Flush(); + } + } + + private void FindDependentTypes(Type type, List<CtorType> dependentTypes) + { + MapType mapType = type as MapType; + if (mapType != null) + { + foreach (Type t in mapType.Arguments) + { + FindDependentTypes(t, dependentTypes); + } + FindDependentTypes(mapType.Result, dependentTypes); + } + CtorType ctorType = type as CtorType; + if (ctorType != null && ctx.KnownDatatypeConstructors.ContainsKey(ctorType)) + { + dependentTypes.Add(ctorType); + } + } + + private void PrepareCommon() + { + if (common.Length == 0) + { + SendCommon("(set-option :print-success false)"); + SendCommon("(set-info :smt-lib-version 2.0)"); + if (options.ProduceModel()) + SendCommon("(set-option :produce-models true)"); + foreach (var opt in options.SmtOptions) + { + SendCommon("(set-option :" + opt.Option + " " + opt.Value + ")"); + } + + if (!string.IsNullOrEmpty(options.Logic)) + { + SendCommon("(set-logic " + options.Logic + ")"); + } + + // Set produce-unsat-cores last. It seems there's a bug in Z3 where if we set it earlier its value + // gets reset by other set-option commands ( https://z3.codeplex.com/workitem/188 ) + if (CommandLineOptions.Clo.ContractInfer && (CommandLineOptions.Clo.UseUnsatCoreForContractInfer || CommandLineOptions.Clo.ExplainHoudini)) + { + SendThisVC("(set-option :produce-unsat-cores true)"); + this.usingUnsatCore = true; + } + + SendCommon("; done setting options\n"); + SendCommon(_backgroundPredicates); + + if (options.UseTickleBool) + { + SendCommon("(declare-fun tickleBool (Bool) Bool)"); + SendCommon("(assert (and (tickleBool true) (tickleBool false)))"); + } + + if (CommandLineOptions.Clo.RunDiagnosticsOnTimeout) + { + SendCommon("(declare-fun timeoutDiagnostics (Int) Bool)"); + } + + if (ctx.KnownDatatypeConstructors.Count > 0) + { + GraphUtil.Graph<CtorType> dependencyGraph = new GraphUtil.Graph<CtorType>(); + foreach (CtorType datatype in ctx.KnownDatatypeConstructors.Keys) + { + dependencyGraph.AddSource(datatype); + foreach (Function f in ctx.KnownDatatypeConstructors[datatype]) + { + List<CtorType> dependentTypes = new List<CtorType>(); + foreach (Variable v in f.InParams) + { + FindDependentTypes(v.TypedIdent.Type, dependentTypes); + } + foreach (CtorType result in dependentTypes) + { + dependencyGraph.AddEdge(datatype, result); + } + } + } + GraphUtil.StronglyConnectedComponents<CtorType> sccs = new GraphUtil.StronglyConnectedComponents<CtorType>(dependencyGraph.Nodes, dependencyGraph.Predecessors, dependencyGraph.Successors); + sccs.Compute(); + foreach (GraphUtil.SCC<CtorType> scc in sccs) + { + string datatypeString = ""; + foreach (CtorType datatype in scc) + { + datatypeString += "(" + SMTLibExprLineariser.TypeToString(datatype) + " "; + foreach (Function f in ctx.KnownDatatypeConstructors[datatype]) + { + string quotedConstructorName = Namer.GetQuotedName(f, f.Name); + if (f.InParams.Count == 0) + { + datatypeString += quotedConstructorName + " "; + } + else + { + datatypeString += "(" + quotedConstructorName + " "; + foreach (Variable v in f.InParams) + { + string quotedSelectorName = Namer.GetQuotedName(v, v.Name + "#" + f.Name); + datatypeString += "(" + quotedSelectorName + " " + DeclCollector.TypeToStringReg(v.TypedIdent.Type) + ") "; + } + datatypeString += ") "; + } + } + datatypeString += ") "; + } + List<string> decls = DeclCollector.GetNewDeclarations(); + foreach (string decl in decls) + { + SendCommon(decl); + } + SendCommon("(declare-datatypes () (" + datatypeString + "))"); + } + } + if (CommandLineOptions.Clo.ProverPreamble != null) + SendCommon("(include \"" + CommandLineOptions.Clo.ProverPreamble + "\")"); + } + + if (!AxiomsAreSetup) + { + var axioms = ctx.Axioms; + var nary = axioms as VCExprNAry; + if (nary != null && nary.Op == VCExpressionGenerator.AndOp) + foreach (var expr in nary.UniformArguments) + { + var str = VCExpr2String(expr, -1); + if (str != "true") + AddAxiom(str); + } + else + AddAxiom(VCExpr2String(axioms, -1)); + AxiomsAreSetup = true; + } + } + + public override int FlushAxiomsToTheoremProver() + { + // we feed the axioms when begincheck is called. + return 0; + } + + private void FlushAxioms() + { + TypeDecls.Iter(SendCommon); + TypeDecls.Clear(); + foreach (string s in Axioms) { + Contract.Assert(s != null); + if (s != "true") + SendCommon("(assert " + s + ")"); + } + Axioms.Clear(); + //FlushPushedAssertions(); + } + + private void CloseLogFile() + { + if (currentLogFile != null) { + currentLogFile.Close(); + currentLogFile = null; + } + } + + private void FlushLogFile() + { + if (currentLogFile != null) { + currentLogFile.Flush(); + } + } + + public override void Close() + { + base.Close(); + CloseLogFile(); + if (Process != null) + Process.Close(); + } + + public override void BeginCheck(string descriptiveName, VCExpr vc, ErrorHandler handler) + { + //Contract.Requires(descriptiveName != null); + //Contract.Requires(vc != null); + //Contract.Requires(handler != null); + rpfp = null; + + if (options.SeparateLogFiles) CloseLogFile(); // shouldn't really happen + + if (options.LogFilename != null && currentLogFile == null) + { + currentLogFile = OpenOutputFile(descriptiveName); + currentLogFile.Write(common.ToString()); + } + + PrepareCommon(); + + string vcString = "(assert (not\n" + VCExpr2String(vc, 1) + "\n))"; + FlushAxioms(); + + PossiblyRestart(); + + SendThisVC("(push 1)"); + SendThisVC("(set-info :boogie-vc-id " + SMTLibNamer.QuoteId(descriptiveName) + ")"); + SendThisVC(vcString); + FlushLogFile(); + + if (Process != null) { + Process.PingPong(); // flush any errors + + if (Process.Inspector != null) + Process.Inspector.NewProblem(descriptiveName, vc, handler); + } + + SendThisVC("(check-sat)"); + FlushLogFile(); + } + + public override void Reset(VCExpressionGenerator gen) + { + if (options.Solver == SolverKind.Z3) + { + this.gen = gen; + SendThisVC("(reset)"); + + if (0 < common.Length) + { + var c = common.ToString(); + Process.Send(c); + if (currentLogFile != null) + { + currentLogFile.WriteLine(c); + } + } + } + } + + public override void FullReset(VCExpressionGenerator gen) + { + if (options.Solver == SolverKind.Z3) + { + this.gen = gen; + Namer.Reset(); + common.Clear(); + SetupAxiomBuilder(gen); + Axioms.Clear(); + TypeDecls.Clear(); + AxiomsAreSetup = false; + ctx.Reset(); + ctx.KnownDatatypeConstructors.Clear(); + ctx.parent = this; + DeclCollector.Reset(); + SendThisVC("; did a full reset"); + } + } + + + + private string StripCruft(string name){ + if(name.Contains("@@")) + return name.Remove(name.LastIndexOf ("@@")); + return name; + } + + private class BadExprFromProver : Exception + { + }; + + private delegate VCExpr ArgGetter (int pos); + + private delegate VCExpr[] ArgsGetter (); + + private delegate VCExprVar[] VarsGetter (); + + private VCExprOp VCStringToVCOp (string op) + { + switch (op) { + case "+" : + return VCExpressionGenerator.AddIOp; + case "-" : + return VCExpressionGenerator.SubIOp; + case "*" : + return VCExpressionGenerator.MulIOp; + case "div" : + return VCExpressionGenerator.DivIOp; + case "=" : + return VCExpressionGenerator.EqOp; + case "<=" : + return VCExpressionGenerator.LeOp; + case "<" : + return VCExpressionGenerator.LtOp; + case ">=" : + return VCExpressionGenerator.GeOp; + case ">" : + return VCExpressionGenerator.GtOp; + case "and" : + return VCExpressionGenerator.AndOp; + case "or" : + return VCExpressionGenerator.OrOp; + case "not" : + return VCExpressionGenerator.NotOp; + case "ite" : + return VCExpressionGenerator.IfThenElseOp; + default: + return null; + } + } + + private class MyDeclHandler : TypeDeclCollector.DeclHandler { + public Dictionary<string,VCExprVar> var_map = new Dictionary<string, VCExprVar>(); + public Dictionary<string,Function> func_map = new Dictionary<string, Function>(); + public override void VarDecl(VCExprVar v){ + var_map[v.Name] = v; + } + public override void FuncDecl(Function f){ + func_map[f.Name] = f; + } + public MyDeclHandler() { + } + } + + private MyDeclHandler declHandler = null; + + private VCExprVar SExprToVar (SExpr e) + { + if(e.Arguments.Count() != 1){ + HandleProverError ("Prover error: bad quantifier syntax"); + throw new BadExprFromProver (); + } + string vname = StripCruft(e.Name); + SExpr vtype = e[0]; + switch(vtype.Name){ + case "Int": + return gen.Variable(vname,Type.Int); + case "Bool": + return gen.Variable (vname,Type.Bool); + case "Array":{ + // TODO: handle more general array types + var idxType = Type.Int; // well, could be something else + var valueType = + (vtype.Arguments[1].Name == "Int") ? Type.Int : Type.Bool; + var types = new List<Type>(); + types.Add(idxType); + return gen.Variable (vname, new MapType(Token.NoToken,new List<TypeVariable>(),types,valueType)); + } + default: { + HandleProverError ("Prover error: bad type: " + vtype.Name); + throw new BadExprFromProver (); + } + } + } + + private VCExpr MakeBinary(VCExprOp op, VCExpr [] args) + { + if (args.Count() == 0) + { + // with zero args we need the identity of the op + if (op == VCExpressionGenerator.AndOp) + return VCExpressionGenerator.True; + if (op == VCExpressionGenerator.OrOp) + return VCExpressionGenerator.False; + if (op == VCExpressionGenerator.AddIOp) + { + Microsoft.Basetypes.BigNum x = Microsoft.Basetypes.BigNum.ZERO; + return gen.Integer(x); + } + HandleProverError("Prover error: bad expression "); + throw new BadExprFromProver(); + } + var temp = args[0]; + for (int i = 1; i < args.Count(); i++) + temp = gen.Function(op, temp, args[i]); + return temp; + } + + protected VCExpr SExprToVCExpr (SExpr e, Dictionary<string,VCExpr> bound) + { + if (e.Arguments.Count() == 0) { + var name = StripCruft(e.Name); + if (name [0] >= '0' && name [0] <= '9') { + Microsoft.Basetypes.BigNum x = Microsoft.Basetypes.BigNum.FromString(name); + return gen.Integer (x); + } + if (bound.ContainsKey (name)) { + return bound [name]; + } + if(name == "true") + return VCExpressionGenerator.True; + if(name == "false") + return VCExpressionGenerator.False; + if(declHandler.var_map.ContainsKey(name)) + return declHandler.var_map[name]; + HandleProverError ("Prover error: unknown symbol:" + name); + //throw new BadExprFromProver (); + var v = gen.Variable(name, Type.Int); + bound.Add(name, v); + return v; + } + ArgGetter g = i => SExprToVCExpr (e [i], bound); + ArgsGetter ga = () => e.Arguments.Select (x => SExprToVCExpr (x, bound)).ToArray (); + VarsGetter gb = () => e [0].Arguments.Select (x => SExprToVar (x)).ToArray (); + switch (e.Name) { + case "select" : + return gen.Select (ga ()); + case "store" : + return gen.Store (ga ()); + case "forall": + case "exists": + { + var binds = e.Arguments[0]; + var vcbinds = new List<VCExprVar>(); + var bound_copy = new Dictionary<string, VCExpr>(bound); + for (int i = 0; i < binds.Arguments.Count(); i++) + { + var bind = binds.Arguments[i]; + var symb = StripCruft(bind.Name); + var vcv = SExprToVar(bind); + vcbinds.Add(vcv); + bound[symb] = vcv; + } + var body = g(1); + if (e.Name == "forall") + body = gen.Forall(vcbinds, new List<VCTrigger>(), body); + else + body = gen.Exists(vcbinds, new List<VCTrigger>(), body); + bound = bound_copy; + return body; + } + case "-" : // have to deal with unary case + { + if(e.ArgCount == 1){ + var args = new VCExpr[2]; + args[0] = gen.Integer (Microsoft.Basetypes.BigNum.ZERO); + args[1] = g(0); + return gen.Function(VCStringToVCOp("-"),args); + } + return gen.Function(VCStringToVCOp("-"),ga()); + } + case "!" : // this is commentary + return g(0); + case "let" : { + // we expand lets exponentially since there is no let binding in Boogie surface syntax + bool expand_lets = true; + var binds = e.Arguments[0]; + var vcbinds = new List<VCExprLetBinding>(); + var bound_copy = new Dictionary<string, VCExpr>(bound); + for(int i = 0; i < binds.Arguments.Count(); i++){ + var bind = binds.Arguments[i]; + var symb = bind.Name; + var def = bind.Arguments[0]; + var vce = SExprToVCExpr(def, bound); + var vcv = gen.Variable(symb,vce.Type); + var vcb = gen.LetBinding(vcv,vce); + vcbinds.Add (vcb); + bound[symb] = expand_lets ? vce : vcv; + } + var body = g(1); + if(!expand_lets) + body = gen.Let(vcbinds,body); + bound = bound_copy; + return body; + } + + default: { + var op = VCStringToVCOp (e.Name); + if (op == null) { + var name = StripCruft(e.Name); + if(declHandler.func_map.ContainsKey(name)){ + Function f = declHandler.func_map[name]; + return gen.Function (f, ga()); + } + HandleProverError ("Prover error: unknown operator:" + e.Name); + throw new BadExprFromProver (); + } + if(op.Arity == 2) + return MakeBinary (op, ga ()); + return gen.Function(op, ga()); + } + } + } + + private void SExprToSoln (SExpr resp, + Dictionary<int,Dictionary<string,string>> varSubst) + { + Dictionary<string, RPFP.Node> pmap = new Dictionary<string,RPFP.Node> (); + + foreach (var node in rpfp.nodes) + pmap.Add ((node.Name as VCExprBoogieFunctionOp).Func.Name, node); + + var lines = resp.Arguments; + + // get all the predicate definitions + for (int i = 0; i < lines.Length; i++) { + var line = lines [i]; + string pname; + RPFP.Transformer annot; + GetDefun(line, out pname, out annot); + + if(pmap.ContainsKey(pname)){ + var node = pmap[pname]; + node.Annotation = annot; + } + else if(pname[0] != '@'){ // if not an internal symbol + HandleProverError ("Prover error: got unknown predicate:" + pname); + throw new BadExprFromProver (); + } + } + + } + + private void GetDefun(SExpr line, out string pname, out RPFP.Transformer annot) + { + if (line.Name != "define-fun") + { + HandleProverError("Prover error: expected define-fun but got:" + line.Name); + throw new BadExprFromProver(); + } + if (line.ArgCount != 4) + { + HandleProverError("Prover error: define-fun has wrong number of arguments"); + throw new BadExprFromProver(); + } + pname = StripCruft(line.Arguments[0].Name); + var pvars = line.Arguments[1]; + var pbody = line.Arguments[3]; // range has to be Bool + var binding = new Dictionary<string, VCExpr>(); + var pvs = new List<VCExpr>(); + foreach (var b in pvars.Arguments) + { + var e = SExprToVar(b); + pvs.Add(e); + binding.Add(StripCruft(b.Name), e); + } + VCExpr bexpr = SExprToVCExpr(pbody, binding); + + annot = rpfp.CreateRelation(pvs.ToArray(), bexpr); + } + + private RPFP.Node SExprToCex(SExpr resp, ErrorHandler handler, + Dictionary<int,Dictionary<string,string>> varSubst) + { + Dictionary<string, RPFP.Node> nmap = new Dictionary<string,RPFP.Node>(); + Dictionary<string, RPFP.Node> pmap = new Dictionary<string,RPFP.Node>(); + + foreach(var node in rpfp.nodes) + pmap.Add((node.Name as VCExprBoogieFunctionOp).Func.Name,node); + + RPFP.Node topnode = null; + var lines = resp.Arguments; + + // last line of derivation is from query, skip it + for (int i = 0; i < lines.Length-1; i++) + { + var line = lines[i]; + if (line.ArgCount != 6) + { + HandleProverError("bad derivation line from prover: " + line.ToString()); + return null; + } + var name = line[0]; + var conseq = line[1]; + var rule = line[2]; + var subst = line[3]; + var labs = line[4]; + var refs = line[5]; + var predName = conseq.Name; + { + string spacer = "@@"; // Hack! UniqueNamer is adding these and I can't stop it! + int pos = predName.LastIndexOf(spacer); + if (pos >= 0) + predName = predName.Substring(0, pos); + } + RPFP.Node node = null; + if (!pmap.TryGetValue(predName, out node)) + { + HandleProverError("unknown predicate from prover: " + predName.ToString()); + return null; + } + RPFP.Node cexnode = rpfp.CloneNode(node); + cexnode.map = node; + nmap.Add(name.Name, cexnode); + List<RPFP.Node> Chs = new List<RPFP.Node>(); + + if (refs.Name != "ref") + { + HandleProverError("bad references from prover: " + refs.ToString()); + return null; + } + foreach (var c in refs.Arguments) + { + if (c.Name == "true") + Chs.Add(null); + else + { + RPFP.Node ch = null; + if (!nmap.TryGetValue(c.Name, out ch)) + { + HandleProverError("unknown reference from prover: " + c.ToString()); + return null; + } + Chs.Add(ch); + } + } + + if (!rule.Name.StartsWith("rule!")) + { + HandleProverError("bad rule name from prover: " + refs.ToString()); + return null; + } + int ruleNum = Convert.ToInt32(rule.Name.Substring(5)) - 1; + if (ruleNum < 0 || ruleNum > rpfp.edges.Count) + { + HandleProverError("bad rule name from prover: " + refs.ToString()); + return null; + } + RPFP.Edge orig_edge = rpfp.edges[ruleNum]; + RPFP.Edge e = rpfp.CreateEdge(cexnode, orig_edge.F, Chs.ToArray()); + e.map = orig_edge; + topnode = cexnode; + + if (labs.Name != "labels") + { + HandleProverError("bad labels from prover: " + labs.ToString()); + return null; + } + e.labels = new HashSet<string>(); + foreach (var l in labs.Arguments) + e.labels.Add(l.Name); + + if (subst.Name != "subst") + { + HandleProverError("bad subst from prover: " + subst.ToString()); + return null; + } + Dictionary<string, string> dict = new Dictionary<string, string>(); + varSubst[e.number] = dict; + foreach (var s in subst.Arguments) + { + if (s.Name != "=" || s.Arguments.Length != 2) + { + HandleProverError("bad equation from prover: " + s.ToString()); + return null; + } + string uniqueName = s.Arguments[0].Name; + string spacer = "@@"; // Hack! UniqueNamer is adding these and I can't stop it! + int pos = uniqueName.LastIndexOf(spacer); + if (pos >= 0) + uniqueName = uniqueName.Substring(0, pos); + dict.Add(uniqueName, s.Arguments[1].ToString()); + } + + } + if (topnode == null) + { + HandleProverError("empty derivation from prover: " + resp.ToString()); + } + return topnode; + } + + private Model SExprToModel(SExpr resp, ErrorHandler handler) + { + // Concatenate all the arguments + string modelString = resp[0].Name; + // modelString = modelString.Substring(7, modelString.Length - 8); // remove "(model " and final ")" + var models = Model.ParseModels(new StringReader("Error model: \n" + modelString)); + if (models == null || models.Count == 0) + { + HandleProverError("no model from prover: " + resp.ToString()); + } + return models[0]; + } + + private string QuantifiedVCExpr2String(VCExpr x) + { + return VCExpr2String(x, 1); +#if false + if (!(x is VCExprQuantifier)) + return VCExpr2String(x, 1); + VCExprQuantifier node = (x as VCExprQuantifier); + if(node.BoundVars.Count == 0) + return VCExpr2String(x, 1); + + StringWriter wr = new StringWriter(); + + 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.GetQuotedName(var, var.Name); + Contract.Assert(printedName != null); + wr.Write("({0} {1}) ", printedName, SMTLibExprLineariser.TypeToString(var.Type)); + } + + wr.Write(") "); + wr.Write(VCExpr2String(node.Body, 1)); + wr.Write(")"); + string res = wr.ToString(); + return res; +#endif + } + + public override Outcome CheckRPFP(string descriptiveName, RPFP _rpfp, ErrorHandler handler, + out RPFP.Node cex, + Dictionary<int, Dictionary<string, string>> varSubst, + Dictionary<string, int> extra_bound) + { + //Contract.Requires(descriptiveName != null); + //Contract.Requires(vc != null); + //Contract.Requires(handler != null); + rpfp = _rpfp; + cex = null; + + + if (options.SeparateLogFiles) CloseLogFile(); // shouldn't really happen + + if (options.LogFilename != null && currentLogFile == null) + { + currentLogFile = OpenOutputFile(descriptiveName); + currentLogFile.Write(common.ToString()); + } + + PrepareCommon(); + + Push(); + SendThisVC("(fixedpoint-push)"); + foreach (var node in rpfp.nodes) + { + DeclCollector.RegisterRelation((node.Name as VCExprBoogieFunctionOp).Func); + } + + LineariserOptions.Default.LabelsBelowQuantifiers = true; + List<string> ruleStrings = new List<string>(); + var recursion_bound = CommandLineOptions.Clo.RecursionBound; + foreach (var edge in rpfp.edges) + { + string node_name = (edge.Parent.Name as VCExprBoogieFunctionOp).Func.Name; + string rule_name = "rule_" + edge.number.ToString(); + string rec_bound = ""; + if(extra_bound != null && extra_bound.ContainsKey(node_name)) + rec_bound = (recursion_bound + extra_bound[node_name]).ToString(); + string ruleString = "(rule " + QuantifiedVCExpr2String(rpfp.GetRule(edge)) + " " + rule_name + " " + rec_bound + "\n)"; + ruleStrings.Add(ruleString); + } + string queryString = "(query " + QuantifiedVCExpr2String(rpfp.GetQuery()) + "\n :engine duality\n :print-certificate true\n"; + +#if true + if (CommandLineOptions.Clo.StratifiedInlining != 0) + queryString += " :stratified-inlining true\n"; + if (CommandLineOptions.Clo.RecursionBound > 0) + queryString += " :recursion-bound " + Convert.ToString(CommandLineOptions.Clo.RecursionBound) + "\n"; +#endif + queryString += ")"; + LineariserOptions.Default.LabelsBelowQuantifiers = false; + FlushAxioms(); + + PossiblyRestart(); + + SendThisVC("(set-info :boogie-vc-id " + SMTLibNamer.QuoteId(descriptiveName) + ")"); + foreach(var rs in ruleStrings) + SendThisVC(rs); + FlushLogFile(); + + if (Process != null) + { + Process.PingPong(); // flush any errors + +#if false + // TODO: this is not going to work + if (Process.Inspector != null) + Process.Inspector.NewProblem(descriptiveName, vc, handler); +#endif + } + + SendThisVC(queryString); + FlushLogFile(); + + var result = Outcome.Undetermined; + + if (Process != null) + { + + var resp = Process.GetProverResponse(); + + if (proverErrors.Count > 0) + { + result = Outcome.Undetermined; + foreach (var err in proverErrors) + { + if (err.Contains("canceled")) + { + result = Outcome.TimeOut; + } + } + } + else if(resp == null) + HandleProverError("Prover did not respond"); + else switch (resp.Name) + { + case "unsat": + result = Outcome.Valid; + break; + case "sat": + result = Outcome.Invalid; + break; + case "unknown": + result = Outcome.Invalid; + break; + case "bounded": + result = Outcome.Bounded; + break; + case "error": + if (resp.ArgCount > 0 && resp.Arguments[0].Name.Contains("canceled")) + { + result = Outcome.TimeOut; + } + else + { + HandleProverError("Prover error: " + resp.Arguments[0]); + result = Outcome.Undetermined; + } + break; + default: + HandleProverError("Unexpected prover response: " + resp.ToString()); + break; + } + + switch (result) + { + case Outcome.Invalid: + { + resp = Process.GetProverResponse(); + if (resp.Name == "derivation") + { + cex = SExprToCex(resp, handler,varSubst); + } + else + HandleProverError("Unexpected prover response: " + resp.ToString()); + resp = Process.GetProverResponse(); + if (resp.Name == "model") + { + var model = SExprToModel(resp, handler); + cex.owner.SetBackgroundModel(model); + } + else + HandleProverError("Unexpected prover response: " + resp.ToString()); + break; + } + case Outcome.Valid: + case Outcome.Bounded: + { + resp = Process.GetProverResponse(); + if (resp.Name == "fixedpoint") + { + // only get the response if we need it + if(CommandLineOptions.Clo.PrintFixedPoint != null) + SExprToSoln(resp, varSubst); + } + else + HandleProverError("Unexpected prover response: " + resp.ToString()); + break; + } + default: + break; + } + +#if false + while (true) + { + resp = Process.GetProverResponse(); + if (resp == null || Process.IsPong(resp)) + break; + HandleProverError("Unexpected prover response: " + resp.ToString()); + } +#endif + } + SendThisVC("(fixedpoint-pop)"); + Pop(); + AxiomsAreSetup = false; + + if (CommandLineOptions.Clo.PrintConjectures != null) + { + ReadConjectures(CommandLineOptions.Clo.PrintConjectures); + } + + return result; + } + + class MyFileParser : SExpr.Parser + { + SMTLibProcessTheoremProver parent; + + public MyFileParser(System.IO.StreamReader _sr, SMTLibProcessTheoremProver _parent) + : base(_sr) + { + parent = _parent; + } + public override void ParseError(string msg) + { + parent.HandleProverError("Error in conjecture file from prover: " + msg); + } + } + + void ReadConjectures(string filename) + { + try + { + System.IO.StreamReader sr = new StreamReader(filename + ".tmp"); + SExpr.Parser p = new MyFileParser(sr, this); + var sexps = p.ParseSExprs(false); + Dictionary<string, RPFP.Node> pmap = GetNodeMap(); + foreach (var e in sexps) + { + string pname; + RPFP.Transformer annot; + GetDefun(e, out pname, out annot); + + if (pmap.ContainsKey(pname)) + { + var c = new RPFP.Conjecture(); + c.node = pmap[pname]; + c.bound = annot; + rpfp.conjectures.Add(c); + } + else if (pname[0] != '@') + { // if not an internal symbol + HandleProverError("Prover error: got unknown predicate:" + pname); + throw new BadExprFromProver(); + } + } + sr.Close(); + } + catch (Exception) + { + HandleProverError("No conjecture file from prover"); + throw new BadExprFromProver(); + } + } + + private Dictionary<string, RPFP.Node> GetNodeMap() + { + Dictionary<string, RPFP.Node> pmap = new Dictionary<string, RPFP.Node>(); + foreach (var node in rpfp.nodes) + pmap.Add((node.Name as VCExprBoogieFunctionOp).Func.Name, node); + return pmap; + } + + private static HashSet<string> usedLogNames = new HashSet<string>(); + + private TextWriter OpenOutputFile(string descriptiveName) + { + Contract.Requires(descriptiveName != null); + Contract.Ensures(Contract.Result<TextWriter>() != null); + + string filename = options.LogFilename; + filename = Helpers.SubstituteAtPROC(descriptiveName, cce.NonNull(filename)); + var curFilename = filename; + + lock (usedLogNames) { + int n = 1; + while (usedLogNames.Contains(curFilename)) { + curFilename = filename + "." + n++; + } + usedLogNames.Add(curFilename); + } + + return new StreamWriter(curFilename, false); + } + + private void FlushProverWarnings() + { + var handler = currentErrorHandler; + if (handler != null) { + lock (proverWarnings) { + proverWarnings.Iter(handler.OnProverWarning); + proverWarnings.Clear(); + } + } + } + + protected void HandleProverError(string s) + { + s = s.Replace("\r", ""); + lock (proverWarnings) { + while (s.StartsWith("WARNING: ")) { + var idx = s.IndexOf('\n'); + var warn = s; + if (idx > 0) { + warn = s.Substring(0, idx); + s = s.Substring(idx + 1); + } else { + s = ""; + } + warn = warn.Substring(9); + proverWarnings.Add(warn); + } + } + + FlushProverWarnings(); + + if (s == "") return; + + lock (proverErrors) { + proverErrors.Add(s); + Console.WriteLine("Prover error: " + s); + } + } + + [NoDefaultContract] + public override Outcome CheckOutcome(ErrorHandler handler, int taskID = -1) + { + Contract.EnsuresOnThrow<UnexpectedProverOutputException>(true); + + var result = CheckOutcomeCore(handler, taskID: taskID); + SendThisVC("(pop 1)"); + FlushLogFile(); + + return result; + } + + [NoDefaultContract] + public override Outcome CheckOutcomeCore(ErrorHandler handler, int taskID = -1) + { + Contract.EnsuresOnThrow<UnexpectedProverOutputException>(true); + + var result = Outcome.Undetermined; + + if (Process == null) + return result; + + try { + currentErrorHandler = handler; + FlushProverWarnings(); + + int errorLimit; + if (CommandLineOptions.Clo.ConcurrentHoudini) { + Contract.Assert(taskID >= 0); + errorLimit = CommandLineOptions.Clo.Cho[taskID].ProverCCLimit; + } else { + errorLimit = CommandLineOptions.Clo.ProverCCLimit; + } + + if (errorLimit < 1) + errorLimit = 1; + + int errorsLeft = errorLimit; + + var globalResult = Outcome.Undetermined; + + while (true) { + string[] labels = null; + bool popLater = false; + + try { + errorsLeft--; + + result = GetResponse(); + + if (CommandLineOptions.Clo.RunDiagnosticsOnTimeout && result == Outcome.TimeOut) + { + #region Run timeout diagnostics + + if (CommandLineOptions.Clo.TraceDiagnosticsOnTimeout) + { + Console.Out.WriteLine("Starting timeout diagnostics with initial time limit {0}.", options.TimeLimit); + } + + SendThisVC("; begin timeout diagnostics"); + + var start = DateTime.UtcNow; + var unverified = new SortedSet<int>(ctx.TimeoutDiagnosticIDToAssertion.Keys); + var timedOut = new SortedSet<int>(); + int frac = 2; + int queries = 0; + int timeLimitPerAssertion = 0 < options.TimeLimit ? (options.TimeLimit / 100) * CommandLineOptions.Clo.TimeLimitPerAssertionInPercent : 1000; + while (true) + { + int rem = unverified.Count; + if (rem == 0) + { + if (0 < timedOut.Count) + { + result = CheckSplit(timedOut, ref popLater, options.TimeLimit, timeLimitPerAssertion, ref queries); + if (result == Outcome.Valid) + { + timedOut.Clear(); + } + else if (result == Outcome.TimeOut) + { + // Give up and report which assertions were not verified. + var cmds = timedOut.Select(id => ctx.TimeoutDiagnosticIDToAssertion[id]); + + if (cmds.Any()) + { + handler.OnResourceExceeded("timeout after running diagnostics", cmds); + } + } + } + else + { + result = Outcome.Valid; + } + break; + } + + // TODO(wuestholz): Try out different ways for splitting up the work (e.g., randomly). + var cnt = Math.Max(1, rem / frac); + // It seems like assertions later in the control flow have smaller indexes. + var split = new SortedSet<int>(unverified.Where((val, idx) => (rem - idx - 1) < cnt)); + Contract.Assert(0 < split.Count); + var splitRes = CheckSplit(split, ref popLater, timeLimitPerAssertion, timeLimitPerAssertion, ref queries); + if (splitRes == Outcome.Valid) + { + unverified.ExceptWith(split); + frac = 1; + } + else if (splitRes == Outcome.Invalid) + { + result = splitRes; + break; + } + else if (splitRes == Outcome.TimeOut) + { + if (2 <= frac && (4 <= (rem / frac))) + { + frac *= 4; + } + else if (2 <= (rem / frac)) + { + frac *= 2; + } + else + { + timedOut.UnionWith(split); + unverified.ExceptWith(split); + frac = 1; + } + } + else + { + break; + } + } + + unverified.UnionWith(timedOut); + + var end = DateTime.UtcNow; + + SendThisVC("; end timeout diagnostics"); + + if (CommandLineOptions.Clo.TraceDiagnosticsOnTimeout) + { + Console.Out.WriteLine("Terminated timeout diagnostics after {0:F0} ms and {1} prover queries.", end.Subtract(start).TotalMilliseconds, queries); + Console.Out.WriteLine("Outcome: {0}", result); + Console.Out.WriteLine("Unverified assertions: {0} (of {1})", unverified.Count, ctx.TimeoutDiagnosticIDToAssertion.Keys.Count); + + string filename = "unknown"; + var assertion = ctx.TimeoutDiagnosticIDToAssertion.Values.Select(t => t.Item1).FirstOrDefault(a => a.tok != null && a.tok != Token.NoToken && a.tok.filename != null); + if (assertion != null) + { + filename = assertion.tok.filename; + } + File.AppendAllText("timeouts.csv", string.Format(";{0};{1};{2:F0};{3};{4};{5};{6}\n", filename, options.TimeLimit, end.Subtract(start).TotalMilliseconds, queries, result, unverified.Count, ctx.TimeoutDiagnosticIDToAssertion.Keys.Count)); + } + + #endregion + } + + if (globalResult == Outcome.Undetermined) + globalResult = result; + + if (result == Outcome.Invalid || result == Outcome.TimeOut || result == Outcome.OutOfMemory) { + IList<string> xlabels; + if (CommandLineOptions.Clo.UseLabels) { + labels = GetLabelsInfo(); + if (labels == null) + { + xlabels = new string[] { }; + } + else + { + xlabels = labels.Select(a => a.Replace("@", "").Replace("+", "")).ToList(); + } + } + else if(CommandLineOptions.Clo.SIBoolControlVC) { + labels = new string[0]; + xlabels = labels; + } else { + labels = CalculatePath(handler.StartingProcId()); + xlabels = labels; + } + Model model = (result == Outcome.TimeOut || result == Outcome.OutOfMemory) ? null : + GetErrorModel(); + handler.OnModel(xlabels, model, result); + } + + if (labels == null || !labels.Any() || errorsLeft == 0) break; + } finally { + if (popLater) + { + SendThisVC("(pop 1)"); + } + } + + if (CommandLineOptions.Clo.UseLabels) { + var negLabels = labels.Where(l => l.StartsWith("@")).ToArray(); + var posLabels = labels.Where(l => !l.StartsWith("@")); + Func<string, string> lbl = (s) => SMTLibNamer.QuoteId(SMTLibNamer.LabelVar(s)); + if (!options.MultiTraces) + posLabels = Enumerable.Empty<string>(); + var conjuncts = posLabels.Select(s => "(not " + lbl(s) + ")").Concat(negLabels.Select(lbl)).ToArray(); + string expr = conjuncts.Length == 1 ? conjuncts[0] : ("(or " + conjuncts.Concat(" ") + ")"); ; + if (!conjuncts.Any()) + { + expr = "false"; + } + SendThisVC("(assert " + expr + ")"); + SendThisVC("(check-sat)"); + } + else { + string source = labels[labels.Length - 2]; + string target = labels[labels.Length - 1]; + SendThisVC("(assert (not (= (ControlFlow 0 " + source + ") (- " + target + "))))"); + SendThisVC("(check-sat)"); + } + } + + FlushLogFile(); + + if (CommandLineOptions.Clo.RestartProverPerVC && Process != null) + Process.NeedsRestart = true; + + return globalResult; + + } finally { + currentErrorHandler = null; + } + } + + private Outcome CheckSplit(SortedSet<int> split, ref bool popLater, int timeLimit, int timeLimitPerAssertion, ref int queries) + { + var tla = timeLimitPerAssertion * split.Count; + + if (popLater) + { + SendThisVC("(pop 1)"); + } + + SendThisVC("(push 1)"); + SendThisVC(string.Format("(set-option :{0} {1})", Z3.SetTimeoutOption(), (0 < tla && tla < timeLimit) ? tla : timeLimit)); + popLater = true; + + SendThisVC(string.Format("; checking split VC with {0} unverified assertions", split.Count)); + var expr = VCExpressionGenerator.True; + foreach (var i in ctx.TimeoutDiagnosticIDToAssertion.Keys) + { + var lit = VCExprGen.Function(VCExpressionGenerator.TimeoutDiagnosticsOp, VCExprGen.Integer(Microsoft.Basetypes.BigNum.FromInt(i))); + if (split.Contains(i)) { + lit = VCExprGen.Not(lit); + } + expr = VCExprGen.AndSimp(expr, lit); + } + SendThisVC("(assert " + VCExpr2String(expr, 1) + ")"); + if (options.Solver == SolverKind.Z3) + { + SendThisVC("(apply (then (using-params propagate-values :max_rounds 1) simplify) :print false)"); + } + FlushLogFile(); + SendThisVC("(check-sat)"); + queries++; + return GetResponse(); + } + + public override string[] CalculatePath(int controlFlowConstant) { + SendThisVC("(get-value ((ControlFlow " + controlFlowConstant + " 0)))"); + var path = new List<string>(); + while (true) { + var resp = Process.GetProverResponse(); + if (resp == null) break; + if (!(resp.Name == "" && resp.ArgCount == 1)) break; + resp = resp.Arguments[0]; + if (!(resp.Name == "" && resp.ArgCount == 2)) break; + resp = resp.Arguments[1]; + var v = resp.Name; + if (v == "-" && resp.ArgCount == 1) { + v = resp.Arguments[0].Name; + path.Add(v); + break; + } + else if (resp.ArgCount != 0) + break; + path.Add(v); + SendThisVC("(get-value ((ControlFlow " + controlFlowConstant + " " + v + ")))"); + } + return path.ToArray(); + } + + + private class SMTErrorModelConverter { + private struct SMTDataType { + public string Constructor; + public List<SExpr> Types; + } + + private List<SExpr> ErrorModelTodo; + private SMTLibProcessTheoremProver Parent; + private StringBuilder ErrorModel = new StringBuilder(); + private HashSet<SExpr> TopLevelProcessed = new HashSet<SExpr>(); + private int NumNewArrays = 0; + private Dictionary<string, int> SortSet = new Dictionary<string, int>(); + private Dictionary<string, SMTDataType> DataTypes = new Dictionary<string, SMTDataType>(); + private Dictionary<string, SExpr> Functions = new Dictionary<string, SExpr>(); + + public SMTErrorModelConverter(SExpr _ErrorModel, SMTLibProcessTheoremProver _Parent) { + ErrorModelTodo = _ErrorModel.Arguments.ToList();; + Parent = _Parent; + } + + public string Convert() { + ConvertErrorModel(ErrorModel); + return ErrorModel.ToString(); + } + + bool isConstArray(SExpr element, SExpr type) { + if (type.Name != "Array") + return false; + + if (element.Name == "__array_store_all__") // CVC4 1.4 + return true; + else if (element.Name == "" && element[0].Name == "as" && + element[0][0].Name == "const") // CVC4 > 1.4 + return true; + + return false; + } + + SExpr getConstArrayElement(SExpr element) { + if (element.Name == "__array_store_all__") // CVC4 1.4 + return element[1]; + else if (element.Name == "" && element[0].Name == "as" && + element[0][0].Name == "const") // CVC4 > 1.4 + return element[1]; + + Parent.HandleProverError("Unexpected value: " + element); + throw new BadExprFromProver (); + } + + void ConstructComplexValue(SExpr element, SExpr type, StringBuilder m) { + if (type.Name == "Array") { + if (element.Name == "store" || isConstArray(element, type)) { + NumNewArrays++; + m.Append("as-array[k!" + NumNewArrays + ']'); + SExpr[] args = {new SExpr("k!" + NumNewArrays), new SExpr(""), type, element}; + var newElement = new SExpr("define-fun", args); + TopLevelProcessed.Add(newElement); + ErrorModelTodo.Add(newElement); + return; + } + } + + ConstructSimpleValue(element, type, m); + } + + void ConstructSimpleValue(SExpr element, SExpr type, StringBuilder m) { + if (type.Name == "Bool" && element.ArgCount == 0) { + m.Append(element.ToString()); + return; + } + + if (type.Name == "Int") { + if (element.ArgCount == 0) { + m.Append(element.ToString()); + return; + } else if (element.Name == "-" && element.ArgCount == 1) { + m.Append(element.ToString()); + return; + } + } + + if (type.Name == "_" && type.ArgCount == 2 && type[0].Name == "BitVec") { + if (element.Name == "_" && element.ArgCount == 2 && + element[0].Name.StartsWith("bv") && element[0].ArgCount == 0 && + element[1].Name == type.Arguments[1].Name && element[1].ArgCount == 0) { + m.Append(element[0].Name + '[' + element[1].Name + ']'); + return; + } + } + + if (type.Name == "Array") { + while (element.Name == "store") { + ConstructComplexValue(element[1], type[0], m); + m.Append(" -> "); + ConstructComplexValue(element[2], type[1], m); + m.Append("\n "); + if (element[0].Name != "store") { + m.Append("else -> "); + } + element = element[0]; + } + + if (isConstArray(element, type)) { + ConstructComplexValue(getConstArrayElement(element), type[1], m); + return; + } else if (element.Name == "_" && element.ArgCount == 2 && + element[0].Name == "as-array") { + m.Append("as-array[" + element[1].Name + ']'); + return; + } + } + + if (SortSet.ContainsKey(type.Name) && SortSet[type.Name] == 0) { + var prefix = "@uc_T_" + type.Name.Substring(2) + "_"; + if (element.Name.StartsWith(prefix)) { + m.Append(type.Name + "!val!" + element.Name.Substring(prefix.Length)); + return; + } + } + + if (Functions.ContainsKey(element.Name) && + type.Name == Functions[element.Name].Name) { + m.Append(element.Name); + return; + } + + if (DataTypes.ContainsKey(type.Name) && + DataTypes[type.Name].Constructor == element.Name && + element.ArgCount == DataTypes[type.Name].Types.Count) { + m.Append("(" + element.Name); + for (int i = 0; i < element.ArgCount; ++i) { + m.Append(" "); + ConstructComplexValue(element[i], DataTypes[type.Name].Types[i], m); + } + m.Append(")"); + return; + } + + Parent.HandleProverError("Unexpected value: " + element); + throw new BadExprFromProver (); + } + + void ConstructFunctionArguments(SExpr arguments, List<SExpr> argTypes, StringBuilder[] argValues) { + if (arguments.Name == "and") { + ConstructFunctionArguments(arguments[0], argTypes, argValues); + ConstructFunctionArguments(arguments[1], argTypes, argValues); + } else if (arguments.Name == "=" && + (arguments[0].Name.StartsWith("_ufmt_") || arguments[0].Name.StartsWith("x!"))) { + int argNum; + if (arguments[0].Name.StartsWith("_ufmt_")) + argNum = System.Convert.ToInt32(arguments[0].Name.Substring("_uftm_".Length)) - 1; + else /* if (arguments[0].Name.StartsWith("x!")) */ + argNum = System.Convert.ToInt32(arguments[0].Name.Substring("x!".Length)) - 1; + if (argNum < 0 || argNum >= argTypes.Count) { + Parent.HandleProverError("Unexpected function argument: " + arguments[0]); + throw new BadExprFromProver (); + } + if (argValues[argNum] != null) { + Parent.HandleProverError("Function argument defined multiple times: " + arguments[0]); + throw new BadExprFromProver (); + } + argValues[argNum] = new StringBuilder(); + ConstructComplexValue(arguments[1], argTypes[argNum], argValues[argNum]); + } else { + Parent.HandleProverError("Unexpected function argument: " + arguments); + throw new BadExprFromProver (); + } + } + + void ConstructFunctionElements(SExpr element, List<SExpr> argTypes, SExpr outType, StringBuilder m) { + while (element.Name == "ite") { + StringBuilder[] argValues = new StringBuilder[argTypes.Count]; + ConstructFunctionArguments(element[0], argTypes, argValues); + foreach (var s in argValues) + m.Append(s + " "); + m.Append("-> "); + ConstructComplexValue(element[1], outType, m); + m.Append("\n "); + if (element[2].Name != "ite") + m.Append("else -> "); + element = element[2]; + } + + ConstructComplexValue(element, outType, m); + } + + void ConstructFunction(SExpr element, SExpr inType, SExpr outType, StringBuilder m) { + List<SExpr> argTypes = new List<SExpr>(); + + for (int i = 0; i < inType.ArgCount; ++i) { + if (inType[i].Name != "_ufmt_" + (i + 1) && inType[i].Name != "x!" + (i + 1) && + !inType[i].Name.StartsWith("BOUND_VARIABLE_")) { + Parent.HandleProverError("Unexpected function argument: " + inType[i].Name); + throw new BadExprFromProver (); + } + argTypes.Add(inType[i][0]); + } + + ConstructFunctionElements(element, argTypes, outType, m); + } + + void ConstructDefine(SExpr element, StringBuilder m) { + Debug.Assert(element.Name == "define-fun"); + + if (element[1].ArgCount != 0) + TopLevelProcessed.Add(element); + + m.Append(element[0] + " -> "); + if (TopLevelProcessed.Contains(element)) + m.Append("{\n "); + + if (element[1].ArgCount == 0 && element[2].Name == "Array" && !TopLevelProcessed.Contains(element)) { + ConstructComplexValue(element[3], element[2], m); + } else if (element[1].ArgCount == 0) { + ConstructSimpleValue(element[3], element[2], m); + } else { + ConstructFunction(element[3], element[1], element[2], m); + } + + if (TopLevelProcessed.Contains(element)) + m.Append("\n}"); + m.Append("\n"); + } + + void ExtractDataType(SExpr datatypes) { + Debug.Assert(datatypes.Name == "declare-datatypes"); + + if (datatypes[0].Name != "" || datatypes[1].Name != "" || datatypes[1].ArgCount != 1) { + Parent.HandleProverError("Unexpected datatype: " + datatypes); + throw new BadExprFromProver (); + } + + SMTDataType dt = new SMTDataType(); + SExpr typeDef = datatypes[1][0]; + + if (typeDef.ArgCount != 1) { + Parent.HandleProverError("Unexpected datatype: " + datatypes); + throw new BadExprFromProver (); + } + + dt.Constructor = typeDef[0].Name; + dt.Types = new List<SExpr>(); + + for (int i = 0; i < typeDef[0].ArgCount; ++i) { + if (typeDef[0][i].ArgCount != 1) { + Parent.HandleProverError("Unexpected datatype constructor: " + typeDef[0]); + throw new BadExprFromProver (); + } + dt.Types.Add(typeDef[0][i][0]); + } + + DataTypes[typeDef.Name] = dt; + } + + private void ConvertErrorModel(StringBuilder m) { + if (Parent.options.Solver == SolverKind.Z3) { + // Datatype declarations are not returned by Z3, so parse common + // instead. This is not very efficient, but currently not an issue, + // as this not the normal way of interfacing with Z3. + var ms = new MemoryStream(Encoding.ASCII.GetBytes(Parent.common.ToString())); + var sr = new StreamReader(ms); + SExpr.Parser p = new MyFileParser(sr, null); + var sexprs = p.ParseSExprs(false); + foreach (var e in sexprs) { + switch (e.Name) { + case "declare-datatypes": + ExtractDataType(e); + break; + } + } + } + + while (ErrorModelTodo.Count > 0) { + var e = ErrorModelTodo[0]; + ErrorModelTodo.RemoveAt(0); + + switch (e.Name) { + case "define-fun": + ConstructDefine(e, m); + break; + case "declare-sort": + SortSet[e[0].Name] = System.Convert.ToInt32(e[1].Name); + break; + case "declare-datatypes": + ExtractDataType(e); + break; + case "declare-fun": + if (e[1].Name != "" || e[1].ArgCount > 0 || e[2].ArgCount > 0 || + e[2].Name == "Bool" || e[2].Name == "Int") { + Parent.HandleProverError("Unexpected top level model element: " + e.Name); + throw new BadExprFromProver (); + } + Functions[e[0].Name] = e[2]; + break; + case "forall": + // ignore + break; + default: + Parent.HandleProverError("Unexpected top level model element: " + e.Name); + throw new BadExprFromProver (); + } + } + } + } + + private Model GetErrorModel() { + if (!options.ExpectingModel()) + return null; + SendThisVC("(get-model)"); + Process.Ping(); + Model theModel = null; + while (true) { + var resp = Process.GetProverResponse(); + if (resp == null || Process.IsPong(resp)) + break; + if (theModel != null) + HandleProverError("Expecting only one model but got many"); + + string modelStr = null; + if (resp.Name == "model" && resp.ArgCount >= 1) { + var converter = new SMTErrorModelConverter(resp, this); + modelStr = converter.Convert(); + } + else if (resp.ArgCount == 0 && resp.Name.Contains("->")) { + modelStr = resp.Name; + } + else { + HandleProverError("Unexpected prover response getting model: " + resp.ToString()); + } + + List<Model> models = null; + try { + switch (options.Solver) { + case SolverKind.Z3: + case SolverKind.CVC4: + models = Model.ParseModels(new StringReader("Error model: \n" + modelStr)); + break; + default: + Debug.Assert(false); + return null; + } + } + catch (ArgumentException exn) { + HandleProverError("Model parsing error: " + exn.Message); + } + if (models == null) + HandleProverError("Could not parse any models"); + else if (models.Count == 0) + HandleProverError("Could not parse any models"); + else if (models.Count > 1) + HandleProverError("Expecting only one model but got many"); + else + theModel = models[0]; + } + return theModel; + } + + private string[] GetLabelsInfo() + { + SendThisVC("(labels)"); + Process.Ping(); + + string[] res = null; + while (true) { + var resp = Process.GetProverResponse(); + if (resp == null || Process.IsPong(resp)) + break; + if (res != null) + HandleProverError("Expecting only one sequence of labels but got many"); + if (resp.Name == "labels" && resp.ArgCount >= 1) { + res = resp.Arguments.Select(a => a.Name.Replace("|", "")).ToArray(); + } + else { + HandleProverError("Unexpected prover response getting labels: " + resp.ToString()); + } + } + return res; + } + + private Outcome GetResponse() + { + var result = Outcome.Undetermined; + var wasUnknown = false; + + Process.Ping(); + + while (true) { + var resp = Process.GetProverResponse(); + if (resp == null || Process.IsPong(resp)) + break; + + switch (resp.Name) { + case "unsat": + result = Outcome.Valid; + break; + case "sat": + result = Outcome.Invalid; + break; + case "unknown": + result = Outcome.Invalid; + wasUnknown = true; + break; + default: + HandleProverError("Unexpected prover response: " + resp.ToString()); + break; + } + } + + if (wasUnknown) { + SendThisVC("(get-info :reason-unknown)"); + Process.Ping(); + while (true) { + var resp = Process.GetProverResponse(); + if (resp == null || Process.IsPong(resp)) + break; + + if (resp.ArgCount == 1 && resp.Name == ":reason-unknown") { + switch (resp[0].Name) { + case "memout": + currentErrorHandler.OnResourceExceeded("memory"); + result = Outcome.OutOfMemory; + Process.NeedsRestart = true; + break; + case "timeout": case "canceled": + currentErrorHandler.OnResourceExceeded("timeout"); + result = Outcome.TimeOut; + break; + default: + break; + } + } else { + HandleProverError("Unexpected prover response (getting info about 'unknown' response): " + resp.ToString()); + } + } + + } + + return result; + } + + protected string VCExpr2String(VCExpr expr, int polarity) + { + Contract.Requires(expr != null); + Contract.Ensures(Contract.Result<string>() != null); + + lock (gen) + { + DateTime start = DateTime.UtcNow; + //if (CommandLineOptions.Clo.Trace) + // Console.Write("Linearising ... "); + + // handle the types in the VCExpr + TypeEraser eraser; + switch (CommandLineOptions.Clo.TypeEncodingMethod) + { + case CommandLineOptions.TypeEncoding.Arguments: + eraser = new TypeEraserArguments((TypeAxiomBuilderArguments)AxBuilder, gen); + break; + case CommandLineOptions.TypeEncoding.Monomorphic: + eraser = null; + break; + default: + eraser = new TypeEraserPremisses((TypeAxiomBuilderPremisses)AxBuilder, gen); + break; + } + VCExpr exprWithoutTypes = eraser == null ? expr : eraser.Erase(expr, polarity); + Contract.Assert(exprWithoutTypes != null); + + LetBindingSorter letSorter = new LetBindingSorter(gen); + Contract.Assert(letSorter != null); + VCExpr sortedExpr = letSorter.Mutate(exprWithoutTypes, true); + Contract.Assert(sortedExpr != null); + VCExpr sortedAxioms = letSorter.Mutate(AxBuilder.GetNewAxioms(), true); + Contract.Assert(sortedAxioms != null); + + DeclCollector.Collect(sortedAxioms); + DeclCollector.Collect(sortedExpr); + FeedTypeDeclsToProver(); + + + + AddAxiom(SMTLibExprLineariser.ToString(sortedAxioms, Namer, options)); + string res = SMTLibExprLineariser.ToString(sortedExpr, Namer, options); + Contract.Assert(res != null); + + if (CommandLineOptions.Clo.Trace) + { + DateTime end = DateTime.UtcNow; + TimeSpan elapsed = end - start; + if (elapsed.TotalSeconds > 0.5) + Console.WriteLine("Linearising [{0} s]", elapsed.TotalSeconds); + } + return res; + } + } + + // the list of all known axioms, where have to be included in each + // verification condition + private readonly List<string/*!>!*/> Axioms = new List<string/*!*/>(); + private bool AxiomsAreSetup = false; + + + + + // similarly, a list of function/predicate declarations + private readonly List<string/*!>!*/> TypeDecls = new List<string/*!*/>(); + + protected void AddAxiom(string axiom) + { + Contract.Requires(axiom != null); + Axioms.Add(axiom); + // if (thmProver != null) { + // LogActivity(":assume " + axiom); + // thmProver.AddAxioms(axiom); + // } + } + + protected void AddTypeDecl(string decl) + { + Contract.Requires(decl != null); + TypeDecls.Add(decl); + // if (thmProver != null) { + // LogActivity(decl); + // thmProver.Feed(decl, 0); + // } + } + + //////////////////////////////////////////////////////////////////////////// + + private static string _backgroundPredicates; + + static void InitializeGlobalInformation() + { + Contract.Ensures(_backgroundPredicates != null); + //throws ProverException, System.IO.FileNotFoundException; + if (_backgroundPredicates == null) { + if (CommandLineOptions.Clo.TypeEncodingMethod == CommandLineOptions.TypeEncoding.Monomorphic) + { + _backgroundPredicates = ""; + } + else + { + _backgroundPredicates = @" +(set-info :category ""industrial"") +(declare-sort |T@U| 0) +(declare-sort |T@T| 0) +(declare-fun real_pow (Real Real) Real) +(declare-fun UOrdering2 (|T@U| |T@U|) Bool) +(declare-fun UOrdering3 (|T@T| |T@U| |T@U|) Bool)"; + } + } + } + + public override VCExpressionGenerator VCExprGen + { + get { return this.gen; } + } + + //// Push/pop interface + + //List<string> pushedAssertions = new List<string>(); + //int numRealPushes; + public override string VCExpressionToString(VCExpr vc) + { + return VCExpr2String(vc, 1); + } + + public override void PushVCExpression(VCExpr vc) + { + throw new NotImplementedException(); + + } + + public override void Pop() + { + SendThisVC("(pop 1)"); + DeclCollector.Pop(); + } + + public override int NumAxiomsPushed() + { + throw new NotImplementedException(); + //return numRealPushes + pushedAssertions.Count; + } + + private void FlushPushedAssertions() + { + throw new NotImplementedException(); + } + + public override void Assert(VCExpr vc, bool polarity) + { + string a = ""; + if (polarity) + { + a = "(assert " + VCExpr2String(vc, 1) + ")"; + } + else + { + a = "(assert (not\n" + VCExpr2String(vc, 1) + "\n))"; + } + AssertAxioms(); + SendThisVC(a); + } + + public override void DefineMacro(Macro f, VCExpr vc) { + DeclCollector.AddFunction(f); + string printedName = Namer.GetQuotedName(f, f.Name); + var argTypes = f.InParams.Cast<Variable>().MapConcat(p => DeclCollector.TypeToStringReg(p.TypedIdent.Type), " "); + string decl = "(define-fun " + printedName + " (" + argTypes + ") " + DeclCollector.TypeToStringReg(f.OutParams[0].TypedIdent.Type) + " " + VCExpr2String(vc, 1) + ")"; + AssertAxioms(); + SendThisVC(decl); + } + + public override void AssertAxioms() + { + FlushAxioms(); + } + + public override void Check() + { + PrepareCommon(); + SendThisVC("(check-sat)"); + FlushLogFile(); + } + + public override void SetTimeOut(int ms) + { + if (options.Solver == SolverKind.Z3) { + var name = Z3.SetTimeoutOption(); + var value = ms.ToString(); + options.TimeLimit = ms; + options.SmtOptions.RemoveAll(ov => ov.Option == name); + options.AddSmtOption(name, value); + SendThisVC(string.Format("(set-option :{0} {1})", name, value)); + } + } + + public override object Evaluate(VCExpr expr) + { + string vcString = VCExpr2String(expr, 1); + SendThisVC("(get-value (" + vcString + "))"); + var resp = Process.GetProverResponse(); + if (resp == null) throw new VCExprEvaluationException(); + if (!(resp.Name == "" && resp.ArgCount == 1)) throw new VCExprEvaluationException(); + resp = resp.Arguments[0]; + if (resp.Name == "") + { + // evaluating an expression + if (resp.ArgCount == 2) + resp = resp.Arguments[1]; + else + throw new VCExprEvaluationException(); + } + else + { + // evaluating a variable + if (resp.ArgCount == 1) + resp = resp.Arguments[0]; + else + throw new VCExprEvaluationException(); + } + if (resp.Name == "-" && resp.ArgCount == 1) // negative int + return Microsoft.Basetypes.BigNum.FromString("-" + resp.Arguments[0].Name); + if (resp.Name == "_" && resp.ArgCount == 2 && resp.Arguments[0].Name.StartsWith("bv")) // bitvector + return new BvConst(Microsoft.Basetypes.BigNum.FromString(resp.Arguments[0].Name.Substring("bv".Length)), + int.Parse(resp.Arguments[1].Name)); + if (resp.ArgCount != 0) + throw new VCExprEvaluationException(); + if (expr.Type.Equals(Boogie.Type.Bool)) + return bool.Parse(resp.Name); + else if (expr.Type.Equals(Boogie.Type.Int)) + return Microsoft.Basetypes.BigNum.FromString(resp.Name); + else + return resp.Name; + } + + /// <summary> + /// Extra state for ApiChecker (used by stratifiedInlining) + /// </summary> + static int nameCounter = 0; + + public override Outcome CheckAssumptions(List<VCExpr> assumptions, out List<int> unsatCore, ErrorHandler handler) + { + unsatCore = new List<int>(); + + Push(); + // Name the assumptions + var nameToAssumption = new Dictionary<string, int>(); + int i = 0; + foreach (var vc in assumptions) + { + var name = "a" + nameCounter.ToString(); + nameCounter++; + nameToAssumption.Add(name, i); + + string vcString = VCExpr2String(vc, 1); + AssertAxioms(); + SendThisVC(string.Format("(assert (! {0} :named {1}))", vcString, name)); + i++; + } + Check(); + + var outcome = CheckOutcomeCore(handler); + + if (outcome != Outcome.Valid) { + Pop(); + return outcome; + } + + Contract.Assert(usingUnsatCore, "SMTLib prover not setup for computing unsat cores"); + SendThisVC("(get-unsat-core)"); + var resp = Process.GetProverResponse(); + unsatCore = new List<int>(); + if (resp.Name != "") unsatCore.Add(nameToAssumption[resp.Name]); + foreach (var s in resp.Arguments) unsatCore.Add(nameToAssumption[s.Name]); + + FlushLogFile(); + Pop(); + return outcome; + } + + public override void Push() + { + SendThisVC("(push 1)"); + DeclCollector.Push(); + } + + public override Outcome CheckAssumptions(List<VCExpr> hardAssumptions, List<VCExpr> softAssumptions, out List<int> unsatisfiedSoftAssumptions, ErrorHandler handler) { + unsatisfiedSoftAssumptions = new List<int>(); + + // First, convert both hard and soft assumptions to SMTLIB strings + List<string> hardAssumptionStrings = new List<string>(); + foreach (var a in hardAssumptions) { + hardAssumptionStrings.Add(VCExpr2String(a, 1)); + } + List<string> currAssumptionStrings = new List<string>(); + foreach (var a in softAssumptions) { + currAssumptionStrings.Add(VCExpr2String(a, 1)); + } + + Push(); + AssertAxioms(); + foreach (var a in hardAssumptionStrings) { + SendThisVC("(assert " + a + ")"); + } + Check(); + Outcome outcome = GetResponse(); + if (outcome != Outcome.Invalid) { + Pop(); + return outcome; + } + + int k = 0; + List<string> relaxVars = new List<string>(); + while (true) { + Push(); + foreach (var a in currAssumptionStrings) { + SendThisVC("(assert " + a + ")"); + } + Check(); + outcome = CheckOutcomeCore(handler); + if (outcome != Outcome.Valid) + break; + Pop(); + string relaxVar = "relax_" + k; + relaxVars.Add(relaxVar); + SendThisVC("(declare-fun " + relaxVar + " () Int)"); + List<string> nextAssumptionStrings = new List<string>(); + for (int i = 0; i < currAssumptionStrings.Count; i++) { + string constraint = "(= " + relaxVar + " " + i + ")"; + nextAssumptionStrings.Add("(or " + currAssumptionStrings[i] + " " + constraint + ")"); + } + currAssumptionStrings = nextAssumptionStrings; + k++; + } + + if (outcome == Outcome.Invalid) { + foreach (var relaxVar in relaxVars) { + SendThisVC("(get-value (" + relaxVar + "))"); + FlushLogFile(); + var resp = Process.GetProverResponse(); + if (resp == null) break; + if (!(resp.Name == "" && resp.ArgCount == 1)) break; + resp = resp.Arguments[0]; + if (!(resp.Name != "" && resp.ArgCount == 1)) break; + resp = resp.Arguments[0]; + if (resp.ArgCount != 0) + break; + int v; + if (int.TryParse(resp.Name, out v)) + unsatisfiedSoftAssumptions.Add(v); + else + break; + } + Pop(); + } + + Pop(); + return outcome; + } + } + + public class SMTLibInterpolatingProcessTheoremProver : SMTLibProcessTheoremProver + { + public SMTLibInterpolatingProcessTheoremProver(ProverOptions options, VCExpressionGenerator gen, + SMTLibProverContext ctx) + : base(AddInterpOption(options), gen, ctx) + { + + } + + private static ProverOptions AddInterpOption(ProverOptions options) + { + var opts = (SMTLibProverOptions)options; + opts.AddSmtOption("produce-interpolants", "true"); + if (CommandLineOptions.Clo.PrintFixedPoint == null) + CommandLineOptions.Clo.PrintFixedPoint = "itp.fixedpoint.bpl"; + return opts; + } + + public override void AssertNamed(VCExpr vc, bool polarity, string name) + { + string vcString; + if (polarity) + { + vcString = VCExpr2String(vc, 1); + } + else + { + vcString = "(not " + VCExpr2String(vc, 1) + ")"; + } + AssertAxioms(); + SendThisVC(string.Format("(assert (! {0} :named {1}))", vcString, name)); + } + + public override VCExpr ComputeInterpolant(VCExpr A, VCExpr B) + { + string A_str = VCExpr2String(A, 1); + string B_str = VCExpr2String(B, 1); + + AssertAxioms(); + SendThisVC("(compute-interpolant " + A_str + " " + B_str + ")"); + + SExpr interpolant; + Outcome result = GetInterpolantResponse(out interpolant); + + if (result != Outcome.Valid) + return null; + + VCExpr interpolantVC = SExprToVCExpr(interpolant, new Dictionary<string, VCExpr>()); + return interpolantVC; + } + + private Outcome GetInterpolantResponse(out SExpr interpolant) + { + var result = Outcome.Undetermined; + var wasUnknown = false; + interpolant = null; + + Process.Ping(); + bool onlyOnce = false; + + while (true) + { + var resp = Process.GetProverResponse(); + if (resp == null || Process.IsPong(resp)) + break; + + switch (resp.Name) + { + case "unsat": + result = Outcome.Valid; + break; + case "sat": + result = Outcome.Invalid; + break; + case "unknown": + result = Outcome.Invalid; + wasUnknown = true; + break; + default: + if (result == Outcome.Valid) + { + interpolant = resp as SExpr; + + Contract.Assert(onlyOnce == false); + onlyOnce = true; + continue; + } + HandleProverError("Unexpected prover response: " + resp.ToString()); + break; + } + } + + if (wasUnknown) + { + SendThisVC("(get-info :reason-unknown)"); + Process.Ping(); + + while (true) + { + var resp = Process.GetProverResponse(); + if (resp == null || Process.IsPong(resp)) + break; + + if (resp.ArgCount == 1 && resp.Name == ":reason-unknown") + { + switch (resp[0].Name) + { + case "memout": + currentErrorHandler.OnResourceExceeded("memory"); + result = Outcome.OutOfMemory; + Process.NeedsRestart = true; + break; + case "timeout": + case "canceled": + currentErrorHandler.OnResourceExceeded("timeout"); + result = Outcome.TimeOut; + break; + default: + break; + } + } + else + { + HandleProverError("Unexpected prover response (getting info about 'unknown' response): " + resp.ToString()); + } + } + } + + return result; + } + + public override List<VCExpr> GetTreeInterpolant(List<string> root, List<string> leaves) + { + List<VCExpr> result = new List<VCExpr>(); + + string vcStr = "true"; + foreach (string str in root) + vcStr = vcStr + " " + str; + foreach (string str in leaves) + vcStr = vcStr + "\r\n (interp " + str + ")"; + + vcStr = "(get-interpolant (and\r\n" + vcStr + "\r\n))"; + SendThisVC(vcStr); + if(currentLogFile != null) currentLogFile.Flush(); + + List<SExpr> interpolantList; + GetTreeInterpolantResponse(out interpolantList); + + Dictionary<string, VCExpr> bound = new Dictionary<string, VCExpr>(); + foreach (SExpr sexpr in interpolantList) + { + VCExpr interpolantVC = SExprToVCExpr(sexpr, bound); + result.Add(interpolantVC); + } + + return result; + } + + private void GetTreeInterpolantResponse(out List<SExpr> interpolantList) + { + interpolantList = new List<SExpr>(); + + Process.Ping(); + + while (true) + { + var resp = Process.GetProverResponse(); + if (resp == null || Process.IsPong(resp)) + break; + + SExpr interpolant = resp as SExpr; + if(interpolant == null) + HandleProverError("Unexpected prover response: got null for interpolant!"); + interpolantList.Add(interpolant); + } + } + } + + public class SMTLibProverContext : DeclFreeProverContext + { + internal SMTLibProcessTheoremProver parent; + + public readonly Dictionary<CtorType, List<Function>> KnownDatatypeConstructors = new Dictionary<CtorType, List<Function>>(); + + public SMTLibProverContext(VCExpressionGenerator gen, + VCGenerationOptions genOptions) + : base(gen, genOptions) + { + } + + protected SMTLibProverContext(SMTLibProverContext par) + : base(par) + { + } + + public override object Clone() + { + return new SMTLibProverContext(this); + } + + public override string Lookup(VCExprVar var) + { + VCExprVar v = parent.AxBuilder.TryTyped2Untyped(var); + if (v != null) { + var = v; + } + return parent.Namer.Lookup(var); + } + + public override void DeclareFunction(Function f, string attributes) { + if (f is DatatypeConstructor) { + CtorType datatype = (CtorType) f.OutParams[0].TypedIdent.Type; + if (!KnownDatatypeConstructors.ContainsKey(datatype)) + KnownDatatypeConstructors[datatype] = new List<Function>(); + KnownDatatypeConstructors[datatype].Add(f); + } + base.DeclareFunction(f, attributes); + } + } + + public class Factory : ProverFactory + { + // Set programmatically + public static bool UseInterpolation = false; + + public override object SpawnProver(ProverOptions options, object ctxt) + { + //Contract.Requires(ctxt != null); + //Contract.Requires(options != null); + Contract.Ensures(Contract.Result<object>() != null); + + return this.SpawnProver(options, + cce.NonNull((SMTLibProverContext)ctxt).ExprGen, + cce.NonNull((SMTLibProverContext)ctxt)); + } + + public override object NewProverContext(ProverOptions options) + { + //Contract.Requires(options != null); + Contract.Ensures(Contract.Result<object>() != null); + + VCExpressionGenerator gen = new VCExpressionGenerator(); + List<string>/*!>!*/ proverCommands = new List<string/*!*/>(); + proverCommands.Add("smtlib"); + var opts = (SMTLibProverOptions)options ; + if (opts.Solver == SolverKind.Z3) + proverCommands.Add("z3"); + else + proverCommands.Add("external"); + VCGenerationOptions genOptions = new VCGenerationOptions(proverCommands); + return new SMTLibProverContext(gen, genOptions); + } + + public override ProverOptions BlankProverOptions() + { + return new SMTLibProverOptions(); + } + + protected virtual SMTLibProcessTheoremProver SpawnProver(ProverOptions options, + VCExpressionGenerator gen, + SMTLibProverContext ctx) + { + Contract.Requires(options != null); + Contract.Requires(gen != null); + Contract.Requires(ctx != null); + Contract.Ensures(Contract.Result<SMTLibProcessTheoremProver>() != null); + + if (UseInterpolation) + return new SMTLibInterpolatingProcessTheoremProver(options, gen, ctx); + + return new SMTLibProcessTheoremProver(options, gen, ctx); + } + + public override bool SupportsLabels(ProverOptions options) + { + return ((SMTLibProverOptions)options).SupportsLabels; + } + } +} diff --git a/Source/Provers/SMTLib/SExpr.cs b/Source/Provers/SMTLib/SExpr.cs index ac681b8a..3e9687e1 100644 --- a/Source/Provers/SMTLib/SExpr.cs +++ b/Source/Provers/SMTLib/SExpr.cs @@ -1,263 +1,263 @@ -//-----------------------------------------------------------------------------
-//
-// Copyright (C) Microsoft Corporation. All Rights Reserved.
-//
-//-----------------------------------------------------------------------------
-
-using System;
-using System.Linq;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Text;
-using System.Diagnostics.Contracts;
-using System.Globalization;
-
-namespace Microsoft.Boogie
-{
- public class SExpr
- {
- static readonly SExpr[] EmptyArgs = new SExpr[0];
- public readonly string Name;
- public SExpr[] Arguments
- {
- get
- {
- Contract.Ensures(Contract.Result<SExpr[]>() != null);
- Contract.Ensures(Contract.ForAll(Contract.Result<SExpr[]>(), expr => expr != null));
-
- return this.arguments;
- }
- }
-
- public SExpr this[int idx]
- {
- get
- {
- return Arguments[idx];
- }
- }
-
- public int ArgCount
- {
- get { return arguments.Length; }
- }
-
- public bool IsId
- {
- get { return Arguments.Length == 0; }
- }
-
- private readonly SExpr[] arguments;
-
- [ContractInvariantMethod]
- void ObjectInvariant()
- {
- Contract.Invariant(this.Name != null);
- Contract.Invariant(this.arguments != null);
- Contract.Invariant(Contract.ForAll(this.arguments, arg => arg != null));
- }
-
- public SExpr(string name, params SExpr[] args)
- : this(name, (IEnumerable<SExpr>)args)
- {
- Contract.Requires(name != null);
- Contract.Requires(args != null);
- Contract.Requires(Contract.ForAll(args, x => x != null));
- }
-
- public SExpr(string name, IEnumerable<SExpr> args)
- {
- Contract.Requires(name != null);
- Contract.Requires(args != null);
- // We don't want to evaluate args twice!
- // Contract.Requires(Contract.ForAll(args, x => x != null));
- Name = name;
- arguments = args.ToArray();
- }
-
- public SExpr(string name)
- : this(name, EmptyArgs)
- {
- Contract.Requires(name != null);
- }
-
- #region pretty-printing
- void WriteTo(StringBuilder sb)
- {
- Contract.Requires(sb != null);
-
- if (Arguments.Length > 0) sb.Append('(');
- if (Name.Any(Char.IsWhiteSpace))
- sb.Append("\"").Append(Name).Append("\"");
- else if (Name.Length == 0)
- sb.Append("()");
- else
- sb.Append(Name);
- foreach (var a in Arguments) {
- sb.Append(' ');
- a.WriteTo(sb);
- }
- if (Arguments.Length > 0) sb.Append(')');
- }
-
- public override string ToString()
- {
- var sb = new StringBuilder();
- this.WriteTo(sb);
- return sb.ToString();
- }
- #endregion
-
- #region parsing
-
- public abstract class Parser
- {
- System.IO.StreamReader sr;
- int linePos = 0;
- string currLine = null;
-
- public Parser(System.IO.StreamReader _sr)
- {
- sr = _sr;
- }
- string Read()
- {
- return sr.ReadLine();
- }
- char SkipWs()
- {
- while (true)
- {
- if (currLine == null)
- {
- currLine = Read();
- if (currLine == null)
- return '\0';
- }
-
- while (linePos < currLine.Length && char.IsWhiteSpace(currLine[linePos]))
- linePos++;
-
- if (linePos < currLine.Length)
- return currLine[linePos];
- else
- {
- currLine = null;
- linePos = 0;
- }
- }
- }
-
- void Shift()
- {
- linePos++;
- }
-
- string ParseId()
- {
- var sb = new StringBuilder();
-
- var beg = SkipWs();
-
- var quoted = beg == '"' || beg == '|';
- if (quoted)
- Shift();
- while (true)
- {
- if (linePos >= currLine.Length)
- {
- if (quoted)
- {
- sb.Append("\n");
- currLine = Read();
- linePos = 0;
- if (currLine == null)
- break;
- }
- else break;
- }
-
- var c = currLine[linePos++];
- if (quoted && c == beg)
- break;
- if (!quoted && (char.IsWhiteSpace(c) || c == '(' || c == ')'))
- {
- linePos--;
- break;
- }
- if (quoted && c == '\\' && linePos < currLine.Length && currLine[linePos] == '"')
- {
- sb.Append('"');
- linePos++;
- continue;
- }
- sb.Append(c);
- }
-
- return sb.ToString();
- }
-
- public abstract void ParseError(string msg);
-
- public IEnumerable<SExpr> ParseSExprs(bool top)
- {
- while (true)
- {
- var c = SkipWs();
- if (c == '\0')
- break;
-
- if (c == ')')
- {
- if (top)
- ParseError("stray ')'");
- break;
- }
-
- string id;
-
- if (c == '(')
- {
- Shift();
- c = SkipWs();
- if (c == '\0')
- {
- ParseError("expecting something after '('");
- break;
- }
- else if (c == '(')
- {
- id = "";
- }
- else
- {
- id = ParseId();
- }
-
- var args = ParseSExprs(false).ToArray();
-
- c = SkipWs();
- if (c == ')')
- {
- Shift();
- }
- else
- {
- ParseError("unclosed '(" + id + "'");
- }
- yield return new SExpr(id, args);
- }
- else
- {
- id = ParseId();
- yield return new SExpr(id);
- }
-
- if (top) break;
- }
- }
- }
- #endregion
- }
-}
-
+//----------------------------------------------------------------------------- +// +// Copyright (C) Microsoft Corporation. All Rights Reserved. +// +//----------------------------------------------------------------------------- + +using System; +using System.Linq; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Text; +using System.Diagnostics.Contracts; +using System.Globalization; + +namespace Microsoft.Boogie +{ + public class SExpr + { + static readonly SExpr[] EmptyArgs = new SExpr[0]; + public readonly string Name; + public SExpr[] Arguments + { + get + { + Contract.Ensures(Contract.Result<SExpr[]>() != null); + Contract.Ensures(Contract.ForAll(Contract.Result<SExpr[]>(), expr => expr != null)); + + return this.arguments; + } + } + + public SExpr this[int idx] + { + get + { + return Arguments[idx]; + } + } + + public int ArgCount + { + get { return arguments.Length; } + } + + public bool IsId + { + get { return Arguments.Length == 0; } + } + + private readonly SExpr[] arguments; + + [ContractInvariantMethod] + void ObjectInvariant() + { + Contract.Invariant(this.Name != null); + Contract.Invariant(this.arguments != null); + Contract.Invariant(Contract.ForAll(this.arguments, arg => arg != null)); + } + + public SExpr(string name, params SExpr[] args) + : this(name, (IEnumerable<SExpr>)args) + { + Contract.Requires(name != null); + Contract.Requires(args != null); + Contract.Requires(Contract.ForAll(args, x => x != null)); + } + + public SExpr(string name, IEnumerable<SExpr> args) + { + Contract.Requires(name != null); + Contract.Requires(args != null); + // We don't want to evaluate args twice! + // Contract.Requires(Contract.ForAll(args, x => x != null)); + Name = name; + arguments = args.ToArray(); + } + + public SExpr(string name) + : this(name, EmptyArgs) + { + Contract.Requires(name != null); + } + + #region pretty-printing + void WriteTo(StringBuilder sb) + { + Contract.Requires(sb != null); + + if (Arguments.Length > 0) sb.Append('('); + if (Name.Any(Char.IsWhiteSpace)) + sb.Append("\"").Append(Name).Append("\""); + else if (Name.Length == 0) + sb.Append("()"); + else + sb.Append(Name); + foreach (var a in Arguments) { + sb.Append(' '); + a.WriteTo(sb); + } + if (Arguments.Length > 0) sb.Append(')'); + } + + public override string ToString() + { + var sb = new StringBuilder(); + this.WriteTo(sb); + return sb.ToString(); + } + #endregion + + #region parsing + + public abstract class Parser + { + System.IO.StreamReader sr; + int linePos = 0; + string currLine = null; + + public Parser(System.IO.StreamReader _sr) + { + sr = _sr; + } + string Read() + { + return sr.ReadLine(); + } + char SkipWs() + { + while (true) + { + if (currLine == null) + { + currLine = Read(); + if (currLine == null) + return '\0'; + } + + while (linePos < currLine.Length && char.IsWhiteSpace(currLine[linePos])) + linePos++; + + if (linePos < currLine.Length) + return currLine[linePos]; + else + { + currLine = null; + linePos = 0; + } + } + } + + void Shift() + { + linePos++; + } + + string ParseId() + { + var sb = new StringBuilder(); + + var beg = SkipWs(); + + var quoted = beg == '"' || beg == '|'; + if (quoted) + Shift(); + while (true) + { + if (linePos >= currLine.Length) + { + if (quoted) + { + sb.Append("\n"); + currLine = Read(); + linePos = 0; + if (currLine == null) + break; + } + else break; + } + + var c = currLine[linePos++]; + if (quoted && c == beg) + break; + if (!quoted && (char.IsWhiteSpace(c) || c == '(' || c == ')')) + { + linePos--; + break; + } + if (quoted && c == '\\' && linePos < currLine.Length && currLine[linePos] == '"') + { + sb.Append('"'); + linePos++; + continue; + } + sb.Append(c); + } + + return sb.ToString(); + } + + public abstract void ParseError(string msg); + + public IEnumerable<SExpr> ParseSExprs(bool top) + { + while (true) + { + var c = SkipWs(); + if (c == '\0') + break; + + if (c == ')') + { + if (top) + ParseError("stray ')'"); + break; + } + + string id; + + if (c == '(') + { + Shift(); + c = SkipWs(); + if (c == '\0') + { + ParseError("expecting something after '('"); + break; + } + else if (c == '(') + { + id = ""; + } + else + { + id = ParseId(); + } + + var args = ParseSExprs(false).ToArray(); + + c = SkipWs(); + if (c == ')') + { + Shift(); + } + else + { + ParseError("unclosed '(" + id + "'"); + } + yield return new SExpr(id, args); + } + else + { + id = ParseId(); + yield return new SExpr(id); + } + + if (top) break; + } + } + } + #endregion + } +} + diff --git a/Source/Provers/SMTLib/SMTLib.csproj b/Source/Provers/SMTLib/SMTLib.csproj index 5e80f4c1..00febc0a 100644 --- a/Source/Provers/SMTLib/SMTLib.csproj +++ b/Source/Provers/SMTLib/SMTLib.csproj @@ -1,237 +1,237 @@ -<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <ProductVersion>9.0.21022</ProductVersion>
- <SchemaVersion>2.0</SchemaVersion>
- <ProjectGuid>{9B163AA3-36BC-4AFB-88AB-79BC9E97E401}</ProjectGuid>
- <OutputType>Library</OutputType>
- <AppDesignerFolder>Properties</AppDesignerFolder>
- <RootNamespace>Microsoft.Boogie.SMTLib</RootNamespace>
- <AssemblyName>Provers.SMTLib</AssemblyName>
- <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
- <FileAlignment>512</FileAlignment>
- <CodeContractsAssemblyMode>1</CodeContractsAssemblyMode>
- <SignAssembly>true</SignAssembly>
- <AssemblyOriginatorKeyFile>..\..\InterimKey.snk</AssemblyOriginatorKeyFile>
- <FileUpgradeFlags>
- </FileUpgradeFlags>
- <OldToolsVersion>3.5</OldToolsVersion>
- <UpgradeBackupLocation />
- <PublishUrl>publish\</PublishUrl>
- <Install>true</Install>
- <InstallFrom>Disk</InstallFrom>
- <UpdateEnabled>false</UpdateEnabled>
- <UpdateMode>Foreground</UpdateMode>
- <UpdateInterval>7</UpdateInterval>
- <UpdateIntervalUnits>Days</UpdateIntervalUnits>
- <UpdatePeriodically>false</UpdatePeriodically>
- <UpdateRequired>false</UpdateRequired>
- <MapFileExtensions>true</MapFileExtensions>
- <ApplicationRevision>0</ApplicationRevision>
- <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
- <IsWebBootstrapper>false</IsWebBootstrapper>
- <UseApplicationTrust>false</UseApplicationTrust>
- <BootstrapperEnabled>true</BootstrapperEnabled>
- <TargetFrameworkProfile Condition=" '$(OS)' == 'Windows_NT'" >Client</TargetFrameworkProfile>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- <DebugSymbols>true</DebugSymbols>
- <DebugType>full</DebugType>
- <Optimize>false</Optimize>
- <OutputPath>bin\Debug\</OutputPath>
- <DefineConstants>DEBUG;TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- <CodeContractsEnableRuntimeChecking>False</CodeContractsEnableRuntimeChecking>
- <CodeContractsRuntimeOnlyPublicSurface>False</CodeContractsRuntimeOnlyPublicSurface>
- <CodeContractsRuntimeThrowOnFailure>True</CodeContractsRuntimeThrowOnFailure>
- <CodeContractsRuntimeCallSiteRequires>False</CodeContractsRuntimeCallSiteRequires>
- <CodeContractsRunCodeAnalysis>False</CodeContractsRunCodeAnalysis>
- <CodeContractsNonNullObligations>False</CodeContractsNonNullObligations>
- <CodeContractsBoundsObligations>False</CodeContractsBoundsObligations>
- <CodeContractsArithmeticObligations>False</CodeContractsArithmeticObligations>
- <CodeContractsPointerObligations>False</CodeContractsPointerObligations>
- <CodeContractsContainerAnalysis>False</CodeContractsContainerAnalysis>
- <CodeContractsRedundantAssumptions>False</CodeContractsRedundantAssumptions>
- <CodeContractsRunInBackground>True</CodeContractsRunInBackground>
- <CodeContractsShowSquigglies>False</CodeContractsShowSquigglies>
- <CodeContractsUseBaseLine>False</CodeContractsUseBaseLine>
- <CodeContractsEmitXMLDocs>False</CodeContractsEmitXMLDocs>
- <CodeContractsCustomRewriterAssembly>
- </CodeContractsCustomRewriterAssembly>
- <CodeContractsCustomRewriterClass>
- </CodeContractsCustomRewriterClass>
- <CodeContractsLibPaths>
- </CodeContractsLibPaths>
- <CodeContractsExtraRewriteOptions>
- </CodeContractsExtraRewriteOptions>
- <CodeContractsExtraAnalysisOptions>
- </CodeContractsExtraAnalysisOptions>
- <CodeContractsBaseLineFile>
- </CodeContractsBaseLineFile>
- <CodeContractsRuntimeCheckingLevel>Full</CodeContractsRuntimeCheckingLevel>
- <CodeContractsReferenceAssembly>%28none%29</CodeContractsReferenceAssembly>
- <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- <DebugType>pdbonly</DebugType>
- <Optimize>true</Optimize>
- <OutputPath>bin\Release\</OutputPath>
- <DefineConstants>TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'z3apidebug|AnyCPU' ">
- <DebugSymbols>true</DebugSymbols>
- <OutputPath>bin\z3apidebug\</OutputPath>
- <DefineConstants>DEBUG;TRACE</DefineConstants>
- <DebugType>full</DebugType>
- <PlatformTarget>AnyCPU</PlatformTarget>
- <CodeAnalysisRuleAssemblies>
- </CodeAnalysisRuleAssemblies>
- <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
- <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
- <ErrorReport>prompt</ErrorReport>
- <CodeAnalysisRuleSet>Migrated rules for SMTLib.ruleset</CodeAnalysisRuleSet>
- <CodeAnalysisIgnoreBuiltInRules>true</CodeAnalysisIgnoreBuiltInRules>
- <WarningLevel>4</WarningLevel>
- <Optimize>false</Optimize>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Checked|AnyCPU'">
- <DebugSymbols>true</DebugSymbols>
- <OutputPath>bin\Checked\</OutputPath>
- <DefineConstants>DEBUG;TRACE</DefineConstants>
- <DebugType>full</DebugType>
- <PlatformTarget>AnyCPU</PlatformTarget>
- <CodeAnalysisLogFile>bin\Debug\Provers.SMTLib.dll.CodeAnalysisLog.xml</CodeAnalysisLogFile>
- <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
- <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
- <ErrorReport>prompt</ErrorReport>
- <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
- <CodeAnalysisRuleSetDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
- <CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
- <CodeContractsEnableRuntimeChecking>True</CodeContractsEnableRuntimeChecking>
- <CodeContractsRuntimeOnlyPublicSurface>False</CodeContractsRuntimeOnlyPublicSurface>
- <CodeContractsRuntimeThrowOnFailure>True</CodeContractsRuntimeThrowOnFailure>
- <CodeContractsRuntimeCallSiteRequires>False</CodeContractsRuntimeCallSiteRequires>
- <CodeContractsRuntimeSkipQuantifiers>False</CodeContractsRuntimeSkipQuantifiers>
- <CodeContractsRunCodeAnalysis>False</CodeContractsRunCodeAnalysis>
- <CodeContractsNonNullObligations>False</CodeContractsNonNullObligations>
- <CodeContractsBoundsObligations>False</CodeContractsBoundsObligations>
- <CodeContractsArithmeticObligations>False</CodeContractsArithmeticObligations>
- <CodeContractsEnumObligations>False</CodeContractsEnumObligations>
- <CodeContractsPointerObligations>False</CodeContractsPointerObligations>
- <CodeContractsRedundantAssumptions>False</CodeContractsRedundantAssumptions>
- <CodeContractsRunInBackground>True</CodeContractsRunInBackground>
- <CodeContractsShowSquigglies>False</CodeContractsShowSquigglies>
- <CodeContractsUseBaseLine>False</CodeContractsUseBaseLine>
- <CodeContractsEmitXMLDocs>False</CodeContractsEmitXMLDocs>
- <CodeContractsCustomRewriterAssembly />
- <CodeContractsCustomRewriterClass />
- <CodeContractsLibPaths />
- <CodeContractsExtraRewriteOptions />
- <CodeContractsExtraAnalysisOptions />
- <CodeContractsBaseLineFile />
- <CodeContractsCacheAnalysisResults>False</CodeContractsCacheAnalysisResults>
- <CodeContractsRuntimeCheckingLevel>Full</CodeContractsRuntimeCheckingLevel>
- <CodeContractsReferenceAssembly>Build</CodeContractsReferenceAssembly>
- <CodeContractsAnalysisWarningLevel>0</CodeContractsAnalysisWarningLevel>
- <WarningLevel>4</WarningLevel>
- <Optimize>false</Optimize>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'QED|AnyCPU'">
- <DebugSymbols>true</DebugSymbols>
- <OutputPath>bin\QED\</OutputPath>
- <DefineConstants>DEBUG;TRACE</DefineConstants>
- <DebugType>full</DebugType>
- <PlatformTarget>AnyCPU</PlatformTarget>
- <ErrorReport>prompt</ErrorReport>
- <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
- </PropertyGroup>
- <ItemGroup>
- <Reference Include="System" />
- <Reference Include="System.Core">
- <RequiredTargetFramework>3.5</RequiredTargetFramework>
- </Reference>
- <Reference Include="System.Data" />
- <Reference Include="System.Xml" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="Inspector.cs" />
- <Compile Include="SMTLibProverOptions.cs" />
- <Compile Include="ProverInterface.cs" />
- <Compile Include="SExpr.cs" />
- <Compile Include="SMTLibLineariser.cs" />
- <Compile Include="SMTLibNamer.cs" />
- <Compile Include="SMTLibProcess.cs" />
- <Compile Include="TypeDeclCollector.cs" />
- <Compile Include="..\..\version.cs" />
- <Compile Include="Z3.cs" />
- <Compile Include="CVC4.cs" />
- </ItemGroup>
- <ItemGroup>
- <ProjectReference Include="..\..\Basetypes\Basetypes.csproj">
- <Project>{43DFAD18-3E35-4558-9BE2-CAFF6B5BA8A0}</Project>
- <Name>Basetypes</Name>
- </ProjectReference>
- <ProjectReference Include="..\..\CodeContractsExtender\CodeContractsExtender.csproj">
- <Project>{ACCC0156-0921-43ED-8F67-AD8BDC8CDE31}</Project>
- <Name>CodeContractsExtender</Name>
- </ProjectReference>
- <ProjectReference Include="..\..\Core\Core.csproj">
- <Project>{B230A69C-C466-4065-B9C1-84D80E76D802}</Project>
- <Name>Core</Name>
- </ProjectReference>
- <ProjectReference Include="..\..\Graph\Graph.csproj">
- <Project>{69A2B0B8-BCAC-4101-AE7A-556FCC58C06E}</Project>
- <Name>Graph</Name>
- </ProjectReference>
- <ProjectReference Include="..\..\Model\Model.csproj">
- <Project>{ACEF88D5-DADD-46DA-BAE1-2144D63F4C83}</Project>
- <Name>Model</Name>
- </ProjectReference>
- <ProjectReference Include="..\..\ParserHelper\ParserHelper.csproj">
- <Project>{FCD3AC7F-9DFD-46C8-AB1E-09F0B0F16DC5}</Project>
- <Name>ParserHelper</Name>
- </ProjectReference>
- <ProjectReference Include="..\..\VCExpr\VCExpr.csproj">
- <Project>{56FFDBCA-7D14-43B8-A6CA-22A20E417EE1}</Project>
- <Name>VCExpr</Name>
- </ProjectReference>
- <ProjectReference Include="..\..\VCGeneration\VCGeneration.csproj">
- <Project>{E1F10180-C7B9-4147-B51F-FA1B701966DC}</Project>
- <Name>VCGeneration</Name>
- </ProjectReference>
- </ItemGroup>
- <ItemGroup>
- <Folder Include="Properties\" />
- </ItemGroup>
- <ItemGroup>
- <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
- <Visible>False</Visible>
- <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
- <Install>false</Install>
- </BootstrapperPackage>
- <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
- <Visible>False</Visible>
- <ProductName>.NET Framework 3.5 SP1</ProductName>
- <Install>true</Install>
- </BootstrapperPackage>
- <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
- <Visible>False</Visible>
- <ProductName>Windows Installer 3.1</ProductName>
- <Install>true</Install>
- </BootstrapperPackage>
- </ItemGroup>
- <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
- <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
- Other similar extension points exist, see Microsoft.Common.targets.
- <Target Name="BeforeBuild">
- </Target>
- <Target Name="AfterBuild">
- </Target>
- -->
-</Project>
+<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProductVersion>9.0.21022</ProductVersion> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{9B163AA3-36BC-4AFB-88AB-79BC9E97E401}</ProjectGuid> + <OutputType>Library</OutputType> + <AppDesignerFolder>Properties</AppDesignerFolder> + <RootNamespace>Microsoft.Boogie.SMTLib</RootNamespace> + <AssemblyName>Provers.SMTLib</AssemblyName> + <TargetFrameworkVersion>v4.0</TargetFrameworkVersion> + <FileAlignment>512</FileAlignment> + <CodeContractsAssemblyMode>1</CodeContractsAssemblyMode> + <SignAssembly>true</SignAssembly> + <AssemblyOriginatorKeyFile>..\..\InterimKey.snk</AssemblyOriginatorKeyFile> + <FileUpgradeFlags> + </FileUpgradeFlags> + <OldToolsVersion>3.5</OldToolsVersion> + <UpgradeBackupLocation /> + <PublishUrl>publish\</PublishUrl> + <Install>true</Install> + <InstallFrom>Disk</InstallFrom> + <UpdateEnabled>false</UpdateEnabled> + <UpdateMode>Foreground</UpdateMode> + <UpdateInterval>7</UpdateInterval> + <UpdateIntervalUnits>Days</UpdateIntervalUnits> + <UpdatePeriodically>false</UpdatePeriodically> + <UpdateRequired>false</UpdateRequired> + <MapFileExtensions>true</MapFileExtensions> + <ApplicationRevision>0</ApplicationRevision> + <ApplicationVersion>1.0.0.%2a</ApplicationVersion> + <IsWebBootstrapper>false</IsWebBootstrapper> + <UseApplicationTrust>false</UseApplicationTrust> + <BootstrapperEnabled>true</BootstrapperEnabled> + <TargetFrameworkProfile Condition=" '$(OS)' == 'Windows_NT'" >Client</TargetFrameworkProfile> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + <DebugSymbols>true</DebugSymbols> + <DebugType>full</DebugType> + <Optimize>false</Optimize> + <OutputPath>bin\Debug\</OutputPath> + <DefineConstants>DEBUG;TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + <CodeContractsEnableRuntimeChecking>False</CodeContractsEnableRuntimeChecking> + <CodeContractsRuntimeOnlyPublicSurface>False</CodeContractsRuntimeOnlyPublicSurface> + <CodeContractsRuntimeThrowOnFailure>True</CodeContractsRuntimeThrowOnFailure> + <CodeContractsRuntimeCallSiteRequires>False</CodeContractsRuntimeCallSiteRequires> + <CodeContractsRunCodeAnalysis>False</CodeContractsRunCodeAnalysis> + <CodeContractsNonNullObligations>False</CodeContractsNonNullObligations> + <CodeContractsBoundsObligations>False</CodeContractsBoundsObligations> + <CodeContractsArithmeticObligations>False</CodeContractsArithmeticObligations> + <CodeContractsPointerObligations>False</CodeContractsPointerObligations> + <CodeContractsContainerAnalysis>False</CodeContractsContainerAnalysis> + <CodeContractsRedundantAssumptions>False</CodeContractsRedundantAssumptions> + <CodeContractsRunInBackground>True</CodeContractsRunInBackground> + <CodeContractsShowSquigglies>False</CodeContractsShowSquigglies> + <CodeContractsUseBaseLine>False</CodeContractsUseBaseLine> + <CodeContractsEmitXMLDocs>False</CodeContractsEmitXMLDocs> + <CodeContractsCustomRewriterAssembly> + </CodeContractsCustomRewriterAssembly> + <CodeContractsCustomRewriterClass> + </CodeContractsCustomRewriterClass> + <CodeContractsLibPaths> + </CodeContractsLibPaths> + <CodeContractsExtraRewriteOptions> + </CodeContractsExtraRewriteOptions> + <CodeContractsExtraAnalysisOptions> + </CodeContractsExtraAnalysisOptions> + <CodeContractsBaseLineFile> + </CodeContractsBaseLineFile> + <CodeContractsRuntimeCheckingLevel>Full</CodeContractsRuntimeCheckingLevel> + <CodeContractsReferenceAssembly>%28none%29</CodeContractsReferenceAssembly> + <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + <DebugType>pdbonly</DebugType> + <Optimize>true</Optimize> + <OutputPath>bin\Release\</OutputPath> + <DefineConstants>TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'z3apidebug|AnyCPU' "> + <DebugSymbols>true</DebugSymbols> + <OutputPath>bin\z3apidebug\</OutputPath> + <DefineConstants>DEBUG;TRACE</DefineConstants> + <DebugType>full</DebugType> + <PlatformTarget>AnyCPU</PlatformTarget> + <CodeAnalysisRuleAssemblies> + </CodeAnalysisRuleAssemblies> + <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression> + <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile> + <ErrorReport>prompt</ErrorReport> + <CodeAnalysisRuleSet>Migrated rules for SMTLib.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisIgnoreBuiltInRules>true</CodeAnalysisIgnoreBuiltInRules> + <WarningLevel>4</WarningLevel> + <Optimize>false</Optimize> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Checked|AnyCPU'"> + <DebugSymbols>true</DebugSymbols> + <OutputPath>bin\Checked\</OutputPath> + <DefineConstants>DEBUG;TRACE</DefineConstants> + <DebugType>full</DebugType> + <PlatformTarget>AnyCPU</PlatformTarget> + <CodeAnalysisLogFile>bin\Debug\Provers.SMTLib.dll.CodeAnalysisLog.xml</CodeAnalysisLogFile> + <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression> + <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile> + <ErrorReport>prompt</ErrorReport> + <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRuleSetDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories> + <CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories> + <CodeContractsEnableRuntimeChecking>True</CodeContractsEnableRuntimeChecking> + <CodeContractsRuntimeOnlyPublicSurface>False</CodeContractsRuntimeOnlyPublicSurface> + <CodeContractsRuntimeThrowOnFailure>True</CodeContractsRuntimeThrowOnFailure> + <CodeContractsRuntimeCallSiteRequires>False</CodeContractsRuntimeCallSiteRequires> + <CodeContractsRuntimeSkipQuantifiers>False</CodeContractsRuntimeSkipQuantifiers> + <CodeContractsRunCodeAnalysis>False</CodeContractsRunCodeAnalysis> + <CodeContractsNonNullObligations>False</CodeContractsNonNullObligations> + <CodeContractsBoundsObligations>False</CodeContractsBoundsObligations> + <CodeContractsArithmeticObligations>False</CodeContractsArithmeticObligations> + <CodeContractsEnumObligations>False</CodeContractsEnumObligations> + <CodeContractsPointerObligations>False</CodeContractsPointerObligations> + <CodeContractsRedundantAssumptions>False</CodeContractsRedundantAssumptions> + <CodeContractsRunInBackground>True</CodeContractsRunInBackground> + <CodeContractsShowSquigglies>False</CodeContractsShowSquigglies> + <CodeContractsUseBaseLine>False</CodeContractsUseBaseLine> + <CodeContractsEmitXMLDocs>False</CodeContractsEmitXMLDocs> + <CodeContractsCustomRewriterAssembly /> + <CodeContractsCustomRewriterClass /> + <CodeContractsLibPaths /> + <CodeContractsExtraRewriteOptions /> + <CodeContractsExtraAnalysisOptions /> + <CodeContractsBaseLineFile /> + <CodeContractsCacheAnalysisResults>False</CodeContractsCacheAnalysisResults> + <CodeContractsRuntimeCheckingLevel>Full</CodeContractsRuntimeCheckingLevel> + <CodeContractsReferenceAssembly>Build</CodeContractsReferenceAssembly> + <CodeContractsAnalysisWarningLevel>0</CodeContractsAnalysisWarningLevel> + <WarningLevel>4</WarningLevel> + <Optimize>false</Optimize> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'QED|AnyCPU'"> + <DebugSymbols>true</DebugSymbols> + <OutputPath>bin\QED\</OutputPath> + <DefineConstants>DEBUG;TRACE</DefineConstants> + <DebugType>full</DebugType> + <PlatformTarget>AnyCPU</PlatformTarget> + <ErrorReport>prompt</ErrorReport> + <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <ItemGroup> + <Reference Include="System" /> + <Reference Include="System.Core"> + <RequiredTargetFramework>3.5</RequiredTargetFramework> + </Reference> + <Reference Include="System.Data" /> + <Reference Include="System.Xml" /> + </ItemGroup> + <ItemGroup> + <Compile Include="Inspector.cs" /> + <Compile Include="SMTLibProverOptions.cs" /> + <Compile Include="ProverInterface.cs" /> + <Compile Include="SExpr.cs" /> + <Compile Include="SMTLibLineariser.cs" /> + <Compile Include="SMTLibNamer.cs" /> + <Compile Include="SMTLibProcess.cs" /> + <Compile Include="TypeDeclCollector.cs" /> + <Compile Include="..\..\version.cs" /> + <Compile Include="Z3.cs" /> + <Compile Include="CVC4.cs" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\..\Basetypes\Basetypes.csproj"> + <Project>{43DFAD18-3E35-4558-9BE2-CAFF6B5BA8A0}</Project> + <Name>Basetypes</Name> + </ProjectReference> + <ProjectReference Include="..\..\CodeContractsExtender\CodeContractsExtender.csproj"> + <Project>{ACCC0156-0921-43ED-8F67-AD8BDC8CDE31}</Project> + <Name>CodeContractsExtender</Name> + </ProjectReference> + <ProjectReference Include="..\..\Core\Core.csproj"> + <Project>{B230A69C-C466-4065-B9C1-84D80E76D802}</Project> + <Name>Core</Name> + </ProjectReference> + <ProjectReference Include="..\..\Graph\Graph.csproj"> + <Project>{69A2B0B8-BCAC-4101-AE7A-556FCC58C06E}</Project> + <Name>Graph</Name> + </ProjectReference> + <ProjectReference Include="..\..\Model\Model.csproj"> + <Project>{ACEF88D5-DADD-46DA-BAE1-2144D63F4C83}</Project> + <Name>Model</Name> + </ProjectReference> + <ProjectReference Include="..\..\ParserHelper\ParserHelper.csproj"> + <Project>{FCD3AC7F-9DFD-46C8-AB1E-09F0B0F16DC5}</Project> + <Name>ParserHelper</Name> + </ProjectReference> + <ProjectReference Include="..\..\VCExpr\VCExpr.csproj"> + <Project>{56FFDBCA-7D14-43B8-A6CA-22A20E417EE1}</Project> + <Name>VCExpr</Name> + </ProjectReference> + <ProjectReference Include="..\..\VCGeneration\VCGeneration.csproj"> + <Project>{E1F10180-C7B9-4147-B51F-FA1B701966DC}</Project> + <Name>VCGeneration</Name> + </ProjectReference> + </ItemGroup> + <ItemGroup> + <Folder Include="Properties\" /> + </ItemGroup> + <ItemGroup> + <BootstrapperPackage Include="Microsoft.Net.Client.3.5"> + <Visible>False</Visible> + <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName> + <Install>false</Install> + </BootstrapperPackage> + <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1"> + <Visible>False</Visible> + <ProductName>.NET Framework 3.5 SP1</ProductName> + <Install>true</Install> + </BootstrapperPackage> + <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1"> + <Visible>False</Visible> + <ProductName>Windows Installer 3.1</ProductName> + <Install>true</Install> + </BootstrapperPackage> + </ItemGroup> + <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> + <!-- To modify your build process, add your task inside one of the targets below and uncomment it. + Other similar extension points exist, see Microsoft.Common.targets. + <Target Name="BeforeBuild"> + </Target> + <Target Name="AfterBuild"> + </Target> + --> +</Project> diff --git a/Source/Provers/SMTLib/SMTLibLineariser.cs b/Source/Provers/SMTLib/SMTLibLineariser.cs index f431c3d5..dcf95bd2 100644 --- a/Source/Provers/SMTLib/SMTLibLineariser.cs +++ b/Source/Provers/SMTLib/SMTLibLineariser.cs @@ -1,851 +1,851 @@ -//-----------------------------------------------------------------------------
-//
-// Copyright (C) Microsoft Corporation. All Rights Reserved.
-//
-//-----------------------------------------------------------------------------
-using System;
-using System.Text;
-using System.IO;
-using System.Collections;
-using System.Collections.Generic;
-using System.Diagnostics.Contracts;
-using System.Linq;
-using Microsoft.Basetypes;
-using Microsoft.Boogie.VCExprAST;
-
-// Method to turn VCExprs into strings that can be fed into SMT
-// solvers. This is currently quite similar to the
-// SimplifyLikeLineariser (but the code is independent)
-
-namespace Microsoft.Boogie.SMTLib
-{
-
- // Options for the linearisation
- public class LineariserOptions
- {
- public static LineariserOptions Default = new LineariserOptions();
- public bool LabelsBelowQuantifiers = false;
- }
-
-
- ////////////////////////////////////////////////////////////////////////////////////////
-
- // Lineariser for expressions. The result (bool) is currently not used for anything
- public class SMTLibExprLineariser : IVCExprVisitor<bool, LineariserOptions/*!*/>
- {
-
- public static string ToString(VCExpr e, UniqueNamer namer, SMTLibProverOptions opts)
- {
- Contract.Requires(e != null);
- Contract.Requires(namer != null);
- Contract.Ensures(Contract.Result<string>() != null);
-
- StringWriter sw = new StringWriter();
- SMTLibExprLineariser lin = new SMTLibExprLineariser(sw, namer, opts);
- Contract.Assert(lin != null);
- lin.Linearise(e, LineariserOptions.Default);
- return cce.NonNull(sw.ToString());
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////
-
- private readonly TextWriter wr;
- [ContractInvariantMethod]
- void ObjectInvariant()
- {
- Contract.Invariant(wr != null);
- Contract.Invariant(Namer != null);
- }
-
- private SMTLibOpLineariser OpLinObject = null;
- private IVCExprOpVisitor<bool, LineariserOptions>/*!>!*/ OpLineariser
- {
- get
- {
- Contract.Ensures(Contract.Result<IVCExprOpVisitor<bool, LineariserOptions>>() != null);
-
- if (OpLinObject == null)
- OpLinObject = new SMTLibOpLineariser(this, wr);
- return OpLinObject;
- }
- }
-
- internal readonly UniqueNamer Namer;
- internal int UnderQuantifier = 0;
- internal readonly SMTLibProverOptions ProverOptions;
-
- public SMTLibExprLineariser(TextWriter wr, UniqueNamer namer, SMTLibProverOptions opts)
- {
- Contract.Requires(wr != null); Contract.Requires(namer != null);
- this.wr = wr;
- this.Namer = namer;
- this.ProverOptions = opts;
- }
-
- public void Linearise(VCExpr expr, LineariserOptions options)
- {
- Contract.Requires(expr != null);
- Contract.Requires(options != null);
- expr.Accept<bool, LineariserOptions>(this, options);
- }
-
- /////////////////////////////////////////////////////////////////////////////////////
-
- private static void TypeToStringHelper(Type t, StringBuilder sb)
- {
- Contract.Requires(t != null);
-
- TypeSynonymAnnotation syn = t as TypeSynonymAnnotation;
- if (syn != null) {
- TypeToStringHelper(syn.ExpandedType, sb);
- } else {
- if (t.IsMap && CommandLineOptions.Clo.UseArrayTheory) {
- MapType m = t.AsMap;
- // Contract.Assert(m.MapArity == 1);
- sb.Append("(Array ");
- foreach (Type tp in m.Arguments)
- sb.Append(TypeToString(tp)).Append(" ");
- sb.Append(TypeToString(m.Result)).Append(")");
- } else if (t.IsMap) {
- MapType m = t.AsMap;
- sb.Append('[');
- for (int i = 0; i < m.MapArity; ++i) {
- if (i != 0)
- sb.Append(',');
- TypeToStringHelper(m.Arguments[i], sb);
- }
- sb.Append(']');
- TypeToStringHelper(m.Result, sb);
- } else if (t.IsBool || t.IsInt || t.IsReal || t.IsBv) {
- sb.Append(TypeToString(t));
- } else {
- System.IO.StringWriter buffer = new System.IO.StringWriter();
- using (TokenTextWriter stream = new TokenTextWriter("<buffer>", buffer, /*setTokens=*/false, /*pretty=*/false)) {
- t.Emit(stream);
- }
- sb.Append(buffer.ToString());
- }
- }
-
- }
-
- public static string TypeToString(Type t)
- {
- Contract.Requires(t != null);
- Contract.Ensures(Contract.Result<string>() != null);
-
- if (t.IsBool)
- return "Bool";
- else if (t.IsInt)
- return "Int";
- else if (t.IsReal)
- return "Real";
- else if (t.IsBv) {
- return "(_ BitVec " + t.BvBits + ")";
- } else {
- StringBuilder sb = new StringBuilder();
- TypeToStringHelper(t, sb);
- var s = sb.ToString();
- if (s[0] == '(')
- return s;
- else
- return SMTLibNamer.QuoteId("T@" + s);
- }
- }
-
- public static string ExtractBuiltin(Function f)
- {
- Contract.Requires(f != null);
- string retVal = null;
- retVal = f.FindStringAttribute("bvbuiltin");
-
- // It used to be "sign_extend 12" in Simplify, and is "(_ sign_extend 12)" with SMT
- if (retVal != null && (retVal.StartsWith("sign_extend ") || retVal.StartsWith("zero_extend ")))
- return "(_ " + retVal + ")";
-
- if (retVal == null) {
- retVal = f.FindStringAttribute("builtin");
- }
-
- if (retVal != null && !CommandLineOptions.Clo.UseArrayTheory && SMTLibOpLineariser.ArrayOps.Contains(retVal))
- {
- retVal = null;
- }
-
- return retVal;
- }
-
- /////////////////////////////////////////////////////////////////////////////////////
-
- public bool Visit(VCExprLiteral node, LineariserOptions options)
- {
- if (node == VCExpressionGenerator.True)
- wr.Write("true");
- else if (node == VCExpressionGenerator.False)
- wr.Write("false");
- else if (node is VCExprIntLit) {
- BigNum lit = ((VCExprIntLit)node).Val;
- if (lit.IsNegative)
- // In SMT2 "-42" is an identifier (SMT2, Sect. 3.2 "Symbols")
- wr.Write("(- 0 {0})", lit.Abs);
- else
- wr.Write(lit);
- }
- else if (node is VCExprRealLit) {
- BigDec lit = ((VCExprRealLit)node).Val;
- if (lit.IsNegative)
- // In SMT2 "-42" is an identifier (SMT2, Sect. 3.2 "Symbols")
- wr.Write("(- 0.0 {0})", lit.Abs.ToDecimalString());
- else
- wr.Write(lit.ToDecimalString());
- }
- else {
- Contract.Assert(false);
- throw new cce.UnreachableException();
- }
-
- return true;
- }
-
- /////////////////////////////////////////////////////////////////////////////////////
-
- public bool Visit(VCExprNAry node, LineariserOptions options)
- {
- VCExprOp op = node.Op;
- Contract.Assert(op != null);
-
- var booleanOps = new HashSet<VCExprOp>();
- booleanOps.Add(VCExpressionGenerator.NotOp);
- booleanOps.Add(VCExpressionGenerator.ImpliesOp);
- booleanOps.Add(VCExpressionGenerator.AndOp);
- booleanOps.Add(VCExpressionGenerator.OrOp);
- if (booleanOps.Contains(op))
- {
- Stack<VCExpr> exprs = new Stack<VCExpr>();
- exprs.Push(node);
- while (exprs.Count > 0)
- {
- VCExpr expr = exprs.Pop();
- if (expr == null)
- {
- wr.Write(")");
- continue;
- }
- wr.Write(" ");
- VCExprNAry naryExpr = expr as VCExprNAry;
- if (naryExpr == null || !booleanOps.Contains(naryExpr.Op))
- {
- Linearise(expr, options);
- continue;
- }
- else if (naryExpr.Op.Equals(VCExpressionGenerator.NotOp))
- {
- wr.Write("(not");
- }
- else if (naryExpr.Op.Equals(VCExpressionGenerator.ImpliesOp))
- {
- wr.Write("(=>");
- }
- else if (naryExpr.Op.Equals(VCExpressionGenerator.AndOp))
- {
- wr.Write("(and");
- }
- else
- {
- System.Diagnostics.Debug.Assert(naryExpr.Op.Equals(VCExpressionGenerator.OrOp));
- wr.Write("(or");
- }
- exprs.Push(null);
- for (int i = naryExpr.Arity - 1; i >= 0; i--)
- {
- exprs.Push(naryExpr[i]);
- }
- }
- return true;
- }
- return node.Accept<bool, LineariserOptions/*!*/>(OpLineariser, options);
- }
-
- /////////////////////////////////////////////////////////////////////////////////////
-
- public bool Visit(VCExprVar node, LineariserOptions options)
- {
- wr.Write(Namer.GetQuotedName(node, node.Name));
- return true;
- }
-
- /////////////////////////////////////////////////////////////////////////////////////
-
- public bool Visit(VCExprQuantifier node, LineariserOptions options)
- {
- Contract.Assert(node.TypeParameters.Count == 0);
-
- UnderQuantifier++;
- 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.GetQuotedLocalName(var, var.Name);
- Contract.Assert(printedName != null);
- wr.Write("({0} {1}) ", printedName, TypeToString(var.Type));
- }
-
- wr.Write(") ");
-
- VCQuantifierInfos infos = node.Infos;
- var weight = QKeyValue.FindIntAttribute(infos.attributes, "weight", 1);
- if (!ProverOptions.UseWeights)
- weight = 1;
- var hasAttrs = node.Triggers.Count > 0 || infos.qid != null || weight != 1 || infos.uniqueId != -1;
-
- if (hasAttrs)
- wr.Write("(! ");
-
- Linearise(node.Body, options);
-
- if (hasAttrs) {
- wr.Write("\n");
- if (infos.qid != null)
- wr.Write(" :qid {0}\n", SMTLibNamer.QuoteId(infos.qid));
- if (weight != 1)
- wr.Write(" :weight {0}\n", weight);
- if (infos.uniqueId != -1)
- wr.Write(" :skolemid |{0}|\n", infos.uniqueId);
- WriteTriggers(node.Triggers, options);
-
- wr.Write(")");
- }
-
- wr.Write(")");
-
- return true;
-
- } finally {
- UnderQuantifier--;
- Namer.PopScope();
- }
- }
-
- private void WriteTriggers(List<VCTrigger/*!>!*/> triggers, LineariserOptions options)
- {
- Contract.Requires(options != null);
- Contract.Requires(triggers != null);
- // 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) {
- foreach (VCTrigger vcTrig in triggers) {
- Contract.Assert(vcTrig != null);
- if (vcTrig.Pos) {
- wr.Write(" :pattern (");
- foreach (VCExpr e in vcTrig.Exprs) {
- Contract.Assert(e != null);
- wr.Write(" ");
- var subPat = e;
- var nary = e as VCExprNAry;
- if (nary != null && (nary.Op == VCExpressionGenerator.NeqOp || nary.Op == VCExpressionGenerator.EqOp)) {
- if (nary[0] is VCExprLiteral)
- subPat = nary[1];
- else if (nary[1] is VCExprLiteral)
- subPat = nary[0];
- }
- Linearise(subPat, options);
- }
- wr.Write(")\n");
- }
- }
- } 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
- foreach (VCTrigger vcTrig in triggers) {
- Contract.Assert(vcTrig != null);
- if (!vcTrig.Pos) {
- wr.Write(" :no-pattern ");
- Contract.Assert(vcTrig.Exprs.Count == 1);
- Linearise(vcTrig.Exprs[0], options);
- wr.Write("\n");
- }
- }
- }
- }
-
- /////////////////////////////////////////////////////////////////////////////////////
-
- public bool Visit(VCExprLet node, LineariserOptions options)
- {
- Namer.PushScope();
- try {
-
- foreach (VCExprLetBinding b in node) {
- wr.Write("(let (");
- Contract.Assert(b != null);
- wr.Write("({0} ", Namer.GetQuotedName(b.V, b.V.Name));
- Linearise(b.E, options);
- wr.Write("))\n");
- }
- Linearise(node.Body, options);
- foreach (VCExprLetBinding b in node)
- wr.Write(")");
- return true;
- } finally {
- Namer.PopScope();
- }
- }
-
- /////////////////////////////////////////////////////////////////////////////////////
-
- // Lineariser for operator terms. The result (bool) is currently not used for anything
- internal class SMTLibOpLineariser : IVCExprOpVisitor<bool, LineariserOptions/*!*/>
- {
- private readonly SMTLibExprLineariser ExprLineariser;
- private readonly TextWriter wr;
- [ContractInvariantMethod]
- void ObjectInvariant()
- {
- Contract.Invariant(wr != null);
- Contract.Invariant(ExprLineariser != null);
- }
-
-
- public SMTLibOpLineariser(SMTLibExprLineariser ExprLineariser, TextWriter wr)
- {
- Contract.Requires(ExprLineariser != null);
- Contract.Requires(wr != null);
- this.ExprLineariser = ExprLineariser;
- this.wr = wr;
- }
-
- ///////////////////////////////////////////////////////////////////////////////////
- private void WriteApplication(string opName, IEnumerable<VCExpr>/*!>!*/ args, LineariserOptions options)
- {
- Contract.Requires(cce.NonNullElements(args));
- Contract.Requires(options != null);
- Contract.Assert(opName != null);
-
- bool hasArgs = false;
- foreach (VCExpr e in args) {
- Contract.Assert(e != null);
- if (!hasArgs)
- wr.Write("({0}", opName);
- wr.Write(" ");
- ExprLineariser.Linearise(e, options);
- hasArgs = true;
- }
-
- if (hasArgs)
- wr.Write(")");
- else
- wr.Write("{0}", opName);
- }
-
- ///////////////////////////////////////////////////////////////////////////////////
-
- public bool VisitNotOp(VCExprNAry node, LineariserOptions options)
- {
- WriteApplication("not", node, options); // arguments can be both terms and formulas
- return true;
- }
-
- private bool PrintEq(VCExprNAry node, LineariserOptions options)
- {
- Contract.Requires(node != null);
- Contract.Requires(options != null);
-
- WriteApplication("=", node, options);
-
- return true;
- }
-
- public bool VisitEqOp(VCExprNAry node, LineariserOptions options)
- {
- return PrintEq(node, options);
- }
-
- public bool VisitNeqOp(VCExprNAry node, LineariserOptions options)
- {
- //Contract.Requires(node != null);
- //Contract.Requires(options != null);
- wr.Write("(not ");
- PrintEq(node, options);
- wr.Write(")");
- return true;
- }
-
- public bool VisitAndOp(VCExprNAry node, LineariserOptions options)
- {
- WriteApplication("and", node, options);
- return true;
- }
-
- public bool VisitOrOp(VCExprNAry node, LineariserOptions options)
- {
- WriteApplication("or", node, options);
- return true;
- }
-
- public bool VisitImpliesOp(VCExprNAry node, LineariserOptions options)
- {
- WriteApplication("=>", node, options);
- return true;
- }
-
- public bool VisitIfThenElseOp(VCExprNAry node, LineariserOptions options)
- {
- WriteApplication("ite", node, options);
- return true;
- }
-
- public bool VisitCustomOp(VCExprNAry node, LineariserOptions options)
- {
- VCExprCustomOp op = (VCExprCustomOp)node.Op;
- if (!ExprLineariser.ProverOptions.UseTickleBool && op.Name == "tickleBool")
- ExprLineariser.Linearise(VCExpressionGenerator.True, options);
- else
- WriteApplication(op.Name, node, options);
- return true;
- }
-
- public bool VisitDistinctOp(VCExprNAry node, LineariserOptions options)
- {
- //Contract.Requires(node != null);
- //Contract.Requires(options != null);
-
- if (node.Length < 2) {
- ExprLineariser.Linearise(VCExpressionGenerator.True, options);
- } else {
- var groupings = node.GroupBy(e => e.Type).Where(g => g.Count() > 1).ToArray();
- if (groupings.Length == 0) {
- ExprLineariser.Linearise(VCExpressionGenerator.True, options);
- } else {
- if (groupings.Length > 1)
- wr.Write("(and ");
-
- foreach (var g in groupings) {
- wr.Write("(distinct");
- foreach (VCExpr e in g) {
- Contract.Assert(e != null);
- wr.Write(" ");
- ExprLineariser.Linearise(e, options);
- }
- wr.Write(")");
- }
-
- if (groupings.Length > 1)
- wr.Write(")");
-
- wr.Write("\n");
- }
- }
-
- return true;
- }
-
- public bool VisitLabelOp(VCExprNAry node, LineariserOptions options)
- {
- if (ExprLineariser.UnderQuantifier > 0 && !options.LabelsBelowQuantifiers) {
- ExprLineariser.Linearise(node[0], options);
- return true;
- }
-
- var op = (VCExprLabelOp)node.Op;
-
- if (CommandLineOptions.Clo.UseLabels)
- {
- // Z3 extension
- //wr.Write("({0} {1} ", op.pos ? "lblpos" : "lblneg", SMTLibNamer.QuoteId(op.label));
- wr.Write("(! ");
- }
-
- if(!options.LabelsBelowQuantifiers)
- wr.Write("({0} {1} ", op.pos ? "and" : "or", SMTLibNamer.QuoteId(SMTLibNamer.LabelVar(op.label)));
-
- ExprLineariser.Linearise(node[0], options);
-
-
- if (!options.LabelsBelowQuantifiers)
- wr.Write(")");
-
- if (CommandLineOptions.Clo.UseLabels)
- wr.Write(" :{0} {1})", op.pos ? "lblpos" : "lblneg", SMTLibNamer.QuoteId(op.label));
-
- return true;
- }
-
- public bool VisitSelectOp(VCExprNAry node, LineariserOptions options)
- {
- var name = SimplifyLikeExprLineariser.SelectOpName(node);
- name = ExprLineariser.Namer.GetQuotedName(name, name);
- if (CommandLineOptions.Clo.UseArrayTheory)
- name = "select";
- WriteApplication(name, node, options);
- return true;
- }
-
- public bool VisitStoreOp(VCExprNAry node, LineariserOptions options)
- {
- var name = SimplifyLikeExprLineariser.StoreOpName(node);
- name = ExprLineariser.Namer.GetQuotedName(name, name);
- if (CommandLineOptions.Clo.UseArrayTheory)
- name = "store";
- WriteApplication(name, node, options);
- return true;
- }
-
- static char[] hex = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
- public bool VisitBvOp(VCExprNAry node, LineariserOptions options)
- {
- var lit = (VCExprIntLit)node[0];
- var bytes = lit.Val.ToByteArray();
- if (node.Type.BvBits % 8 == 0) {
- wr.Write("#x");
- for (var pos = node.Type.BvBits / 8 - 1; pos >= 0; pos--) {
- var k = pos < bytes.Length ? bytes[pos] : (byte)0;
- wr.Write(hex[k >> 4]);
- wr.Write(hex[k & 0xf]);
- }
- } else {
- wr.Write("#b");
- for (var pos = node.Type.BvBits - 1; pos >= 0; pos--) {
- var i = pos >> 3;
- var k = i < bytes.Length ? bytes[i] : (byte)0;
- wr.Write((k & (1 << (pos & 7))) == 0 ? '0' : '1');
- }
- }
- return true;
- }
-
- public bool VisitBvExtractOp(VCExprNAry node, LineariserOptions options)
- {
- var op = (VCExprBvExtractOp)node.Op;
- wr.Write("((_ extract {0} {1}) ", op.End - 1, op.Start);
- ExprLineariser.Linearise(node[0], options);
- wr.Write(")");
- return true;
- }
-
- public bool VisitBvConcatOp(VCExprNAry node, LineariserOptions options)
- {
- WriteApplication("concat", node, options);
- return true;
- }
-
- public bool VisitAddOp(VCExprNAry node, LineariserOptions options)
- {
- WriteApplication("+", node, options);
- return true;
- }
-
- public bool VisitSubOp(VCExprNAry node, LineariserOptions options)
- {
- WriteApplication("-", node, options);
- return true;
- }
-
- public bool VisitMulOp(VCExprNAry node, LineariserOptions options)
- {
- WriteApplication("*", node, options);
- return true;
- }
-
- public bool VisitDivOp(VCExprNAry node, LineariserOptions options)
- {
- WriteApplication("div", node, options);
- return true;
- }
-
- public bool VisitModOp(VCExprNAry node, LineariserOptions options)
- {
- WriteApplication("mod", node, options);
- return true;
- }
-
- public bool VisitRealDivOp(VCExprNAry node, LineariserOptions options) {
- WriteApplication("/", node, options);
- return true;
- }
-
- public bool VisitPowOp(VCExprNAry node, LineariserOptions options) {
- WriteApplication("real_pow", node, options);
- return true;
- }
-
- public bool VisitLtOp(VCExprNAry node, LineariserOptions options)
- {
- WriteApplication("<", node, options);
- return true;
- }
-
- public bool VisitLeOp(VCExprNAry node, LineariserOptions options)
- {
- WriteApplication("<=", node, options);
- return true;
- }
-
- public bool VisitGtOp(VCExprNAry node, LineariserOptions options)
- {
- WriteApplication(">", node, options);
- return true;
- }
-
- public bool VisitGeOp(VCExprNAry node, LineariserOptions options)
- {
- WriteApplication(">=", node, options);
- return true;
- }
-
- public bool VisitSubtypeOp(VCExprNAry node, LineariserOptions options)
- {
- WriteApplication("UOrdering2", node, options);
- return true;
- }
-
- public bool VisitSubtype3Op(VCExprNAry node, LineariserOptions options)
- {
- WriteApplication("UOrdering3", node, options);
- return true;
- }
-
- public bool VisitToIntOp(VCExprNAry node, LineariserOptions options) {
- WriteApplication("to_int", node, options);
- return true;
- }
-
- public bool VisitToRealOp(VCExprNAry node, LineariserOptions options) {
- WriteApplication("to_real", node, options);
- return true;
- }
-
- private string ExtractDatatype(Function func) {
- if (func is DatatypeSelector) {
- DatatypeSelector selector = (DatatypeSelector) func;
- Variable v = selector.constructor.InParams[selector.index];
- return ExprLineariser.Namer.GetQuotedName(v, v.Name + "#" + selector.constructor.Name);
- }
- else if (func is DatatypeMembership) {
- DatatypeMembership membership = (DatatypeMembership)func;
- return ExprLineariser.Namer.GetQuotedName(membership, "is-" + membership.constructor.Name);
- }
- else {
- return null;
- }
- }
-
- public bool VisitBoogieFunctionOp(VCExprNAry node, LineariserOptions options) {
- VCExprBoogieFunctionOp op = (VCExprBoogieFunctionOp)node.Op;
- Contract.Assert(op != null);
- string printedName;
-
- var builtin = ExtractBuiltin(op.Func);
- var datatype = ExtractDatatype(op.Func);
- if (builtin != null)
- {
- printedName = CheckMapApply(builtin, node);
- }
- else if (datatype != null)
- {
- printedName = datatype;
- }
- else
- {
- printedName = ExprLineariser.Namer.GetQuotedName(op.Func, op.Func.Name);
- }
- Contract.Assert(printedName != null);
-
- WriteApplication(printedName, node, options);
-
- return true;
- }
-
- private static Type ResultType(Type type) {
- MapType mapType = type as MapType;
- if (mapType != null) {
- return ResultType(mapType.Result);
- }
- else {
- return type;
- }
- }
-
- public static HashSet<string> ArrayOps = new HashSet<string>(new string[] {
- "MapConst", "MapAdd", "MapSub", "MapMul", "MapDiv", "MapMod", "MapEq", "MapIff", "MapGt", "MapGe", "MapLt", "MapLe", "MapOr", "MapAnd", "MapNot", "MapImp", "MapIte" });
-
- private static string CheckMapApply(string name, VCExprNAry node) {
- if (name == "MapConst") {
- Type type = node.Type;
- string s = TypeToString(type);
- return "(as const " + s + ")";
- }
- else if (name == "MapAdd") {
- return "(_ map (+ (Int Int) Int))";
- }
- else if (name == "MapSub") {
- return "(_ map (- (Int Int) Int))";
- }
- else if (name == "MapMul") {
- return "(_ map (* (Int Int) Int))";
- }
- else if (name == "MapDiv") {
- return "(_ map (div (Int Int) Int))";
- }
- else if (name == "MapMod") {
- return "(_ map (mod (Int Int) Int))";
- }
- else if (name == "MapEq") {
- Type type = ResultType(node[0].Type);
- string s = TypeToString(type);
- return "(_ map (= (" + s + " " + s + ") Bool))";
- }
- else if (name == "MapIff") {
- return "(_ map (= (Bool Bool) Bool))";
- }
- else if (name == "MapGt") {
- return "(_ map (> (Int Int) Int))";
- }
- else if (name == "MapGe") {
- return "(_ map (>= (Int Int) Int))";
- }
- else if (name == "MapLt") {
- return "(_ map (< (Int Int) Int))";
- }
- else if (name == "MapLe") {
- return "(_ map (<= (Int Int) Int))";
- }
- else if (name == "MapOr") {
- return "(_ map or)";
- }
- else if (name == "MapAnd") {
- return "(_ map and)";
- }
- else if (name == "MapNot") {
- return "(_ map not)";
- }
- else if (name == "MapImp") {
- return "(_ map =>)";
- }
- else if (name == "MapIte") {
- Type type = ResultType(node.Type);
- string s = TypeToString(type);
- return "(_ map (ite (Bool " + s + " " + s + ") " + s + "))";
- }
- else {
- return name;
- }
- }
- }
- }
-
-}
+//----------------------------------------------------------------------------- +// +// Copyright (C) Microsoft Corporation. All Rights Reserved. +// +//----------------------------------------------------------------------------- +using System; +using System.Text; +using System.IO; +using System.Collections; +using System.Collections.Generic; +using System.Diagnostics.Contracts; +using System.Linq; +using Microsoft.Basetypes; +using Microsoft.Boogie.VCExprAST; + +// Method to turn VCExprs into strings that can be fed into SMT +// solvers. This is currently quite similar to the +// SimplifyLikeLineariser (but the code is independent) + +namespace Microsoft.Boogie.SMTLib +{ + + // Options for the linearisation + public class LineariserOptions + { + public static LineariserOptions Default = new LineariserOptions(); + public bool LabelsBelowQuantifiers = false; + } + + + //////////////////////////////////////////////////////////////////////////////////////// + + // Lineariser for expressions. The result (bool) is currently not used for anything + public class SMTLibExprLineariser : IVCExprVisitor<bool, LineariserOptions/*!*/> + { + + public static string ToString(VCExpr e, UniqueNamer namer, SMTLibProverOptions opts) + { + Contract.Requires(e != null); + Contract.Requires(namer != null); + Contract.Ensures(Contract.Result<string>() != null); + + StringWriter sw = new StringWriter(); + SMTLibExprLineariser lin = new SMTLibExprLineariser(sw, namer, opts); + Contract.Assert(lin != null); + lin.Linearise(e, LineariserOptions.Default); + return cce.NonNull(sw.ToString()); + } + + //////////////////////////////////////////////////////////////////////////////////////// + + private readonly TextWriter wr; + [ContractInvariantMethod] + void ObjectInvariant() + { + Contract.Invariant(wr != null); + Contract.Invariant(Namer != null); + } + + private SMTLibOpLineariser OpLinObject = null; + private IVCExprOpVisitor<bool, LineariserOptions>/*!>!*/ OpLineariser + { + get + { + Contract.Ensures(Contract.Result<IVCExprOpVisitor<bool, LineariserOptions>>() != null); + + if (OpLinObject == null) + OpLinObject = new SMTLibOpLineariser(this, wr); + return OpLinObject; + } + } + + internal readonly UniqueNamer Namer; + internal int UnderQuantifier = 0; + internal readonly SMTLibProverOptions ProverOptions; + + public SMTLibExprLineariser(TextWriter wr, UniqueNamer namer, SMTLibProverOptions opts) + { + Contract.Requires(wr != null); Contract.Requires(namer != null); + this.wr = wr; + this.Namer = namer; + this.ProverOptions = opts; + } + + public void Linearise(VCExpr expr, LineariserOptions options) + { + Contract.Requires(expr != null); + Contract.Requires(options != null); + expr.Accept<bool, LineariserOptions>(this, options); + } + + ///////////////////////////////////////////////////////////////////////////////////// + + private static void TypeToStringHelper(Type t, StringBuilder sb) + { + Contract.Requires(t != null); + + TypeSynonymAnnotation syn = t as TypeSynonymAnnotation; + if (syn != null) { + TypeToStringHelper(syn.ExpandedType, sb); + } else { + if (t.IsMap && CommandLineOptions.Clo.UseArrayTheory) { + MapType m = t.AsMap; + // Contract.Assert(m.MapArity == 1); + sb.Append("(Array "); + foreach (Type tp in m.Arguments) + sb.Append(TypeToString(tp)).Append(" "); + sb.Append(TypeToString(m.Result)).Append(")"); + } else if (t.IsMap) { + MapType m = t.AsMap; + sb.Append('['); + for (int i = 0; i < m.MapArity; ++i) { + if (i != 0) + sb.Append(','); + TypeToStringHelper(m.Arguments[i], sb); + } + sb.Append(']'); + TypeToStringHelper(m.Result, sb); + } else if (t.IsBool || t.IsInt || t.IsReal || t.IsBv) { + sb.Append(TypeToString(t)); + } else { + System.IO.StringWriter buffer = new System.IO.StringWriter(); + using (TokenTextWriter stream = new TokenTextWriter("<buffer>", buffer, /*setTokens=*/false, /*pretty=*/false)) { + t.Emit(stream); + } + sb.Append(buffer.ToString()); + } + } + + } + + public static string TypeToString(Type t) + { + Contract.Requires(t != null); + Contract.Ensures(Contract.Result<string>() != null); + + if (t.IsBool) + return "Bool"; + else if (t.IsInt) + return "Int"; + else if (t.IsReal) + return "Real"; + else if (t.IsBv) { + return "(_ BitVec " + t.BvBits + ")"; + } else { + StringBuilder sb = new StringBuilder(); + TypeToStringHelper(t, sb); + var s = sb.ToString(); + if (s[0] == '(') + return s; + else + return SMTLibNamer.QuoteId("T@" + s); + } + } + + public static string ExtractBuiltin(Function f) + { + Contract.Requires(f != null); + string retVal = null; + retVal = f.FindStringAttribute("bvbuiltin"); + + // It used to be "sign_extend 12" in Simplify, and is "(_ sign_extend 12)" with SMT + if (retVal != null && (retVal.StartsWith("sign_extend ") || retVal.StartsWith("zero_extend "))) + return "(_ " + retVal + ")"; + + if (retVal == null) { + retVal = f.FindStringAttribute("builtin"); + } + + if (retVal != null && !CommandLineOptions.Clo.UseArrayTheory && SMTLibOpLineariser.ArrayOps.Contains(retVal)) + { + retVal = null; + } + + return retVal; + } + + ///////////////////////////////////////////////////////////////////////////////////// + + public bool Visit(VCExprLiteral node, LineariserOptions options) + { + if (node == VCExpressionGenerator.True) + wr.Write("true"); + else if (node == VCExpressionGenerator.False) + wr.Write("false"); + else if (node is VCExprIntLit) { + BigNum lit = ((VCExprIntLit)node).Val; + if (lit.IsNegative) + // In SMT2 "-42" is an identifier (SMT2, Sect. 3.2 "Symbols") + wr.Write("(- 0 {0})", lit.Abs); + else + wr.Write(lit); + } + else if (node is VCExprRealLit) { + BigDec lit = ((VCExprRealLit)node).Val; + if (lit.IsNegative) + // In SMT2 "-42" is an identifier (SMT2, Sect. 3.2 "Symbols") + wr.Write("(- 0.0 {0})", lit.Abs.ToDecimalString()); + else + wr.Write(lit.ToDecimalString()); + } + else { + Contract.Assert(false); + throw new cce.UnreachableException(); + } + + return true; + } + + ///////////////////////////////////////////////////////////////////////////////////// + + public bool Visit(VCExprNAry node, LineariserOptions options) + { + VCExprOp op = node.Op; + Contract.Assert(op != null); + + var booleanOps = new HashSet<VCExprOp>(); + booleanOps.Add(VCExpressionGenerator.NotOp); + booleanOps.Add(VCExpressionGenerator.ImpliesOp); + booleanOps.Add(VCExpressionGenerator.AndOp); + booleanOps.Add(VCExpressionGenerator.OrOp); + if (booleanOps.Contains(op)) + { + Stack<VCExpr> exprs = new Stack<VCExpr>(); + exprs.Push(node); + while (exprs.Count > 0) + { + VCExpr expr = exprs.Pop(); + if (expr == null) + { + wr.Write(")"); + continue; + } + wr.Write(" "); + VCExprNAry naryExpr = expr as VCExprNAry; + if (naryExpr == null || !booleanOps.Contains(naryExpr.Op)) + { + Linearise(expr, options); + continue; + } + else if (naryExpr.Op.Equals(VCExpressionGenerator.NotOp)) + { + wr.Write("(not"); + } + else if (naryExpr.Op.Equals(VCExpressionGenerator.ImpliesOp)) + { + wr.Write("(=>"); + } + else if (naryExpr.Op.Equals(VCExpressionGenerator.AndOp)) + { + wr.Write("(and"); + } + else + { + System.Diagnostics.Debug.Assert(naryExpr.Op.Equals(VCExpressionGenerator.OrOp)); + wr.Write("(or"); + } + exprs.Push(null); + for (int i = naryExpr.Arity - 1; i >= 0; i--) + { + exprs.Push(naryExpr[i]); + } + } + return true; + } + return node.Accept<bool, LineariserOptions/*!*/>(OpLineariser, options); + } + + ///////////////////////////////////////////////////////////////////////////////////// + + public bool Visit(VCExprVar node, LineariserOptions options) + { + wr.Write(Namer.GetQuotedName(node, node.Name)); + return true; + } + + ///////////////////////////////////////////////////////////////////////////////////// + + public bool Visit(VCExprQuantifier node, LineariserOptions options) + { + Contract.Assert(node.TypeParameters.Count == 0); + + UnderQuantifier++; + 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.GetQuotedLocalName(var, var.Name); + Contract.Assert(printedName != null); + wr.Write("({0} {1}) ", printedName, TypeToString(var.Type)); + } + + wr.Write(") "); + + VCQuantifierInfos infos = node.Infos; + var weight = QKeyValue.FindIntAttribute(infos.attributes, "weight", 1); + if (!ProverOptions.UseWeights) + weight = 1; + var hasAttrs = node.Triggers.Count > 0 || infos.qid != null || weight != 1 || infos.uniqueId != -1; + + if (hasAttrs) + wr.Write("(! "); + + Linearise(node.Body, options); + + if (hasAttrs) { + wr.Write("\n"); + if (infos.qid != null) + wr.Write(" :qid {0}\n", SMTLibNamer.QuoteId(infos.qid)); + if (weight != 1) + wr.Write(" :weight {0}\n", weight); + if (infos.uniqueId != -1) + wr.Write(" :skolemid |{0}|\n", infos.uniqueId); + WriteTriggers(node.Triggers, options); + + wr.Write(")"); + } + + wr.Write(")"); + + return true; + + } finally { + UnderQuantifier--; + Namer.PopScope(); + } + } + + private void WriteTriggers(List<VCTrigger/*!>!*/> triggers, LineariserOptions options) + { + Contract.Requires(options != null); + Contract.Requires(triggers != null); + // 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) { + foreach (VCTrigger vcTrig in triggers) { + Contract.Assert(vcTrig != null); + if (vcTrig.Pos) { + wr.Write(" :pattern ("); + foreach (VCExpr e in vcTrig.Exprs) { + Contract.Assert(e != null); + wr.Write(" "); + var subPat = e; + var nary = e as VCExprNAry; + if (nary != null && (nary.Op == VCExpressionGenerator.NeqOp || nary.Op == VCExpressionGenerator.EqOp)) { + if (nary[0] is VCExprLiteral) + subPat = nary[1]; + else if (nary[1] is VCExprLiteral) + subPat = nary[0]; + } + Linearise(subPat, options); + } + wr.Write(")\n"); + } + } + } 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 + foreach (VCTrigger vcTrig in triggers) { + Contract.Assert(vcTrig != null); + if (!vcTrig.Pos) { + wr.Write(" :no-pattern "); + Contract.Assert(vcTrig.Exprs.Count == 1); + Linearise(vcTrig.Exprs[0], options); + wr.Write("\n"); + } + } + } + } + + ///////////////////////////////////////////////////////////////////////////////////// + + public bool Visit(VCExprLet node, LineariserOptions options) + { + Namer.PushScope(); + try { + + foreach (VCExprLetBinding b in node) { + wr.Write("(let ("); + Contract.Assert(b != null); + wr.Write("({0} ", Namer.GetQuotedName(b.V, b.V.Name)); + Linearise(b.E, options); + wr.Write("))\n"); + } + Linearise(node.Body, options); + foreach (VCExprLetBinding b in node) + wr.Write(")"); + return true; + } finally { + Namer.PopScope(); + } + } + + ///////////////////////////////////////////////////////////////////////////////////// + + // Lineariser for operator terms. The result (bool) is currently not used for anything + internal class SMTLibOpLineariser : IVCExprOpVisitor<bool, LineariserOptions/*!*/> + { + private readonly SMTLibExprLineariser ExprLineariser; + private readonly TextWriter wr; + [ContractInvariantMethod] + void ObjectInvariant() + { + Contract.Invariant(wr != null); + Contract.Invariant(ExprLineariser != null); + } + + + public SMTLibOpLineariser(SMTLibExprLineariser ExprLineariser, TextWriter wr) + { + Contract.Requires(ExprLineariser != null); + Contract.Requires(wr != null); + this.ExprLineariser = ExprLineariser; + this.wr = wr; + } + + /////////////////////////////////////////////////////////////////////////////////// + private void WriteApplication(string opName, IEnumerable<VCExpr>/*!>!*/ args, LineariserOptions options) + { + Contract.Requires(cce.NonNullElements(args)); + Contract.Requires(options != null); + Contract.Assert(opName != null); + + bool hasArgs = false; + foreach (VCExpr e in args) { + Contract.Assert(e != null); + if (!hasArgs) + wr.Write("({0}", opName); + wr.Write(" "); + ExprLineariser.Linearise(e, options); + hasArgs = true; + } + + if (hasArgs) + wr.Write(")"); + else + wr.Write("{0}", opName); + } + + /////////////////////////////////////////////////////////////////////////////////// + + public bool VisitNotOp(VCExprNAry node, LineariserOptions options) + { + WriteApplication("not", node, options); // arguments can be both terms and formulas + return true; + } + + private bool PrintEq(VCExprNAry node, LineariserOptions options) + { + Contract.Requires(node != null); + Contract.Requires(options != null); + + WriteApplication("=", node, options); + + return true; + } + + public bool VisitEqOp(VCExprNAry node, LineariserOptions options) + { + return PrintEq(node, options); + } + + public bool VisitNeqOp(VCExprNAry node, LineariserOptions options) + { + //Contract.Requires(node != null); + //Contract.Requires(options != null); + wr.Write("(not "); + PrintEq(node, options); + wr.Write(")"); + return true; + } + + public bool VisitAndOp(VCExprNAry node, LineariserOptions options) + { + WriteApplication("and", node, options); + return true; + } + + public bool VisitOrOp(VCExprNAry node, LineariserOptions options) + { + WriteApplication("or", node, options); + return true; + } + + public bool VisitImpliesOp(VCExprNAry node, LineariserOptions options) + { + WriteApplication("=>", node, options); + return true; + } + + public bool VisitIfThenElseOp(VCExprNAry node, LineariserOptions options) + { + WriteApplication("ite", node, options); + return true; + } + + public bool VisitCustomOp(VCExprNAry node, LineariserOptions options) + { + VCExprCustomOp op = (VCExprCustomOp)node.Op; + if (!ExprLineariser.ProverOptions.UseTickleBool && op.Name == "tickleBool") + ExprLineariser.Linearise(VCExpressionGenerator.True, options); + else + WriteApplication(op.Name, node, options); + return true; + } + + public bool VisitDistinctOp(VCExprNAry node, LineariserOptions options) + { + //Contract.Requires(node != null); + //Contract.Requires(options != null); + + if (node.Length < 2) { + ExprLineariser.Linearise(VCExpressionGenerator.True, options); + } else { + var groupings = node.GroupBy(e => e.Type).Where(g => g.Count() > 1).ToArray(); + if (groupings.Length == 0) { + ExprLineariser.Linearise(VCExpressionGenerator.True, options); + } else { + if (groupings.Length > 1) + wr.Write("(and "); + + foreach (var g in groupings) { + wr.Write("(distinct"); + foreach (VCExpr e in g) { + Contract.Assert(e != null); + wr.Write(" "); + ExprLineariser.Linearise(e, options); + } + wr.Write(")"); + } + + if (groupings.Length > 1) + wr.Write(")"); + + wr.Write("\n"); + } + } + + return true; + } + + public bool VisitLabelOp(VCExprNAry node, LineariserOptions options) + { + if (ExprLineariser.UnderQuantifier > 0 && !options.LabelsBelowQuantifiers) { + ExprLineariser.Linearise(node[0], options); + return true; + } + + var op = (VCExprLabelOp)node.Op; + + if (CommandLineOptions.Clo.UseLabels) + { + // Z3 extension + //wr.Write("({0} {1} ", op.pos ? "lblpos" : "lblneg", SMTLibNamer.QuoteId(op.label)); + wr.Write("(! "); + } + + if(!options.LabelsBelowQuantifiers) + wr.Write("({0} {1} ", op.pos ? "and" : "or", SMTLibNamer.QuoteId(SMTLibNamer.LabelVar(op.label))); + + ExprLineariser.Linearise(node[0], options); + + + if (!options.LabelsBelowQuantifiers) + wr.Write(")"); + + if (CommandLineOptions.Clo.UseLabels) + wr.Write(" :{0} {1})", op.pos ? "lblpos" : "lblneg", SMTLibNamer.QuoteId(op.label)); + + return true; + } + + public bool VisitSelectOp(VCExprNAry node, LineariserOptions options) + { + var name = SimplifyLikeExprLineariser.SelectOpName(node); + name = ExprLineariser.Namer.GetQuotedName(name, name); + if (CommandLineOptions.Clo.UseArrayTheory) + name = "select"; + WriteApplication(name, node, options); + return true; + } + + public bool VisitStoreOp(VCExprNAry node, LineariserOptions options) + { + var name = SimplifyLikeExprLineariser.StoreOpName(node); + name = ExprLineariser.Namer.GetQuotedName(name, name); + if (CommandLineOptions.Clo.UseArrayTheory) + name = "store"; + WriteApplication(name, node, options); + return true; + } + + static char[] hex = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; + public bool VisitBvOp(VCExprNAry node, LineariserOptions options) + { + var lit = (VCExprIntLit)node[0]; + var bytes = lit.Val.ToByteArray(); + if (node.Type.BvBits % 8 == 0) { + wr.Write("#x"); + for (var pos = node.Type.BvBits / 8 - 1; pos >= 0; pos--) { + var k = pos < bytes.Length ? bytes[pos] : (byte)0; + wr.Write(hex[k >> 4]); + wr.Write(hex[k & 0xf]); + } + } else { + wr.Write("#b"); + for (var pos = node.Type.BvBits - 1; pos >= 0; pos--) { + var i = pos >> 3; + var k = i < bytes.Length ? bytes[i] : (byte)0; + wr.Write((k & (1 << (pos & 7))) == 0 ? '0' : '1'); + } + } + return true; + } + + public bool VisitBvExtractOp(VCExprNAry node, LineariserOptions options) + { + var op = (VCExprBvExtractOp)node.Op; + wr.Write("((_ extract {0} {1}) ", op.End - 1, op.Start); + ExprLineariser.Linearise(node[0], options); + wr.Write(")"); + return true; + } + + public bool VisitBvConcatOp(VCExprNAry node, LineariserOptions options) + { + WriteApplication("concat", node, options); + return true; + } + + public bool VisitAddOp(VCExprNAry node, LineariserOptions options) + { + WriteApplication("+", node, options); + return true; + } + + public bool VisitSubOp(VCExprNAry node, LineariserOptions options) + { + WriteApplication("-", node, options); + return true; + } + + public bool VisitMulOp(VCExprNAry node, LineariserOptions options) + { + WriteApplication("*", node, options); + return true; + } + + public bool VisitDivOp(VCExprNAry node, LineariserOptions options) + { + WriteApplication("div", node, options); + return true; + } + + public bool VisitModOp(VCExprNAry node, LineariserOptions options) + { + WriteApplication("mod", node, options); + return true; + } + + public bool VisitRealDivOp(VCExprNAry node, LineariserOptions options) { + WriteApplication("/", node, options); + return true; + } + + public bool VisitPowOp(VCExprNAry node, LineariserOptions options) { + WriteApplication("real_pow", node, options); + return true; + } + + public bool VisitLtOp(VCExprNAry node, LineariserOptions options) + { + WriteApplication("<", node, options); + return true; + } + + public bool VisitLeOp(VCExprNAry node, LineariserOptions options) + { + WriteApplication("<=", node, options); + return true; + } + + public bool VisitGtOp(VCExprNAry node, LineariserOptions options) + { + WriteApplication(">", node, options); + return true; + } + + public bool VisitGeOp(VCExprNAry node, LineariserOptions options) + { + WriteApplication(">=", node, options); + return true; + } + + public bool VisitSubtypeOp(VCExprNAry node, LineariserOptions options) + { + WriteApplication("UOrdering2", node, options); + return true; + } + + public bool VisitSubtype3Op(VCExprNAry node, LineariserOptions options) + { + WriteApplication("UOrdering3", node, options); + return true; + } + + public bool VisitToIntOp(VCExprNAry node, LineariserOptions options) { + WriteApplication("to_int", node, options); + return true; + } + + public bool VisitToRealOp(VCExprNAry node, LineariserOptions options) { + WriteApplication("to_real", node, options); + return true; + } + + private string ExtractDatatype(Function func) { + if (func is DatatypeSelector) { + DatatypeSelector selector = (DatatypeSelector) func; + Variable v = selector.constructor.InParams[selector.index]; + return ExprLineariser.Namer.GetQuotedName(v, v.Name + "#" + selector.constructor.Name); + } + else if (func is DatatypeMembership) { + DatatypeMembership membership = (DatatypeMembership)func; + return ExprLineariser.Namer.GetQuotedName(membership, "is-" + membership.constructor.Name); + } + else { + return null; + } + } + + public bool VisitBoogieFunctionOp(VCExprNAry node, LineariserOptions options) { + VCExprBoogieFunctionOp op = (VCExprBoogieFunctionOp)node.Op; + Contract.Assert(op != null); + string printedName; + + var builtin = ExtractBuiltin(op.Func); + var datatype = ExtractDatatype(op.Func); + if (builtin != null) + { + printedName = CheckMapApply(builtin, node); + } + else if (datatype != null) + { + printedName = datatype; + } + else + { + printedName = ExprLineariser.Namer.GetQuotedName(op.Func, op.Func.Name); + } + Contract.Assert(printedName != null); + + WriteApplication(printedName, node, options); + + return true; + } + + private static Type ResultType(Type type) { + MapType mapType = type as MapType; + if (mapType != null) { + return ResultType(mapType.Result); + } + else { + return type; + } + } + + public static HashSet<string> ArrayOps = new HashSet<string>(new string[] { + "MapConst", "MapAdd", "MapSub", "MapMul", "MapDiv", "MapMod", "MapEq", "MapIff", "MapGt", "MapGe", "MapLt", "MapLe", "MapOr", "MapAnd", "MapNot", "MapImp", "MapIte" }); + + private static string CheckMapApply(string name, VCExprNAry node) { + if (name == "MapConst") { + Type type = node.Type; + string s = TypeToString(type); + return "(as const " + s + ")"; + } + else if (name == "MapAdd") { + return "(_ map (+ (Int Int) Int))"; + } + else if (name == "MapSub") { + return "(_ map (- (Int Int) Int))"; + } + else if (name == "MapMul") { + return "(_ map (* (Int Int) Int))"; + } + else if (name == "MapDiv") { + return "(_ map (div (Int Int) Int))"; + } + else if (name == "MapMod") { + return "(_ map (mod (Int Int) Int))"; + } + else if (name == "MapEq") { + Type type = ResultType(node[0].Type); + string s = TypeToString(type); + return "(_ map (= (" + s + " " + s + ") Bool))"; + } + else if (name == "MapIff") { + return "(_ map (= (Bool Bool) Bool))"; + } + else if (name == "MapGt") { + return "(_ map (> (Int Int) Int))"; + } + else if (name == "MapGe") { + return "(_ map (>= (Int Int) Int))"; + } + else if (name == "MapLt") { + return "(_ map (< (Int Int) Int))"; + } + else if (name == "MapLe") { + return "(_ map (<= (Int Int) Int))"; + } + else if (name == "MapOr") { + return "(_ map or)"; + } + else if (name == "MapAnd") { + return "(_ map and)"; + } + else if (name == "MapNot") { + return "(_ map not)"; + } + else if (name == "MapImp") { + return "(_ map =>)"; + } + else if (name == "MapIte") { + Type type = ResultType(node.Type); + string s = TypeToString(type); + return "(_ map (ite (Bool " + s + " " + s + ") " + s + "))"; + } + else { + return name; + } + } + } + } + +} diff --git a/Source/Provers/SMTLib/SMTLibNamer.cs b/Source/Provers/SMTLib/SMTLibNamer.cs index 40007ab9..900bdbcc 100644 --- a/Source/Provers/SMTLib/SMTLibNamer.cs +++ b/Source/Provers/SMTLib/SMTLibNamer.cs @@ -1,147 +1,147 @@ -using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Microsoft.Boogie.VCExprAST;
-
-namespace Microsoft.Boogie.SMTLib
-{
- public class SMTLibNamer : UniqueNamer
- {
- // The following Boogie ID characters are not SMT ID characters: `'\#
- const string idCharacters = "~!@$%^&*_-+=<>.?/";
-
-
- static string[] reservedSmtWordsList =
- { // Basic symbols:
- "", "!", "_", "as", "DECIMAL", "exists", "forall", "let", "NUMERAL", "par", "STRING",
- // Commands:
- "assert", "check-sat", "declare-sort", "declare-fun", "define-sort,", "define-fun", "exit",
- "get-assertions", "get-assignment", "get-info", "get-option,", "get-proof", "get-unsat-core",
- "get-value", "pop", "push", "set-logic", "set-info", "set-option",
- // Core theory:
- "and", "or", "not", "iff", "true", "false", "xor", "distinct", "ite", "=", "Bool",
- "=>", // implies (sic!)
- // Integers and reals
- "Int", "Real", "*", "/", "-", "~", "+", "<", "<=", ">", ">=", "div", "mod", "rem",
- "^", "sin", "cos", "tan", "asin", "acos", "atan", "sinh", "cosh", "tanh", "asinh", "acosh", "atanh", "pi", "euler",
- "to_real", "to_int", "is_int",
- // Bitvectors
- "extract", "concat",
- "bvnot", "bvneg", "bvand", "bvor", "bvadd", "bvmul", "bvudiv", "bvurem", "bvshl", "bvlshr", "bvult",
- // arrays
- "store", "select", "const", "default", "map", "union", "intersect", "difference", "complement",
- "subset", "array-ext", "as-array", "Array",
- // Z3 (and not only?) extensions to bitvectors
- "bit1", "bit0", "bvsub", "bvsdiv", "bvsrem", "bvsmod", "bvsdiv0", "bvudiv0", "bvsrem0", "bvurem0",
- "bvsmod0", "bvsdiv_i", "bvudiv_i", "bvsrem_i", "bvurem_i", "bvumod_i", "bvule", "bvsle", "bvuge",
- "bvsge", "bvslt", "bvugt", "bvsgt", "bvxor", "bvnand", "bvnor", "bvxnor", "sign_extend", "zero_extend",
- "repeat", "bvredor", "bvredand", "bvcomp", "bvumul_noovfl", "bvsmul_noovfl", "bvsmul_noudfl", "bvashr",
- "rotate_left", "rotate_right", "ext_rotate_left", "ext_rotate_right", "int2bv", "bv2int", "mkbv",
- // floating point (FIXME: Legacy, remove this)
- "plusInfinity", "minusInfinity",
- "+", "-", "/", "*", "==", "<", ">", "<=", ">=",
- "abs", "remainder", "fusedMA", "squareRoot", "roundToIntegral",
- "isZero", "isNZero", "isPZero", "isSignMinus", "min", "max", "asFloat",
- // SMT v1 stuff (FIXME: Legacy, remove this)
- "flet", "implies", "!=", "if_then_else",
- // Z3 extensions
- "lblneg", "lblpos", "lbl-lit",
- "if", "&&", "||", "equals", "equiv", "bool",
- // Boogie-defined
- "real_pow", "UOrdering2", "UOrdering3",
- // Floating point (final draft SMTLIB-v2.5)
- "NaN",
- "roundNearestTiesToEven", "roundNearestTiesToAway", "roundTowardPositive", "roundTowardNegative", "roundTowardZero",
- "RNE", "RNA", "RTP", "RTN", "RTZ",
- "fp.abs", "fp.neg", "fp.add", "fp.sub", "fp.mul", "fp.div", "fp.fma", "fp.sqrt", "fp.rem", "fp.roundToIntegral",
- "fp.min", "fp.max", "fp.leq", "fp.lt", "fp.geq", "fp.gt", "fp.eq",
- "fp.isNormal", "fp.isSubnormal", "fp.isZero", "fp.isInfinite", "fp.isNaN", "fp.isNegative", "fp.isPositive",
- "fp", "fp.to_ubv", "fp.to_sbv", "to_fp",
- };
-
- static HashSet<string> reservedSmtWords;
- static bool[] validIdChar;
- static bool symbolListsInitilized;
-
- static void InitSymbolLists()
- {
- lock (reservedSmtWordsList) {
- // don't move out, c.f. http://en.wikipedia.org/wiki/Double-checked_locking
- if (symbolListsInitilized)
- return;
- reservedSmtWords = new HashSet<string>();
- foreach (var w in reservedSmtWordsList)
- reservedSmtWords.Add(w);
- validIdChar = new bool[255];
- for (int i = 0; i < validIdChar.Length; ++i)
- validIdChar[i] = char.IsLetterOrDigit((char)i) || idCharacters.IndexOf((char)i) >= 0;
- symbolListsInitilized = true;
- }
- }
-
- static string AddQuotes(string s)
- {
- var allGood = true;
-
- foreach (char ch in s) {
- var c = (int)ch;
- if (c >= validIdChar.Length || !validIdChar[c]) {
- allGood = false;
- break;
- }
- }
-
- if (allGood)
- return s;
-
- return "|" + s + "|";
- }
-
- static string FilterReserved(string s)
- {
- // Note symbols starting with ``.`` and ``@`` are reserved for internal
- // solver use in SMT-LIBv2 however if we check for the first character
- // being ``@`` then Boogie's tests fail spectacularly because they are
- // used for labels so we don't check for it here. It hopefully won't matter
- // in practice because ``@`` cannot be legally used in Boogie identifiers.
- if (reservedSmtWords.Contains(s) || char.IsDigit(s[0]) || s[0] == '.')
- s = "q@" + s;
-
- // | and \ are illegal even in quoted identifiers
- if (s.IndexOf('|') >= 0)
- s = s.Replace("|", "_");
-
- if (s.IndexOf('\\') >= 0)
- s = s.Replace("\\", "_");
-
- return s;
- }
-
- public static string LabelVar(string s)
- {
- return "%lbl%" + s;
- }
-
- public static string QuoteId(string s)
- {
- return AddQuotes(FilterReserved(s));
- }
-
- public override string GetQuotedLocalName(object thingie, string inherentName)
- {
- return AddQuotes(base.GetLocalName(thingie, FilterReserved(inherentName)));
- }
-
- public override string GetQuotedName(object thingie, string inherentName)
- {
- return AddQuotes(base.GetName(thingie, FilterReserved(inherentName)));
- }
-
- public SMTLibNamer()
- {
- this.Spacer = "@@";
- InitSymbolLists();
- }
- }
-}
+using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Microsoft.Boogie.VCExprAST; + +namespace Microsoft.Boogie.SMTLib +{ + public class SMTLibNamer : UniqueNamer + { + // The following Boogie ID characters are not SMT ID characters: `'\# + const string idCharacters = "~!@$%^&*_-+=<>.?/"; + + + static string[] reservedSmtWordsList = + { // Basic symbols: + "", "!", "_", "as", "DECIMAL", "exists", "forall", "let", "NUMERAL", "par", "STRING", + // Commands: + "assert", "check-sat", "declare-sort", "declare-fun", "define-sort,", "define-fun", "exit", + "get-assertions", "get-assignment", "get-info", "get-option,", "get-proof", "get-unsat-core", + "get-value", "pop", "push", "set-logic", "set-info", "set-option", + // Core theory: + "and", "or", "not", "iff", "true", "false", "xor", "distinct", "ite", "=", "Bool", + "=>", // implies (sic!) + // Integers and reals + "Int", "Real", "*", "/", "-", "~", "+", "<", "<=", ">", ">=", "div", "mod", "rem", + "^", "sin", "cos", "tan", "asin", "acos", "atan", "sinh", "cosh", "tanh", "asinh", "acosh", "atanh", "pi", "euler", + "to_real", "to_int", "is_int", + // Bitvectors + "extract", "concat", + "bvnot", "bvneg", "bvand", "bvor", "bvadd", "bvmul", "bvudiv", "bvurem", "bvshl", "bvlshr", "bvult", + // arrays + "store", "select", "const", "default", "map", "union", "intersect", "difference", "complement", + "subset", "array-ext", "as-array", "Array", + // Z3 (and not only?) extensions to bitvectors + "bit1", "bit0", "bvsub", "bvsdiv", "bvsrem", "bvsmod", "bvsdiv0", "bvudiv0", "bvsrem0", "bvurem0", + "bvsmod0", "bvsdiv_i", "bvudiv_i", "bvsrem_i", "bvurem_i", "bvumod_i", "bvule", "bvsle", "bvuge", + "bvsge", "bvslt", "bvugt", "bvsgt", "bvxor", "bvnand", "bvnor", "bvxnor", "sign_extend", "zero_extend", + "repeat", "bvredor", "bvredand", "bvcomp", "bvumul_noovfl", "bvsmul_noovfl", "bvsmul_noudfl", "bvashr", + "rotate_left", "rotate_right", "ext_rotate_left", "ext_rotate_right", "int2bv", "bv2int", "mkbv", + // floating point (FIXME: Legacy, remove this) + "plusInfinity", "minusInfinity", + "+", "-", "/", "*", "==", "<", ">", "<=", ">=", + "abs", "remainder", "fusedMA", "squareRoot", "roundToIntegral", + "isZero", "isNZero", "isPZero", "isSignMinus", "min", "max", "asFloat", + // SMT v1 stuff (FIXME: Legacy, remove this) + "flet", "implies", "!=", "if_then_else", + // Z3 extensions + "lblneg", "lblpos", "lbl-lit", + "if", "&&", "||", "equals", "equiv", "bool", + // Boogie-defined + "real_pow", "UOrdering2", "UOrdering3", + // Floating point (final draft SMTLIB-v2.5) + "NaN", + "roundNearestTiesToEven", "roundNearestTiesToAway", "roundTowardPositive", "roundTowardNegative", "roundTowardZero", + "RNE", "RNA", "RTP", "RTN", "RTZ", + "fp.abs", "fp.neg", "fp.add", "fp.sub", "fp.mul", "fp.div", "fp.fma", "fp.sqrt", "fp.rem", "fp.roundToIntegral", + "fp.min", "fp.max", "fp.leq", "fp.lt", "fp.geq", "fp.gt", "fp.eq", + "fp.isNormal", "fp.isSubnormal", "fp.isZero", "fp.isInfinite", "fp.isNaN", "fp.isNegative", "fp.isPositive", + "fp", "fp.to_ubv", "fp.to_sbv", "to_fp", + }; + + static HashSet<string> reservedSmtWords; + static bool[] validIdChar; + static bool symbolListsInitilized; + + static void InitSymbolLists() + { + lock (reservedSmtWordsList) { + // don't move out, c.f. http://en.wikipedia.org/wiki/Double-checked_locking + if (symbolListsInitilized) + return; + reservedSmtWords = new HashSet<string>(); + foreach (var w in reservedSmtWordsList) + reservedSmtWords.Add(w); + validIdChar = new bool[255]; + for (int i = 0; i < validIdChar.Length; ++i) + validIdChar[i] = char.IsLetterOrDigit((char)i) || idCharacters.IndexOf((char)i) >= 0; + symbolListsInitilized = true; + } + } + + static string AddQuotes(string s) + { + var allGood = true; + + foreach (char ch in s) { + var c = (int)ch; + if (c >= validIdChar.Length || !validIdChar[c]) { + allGood = false; + break; + } + } + + if (allGood) + return s; + + return "|" + s + "|"; + } + + static string FilterReserved(string s) + { + // Note symbols starting with ``.`` and ``@`` are reserved for internal + // solver use in SMT-LIBv2 however if we check for the first character + // being ``@`` then Boogie's tests fail spectacularly because they are + // used for labels so we don't check for it here. It hopefully won't matter + // in practice because ``@`` cannot be legally used in Boogie identifiers. + if (reservedSmtWords.Contains(s) || char.IsDigit(s[0]) || s[0] == '.') + s = "q@" + s; + + // | and \ are illegal even in quoted identifiers + if (s.IndexOf('|') >= 0) + s = s.Replace("|", "_"); + + if (s.IndexOf('\\') >= 0) + s = s.Replace("\\", "_"); + + return s; + } + + public static string LabelVar(string s) + { + return "%lbl%" + s; + } + + public static string QuoteId(string s) + { + return AddQuotes(FilterReserved(s)); + } + + public override string GetQuotedLocalName(object thingie, string inherentName) + { + return AddQuotes(base.GetLocalName(thingie, FilterReserved(inherentName))); + } + + public override string GetQuotedName(object thingie, string inherentName) + { + return AddQuotes(base.GetName(thingie, FilterReserved(inherentName))); + } + + public SMTLibNamer() + { + this.Spacer = "@@"; + InitSymbolLists(); + } + } +} diff --git a/Source/Provers/SMTLib/SMTLibProverOptions.cs b/Source/Provers/SMTLib/SMTLibProverOptions.cs index 0cfa65d8..5c3bed3e 100644 --- a/Source/Provers/SMTLib/SMTLibProverOptions.cs +++ b/Source/Provers/SMTLib/SMTLibProverOptions.cs @@ -1,158 +1,158 @@ -using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Diagnostics.Contracts;
-
-namespace Microsoft.Boogie.SMTLib
-{
-
- public class OptionValue
- {
- public readonly string Option;
- public readonly string Value;
- [ContractInvariantMethod]
- void ObjectInvariant()
- {
- Contract.Invariant(Option != null);
- Contract.Invariant(Value != null);
- }
-
- public OptionValue(string option, string value)
- {
- Contract.Requires(option != null);
- Contract.Requires(value != null);
- Option = option;
- Value = value;
- }
- }
-
- public enum SolverKind { Z3, CVC4 };
-
- public class SMTLibProverOptions : ProverOptions
- {
- public bool UseWeights = true;
- public bool SupportsLabels { get { return Solver == SolverKind.Z3; } }
- public bool UseTickleBool { get { return Solver == SolverKind.Z3; } }
- public SolverKind Solver = SolverKind.Z3;
- public List<OptionValue> SmtOptions = new List<OptionValue>();
- public List<string> SolverArguments = new List<string>();
- public bool MultiTraces = false;
- public string Logic = "";
-
- // Z3 specific (at the moment; some of them make sense also for other provers)
- public string Inspector = null;
- public bool OptimizeForBv = false;
- public bool SMTLib2Model = false;
-
- public bool ProduceModel() {
- return !CommandLineOptions.Clo.UseLabels || CommandLineOptions.Clo.ExplainHoudini || CommandLineOptions.Clo.UseProverEvaluate ||
- ExpectingModel();
- }
-
- public bool ExpectingModel()
- {
- return CommandLineOptions.Clo.PrintErrorModel >= 1 ||
- CommandLineOptions.Clo.EnhancedErrorMessages == 1 ||
- CommandLineOptions.Clo.ModelViewFile != null ||
- (CommandLineOptions.Clo.StratifiedInlining > 0 && !CommandLineOptions.Clo.StratifiedInliningWithoutModels);
- }
-
- public void AddSolverArgument(string s)
- {
- SolverArguments.Add(s);
- }
-
- public void AddSmtOption(string name, string val)
- {
- SmtOptions.Add(new OptionValue(name, val));
- }
-
- public void AddWeakSmtOption(string name, string val)
- {
- if (!SmtOptions.Any(o => o.Option == name))
- SmtOptions.Add(new OptionValue(name, val));
- }
-
- public void AddSmtOption(string opt)
- {
- var idx = opt.IndexOf('=');
- if (idx <= 0 || idx == opt.Length - 1)
- ReportError("Options to be passed to the prover should have the format: O:<name>=<value>, got '" + opt + "'");
- AddSmtOption(opt.Substring(0, idx), opt.Substring(idx + 1));
- }
-
- protected override bool Parse(string opt)
- {
- string SolverStr = null;
- if (ParseString(opt, "SOLVER", ref SolverStr)) {
- switch (SolverStr) {
- case "Z3":
- case "z3":
- Solver = SolverKind.Z3;
- break;
- case "CVC4":
- case "cvc4":
- Solver = SolverKind.CVC4;
- if (Logic.Equals("")) Logic = "ALL_SUPPORTED";
- break;
- default:
- ReportError("Invalid SOLVER value; must be 'Z3' or 'CVC4'");
- return false;
- }
- return true;
- }
-
- if (opt.StartsWith("O:")) {
- AddSmtOption(opt.Substring(2));
- return true;
- }
-
- if (opt.StartsWith("C:")) {
- AddSolverArgument(opt.Substring(2));
- return true;
- }
-
- return
- ParseBool(opt, "MULTI_TRACES", ref MultiTraces) ||
- ParseBool(opt, "USE_WEIGHTS", ref UseWeights) ||
- ParseString(opt, "INSPECTOR", ref Inspector) ||
- ParseBool(opt, "OPTIMIZE_FOR_BV", ref OptimizeForBv) ||
- ParseBool(opt, "SMTLIB2_MODEL", ref SMTLib2Model) ||
- ParseString(opt, "LOGIC", ref Logic) ||
- base.Parse(opt);
- }
-
- public override void PostParse()
- {
- base.PostParse();
- if (Solver == SolverKind.Z3)
- Z3.SetupOptions(this);
- }
-
- public override string Help
- {
- get
- {
- return
-@"
-SMT-specific options:
-~~~~~~~~~~~~~~~~~~~~~
-SOLVER=<string> Use the given SMT solver (z3 or cvc4; default: z3)
-USE_WEIGHTS=<bool> Pass :weight annotations on quantified formulas (default: true)
-VERBOSITY=<int> 1 - print prover output (default: 0)
-O:<name>=<value> Pass (set-option :<name> <value>) to the SMT solver.
-C:<string> Pass <string> to the SMT on the command line.
-LOGIC=<string> Pass (set-logic <string>) to the prover (default: empty, 'ALL_SUPPORTED' for CVC4)
-
-Z3-specific options:
-~~~~~~~~~~~~~~~~~~~~
-MULTI_TRACES=<bool> Report errors with multiple paths leading to the same assertion.
-INSPECTOR=<string> Use the specified Z3Inspector binary.
-OPTIMIZE_FOR_BV=<bool> Optimize Z3 options for bitvector reasoning, and not quantifier instantiation. Defaults to false.
-SMTLIB2_MODEL=<bool> Use the SMTLIB2 output model. Defaults to false.
-" + base.Help;
- }
- }
- }
-}
+using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Diagnostics.Contracts; + +namespace Microsoft.Boogie.SMTLib +{ + + public class OptionValue + { + public readonly string Option; + public readonly string Value; + [ContractInvariantMethod] + void ObjectInvariant() + { + Contract.Invariant(Option != null); + Contract.Invariant(Value != null); + } + + public OptionValue(string option, string value) + { + Contract.Requires(option != null); + Contract.Requires(value != null); + Option = option; + Value = value; + } + } + + public enum SolverKind { Z3, CVC4 }; + + public class SMTLibProverOptions : ProverOptions + { + public bool UseWeights = true; + public bool SupportsLabels { get { return Solver == SolverKind.Z3; } } + public bool UseTickleBool { get { return Solver == SolverKind.Z3; } } + public SolverKind Solver = SolverKind.Z3; + public List<OptionValue> SmtOptions = new List<OptionValue>(); + public List<string> SolverArguments = new List<string>(); + public bool MultiTraces = false; + public string Logic = ""; + + // Z3 specific (at the moment; some of them make sense also for other provers) + public string Inspector = null; + public bool OptimizeForBv = false; + public bool SMTLib2Model = false; + + public bool ProduceModel() { + return !CommandLineOptions.Clo.UseLabels || CommandLineOptions.Clo.ExplainHoudini || CommandLineOptions.Clo.UseProverEvaluate || + ExpectingModel(); + } + + public bool ExpectingModel() + { + return CommandLineOptions.Clo.PrintErrorModel >= 1 || + CommandLineOptions.Clo.EnhancedErrorMessages == 1 || + CommandLineOptions.Clo.ModelViewFile != null || + (CommandLineOptions.Clo.StratifiedInlining > 0 && !CommandLineOptions.Clo.StratifiedInliningWithoutModels); + } + + public void AddSolverArgument(string s) + { + SolverArguments.Add(s); + } + + public void AddSmtOption(string name, string val) + { + SmtOptions.Add(new OptionValue(name, val)); + } + + public void AddWeakSmtOption(string name, string val) + { + if (!SmtOptions.Any(o => o.Option == name)) + SmtOptions.Add(new OptionValue(name, val)); + } + + public void AddSmtOption(string opt) + { + var idx = opt.IndexOf('='); + if (idx <= 0 || idx == opt.Length - 1) + ReportError("Options to be passed to the prover should have the format: O:<name>=<value>, got '" + opt + "'"); + AddSmtOption(opt.Substring(0, idx), opt.Substring(idx + 1)); + } + + protected override bool Parse(string opt) + { + string SolverStr = null; + if (ParseString(opt, "SOLVER", ref SolverStr)) { + switch (SolverStr) { + case "Z3": + case "z3": + Solver = SolverKind.Z3; + break; + case "CVC4": + case "cvc4": + Solver = SolverKind.CVC4; + if (Logic.Equals("")) Logic = "ALL_SUPPORTED"; + break; + default: + ReportError("Invalid SOLVER value; must be 'Z3' or 'CVC4'"); + return false; + } + return true; + } + + if (opt.StartsWith("O:")) { + AddSmtOption(opt.Substring(2)); + return true; + } + + if (opt.StartsWith("C:")) { + AddSolverArgument(opt.Substring(2)); + return true; + } + + return + ParseBool(opt, "MULTI_TRACES", ref MultiTraces) || + ParseBool(opt, "USE_WEIGHTS", ref UseWeights) || + ParseString(opt, "INSPECTOR", ref Inspector) || + ParseBool(opt, "OPTIMIZE_FOR_BV", ref OptimizeForBv) || + ParseBool(opt, "SMTLIB2_MODEL", ref SMTLib2Model) || + ParseString(opt, "LOGIC", ref Logic) || + base.Parse(opt); + } + + public override void PostParse() + { + base.PostParse(); + if (Solver == SolverKind.Z3) + Z3.SetupOptions(this); + } + + public override string Help + { + get + { + return +@" +SMT-specific options: +~~~~~~~~~~~~~~~~~~~~~ +SOLVER=<string> Use the given SMT solver (z3 or cvc4; default: z3) +USE_WEIGHTS=<bool> Pass :weight annotations on quantified formulas (default: true) +VERBOSITY=<int> 1 - print prover output (default: 0) +O:<name>=<value> Pass (set-option :<name> <value>) to the SMT solver. +C:<string> Pass <string> to the SMT on the command line. +LOGIC=<string> Pass (set-logic <string>) to the prover (default: empty, 'ALL_SUPPORTED' for CVC4) + +Z3-specific options: +~~~~~~~~~~~~~~~~~~~~ +MULTI_TRACES=<bool> Report errors with multiple paths leading to the same assertion. +INSPECTOR=<string> Use the specified Z3Inspector binary. +OPTIMIZE_FOR_BV=<bool> Optimize Z3 options for bitvector reasoning, and not quantifier instantiation. Defaults to false. +SMTLIB2_MODEL=<bool> Use the SMTLIB2 output model. Defaults to false. +" + base.Help; + } + } + } +} diff --git a/Source/Provers/SMTLib/TypeDeclCollector.cs b/Source/Provers/SMTLib/TypeDeclCollector.cs index 9205d54c..32e28560 100644 --- a/Source/Provers/SMTLib/TypeDeclCollector.cs +++ b/Source/Provers/SMTLib/TypeDeclCollector.cs @@ -1,396 +1,396 @@ -//-----------------------------------------------------------------------------
-//
-// Copyright (C) Microsoft Corporation. All Rights Reserved.
-//
-//-----------------------------------------------------------------------------
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Linq;
-using System.Diagnostics;
-using System.Diagnostics.Contracts;
-using Microsoft.Boogie.VCExprAST;
-
-namespace Microsoft.Boogie.SMTLib
-{
- // Visitor for collecting the occurring function symbols in a VCExpr,
- // and for creating the corresponding declarations
-
- public class TypeDeclCollector : BoundVarTraversingVCExprVisitor<bool, bool> {
-
- private readonly UniqueNamer Namer;
- private readonly SMTLibProverOptions Options;
- private HashSet<Function/*!*/>/*!*/ RegisteredRelations = new HashSet<Function>();
-
- [ContractInvariantMethod]
-void ObjectInvariant()
-{
- Contract.Invariant(Namer!=null);
- Contract.Invariant(AllDecls != null);
- Contract.Invariant(IncDecls != null);
- Contract.Invariant(KnownFunctions != null);
- Contract.Invariant(KnownVariables != null);
-}
-
-
- public TypeDeclCollector(SMTLibProverOptions opts, UniqueNamer namer) {
- Contract.Requires(namer != null);
- this.Namer = namer;
- this.Options = opts;
- InitializeKnownDecls();
- }
-
- // not used
- protected override bool StandardResult(VCExpr node, bool arg) {
- //Contract.Requires(node != null);
- return true;
- }
-
- private readonly List<string/*!>!*/> AllDecls = new List<string/*!*/> ();
- private readonly List<string/*!>!*/> IncDecls = new List<string/*!*/> ();
-
- // In order to support push/pop interface of the theorem prover, the "known" declarations
- // must be kept in a stack
-
- private HashSet<Function/*!*/>/*!*/ KnownFunctions
- {
- get { return _KnownFunctions.Peek(); }
- }
-
- private HashSet<VCExprVar/*!*/>/*!*/ KnownVariables
- {
- get { return _KnownVariables.Peek(); }
- }
-
- private HashSet<Type/*!*/>/*!*/ KnownTypes
- {
- get { return _KnownTypes.Peek(); }
- }
-
- private HashSet<string/*!*/>/*!*/ KnownStoreFunctions
- {
- get { return _KnownStoreFunctions.Peek(); }
- }
-
- private HashSet<string/*!*/>/*!*/ KnownSelectFunctions
- {
- get { return _KnownSelectFunctions.Peek(); }
- }
-
- private HashSet<string> KnownLBL
- {
- get { return _KnownLBL.Peek(); }
- }
-
- // ------
- private readonly Stack<HashSet<Function/*!*/>/*!*/> _KnownFunctions = new Stack<HashSet<Function/*!*/>>();
- private readonly Stack<HashSet<VCExprVar/*!*/>/*!*/> _KnownVariables = new Stack<HashSet<VCExprVar/*!*/>>();
-
- private readonly Stack<HashSet<Type/*!*/>/*!*/> _KnownTypes = new Stack<HashSet<Type>>();
- private readonly Stack<HashSet<string/*!*/>/*!*/> _KnownStoreFunctions = new Stack<HashSet<string>>();
- private readonly Stack<HashSet<string/*!*/>/*!*/> _KnownSelectFunctions = new Stack<HashSet<string>>();
- private readonly Stack<HashSet<string>> _KnownLBL = new Stack<HashSet<string>>();
-
- // lets RPFP checker capture decls
- public abstract class DeclHandler {
- public abstract void VarDecl(VCExprVar v);
- public abstract void FuncDecl(Function f);
- }
-
- private DeclHandler declHandler = null;
-
- public void SetDeclHandler(DeclHandler _d){
- declHandler = _d;
- }
-
- private void InitializeKnownDecls()
- {
- _KnownFunctions.Push(new HashSet<Function>());
- _KnownVariables.Push(new HashSet<VCExprVar>());
- _KnownTypes.Push(new HashSet<Type>());
- _KnownStoreFunctions.Push(new HashSet<string>());
- _KnownSelectFunctions.Push(new HashSet<string>());
- _KnownLBL.Push(new HashSet<string>());
- }
-
- public void Reset()
- {
- _KnownFunctions.Clear();
- _KnownVariables.Clear();
- _KnownTypes.Clear();
- _KnownStoreFunctions.Clear();
- _KnownSelectFunctions.Clear();
- _KnownLBL.Clear();
- AllDecls.Clear();
- IncDecls.Clear();
- InitializeKnownDecls();
- }
-
- public void Push()
- {
- Contract.Assert(_KnownFunctions.Count > 0);
- _KnownFunctions.Push(new HashSet<Function>(_KnownFunctions.Peek()));
- _KnownVariables.Push(new HashSet<VCExprVar>(_KnownVariables.Peek()));
- _KnownTypes.Push(new HashSet<Type>(_KnownTypes.Peek()));
- _KnownStoreFunctions.Push(new HashSet<string>(_KnownStoreFunctions.Peek()));
- _KnownSelectFunctions.Push(new HashSet<string>(_KnownSelectFunctions.Peek()));
- _KnownLBL.Push(new HashSet<string>(_KnownLBL.Peek()));
- }
-
- public void Pop()
- {
- Contract.Assert(_KnownFunctions.Count > 1);
- _KnownFunctions.Pop();
- _KnownVariables.Pop();
- _KnownTypes.Pop();
- _KnownStoreFunctions.Pop();
- _KnownSelectFunctions.Pop();
- _KnownLBL.Pop();
- }
-
- public List<string/*!>!*/> AllDeclarations { get {
- Contract.Ensures(cce.NonNullElements(Contract.Result<List<string>>() ));
-
- List<string>/*!>!*/ res = new List<string/*!*/> ();
- res.AddRange(AllDecls);
- return res;
- } }
-
- public List<string/*!>!*/> GetNewDeclarations() {
- Contract.Ensures(cce.NonNullElements(Contract.Result<List<string>>() ));
- List<string>/*!>!*/ res = new List<string/*!*/>();
- res.AddRange(IncDecls);
- IncDecls.Clear();
- return res;
- }
-
- private void AddDeclaration(string decl) {
- Contract.Requires(decl != null);
- AllDecls.Add(decl);
- IncDecls.Add(decl);
- }
-
- public void Collect(VCExpr expr) {
- Contract.Requires(expr != null);
- Traverse(expr, true);
- }
-
- ///////////////////////////////////////////////////////////////////////////
-
- private static string TypeToString(Type t) {
- Contract.Requires(t != null);
- Contract.Ensures(Contract.Result<string>() != null);
-
- return SMTLibExprLineariser.TypeToString(t);
- }
-
- public string TypeToStringReg(Type t)
- {
- RegisterType(t);
- return TypeToString(t);
- }
-
- public void AddFunction(Function func) {
- if (KnownFunctions.Contains(func))
- return;
- KnownFunctions.Add(func);
- if(declHandler != null)
- declHandler.FuncDecl(func);
- }
-
- public void RegisterRelation(Function func)
- {
- if (RegisteredRelations.Contains(func))
- return;
- RegisteredRelations.Add(func);
- }
-
- public override bool Visit(VCExprNAry node, bool arg) {
- Contract.Requires(node != null);
-
- if (node.Op is VCExprStoreOp) RegisterStore(node);
- else if (node.Op is VCExprSelectOp) RegisterSelect(node);
- else {
- VCExprBoogieFunctionOp op = node.Op as VCExprBoogieFunctionOp;
- if (op != null &&
- !(op.Func is DatatypeConstructor) && !(op.Func is DatatypeMembership) && !(op.Func is DatatypeSelector) &&
- !KnownFunctions.Contains(op.Func)) {
- Function f = op.Func;
- Contract.Assert(f != null);
-
- var builtin = SMTLibExprLineariser.ExtractBuiltin(f);
- if (builtin == null) {
- string printedName = Namer.GetQuotedName(f, f.Name);
- Contract.Assert(printedName != null);
-
- Contract.Assert(f.OutParams.Count == 1);
- var argTypes = f.InParams.Cast<Variable>().MapConcat(p => TypeToStringReg(p.TypedIdent.Type), " ");
- string decl;
- if(RegisteredRelations.Contains(op.Func))
- decl = "(declare-rel " + printedName + " (" + argTypes + ") " + ")";
- else
- decl = "(declare-fun " + printedName + " (" + argTypes + ") " + TypeToStringReg(f.OutParams[0].TypedIdent.Type) + ")";
- AddDeclaration(decl);
- if (declHandler != null) declHandler.FuncDecl(f);
- }
- KnownFunctions.Add(f);
- } else {
- var lab = node.Op as VCExprLabelOp;
- if (lab != null && !KnownLBL.Contains(lab.label)) {
- KnownLBL.Add(lab.label);
- var name = SMTLibNamer.QuoteId(SMTLibNamer.LabelVar(lab.label));
- AddDeclaration("(declare-fun " + name + " () Bool)");
- }
- }
- }
-
- return base.Visit(node, arg);
- }
-
- public override bool Visit(VCExprVar node, bool arg) {
- Contract.Requires(node != null);
- if (!BoundTermVars.Contains(node) && !KnownVariables.Contains(node)) {
- string printedName = Namer.GetQuotedName(node, node.Name);
- Contract.Assert(printedName!=null);
- RegisterType(node.Type);
- string decl =
- "(declare-fun " + printedName + " () " + TypeToString(node.Type) + ")";
- AddDeclaration(decl);
- KnownVariables.Add(node);
- if(declHandler != null)
- declHandler.VarDecl(node);
- }
-
- return base.Visit(node, arg);
- }
-
- public override bool Visit(VCExprQuantifier node, bool arg)
- {
- Contract.Requires(node != null);
- foreach (VCExprVar v in node.BoundVars) {
- Contract.Assert(v != null);
- RegisterType(v.Type);
- }
-
- return base.Visit(node, arg);
- }
-
- private void RegisterType(Type type)
- {
- Contract.Requires(type != null);
- if (KnownTypes.Contains(type)) return;
-
- if (type.IsMap && CommandLineOptions.Clo.MonomorphicArrays) {
- KnownTypes.Add(type);
- MapType mapType = type.AsMap;
- Contract.Assert(mapType != null);
-
- foreach (Type t in mapType.Arguments) {
- Contract.Assert(t != null);
- RegisterType(t);
- }
- RegisterType(mapType.Result);
-
- if (!CommandLineOptions.Clo.UseArrayTheory)
- AddDeclaration("(declare-sort " + TypeToString(type) + " 0)");
-
- return;
- }
-
- if (type.IsBool || type.IsInt || type.IsReal || type.IsBv)
- return;
-
- CtorType ctorType = type as CtorType;
- if (ctorType != null && ctorType.IsDatatype())
- return;
-
- if (CommandLineOptions.Clo.TypeEncodingMethod == CommandLineOptions.TypeEncoding.Monomorphic) {
- AddDeclaration("(declare-sort " + TypeToString(type) + " 0)");
- KnownTypes.Add(type);
- return;
- }
- }
-
- private void RegisterSelect(VCExprNAry node)
- {
- RegisterType(node[0].Type);
-
- if (CommandLineOptions.Clo.UseArrayTheory)
- return;
-
- string name = SimplifyLikeExprLineariser.SelectOpName(node);
- name = Namer.GetQuotedName(name, name);
-
- if (!KnownSelectFunctions.Contains(name)) {
- string decl = "(declare-fun " + name + " (" + node.MapConcat(n => TypeToString(n.Type), " ") + ") " + TypeToString(node.Type) + ")";
- AddDeclaration(decl);
- KnownSelectFunctions.Add(name);
- }
- }
-
- private void RegisterStore(VCExprNAry node)
- {
- RegisterType(node.Type); // this is the map type, registering it should register also the index and value types
-
- if (CommandLineOptions.Clo.UseArrayTheory)
- return;
-
- string name = SimplifyLikeExprLineariser.StoreOpName(node);
- name = Namer.GetQuotedName(name, name);
-
- if (!KnownStoreFunctions.Contains(name)) {
- string decl = "(declare-fun " + name + " (" + node.MapConcat(n => TypeToString(n.Type), " ") + ") " + TypeToString(node.Type) + ")";
- AddDeclaration(decl);
-
- if (CommandLineOptions.Clo.MonomorphicArrays) {
- var sel = SimplifyLikeExprLineariser.SelectOpName(node);
- sel = Namer.GetQuotedName(sel, sel);
-
- if (!KnownSelectFunctions.Contains(sel)) {
- // need to declare it before reference
- var args = node.SkipEnd(1);
- var ret = node.Last();
- string seldecl = "(declare-fun " + sel + " (" + args.MapConcat(n => TypeToString(n.Type), " ") + ") " + TypeToString(ret.Type) + ")";
- AddDeclaration(seldecl);
- KnownSelectFunctions.Add(sel);
- }
-
- string ax1 = "(assert (forall (";
- string ax2 = "(assert (forall (";
-
- string argX = "", argY = "";
- string dist = "";
- for (int i = 0; i < node.Arity; i++) {
- var t = " " + TypeToString(node[i].Type);
- var x = " ?x" + i;
- var y = " ?y" + i;
- ax1 += " (" + x + t + ")";
- ax2 += " (" + x + t + ")";
- if (i != 0 && i != node.Arity - 1) {
- argX += x;
- argY += y;
- ax2 += " (" + y + t + ")";
- dist += " (not (=" + x + y + "))";
- }
- }
- string v = " ?x" + (node.Arity - 1);
- ax1 += ") (= (" + sel + " (" + name + " ?x0" + argX + v + ")" + argX + ") " + v + ")";
- ax1 += "))";
-
- if (node.Arity > 3)
- dist = "(or " + dist + ")";
- ax2 += ") (=> " + dist + " (= (" + sel + " (" + name + " ?x0" + argX + v + ")" + argY + ") (" + sel + " ?x0" + argY + ")))";
- ax2 += "))";
-
- AddDeclaration(ax1);
- AddDeclaration(ax2);
- }
-
- KnownStoreFunctions.Add(name);
- }
- //
- }
-
- }
-
+//----------------------------------------------------------------------------- +// +// Copyright (C) Microsoft Corporation. All Rights Reserved. +// +//----------------------------------------------------------------------------- +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Diagnostics; +using System.Diagnostics.Contracts; +using Microsoft.Boogie.VCExprAST; + +namespace Microsoft.Boogie.SMTLib +{ + // Visitor for collecting the occurring function symbols in a VCExpr, + // and for creating the corresponding declarations + + public class TypeDeclCollector : BoundVarTraversingVCExprVisitor<bool, bool> { + + private readonly UniqueNamer Namer; + private readonly SMTLibProverOptions Options; + private HashSet<Function/*!*/>/*!*/ RegisteredRelations = new HashSet<Function>(); + + [ContractInvariantMethod] +void ObjectInvariant() +{ + Contract.Invariant(Namer!=null); + Contract.Invariant(AllDecls != null); + Contract.Invariant(IncDecls != null); + Contract.Invariant(KnownFunctions != null); + Contract.Invariant(KnownVariables != null); +} + + + public TypeDeclCollector(SMTLibProverOptions opts, UniqueNamer namer) { + Contract.Requires(namer != null); + this.Namer = namer; + this.Options = opts; + InitializeKnownDecls(); + } + + // not used + protected override bool StandardResult(VCExpr node, bool arg) { + //Contract.Requires(node != null); + return true; + } + + private readonly List<string/*!>!*/> AllDecls = new List<string/*!*/> (); + private readonly List<string/*!>!*/> IncDecls = new List<string/*!*/> (); + + // In order to support push/pop interface of the theorem prover, the "known" declarations + // must be kept in a stack + + private HashSet<Function/*!*/>/*!*/ KnownFunctions + { + get { return _KnownFunctions.Peek(); } + } + + private HashSet<VCExprVar/*!*/>/*!*/ KnownVariables + { + get { return _KnownVariables.Peek(); } + } + + private HashSet<Type/*!*/>/*!*/ KnownTypes + { + get { return _KnownTypes.Peek(); } + } + + private HashSet<string/*!*/>/*!*/ KnownStoreFunctions + { + get { return _KnownStoreFunctions.Peek(); } + } + + private HashSet<string/*!*/>/*!*/ KnownSelectFunctions + { + get { return _KnownSelectFunctions.Peek(); } + } + + private HashSet<string> KnownLBL + { + get { return _KnownLBL.Peek(); } + } + + // ------ + private readonly Stack<HashSet<Function/*!*/>/*!*/> _KnownFunctions = new Stack<HashSet<Function/*!*/>>(); + private readonly Stack<HashSet<VCExprVar/*!*/>/*!*/> _KnownVariables = new Stack<HashSet<VCExprVar/*!*/>>(); + + private readonly Stack<HashSet<Type/*!*/>/*!*/> _KnownTypes = new Stack<HashSet<Type>>(); + private readonly Stack<HashSet<string/*!*/>/*!*/> _KnownStoreFunctions = new Stack<HashSet<string>>(); + private readonly Stack<HashSet<string/*!*/>/*!*/> _KnownSelectFunctions = new Stack<HashSet<string>>(); + private readonly Stack<HashSet<string>> _KnownLBL = new Stack<HashSet<string>>(); + + // lets RPFP checker capture decls + public abstract class DeclHandler { + public abstract void VarDecl(VCExprVar v); + public abstract void FuncDecl(Function f); + } + + private DeclHandler declHandler = null; + + public void SetDeclHandler(DeclHandler _d){ + declHandler = _d; + } + + private void InitializeKnownDecls() + { + _KnownFunctions.Push(new HashSet<Function>()); + _KnownVariables.Push(new HashSet<VCExprVar>()); + _KnownTypes.Push(new HashSet<Type>()); + _KnownStoreFunctions.Push(new HashSet<string>()); + _KnownSelectFunctions.Push(new HashSet<string>()); + _KnownLBL.Push(new HashSet<string>()); + } + + public void Reset() + { + _KnownFunctions.Clear(); + _KnownVariables.Clear(); + _KnownTypes.Clear(); + _KnownStoreFunctions.Clear(); + _KnownSelectFunctions.Clear(); + _KnownLBL.Clear(); + AllDecls.Clear(); + IncDecls.Clear(); + InitializeKnownDecls(); + } + + public void Push() + { + Contract.Assert(_KnownFunctions.Count > 0); + _KnownFunctions.Push(new HashSet<Function>(_KnownFunctions.Peek())); + _KnownVariables.Push(new HashSet<VCExprVar>(_KnownVariables.Peek())); + _KnownTypes.Push(new HashSet<Type>(_KnownTypes.Peek())); + _KnownStoreFunctions.Push(new HashSet<string>(_KnownStoreFunctions.Peek())); + _KnownSelectFunctions.Push(new HashSet<string>(_KnownSelectFunctions.Peek())); + _KnownLBL.Push(new HashSet<string>(_KnownLBL.Peek())); + } + + public void Pop() + { + Contract.Assert(_KnownFunctions.Count > 1); + _KnownFunctions.Pop(); + _KnownVariables.Pop(); + _KnownTypes.Pop(); + _KnownStoreFunctions.Pop(); + _KnownSelectFunctions.Pop(); + _KnownLBL.Pop(); + } + + public List<string/*!>!*/> AllDeclarations { get { + Contract.Ensures(cce.NonNullElements(Contract.Result<List<string>>() )); + + List<string>/*!>!*/ res = new List<string/*!*/> (); + res.AddRange(AllDecls); + return res; + } } + + public List<string/*!>!*/> GetNewDeclarations() { + Contract.Ensures(cce.NonNullElements(Contract.Result<List<string>>() )); + List<string>/*!>!*/ res = new List<string/*!*/>(); + res.AddRange(IncDecls); + IncDecls.Clear(); + return res; + } + + private void AddDeclaration(string decl) { + Contract.Requires(decl != null); + AllDecls.Add(decl); + IncDecls.Add(decl); + } + + public void Collect(VCExpr expr) { + Contract.Requires(expr != null); + Traverse(expr, true); + } + + /////////////////////////////////////////////////////////////////////////// + + private static string TypeToString(Type t) { + Contract.Requires(t != null); + Contract.Ensures(Contract.Result<string>() != null); + + return SMTLibExprLineariser.TypeToString(t); + } + + public string TypeToStringReg(Type t) + { + RegisterType(t); + return TypeToString(t); + } + + public void AddFunction(Function func) { + if (KnownFunctions.Contains(func)) + return; + KnownFunctions.Add(func); + if(declHandler != null) + declHandler.FuncDecl(func); + } + + public void RegisterRelation(Function func) + { + if (RegisteredRelations.Contains(func)) + return; + RegisteredRelations.Add(func); + } + + public override bool Visit(VCExprNAry node, bool arg) { + Contract.Requires(node != null); + + if (node.Op is VCExprStoreOp) RegisterStore(node); + else if (node.Op is VCExprSelectOp) RegisterSelect(node); + else { + VCExprBoogieFunctionOp op = node.Op as VCExprBoogieFunctionOp; + if (op != null && + !(op.Func is DatatypeConstructor) && !(op.Func is DatatypeMembership) && !(op.Func is DatatypeSelector) && + !KnownFunctions.Contains(op.Func)) { + Function f = op.Func; + Contract.Assert(f != null); + + var builtin = SMTLibExprLineariser.ExtractBuiltin(f); + if (builtin == null) { + string printedName = Namer.GetQuotedName(f, f.Name); + Contract.Assert(printedName != null); + + Contract.Assert(f.OutParams.Count == 1); + var argTypes = f.InParams.Cast<Variable>().MapConcat(p => TypeToStringReg(p.TypedIdent.Type), " "); + string decl; + if(RegisteredRelations.Contains(op.Func)) + decl = "(declare-rel " + printedName + " (" + argTypes + ") " + ")"; + else + decl = "(declare-fun " + printedName + " (" + argTypes + ") " + TypeToStringReg(f.OutParams[0].TypedIdent.Type) + ")"; + AddDeclaration(decl); + if (declHandler != null) declHandler.FuncDecl(f); + } + KnownFunctions.Add(f); + } else { + var lab = node.Op as VCExprLabelOp; + if (lab != null && !KnownLBL.Contains(lab.label)) { + KnownLBL.Add(lab.label); + var name = SMTLibNamer.QuoteId(SMTLibNamer.LabelVar(lab.label)); + AddDeclaration("(declare-fun " + name + " () Bool)"); + } + } + } + + return base.Visit(node, arg); + } + + public override bool Visit(VCExprVar node, bool arg) { + Contract.Requires(node != null); + if (!BoundTermVars.Contains(node) && !KnownVariables.Contains(node)) { + string printedName = Namer.GetQuotedName(node, node.Name); + Contract.Assert(printedName!=null); + RegisterType(node.Type); + string decl = + "(declare-fun " + printedName + " () " + TypeToString(node.Type) + ")"; + AddDeclaration(decl); + KnownVariables.Add(node); + if(declHandler != null) + declHandler.VarDecl(node); + } + + return base.Visit(node, arg); + } + + public override bool Visit(VCExprQuantifier node, bool arg) + { + Contract.Requires(node != null); + foreach (VCExprVar v in node.BoundVars) { + Contract.Assert(v != null); + RegisterType(v.Type); + } + + return base.Visit(node, arg); + } + + private void RegisterType(Type type) + { + Contract.Requires(type != null); + if (KnownTypes.Contains(type)) return; + + if (type.IsMap && CommandLineOptions.Clo.MonomorphicArrays) { + KnownTypes.Add(type); + MapType mapType = type.AsMap; + Contract.Assert(mapType != null); + + foreach (Type t in mapType.Arguments) { + Contract.Assert(t != null); + RegisterType(t); + } + RegisterType(mapType.Result); + + if (!CommandLineOptions.Clo.UseArrayTheory) + AddDeclaration("(declare-sort " + TypeToString(type) + " 0)"); + + return; + } + + if (type.IsBool || type.IsInt || type.IsReal || type.IsBv) + return; + + CtorType ctorType = type as CtorType; + if (ctorType != null && ctorType.IsDatatype()) + return; + + if (CommandLineOptions.Clo.TypeEncodingMethod == CommandLineOptions.TypeEncoding.Monomorphic) { + AddDeclaration("(declare-sort " + TypeToString(type) + " 0)"); + KnownTypes.Add(type); + return; + } + } + + private void RegisterSelect(VCExprNAry node) + { + RegisterType(node[0].Type); + + if (CommandLineOptions.Clo.UseArrayTheory) + return; + + string name = SimplifyLikeExprLineariser.SelectOpName(node); + name = Namer.GetQuotedName(name, name); + + if (!KnownSelectFunctions.Contains(name)) { + string decl = "(declare-fun " + name + " (" + node.MapConcat(n => TypeToString(n.Type), " ") + ") " + TypeToString(node.Type) + ")"; + AddDeclaration(decl); + KnownSelectFunctions.Add(name); + } + } + + private void RegisterStore(VCExprNAry node) + { + RegisterType(node.Type); // this is the map type, registering it should register also the index and value types + + if (CommandLineOptions.Clo.UseArrayTheory) + return; + + string name = SimplifyLikeExprLineariser.StoreOpName(node); + name = Namer.GetQuotedName(name, name); + + if (!KnownStoreFunctions.Contains(name)) { + string decl = "(declare-fun " + name + " (" + node.MapConcat(n => TypeToString(n.Type), " ") + ") " + TypeToString(node.Type) + ")"; + AddDeclaration(decl); + + if (CommandLineOptions.Clo.MonomorphicArrays) { + var sel = SimplifyLikeExprLineariser.SelectOpName(node); + sel = Namer.GetQuotedName(sel, sel); + + if (!KnownSelectFunctions.Contains(sel)) { + // need to declare it before reference + var args = node.SkipEnd(1); + var ret = node.Last(); + string seldecl = "(declare-fun " + sel + " (" + args.MapConcat(n => TypeToString(n.Type), " ") + ") " + TypeToString(ret.Type) + ")"; + AddDeclaration(seldecl); + KnownSelectFunctions.Add(sel); + } + + string ax1 = "(assert (forall ("; + string ax2 = "(assert (forall ("; + + string argX = "", argY = ""; + string dist = ""; + for (int i = 0; i < node.Arity; i++) { + var t = " " + TypeToString(node[i].Type); + var x = " ?x" + i; + var y = " ?y" + i; + ax1 += " (" + x + t + ")"; + ax2 += " (" + x + t + ")"; + if (i != 0 && i != node.Arity - 1) { + argX += x; + argY += y; + ax2 += " (" + y + t + ")"; + dist += " (not (=" + x + y + "))"; + } + } + string v = " ?x" + (node.Arity - 1); + ax1 += ") (= (" + sel + " (" + name + " ?x0" + argX + v + ")" + argX + ") " + v + ")"; + ax1 += "))"; + + if (node.Arity > 3) + dist = "(or " + dist + ")"; + ax2 += ") (=> " + dist + " (= (" + sel + " (" + name + " ?x0" + argX + v + ")" + argY + ") (" + sel + " ?x0" + argY + ")))"; + ax2 += "))"; + + AddDeclaration(ax1); + AddDeclaration(ax2); + } + + KnownStoreFunctions.Add(name); + } + // + } + + } + }
\ No newline at end of file diff --git a/Source/Provers/SMTLib/Z3.cs b/Source/Provers/SMTLib/Z3.cs index bbc23917..f4bbbd6d 100644 --- a/Source/Provers/SMTLib/Z3.cs +++ b/Source/Provers/SMTLib/Z3.cs @@ -1,387 +1,387 @@ -//-----------------------------------------------------------------------------
-//
-// Copyright (C) Microsoft Corporation. All Rights Reserved.
-//
-//-----------------------------------------------------------------------------
-
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Diagnostics.Contracts;
-using System.IO;
-using System.Text.RegularExpressions;
-
-namespace Microsoft.Boogie.SMTLib
-{
- class Z3
- {
- static string _proverPath;
-
- static string CodebaseString()
- {
- Contract.Ensures(Contract.Result<string>() != null);
- return Path.GetDirectoryName(cce.NonNull(System.Reflection.Assembly.GetExecutingAssembly().Location));
- }
-
- public static string ExecutablePath()
- {
- if (_proverPath == null)
- FindExecutable();
- return _proverPath;
- }
-
- static void FindExecutable()
- // throws ProverException, System.IO.FileNotFoundException;
- {
- Contract.Ensures(_proverPath != null);
-
- // Command line option 'z3exe' always has priority if set
- if (CommandLineOptions.Clo.Z3ExecutablePath != null)
- {
- _proverPath = CommandLineOptions.Clo.Z3ExecutablePath;
- if (!File.Exists(_proverPath))
- {
- throw new ProverException("Cannot find prover specified with z3exe: " + _proverPath);
- }
- if (CommandLineOptions.Clo.Trace)
- {
- Console.WriteLine("[TRACE] Using prover: " + _proverPath);
- }
- return;
- }
-
- var proverExe = CommandLineOptions.Clo.Z3ExecutableName;
- proverExe = proverExe == null ? "z3.exe" : proverExe;
-
- if (_proverPath == null)
- {
- // Initialize '_proverPath'
- _proverPath = Path.Combine(CodebaseString(), proverExe);
- string firstTry = _proverPath;
-
- if (File.Exists(firstTry))
- {
- if (CommandLineOptions.Clo.Trace)
- {
- Console.WriteLine("[TRACE] Using prover: " + _proverPath);
- }
- return;
- }
-
- List<string> z3Dirs = new List<string>();
- var msrDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), @"Microsoft Research\");
- if (Directory.Exists(msrDir))
- {
- z3Dirs.AddRange(Directory.GetDirectories(msrDir, "Z3-*"));
- }
- var msrDirX86 = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), @"Microsoft Research\");
- if (Directory.Exists(msrDirX86))
- {
- z3Dirs.AddRange(Directory.GetDirectories(msrDirX86, "Z3-*"));
- }
-
- int minMajor = 3, minMinor = 2;
-
- // Look for the most recent version of Z3.
- int minor = 0, major = 0;
- string winner = null;
- Regex r = new Regex(@"^Z3-(\d+)\.(\d+)$");
- foreach (string d in z3Dirs)
- {
- string name = new DirectoryInfo(d).Name;
- foreach (Match m in r.Matches(name))
- {
- int ma, mi;
- ma = int.Parse(m.Groups[1].ToString());
- mi = int.Parse(m.Groups[2].ToString());
- if (major < ma || (major == ma && minor < mi))
- {
- major = ma;
- minor = mi;
- winner = d;
- }
- }
- }
-
- if (major == 0 && minor == 0)
- {
- throw new ProverException("Cannot find executable: " + firstTry);
- }
-
- Contract.Assert(winner != null);
-
- _proverPath = Path.Combine(Path.Combine(winner, "bin"), proverExe);
- if (!File.Exists(_proverPath))
- {
- throw new ProverException("Cannot find prover: " + _proverPath);
- }
-
- if (CommandLineOptions.Clo.Trace)
- {
- Console.WriteLine("[TRACE] Using prover: " + _proverPath);
- }
-
- if (major < minMajor || (major == minMajor && minor < minMinor))
- {
- throw new ProverException(string.Format("Found version {0}.{1} of Z3. Please install version {2}.{3} or later. " +
- "(More conservative users might opt to supply -prover:Z3 option instead to get the historic Simplify back-end)",
- major, minor, minMajor, minMinor));
- }
- }
- }
-
-
- static int Z3MajorVersion = 0;
- static int Z3MinorVersion = 0;
- static bool Z3VersionObtained = false;
-
- public static void GetVersion(out int major, out int minor)
- {
- if (!Z3VersionObtained)
- {
- var proc = new System.Diagnostics.Process();
- proc.StartInfo.FileName = _proverPath;
- proc.StartInfo.Arguments = "--version";
- proc.StartInfo.RedirectStandardOutput = true;
- proc.StartInfo.RedirectStandardError = true;
- proc.StartInfo.UseShellExecute = false;
- proc.StartInfo.CreateNoWindow = true;
- proc.Start();
- string answer = proc.StandardOutput.ReadToEnd();
- proc.WaitForExit();
- if (proc.ExitCode == 0)
- {
- var firstdot = answer.IndexOf('.');
- if (firstdot >= 0)
- {
- var seconddot = answer.IndexOf('.', firstdot + 1);
- if (seconddot >= firstdot + 1)
- {
- var spacebeforefirstdot = answer.LastIndexOf(' ', firstdot);
- if (spacebeforefirstdot >= 0)
- {
- var majorstr = answer.Substring(spacebeforefirstdot, firstdot - spacebeforefirstdot);
- var minorstr = answer.Substring(firstdot + 1, seconddot - firstdot - 1);
- Z3MajorVersion = Convert.ToInt32(majorstr);
- Z3MinorVersion = Convert.ToInt32(minorstr);
- }
- }
- }
- }
- Z3VersionObtained = true;
- }
- major = Z3MajorVersion;
- minor = Z3MinorVersion;
- }
-
- public static string SetTimeoutOption()
- {
- int major, minor;
- GetVersion(out major, out minor);
- if (major > 4 || major == 4 && minor >= 3)
- return "TIMEOUT";
- else
- return "SOFT_TIMEOUT";
- }
-
- // options that work only on the command line
- static string[] commandLineOnly = { "TRACE", "PROOF_MODE" };
-
-
- public static void SetupOptions(SMTLibProverOptions options)
- {
- FindExecutable();
- int major, minor;
- GetVersion(out major, out minor);
- if (major > 4 || major == 4 && minor >= 3)
- {
-
- bool fp = false; // CommandLineOptions.Clo.FixedPointEngine != null;
-
- // don't bother with auto-config - it would disable explicit settings for eager threshold and so on
- if(!fp) options.AddWeakSmtOption("AUTO_CONFIG", "false");
-
- //options.AddWeakSmtOption("MODEL_PARTIAL", "true");
- //options.WeakAddSmtOption("MODEL_VALUE_COMPLETION", "false");
-
- // options.AddWeakSmtOption("MODEL_HIDE_UNUSED_PARTITIONS", "false"); TODO: what does this do?
-
- // Make sure we get something that is parsable as a bitvector
- options.AddWeakSmtOption("pp.bv_literals", "false");
- if (!CommandLineOptions.Clo.UseSmtOutputFormat)
- {
- options.AddWeakSmtOption("MODEL.V2", "true");
- }
- //options.AddWeakSmtOption("ASYNC_COMMANDS", "false"); TODO: is this needed?
-
- if (!options.OptimizeForBv)
- {
- // Phase selection means to always try the negative literal polarity first, seems to be good for Boogie.
- // The restart parameters change the restart behavior to match Z3 v1, which also seems to be good.
- options.AddWeakSmtOption("smt.PHASE_SELECTION", "0");
- options.AddWeakSmtOption("smt.RESTART_STRATEGY", "0");
- options.AddWeakSmtOption("smt.RESTART_FACTOR", "|1.5|");
-
- // Make the integer model more diverse by default, speeds up some benchmarks a lot.
- options.AddWeakSmtOption("smt.ARITH.RANDOM_INITIAL_VALUE", "true");
-
- // The left-to-right structural case-splitting strategy.
- //options.AddWeakSmtOption("SORT_AND_OR", "false"); // always false now
-
- if (!fp) options.AddWeakSmtOption("smt.CASE_SPLIT", "3");
-
- // In addition delay adding unit conflicts.
- options.AddWeakSmtOption("smt.DELAY_UNITS", "true");
- //options.AddWeakSmtOption("DELAY_UNITS_THRESHOLD", "16"); TODO: what?
- }
-
- // This is used by VCC, but could be also useful for others, if sk_hack(foo(x)) is included as trigger,
- // the foo(x0) will be activated for e-matching when x is skolemized to x0.
- options.AddWeakSmtOption("NNF.SK_HACK", "true");
-
- // don't use model-based quantifier instantiation; it never finishes on non-trivial Boogie problems
- options.AddWeakSmtOption("smt.MBQI", "false");
-
- // More or less like MAM=0.
- options.AddWeakSmtOption("smt.QI.EAGER_THRESHOLD", "100");
- // Complex proof attempts in VCC (and likely elsewhere) require matching depth of 20 or more.
-
- // the following will make the :weight option more usable
- // KLM: this QI cost function is the default
- // if (!fp) options.AddWeakSmtOption("smt.QI.COST", "|(+ weight generation)|"); // TODO: this doesn't seem to work
-
- //if (options.Inspector != null)
- // options.WeakAddSmtOption("PROGRESS_SAMPLING_FREQ", "100");
-
- options.AddWeakSmtOption("TYPE_CHECK", "true");
- options.AddWeakSmtOption("smt.BV.REFLECT", "true");
-
- if (options.TimeLimit > 0)
- {
- options.AddWeakSmtOption("TIMEOUT", options.TimeLimit.ToString());
- options.AddWeakSmtOption("fixedpoint.TIMEOUT", options.TimeLimit.ToString());
- // This kills the Z3 *instance* after the specified time, not a particular query, so we cannot use it.
- // options.AddSolverArgument("/T:" + (options.TimeLimit + 1000) / 1000);
- }
-
- if (options.Inspector != null)
- options.AddWeakSmtOption("PROGRESS_SAMPLING_FREQ", "200");
-
- if (CommandLineOptions.Clo.WeakArrayTheory)
- {
- options.AddWeakSmtOption("smt.array.weak", "true");
- options.AddWeakSmtOption("smt.array.extensional", "false");
- }
-
- if (CommandLineOptions.Clo.PrintConjectures != null)
- {
- options.AddWeakSmtOption("fixedpoint.conjecture_file", CommandLineOptions.Clo.PrintConjectures + ".tmp");
- }
- }
- else
- {
- // don't bother with auto-config - it would disable explicit settings for eager threshold and so on
- options.AddWeakSmtOption("AUTO_CONFIG", "false");
-
- //options.AddWeakSmtOption("MODEL_PARTIAL", "true");
- //options.WeakAddSmtOption("MODEL_VALUE_COMPLETION", "false");
- options.AddWeakSmtOption("MODEL_HIDE_UNUSED_PARTITIONS", "false");
- options.AddWeakSmtOption("ASYNC_COMMANDS", "false");
-
- if (CommandLineOptions.Clo.UseSmtOutputFormat)
- {
- options.AddWeakSmtOption("pp-bv-literals", "false"); ;
- }
- else
- {
- options.AddWeakSmtOption("MODEL_V2", "true");
- }
-
- if (!options.OptimizeForBv)
- {
- // Phase selection means to always try the negative literal polarity first, seems to be good for Boogie.
- // The restart parameters change the restart behavior to match Z3 v1, which also seems to be good.
- options.AddWeakSmtOption("PHASE_SELECTION", "0");
- options.AddWeakSmtOption("RESTART_STRATEGY", "0");
- options.AddWeakSmtOption("RESTART_FACTOR", "|1.5|");
-
- // Make the integer model more diverse by default, speeds up some benchmarks a lot.
- options.AddWeakSmtOption("ARITH_RANDOM_INITIAL_VALUE", "true");
-
- // The left-to-right structural case-splitting strategy.
- //options.AddWeakSmtOption("SORT_AND_OR", "false"); // always false now
- options.AddWeakSmtOption("CASE_SPLIT", "3");
-
- // In addition delay adding unit conflicts.
- options.AddWeakSmtOption("DELAY_UNITS", "true");
- options.AddWeakSmtOption("DELAY_UNITS_THRESHOLD", "16");
- }
-
- // This is used by VCC, but could be also useful for others, if sk_hack(foo(x)) is included as trigger,
- // the foo(x0) will be activated for e-matching when x is skolemized to x0.
- options.AddWeakSmtOption("NNF_SK_HACK", "true");
-
- // don't use model-based quantifier instantiation; it never finishes on non-trivial Boogie problems
- options.AddWeakSmtOption("MBQI", "false");
-
- // More or less like MAM=0.
- options.AddWeakSmtOption("QI_EAGER_THRESHOLD", "100");
- // Complex proof attempts in VCC (and likely elsewhere) require matching depth of 20 or more.
-
- // the following will make the :weight option more usable
- options.AddWeakSmtOption("QI_COST", "|\"(+ weight generation)\"|");
-
- //if (options.Inspector != null)
- // options.WeakAddSmtOption("PROGRESS_SAMPLING_FREQ", "100");
-
- options.AddWeakSmtOption("TYPE_CHECK", "true");
- options.AddWeakSmtOption("BV_REFLECT", "true");
-
- if (options.TimeLimit > 0)
- {
- options.AddWeakSmtOption("SOFT_TIMEOUT", options.TimeLimit.ToString());
- // This kills the Z3 *instance* after the specified time, not a particular query, so we cannot use it.
- // options.AddSolverArgument("/T:" + (options.TimeLimit + 1000) / 1000);
- }
-
- if (options.Inspector != null)
- options.AddWeakSmtOption("PROGRESS_SAMPLING_FREQ", "200");
-
- if (CommandLineOptions.Clo.WeakArrayTheory)
- {
- options.AddWeakSmtOption("ARRAY_WEAK", "true");
- options.AddWeakSmtOption("ARRAY_EXTENSIONAL", "false");
- }
-
- options.AddWeakSmtOption("MODEL_ON_TIMEOUT", "true");
-
- }
-
- // KLM: don't add Z3 options here. The options are different in different Z3 versions.
- // Add options in the above condition for the appropriate version.
-
- // legacy option handling
- if (!CommandLineOptions.Clo.z3AtFlag)
- options.MultiTraces = true;
-
-
- foreach (string opt in CommandLineOptions.Clo.Z3Options)
- {
- Contract.Assert(opt != null);
- int eq = opt.IndexOf("=");
- if (eq > 0 && 'A' <= opt[0] && opt[0] <= 'Z' && !commandLineOnly.Contains(opt.Substring(0, eq)))
- {
- options.AddSmtOption(opt.Substring(0, eq), opt.Substring(eq + 1));
- }
- else
- {
- options.AddSolverArgument(opt);
- }
- }
- }
-
-
- }
-}
+//----------------------------------------------------------------------------- +// +// Copyright (C) Microsoft Corporation. All Rights Reserved. +// +//----------------------------------------------------------------------------- + + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Diagnostics.Contracts; +using System.IO; +using System.Text.RegularExpressions; + +namespace Microsoft.Boogie.SMTLib +{ + class Z3 + { + static string _proverPath; + + static string CodebaseString() + { + Contract.Ensures(Contract.Result<string>() != null); + return Path.GetDirectoryName(cce.NonNull(System.Reflection.Assembly.GetExecutingAssembly().Location)); + } + + public static string ExecutablePath() + { + if (_proverPath == null) + FindExecutable(); + return _proverPath; + } + + static void FindExecutable() + // throws ProverException, System.IO.FileNotFoundException; + { + Contract.Ensures(_proverPath != null); + + // Command line option 'z3exe' always has priority if set + if (CommandLineOptions.Clo.Z3ExecutablePath != null) + { + _proverPath = CommandLineOptions.Clo.Z3ExecutablePath; + if (!File.Exists(_proverPath)) + { + throw new ProverException("Cannot find prover specified with z3exe: " + _proverPath); + } + if (CommandLineOptions.Clo.Trace) + { + Console.WriteLine("[TRACE] Using prover: " + _proverPath); + } + return; + } + + var proverExe = CommandLineOptions.Clo.Z3ExecutableName; + proverExe = proverExe == null ? "z3.exe" : proverExe; + + if (_proverPath == null) + { + // Initialize '_proverPath' + _proverPath = Path.Combine(CodebaseString(), proverExe); + string firstTry = _proverPath; + + if (File.Exists(firstTry)) + { + if (CommandLineOptions.Clo.Trace) + { + Console.WriteLine("[TRACE] Using prover: " + _proverPath); + } + return; + } + + List<string> z3Dirs = new List<string>(); + var msrDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), @"Microsoft Research\"); + if (Directory.Exists(msrDir)) + { + z3Dirs.AddRange(Directory.GetDirectories(msrDir, "Z3-*")); + } + var msrDirX86 = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), @"Microsoft Research\"); + if (Directory.Exists(msrDirX86)) + { + z3Dirs.AddRange(Directory.GetDirectories(msrDirX86, "Z3-*")); + } + + int minMajor = 3, minMinor = 2; + + // Look for the most recent version of Z3. + int minor = 0, major = 0; + string winner = null; + Regex r = new Regex(@"^Z3-(\d+)\.(\d+)$"); + foreach (string d in z3Dirs) + { + string name = new DirectoryInfo(d).Name; + foreach (Match m in r.Matches(name)) + { + int ma, mi; + ma = int.Parse(m.Groups[1].ToString()); + mi = int.Parse(m.Groups[2].ToString()); + if (major < ma || (major == ma && minor < mi)) + { + major = ma; + minor = mi; + winner = d; + } + } + } + + if (major == 0 && minor == 0) + { + throw new ProverException("Cannot find executable: " + firstTry); + } + + Contract.Assert(winner != null); + + _proverPath = Path.Combine(Path.Combine(winner, "bin"), proverExe); + if (!File.Exists(_proverPath)) + { + throw new ProverException("Cannot find prover: " + _proverPath); + } + + if (CommandLineOptions.Clo.Trace) + { + Console.WriteLine("[TRACE] Using prover: " + _proverPath); + } + + if (major < minMajor || (major == minMajor && minor < minMinor)) + { + throw new ProverException(string.Format("Found version {0}.{1} of Z3. Please install version {2}.{3} or later. " + + "(More conservative users might opt to supply -prover:Z3 option instead to get the historic Simplify back-end)", + major, minor, minMajor, minMinor)); + } + } + } + + + static int Z3MajorVersion = 0; + static int Z3MinorVersion = 0; + static bool Z3VersionObtained = false; + + public static void GetVersion(out int major, out int minor) + { + if (!Z3VersionObtained) + { + var proc = new System.Diagnostics.Process(); + proc.StartInfo.FileName = _proverPath; + proc.StartInfo.Arguments = "--version"; + proc.StartInfo.RedirectStandardOutput = true; + proc.StartInfo.RedirectStandardError = true; + proc.StartInfo.UseShellExecute = false; + proc.StartInfo.CreateNoWindow = true; + proc.Start(); + string answer = proc.StandardOutput.ReadToEnd(); + proc.WaitForExit(); + if (proc.ExitCode == 0) + { + var firstdot = answer.IndexOf('.'); + if (firstdot >= 0) + { + var seconddot = answer.IndexOf('.', firstdot + 1); + if (seconddot >= firstdot + 1) + { + var spacebeforefirstdot = answer.LastIndexOf(' ', firstdot); + if (spacebeforefirstdot >= 0) + { + var majorstr = answer.Substring(spacebeforefirstdot, firstdot - spacebeforefirstdot); + var minorstr = answer.Substring(firstdot + 1, seconddot - firstdot - 1); + Z3MajorVersion = Convert.ToInt32(majorstr); + Z3MinorVersion = Convert.ToInt32(minorstr); + } + } + } + } + Z3VersionObtained = true; + } + major = Z3MajorVersion; + minor = Z3MinorVersion; + } + + public static string SetTimeoutOption() + { + int major, minor; + GetVersion(out major, out minor); + if (major > 4 || major == 4 && minor >= 3) + return "TIMEOUT"; + else + return "SOFT_TIMEOUT"; + } + + // options that work only on the command line + static string[] commandLineOnly = { "TRACE", "PROOF_MODE" }; + + + public static void SetupOptions(SMTLibProverOptions options) + { + FindExecutable(); + int major, minor; + GetVersion(out major, out minor); + if (major > 4 || major == 4 && minor >= 3) + { + + bool fp = false; // CommandLineOptions.Clo.FixedPointEngine != null; + + // don't bother with auto-config - it would disable explicit settings for eager threshold and so on + if(!fp) options.AddWeakSmtOption("AUTO_CONFIG", "false"); + + //options.AddWeakSmtOption("MODEL_PARTIAL", "true"); + //options.WeakAddSmtOption("MODEL_VALUE_COMPLETION", "false"); + + // options.AddWeakSmtOption("MODEL_HIDE_UNUSED_PARTITIONS", "false"); TODO: what does this do? + + // Make sure we get something that is parsable as a bitvector + options.AddWeakSmtOption("pp.bv_literals", "false"); + if (!CommandLineOptions.Clo.UseSmtOutputFormat) + { + options.AddWeakSmtOption("MODEL.V2", "true"); + } + //options.AddWeakSmtOption("ASYNC_COMMANDS", "false"); TODO: is this needed? + + if (!options.OptimizeForBv) + { + // Phase selection means to always try the negative literal polarity first, seems to be good for Boogie. + // The restart parameters change the restart behavior to match Z3 v1, which also seems to be good. + options.AddWeakSmtOption("smt.PHASE_SELECTION", "0"); + options.AddWeakSmtOption("smt.RESTART_STRATEGY", "0"); + options.AddWeakSmtOption("smt.RESTART_FACTOR", "|1.5|"); + + // Make the integer model more diverse by default, speeds up some benchmarks a lot. + options.AddWeakSmtOption("smt.ARITH.RANDOM_INITIAL_VALUE", "true"); + + // The left-to-right structural case-splitting strategy. + //options.AddWeakSmtOption("SORT_AND_OR", "false"); // always false now + + if (!fp) options.AddWeakSmtOption("smt.CASE_SPLIT", "3"); + + // In addition delay adding unit conflicts. + options.AddWeakSmtOption("smt.DELAY_UNITS", "true"); + //options.AddWeakSmtOption("DELAY_UNITS_THRESHOLD", "16"); TODO: what? + } + + // This is used by VCC, but could be also useful for others, if sk_hack(foo(x)) is included as trigger, + // the foo(x0) will be activated for e-matching when x is skolemized to x0. + options.AddWeakSmtOption("NNF.SK_HACK", "true"); + + // don't use model-based quantifier instantiation; it never finishes on non-trivial Boogie problems + options.AddWeakSmtOption("smt.MBQI", "false"); + + // More or less like MAM=0. + options.AddWeakSmtOption("smt.QI.EAGER_THRESHOLD", "100"); + // Complex proof attempts in VCC (and likely elsewhere) require matching depth of 20 or more. + + // the following will make the :weight option more usable + // KLM: this QI cost function is the default + // if (!fp) options.AddWeakSmtOption("smt.QI.COST", "|(+ weight generation)|"); // TODO: this doesn't seem to work + + //if (options.Inspector != null) + // options.WeakAddSmtOption("PROGRESS_SAMPLING_FREQ", "100"); + + options.AddWeakSmtOption("TYPE_CHECK", "true"); + options.AddWeakSmtOption("smt.BV.REFLECT", "true"); + + if (options.TimeLimit > 0) + { + options.AddWeakSmtOption("TIMEOUT", options.TimeLimit.ToString()); + options.AddWeakSmtOption("fixedpoint.TIMEOUT", options.TimeLimit.ToString()); + // This kills the Z3 *instance* after the specified time, not a particular query, so we cannot use it. + // options.AddSolverArgument("/T:" + (options.TimeLimit + 1000) / 1000); + } + + if (options.Inspector != null) + options.AddWeakSmtOption("PROGRESS_SAMPLING_FREQ", "200"); + + if (CommandLineOptions.Clo.WeakArrayTheory) + { + options.AddWeakSmtOption("smt.array.weak", "true"); + options.AddWeakSmtOption("smt.array.extensional", "false"); + } + + if (CommandLineOptions.Clo.PrintConjectures != null) + { + options.AddWeakSmtOption("fixedpoint.conjecture_file", CommandLineOptions.Clo.PrintConjectures + ".tmp"); + } + } + else + { + // don't bother with auto-config - it would disable explicit settings for eager threshold and so on + options.AddWeakSmtOption("AUTO_CONFIG", "false"); + + //options.AddWeakSmtOption("MODEL_PARTIAL", "true"); + //options.WeakAddSmtOption("MODEL_VALUE_COMPLETION", "false"); + options.AddWeakSmtOption("MODEL_HIDE_UNUSED_PARTITIONS", "false"); + options.AddWeakSmtOption("ASYNC_COMMANDS", "false"); + + if (CommandLineOptions.Clo.UseSmtOutputFormat) + { + options.AddWeakSmtOption("pp-bv-literals", "false"); ; + } + else + { + options.AddWeakSmtOption("MODEL_V2", "true"); + } + + if (!options.OptimizeForBv) + { + // Phase selection means to always try the negative literal polarity first, seems to be good for Boogie. + // The restart parameters change the restart behavior to match Z3 v1, which also seems to be good. + options.AddWeakSmtOption("PHASE_SELECTION", "0"); + options.AddWeakSmtOption("RESTART_STRATEGY", "0"); + options.AddWeakSmtOption("RESTART_FACTOR", "|1.5|"); + + // Make the integer model more diverse by default, speeds up some benchmarks a lot. + options.AddWeakSmtOption("ARITH_RANDOM_INITIAL_VALUE", "true"); + + // The left-to-right structural case-splitting strategy. + //options.AddWeakSmtOption("SORT_AND_OR", "false"); // always false now + options.AddWeakSmtOption("CASE_SPLIT", "3"); + + // In addition delay adding unit conflicts. + options.AddWeakSmtOption("DELAY_UNITS", "true"); + options.AddWeakSmtOption("DELAY_UNITS_THRESHOLD", "16"); + } + + // This is used by VCC, but could be also useful for others, if sk_hack(foo(x)) is included as trigger, + // the foo(x0) will be activated for e-matching when x is skolemized to x0. + options.AddWeakSmtOption("NNF_SK_HACK", "true"); + + // don't use model-based quantifier instantiation; it never finishes on non-trivial Boogie problems + options.AddWeakSmtOption("MBQI", "false"); + + // More or less like MAM=0. + options.AddWeakSmtOption("QI_EAGER_THRESHOLD", "100"); + // Complex proof attempts in VCC (and likely elsewhere) require matching depth of 20 or more. + + // the following will make the :weight option more usable + options.AddWeakSmtOption("QI_COST", "|\"(+ weight generation)\"|"); + + //if (options.Inspector != null) + // options.WeakAddSmtOption("PROGRESS_SAMPLING_FREQ", "100"); + + options.AddWeakSmtOption("TYPE_CHECK", "true"); + options.AddWeakSmtOption("BV_REFLECT", "true"); + + if (options.TimeLimit > 0) + { + options.AddWeakSmtOption("SOFT_TIMEOUT", options.TimeLimit.ToString()); + // This kills the Z3 *instance* after the specified time, not a particular query, so we cannot use it. + // options.AddSolverArgument("/T:" + (options.TimeLimit + 1000) / 1000); + } + + if (options.Inspector != null) + options.AddWeakSmtOption("PROGRESS_SAMPLING_FREQ", "200"); + + if (CommandLineOptions.Clo.WeakArrayTheory) + { + options.AddWeakSmtOption("ARRAY_WEAK", "true"); + options.AddWeakSmtOption("ARRAY_EXTENSIONAL", "false"); + } + + options.AddWeakSmtOption("MODEL_ON_TIMEOUT", "true"); + + } + + // KLM: don't add Z3 options here. The options are different in different Z3 versions. + // Add options in the above condition for the appropriate version. + + // legacy option handling + if (!CommandLineOptions.Clo.z3AtFlag) + options.MultiTraces = true; + + + foreach (string opt in CommandLineOptions.Clo.Z3Options) + { + Contract.Assert(opt != null); + int eq = opt.IndexOf("="); + if (eq > 0 && 'A' <= opt[0] && opt[0] <= 'Z' && !commandLineOnly.Contains(opt.Substring(0, eq))) + { + options.AddSmtOption(opt.Substring(0, eq), opt.Substring(eq + 1)); + } + else + { + options.AddSolverArgument(opt); + } + } + } + + + } +} diff --git a/Source/Provers/SMTLib/cce.cs b/Source/Provers/SMTLib/cce.cs index ef594484..1e0b12a5 100644 --- a/Source/Provers/SMTLib/cce.cs +++ b/Source/Provers/SMTLib/cce.cs @@ -1,193 +1,193 @@ -using System;
-using SA=System.Attribute;
-using System.Collections.Generic;
-using System.Diagnostics.Contracts;
-using System.Text;
-//using Microsoft.Boogie;
-
-/// <summary>
-/// A class containing static methods to extend the functionality of Code Contracts
-/// </summary>
-
-public static class cce {
- //[Pure]
- //public static bool NonNullElements<T>(Microsoft.Dafny.Graph<T> collection) {
- // return collection != null && cce.NonNullElements(collection.TopologicallySortedComponents());
- //}
- [Pure]
- public static T NonNull<T>(T t) {
- Contract.Assert(t != null);
- return t;
- }
- [Pure]
- public static bool NonNullElements<T>(IEnumerable<T> collection) {
- return collection != null && Contract.ForAll(collection, c => c != null);
- }
- [Pure]
- public static bool NonNullElements<TKey, TValue>(IDictionary<TKey, TValue> collection) {
- return collection != null && Contract.ForAll(collection, pair => NonNullElements(pair));
- }
- //[Pure]
- //public static bool NonNullElements(VariableSeq collection) {
- // return collection != null && Contract.ForAll(0, collection.Length, i => collection[i] != null);
- //}
- /// <summary>
- /// For possibly-null lists of non-null elements
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="collection"></param>
- /// <param name="nullability">If true, the collection is treated as an IEnumerable<T!>?, rather than an IEnumerable<T!>!</param>
- /// <returns></returns>
- [Pure]
- public static bool NonNullElements<T>(IEnumerable<T> collection, bool nullability) {
- return (nullability && collection == null) || cce.NonNullElements(collection);
- //Should be the same as:
- /*if(nullability&&collection==null)
- * return true;
- * return cce.NonNullElements(collection)
- */
-
- }
- [Pure]
- public static bool NonNullElements<TKey, TValue>(KeyValuePair<TKey, TValue> kvp) {
- return kvp.Key != null && kvp.Value != null;
- }
- [Pure]
- public static bool NonNullElements<T>(IEnumerator<T> iEnumerator) {
- return iEnumerator != null;
- }
- //[Pure]
- //public static bool NonNullElements<T>(Graphing.Graph<T> graph) {
- // return cce.NonNullElements(graph.TopologicalSort());
- //}
- [Pure]
- public static void BeginExpose(object o) {
- }
- [Pure]
- public static void EndExpose() {
- }
- [Pure]
- public static bool IsPeerConsistent(object o) {
- return true;
- }
- [Pure]
- public static bool IsConsistent(object o) {
- return true;
- }
- [Pure]
- public static bool IsExposable(object o) {
- return true;
- }
- [Pure]
- public static bool IsExposed(object o) {
- return true;
- }
- [Pure]
- public static bool IsNew(object o) {
- return true;
- }
- public static class Owner {
- [Pure]
- public static bool Same(object o, object p) {
- return true;
- }
- [Pure]
- public static void AssignSame(object o, object p) {
- }
- [Pure]
- public static object ElementProxy(object o) {
- return o;
- }
- [Pure]
- public static bool None(object o) {
- return true;
- }
- [Pure]
- public static bool Different(object o, object p) {
- return true;
- }
- [Pure]
- public static bool New(object o) {
- return true;
- }
- }
- [Pure]
- public static void LoopInvariant(bool p) {
- Contract.Assert(p);
- }
- public class UnreachableException : Exception {
- public UnreachableException() {
- }
- }
- //[Pure]
- //public static bool IsValid(Microsoft.Dafny.Expression expression) {
- // return true;
- //}
- //public static List<T> toList<T>(PureCollections.Sequence s) {
- // List<T> toRet = new List<T>();
- // foreach (T t in s.elems)
- // if(t!=null)
- // toRet.Add(t);
- // return toRet;
- //}
-
- //internal static bool NonNullElements(Set set) {
- // return set != null && Contract.ForAll(0,set.Count, i => set[i] != null);
- //}
-}
-
-public class PeerAttribute : SA {
-}
-public class RepAttribute : SA {
-}
-public class CapturedAttribute : SA {
-}
-public class NotDelayedAttribute : SA {
-}
-public class NoDefaultContractAttribute : SA {
-}
-public class VerifyAttribute : SA {
- public VerifyAttribute(bool b) {
-
- }
-}
-public class StrictReadonlyAttribute : SA {
-}
-public class AdditiveAttribute : SA {
-}
-public class ReadsAttribute : SA {
- public enum Reads {
- Nothing,
- Everything,
- };
- public ReadsAttribute(object o) {
- }
-}
-public class GlobalAccessAttribute : SA {
- public GlobalAccessAttribute(bool b) {
- }
-}
-public class EscapesAttribute : SA {
- public EscapesAttribute(bool b, bool b_2) {
- }
-}
-public class NeedsContractsAttribute : SA {
- public NeedsContractsAttribute() {
- }
- public NeedsContractsAttribute(bool ret, bool parameters) {
- }
- public NeedsContractsAttribute(bool ret, int[] parameters) {
- }
-}
-public class ImmutableAttribute : SA {
-}
-public class InsideAttribute : SA {
-}
-public class SpecPublicAttribute : SA {
-}
-public class ElementsPeerAttribute : SA {
-}
-public class ResultNotNewlyAllocatedAttribute : SA {
-}
-public class OnceAttribute : SA {
+using System; +using SA=System.Attribute; +using System.Collections.Generic; +using System.Diagnostics.Contracts; +using System.Text; +//using Microsoft.Boogie; + +/// <summary> +/// A class containing static methods to extend the functionality of Code Contracts +/// </summary> + +public static class cce { + //[Pure] + //public static bool NonNullElements<T>(Microsoft.Dafny.Graph<T> collection) { + // return collection != null && cce.NonNullElements(collection.TopologicallySortedComponents()); + //} + [Pure] + public static T NonNull<T>(T t) { + Contract.Assert(t != null); + return t; + } + [Pure] + public static bool NonNullElements<T>(IEnumerable<T> collection) { + return collection != null && Contract.ForAll(collection, c => c != null); + } + [Pure] + public static bool NonNullElements<TKey, TValue>(IDictionary<TKey, TValue> collection) { + return collection != null && Contract.ForAll(collection, pair => NonNullElements(pair)); + } + //[Pure] + //public static bool NonNullElements(VariableSeq collection) { + // return collection != null && Contract.ForAll(0, collection.Length, i => collection[i] != null); + //} + /// <summary> + /// For possibly-null lists of non-null elements + /// </summary> + /// <typeparam name="T"></typeparam> + /// <param name="collection"></param> + /// <param name="nullability">If true, the collection is treated as an IEnumerable<T!>?, rather than an IEnumerable<T!>!</param> + /// <returns></returns> + [Pure] + public static bool NonNullElements<T>(IEnumerable<T> collection, bool nullability) { + return (nullability && collection == null) || cce.NonNullElements(collection); + //Should be the same as: + /*if(nullability&&collection==null) + * return true; + * return cce.NonNullElements(collection) + */ + + } + [Pure] + public static bool NonNullElements<TKey, TValue>(KeyValuePair<TKey, TValue> kvp) { + return kvp.Key != null && kvp.Value != null; + } + [Pure] + public static bool NonNullElements<T>(IEnumerator<T> iEnumerator) { + return iEnumerator != null; + } + //[Pure] + //public static bool NonNullElements<T>(Graphing.Graph<T> graph) { + // return cce.NonNullElements(graph.TopologicalSort()); + //} + [Pure] + public static void BeginExpose(object o) { + } + [Pure] + public static void EndExpose() { + } + [Pure] + public static bool IsPeerConsistent(object o) { + return true; + } + [Pure] + public static bool IsConsistent(object o) { + return true; + } + [Pure] + public static bool IsExposable(object o) { + return true; + } + [Pure] + public static bool IsExposed(object o) { + return true; + } + [Pure] + public static bool IsNew(object o) { + return true; + } + public static class Owner { + [Pure] + public static bool Same(object o, object p) { + return true; + } + [Pure] + public static void AssignSame(object o, object p) { + } + [Pure] + public static object ElementProxy(object o) { + return o; + } + [Pure] + public static bool None(object o) { + return true; + } + [Pure] + public static bool Different(object o, object p) { + return true; + } + [Pure] + public static bool New(object o) { + return true; + } + } + [Pure] + public static void LoopInvariant(bool p) { + Contract.Assert(p); + } + public class UnreachableException : Exception { + public UnreachableException() { + } + } + //[Pure] + //public static bool IsValid(Microsoft.Dafny.Expression expression) { + // return true; + //} + //public static List<T> toList<T>(PureCollections.Sequence s) { + // List<T> toRet = new List<T>(); + // foreach (T t in s.elems) + // if(t!=null) + // toRet.Add(t); + // return toRet; + //} + + //internal static bool NonNullElements(Set set) { + // return set != null && Contract.ForAll(0,set.Count, i => set[i] != null); + //} +} + +public class PeerAttribute : SA { +} +public class RepAttribute : SA { +} +public class CapturedAttribute : SA { +} +public class NotDelayedAttribute : SA { +} +public class NoDefaultContractAttribute : SA { +} +public class VerifyAttribute : SA { + public VerifyAttribute(bool b) { + + } +} +public class StrictReadonlyAttribute : SA { +} +public class AdditiveAttribute : SA { +} +public class ReadsAttribute : SA { + public enum Reads { + Nothing, + Everything, + }; + public ReadsAttribute(object o) { + } +} +public class GlobalAccessAttribute : SA { + public GlobalAccessAttribute(bool b) { + } +} +public class EscapesAttribute : SA { + public EscapesAttribute(bool b, bool b_2) { + } +} +public class NeedsContractsAttribute : SA { + public NeedsContractsAttribute() { + } + public NeedsContractsAttribute(bool ret, bool parameters) { + } + public NeedsContractsAttribute(bool ret, int[] parameters) { + } +} +public class ImmutableAttribute : SA { +} +public class InsideAttribute : SA { +} +public class SpecPublicAttribute : SA { +} +public class ElementsPeerAttribute : SA { +} +public class ResultNotNewlyAllocatedAttribute : SA { +} +public class OnceAttribute : SA { }
\ No newline at end of file diff --git a/Source/Provers/TPTP/ProverInterface.cs b/Source/Provers/TPTP/ProverInterface.cs index b714ed67..669c459f 100644 --- a/Source/Provers/TPTP/ProverInterface.cs +++ b/Source/Provers/TPTP/ProverInterface.cs @@ -1,351 +1,351 @@ -//-----------------------------------------------------------------------------
-//
-// Copyright (C) Microsoft Corporation. All Rights Reserved.
-//
-//-----------------------------------------------------------------------------
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading;
-using System.IO;
-using System.Diagnostics;
-using System.Diagnostics.Contracts;
-using Microsoft.Boogie;
-using Microsoft.Boogie.VCExprAST;
-using Microsoft.Boogie.Clustering;
-using Microsoft.Boogie.TypeErasure;
-using Microsoft.Boogie.Simplify;
-
-namespace Microsoft.Boogie.TPTP
-{
- public class TPTPProverOptions : ProverOptions
- {
- public string Output = "boogie-vc-@PROC@.tptp";
- public bool UsePredicates = false;
-
- protected override bool Parse(string opt)
- {
- return
- ParseString(opt, "OUTPUT", ref Output) ||
- ParseBool(opt, "USE_PREDICATES", ref UsePredicates) ||
- base.Parse(opt);
- }
-
- public override string Help
- {
- get
- {
- return
-@"
-TPTP-specific options:
-~~~~~~~~~~~~~~~~~~~~~~
-OUTPUT=<string> Store VC in named file. Defaults to boogie-vc-@PROC@.tptp.
-USE_PREDICATES=<bool> Try to use SMT predicates for functions returning bool.
-
-" + base.Help;
- // DIST requires non-public binaries
- }
- }
- }
-
- public class TPTPProcessTheoremProver : LogProverInterface
- {
- private readonly DeclFreeProverContext ctx;
- private readonly VCExpressionGenerator Gen;
-
- [ContractInvariantMethod]
- void ObjectInvariant()
- {
- Contract.Invariant(ctx != null);
- Contract.Invariant(AxBuilder != null);
- Contract.Invariant(Namer != null);
- Contract.Invariant(DeclCollector != null);
- Contract.Invariant(cce.NonNullElements(Axioms));
- Contract.Invariant(cce.NonNullElements(TypeDecls));
- Contract.Invariant(_backgroundPredicates != null);
-
- }
-
-
- [NotDelayed]
- public TPTPProcessTheoremProver(ProverOptions options, VCExpressionGenerator gen,
- DeclFreeProverContext ctx)
- : base(options, "", "", "", "", gen)
- {
- Contract.Requires(options != null);
- Contract.Requires(gen != null);
- Contract.Requires(ctx != null);
-
- // No bg predicate at the moment
- // InitializeGlobalInformation("UnivBackPred.tptp");
-
- this.ctx = ctx;
- this.Gen = gen;
-
- TypeAxiomBuilder axBuilder;
- switch (CommandLineOptions.Clo.TypeEncodingMethod) {
- case CommandLineOptions.TypeEncoding.Arguments:
- axBuilder = new TypeAxiomBuilderArguments(gen);
- axBuilder.Setup();
- break;
- case CommandLineOptions.TypeEncoding.Monomorphic:
- axBuilder = new TypeAxiomBuilderPremisses(gen);
- break;
- default:
- axBuilder = new TypeAxiomBuilderPremisses(gen);
- axBuilder.Setup();
- break;
- }
- AxBuilder = axBuilder;
- UniqueNamer namer = new UniqueNamer();
- Namer = namer;
- Namer.Spacer = "__";
- this.DeclCollector = new TypeDeclCollector(namer);
-
- }
-
- public override ProverContext Context
- {
- get
- {
- Contract.Ensures(Contract.Result<ProverContext>() != null);
-
- return ctx;
- }
- }
-
- private readonly TypeAxiomBuilder AxBuilder;
- private readonly UniqueNamer Namer;
- private readonly TypeDeclCollector DeclCollector;
-
- private void FeedTypeDeclsToProver()
- {
- foreach (string s in DeclCollector.GetNewDeclarations()) {
- Contract.Assert(s != null);
- AddTypeDecl(s);
- }
- }
-
- public override void BeginCheck(string descriptiveName, VCExpr vc, ErrorHandler handler)
- {
- //Contract.Requires(descriptiveName != null);
- //Contract.Requires(vc != null);
- //Contract.Requires(handler != null);
- TextWriter output = OpenOutputFile(descriptiveName);
- Contract.Assert(output != null);
-
- WriteLineAndLog(output, "%------------------------------------------------------------------------------");
- WriteLineAndLog(output, "% Boogie benchmark: " + descriptiveName);
- WriteLineAndLog(output, "%------------------------------------------------------------------------------");
-
- WriteLineAndLog(output, _backgroundPredicates);
-
- if (!AxiomsAreSetup) {
- AddAxiom(VCExpr2String(ctx.Axioms, -1));
- AxiomsAreSetup = true;
- }
-
- string vcString = "fof(vc, conjecture, " + VCExpr2String(vc, 1) + ").";
-
- foreach (string s in TypeDecls) {
- Contract.Assert(s != null);
- WriteLineAndLog(output, s);
- }
- int id = 0;
- foreach (string s in Axioms) {
- Contract.Assert(s != null);
- WriteLineAndLog(output, "fof(ax" + id++ + ", axiom,");
- WriteLineAndLog(output, s);
- WriteLineAndLog(output, ").");
- }
-
- WriteLineAndLog(output, vcString);
-
- output.Close();
- }
-
- public TPTPProverOptions Options
- {
- get { return (TPTPProverOptions)this.options; }
- }
-
- private TextWriter OpenOutputFile(string descriptiveName)
- {
- Contract.Requires(descriptiveName != null);
- Contract.Ensures(Contract.Result<TextWriter>() != null);
-
- string filename = Options.Output;
- filename = Helpers.SubstituteAtPROC(descriptiveName, cce.NonNull(filename));
- return new StreamWriter(filename, false);
- }
-
- private void WriteLineAndLog(TextWriter output, string msg)
- {
- Contract.Requires(output != null);
- Contract.Requires(msg != null);
- LogActivity(msg);
- output.WriteLine(msg);
- }
-
- [NoDefaultContract]
- public override Outcome CheckOutcome(ErrorHandler handler)
- { //Contract.Requires(handler != null);
- Contract.EnsuresOnThrow<UnexpectedProverOutputException>(true);
- return Outcome.Undetermined;
- }
-
- protected string VCExpr2String(VCExpr expr, int polarity)
- {
- Contract.Requires(expr != null);
- Contract.Ensures(Contract.Result<string>() != null);
-
- DateTime start = DateTime.UtcNow;
- if (CommandLineOptions.Clo.Trace)
- Console.Write("Linearising ... ");
-
- // handle the types in the VCExpr
- TypeEraser eraser;
- switch (CommandLineOptions.Clo.TypeEncodingMethod) {
- case CommandLineOptions.TypeEncoding.Arguments:
- eraser = new TypeEraserArguments((TypeAxiomBuilderArguments)AxBuilder, gen);
- break;
- case CommandLineOptions.TypeEncoding.Monomorphic:
- eraser = null;
- break;
- default:
- eraser = new TypeEraserPremisses((TypeAxiomBuilderPremisses)AxBuilder, gen);
- break;
- }
- VCExpr exprWithoutTypes = eraser == null ? expr : eraser.Erase(expr, polarity);
- Contract.Assert(exprWithoutTypes != null);
-
- var letImplier = new Let2ImpliesMutator(Gen);
- var flattener = new TermFormulaFlattener(Gen);
- var exprWithLet = flattener.Flatten(exprWithoutTypes);
- var exprWithoutLet = letImplier.Mutate(exprWithLet);
-
- var axiomsWithLet = flattener.Flatten(AxBuilder.GetNewAxioms());
- var axiomsWithoutLet = letImplier.Mutate(axiomsWithLet);
-
- DeclCollector.Collect(axiomsWithoutLet);
- DeclCollector.Collect(exprWithoutLet);
- FeedTypeDeclsToProver();
-
- AddAxiom(TPTPExprLineariser.ToString(axiomsWithoutLet, Namer, Options));
- string res = TPTPExprLineariser.ToString(exprWithoutLet, Namer, Options);
- Contract.Assert(res != null);
-
- if (CommandLineOptions.Clo.Trace) {
- DateTime end = DateTime.UtcNow;
- TimeSpan elapsed = end - start;
- Console.WriteLine("finished [{0} s]", elapsed.TotalSeconds);
- }
- return res;
- }
-
- // the list of all known axioms, where have to be included in each
- // verification condition
- private readonly List<string/*!>!*/> Axioms = new List<string/*!*/>();
- private bool AxiomsAreSetup = false;
-
-
-
-
- // similarly, a list of function/predicate declarations
- private readonly List<string/*!>!*/> TypeDecls = new List<string/*!*/>();
-
- protected void AddAxiom(string axiom)
- {
- Contract.Requires(axiom != null);
- Axioms.Add(axiom);
- // if (thmProver != null) {
- // LogActivity(":assume " + axiom);
- // thmProver.AddAxioms(axiom);
- // }
- }
-
- protected void AddTypeDecl(string decl)
- {
- Contract.Requires(decl != null);
- TypeDecls.Add(decl);
- // if (thmProver != null) {
- // LogActivity(decl);
- // thmProver.Feed(decl, 0);
- // }
- }
-
- ////////////////////////////////////////////////////////////////////////////
-
- private static string _backgroundPredicates = "";
-
- static void InitializeGlobalInformation(string backgroundPred)
- {
- Contract.Requires(backgroundPred != null);
- Contract.Ensures(_backgroundPredicates != null);
- //throws ProverException, System.IO.FileNotFoundException;
- if (_backgroundPredicates == null) {
- string codebaseString =
- cce.NonNull(Path.GetDirectoryName(cce.NonNull(System.Reflection.Assembly.GetExecutingAssembly().Location)));
-
- // Initialize '_backgroundPredicates'
- string univBackPredPath = Path.Combine(codebaseString, backgroundPred);
- using (StreamReader reader = new System.IO.StreamReader(univBackPredPath)) {
- _backgroundPredicates = reader.ReadToEnd();
- }
- }
- }
- }
-
- public class Factory : ProverFactory
- {
-
- public override object SpawnProver(ProverOptions options, object ctxt)
- {
- //Contract.Requires(ctxt != null);
- //Contract.Requires(options != null);
- Contract.Ensures(Contract.Result<object>() != null);
-
- return this.SpawnProver(options,
- cce.NonNull((DeclFreeProverContext)ctxt).ExprGen,
- cce.NonNull((DeclFreeProverContext)ctxt));
- }
-
- public override object NewProverContext(ProverOptions options)
- {
- //Contract.Requires(options != null);
- Contract.Ensures(Contract.Result<object>() != null);
-
- if (CommandLineOptions.Clo.BracketIdsInVC < 0) {
- CommandLineOptions.Clo.BracketIdsInVC = 0;
- }
-
- VCExpressionGenerator gen = new VCExpressionGenerator();
- List<string>/*!>!*/ proverCommands = new List<string/*!*/>();
- proverCommands.Add("tptp");
- proverCommands.Add("external");
- VCGenerationOptions genOptions = new VCGenerationOptions(proverCommands);
- Contract.Assert(genOptions != null);
-
- return new DeclFreeProverContext(gen, genOptions);
- }
-
- public override ProverOptions BlankProverOptions()
- {
- return new TPTPProverOptions();
- }
-
- protected virtual TPTPProcessTheoremProver SpawnProver(ProverOptions options,
- VCExpressionGenerator gen,
- DeclFreeProverContext ctx)
- {
- Contract.Requires(options != null);
- Contract.Requires(gen != null);
- Contract.Requires(ctx != null);
- Contract.Ensures(Contract.Result<TPTPProcessTheoremProver>() != null);
-
- return new TPTPProcessTheoremProver(options, gen, ctx);
- }
- }
-}
+//----------------------------------------------------------------------------- +// +// Copyright (C) Microsoft Corporation. All Rights Reserved. +// +//----------------------------------------------------------------------------- + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.IO; +using System.Diagnostics; +using System.Diagnostics.Contracts; +using Microsoft.Boogie; +using Microsoft.Boogie.VCExprAST; +using Microsoft.Boogie.Clustering; +using Microsoft.Boogie.TypeErasure; +using Microsoft.Boogie.Simplify; + +namespace Microsoft.Boogie.TPTP +{ + public class TPTPProverOptions : ProverOptions + { + public string Output = "boogie-vc-@PROC@.tptp"; + public bool UsePredicates = false; + + protected override bool Parse(string opt) + { + return + ParseString(opt, "OUTPUT", ref Output) || + ParseBool(opt, "USE_PREDICATES", ref UsePredicates) || + base.Parse(opt); + } + + public override string Help + { + get + { + return +@" +TPTP-specific options: +~~~~~~~~~~~~~~~~~~~~~~ +OUTPUT=<string> Store VC in named file. Defaults to boogie-vc-@PROC@.tptp. +USE_PREDICATES=<bool> Try to use SMT predicates for functions returning bool. + +" + base.Help; + // DIST requires non-public binaries + } + } + } + + public class TPTPProcessTheoremProver : LogProverInterface + { + private readonly DeclFreeProverContext ctx; + private readonly VCExpressionGenerator Gen; + + [ContractInvariantMethod] + void ObjectInvariant() + { + Contract.Invariant(ctx != null); + Contract.Invariant(AxBuilder != null); + Contract.Invariant(Namer != null); + Contract.Invariant(DeclCollector != null); + Contract.Invariant(cce.NonNullElements(Axioms)); + Contract.Invariant(cce.NonNullElements(TypeDecls)); + Contract.Invariant(_backgroundPredicates != null); + + } + + + [NotDelayed] + public TPTPProcessTheoremProver(ProverOptions options, VCExpressionGenerator gen, + DeclFreeProverContext ctx) + : base(options, "", "", "", "", gen) + { + Contract.Requires(options != null); + Contract.Requires(gen != null); + Contract.Requires(ctx != null); + + // No bg predicate at the moment + // InitializeGlobalInformation("UnivBackPred.tptp"); + + this.ctx = ctx; + this.Gen = gen; + + TypeAxiomBuilder axBuilder; + switch (CommandLineOptions.Clo.TypeEncodingMethod) { + case CommandLineOptions.TypeEncoding.Arguments: + axBuilder = new TypeAxiomBuilderArguments(gen); + axBuilder.Setup(); + break; + case CommandLineOptions.TypeEncoding.Monomorphic: + axBuilder = new TypeAxiomBuilderPremisses(gen); + break; + default: + axBuilder = new TypeAxiomBuilderPremisses(gen); + axBuilder.Setup(); + break; + } + AxBuilder = axBuilder; + UniqueNamer namer = new UniqueNamer(); + Namer = namer; + Namer.Spacer = "__"; + this.DeclCollector = new TypeDeclCollector(namer); + + } + + public override ProverContext Context + { + get + { + Contract.Ensures(Contract.Result<ProverContext>() != null); + + return ctx; + } + } + + private readonly TypeAxiomBuilder AxBuilder; + private readonly UniqueNamer Namer; + private readonly TypeDeclCollector DeclCollector; + + private void FeedTypeDeclsToProver() + { + foreach (string s in DeclCollector.GetNewDeclarations()) { + Contract.Assert(s != null); + AddTypeDecl(s); + } + } + + public override void BeginCheck(string descriptiveName, VCExpr vc, ErrorHandler handler) + { + //Contract.Requires(descriptiveName != null); + //Contract.Requires(vc != null); + //Contract.Requires(handler != null); + TextWriter output = OpenOutputFile(descriptiveName); + Contract.Assert(output != null); + + WriteLineAndLog(output, "%------------------------------------------------------------------------------"); + WriteLineAndLog(output, "% Boogie benchmark: " + descriptiveName); + WriteLineAndLog(output, "%------------------------------------------------------------------------------"); + + WriteLineAndLog(output, _backgroundPredicates); + + if (!AxiomsAreSetup) { + AddAxiom(VCExpr2String(ctx.Axioms, -1)); + AxiomsAreSetup = true; + } + + string vcString = "fof(vc, conjecture, " + VCExpr2String(vc, 1) + ")."; + + foreach (string s in TypeDecls) { + Contract.Assert(s != null); + WriteLineAndLog(output, s); + } + int id = 0; + foreach (string s in Axioms) { + Contract.Assert(s != null); + WriteLineAndLog(output, "fof(ax" + id++ + ", axiom,"); + WriteLineAndLog(output, s); + WriteLineAndLog(output, ")."); + } + + WriteLineAndLog(output, vcString); + + output.Close(); + } + + public TPTPProverOptions Options + { + get { return (TPTPProverOptions)this.options; } + } + + private TextWriter OpenOutputFile(string descriptiveName) + { + Contract.Requires(descriptiveName != null); + Contract.Ensures(Contract.Result<TextWriter>() != null); + + string filename = Options.Output; + filename = Helpers.SubstituteAtPROC(descriptiveName, cce.NonNull(filename)); + return new StreamWriter(filename, false); + } + + private void WriteLineAndLog(TextWriter output, string msg) + { + Contract.Requires(output != null); + Contract.Requires(msg != null); + LogActivity(msg); + output.WriteLine(msg); + } + + [NoDefaultContract] + public override Outcome CheckOutcome(ErrorHandler handler) + { //Contract.Requires(handler != null); + Contract.EnsuresOnThrow<UnexpectedProverOutputException>(true); + return Outcome.Undetermined; + } + + protected string VCExpr2String(VCExpr expr, int polarity) + { + Contract.Requires(expr != null); + Contract.Ensures(Contract.Result<string>() != null); + + DateTime start = DateTime.UtcNow; + if (CommandLineOptions.Clo.Trace) + Console.Write("Linearising ... "); + + // handle the types in the VCExpr + TypeEraser eraser; + switch (CommandLineOptions.Clo.TypeEncodingMethod) { + case CommandLineOptions.TypeEncoding.Arguments: + eraser = new TypeEraserArguments((TypeAxiomBuilderArguments)AxBuilder, gen); + break; + case CommandLineOptions.TypeEncoding.Monomorphic: + eraser = null; + break; + default: + eraser = new TypeEraserPremisses((TypeAxiomBuilderPremisses)AxBuilder, gen); + break; + } + VCExpr exprWithoutTypes = eraser == null ? expr : eraser.Erase(expr, polarity); + Contract.Assert(exprWithoutTypes != null); + + var letImplier = new Let2ImpliesMutator(Gen); + var flattener = new TermFormulaFlattener(Gen); + var exprWithLet = flattener.Flatten(exprWithoutTypes); + var exprWithoutLet = letImplier.Mutate(exprWithLet); + + var axiomsWithLet = flattener.Flatten(AxBuilder.GetNewAxioms()); + var axiomsWithoutLet = letImplier.Mutate(axiomsWithLet); + + DeclCollector.Collect(axiomsWithoutLet); + DeclCollector.Collect(exprWithoutLet); + FeedTypeDeclsToProver(); + + AddAxiom(TPTPExprLineariser.ToString(axiomsWithoutLet, Namer, Options)); + string res = TPTPExprLineariser.ToString(exprWithoutLet, Namer, Options); + Contract.Assert(res != null); + + if (CommandLineOptions.Clo.Trace) { + DateTime end = DateTime.UtcNow; + TimeSpan elapsed = end - start; + Console.WriteLine("finished [{0} s]", elapsed.TotalSeconds); + } + return res; + } + + // the list of all known axioms, where have to be included in each + // verification condition + private readonly List<string/*!>!*/> Axioms = new List<string/*!*/>(); + private bool AxiomsAreSetup = false; + + + + + // similarly, a list of function/predicate declarations + private readonly List<string/*!>!*/> TypeDecls = new List<string/*!*/>(); + + protected void AddAxiom(string axiom) + { + Contract.Requires(axiom != null); + Axioms.Add(axiom); + // if (thmProver != null) { + // LogActivity(":assume " + axiom); + // thmProver.AddAxioms(axiom); + // } + } + + protected void AddTypeDecl(string decl) + { + Contract.Requires(decl != null); + TypeDecls.Add(decl); + // if (thmProver != null) { + // LogActivity(decl); + // thmProver.Feed(decl, 0); + // } + } + + //////////////////////////////////////////////////////////////////////////// + + private static string _backgroundPredicates = ""; + + static void InitializeGlobalInformation(string backgroundPred) + { + Contract.Requires(backgroundPred != null); + Contract.Ensures(_backgroundPredicates != null); + //throws ProverException, System.IO.FileNotFoundException; + if (_backgroundPredicates == null) { + string codebaseString = + cce.NonNull(Path.GetDirectoryName(cce.NonNull(System.Reflection.Assembly.GetExecutingAssembly().Location))); + + // Initialize '_backgroundPredicates' + string univBackPredPath = Path.Combine(codebaseString, backgroundPred); + using (StreamReader reader = new System.IO.StreamReader(univBackPredPath)) { + _backgroundPredicates = reader.ReadToEnd(); + } + } + } + } + + public class Factory : ProverFactory + { + + public override object SpawnProver(ProverOptions options, object ctxt) + { + //Contract.Requires(ctxt != null); + //Contract.Requires(options != null); + Contract.Ensures(Contract.Result<object>() != null); + + return this.SpawnProver(options, + cce.NonNull((DeclFreeProverContext)ctxt).ExprGen, + cce.NonNull((DeclFreeProverContext)ctxt)); + } + + public override object NewProverContext(ProverOptions options) + { + //Contract.Requires(options != null); + Contract.Ensures(Contract.Result<object>() != null); + + if (CommandLineOptions.Clo.BracketIdsInVC < 0) { + CommandLineOptions.Clo.BracketIdsInVC = 0; + } + + VCExpressionGenerator gen = new VCExpressionGenerator(); + List<string>/*!>!*/ proverCommands = new List<string/*!*/>(); + proverCommands.Add("tptp"); + proverCommands.Add("external"); + VCGenerationOptions genOptions = new VCGenerationOptions(proverCommands); + Contract.Assert(genOptions != null); + + return new DeclFreeProverContext(gen, genOptions); + } + + public override ProverOptions BlankProverOptions() + { + return new TPTPProverOptions(); + } + + protected virtual TPTPProcessTheoremProver SpawnProver(ProverOptions options, + VCExpressionGenerator gen, + DeclFreeProverContext ctx) + { + Contract.Requires(options != null); + Contract.Requires(gen != null); + Contract.Requires(ctx != null); + Contract.Ensures(Contract.Result<TPTPProcessTheoremProver>() != null); + + return new TPTPProcessTheoremProver(options, gen, ctx); + } + } +} diff --git a/Source/Provers/TPTP/TPTP.csproj b/Source/Provers/TPTP/TPTP.csproj index a3ee1caa..116492d0 100644 --- a/Source/Provers/TPTP/TPTP.csproj +++ b/Source/Provers/TPTP/TPTP.csproj @@ -1,131 +1,131 @@ -<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <ProductVersion>8.0.30703</ProductVersion>
- <SchemaVersion>2.0</SchemaVersion>
- <ProjectGuid>{A598ED5A-93AD-4125-A555-3921A2F936FA}</ProjectGuid>
- <OutputType>Library</OutputType>
- <AppDesignerFolder>Properties</AppDesignerFolder>
- <RootNamespace>Microsoft.Boogie.TPTP</RootNamespace>
- <AssemblyName>Provers.TPTP</AssemblyName>
- <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
- <FileAlignment>512</FileAlignment>
- <TargetFrameworkProfile Condition=" '$(OS)' == 'Windows_NT'" >Client</TargetFrameworkProfile>
- <CodeContractsAssemblyMode>0</CodeContractsAssemblyMode>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- <DebugSymbols>true</DebugSymbols>
- <DebugType>full</DebugType>
- <Optimize>false</Optimize>
- <OutputPath>bin\Debug\</OutputPath>
- <DefineConstants>DEBUG;TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- <DebugType>pdbonly</DebugType>
- <Optimize>true</Optimize>
- <OutputPath>bin\Release\</OutputPath>
- <DefineConstants>TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Checked|AnyCPU'">
- <DebugSymbols>true</DebugSymbols>
- <OutputPath>bin\Checked\</OutputPath>
- <DefineConstants>DEBUG;TRACE</DefineConstants>
- <DebugType>full</DebugType>
- <PlatformTarget>AnyCPU</PlatformTarget>
- <CodeAnalysisLogFile>bin\Debug\Provers.TPTP.dll.CodeAnalysisLog.xml</CodeAnalysisLogFile>
- <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
- <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
- <ErrorReport>prompt</ErrorReport>
- <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
- <CodeAnalysisRuleSetDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
- <CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
- <CodeContractsEnableRuntimeChecking>True</CodeContractsEnableRuntimeChecking>
- <CodeContractsRuntimeOnlyPublicSurface>False</CodeContractsRuntimeOnlyPublicSurface>
- <CodeContractsRuntimeThrowOnFailure>True</CodeContractsRuntimeThrowOnFailure>
- <CodeContractsRuntimeCallSiteRequires>False</CodeContractsRuntimeCallSiteRequires>
- <CodeContractsRuntimeSkipQuantifiers>False</CodeContractsRuntimeSkipQuantifiers>
- <CodeContractsRunCodeAnalysis>False</CodeContractsRunCodeAnalysis>
- <CodeContractsNonNullObligations>False</CodeContractsNonNullObligations>
- <CodeContractsBoundsObligations>False</CodeContractsBoundsObligations>
- <CodeContractsArithmeticObligations>False</CodeContractsArithmeticObligations>
- <CodeContractsEnumObligations>False</CodeContractsEnumObligations>
- <CodeContractsPointerObligations>False</CodeContractsPointerObligations>
- <CodeContractsRedundantAssumptions>False</CodeContractsRedundantAssumptions>
- <CodeContractsRunInBackground>True</CodeContractsRunInBackground>
- <CodeContractsShowSquigglies>False</CodeContractsShowSquigglies>
- <CodeContractsUseBaseLine>False</CodeContractsUseBaseLine>
- <CodeContractsEmitXMLDocs>False</CodeContractsEmitXMLDocs>
- <CodeContractsCustomRewriterAssembly />
- <CodeContractsCustomRewriterClass />
- <CodeContractsLibPaths />
- <CodeContractsExtraRewriteOptions />
- <CodeContractsExtraAnalysisOptions />
- <CodeContractsBaseLineFile />
- <CodeContractsCacheAnalysisResults>False</CodeContractsCacheAnalysisResults>
- <CodeContractsRuntimeCheckingLevel>Full</CodeContractsRuntimeCheckingLevel>
- <CodeContractsReferenceAssembly>Build</CodeContractsReferenceAssembly>
- <CodeContractsAnalysisWarningLevel>0</CodeContractsAnalysisWarningLevel>
- </PropertyGroup>
- <ItemGroup>
- <Reference Include="System" />
- <Reference Include="System.Core" />
- <Reference Include="System.Xml.Linq" />
- <Reference Include="System.Data.DataSetExtensions" />
- <Reference Include="Microsoft.CSharp" />
- <Reference Include="System.Data" />
- <Reference Include="System.Xml" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="ProverInterface.cs" />
- <Compile Include="..\..\version.cs" />
- <Compile Include="TPTPLineariser.cs" />
- <Compile Include="TypeDeclCollector.cs" />
- </ItemGroup>
- <ItemGroup>
- <ProjectReference Include="..\..\AbsInt\AbsInt.csproj">
- <Project>{0EFA3E43-690B-48DC-A72C-384A3EA7F31F}</Project>
- <Name>AbsInt</Name>
- </ProjectReference>
- <ProjectReference Include="..\..\AIFramework\AIFramework.csproj">
- <Project>{39B0658D-C955-41C5-9A43-48C97A1EF5FD}</Project>
- <Name>AIFramework</Name>
- </ProjectReference>
- <ProjectReference Include="..\..\Basetypes\Basetypes.csproj">
- <Project>{43DFAD18-3E35-4558-9BE2-CAFF6B5BA8A0}</Project>
- <Name>Basetypes</Name>
- </ProjectReference>
- <ProjectReference Include="..\..\CodeContractsExtender\CodeContractsExtender.csproj">
- <Project>{ACCC0156-0921-43ED-8F67-AD8BDC8CDE31}</Project>
- <Name>CodeContractsExtender</Name>
- </ProjectReference>
- <ProjectReference Include="..\..\Core\Core.csproj">
- <Project>{B230A69C-C466-4065-B9C1-84D80E76D802}</Project>
- <Name>Core</Name>
- </ProjectReference>
- <ProjectReference Include="..\..\VCExpr\VCExpr.csproj">
- <Project>{56FFDBCA-7D14-43B8-A6CA-22A20E417EE1}</Project>
- <Name>VCExpr</Name>
- </ProjectReference>
- <ProjectReference Include="..\..\VCGeneration\VCGeneration.csproj">
- <Project>{E1F10180-C7B9-4147-B51F-FA1B701966DC}</Project>
- <Name>VCGeneration</Name>
- </ProjectReference>
- </ItemGroup>
- <ItemGroup>
- <Folder Include="Properties\" />
- </ItemGroup>
- <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
- <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
- Other similar extension points exist, see Microsoft.Common.targets.
- <Target Name="BeforeBuild">
- </Target>
- <Target Name="AfterBuild">
- </Target>
- -->
+<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProductVersion>8.0.30703</ProductVersion> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{A598ED5A-93AD-4125-A555-3921A2F936FA}</ProjectGuid> + <OutputType>Library</OutputType> + <AppDesignerFolder>Properties</AppDesignerFolder> + <RootNamespace>Microsoft.Boogie.TPTP</RootNamespace> + <AssemblyName>Provers.TPTP</AssemblyName> + <TargetFrameworkVersion>v4.0</TargetFrameworkVersion> + <FileAlignment>512</FileAlignment> + <TargetFrameworkProfile Condition=" '$(OS)' == 'Windows_NT'" >Client</TargetFrameworkProfile> + <CodeContractsAssemblyMode>0</CodeContractsAssemblyMode> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + <DebugSymbols>true</DebugSymbols> + <DebugType>full</DebugType> + <Optimize>false</Optimize> + <OutputPath>bin\Debug\</OutputPath> + <DefineConstants>DEBUG;TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + <DebugType>pdbonly</DebugType> + <Optimize>true</Optimize> + <OutputPath>bin\Release\</OutputPath> + <DefineConstants>TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Checked|AnyCPU'"> + <DebugSymbols>true</DebugSymbols> + <OutputPath>bin\Checked\</OutputPath> + <DefineConstants>DEBUG;TRACE</DefineConstants> + <DebugType>full</DebugType> + <PlatformTarget>AnyCPU</PlatformTarget> + <CodeAnalysisLogFile>bin\Debug\Provers.TPTP.dll.CodeAnalysisLog.xml</CodeAnalysisLogFile> + <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression> + <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile> + <ErrorReport>prompt</ErrorReport> + <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRuleSetDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories> + <CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories> + <CodeContractsEnableRuntimeChecking>True</CodeContractsEnableRuntimeChecking> + <CodeContractsRuntimeOnlyPublicSurface>False</CodeContractsRuntimeOnlyPublicSurface> + <CodeContractsRuntimeThrowOnFailure>True</CodeContractsRuntimeThrowOnFailure> + <CodeContractsRuntimeCallSiteRequires>False</CodeContractsRuntimeCallSiteRequires> + <CodeContractsRuntimeSkipQuantifiers>False</CodeContractsRuntimeSkipQuantifiers> + <CodeContractsRunCodeAnalysis>False</CodeContractsRunCodeAnalysis> + <CodeContractsNonNullObligations>False</CodeContractsNonNullObligations> + <CodeContractsBoundsObligations>False</CodeContractsBoundsObligations> + <CodeContractsArithmeticObligations>False</CodeContractsArithmeticObligations> + <CodeContractsEnumObligations>False</CodeContractsEnumObligations> + <CodeContractsPointerObligations>False</CodeContractsPointerObligations> + <CodeContractsRedundantAssumptions>False</CodeContractsRedundantAssumptions> + <CodeContractsRunInBackground>True</CodeContractsRunInBackground> + <CodeContractsShowSquigglies>False</CodeContractsShowSquigglies> + <CodeContractsUseBaseLine>False</CodeContractsUseBaseLine> + <CodeContractsEmitXMLDocs>False</CodeContractsEmitXMLDocs> + <CodeContractsCustomRewriterAssembly /> + <CodeContractsCustomRewriterClass /> + <CodeContractsLibPaths /> + <CodeContractsExtraRewriteOptions /> + <CodeContractsExtraAnalysisOptions /> + <CodeContractsBaseLineFile /> + <CodeContractsCacheAnalysisResults>False</CodeContractsCacheAnalysisResults> + <CodeContractsRuntimeCheckingLevel>Full</CodeContractsRuntimeCheckingLevel> + <CodeContractsReferenceAssembly>Build</CodeContractsReferenceAssembly> + <CodeContractsAnalysisWarningLevel>0</CodeContractsAnalysisWarningLevel> + </PropertyGroup> + <ItemGroup> + <Reference Include="System" /> + <Reference Include="System.Core" /> + <Reference Include="System.Xml.Linq" /> + <Reference Include="System.Data.DataSetExtensions" /> + <Reference Include="Microsoft.CSharp" /> + <Reference Include="System.Data" /> + <Reference Include="System.Xml" /> + </ItemGroup> + <ItemGroup> + <Compile Include="ProverInterface.cs" /> + <Compile Include="..\..\version.cs" /> + <Compile Include="TPTPLineariser.cs" /> + <Compile Include="TypeDeclCollector.cs" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\..\AbsInt\AbsInt.csproj"> + <Project>{0EFA3E43-690B-48DC-A72C-384A3EA7F31F}</Project> + <Name>AbsInt</Name> + </ProjectReference> + <ProjectReference Include="..\..\AIFramework\AIFramework.csproj"> + <Project>{39B0658D-C955-41C5-9A43-48C97A1EF5FD}</Project> + <Name>AIFramework</Name> + </ProjectReference> + <ProjectReference Include="..\..\Basetypes\Basetypes.csproj"> + <Project>{43DFAD18-3E35-4558-9BE2-CAFF6B5BA8A0}</Project> + <Name>Basetypes</Name> + </ProjectReference> + <ProjectReference Include="..\..\CodeContractsExtender\CodeContractsExtender.csproj"> + <Project>{ACCC0156-0921-43ED-8F67-AD8BDC8CDE31}</Project> + <Name>CodeContractsExtender</Name> + </ProjectReference> + <ProjectReference Include="..\..\Core\Core.csproj"> + <Project>{B230A69C-C466-4065-B9C1-84D80E76D802}</Project> + <Name>Core</Name> + </ProjectReference> + <ProjectReference Include="..\..\VCExpr\VCExpr.csproj"> + <Project>{56FFDBCA-7D14-43B8-A6CA-22A20E417EE1}</Project> + <Name>VCExpr</Name> + </ProjectReference> + <ProjectReference Include="..\..\VCGeneration\VCGeneration.csproj"> + <Project>{E1F10180-C7B9-4147-B51F-FA1B701966DC}</Project> + <Name>VCGeneration</Name> + </ProjectReference> + </ItemGroup> + <ItemGroup> + <Folder Include="Properties\" /> + </ItemGroup> + <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> + <!-- To modify your build process, add your task inside one of the targets below and uncomment it. + Other similar extension points exist, see Microsoft.Common.targets. + <Target Name="BeforeBuild"> + </Target> + <Target Name="AfterBuild"> + </Target> + --> </Project>
\ No newline at end of file diff --git a/Source/Provers/TPTP/TPTPLineariser.cs b/Source/Provers/TPTP/TPTPLineariser.cs index a35d43f0..4bdf29b9 100644 --- a/Source/Provers/TPTP/TPTPLineariser.cs +++ b/Source/Provers/TPTP/TPTPLineariser.cs @@ -1,740 +1,740 @@ -//-----------------------------------------------------------------------------
-//
-// Copyright (C) Microsoft Corporation. All Rights Reserved.
-//
-//-----------------------------------------------------------------------------
-using System;
-using System.Text;
-using System.IO;
-using System.Collections;
-using System.Collections.Generic;
-using System.Diagnostics.Contracts;
-using Microsoft.Basetypes;
-using Microsoft.Boogie.VCExprAST;
-
-// Method to turn VCExprs into strings that can be fed into TPTP provers.
-// This is currently quite similar to the
-// SimplifyLikeLineariser (but the code is independent)
-
-namespace Microsoft.Boogie.TPTP
-{
-
- // Options for the linearisation
- public class LineariserOptions {
-
- public readonly bool AsTerm;
- public LineariserOptions SetAsTerm(bool newVal) {
- Contract.Ensures(Contract.Result<LineariserOptions>() != null);
-
- if (newVal)
- return DefaultTerm;
- else
- return Default;
- }
-
- internal LineariserOptions(bool asTerm) {
- this.AsTerm = asTerm;
- }
-
- [ContractInvariantMethod]
-void ObjectInvariant()
-{
- Contract.Invariant(Default!=null);
- Contract.Invariant(DefaultTerm!=null);
-}
-
- public static readonly LineariserOptions Default = new LineariserOptions (false);
- internal static readonly LineariserOptions DefaultTerm = new LineariserOptions (true);
- }
-
-
- ////////////////////////////////////////////////////////////////////////////////////////
-
- // Lineariser for expressions. The result (bool) is currently not used for anything
- public class TPTPExprLineariser : IVCExprVisitor<bool, LineariserOptions/*!*/> {
-
- public static string ToString(VCExpr e, UniqueNamer namer, TPTPProverOptions opts) {
- Contract.Requires(e != null);
- Contract.Requires(namer != null);
- Contract.Ensures(Contract.Result<string>() != null);
-
- StringWriter sw = new StringWriter();
- TPTPExprLineariser lin = new TPTPExprLineariser (sw, namer, opts);
- Contract.Assert(lin!=null);
- lin.Linearise(e, LineariserOptions.Default);
- return cce.NonNull(sw.ToString());
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////
-
- private readonly TextWriter wr;
- [ContractInvariantMethod]
-void ObjectInvariant()
-{
- Contract.Invariant(wr!=null);
- Contract.Invariant(Namer != null);
-}
-
- private TPTPOpLineariser OpLinObject = null;
- private IVCExprOpVisitor<bool, LineariserOptions>/*!>!*/ OpLineariser { get {
- Contract.Ensures(Contract.Result<IVCExprOpVisitor<bool,LineariserOptions>>() !=null);
-
- if (OpLinObject == null)
- OpLinObject = new TPTPOpLineariser(this, wr);
- return OpLinObject;
- } }
-
- internal readonly UniqueNamer Namer;
- internal readonly TPTPProverOptions Options;
-
- public TPTPExprLineariser(TextWriter wr, UniqueNamer namer, TPTPProverOptions opts) {
- Contract.Requires(wr != null);Contract.Requires(namer != null);
- this.wr = wr;
- this.Namer = namer;
- this.Options = opts;
- }
-
- public void Linearise(VCExpr expr, LineariserOptions options) {
- Contract.Requires(expr != null);
- Contract.Requires(options != null);
- expr.Accept<bool, LineariserOptions>(this, options);
- }
-
- public void LineariseAsTerm(VCExpr expr, LineariserOptions options) {
- Contract.Requires(expr != null);
- Contract.Requires(options != null);
- Linearise(expr, options.SetAsTerm(true));
- }
-
- /////////////////////////////////////////////////////////////////////////////////////
-
- public static string MakeIdPrintable(string s) {
- Contract.Requires(s != null);
- Contract.Ensures(Contract.Result<string>() != null);
-
- // make sure that no keywords are used as identifiers
- switch(s) {
- case andName:
- case orName:
- case notName:
- case impliesName:
- case iffName:
- case eqName:
- case TRUEName:
- case FALSEName:
- case "Array":
- s = "nonkeyword_" + s;
- break;
- }
-
- var res = new StringBuilder();
-
- foreach (char ch in s) {
- if (Char.IsLetterOrDigit(ch))
- res.Append(ch);
- else
- // replace everything else with a _
- res.Append('_');
- }
-
- return res.ToString();
- }
-
- public static string Lowercase(string s)
- {
- if (char.IsLower(s[0])) return MakeIdPrintable(s);
- else return MakeIdPrintable("x" + s);
- }
-
- /////////////////////////////////////////////////////////////////////////////////////
-
- internal const string andName = "&"; // conjunction
- internal const string orName = "|"; // disjunction
- internal const string notName = "~"; // negation
- internal const string impliesName = "=>"; // implication
- internal const string iteName = "$itef"; // if-then-else
- internal const string iffName = "<=>"; // logical equivalence
- internal const string eqName = "="; // equality
- internal const string lessName = "lt";
- internal const string greaterName = "gt";
- internal const string atmostName = "le";
- internal const string atleastName = "ge";
- internal const string TRUEName = "$true"; // nullary predicate that is always true
- internal const string FALSEName = "$false"; // nullary predicate that is always false
- internal const string subtypeName = "UOrdering2";
- internal const string subtypeArgsName = "UOrdering3";
-
- internal const string boolTrueName = "boolTrue";
- internal const string boolFalseName = "boolFalse";
- internal const string boolIteName = "ite";
- internal const string intAddName = "intAdd";
- internal const string intSubName = "intSub";
- internal const string intMulName = "intMul";
- internal const string intDivName = "boogieIntDiv";
- internal const string intModName = "boogieIntMod";
-
- internal void AssertAsTerm(string x, LineariserOptions options) {
- Contract.Requires(x != null);
- Contract.Requires(options != null);
- if (!options.AsTerm)
- System.Diagnostics.Debug.Fail("One should never write " + x + " as a formula!");
- }
-
- internal void AssertAsFormula(string x, LineariserOptions options) {
- Contract.Requires(x != null);
- Contract.Requires(options != null);
- if (options.AsTerm)
- System.Diagnostics.Debug.Fail("One should never write " + x + " as a term!");
- }
-
- /////////////////////////////////////////////////////////////////////////////////////
-
- public bool Visit(VCExprLiteral node, LineariserOptions options) {
- //Contract.Requires(node != null);
- //Contract.Requires(options != null);
- if (options.AsTerm) {
-
- if (node == VCExpressionGenerator.True)
- wr.Write("{0}", boolTrueName);
- else if (node == VCExpressionGenerator.False)
- wr.Write("{0}", boolFalseName);
- else if (node is VCExprIntLit) {
- BigNum lit = ((VCExprIntLit)node).Val;
- wr.Write(lit);
- } else {
- Contract.Assert(false);
- throw new cce.UnreachableException();
- }
-
- } else {
-
- if (node == VCExpressionGenerator.True)
- wr.Write("{0}", TRUEName);
- else if (node == VCExpressionGenerator.False)
- wr.Write("{0}", FALSEName);
- else if (node is VCExprIntLit) {
- System.Diagnostics.Debug.Fail("One should never write IntLit as a predicate!");
- } else
- {Contract.Assert(false); throw new cce.UnreachableException();}
-
- }
-
- return true;
- }
-
- /////////////////////////////////////////////////////////////////////////////////////
-
- public bool Visit(VCExprNAry node, LineariserOptions options) {
- //Contract.Requires(node != null);
- //Contract.Requires(options != null);
-
- VCExprOp op = node.Op;
- Contract.Assert(op!=null);
-
- if (!options.AsTerm &&
- (op.Equals(VCExpressionGenerator.AndOp) ||
- op.Equals(VCExpressionGenerator.OrOp))) {
- // handle these operators without recursion
-
- var sop = op.Equals(VCExpressionGenerator.AndOp) ? andName : orName;
- wr.Write("(");
- IEnumerator enumerator = new VCExprNAryUniformOpEnumerator (node);
- Contract.Assert(enumerator!=null);
- var cnt = 0;
- while (enumerator.MoveNext()) {
- VCExprNAry naryExpr = enumerator.Current as VCExprNAry;
- if (naryExpr == null || !naryExpr.Op.Equals(op)) {
- if (cnt > 0)
- wr.Write(" {0} ", sop);
- cnt++;
- Linearise(cce.NonNull((VCExpr)enumerator.Current), options);
- }
- }
-
- wr.Write(")");
-
- return true;
- }
-
- return node.Accept<bool, LineariserOptions/*!*/>(OpLineariser, options);
- }
-
- /////////////////////////////////////////////////////////////////////////////////////
-
- public bool Visit(VCExprVar node, LineariserOptions options) {
- //Contract.Requires(node != null);
- //Contract.Requires(options != null);
- string printedName = Namer.GetName(node, MakeIdPrintable(Lowercase(node.Name)));
- Contract.Assert(printedName!=null);
-
- if (options.AsTerm ||
- // formula variables are easy to identify in SMT-Lib
- printedName[0] == '$')
- wr.Write("{0}", printedName);
- else
- wr.Write("({0} = {1})", printedName, boolTrueName);
-
- return true;
- }
-
- /////////////////////////////////////////////////////////////////////////////////////
-
- public bool Visit(VCExprQuantifier node, LineariserOptions options) {
- //Contract.Requires(node != null);
- //Contract.Requires(options != null);
- AssertAsFormula(node.Quan.ToString(), options);
- Contract.Assert(node.TypeParameters.Count == 0);
-
- Namer.PushScope(); try {
-
- string kind = node.Quan == Quantifier.ALL ? "!" : "?";
- wr.Write("{0} [", kind);
-
- for (int i = 0; i < node.BoundVars.Count; i++)
- {
- VCExprVar var = node.BoundVars[i];
- Contract.Assert(var!=null);
- // ensure that the variable name starts with ?
- string printedName = Namer.GetLocalName(var, "V" + MakeIdPrintable(var.Name));
- Contract.Assert(printedName!=null);
- Contract.Assert(printedName[0] == 'V');
- if (i > 0) wr.Write(",");
- wr.Write("{0}", printedName);
- }
-
- wr.Write("] : (");
-
- /* if (options.QuantifierIds) {
- // only needed for Z3
- VCQuantifierInfos! infos = node.Infos;
- 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(") ");
- }
- } */
-
- Linearise(node.Body, options);
-
- // WriteTriggers(node.Triggers, options);
- wr.Write(")");
-
- return true;
-
- } finally {
- Namer.PopScope();
- }
- }
-
-
-
- /////////////////////////////////////////////////////////////////////////////////////
-
- public bool Visit(VCExprLet node, LineariserOptions options) {
- throw new NotImplementedException();
- }
-
- /////////////////////////////////////////////////////////////////////////////////////
-
- // Lineariser for operator terms. The result (bool) is currently not used for anything
- internal class TPTPOpLineariser : IVCExprOpVisitor<bool, LineariserOptions/*!*/> {
- private readonly TPTPExprLineariser ExprLineariser;
- private readonly TextWriter wr;
- [ContractInvariantMethod]
-void ObjectInvariant()
-{
- Contract.Invariant(wr!=null);
- Contract.Invariant(ExprLineariser!=null);
-}
-
-
- public TPTPOpLineariser(TPTPExprLineariser ExprLineariser, TextWriter wr) {
- Contract.Requires(ExprLineariser != null);
- Contract.Requires(wr != null);
- this.ExprLineariser = ExprLineariser;
- this.wr = wr;
- }
-
- ///////////////////////////////////////////////////////////////////////////////////
-
- private void WriteApplication(string op, IEnumerable<VCExpr/*!>!*/> args,
- LineariserOptions options) {
- Contract.Requires(op != null);
- Contract.Requires(cce.NonNullElements(args ));
- Contract.Requires(options != null);
- WriteApplication(op, args, options, options.AsTerm);
- }
-
- private void WriteTermApplication(string op, IEnumerable<VCExpr/*!>!*/> args,
- LineariserOptions options) {
- Contract.Requires(op != null);
- Contract.Requires(cce.NonNullElements(args ));
- Contract.Requires(options != null);
- ExprLineariser.AssertAsTerm(op, options);
- WriteApplication(op, args, options, options.AsTerm);
- }
-
-
- private void WriteApplication(string termOp,
- IEnumerable<VCExpr>/*!>!*/ args, LineariserOptions options,
- // change the AsTerm option for the arguments?
- bool argsAsTerms) {
- Contract.Requires(termOp != null);
- Contract.Requires(cce.NonNullElements(args ));
- Contract.Requires(options != null);
- LineariserOptions newOptions = options.SetAsTerm(argsAsTerms);
- Contract.Assert(newOptions!=null);
-
- var argCnt = 0;
- if (termOp == "~") {
- wr.Write("(~ ");
- foreach (var e in args) {
- ExprLineariser.Linearise(e, newOptions);
- argCnt++;
- }
- Contract.Assert(argCnt == 1);
- wr.Write(")");
- } else if ("&|~=><".IndexOf(termOp[0]) >= 0) {
- wr.Write("(");
- foreach (var e in args) {
- ExprLineariser.Linearise(e, newOptions);
- argCnt++;
- if (argCnt == 1) {
- wr.Write(" {0} ", termOp);
- }
- }
- Contract.Assert(argCnt == 2);
- wr.Write(")");
- } else {
- wr.Write(termOp);
- foreach (var e in args) {
- Contract.Assert(e != null);
- if (argCnt == 0)
- wr.Write("(");
- else
- wr.Write(", ");
- argCnt++;
- ExprLineariser.Linearise(e, newOptions);
- }
-
- if (argCnt > 0)
- wr.Write(")");
- }
- }
-
- // 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(termOp != null);
- Contract.Requires(cce.NonNullElements(args));
- Contract.Requires(options != null);
- if (!options.AsTerm)
- // Write: (EQ (f args) |@true|)
- // where "args" are written as terms
- wr.Write("(", eqName);
-
- WriteApplication(termOp, args, options, true);
-
- if (!options.AsTerm)
- wr.Write(" = {0})", boolTrueName);
- }
-
- ///////////////////////////////////////////////////////////////////////////////////
-
- public bool VisitNotOp (VCExprNAry node, LineariserOptions options) {
- //Contract.Requires(node != null);
- //Contract.Requires(options != null);
- WriteApplication(notName, node, options); // arguments can be both terms and formulas
- return true;
- }
-
- private bool PrintEq(VCExprNAry node, LineariserOptions options) {
- Contract.Requires(node != null);
- Contract.Requires(options != null);
- if (options.AsTerm) {
- throw new NotImplementedException();
- } else {
- if (node[0].Type.IsBool) {
- Contract.Assert(node[1].Type.IsBool);
- // use equivalence
- WriteApplication(iffName, node, options);
- } else {
- // use equality and write the arguments as terms
- WriteApplication(eqName, node, options, true);
- }
- }
-
- return true;
- }
-
- public bool VisitEqOp (VCExprNAry node, LineariserOptions options) {
- //Contract.Requires(node != null);
- //Contract.Requires(options != null);
- return PrintEq(node, options);
- }
-
- public bool VisitNeqOp (VCExprNAry node, LineariserOptions options) {
- //Contract.Requires(node != null);
- //Contract.Requires(options != null);
- wr.Write("(~ ");
- PrintEq(node, options);
- wr.Write(")");
- return true;
- }
-
- public bool VisitAndOp (VCExprNAry node, LineariserOptions options) {
- //Contract.Requires(node != null);
- //Contract.Requires(options != null);
- Contract.Assert(options.AsTerm);
- WriteApplication(andName, node, options);
- return true;
- }
-
- public bool VisitOrOp (VCExprNAry node, LineariserOptions options) {
- //Contract.Requires(node != null);
- //Contract.Requires(options != null);
-
- Contract.Assert(options.AsTerm);
- WriteApplication(orName, node, options);
- return true;
- }
-
- public bool VisitImpliesOp (VCExprNAry node, LineariserOptions options) {
- //Contract.Requires(node != null);
- //Contract.Requires(options != null);
-
- WriteApplication(impliesName, node, options);
- return true;
- }
-
- public bool VisitIfThenElseOp (VCExprNAry node, LineariserOptions options) {
- //Contract.Requires(node != null);
- //Contract.Requires(options != null);
- throw new NotImplementedException();
- }
-
- public bool VisitCustomOp(VCExprNAry node, LineariserOptions options) {
- //Contract.Requires(node != null);
- //Contract.Requires(options != null);
-
- VCExprCustomOp op = (VCExprCustomOp)node.Op;
- WriteApplicationTermOnly(op.Name, node, options);
- return true;
- }
-
- public bool VisitDistinctOp (VCExprNAry node, LineariserOptions options) {
- //Contract.Requires(node != null);
- //Contract.Requires(options != null);
-
- ExprLineariser.AssertAsFormula("distinct", options);
-
- if (node.Length < 2) {
- ExprLineariser.Linearise(VCExpressionGenerator.True, options);
- } else {
- var bits = 0;
- var cnt = node.Length;
- while (cnt > 0) {
- cnt >>= 1;
- bits++;
- }
-
- wr.Write("($true ");
- foreach (VCExpr e in node) {
- for (var i = 0; i < bits; ++i) {
- var neg = (cnt & (1 << i)) != 0 ? "~" : "";
- wr.Write(" & {0}distinct__f__{1}(", neg, i);
- ExprLineariser.LineariseAsTerm(e, options);
- wr.Write(")");
- }
- wr.WriteLine();
- cnt++;
- }
- wr.Write(")");
- }
-
- return true;
- }
-
- public bool VisitLabelOp (VCExprNAry node, LineariserOptions options) {
- //Contract.Requires(node != null);
- //Contract.Requires(options != null);
- //Contract.Requires(node.Length>=1);
- // VCExprLabelOp! op = (VCExprLabelOp)node.Op;
- // TODO
- // wr.Write(String.Format("({0} |{1}| ", op.pos ? "LBLPOS" : "LBLNEG", op.label));
- ExprLineariser.Linearise(node[0], options);
- // wr.Write(")");
- return true;
- }
-
- public bool VisitSelectOp(VCExprNAry node, LineariserOptions options)
- {
- //Contract.Requires(options != null);
- //Contract.Requires(node != null);
- var name = Lowercase(SimplifyLikeExprLineariser.SelectOpName(node));
- wr.Write(name + "(");
- var cnt = 0;
- foreach (VCExpr/*!*/ e in node) {
- Contract.Assert(e != null);
- if (cnt++ > 0)
- wr.Write(", ");
- ExprLineariser.Linearise(e, options.SetAsTerm(!e.Type.IsBool));
- }
- wr.Write(")");
- return true;
- }
-
- public bool VisitStoreOp(VCExprNAry node, LineariserOptions options)
- {
- //Contract.Requires(options != null);
- //Contract.Requires(node != null);
- var name = Lowercase(SimplifyLikeExprLineariser.StoreOpName(node));
- wr.Write(name + "(");
- var cnt = 0;
- foreach (VCExpr e in node) {
- Contract.Assert(e != null);
- if (cnt++ > 0)
- wr.Write(", ");
- ExprLineariser.Linearise(e, options.SetAsTerm(!e.Type.IsBool));
- }
- wr.Write(")");
- return true;
- }
-
- public bool VisitBvOp (VCExprNAry node, LineariserOptions options) {
- //Contract.Requires(node != null);
- //Contract.Requires(options != null);
-
- {Contract.Assert(false); throw new NotImplementedException();} // TODO
- }
-
- public bool VisitBvExtractOp(VCExprNAry node, LineariserOptions options) {
- //Contract.Requires(node != null);
- //Contract.Requires(options != null);
-
- {Contract.Assert(false); throw new NotImplementedException();} // TODO
- }
-
- public bool VisitBvConcatOp (VCExprNAry node, LineariserOptions options) {
- //Contract.Requires(node != null);
- //Contract.Requires(options != null);
-
- {Contract.Assert(false); throw new NotImplementedException();} // TODO
- }
-
- public bool VisitAddOp (VCExprNAry node, LineariserOptions options) {
- //Contract.Requires(node != null);
- //Contract.Requires(options != null);
-
- WriteTermApplication(intAddName, node, options);
- return true;
- }
-
- public bool VisitSubOp (VCExprNAry node, LineariserOptions options) {
- //Contract.Requires(node != null);
- //Contract.Requires(options != null);
-
- WriteTermApplication(intSubName, node, options);
- return true;
- }
-
- public bool VisitMulOp (VCExprNAry node, LineariserOptions options) {
- //Contract.Requires(node != null);
- //Contract.Requires(options != null);
-
- WriteTermApplication(intMulName, node, options);
- return true;
- }
-
- public bool VisitDivOp (VCExprNAry node, LineariserOptions options) {
- //Contract.Requires(node != null);
- //Contract.Requires(options != null);
-
- WriteTermApplication(intDivName, node, options);
- return true;
- }
-
- public bool VisitModOp (VCExprNAry node, LineariserOptions options) {
- //Contract.Requires(node != null);
- //Contract.Requires(options != null);
-
- WriteTermApplication(intModName, node, options);
- return true;
- }
-
- public bool VisitLtOp (VCExprNAry node, LineariserOptions options) {
- //Contract.Requires(node != null);
- //Contract.Requires(options != null);
-
- WriteApplication(lessName, node, options, true); // arguments are always terms
- return true;
- }
-
- public bool VisitLeOp (VCExprNAry node, LineariserOptions options) {
- //Contract.Requires(node != null);
- //Contract.Requires(options != null);
-
- WriteApplication(atmostName, node, options, true); // arguments are always terms
- return true;
- }
-
- public bool VisitGtOp (VCExprNAry node, LineariserOptions options) {
- //Contract.Requires(node != null);
- //Contract.Requires(options != null);
-
- WriteApplication(greaterName, node, options, true); // arguments are always terms
- return true;
- }
-
- public bool VisitGeOp (VCExprNAry node, LineariserOptions options) {
- //Contract.Requires(node != null);
- //Contract.Requires(options != null);
-
- WriteApplication(atleastName, node, options, true); // arguments are always terms
- return true;
- }
-
- public bool VisitSubtypeOp (VCExprNAry node, LineariserOptions options) {
- //Contract.Requires(node != null);
- //Contract.Requires(options != null);
-
- WriteApplication(subtypeName, node, options, true); // arguments are always terms
- return true;
- }
-
- public bool VisitSubtype3Op (VCExprNAry node, LineariserOptions options) {
- //Contract.Requires(node != null);
- //Contract.Requires(options != null);
-
- WriteApplication(subtypeArgsName, node, options, true); // arguments are always terms
- return true;
- }
-
- public bool VisitBoogieFunctionOp (VCExprNAry node, LineariserOptions options) {
- //Contract.Requires(node != null);
- //Contract.Requires(options != null);
-
- VCExprBoogieFunctionOp op = (VCExprBoogieFunctionOp)node.Op;
- Contract.Assert(op!=null);
- string printedName = ExprLineariser.Namer.GetName(op.Func, Lowercase(op.Func.Name));
- Contract.Assert(printedName!=null);
-
- if (ExprLineariser.Options.UsePredicates && op.Func.OutParams[0].TypedIdent.Type.IsBool)
- WriteApplication(printedName, node, options, true);
- else
- // arguments are always terms
- WriteApplicationTermOnly(printedName, node, options);
- return true;
- }
-
- }
- }
-
-}
+//----------------------------------------------------------------------------- +// +// Copyright (C) Microsoft Corporation. All Rights Reserved. +// +//----------------------------------------------------------------------------- +using System; +using System.Text; +using System.IO; +using System.Collections; +using System.Collections.Generic; +using System.Diagnostics.Contracts; +using Microsoft.Basetypes; +using Microsoft.Boogie.VCExprAST; + +// Method to turn VCExprs into strings that can be fed into TPTP provers. +// This is currently quite similar to the +// SimplifyLikeLineariser (but the code is independent) + +namespace Microsoft.Boogie.TPTP +{ + + // Options for the linearisation + public class LineariserOptions { + + public readonly bool AsTerm; + public LineariserOptions SetAsTerm(bool newVal) { + Contract.Ensures(Contract.Result<LineariserOptions>() != null); + + if (newVal) + return DefaultTerm; + else + return Default; + } + + internal LineariserOptions(bool asTerm) { + this.AsTerm = asTerm; + } + + [ContractInvariantMethod] +void ObjectInvariant() +{ + Contract.Invariant(Default!=null); + Contract.Invariant(DefaultTerm!=null); +} + + public static readonly LineariserOptions Default = new LineariserOptions (false); + internal static readonly LineariserOptions DefaultTerm = new LineariserOptions (true); + } + + + //////////////////////////////////////////////////////////////////////////////////////// + + // Lineariser for expressions. The result (bool) is currently not used for anything + public class TPTPExprLineariser : IVCExprVisitor<bool, LineariserOptions/*!*/> { + + public static string ToString(VCExpr e, UniqueNamer namer, TPTPProverOptions opts) { + Contract.Requires(e != null); + Contract.Requires(namer != null); + Contract.Ensures(Contract.Result<string>() != null); + + StringWriter sw = new StringWriter(); + TPTPExprLineariser lin = new TPTPExprLineariser (sw, namer, opts); + Contract.Assert(lin!=null); + lin.Linearise(e, LineariserOptions.Default); + return cce.NonNull(sw.ToString()); + } + + //////////////////////////////////////////////////////////////////////////////////////// + + private readonly TextWriter wr; + [ContractInvariantMethod] +void ObjectInvariant() +{ + Contract.Invariant(wr!=null); + Contract.Invariant(Namer != null); +} + + private TPTPOpLineariser OpLinObject = null; + private IVCExprOpVisitor<bool, LineariserOptions>/*!>!*/ OpLineariser { get { + Contract.Ensures(Contract.Result<IVCExprOpVisitor<bool,LineariserOptions>>() !=null); + + if (OpLinObject == null) + OpLinObject = new TPTPOpLineariser(this, wr); + return OpLinObject; + } } + + internal readonly UniqueNamer Namer; + internal readonly TPTPProverOptions Options; + + public TPTPExprLineariser(TextWriter wr, UniqueNamer namer, TPTPProverOptions opts) { + Contract.Requires(wr != null);Contract.Requires(namer != null); + this.wr = wr; + this.Namer = namer; + this.Options = opts; + } + + public void Linearise(VCExpr expr, LineariserOptions options) { + Contract.Requires(expr != null); + Contract.Requires(options != null); + expr.Accept<bool, LineariserOptions>(this, options); + } + + public void LineariseAsTerm(VCExpr expr, LineariserOptions options) { + Contract.Requires(expr != null); + Contract.Requires(options != null); + Linearise(expr, options.SetAsTerm(true)); + } + + ///////////////////////////////////////////////////////////////////////////////////// + + public static string MakeIdPrintable(string s) { + Contract.Requires(s != null); + Contract.Ensures(Contract.Result<string>() != null); + + // make sure that no keywords are used as identifiers + switch(s) { + case andName: + case orName: + case notName: + case impliesName: + case iffName: + case eqName: + case TRUEName: + case FALSEName: + case "Array": + s = "nonkeyword_" + s; + break; + } + + var res = new StringBuilder(); + + foreach (char ch in s) { + if (Char.IsLetterOrDigit(ch)) + res.Append(ch); + else + // replace everything else with a _ + res.Append('_'); + } + + return res.ToString(); + } + + public static string Lowercase(string s) + { + if (char.IsLower(s[0])) return MakeIdPrintable(s); + else return MakeIdPrintable("x" + s); + } + + ///////////////////////////////////////////////////////////////////////////////////// + + internal const string andName = "&"; // conjunction + internal const string orName = "|"; // disjunction + internal const string notName = "~"; // negation + internal const string impliesName = "=>"; // implication + internal const string iteName = "$itef"; // if-then-else + internal const string iffName = "<=>"; // logical equivalence + internal const string eqName = "="; // equality + internal const string lessName = "lt"; + internal const string greaterName = "gt"; + internal const string atmostName = "le"; + internal const string atleastName = "ge"; + internal const string TRUEName = "$true"; // nullary predicate that is always true + internal const string FALSEName = "$false"; // nullary predicate that is always false + internal const string subtypeName = "UOrdering2"; + internal const string subtypeArgsName = "UOrdering3"; + + internal const string boolTrueName = "boolTrue"; + internal const string boolFalseName = "boolFalse"; + internal const string boolIteName = "ite"; + internal const string intAddName = "intAdd"; + internal const string intSubName = "intSub"; + internal const string intMulName = "intMul"; + internal const string intDivName = "boogieIntDiv"; + internal const string intModName = "boogieIntMod"; + + internal void AssertAsTerm(string x, LineariserOptions options) { + Contract.Requires(x != null); + Contract.Requires(options != null); + if (!options.AsTerm) + System.Diagnostics.Debug.Fail("One should never write " + x + " as a formula!"); + } + + internal void AssertAsFormula(string x, LineariserOptions options) { + Contract.Requires(x != null); + Contract.Requires(options != null); + if (options.AsTerm) + System.Diagnostics.Debug.Fail("One should never write " + x + " as a term!"); + } + + ///////////////////////////////////////////////////////////////////////////////////// + + public bool Visit(VCExprLiteral node, LineariserOptions options) { + //Contract.Requires(node != null); + //Contract.Requires(options != null); + if (options.AsTerm) { + + if (node == VCExpressionGenerator.True) + wr.Write("{0}", boolTrueName); + else if (node == VCExpressionGenerator.False) + wr.Write("{0}", boolFalseName); + else if (node is VCExprIntLit) { + BigNum lit = ((VCExprIntLit)node).Val; + wr.Write(lit); + } else { + Contract.Assert(false); + throw new cce.UnreachableException(); + } + + } else { + + if (node == VCExpressionGenerator.True) + wr.Write("{0}", TRUEName); + else if (node == VCExpressionGenerator.False) + wr.Write("{0}", FALSEName); + else if (node is VCExprIntLit) { + System.Diagnostics.Debug.Fail("One should never write IntLit as a predicate!"); + } else + {Contract.Assert(false); throw new cce.UnreachableException();} + + } + + return true; + } + + ///////////////////////////////////////////////////////////////////////////////////// + + public bool Visit(VCExprNAry node, LineariserOptions options) { + //Contract.Requires(node != null); + //Contract.Requires(options != null); + + VCExprOp op = node.Op; + Contract.Assert(op!=null); + + if (!options.AsTerm && + (op.Equals(VCExpressionGenerator.AndOp) || + op.Equals(VCExpressionGenerator.OrOp))) { + // handle these operators without recursion + + var sop = op.Equals(VCExpressionGenerator.AndOp) ? andName : orName; + wr.Write("("); + IEnumerator enumerator = new VCExprNAryUniformOpEnumerator (node); + Contract.Assert(enumerator!=null); + var cnt = 0; + while (enumerator.MoveNext()) { + VCExprNAry naryExpr = enumerator.Current as VCExprNAry; + if (naryExpr == null || !naryExpr.Op.Equals(op)) { + if (cnt > 0) + wr.Write(" {0} ", sop); + cnt++; + Linearise(cce.NonNull((VCExpr)enumerator.Current), options); + } + } + + wr.Write(")"); + + return true; + } + + return node.Accept<bool, LineariserOptions/*!*/>(OpLineariser, options); + } + + ///////////////////////////////////////////////////////////////////////////////////// + + public bool Visit(VCExprVar node, LineariserOptions options) { + //Contract.Requires(node != null); + //Contract.Requires(options != null); + string printedName = Namer.GetName(node, MakeIdPrintable(Lowercase(node.Name))); + Contract.Assert(printedName!=null); + + if (options.AsTerm || + // formula variables are easy to identify in SMT-Lib + printedName[0] == '$') + wr.Write("{0}", printedName); + else + wr.Write("({0} = {1})", printedName, boolTrueName); + + return true; + } + + ///////////////////////////////////////////////////////////////////////////////////// + + public bool Visit(VCExprQuantifier node, LineariserOptions options) { + //Contract.Requires(node != null); + //Contract.Requires(options != null); + AssertAsFormula(node.Quan.ToString(), options); + Contract.Assert(node.TypeParameters.Count == 0); + + Namer.PushScope(); try { + + string kind = node.Quan == Quantifier.ALL ? "!" : "?"; + wr.Write("{0} [", kind); + + for (int i = 0; i < node.BoundVars.Count; i++) + { + VCExprVar var = node.BoundVars[i]; + Contract.Assert(var!=null); + // ensure that the variable name starts with ? + string printedName = Namer.GetLocalName(var, "V" + MakeIdPrintable(var.Name)); + Contract.Assert(printedName!=null); + Contract.Assert(printedName[0] == 'V'); + if (i > 0) wr.Write(","); + wr.Write("{0}", printedName); + } + + wr.Write("] : ("); + + /* if (options.QuantifierIds) { + // only needed for Z3 + VCQuantifierInfos! infos = node.Infos; + 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(") "); + } + } */ + + Linearise(node.Body, options); + + // WriteTriggers(node.Triggers, options); + wr.Write(")"); + + return true; + + } finally { + Namer.PopScope(); + } + } + + + + ///////////////////////////////////////////////////////////////////////////////////// + + public bool Visit(VCExprLet node, LineariserOptions options) { + throw new NotImplementedException(); + } + + ///////////////////////////////////////////////////////////////////////////////////// + + // Lineariser for operator terms. The result (bool) is currently not used for anything + internal class TPTPOpLineariser : IVCExprOpVisitor<bool, LineariserOptions/*!*/> { + private readonly TPTPExprLineariser ExprLineariser; + private readonly TextWriter wr; + [ContractInvariantMethod] +void ObjectInvariant() +{ + Contract.Invariant(wr!=null); + Contract.Invariant(ExprLineariser!=null); +} + + + public TPTPOpLineariser(TPTPExprLineariser ExprLineariser, TextWriter wr) { + Contract.Requires(ExprLineariser != null); + Contract.Requires(wr != null); + this.ExprLineariser = ExprLineariser; + this.wr = wr; + } + + /////////////////////////////////////////////////////////////////////////////////// + + private void WriteApplication(string op, IEnumerable<VCExpr/*!>!*/> args, + LineariserOptions options) { + Contract.Requires(op != null); + Contract.Requires(cce.NonNullElements(args )); + Contract.Requires(options != null); + WriteApplication(op, args, options, options.AsTerm); + } + + private void WriteTermApplication(string op, IEnumerable<VCExpr/*!>!*/> args, + LineariserOptions options) { + Contract.Requires(op != null); + Contract.Requires(cce.NonNullElements(args )); + Contract.Requires(options != null); + ExprLineariser.AssertAsTerm(op, options); + WriteApplication(op, args, options, options.AsTerm); + } + + + private void WriteApplication(string termOp, + IEnumerable<VCExpr>/*!>!*/ args, LineariserOptions options, + // change the AsTerm option for the arguments? + bool argsAsTerms) { + Contract.Requires(termOp != null); + Contract.Requires(cce.NonNullElements(args )); + Contract.Requires(options != null); + LineariserOptions newOptions = options.SetAsTerm(argsAsTerms); + Contract.Assert(newOptions!=null); + + var argCnt = 0; + if (termOp == "~") { + wr.Write("(~ "); + foreach (var e in args) { + ExprLineariser.Linearise(e, newOptions); + argCnt++; + } + Contract.Assert(argCnt == 1); + wr.Write(")"); + } else if ("&|~=><".IndexOf(termOp[0]) >= 0) { + wr.Write("("); + foreach (var e in args) { + ExprLineariser.Linearise(e, newOptions); + argCnt++; + if (argCnt == 1) { + wr.Write(" {0} ", termOp); + } + } + Contract.Assert(argCnt == 2); + wr.Write(")"); + } else { + wr.Write(termOp); + foreach (var e in args) { + Contract.Assert(e != null); + if (argCnt == 0) + wr.Write("("); + else + wr.Write(", "); + argCnt++; + ExprLineariser.Linearise(e, newOptions); + } + + if (argCnt > 0) + wr.Write(")"); + } + } + + // 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(termOp != null); + Contract.Requires(cce.NonNullElements(args)); + Contract.Requires(options != null); + if (!options.AsTerm) + // Write: (EQ (f args) |@true|) + // where "args" are written as terms + wr.Write("(", eqName); + + WriteApplication(termOp, args, options, true); + + if (!options.AsTerm) + wr.Write(" = {0})", boolTrueName); + } + + /////////////////////////////////////////////////////////////////////////////////// + + public bool VisitNotOp (VCExprNAry node, LineariserOptions options) { + //Contract.Requires(node != null); + //Contract.Requires(options != null); + WriteApplication(notName, node, options); // arguments can be both terms and formulas + return true; + } + + private bool PrintEq(VCExprNAry node, LineariserOptions options) { + Contract.Requires(node != null); + Contract.Requires(options != null); + if (options.AsTerm) { + throw new NotImplementedException(); + } else { + if (node[0].Type.IsBool) { + Contract.Assert(node[1].Type.IsBool); + // use equivalence + WriteApplication(iffName, node, options); + } else { + // use equality and write the arguments as terms + WriteApplication(eqName, node, options, true); + } + } + + return true; + } + + public bool VisitEqOp (VCExprNAry node, LineariserOptions options) { + //Contract.Requires(node != null); + //Contract.Requires(options != null); + return PrintEq(node, options); + } + + public bool VisitNeqOp (VCExprNAry node, LineariserOptions options) { + //Contract.Requires(node != null); + //Contract.Requires(options != null); + wr.Write("(~ "); + PrintEq(node, options); + wr.Write(")"); + return true; + } + + public bool VisitAndOp (VCExprNAry node, LineariserOptions options) { + //Contract.Requires(node != null); + //Contract.Requires(options != null); + Contract.Assert(options.AsTerm); + WriteApplication(andName, node, options); + return true; + } + + public bool VisitOrOp (VCExprNAry node, LineariserOptions options) { + //Contract.Requires(node != null); + //Contract.Requires(options != null); + + Contract.Assert(options.AsTerm); + WriteApplication(orName, node, options); + return true; + } + + public bool VisitImpliesOp (VCExprNAry node, LineariserOptions options) { + //Contract.Requires(node != null); + //Contract.Requires(options != null); + + WriteApplication(impliesName, node, options); + return true; + } + + public bool VisitIfThenElseOp (VCExprNAry node, LineariserOptions options) { + //Contract.Requires(node != null); + //Contract.Requires(options != null); + throw new NotImplementedException(); + } + + public bool VisitCustomOp(VCExprNAry node, LineariserOptions options) { + //Contract.Requires(node != null); + //Contract.Requires(options != null); + + VCExprCustomOp op = (VCExprCustomOp)node.Op; + WriteApplicationTermOnly(op.Name, node, options); + return true; + } + + public bool VisitDistinctOp (VCExprNAry node, LineariserOptions options) { + //Contract.Requires(node != null); + //Contract.Requires(options != null); + + ExprLineariser.AssertAsFormula("distinct", options); + + if (node.Length < 2) { + ExprLineariser.Linearise(VCExpressionGenerator.True, options); + } else { + var bits = 0; + var cnt = node.Length; + while (cnt > 0) { + cnt >>= 1; + bits++; + } + + wr.Write("($true "); + foreach (VCExpr e in node) { + for (var i = 0; i < bits; ++i) { + var neg = (cnt & (1 << i)) != 0 ? "~" : ""; + wr.Write(" & {0}distinct__f__{1}(", neg, i); + ExprLineariser.LineariseAsTerm(e, options); + wr.Write(")"); + } + wr.WriteLine(); + cnt++; + } + wr.Write(")"); + } + + return true; + } + + public bool VisitLabelOp (VCExprNAry node, LineariserOptions options) { + //Contract.Requires(node != null); + //Contract.Requires(options != null); + //Contract.Requires(node.Length>=1); + // VCExprLabelOp! op = (VCExprLabelOp)node.Op; + // TODO + // wr.Write(String.Format("({0} |{1}| ", op.pos ? "LBLPOS" : "LBLNEG", op.label)); + ExprLineariser.Linearise(node[0], options); + // wr.Write(")"); + return true; + } + + public bool VisitSelectOp(VCExprNAry node, LineariserOptions options) + { + //Contract.Requires(options != null); + //Contract.Requires(node != null); + var name = Lowercase(SimplifyLikeExprLineariser.SelectOpName(node)); + wr.Write(name + "("); + var cnt = 0; + foreach (VCExpr/*!*/ e in node) { + Contract.Assert(e != null); + if (cnt++ > 0) + wr.Write(", "); + ExprLineariser.Linearise(e, options.SetAsTerm(!e.Type.IsBool)); + } + wr.Write(")"); + return true; + } + + public bool VisitStoreOp(VCExprNAry node, LineariserOptions options) + { + //Contract.Requires(options != null); + //Contract.Requires(node != null); + var name = Lowercase(SimplifyLikeExprLineariser.StoreOpName(node)); + wr.Write(name + "("); + var cnt = 0; + foreach (VCExpr e in node) { + Contract.Assert(e != null); + if (cnt++ > 0) + wr.Write(", "); + ExprLineariser.Linearise(e, options.SetAsTerm(!e.Type.IsBool)); + } + wr.Write(")"); + return true; + } + + public bool VisitBvOp (VCExprNAry node, LineariserOptions options) { + //Contract.Requires(node != null); + //Contract.Requires(options != null); + + {Contract.Assert(false); throw new NotImplementedException();} // TODO + } + + public bool VisitBvExtractOp(VCExprNAry node, LineariserOptions options) { + //Contract.Requires(node != null); + //Contract.Requires(options != null); + + {Contract.Assert(false); throw new NotImplementedException();} // TODO + } + + public bool VisitBvConcatOp (VCExprNAry node, LineariserOptions options) { + //Contract.Requires(node != null); + //Contract.Requires(options != null); + + {Contract.Assert(false); throw new NotImplementedException();} // TODO + } + + public bool VisitAddOp (VCExprNAry node, LineariserOptions options) { + //Contract.Requires(node != null); + //Contract.Requires(options != null); + + WriteTermApplication(intAddName, node, options); + return true; + } + + public bool VisitSubOp (VCExprNAry node, LineariserOptions options) { + //Contract.Requires(node != null); + //Contract.Requires(options != null); + + WriteTermApplication(intSubName, node, options); + return true; + } + + public bool VisitMulOp (VCExprNAry node, LineariserOptions options) { + //Contract.Requires(node != null); + //Contract.Requires(options != null); + + WriteTermApplication(intMulName, node, options); + return true; + } + + public bool VisitDivOp (VCExprNAry node, LineariserOptions options) { + //Contract.Requires(node != null); + //Contract.Requires(options != null); + + WriteTermApplication(intDivName, node, options); + return true; + } + + public bool VisitModOp (VCExprNAry node, LineariserOptions options) { + //Contract.Requires(node != null); + //Contract.Requires(options != null); + + WriteTermApplication(intModName, node, options); + return true; + } + + public bool VisitLtOp (VCExprNAry node, LineariserOptions options) { + //Contract.Requires(node != null); + //Contract.Requires(options != null); + + WriteApplication(lessName, node, options, true); // arguments are always terms + return true; + } + + public bool VisitLeOp (VCExprNAry node, LineariserOptions options) { + //Contract.Requires(node != null); + //Contract.Requires(options != null); + + WriteApplication(atmostName, node, options, true); // arguments are always terms + return true; + } + + public bool VisitGtOp (VCExprNAry node, LineariserOptions options) { + //Contract.Requires(node != null); + //Contract.Requires(options != null); + + WriteApplication(greaterName, node, options, true); // arguments are always terms + return true; + } + + public bool VisitGeOp (VCExprNAry node, LineariserOptions options) { + //Contract.Requires(node != null); + //Contract.Requires(options != null); + + WriteApplication(atleastName, node, options, true); // arguments are always terms + return true; + } + + public bool VisitSubtypeOp (VCExprNAry node, LineariserOptions options) { + //Contract.Requires(node != null); + //Contract.Requires(options != null); + + WriteApplication(subtypeName, node, options, true); // arguments are always terms + return true; + } + + public bool VisitSubtype3Op (VCExprNAry node, LineariserOptions options) { + //Contract.Requires(node != null); + //Contract.Requires(options != null); + + WriteApplication(subtypeArgsName, node, options, true); // arguments are always terms + return true; + } + + public bool VisitBoogieFunctionOp (VCExprNAry node, LineariserOptions options) { + //Contract.Requires(node != null); + //Contract.Requires(options != null); + + VCExprBoogieFunctionOp op = (VCExprBoogieFunctionOp)node.Op; + Contract.Assert(op!=null); + string printedName = ExprLineariser.Namer.GetName(op.Func, Lowercase(op.Func.Name)); + Contract.Assert(printedName!=null); + + if (ExprLineariser.Options.UsePredicates && op.Func.OutParams[0].TypedIdent.Type.IsBool) + WriteApplication(printedName, node, options, true); + else + // arguments are always terms + WriteApplicationTermOnly(printedName, node, options); + return true; + } + + } + } + +} diff --git a/Source/Provers/TPTP/TypeDeclCollector.cs b/Source/Provers/TPTP/TypeDeclCollector.cs index b7495659..1daf19a5 100644 --- a/Source/Provers/TPTP/TypeDeclCollector.cs +++ b/Source/Provers/TPTP/TypeDeclCollector.cs @@ -1,136 +1,136 @@ -//-----------------------------------------------------------------------------
-//
-// Copyright (C) Microsoft Corporation. All Rights Reserved.
-//
-//-----------------------------------------------------------------------------
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Diagnostics.Contracts;
-using Microsoft.Boogie.VCExprAST;
-
-namespace Microsoft.Boogie.TPTP
-{
- // Visitor for collecting the occurring function symbols in a VCExpr,
- // and for creating the corresponding declarations
-
- public class TypeDeclCollector : BoundVarTraversingVCExprVisitor<bool, bool> {
-
- private readonly HashSet<string/*!*/>/*!*/ KnownStoreFunctions = new HashSet<string>();
- private readonly HashSet<string/*!*/>/*!*/ KnownSelectFunctions = new HashSet<string>();
-
- private readonly UniqueNamer Namer;
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(Namer != null);
- Contract.Invariant(AllDecls != null);
- Contract.Invariant(IncDecls != null);
- Contract.Invariant(cce.NonNull(KnownFunctions));
- Contract.Invariant(cce.NonNull(KnownVariables));
- }
-
-
- public TypeDeclCollector(UniqueNamer namer) {
- Contract.Requires(namer != null);
- this.Namer = namer;
- }
-
- // not used
- protected override bool StandardResult(VCExpr node, bool arg) {
- //Contract.Requires(node != null);
- return true;
- }
-
- private readonly List<string/*!>!*/> AllDecls = new List<string/*!*/> ();
- private readonly List<string/*!>!*/> IncDecls = new List<string/*!*/> ();
-
- private readonly HashSet<Function/*!*/>/*!*/ KnownFunctions = new HashSet<Function/*!*/>();
- private readonly HashSet<VCExprVar/*!*/>/*!*/ KnownVariables = new HashSet<VCExprVar/*!*/>();
-
- public List<string/*!>!*/> AllDeclarations { get {
- Contract.Ensures(cce.NonNullElements(Contract.Result<List<string>>() ));
-
- List<string>/*!>!*/ res = new List<string/*!*/> ();
- res.AddRange(AllDecls);
- return res;
- } }
-
- public List<string/*!>!*/> GetNewDeclarations() {
- Contract.Ensures(cce.NonNullElements(Contract.Result<List<string>>() ));
- List<string>/*!>!*/ res = new List<string/*!*/>();
- res.AddRange(IncDecls);
- IncDecls.Clear();
- return res;
- }
-
- private void AddDeclaration(string decl) {
- Contract.Requires(decl != null);
- AllDecls.Add(decl);
- IncDecls.Add(decl);
- }
-
- public void Collect(VCExpr expr) {
- Contract.Requires(expr != null);
- Traverse(expr, true);
- }
-
- ///////////////////////////////////////////////////////////////////////////
-
-
- public override bool Visit(VCExprNAry node, bool arg) {
- Contract.Requires(node != null);
-
- if (node.Op is VCExprStoreOp) {
- string name = TPTPExprLineariser.Lowercase(SimplifyLikeExprLineariser.StoreOpName(node));
- if (!KnownStoreFunctions.Contains(name)) {
- var id = KnownStoreFunctions.Count;
-
- if (CommandLineOptions.Clo.MonomorphicArrays) {
- var sel = TPTPExprLineariser.Lowercase(SimplifyLikeExprLineariser.SelectOpName(node));
-
- var eq = "=";
- if (node[node.Arity - 1].Type.IsBool)
- eq = "<=>";
-
- string xS = "", yS = "";
- string dist = "";
-
- for (int i = 0; i < node.Arity - 2; i++) {
- if (i != 0) {
- dist += " | ";
- xS += ",";
- yS += ",";
- }
- var x = "X" + i;
- var y = "Y" + i;
- xS += x;
- yS += y;
- dist += string.Format("({0} != {1})", x, y);
- }
-
- string ax1 = "fof(selectEq" + id + ", axiom, ! [M,V," + xS + "] : (" +
- string.Format("{0}({1}(M,{2},V),{2}) {3} V", sel, name, xS, eq) + ")).";
- string ax2 = "fof(selectNeq" + id + ", axiom, ! [M,V," + xS + "," + yS + "] : (" +
- string.Format("( {0} ) => ", dist) +
- string.Format("{0}({1}(M,{2},V),{3}) {4} {0}(M,{3})", sel, name, xS, yS, eq) + ")).";
-
- AddDeclaration(ax1);
- AddDeclaration(ax2);
- }
-
- KnownStoreFunctions.Add(name);
- }
- //
- }
-
- return base.Visit(node, arg);
- }
-
- public override bool Visit(VCExprVar node, bool arg) {
-
- return base.Visit(node, arg);
- }
- }
-
+//----------------------------------------------------------------------------- +// +// Copyright (C) Microsoft Corporation. All Rights Reserved. +// +//----------------------------------------------------------------------------- +using System; +using System.Collections; +using System.Collections.Generic; +using System.Diagnostics; +using System.Diagnostics.Contracts; +using Microsoft.Boogie.VCExprAST; + +namespace Microsoft.Boogie.TPTP +{ + // Visitor for collecting the occurring function symbols in a VCExpr, + // and for creating the corresponding declarations + + public class TypeDeclCollector : BoundVarTraversingVCExprVisitor<bool, bool> { + + private readonly HashSet<string/*!*/>/*!*/ KnownStoreFunctions = new HashSet<string>(); + private readonly HashSet<string/*!*/>/*!*/ KnownSelectFunctions = new HashSet<string>(); + + private readonly UniqueNamer Namer; + [ContractInvariantMethod] + void ObjectInvariant() { + Contract.Invariant(Namer != null); + Contract.Invariant(AllDecls != null); + Contract.Invariant(IncDecls != null); + Contract.Invariant(cce.NonNull(KnownFunctions)); + Contract.Invariant(cce.NonNull(KnownVariables)); + } + + + public TypeDeclCollector(UniqueNamer namer) { + Contract.Requires(namer != null); + this.Namer = namer; + } + + // not used + protected override bool StandardResult(VCExpr node, bool arg) { + //Contract.Requires(node != null); + return true; + } + + private readonly List<string/*!>!*/> AllDecls = new List<string/*!*/> (); + private readonly List<string/*!>!*/> IncDecls = new List<string/*!*/> (); + + private readonly HashSet<Function/*!*/>/*!*/ KnownFunctions = new HashSet<Function/*!*/>(); + private readonly HashSet<VCExprVar/*!*/>/*!*/ KnownVariables = new HashSet<VCExprVar/*!*/>(); + + public List<string/*!>!*/> AllDeclarations { get { + Contract.Ensures(cce.NonNullElements(Contract.Result<List<string>>() )); + + List<string>/*!>!*/ res = new List<string/*!*/> (); + res.AddRange(AllDecls); + return res; + } } + + public List<string/*!>!*/> GetNewDeclarations() { + Contract.Ensures(cce.NonNullElements(Contract.Result<List<string>>() )); + List<string>/*!>!*/ res = new List<string/*!*/>(); + res.AddRange(IncDecls); + IncDecls.Clear(); + return res; + } + + private void AddDeclaration(string decl) { + Contract.Requires(decl != null); + AllDecls.Add(decl); + IncDecls.Add(decl); + } + + public void Collect(VCExpr expr) { + Contract.Requires(expr != null); + Traverse(expr, true); + } + + /////////////////////////////////////////////////////////////////////////// + + + public override bool Visit(VCExprNAry node, bool arg) { + Contract.Requires(node != null); + + if (node.Op is VCExprStoreOp) { + string name = TPTPExprLineariser.Lowercase(SimplifyLikeExprLineariser.StoreOpName(node)); + if (!KnownStoreFunctions.Contains(name)) { + var id = KnownStoreFunctions.Count; + + if (CommandLineOptions.Clo.MonomorphicArrays) { + var sel = TPTPExprLineariser.Lowercase(SimplifyLikeExprLineariser.SelectOpName(node)); + + var eq = "="; + if (node[node.Arity - 1].Type.IsBool) + eq = "<=>"; + + string xS = "", yS = ""; + string dist = ""; + + for (int i = 0; i < node.Arity - 2; i++) { + if (i != 0) { + dist += " | "; + xS += ","; + yS += ","; + } + var x = "X" + i; + var y = "Y" + i; + xS += x; + yS += y; + dist += string.Format("({0} != {1})", x, y); + } + + string ax1 = "fof(selectEq" + id + ", axiom, ! [M,V," + xS + "] : (" + + string.Format("{0}({1}(M,{2},V),{2}) {3} V", sel, name, xS, eq) + "))."; + string ax2 = "fof(selectNeq" + id + ", axiom, ! [M,V," + xS + "," + yS + "] : (" + + string.Format("( {0} ) => ", dist) + + string.Format("{0}({1}(M,{2},V),{3}) {4} {0}(M,{3})", sel, name, xS, yS, eq) + "))."; + + AddDeclaration(ax1); + AddDeclaration(ax2); + } + + KnownStoreFunctions.Add(name); + } + // + } + + return base.Visit(node, arg); + } + + public override bool Visit(VCExprVar node, bool arg) { + + return base.Visit(node, arg); + } + } + }
\ No newline at end of file diff --git a/Source/Provers/Z3api/ContextLayer.cs b/Source/Provers/Z3api/ContextLayer.cs index ad0c2239..87fd8c17 100644 --- a/Source/Provers/Z3api/ContextLayer.cs +++ b/Source/Provers/Z3api/ContextLayer.cs @@ -1,728 +1,728 @@ -using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Threading;
-using System.IO;
-using System.Diagnostics;
-using Microsoft.Boogie.AbstractInterpretation;
-using Microsoft.Boogie;
-using Microsoft.Boogie.Z3;
-using Microsoft.Z3;
-using Microsoft.Boogie.VCExprAST;
-using Microsoft.Basetypes;
-
-using Z3Model = Microsoft.Z3.Model;
-using BoogieModel = Microsoft.Boogie.Model;
-
-namespace Microsoft.Boogie.Z3 {
- public class Z3apiProverContext : DeclFreeProverContext {
- private BacktrackDictionary<string, Symbol> symbols = new BacktrackDictionary<string, Symbol>();
- internal BacktrackDictionary<string, Term> constants = new BacktrackDictionary<string, Term>();
- internal BacktrackDictionary<string, FuncDecl> functions = new BacktrackDictionary<string, FuncDecl>();
- internal BacktrackDictionary<string, Term> labels = new BacktrackDictionary<string, Term>();
- internal BacktrackDictionary<Term, VCExpr> constants_inv = null;
- internal BacktrackDictionary<FuncDecl, Function> functions_inv = null;
-
- public Config config;
- public Context z3;
-
- private Z3TypeCachedBuilder tm;
- private UniqueNamer namer;
- private StreamWriter z3log;
-
- private int counterexamples;
- private string logFilename;
- private List<string> debugTraces;
-
- public Z3apiProverContext(Z3InstanceOptions opts, VCExpressionGenerator gen)
- : base(gen, new VCGenerationOptions(new List<string>())) {
- int timeout = opts.Timeout * 1000;
- config = new Config();
- config.SetParamValue("MODEL", "true");
- config.SetParamValue("MODEL_V2", "true");
- config.SetParamValue("MODEL_COMPLETION", "true");
- config.SetParamValue("MBQI", "false");
- config.SetParamValue("TYPE_CHECK", "true");
- if (0 <= timeout) {
- config.SetParamValue("SOFT_TIMEOUT", timeout.ToString());
- }
-
- if (0 <= CommandLineOptions.Clo.ProverCCLimit) {
- this.counterexamples = CommandLineOptions.Clo.ProverCCLimit;
- }
- if (CommandLineOptions.Clo.SimplifyLogFilePath != null) {
- logFilename = CommandLineOptions.Clo.SimplifyLogFilePath;
- }
- this.debugTraces = new List<string>();
-
- z3 = new Context(config);
- z3.SetPrintMode(PrintMode.Smtlib2Compliant);
- if (logFilename != null)
- {
-#if true
- Z3Log.Open(logFilename);
-#else
- z3.OpenLog(logFilename);
-#endif
- }
- foreach (string tag in debugTraces)
- z3.EnableDebugTrace(tag);
-
- this.z3log = null;
- this.tm = new Z3TypeCachedBuilder(this);
- this.namer = new UniqueNamer();
- }
-
- public Z3apiProverContext(Context ctx, VCExpressionGenerator gen)
- : base(gen, new VCGenerationOptions(new List<string>()))
- {
- z3 = ctx;
-
- this.z3log = null;
- this.tm = new Z3TypeCachedBuilder(this);
- this.namer = new UniqueNamer();
-
- // For external
-
- constants_inv = new BacktrackDictionary<Term, VCExpr>();
- functions_inv = new BacktrackDictionary<FuncDecl, Function>();
- }
-
- public Term VCExprToTerm(VCExpr expr, LineariserOptions linOptions) {
- Z3apiExprLineariser visitor = new Z3apiExprLineariser(this, namer);
- return (Term)expr.Accept(visitor, linOptions);
- }
-
-
- private class fromZ3
- {
- private VCExpressionGenerator gen;
- private Dictionary<Term, VCExpr> memo;
- private BacktrackDictionary<Term, VCExpr> constants_inv;
- private BacktrackDictionary<FuncDecl, Function> functions_inv;
- private List<VCExprLetBinding> lets;
- private int let_ctr = 0;
-
- private VCExpr create_let(Term t, VCExpr u)
- {
- var name = "$x" + let_ctr.ToString();
- let_ctr++;
- var sym = gen.Variable(name, u.Type);
- memo.Remove(t);
- memo.Add(t, sym);
- lets.Add(gen.LetBinding(sym, u));
- return sym;
- }
-
- public fromZ3(VCExpressionGenerator _gen,
- BacktrackDictionary<Term, VCExpr> _constants_inv,
- BacktrackDictionary<FuncDecl, Function> _functions_inv)
- {
- gen = _gen;
- constants_inv = _constants_inv;
- functions_inv = _functions_inv;
- memo = new Dictionary<Term, VCExpr>();
- lets = new List<VCExprLetBinding>();
- }
-
- public void clear()
- {
- memo.Clear();
- lets.Clear();
- }
- public VCExpr get(Term arg)
- {
- if (memo.ContainsKey(arg))
- return memo[arg];
- VCExpr res = null;
- switch (arg.GetKind())
- {
- case TermKind.Numeral:
- var numstr = arg.GetNumeralString();
- if (arg.GetSort().GetSortKind() == SortKind.Int) {
- res = gen.Integer(Basetypes.BigNum.FromString(numstr));
- }
- else {
- res = gen.Real(Basetypes.BigDec.FromString(numstr));
- }
- break;
- case TermKind.App:
- var args = arg.GetAppArgs();
- var vcargs = new VCExpr[args.Length];
- for (int i = 0; i < args.Length; i++)
- vcargs[i] = get(args[i]);
-
- switch (arg.GetAppDecl().GetKind())
- {
- case DeclKind.Add:
- if (vcargs.Length == 0) {
- if (arg.GetSort().GetSortKind() == SortKind.Int) {
- res = gen.Integer(Basetypes.BigNum.ZERO);
- }
- else {
- res = gen.Real(Basetypes.BigDec.ZERO);
- }
- }
- else
- {
- res = vcargs[0];
- for (int k = 1; k < vcargs.Length; k++)
- res = gen.Add(res, vcargs[k]);
- }
- break;
- case DeclKind.And:
- res = VCExpressionGenerator.True;
- for (int i = 0; i < vcargs.Length; i++)
- res = gen.AndSimp(res, vcargs[i]);
- break;
- case DeclKind.Div:
- Debug.Assert(vcargs.Length == 2);
- res = gen.Function(VCExpressionGenerator.RealDivOp, vcargs[0], vcargs[1]);
- break;
- case DeclKind.Eq:
- Debug.Assert(vcargs.Length == 2);
- res = gen.Eq(vcargs[0], vcargs[1]);
- break;
- case DeclKind.False:
- res = VCExpressionGenerator.False;
- break;
- case DeclKind.Ge:
- Debug.Assert(vcargs.Length == 2);
- res = gen.Function(VCExpressionGenerator.GeOp, vcargs[0], vcargs[1]);
- break;
- case DeclKind.Gt:
- Debug.Assert(vcargs.Length == 2);
- res = gen.Gt(vcargs[0], vcargs[1]);
- break;
- case DeclKind.IDiv:
- Debug.Assert(vcargs.Length == 2);
- res = gen.Function(VCExpressionGenerator.DivOp, vcargs[0], vcargs[1]);
- break;
- case DeclKind.Iff:
- Debug.Assert(vcargs.Length == 2);
- var l = create_let(args[0], vcargs[0]);
- var r = create_let(args[1], vcargs[1]);
- return gen.And(gen.Implies(l, r), gen.Implies(r, l));
- case DeclKind.Implies:
- Debug.Assert(vcargs.Length == 2);
- res = gen.Implies(vcargs[0], vcargs[1]);
- break;
- case DeclKind.Ite:
- Debug.Assert(vcargs.Length == 3);
- res = gen.Function(VCExpressionGenerator.IfThenElseOp, vcargs[0], vcargs[1], vcargs[2]);
- break;
- case DeclKind.Le:
- Debug.Assert(vcargs.Length == 2);
- res = gen.Function(VCExpressionGenerator.LeOp, vcargs[0], vcargs[1]);
- break;
- case DeclKind.Lt:
- Debug.Assert(vcargs.Length == 2);
- res = gen.Function(VCExpressionGenerator.LtOp, vcargs[0], vcargs[1]);
- break;
- case DeclKind.Mod:
- Debug.Assert(vcargs.Length == 2);
- res = gen.Function(VCExpressionGenerator.ModOp, vcargs[0], vcargs[1]);
- break;
- case DeclKind.Mul:
- Debug.Assert(vcargs.Length == 2);
- res = gen.Function(VCExpressionGenerator.MulOp, vcargs[0], vcargs[1]);
- break;
- case DeclKind.Not:
- Debug.Assert(vcargs.Length == 1);
- res = gen.Not(vcargs[0]);
- break;
- case DeclKind.Or:
- res = VCExpressionGenerator.False;
- for (int i = 0; i < vcargs.Length; i++)
- res = gen.OrSimp(res, vcargs[i]);
- break;
- case DeclKind.Select:
- Debug.Assert(vcargs.Length == 2);
- res = gen.Select(vcargs[0], vcargs[1]);
- break;
- case DeclKind.Store:
- Debug.Assert(vcargs.Length == 3);
- res = gen.Store(vcargs[0], vcargs[1], vcargs[2]);
- break;
- case DeclKind.Sub:
- Debug.Assert(vcargs.Length == 2);
- res = gen.Function(VCExpressionGenerator.SubOp, vcargs[0], vcargs[1]);
- break;
- case DeclKind.True:
- res = VCExpressionGenerator.True;
- break;
- case DeclKind.Uminus:
- Debug.Assert(vcargs.Length == 1);
- var argzero = null;
- if (vcargs[0].Type.IsInt) {
- argzero = gen.Integer(Basetypes.BigNum.ZERO);
- }
- else {
- argzero = gen.Real(Basetypes.BigDec.ZERO);
- }
- res = gen.Function(VCExpressionGenerator.SubOp, argzero, vcargs[0]);
- break;
- case DeclKind.ToInt:
- Debug.Assert(vcargs.Length == 1);
- res = gen.Function(VCExpressionGenerator.ToIntOp, vcargs[0]);
- break;
- case DeclKind.ToReal:
- Debug.Assert(vcargs.Length == 1);
- res = gen.Function(VCExpressionGenerator.ToRealOp, vcargs[0]);
- break;
- case DeclKind.Uninterpreted:
- var name = arg.GetAppDecl().GetDeclName();
- if (args.Length == 0)
- { // a 0-ary constant is a VCExprVar
- if (!constants_inv.TryGetValue(arg, out res))
- throw new Exception("Z3 returned unknown constant: " + name);
- }
- else
- {
- Function f;
- if (!functions_inv.TryGetValue(arg.GetAppDecl(), out f))
- throw new Exception("Z3 returned unknown function: " + name);
- List<VCExpr> vcargsList = new List<VCExpr>(vcargs);
- res = gen.Function(f, vcargsList);
- }
- break;
- default:
- throw new Exception("Unknown Z3 operator");
- }
- break;
- default:
- Debug.Assert(false);
- throw new Exception("Unknown Z3 AST kind");
- }
-
- memo.Add(arg, res);
- return res;
- }
- public VCExpr add_lets(VCExpr e)
- {
- foreach (var let in lets)
- {
- e = gen.Let(e, let);
- }
- return e;
- }
- }
-
- public VCExpr TermToVCExpr(Term t)
- {
- var fZ = new fromZ3(gen, constants_inv, functions_inv);
- return fZ.add_lets(fZ.get(t));
- }
-
-
-
-
-
- public override void DeclareType(TypeCtorDecl t, string attributes) {
- base.DeclareType(t, attributes);
- log("(declare-sort {0})", t.Name);
- }
-
- public override void DeclareConstant(Constant c, bool uniq, string attributes) {
- base.DeclareConstant(c, uniq, attributes);
- DeclareConstant(c.Name, c.TypedIdent.Type);
- }
-
- public override void DeclareFunction(Function f, string attributes) {
- base.DeclareFunction(f, attributes);
- List<Type> domain = new List<Type>();
- foreach (Variable v in f.InParams) {
- domain.Add(v.TypedIdent.Type);
- }
- if (f.OutParams.Length != 1)
- throw new Exception("Cannot handle functions with " + f.OutParams + " out parameters.");
- Type range = f.OutParams[0].TypedIdent.Type;
-
- string functionName = f.Name;
- Symbol symbolAst = GetSymbol(functionName);
- var domainStr = "";
- List<Sort> domainAst = new List<Sort>();
- foreach (Type domainType in domain) {
- Sort type = tm.GetType(domainType);
- domainAst.Add(type);
- domainStr += type.ToString() + " ";
- }
- Sort rangeAst = tm.GetType(range);
- FuncDecl constDeclAst = z3.MkFuncDecl(symbolAst, domainAst.ToArray(), rangeAst);
- functions.Add(functionName, constDeclAst);
- if(functions_inv != null)functions_inv.Add(constDeclAst, f);
- log("(declare-funs (({0} {1} {2})))", functionName, domainStr, rangeAst);
- }
-
- public override void DeclareGlobalVariable(GlobalVariable v, string attributes) {
- base.DeclareGlobalVariable(v, attributes);
- DeclareConstant(v.Name, v.TypedIdent.Type);
- }
-
- public override string Lookup(VCExprVar var) {
- return namer.Lookup(var);
- }
-
- public void log(string format, params object[] args) {
- // Currently, this is a no-op because z3log is always null
- // We use the default (automatic) tracing facility of z3
- if (z3log != null) {
- var str = string.Format(format, args);
- // Do standard string replacement
- str = str.Replace("array", "Array");
- z3log.WriteLine(str);
- z3log.Flush();
- }
- }
-
- public void CloseLog() {
-#if true
- Z3Log.Close();
-#else
- z3.CloseLog();
-#endif
- if (z3log != null) {
- z3log.Close();
- }
- z3log = null;
- }
-
- public void CreateBacktrackPoint() {
- symbols.CreateBacktrackPoint();
- constants.CreateBacktrackPoint();
- functions.CreateBacktrackPoint();
- labels.CreateBacktrackPoint();
- if(constants_inv != null)constants_inv.CreateBacktrackPoint();
- if(functions_inv != null)functions_inv.CreateBacktrackPoint();
- z3.Push();
- log("(push)");
- }
-
- public void Backtrack() {
- z3.Pop();
- labels.Backtrack();
- functions.Backtrack();
- constants.Backtrack();
- symbols.Backtrack();
- if (constants_inv != null) constants_inv.Backtrack();
- if (functions_inv != null) functions_inv.Backtrack();
- log("(pop)");
- }
-
- public void AddAxiom(VCExpr axiom, LineariserOptions linOptions) {
- Z3apiExprLineariser visitor = new Z3apiExprLineariser(this, namer);
- Term term = (Term)axiom.Accept(visitor, linOptions);
- log("(assert {0})", term);
- z3.AssertCnstr(term);
- }
-
- public void AddConjecture(VCExpr vc, LineariserOptions linOptions) {
- VCExpr not_vc = (VCExpr)this.gen.Not(vc);
- Z3apiExprLineariser visitor = new Z3apiExprLineariser(this, namer);
- Term term = (Term)not_vc.Accept(visitor, linOptions);
- log("(assert {0})", term);
- z3.AssertCnstr(term);
- }
-
- public void AddSmtlibString(string smtlibString) {
- FuncDecl[] decls;
- Term[] assumptions;
- Term[] terms;
- Sort[] sorts;
- string tmp;
-
- z3.ParseSmtlibString(smtlibString, new Sort[] { }, new FuncDecl[] { },
- out assumptions, out terms, out decls, out sorts, out tmp);
- // TBD: check with Nikolaj about the correct position of assumptions
- foreach (FuncDecl decl in decls) {
- Symbol symbol = z3.GetDeclName(decl);
- string functionName = z3.GetSymbolString(symbol);
- functions.Add(functionName, decl);
- }
- foreach (Term assumption in assumptions) {
- log("(assert {0})", assumption);
- z3.AssertCnstr(assumption);
- }
- }
-
- private List<Sort> GetTypes(List<Type> boogieTypes) {
- List<Sort> z3Types = new List<Sort>();
- foreach (Type boogieType in boogieTypes) {
- Sort type = tm.GetType(boogieType);
- z3Types.Add(type);
- }
- return z3Types;
- }
-
- private static bool Equals(List<string> l, List<string> r) {
- Debug.Assert(l != null);
- if (r == null)
- return false;
-
- if (l.Count != r.Count)
- return false;
-
- for (int i = 0; i < l.Count; i++)
- if (!l[i].Equals(r[i]))
- return false;
- return true;
- }
-
- private void DisplayRelevantLabels(List<string> relevantLabels) {
- foreach (string labelName in relevantLabels) {
- System.Console.Write(labelName + ",");
- }
- System.Console.WriteLine("---");
- }
-
- private void DeclareConstant(string constantName, Type boogieType) {
- Symbol symbolAst = GetSymbol(constantName);
- Sort typeAst = tm.GetType(boogieType);
-
- Term constAst = z3.MkConst(symbolAst, typeAst);
- constants.Add(constantName, constAst);
- log("(declare-funs (({0} {1})))", constAst, typeAst);
- }
-
- public ProverInterface.Outcome Check(out List<Z3ErrorModelAndLabels> boogieErrors) {
- Microsoft.Boogie.Helpers.ExtraTraceInformation("Sending data to the theorem prover");
- boogieErrors = new List<Z3ErrorModelAndLabels>();
- LBool outcome = LBool.Undef;
- Debug.Assert(0 < this.counterexamples);
- while (true) {
- Z3Model z3Model;
- outcome = z3.CheckAndGetModel(out z3Model);
-
- log("(check-sat)");
- if (outcome == LBool.False)
- break;
-
- if (outcome == LBool.Undef && z3Model == null) {
- // Blame this on timeout
- return ProverInterface.Outcome.TimeOut;
- }
-
- Debug.Assert(z3Model != null);
- LabeledLiterals labels = z3.GetRelevantLabels();
- Debug.Assert(labels != null);
-
- List<string> labelStrings = new List<string>();
- uint numLabels = labels.GetNumLabels();
- for (uint i = 0; i < numLabels; ++i) {
- Symbol sym = labels.GetLabel(i);
- string labelName = z3.GetSymbolString(sym);
- if (!labelName.StartsWith("@")) {
- labels.Disable(i);
- }
- labelStrings.Add(labelName);
- }
-
- var sw = new StringWriter();
- sw.WriteLine("*** MODEL");
- z3Model.Display(sw);
- sw.WriteLine("*** END_MODEL");
- var sr = new StringReader(sw.ToString());
- var models = Microsoft.Boogie.Model.ParseModels(sr);
- Z3ErrorModelAndLabels e = new Z3ErrorModelAndLabels(models[0], new List<string>(labelStrings));
- boogieErrors.Add(e);
-
- if (boogieErrors.Count < this.counterexamples) {
- z3.BlockLiterals(labels);
- log("block-literals {0}", labels);
- }
-
- labels.Dispose();
- z3Model.Dispose();
- if (boogieErrors.Count == this.counterexamples)
- break;
- }
-
- if (boogieErrors.Count > 0) {
- return ProverInterface.Outcome.Invalid;
- }
- else if (outcome == LBool.False) {
- return ProverInterface.Outcome.Valid;
- }
- else {
- Debug.Assert(outcome == LBool.Undef);
- return ProverInterface.Outcome.Undetermined;
- }
- }
-
- public ProverInterface.Outcome CheckAssumptions(List<VCExpr> assumptions, LineariserOptions linOptions,
- out List<Z3ErrorModelAndLabels> boogieErrors,
- out List<int> unsatCore) {
- Microsoft.Boogie.Helpers.ExtraTraceInformation("Sending data to the theorem prover");
- boogieErrors = new List<Z3ErrorModelAndLabels>();
- unsatCore = new List<int>();
- LBool outcome = LBool.Undef;
-
- Z3Model z3Model;
- Term proof;
- Term[] core;
- Term[] assumption_terms = new Term[assumptions.Count];
- var logstring = "";
- for (int i = 0; i < assumptions.Count; i++) {
- Z3apiExprLineariser visitor = new Z3apiExprLineariser(this, namer);
- Term z3ast = (Term)assumptions[i].Accept(visitor, linOptions);
- assumption_terms[i] = z3ast;
- logstring += string.Format("({0}) ", assumption_terms[i]);
- }
-
- log("(get-core {0})", logstring);
- outcome = z3.CheckAssumptions(out z3Model, assumption_terms, out proof, out core);
-
- if (outcome != LBool.False) {
- Debug.Assert(z3Model != null);
- LabeledLiterals labels = z3.GetRelevantLabels();
- Debug.Assert(labels != null);
-
- List<string> labelStrings = new List<string>();
- uint numLabels = labels.GetNumLabels();
- for (uint i = 0; i < numLabels; ++i) {
- Symbol sym = labels.GetLabel(i);
- string labelName = z3.GetSymbolString(sym);
- if (!labelName.StartsWith("@")) {
- labels.Disable(i);
- }
- labelStrings.Add(labelName);
- }
-
- var sw = new StringWriter();
- sw.WriteLine("*** MODEL");
- z3Model.Display(sw);
- sw.WriteLine("*** END_MODEL");
- var sr = new StringReader(sw.ToString());
- var models = Microsoft.Boogie.Model.ParseModels(sr);
- Z3ErrorModelAndLabels e = new Z3ErrorModelAndLabels(models[0], new List<string>(labelStrings));
- boogieErrors.Add(e);
-
- labels.Dispose();
- z3Model.Dispose();
- }
-
- if (boogieErrors.Count > 0) {
- return ProverInterface.Outcome.Invalid;
- }
- else if (outcome == LBool.False) {
- foreach (Term t in core) {
- for (int i = 0; i < assumption_terms.Length; i++) {
- if (t.Equals(assumption_terms[i]))
- unsatCore.Add(i);
- }
- }
- return ProverInterface.Outcome.Valid;
- }
- else {
- Debug.Assert(outcome == LBool.Undef);
- return ProverInterface.Outcome.Undetermined;
- }
- }
-
- private Symbol GetSymbol(string symbolName) {
- if (!symbols.ContainsKey(symbolName)) {
- Symbol symbolAst = z3.MkSymbol(symbolName);
- symbols.Add(symbolName, symbolAst);
- }
- Symbol result;
- if (!symbols.TryGetValue(symbolName, out result))
- throw new Exception("symbol " + symbolName + " is undefined");
- return result;
- }
-
- public Term GetConstant(string constantName, Type constantType, VCExpr node)
- {
- Term typeSafeTerm;
- if (!constants.ContainsKey(constantName))
- this.DeclareConstant(constantName, constantType);
-
- if (!constants.TryGetValue(constantName, out typeSafeTerm))
- throw new Exception("constant " + constantName + " is not defined");
-
- if (constants_inv != null && !constants_inv.ContainsKey(typeSafeTerm))
- constants_inv.Add(typeSafeTerm, node);
-
- return typeSafeTerm;
- }
-
- public FuncDecl GetFunction(string functionName) {
- FuncDecl f;
- if (!functions.TryGetValue(functionName, out f))
- throw new Exception("function " + functionName + " is undefined");
- return f;
- }
-
- public Term MakeLabel(string labelName, bool pos, Term child) {
- Symbol labelSymbol = this.GetSymbol(labelName);
- Term labeledExpr = z3.MkLabel(labelSymbol, pos, child);
- labels.Add(labelName, labeledExpr);
- return labeledExpr;
- }
-
- public LabeledLiterals GetRelevantLabels() {
- LabeledLiterals safeLiterals = z3.GetRelevantLabels();
- log("get-relevant-labels");
- return safeLiterals;
- }
- }
-
- internal class BacktrackDictionary<K, V> {
- private Dictionary<K, V> dictionary = new Dictionary<K, V>();
- private Stack<List<K>> keyStack = new Stack<List<K>>();
-
- public BacktrackDictionary() {
- CreateBacktrackPoint();
- }
-
- public bool TryGetValue(K key, out V val) {
- return dictionary.TryGetValue(key, out val);
- }
-
- public void Add(K key, V v) {
- if (dictionary.ContainsKey(key)) {
- dictionary.Remove(key);
- }
- dictionary.Add(key, v);
- keyStack.Peek().Add(key);
- }
-
- public bool ContainsKey(K k) {
- return dictionary.ContainsKey(k);
- }
-
- public void CreateBacktrackPoint() {
- keyStack.Push(new List<K>());
- }
-
- public void Backtrack() {
- List<K> keysToErase = keyStack.Pop();
- foreach (K key in keysToErase) {
- dictionary.Remove(key);
- }
- if (keyStack.Count == 0)
- this.CreateBacktrackPoint();
- }
-
- public IEnumerator GetEnumerator() {
- return dictionary.Keys.GetEnumerator();
- }
- }
-
- public class Z3ErrorModelAndLabels {
- private Model _model;
- private List<string> _relevantLabels;
- public Model Model {
- get { return this._model; }
- }
- public List<string> RelevantLabels {
- get { return this._relevantLabels; }
- }
- public Z3ErrorModelAndLabels(Model model, List<string> relevantLabels) {
- this._model = model;
- this._relevantLabels = relevantLabels;
- }
- }
-
-
-
+using System; +using System.Collections; +using System.Collections.Generic; +using System.Threading; +using System.IO; +using System.Diagnostics; +using Microsoft.Boogie.AbstractInterpretation; +using Microsoft.Boogie; +using Microsoft.Boogie.Z3; +using Microsoft.Z3; +using Microsoft.Boogie.VCExprAST; +using Microsoft.Basetypes; + +using Z3Model = Microsoft.Z3.Model; +using BoogieModel = Microsoft.Boogie.Model; + +namespace Microsoft.Boogie.Z3 { + public class Z3apiProverContext : DeclFreeProverContext { + private BacktrackDictionary<string, Symbol> symbols = new BacktrackDictionary<string, Symbol>(); + internal BacktrackDictionary<string, Term> constants = new BacktrackDictionary<string, Term>(); + internal BacktrackDictionary<string, FuncDecl> functions = new BacktrackDictionary<string, FuncDecl>(); + internal BacktrackDictionary<string, Term> labels = new BacktrackDictionary<string, Term>(); + internal BacktrackDictionary<Term, VCExpr> constants_inv = null; + internal BacktrackDictionary<FuncDecl, Function> functions_inv = null; + + public Config config; + public Context z3; + + private Z3TypeCachedBuilder tm; + private UniqueNamer namer; + private StreamWriter z3log; + + private int counterexamples; + private string logFilename; + private List<string> debugTraces; + + public Z3apiProverContext(Z3InstanceOptions opts, VCExpressionGenerator gen) + : base(gen, new VCGenerationOptions(new List<string>())) { + int timeout = opts.Timeout * 1000; + config = new Config(); + config.SetParamValue("MODEL", "true"); + config.SetParamValue("MODEL_V2", "true"); + config.SetParamValue("MODEL_COMPLETION", "true"); + config.SetParamValue("MBQI", "false"); + config.SetParamValue("TYPE_CHECK", "true"); + if (0 <= timeout) { + config.SetParamValue("SOFT_TIMEOUT", timeout.ToString()); + } + + if (0 <= CommandLineOptions.Clo.ProverCCLimit) { + this.counterexamples = CommandLineOptions.Clo.ProverCCLimit; + } + if (CommandLineOptions.Clo.SimplifyLogFilePath != null) { + logFilename = CommandLineOptions.Clo.SimplifyLogFilePath; + } + this.debugTraces = new List<string>(); + + z3 = new Context(config); + z3.SetPrintMode(PrintMode.Smtlib2Compliant); + if (logFilename != null) + { +#if true + Z3Log.Open(logFilename); +#else + z3.OpenLog(logFilename); +#endif + } + foreach (string tag in debugTraces) + z3.EnableDebugTrace(tag); + + this.z3log = null; + this.tm = new Z3TypeCachedBuilder(this); + this.namer = new UniqueNamer(); + } + + public Z3apiProverContext(Context ctx, VCExpressionGenerator gen) + : base(gen, new VCGenerationOptions(new List<string>())) + { + z3 = ctx; + + this.z3log = null; + this.tm = new Z3TypeCachedBuilder(this); + this.namer = new UniqueNamer(); + + // For external + + constants_inv = new BacktrackDictionary<Term, VCExpr>(); + functions_inv = new BacktrackDictionary<FuncDecl, Function>(); + } + + public Term VCExprToTerm(VCExpr expr, LineariserOptions linOptions) { + Z3apiExprLineariser visitor = new Z3apiExprLineariser(this, namer); + return (Term)expr.Accept(visitor, linOptions); + } + + + private class fromZ3 + { + private VCExpressionGenerator gen; + private Dictionary<Term, VCExpr> memo; + private BacktrackDictionary<Term, VCExpr> constants_inv; + private BacktrackDictionary<FuncDecl, Function> functions_inv; + private List<VCExprLetBinding> lets; + private int let_ctr = 0; + + private VCExpr create_let(Term t, VCExpr u) + { + var name = "$x" + let_ctr.ToString(); + let_ctr++; + var sym = gen.Variable(name, u.Type); + memo.Remove(t); + memo.Add(t, sym); + lets.Add(gen.LetBinding(sym, u)); + return sym; + } + + public fromZ3(VCExpressionGenerator _gen, + BacktrackDictionary<Term, VCExpr> _constants_inv, + BacktrackDictionary<FuncDecl, Function> _functions_inv) + { + gen = _gen; + constants_inv = _constants_inv; + functions_inv = _functions_inv; + memo = new Dictionary<Term, VCExpr>(); + lets = new List<VCExprLetBinding>(); + } + + public void clear() + { + memo.Clear(); + lets.Clear(); + } + public VCExpr get(Term arg) + { + if (memo.ContainsKey(arg)) + return memo[arg]; + VCExpr res = null; + switch (arg.GetKind()) + { + case TermKind.Numeral: + var numstr = arg.GetNumeralString(); + if (arg.GetSort().GetSortKind() == SortKind.Int) { + res = gen.Integer(Basetypes.BigNum.FromString(numstr)); + } + else { + res = gen.Real(Basetypes.BigDec.FromString(numstr)); + } + break; + case TermKind.App: + var args = arg.GetAppArgs(); + var vcargs = new VCExpr[args.Length]; + for (int i = 0; i < args.Length; i++) + vcargs[i] = get(args[i]); + + switch (arg.GetAppDecl().GetKind()) + { + case DeclKind.Add: + if (vcargs.Length == 0) { + if (arg.GetSort().GetSortKind() == SortKind.Int) { + res = gen.Integer(Basetypes.BigNum.ZERO); + } + else { + res = gen.Real(Basetypes.BigDec.ZERO); + } + } + else + { + res = vcargs[0]; + for (int k = 1; k < vcargs.Length; k++) + res = gen.Add(res, vcargs[k]); + } + break; + case DeclKind.And: + res = VCExpressionGenerator.True; + for (int i = 0; i < vcargs.Length; i++) + res = gen.AndSimp(res, vcargs[i]); + break; + case DeclKind.Div: + Debug.Assert(vcargs.Length == 2); + res = gen.Function(VCExpressionGenerator.RealDivOp, vcargs[0], vcargs[1]); + break; + case DeclKind.Eq: + Debug.Assert(vcargs.Length == 2); + res = gen.Eq(vcargs[0], vcargs[1]); + break; + case DeclKind.False: + res = VCExpressionGenerator.False; + break; + case DeclKind.Ge: + Debug.Assert(vcargs.Length == 2); + res = gen.Function(VCExpressionGenerator.GeOp, vcargs[0], vcargs[1]); + break; + case DeclKind.Gt: + Debug.Assert(vcargs.Length == 2); + res = gen.Gt(vcargs[0], vcargs[1]); + break; + case DeclKind.IDiv: + Debug.Assert(vcargs.Length == 2); + res = gen.Function(VCExpressionGenerator.DivOp, vcargs[0], vcargs[1]); + break; + case DeclKind.Iff: + Debug.Assert(vcargs.Length == 2); + var l = create_let(args[0], vcargs[0]); + var r = create_let(args[1], vcargs[1]); + return gen.And(gen.Implies(l, r), gen.Implies(r, l)); + case DeclKind.Implies: + Debug.Assert(vcargs.Length == 2); + res = gen.Implies(vcargs[0], vcargs[1]); + break; + case DeclKind.Ite: + Debug.Assert(vcargs.Length == 3); + res = gen.Function(VCExpressionGenerator.IfThenElseOp, vcargs[0], vcargs[1], vcargs[2]); + break; + case DeclKind.Le: + Debug.Assert(vcargs.Length == 2); + res = gen.Function(VCExpressionGenerator.LeOp, vcargs[0], vcargs[1]); + break; + case DeclKind.Lt: + Debug.Assert(vcargs.Length == 2); + res = gen.Function(VCExpressionGenerator.LtOp, vcargs[0], vcargs[1]); + break; + case DeclKind.Mod: + Debug.Assert(vcargs.Length == 2); + res = gen.Function(VCExpressionGenerator.ModOp, vcargs[0], vcargs[1]); + break; + case DeclKind.Mul: + Debug.Assert(vcargs.Length == 2); + res = gen.Function(VCExpressionGenerator.MulOp, vcargs[0], vcargs[1]); + break; + case DeclKind.Not: + Debug.Assert(vcargs.Length == 1); + res = gen.Not(vcargs[0]); + break; + case DeclKind.Or: + res = VCExpressionGenerator.False; + for (int i = 0; i < vcargs.Length; i++) + res = gen.OrSimp(res, vcargs[i]); + break; + case DeclKind.Select: + Debug.Assert(vcargs.Length == 2); + res = gen.Select(vcargs[0], vcargs[1]); + break; + case DeclKind.Store: + Debug.Assert(vcargs.Length == 3); + res = gen.Store(vcargs[0], vcargs[1], vcargs[2]); + break; + case DeclKind.Sub: + Debug.Assert(vcargs.Length == 2); + res = gen.Function(VCExpressionGenerator.SubOp, vcargs[0], vcargs[1]); + break; + case DeclKind.True: + res = VCExpressionGenerator.True; + break; + case DeclKind.Uminus: + Debug.Assert(vcargs.Length == 1); + var argzero = null; + if (vcargs[0].Type.IsInt) { + argzero = gen.Integer(Basetypes.BigNum.ZERO); + } + else { + argzero = gen.Real(Basetypes.BigDec.ZERO); + } + res = gen.Function(VCExpressionGenerator.SubOp, argzero, vcargs[0]); + break; + case DeclKind.ToInt: + Debug.Assert(vcargs.Length == 1); + res = gen.Function(VCExpressionGenerator.ToIntOp, vcargs[0]); + break; + case DeclKind.ToReal: + Debug.Assert(vcargs.Length == 1); + res = gen.Function(VCExpressionGenerator.ToRealOp, vcargs[0]); + break; + case DeclKind.Uninterpreted: + var name = arg.GetAppDecl().GetDeclName(); + if (args.Length == 0) + { // a 0-ary constant is a VCExprVar + if (!constants_inv.TryGetValue(arg, out res)) + throw new Exception("Z3 returned unknown constant: " + name); + } + else + { + Function f; + if (!functions_inv.TryGetValue(arg.GetAppDecl(), out f)) + throw new Exception("Z3 returned unknown function: " + name); + List<VCExpr> vcargsList = new List<VCExpr>(vcargs); + res = gen.Function(f, vcargsList); + } + break; + default: + throw new Exception("Unknown Z3 operator"); + } + break; + default: + Debug.Assert(false); + throw new Exception("Unknown Z3 AST kind"); + } + + memo.Add(arg, res); + return res; + } + public VCExpr add_lets(VCExpr e) + { + foreach (var let in lets) + { + e = gen.Let(e, let); + } + return e; + } + } + + public VCExpr TermToVCExpr(Term t) + { + var fZ = new fromZ3(gen, constants_inv, functions_inv); + return fZ.add_lets(fZ.get(t)); + } + + + + + + public override void DeclareType(TypeCtorDecl t, string attributes) { + base.DeclareType(t, attributes); + log("(declare-sort {0})", t.Name); + } + + public override void DeclareConstant(Constant c, bool uniq, string attributes) { + base.DeclareConstant(c, uniq, attributes); + DeclareConstant(c.Name, c.TypedIdent.Type); + } + + public override void DeclareFunction(Function f, string attributes) { + base.DeclareFunction(f, attributes); + List<Type> domain = new List<Type>(); + foreach (Variable v in f.InParams) { + domain.Add(v.TypedIdent.Type); + } + if (f.OutParams.Length != 1) + throw new Exception("Cannot handle functions with " + f.OutParams + " out parameters."); + Type range = f.OutParams[0].TypedIdent.Type; + + string functionName = f.Name; + Symbol symbolAst = GetSymbol(functionName); + var domainStr = ""; + List<Sort> domainAst = new List<Sort>(); + foreach (Type domainType in domain) { + Sort type = tm.GetType(domainType); + domainAst.Add(type); + domainStr += type.ToString() + " "; + } + Sort rangeAst = tm.GetType(range); + FuncDecl constDeclAst = z3.MkFuncDecl(symbolAst, domainAst.ToArray(), rangeAst); + functions.Add(functionName, constDeclAst); + if(functions_inv != null)functions_inv.Add(constDeclAst, f); + log("(declare-funs (({0} {1} {2})))", functionName, domainStr, rangeAst); + } + + public override void DeclareGlobalVariable(GlobalVariable v, string attributes) { + base.DeclareGlobalVariable(v, attributes); + DeclareConstant(v.Name, v.TypedIdent.Type); + } + + public override string Lookup(VCExprVar var) { + return namer.Lookup(var); + } + + public void log(string format, params object[] args) { + // Currently, this is a no-op because z3log is always null + // We use the default (automatic) tracing facility of z3 + if (z3log != null) { + var str = string.Format(format, args); + // Do standard string replacement + str = str.Replace("array", "Array"); + z3log.WriteLine(str); + z3log.Flush(); + } + } + + public void CloseLog() { +#if true + Z3Log.Close(); +#else + z3.CloseLog(); +#endif + if (z3log != null) { + z3log.Close(); + } + z3log = null; + } + + public void CreateBacktrackPoint() { + symbols.CreateBacktrackPoint(); + constants.CreateBacktrackPoint(); + functions.CreateBacktrackPoint(); + labels.CreateBacktrackPoint(); + if(constants_inv != null)constants_inv.CreateBacktrackPoint(); + if(functions_inv != null)functions_inv.CreateBacktrackPoint(); + z3.Push(); + log("(push)"); + } + + public void Backtrack() { + z3.Pop(); + labels.Backtrack(); + functions.Backtrack(); + constants.Backtrack(); + symbols.Backtrack(); + if (constants_inv != null) constants_inv.Backtrack(); + if (functions_inv != null) functions_inv.Backtrack(); + log("(pop)"); + } + + public void AddAxiom(VCExpr axiom, LineariserOptions linOptions) { + Z3apiExprLineariser visitor = new Z3apiExprLineariser(this, namer); + Term term = (Term)axiom.Accept(visitor, linOptions); + log("(assert {0})", term); + z3.AssertCnstr(term); + } + + public void AddConjecture(VCExpr vc, LineariserOptions linOptions) { + VCExpr not_vc = (VCExpr)this.gen.Not(vc); + Z3apiExprLineariser visitor = new Z3apiExprLineariser(this, namer); + Term term = (Term)not_vc.Accept(visitor, linOptions); + log("(assert {0})", term); + z3.AssertCnstr(term); + } + + public void AddSmtlibString(string smtlibString) { + FuncDecl[] decls; + Term[] assumptions; + Term[] terms; + Sort[] sorts; + string tmp; + + z3.ParseSmtlibString(smtlibString, new Sort[] { }, new FuncDecl[] { }, + out assumptions, out terms, out decls, out sorts, out tmp); + // TBD: check with Nikolaj about the correct position of assumptions + foreach (FuncDecl decl in decls) { + Symbol symbol = z3.GetDeclName(decl); + string functionName = z3.GetSymbolString(symbol); + functions.Add(functionName, decl); + } + foreach (Term assumption in assumptions) { + log("(assert {0})", assumption); + z3.AssertCnstr(assumption); + } + } + + private List<Sort> GetTypes(List<Type> boogieTypes) { + List<Sort> z3Types = new List<Sort>(); + foreach (Type boogieType in boogieTypes) { + Sort type = tm.GetType(boogieType); + z3Types.Add(type); + } + return z3Types; + } + + private static bool Equals(List<string> l, List<string> r) { + Debug.Assert(l != null); + if (r == null) + return false; + + if (l.Count != r.Count) + return false; + + for (int i = 0; i < l.Count; i++) + if (!l[i].Equals(r[i])) + return false; + return true; + } + + private void DisplayRelevantLabels(List<string> relevantLabels) { + foreach (string labelName in relevantLabels) { + System.Console.Write(labelName + ","); + } + System.Console.WriteLine("---"); + } + + private void DeclareConstant(string constantName, Type boogieType) { + Symbol symbolAst = GetSymbol(constantName); + Sort typeAst = tm.GetType(boogieType); + + Term constAst = z3.MkConst(symbolAst, typeAst); + constants.Add(constantName, constAst); + log("(declare-funs (({0} {1})))", constAst, typeAst); + } + + public ProverInterface.Outcome Check(out List<Z3ErrorModelAndLabels> boogieErrors) { + Microsoft.Boogie.Helpers.ExtraTraceInformation("Sending data to the theorem prover"); + boogieErrors = new List<Z3ErrorModelAndLabels>(); + LBool outcome = LBool.Undef; + Debug.Assert(0 < this.counterexamples); + while (true) { + Z3Model z3Model; + outcome = z3.CheckAndGetModel(out z3Model); + + log("(check-sat)"); + if (outcome == LBool.False) + break; + + if (outcome == LBool.Undef && z3Model == null) { + // Blame this on timeout + return ProverInterface.Outcome.TimeOut; + } + + Debug.Assert(z3Model != null); + LabeledLiterals labels = z3.GetRelevantLabels(); + Debug.Assert(labels != null); + + List<string> labelStrings = new List<string>(); + uint numLabels = labels.GetNumLabels(); + for (uint i = 0; i < numLabels; ++i) { + Symbol sym = labels.GetLabel(i); + string labelName = z3.GetSymbolString(sym); + if (!labelName.StartsWith("@")) { + labels.Disable(i); + } + labelStrings.Add(labelName); + } + + var sw = new StringWriter(); + sw.WriteLine("*** MODEL"); + z3Model.Display(sw); + sw.WriteLine("*** END_MODEL"); + var sr = new StringReader(sw.ToString()); + var models = Microsoft.Boogie.Model.ParseModels(sr); + Z3ErrorModelAndLabels e = new Z3ErrorModelAndLabels(models[0], new List<string>(labelStrings)); + boogieErrors.Add(e); + + if (boogieErrors.Count < this.counterexamples) { + z3.BlockLiterals(labels); + log("block-literals {0}", labels); + } + + labels.Dispose(); + z3Model.Dispose(); + if (boogieErrors.Count == this.counterexamples) + break; + } + + if (boogieErrors.Count > 0) { + return ProverInterface.Outcome.Invalid; + } + else if (outcome == LBool.False) { + return ProverInterface.Outcome.Valid; + } + else { + Debug.Assert(outcome == LBool.Undef); + return ProverInterface.Outcome.Undetermined; + } + } + + public ProverInterface.Outcome CheckAssumptions(List<VCExpr> assumptions, LineariserOptions linOptions, + out List<Z3ErrorModelAndLabels> boogieErrors, + out List<int> unsatCore) { + Microsoft.Boogie.Helpers.ExtraTraceInformation("Sending data to the theorem prover"); + boogieErrors = new List<Z3ErrorModelAndLabels>(); + unsatCore = new List<int>(); + LBool outcome = LBool.Undef; + + Z3Model z3Model; + Term proof; + Term[] core; + Term[] assumption_terms = new Term[assumptions.Count]; + var logstring = ""; + for (int i = 0; i < assumptions.Count; i++) { + Z3apiExprLineariser visitor = new Z3apiExprLineariser(this, namer); + Term z3ast = (Term)assumptions[i].Accept(visitor, linOptions); + assumption_terms[i] = z3ast; + logstring += string.Format("({0}) ", assumption_terms[i]); + } + + log("(get-core {0})", logstring); + outcome = z3.CheckAssumptions(out z3Model, assumption_terms, out proof, out core); + + if (outcome != LBool.False) { + Debug.Assert(z3Model != null); + LabeledLiterals labels = z3.GetRelevantLabels(); + Debug.Assert(labels != null); + + List<string> labelStrings = new List<string>(); + uint numLabels = labels.GetNumLabels(); + for (uint i = 0; i < numLabels; ++i) { + Symbol sym = labels.GetLabel(i); + string labelName = z3.GetSymbolString(sym); + if (!labelName.StartsWith("@")) { + labels.Disable(i); + } + labelStrings.Add(labelName); + } + + var sw = new StringWriter(); + sw.WriteLine("*** MODEL"); + z3Model.Display(sw); + sw.WriteLine("*** END_MODEL"); + var sr = new StringReader(sw.ToString()); + var models = Microsoft.Boogie.Model.ParseModels(sr); + Z3ErrorModelAndLabels e = new Z3ErrorModelAndLabels(models[0], new List<string>(labelStrings)); + boogieErrors.Add(e); + + labels.Dispose(); + z3Model.Dispose(); + } + + if (boogieErrors.Count > 0) { + return ProverInterface.Outcome.Invalid; + } + else if (outcome == LBool.False) { + foreach (Term t in core) { + for (int i = 0; i < assumption_terms.Length; i++) { + if (t.Equals(assumption_terms[i])) + unsatCore.Add(i); + } + } + return ProverInterface.Outcome.Valid; + } + else { + Debug.Assert(outcome == LBool.Undef); + return ProverInterface.Outcome.Undetermined; + } + } + + private Symbol GetSymbol(string symbolName) { + if (!symbols.ContainsKey(symbolName)) { + Symbol symbolAst = z3.MkSymbol(symbolName); + symbols.Add(symbolName, symbolAst); + } + Symbol result; + if (!symbols.TryGetValue(symbolName, out result)) + throw new Exception("symbol " + symbolName + " is undefined"); + return result; + } + + public Term GetConstant(string constantName, Type constantType, VCExpr node) + { + Term typeSafeTerm; + if (!constants.ContainsKey(constantName)) + this.DeclareConstant(constantName, constantType); + + if (!constants.TryGetValue(constantName, out typeSafeTerm)) + throw new Exception("constant " + constantName + " is not defined"); + + if (constants_inv != null && !constants_inv.ContainsKey(typeSafeTerm)) + constants_inv.Add(typeSafeTerm, node); + + return typeSafeTerm; + } + + public FuncDecl GetFunction(string functionName) { + FuncDecl f; + if (!functions.TryGetValue(functionName, out f)) + throw new Exception("function " + functionName + " is undefined"); + return f; + } + + public Term MakeLabel(string labelName, bool pos, Term child) { + Symbol labelSymbol = this.GetSymbol(labelName); + Term labeledExpr = z3.MkLabel(labelSymbol, pos, child); + labels.Add(labelName, labeledExpr); + return labeledExpr; + } + + public LabeledLiterals GetRelevantLabels() { + LabeledLiterals safeLiterals = z3.GetRelevantLabels(); + log("get-relevant-labels"); + return safeLiterals; + } + } + + internal class BacktrackDictionary<K, V> { + private Dictionary<K, V> dictionary = new Dictionary<K, V>(); + private Stack<List<K>> keyStack = new Stack<List<K>>(); + + public BacktrackDictionary() { + CreateBacktrackPoint(); + } + + public bool TryGetValue(K key, out V val) { + return dictionary.TryGetValue(key, out val); + } + + public void Add(K key, V v) { + if (dictionary.ContainsKey(key)) { + dictionary.Remove(key); + } + dictionary.Add(key, v); + keyStack.Peek().Add(key); + } + + public bool ContainsKey(K k) { + return dictionary.ContainsKey(k); + } + + public void CreateBacktrackPoint() { + keyStack.Push(new List<K>()); + } + + public void Backtrack() { + List<K> keysToErase = keyStack.Pop(); + foreach (K key in keysToErase) { + dictionary.Remove(key); + } + if (keyStack.Count == 0) + this.CreateBacktrackPoint(); + } + + public IEnumerator GetEnumerator() { + return dictionary.Keys.GetEnumerator(); + } + } + + public class Z3ErrorModelAndLabels { + private Model _model; + private List<string> _relevantLabels; + public Model Model { + get { return this._model; } + } + public List<string> RelevantLabels { + get { return this._relevantLabels; } + } + public Z3ErrorModelAndLabels(Model model, List<string> relevantLabels) { + this._model = model; + this._relevantLabels = relevantLabels; + } + } + + + }
\ No newline at end of file diff --git a/Source/Provers/Z3api/ProverLayer.cs b/Source/Provers/Z3api/ProverLayer.cs index d72705f3..cb7df8d7 100644 --- a/Source/Provers/Z3api/ProverLayer.cs +++ b/Source/Provers/Z3api/ProverLayer.cs @@ -1,354 +1,354 @@ -using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Threading;
-using System.IO;
-using System.Diagnostics;
-using Microsoft.Boogie.AbstractInterpretation;
-using Microsoft.Boogie;
-using Microsoft.Boogie.Z3;
-using Microsoft.Boogie.VCExprAST;
-using System.Diagnostics.Contracts;
-
-using TypeAst = System.IntPtr;
-using TermAst = System.IntPtr;
-using ConstDeclAst = System.IntPtr;
-using ConstAst = System.IntPtr;
-using Value = System.IntPtr;
-using PatternAst = System.IntPtr;
-
-namespace Microsoft.Boogie.Z3
-{
- public class Z3InstanceOptions : ProverOptions {
- public int Timeout { get { return TimeLimit / 1000; } }
- public int Lets {
- get {
- Contract.Ensures(0 <= Contract.Result<int>() && Contract.Result<int>() < 4);
- return CommandLineOptions.Clo.Z3lets;
- }
- }
- public bool DistZ3 = false;
- public string ExeName = "z3.exe";
- public bool InverseImplies = false;
- public string Inspector = null;
- public bool OptimizeForBv = false;
-
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(ExeName != null);
- }
-
- protected override bool Parse(string opt) {
- //Contract.Requires(opt!=null);
- return ParseBool(opt, "REVERSE_IMPLIES", ref InverseImplies) ||
- ParseString(opt, "INSPECTOR", ref Inspector) ||
- ParseBool(opt, "DIST", ref DistZ3) ||
- ParseBool(opt, "OPTIMIZE_FOR_BV", ref OptimizeForBv) ||
- base.Parse(opt);
- }
-
- public override void PostParse() {
- base.PostParse();
-
- if (DistZ3) {
- ExeName = "z3-dist.exe";
- CommandLineOptions.Clo.RestartProverPerVC = true;
- }
- }
-
- public override string Help {
- get {
- return
-@"
-Z3-specific options:
-~~~~~~~~~~~~~~~~~~~~
-INSPECTOR=<string> Use the specified Z3Inspector binary.
-OPTIMIZE_FOR_BV=<bool> Optimize Z3 options for bitvector reasoning, and not quantifier instantiation. Defaults to false.
-
-Obscure options:
-~~~~~~~~~~~~~~~~
-DIST=<bool> Use z3-dist.exe binary.
-REVERSE_IMPLIES=<bool> Encode P==>Q as Q||!P.
-
-" + base.Help;
- // DIST requires non-public binaries
- }
- }
- }
-
- public class Z3LineariserOptions : LineariserOptions {
- private readonly Z3InstanceOptions opts;
-
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(opts != null);
- }
-
-
- public Z3LineariserOptions(bool asTerm, Z3InstanceOptions opts, List<VCExprVar/*!>!*/> letVariables)
- : base(asTerm) {
- Contract.Requires(opts != null);
- Contract.Requires(cce.NonNullElements(letVariables));
-
- this.opts = opts;
- this.LetVariablesAttr = letVariables;
- }
-
- public override bool UseWeights {
- get {
- return true;
- }
- }
-
- public override bool UseTypes {
- get {
- return true;
- }
- }
-
- public override bool QuantifierIds {
- get {
- return true;
- }
- }
-
- public override bool InverseImplies {
- get {
- return opts.InverseImplies;
- }
- }
-
- public override LineariserOptions SetAsTerm(bool newVal) {
- Contract.Ensures(Contract.Result<LineariserOptions>() != null);
-
- if (newVal == AsTerm)
- return this;
- return new Z3LineariserOptions(newVal, opts, LetVariables);
- }
-
- // variables representing formulas in let-bindings have to be
- // printed in a different way than other variables
- private readonly List<VCExprVar/*!>!*/> LetVariablesAttr;
- public override List<VCExprVar/*!>!*/> LetVariables {
- get {
- Contract.Ensures(cce.NonNullElements(Contract.Result<List<VCExprVar>>()));
-
- return LetVariablesAttr;
- }
- }
-
- public override LineariserOptions AddLetVariable(VCExprVar furtherVar) {
- //Contract.Requires(furtherVar != null);
- Contract.Ensures(Contract.Result<LineariserOptions>() != null);
-
- List<VCExprVar/*!>!*/> allVars = new List<VCExprVar/*!*/>();
- allVars.AddRange(LetVariables);
- allVars.Add(furtherVar);
- return new Z3LineariserOptions(AsTerm, opts, allVars);
- }
-
- public override LineariserOptions AddLetVariables(List<VCExprVar/*!>!*/> furtherVars) {
- //Contract.Requires(furtherVars != null);
- Contract.Ensures(Contract.Result<LineariserOptions>() != null);
-
- List<VCExprVar/*!>!*/> allVars = new List<VCExprVar/*!*/>();
- allVars.AddRange(LetVariables);
- allVars.AddRange(furtherVars);
- return new Z3LineariserOptions(AsTerm, opts, allVars);
- }
- }
-
- public class Z3apiProcessTheoremProver : ProverInterface
- {
- public Z3apiProcessTheoremProver(Z3InstanceOptions opts, DeclFreeProverContext ctxt)
- {
- this.options = opts;
- this.context = (Z3apiProverContext) ctxt;
- this.numAxiomsPushed = 0;
- }
-
- private Z3InstanceOptions options;
-
- private Z3apiProverContext context;
- public override ProverContext Context
- {
- get { return context; }
- }
-
- public override VCExpressionGenerator VCExprGen
- {
- get { return context.ExprGen; }
- }
-
- private int numAxiomsPushed;
-
- public override void Close()
- {
- base.Close();
- context.CloseLog();
- context.z3.Dispose();
- context.config.Dispose();
- }
-
- public void PushAxiom(VCExpr axiom)
- {
- context.CreateBacktrackPoint();
- LineariserOptions linOptions = new Z3LineariserOptions(false, (Z3InstanceOptions)this.options, new List<VCExprVar>());
- context.AddAxiom(axiom, linOptions);
- }
-
- private void PushConjecture(VCExpr conjecture)
- {
- context.CreateBacktrackPoint();
- LineariserOptions linOptions = new Z3LineariserOptions(false, (Z3InstanceOptions)this.options, new List<VCExprVar>());
- context.AddConjecture(conjecture, linOptions);
- }
-
- public override void PushVCExpression(VCExpr vc)
- {
- PushAxiom(vc);
- numAxiomsPushed++;
- }
-
- public void CreateBacktrackPoint()
- {
- context.CreateBacktrackPoint();
- }
-
- public override void BeginCheck(string descriptiveName, VCExpr vc, ErrorHandler handler)
- {
- LineariserOptions linOptions = new Z3LineariserOptions(false, (Z3InstanceOptions)this.options, new List<VCExprVar>());
- Push();
- context.AddAxiom(context.Axioms, linOptions);
- context.AddConjecture(vc, linOptions);
- outcome = context.Check(out z3LabelModels);
- Pop();
- }
-
- public override void Check()
- {
- outcome = context.Check(out z3LabelModels);
- }
-
- public override ProverInterface.Outcome CheckAssumptions(List<VCExpr> assumptions, out List<int> unsatCore, ErrorHandler handler)
- {
- LineariserOptions linOptions = new Z3LineariserOptions(false, (Z3InstanceOptions)this.options, new List<VCExprVar>());
- return context.CheckAssumptions(assumptions, linOptions, out z3LabelModels, out unsatCore);
- }
-
- public override void Push()
- {
- context.CreateBacktrackPoint();
- }
-
- public override void Pop()
- {
- context.Backtrack();
- }
-
- public override void Assert(VCExpr vc, bool polarity)
- {
- LineariserOptions linOptions = new Z3LineariserOptions(false, (Z3InstanceOptions)this.options, new List<VCExprVar>());
- if (polarity)
- context.AddAxiom(vc, linOptions);
- else
- context.AddConjecture(vc, linOptions);
- }
-
- public override void AssertAxioms()
- {
- LineariserOptions linOptions = new Z3LineariserOptions(false, (Z3InstanceOptions)this.options, new List<VCExprVar>());
- context.AddAxiom(context.Axioms, linOptions);
- }
-
- // Number of axioms pushed since the last call to FlushAxioms
- public override int NumAxiomsPushed()
- {
- return numAxiomsPushed;
- }
-
- public override int FlushAxiomsToTheoremProver()
- {
- var ret = numAxiomsPushed;
- numAxiomsPushed = 0;
- return ret;
- }
-
- private Outcome outcome;
- private List<Z3ErrorModelAndLabels> z3LabelModels = new List<Z3ErrorModelAndLabels>();
-
- [NoDefaultContract]
- public override Outcome CheckOutcome(ErrorHandler handler)
- {
- if (outcome == Outcome.Invalid)
- {
- foreach (Z3ErrorModelAndLabels z3LabelModel in z3LabelModels)
- {
- List<string> unprefixedLabels = RemovePrefixes(z3LabelModel.RelevantLabels);
- handler.OnModel(unprefixedLabels, z3LabelModel.Model);
- }
- }
- return outcome;
- }
-
- public override Outcome CheckOutcomeCore(ErrorHandler handler) {
- if (outcome == Outcome.Invalid) {
- foreach (Z3ErrorModelAndLabels z3LabelModel in z3LabelModels) {
- List<string> unprefixedLabels = RemovePrefixes(z3LabelModel.RelevantLabels);
- handler.OnModel(unprefixedLabels, z3LabelModel.Model);
- }
- }
- return outcome;
- }
-
- private List<string> RemovePrefixes(List<string> labels)
- {
- List<string> result = new List<string>();
- foreach (string label in labels)
- {
- if (label.StartsWith("+"))
- {
- result.Add(label.Substring(1));
- }
- else if (label.StartsWith("|"))
- {
- result.Add(label.Substring(1));
- }
- else if (label.StartsWith("@"))
- {
- result.Add(label.Substring(1));
- }
- else
- throw new Exception("Unknown prefix in label " + label);
- }
- return result;
- }
- }
-}
-
-namespace Microsoft.Boogie.Z3api
-{
- public class Factory : ProverFactory
- {
- public override object SpawnProver(ProverOptions options, object ctxt)
- {
- return new Z3apiProcessTheoremProver((Z3InstanceOptions) options, (Z3apiProverContext) ctxt);
- }
-
- public override object NewProverContext(ProverOptions opts)
- {
- if (CommandLineOptions.Clo.BracketIdsInVC < 0)
- {
- CommandLineOptions.Clo.BracketIdsInVC = 0;
- }
-
- VCExpressionGenerator gen = new VCExpressionGenerator();
- return new Z3apiProverContext((Z3InstanceOptions)opts, gen);
- }
-
- public override ProverOptions BlankProverOptions()
- {
- return new Z3InstanceOptions();
- }
- }
+using System; +using System.Collections; +using System.Collections.Generic; +using System.Threading; +using System.IO; +using System.Diagnostics; +using Microsoft.Boogie.AbstractInterpretation; +using Microsoft.Boogie; +using Microsoft.Boogie.Z3; +using Microsoft.Boogie.VCExprAST; +using System.Diagnostics.Contracts; + +using TypeAst = System.IntPtr; +using TermAst = System.IntPtr; +using ConstDeclAst = System.IntPtr; +using ConstAst = System.IntPtr; +using Value = System.IntPtr; +using PatternAst = System.IntPtr; + +namespace Microsoft.Boogie.Z3 +{ + public class Z3InstanceOptions : ProverOptions { + public int Timeout { get { return TimeLimit / 1000; } } + public int Lets { + get { + Contract.Ensures(0 <= Contract.Result<int>() && Contract.Result<int>() < 4); + return CommandLineOptions.Clo.Z3lets; + } + } + public bool DistZ3 = false; + public string ExeName = "z3.exe"; + public bool InverseImplies = false; + public string Inspector = null; + public bool OptimizeForBv = false; + + [ContractInvariantMethod] + void ObjectInvariant() { + Contract.Invariant(ExeName != null); + } + + protected override bool Parse(string opt) { + //Contract.Requires(opt!=null); + return ParseBool(opt, "REVERSE_IMPLIES", ref InverseImplies) || + ParseString(opt, "INSPECTOR", ref Inspector) || + ParseBool(opt, "DIST", ref DistZ3) || + ParseBool(opt, "OPTIMIZE_FOR_BV", ref OptimizeForBv) || + base.Parse(opt); + } + + public override void PostParse() { + base.PostParse(); + + if (DistZ3) { + ExeName = "z3-dist.exe"; + CommandLineOptions.Clo.RestartProverPerVC = true; + } + } + + public override string Help { + get { + return +@" +Z3-specific options: +~~~~~~~~~~~~~~~~~~~~ +INSPECTOR=<string> Use the specified Z3Inspector binary. +OPTIMIZE_FOR_BV=<bool> Optimize Z3 options for bitvector reasoning, and not quantifier instantiation. Defaults to false. + +Obscure options: +~~~~~~~~~~~~~~~~ +DIST=<bool> Use z3-dist.exe binary. +REVERSE_IMPLIES=<bool> Encode P==>Q as Q||!P. + +" + base.Help; + // DIST requires non-public binaries + } + } + } + + public class Z3LineariserOptions : LineariserOptions { + private readonly Z3InstanceOptions opts; + + [ContractInvariantMethod] + void ObjectInvariant() { + Contract.Invariant(opts != null); + } + + + public Z3LineariserOptions(bool asTerm, Z3InstanceOptions opts, List<VCExprVar/*!>!*/> letVariables) + : base(asTerm) { + Contract.Requires(opts != null); + Contract.Requires(cce.NonNullElements(letVariables)); + + this.opts = opts; + this.LetVariablesAttr = letVariables; + } + + public override bool UseWeights { + get { + return true; + } + } + + public override bool UseTypes { + get { + return true; + } + } + + public override bool QuantifierIds { + get { + return true; + } + } + + public override bool InverseImplies { + get { + return opts.InverseImplies; + } + } + + public override LineariserOptions SetAsTerm(bool newVal) { + Contract.Ensures(Contract.Result<LineariserOptions>() != null); + + if (newVal == AsTerm) + return this; + return new Z3LineariserOptions(newVal, opts, LetVariables); + } + + // variables representing formulas in let-bindings have to be + // printed in a different way than other variables + private readonly List<VCExprVar/*!>!*/> LetVariablesAttr; + public override List<VCExprVar/*!>!*/> LetVariables { + get { + Contract.Ensures(cce.NonNullElements(Contract.Result<List<VCExprVar>>())); + + return LetVariablesAttr; + } + } + + public override LineariserOptions AddLetVariable(VCExprVar furtherVar) { + //Contract.Requires(furtherVar != null); + Contract.Ensures(Contract.Result<LineariserOptions>() != null); + + List<VCExprVar/*!>!*/> allVars = new List<VCExprVar/*!*/>(); + allVars.AddRange(LetVariables); + allVars.Add(furtherVar); + return new Z3LineariserOptions(AsTerm, opts, allVars); + } + + public override LineariserOptions AddLetVariables(List<VCExprVar/*!>!*/> furtherVars) { + //Contract.Requires(furtherVars != null); + Contract.Ensures(Contract.Result<LineariserOptions>() != null); + + List<VCExprVar/*!>!*/> allVars = new List<VCExprVar/*!*/>(); + allVars.AddRange(LetVariables); + allVars.AddRange(furtherVars); + return new Z3LineariserOptions(AsTerm, opts, allVars); + } + } + + public class Z3apiProcessTheoremProver : ProverInterface + { + public Z3apiProcessTheoremProver(Z3InstanceOptions opts, DeclFreeProverContext ctxt) + { + this.options = opts; + this.context = (Z3apiProverContext) ctxt; + this.numAxiomsPushed = 0; + } + + private Z3InstanceOptions options; + + private Z3apiProverContext context; + public override ProverContext Context + { + get { return context; } + } + + public override VCExpressionGenerator VCExprGen + { + get { return context.ExprGen; } + } + + private int numAxiomsPushed; + + public override void Close() + { + base.Close(); + context.CloseLog(); + context.z3.Dispose(); + context.config.Dispose(); + } + + public void PushAxiom(VCExpr axiom) + { + context.CreateBacktrackPoint(); + LineariserOptions linOptions = new Z3LineariserOptions(false, (Z3InstanceOptions)this.options, new List<VCExprVar>()); + context.AddAxiom(axiom, linOptions); + } + + private void PushConjecture(VCExpr conjecture) + { + context.CreateBacktrackPoint(); + LineariserOptions linOptions = new Z3LineariserOptions(false, (Z3InstanceOptions)this.options, new List<VCExprVar>()); + context.AddConjecture(conjecture, linOptions); + } + + public override void PushVCExpression(VCExpr vc) + { + PushAxiom(vc); + numAxiomsPushed++; + } + + public void CreateBacktrackPoint() + { + context.CreateBacktrackPoint(); + } + + public override void BeginCheck(string descriptiveName, VCExpr vc, ErrorHandler handler) + { + LineariserOptions linOptions = new Z3LineariserOptions(false, (Z3InstanceOptions)this.options, new List<VCExprVar>()); + Push(); + context.AddAxiom(context.Axioms, linOptions); + context.AddConjecture(vc, linOptions); + outcome = context.Check(out z3LabelModels); + Pop(); + } + + public override void Check() + { + outcome = context.Check(out z3LabelModels); + } + + public override ProverInterface.Outcome CheckAssumptions(List<VCExpr> assumptions, out List<int> unsatCore, ErrorHandler handler) + { + LineariserOptions linOptions = new Z3LineariserOptions(false, (Z3InstanceOptions)this.options, new List<VCExprVar>()); + return context.CheckAssumptions(assumptions, linOptions, out z3LabelModels, out unsatCore); + } + + public override void Push() + { + context.CreateBacktrackPoint(); + } + + public override void Pop() + { + context.Backtrack(); + } + + public override void Assert(VCExpr vc, bool polarity) + { + LineariserOptions linOptions = new Z3LineariserOptions(false, (Z3InstanceOptions)this.options, new List<VCExprVar>()); + if (polarity) + context.AddAxiom(vc, linOptions); + else + context.AddConjecture(vc, linOptions); + } + + public override void AssertAxioms() + { + LineariserOptions linOptions = new Z3LineariserOptions(false, (Z3InstanceOptions)this.options, new List<VCExprVar>()); + context.AddAxiom(context.Axioms, linOptions); + } + + // Number of axioms pushed since the last call to FlushAxioms + public override int NumAxiomsPushed() + { + return numAxiomsPushed; + } + + public override int FlushAxiomsToTheoremProver() + { + var ret = numAxiomsPushed; + numAxiomsPushed = 0; + return ret; + } + + private Outcome outcome; + private List<Z3ErrorModelAndLabels> z3LabelModels = new List<Z3ErrorModelAndLabels>(); + + [NoDefaultContract] + public override Outcome CheckOutcome(ErrorHandler handler) + { + if (outcome == Outcome.Invalid) + { + foreach (Z3ErrorModelAndLabels z3LabelModel in z3LabelModels) + { + List<string> unprefixedLabels = RemovePrefixes(z3LabelModel.RelevantLabels); + handler.OnModel(unprefixedLabels, z3LabelModel.Model); + } + } + return outcome; + } + + public override Outcome CheckOutcomeCore(ErrorHandler handler) { + if (outcome == Outcome.Invalid) { + foreach (Z3ErrorModelAndLabels z3LabelModel in z3LabelModels) { + List<string> unprefixedLabels = RemovePrefixes(z3LabelModel.RelevantLabels); + handler.OnModel(unprefixedLabels, z3LabelModel.Model); + } + } + return outcome; + } + + private List<string> RemovePrefixes(List<string> labels) + { + List<string> result = new List<string>(); + foreach (string label in labels) + { + if (label.StartsWith("+")) + { + result.Add(label.Substring(1)); + } + else if (label.StartsWith("|")) + { + result.Add(label.Substring(1)); + } + else if (label.StartsWith("@")) + { + result.Add(label.Substring(1)); + } + else + throw new Exception("Unknown prefix in label " + label); + } + return result; + } + } +} + +namespace Microsoft.Boogie.Z3api +{ + public class Factory : ProverFactory + { + public override object SpawnProver(ProverOptions options, object ctxt) + { + return new Z3apiProcessTheoremProver((Z3InstanceOptions) options, (Z3apiProverContext) ctxt); + } + + public override object NewProverContext(ProverOptions opts) + { + if (CommandLineOptions.Clo.BracketIdsInVC < 0) + { + CommandLineOptions.Clo.BracketIdsInVC = 0; + } + + VCExpressionGenerator gen = new VCExpressionGenerator(); + return new Z3apiProverContext((Z3InstanceOptions)opts, gen); + } + + public override ProverOptions BlankProverOptions() + { + return new Z3InstanceOptions(); + } + } }
\ No newline at end of file diff --git a/Source/Provers/Z3api/SafeContext.cs b/Source/Provers/Z3api/SafeContext.cs index 72192804..b83d6dff 100644 --- a/Source/Provers/Z3api/SafeContext.cs +++ b/Source/Provers/Z3api/SafeContext.cs @@ -1,16 +1,16 @@ -using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Threading;
-using System.IO;
-using System.Diagnostics;
-using Microsoft.Boogie.AbstractInterpretation;
-using Microsoft.Boogie;
-using Microsoft.Boogie.Z3;
-using Microsoft.Z3;
-using Microsoft.Boogie.VCExprAST;
-
-namespace Microsoft.Boogie.Z3
-{
-
+using System; +using System.Collections; +using System.Collections.Generic; +using System.Threading; +using System.IO; +using System.Diagnostics; +using Microsoft.Boogie.AbstractInterpretation; +using Microsoft.Boogie; +using Microsoft.Boogie.Z3; +using Microsoft.Z3; +using Microsoft.Boogie.VCExprAST; + +namespace Microsoft.Boogie.Z3 +{ + }
\ No newline at end of file diff --git a/Source/Provers/Z3api/StubContext.cs b/Source/Provers/Z3api/StubContext.cs index b129b378..79f140aa 100644 --- a/Source/Provers/Z3api/StubContext.cs +++ b/Source/Provers/Z3api/StubContext.cs @@ -1,75 +1,75 @@ -using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Threading;
-using System.IO;
-using System.Diagnostics;
-using Microsoft.Boogie.AbstractInterpretation;
-using Microsoft.Boogie;
-using Microsoft.Boogie.Z3;
-using Microsoft.Z3;
-using Microsoft.Boogie.VCExprAST;
-
-namespace Microsoft.Boogie.Z3 {
- public class Z3StubContext : Z3Context {
- class Z3StubPatternAst: Z3PatternAst {}
- class Z3StubTermAst: Z3TermAst {}
- class Z3StubLabeledLiterals: Z3LabeledLiterals {}
-
- public void CreateBacktrackPoint(){}
- public void Backtrack(){}
- public void AddAxiom(VCExpr axiom, LineariserOptions linOptions) { }
- public void AddConjecture(VCExpr vc, LineariserOptions linOptions){}
- public void AddSmtlibString(string smtlibString) {}
- public string GetDeclName(Z3ConstDeclAst constDeclAst) {
- return "";
- }
- public Z3PatternAst MakePattern(List<Z3TermAst> exprs) {
- return new Z3StubPatternAst();
- }
- public Z3TermAst MakeQuantifier(bool isForall, uint weight, string qid, int skolemid, List<string> varNames, List<Type> boogieTypes, List<Z3PatternAst> patterns, List<Z3TermAst> no_patterns, Z3TermAst body) {
- return new Z3StubTermAst();
- }
- public ProverInterface.Outcome Check(out List<Z3ErrorModelAndLabels> boogieErrors) {
- boogieErrors = new List<Z3ErrorModelAndLabels>();
- return ProverInterface.Outcome.Undetermined;
- }
- public void TypeCheckBool(Z3TermAst t){}
- public void TypeCheckInt(Z3TermAst t){}
- public void DeclareType(string typeName) {}
- public void DeclareConstant(string constantName, Type boogieType) {}
- public void DeclareFunction(string functionName, List<Type> domain, Type range) {}
- public Z3TermAst GetConstant(string constantName, Type constantType) {
- return new Z3StubTermAst();
- }
- public Z3TermAst MakeIntLiteral(string numeral) {
- return new Z3StubTermAst();
- }
- public Z3TermAst MakeBvLiteral(int i, uint bvSize) {
- return new Z3StubTermAst();
- }
- public Z3TermAst MakeTrue() {
- return new Z3StubTermAst();
- }
- public Z3TermAst MakeFalse() {
- return new Z3StubTermAst();
- }
- public Z3TermAst MakeLabel(string labelName, bool pos, Z3TermAst child) {
- return new Z3StubTermAst();
- }
- public Z3LabeledLiterals GetRelevantLabels() {
- return new Z3StubLabeledLiterals();
- }
- public Z3TermAst Make(string op, List<Z3TermAst> children) {
- return new Z3StubTermAst();
- }
- public Z3TermAst MakeArraySelect(List<Z3TermAst> args)
- {
- return new Z3StubTermAst();
- }
- public Z3TermAst MakeArrayStore(List<Z3TermAst> args)
- {
- return new Z3StubTermAst();
- }
- }
+using System; +using System.Collections; +using System.Collections.Generic; +using System.Threading; +using System.IO; +using System.Diagnostics; +using Microsoft.Boogie.AbstractInterpretation; +using Microsoft.Boogie; +using Microsoft.Boogie.Z3; +using Microsoft.Z3; +using Microsoft.Boogie.VCExprAST; + +namespace Microsoft.Boogie.Z3 { + public class Z3StubContext : Z3Context { + class Z3StubPatternAst: Z3PatternAst {} + class Z3StubTermAst: Z3TermAst {} + class Z3StubLabeledLiterals: Z3LabeledLiterals {} + + public void CreateBacktrackPoint(){} + public void Backtrack(){} + public void AddAxiom(VCExpr axiom, LineariserOptions linOptions) { } + public void AddConjecture(VCExpr vc, LineariserOptions linOptions){} + public void AddSmtlibString(string smtlibString) {} + public string GetDeclName(Z3ConstDeclAst constDeclAst) { + return ""; + } + public Z3PatternAst MakePattern(List<Z3TermAst> exprs) { + return new Z3StubPatternAst(); + } + public Z3TermAst MakeQuantifier(bool isForall, uint weight, string qid, int skolemid, List<string> varNames, List<Type> boogieTypes, List<Z3PatternAst> patterns, List<Z3TermAst> no_patterns, Z3TermAst body) { + return new Z3StubTermAst(); + } + public ProverInterface.Outcome Check(out List<Z3ErrorModelAndLabels> boogieErrors) { + boogieErrors = new List<Z3ErrorModelAndLabels>(); + return ProverInterface.Outcome.Undetermined; + } + public void TypeCheckBool(Z3TermAst t){} + public void TypeCheckInt(Z3TermAst t){} + public void DeclareType(string typeName) {} + public void DeclareConstant(string constantName, Type boogieType) {} + public void DeclareFunction(string functionName, List<Type> domain, Type range) {} + public Z3TermAst GetConstant(string constantName, Type constantType) { + return new Z3StubTermAst(); + } + public Z3TermAst MakeIntLiteral(string numeral) { + return new Z3StubTermAst(); + } + public Z3TermAst MakeBvLiteral(int i, uint bvSize) { + return new Z3StubTermAst(); + } + public Z3TermAst MakeTrue() { + return new Z3StubTermAst(); + } + public Z3TermAst MakeFalse() { + return new Z3StubTermAst(); + } + public Z3TermAst MakeLabel(string labelName, bool pos, Z3TermAst child) { + return new Z3StubTermAst(); + } + public Z3LabeledLiterals GetRelevantLabels() { + return new Z3StubLabeledLiterals(); + } + public Z3TermAst Make(string op, List<Z3TermAst> children) { + return new Z3StubTermAst(); + } + public Z3TermAst MakeArraySelect(List<Z3TermAst> args) + { + return new Z3StubTermAst(); + } + public Z3TermAst MakeArrayStore(List<Z3TermAst> args) + { + return new Z3StubTermAst(); + } + } }
\ No newline at end of file diff --git a/Source/Provers/Z3api/TypeAdapter.cs b/Source/Provers/Z3api/TypeAdapter.cs index 879211f7..f2a9a8fd 100644 --- a/Source/Provers/Z3api/TypeAdapter.cs +++ b/Source/Provers/Z3api/TypeAdapter.cs @@ -1,197 +1,197 @@ -using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Threading;
-using System.IO;
-using System.Diagnostics;
-using Microsoft.Boogie.AbstractInterpretation;
-using Microsoft.Boogie;
-using Microsoft.Boogie.Z3;
-using Microsoft.Z3;
-using Microsoft.Boogie.VCExprAST;
-
-namespace Microsoft.Boogie.Z3
-{
- internal class Z3TypeCachedBuilder
- {
- private class MapTypeComparator : IEqualityComparer<MapType>
- {
- public bool Equals(MapType x, MapType y)
- {
- if (x.MapArity != y.MapArity)
- return false;
- for (int i = 0; i < x.MapArity; i++)
- {
- if (!Equals(x.Arguments[i], y.Arguments[i]))
- return false;
- }
- return Equals(x.Result, y.Result);
-
- }
- public int GetHashCode(MapType mapType)
- {
- return mapType.GetHashCode();
- }
- }
-
- private class BvTypeComparator : IEqualityComparer<BvType>
- {
- public bool Equals(BvType x, BvType y)
- {
- return x.Bits == y.Bits;
- }
- public int GetHashCode(BvType bvType)
- {
- return bvType.Bits;
- }
- }
-
- private class BasicTypeComparator : IEqualityComparer<BasicType>
- {
- public bool Equals(BasicType x, BasicType y)
- {
- return (x.IsBool == y.IsBool) &&
- (x.IsInt == y.IsInt) &&
- (x.IsReal == y.IsReal);
- }
-
- public int GetHashCode(BasicType basicType)
- {
- if (basicType.IsBool)
- return 1;
- else if (basicType.IsInt)
- return 2;
- else if (basicType.IsReal)
- return 3;
- else
- throw new Exception("Basic Type " + basicType.ToString() + " is unkwown");
- }
- }
-
- private class CtorTypeComparator : IEqualityComparer<CtorType> {
- public bool Equals(CtorType x, CtorType y) {
- return (x.Decl.Name == y.Decl.Name);
- }
-
- public int GetHashCode(CtorType ctorType) {
- return ctorType.Decl.Name.GetHashCode();
- }
- }
-
- private Dictionary<MapType, Sort> mapTypes = new Dictionary<MapType, Sort>(new MapTypeComparator());
- private Dictionary<BvType, Sort> bvTypes = new Dictionary<BvType, Sort>(new BvTypeComparator());
- private Dictionary<BasicType, Sort> basicTypes = new Dictionary<BasicType, Sort>(new BasicTypeComparator());
- private Dictionary<CtorType, Sort> ctorTypes = new Dictionary<CtorType, Sort>(new CtorTypeComparator());
-
- private Z3apiProverContext container;
-
- public Z3TypeCachedBuilder(Z3apiProverContext context)
- {
- this.container = context;
- }
-
- private Sort GetMapType(MapType mapType) {
- Context z3 = ((Z3apiProverContext)container).z3;
- if (!mapTypes.ContainsKey(mapType)) {
- Type result = mapType.Result;
- for (int i = mapType.Arguments.Length-1; i > 0; i--) {
- GetType(result);
- result = new MapType(mapType.tok, new TypeVariableSeq(), new TypeSeq(mapType.Arguments[i]), result);
- }
- mapTypes.Add(mapType, BuildMapType(GetType(mapType.Arguments[0]), GetType(result)));
- }
- return mapTypes[mapType];
- }
-
- private Sort GetBvType(BvType bvType)
- {
- if (!bvTypes.ContainsKey(bvType))
- {
- Sort typeAst = BuildBvType(bvType);
- bvTypes.Add(bvType, typeAst);
- }
- Sort result;
- bool containsKey = bvTypes.TryGetValue(bvType, out result);
- Debug.Assert(containsKey);
- return result;
- }
-
- private Sort GetBasicType(BasicType basicType)
- {
- if (!basicTypes.ContainsKey(basicType))
- {
- Sort typeAst = BuildBasicType(basicType);
- basicTypes.Add(basicType, typeAst);
- }
- Sort result;
- bool containsKey = basicTypes.TryGetValue(basicType, out result);
- Debug.Assert(containsKey);
- return result;
- }
-
- private Sort GetCtorType(CtorType ctorType) {
- if (!ctorTypes.ContainsKey(ctorType)) {
- Sort typeAst = BuildCtorType(ctorType);
- ctorTypes.Add(ctorType, typeAst);
- }
- Sort result;
- bool containsKey = ctorTypes.TryGetValue(ctorType, out result);
- Debug.Assert(containsKey);
- return result;
- }
-
- public virtual Sort GetType(Type boogieType) {
- System.Type type = boogieType.GetType();
- if (type.Equals(typeof(BvType)))
- return GetBvType((BvType)boogieType);
- else if (type.Equals(typeof(BasicType)))
- return GetBasicType((BasicType)boogieType);
- else if (type.Equals(typeof(MapType)))
- return GetMapType((MapType)boogieType);
- else if (type.Equals(typeof(CtorType)))
- return GetCtorType((CtorType)boogieType);
- else
- throw new Exception("Boogie Type " + boogieType.GetType() + " is unknown");
- }
-
- public Sort BuildMapType(Sort domain, Sort range)
- {
- Context z3 = ((Z3apiProverContext)container).z3;
- return z3.MkArraySort(domain, range);
- }
-
- public Sort BuildBvType(BvType bvType)
- {
- Context z3 = ((Z3apiProverContext)container).z3;
- return z3.MkBvSort((uint)bvType.Bits);
- }
-
- public Sort BuildBasicType(BasicType basicType)
- {
- Context z3 = ((Z3apiProverContext)container).z3;
- Sort typeAst;
- if (basicType.IsBool)
- {
- typeAst = z3.MkBoolSort();
- }
- else if (basicType.IsInt)
- {
- typeAst = z3.MkIntSort();
- }
- else if (basicType.IsReal)
- {
- typeAst = z3.MkRealSort();
- }
- else
- throw new Exception("Unknown Basic Type " + basicType.ToString());
- return typeAst;
- }
-
- public Sort BuildCtorType(CtorType ctorType) {
- Context z3 = ((Z3apiProverContext)container).z3;
- if (ctorType.Arguments.Length > 0)
- throw new Exception("Type constructor of non-zero arity are not handled");
- return z3.MkSort(ctorType.Decl.Name);
- }
- }
+using System; +using System.Collections; +using System.Collections.Generic; +using System.Threading; +using System.IO; +using System.Diagnostics; +using Microsoft.Boogie.AbstractInterpretation; +using Microsoft.Boogie; +using Microsoft.Boogie.Z3; +using Microsoft.Z3; +using Microsoft.Boogie.VCExprAST; + +namespace Microsoft.Boogie.Z3 +{ + internal class Z3TypeCachedBuilder + { + private class MapTypeComparator : IEqualityComparer<MapType> + { + public bool Equals(MapType x, MapType y) + { + if (x.MapArity != y.MapArity) + return false; + for (int i = 0; i < x.MapArity; i++) + { + if (!Equals(x.Arguments[i], y.Arguments[i])) + return false; + } + return Equals(x.Result, y.Result); + + } + public int GetHashCode(MapType mapType) + { + return mapType.GetHashCode(); + } + } + + private class BvTypeComparator : IEqualityComparer<BvType> + { + public bool Equals(BvType x, BvType y) + { + return x.Bits == y.Bits; + } + public int GetHashCode(BvType bvType) + { + return bvType.Bits; + } + } + + private class BasicTypeComparator : IEqualityComparer<BasicType> + { + public bool Equals(BasicType x, BasicType y) + { + return (x.IsBool == y.IsBool) && + (x.IsInt == y.IsInt) && + (x.IsReal == y.IsReal); + } + + public int GetHashCode(BasicType basicType) + { + if (basicType.IsBool) + return 1; + else if (basicType.IsInt) + return 2; + else if (basicType.IsReal) + return 3; + else + throw new Exception("Basic Type " + basicType.ToString() + " is unkwown"); + } + } + + private class CtorTypeComparator : IEqualityComparer<CtorType> { + public bool Equals(CtorType x, CtorType y) { + return (x.Decl.Name == y.Decl.Name); + } + + public int GetHashCode(CtorType ctorType) { + return ctorType.Decl.Name.GetHashCode(); + } + } + + private Dictionary<MapType, Sort> mapTypes = new Dictionary<MapType, Sort>(new MapTypeComparator()); + private Dictionary<BvType, Sort> bvTypes = new Dictionary<BvType, Sort>(new BvTypeComparator()); + private Dictionary<BasicType, Sort> basicTypes = new Dictionary<BasicType, Sort>(new BasicTypeComparator()); + private Dictionary<CtorType, Sort> ctorTypes = new Dictionary<CtorType, Sort>(new CtorTypeComparator()); + + private Z3apiProverContext container; + + public Z3TypeCachedBuilder(Z3apiProverContext context) + { + this.container = context; + } + + private Sort GetMapType(MapType mapType) { + Context z3 = ((Z3apiProverContext)container).z3; + if (!mapTypes.ContainsKey(mapType)) { + Type result = mapType.Result; + for (int i = mapType.Arguments.Length-1; i > 0; i--) { + GetType(result); + result = new MapType(mapType.tok, new TypeVariableSeq(), new TypeSeq(mapType.Arguments[i]), result); + } + mapTypes.Add(mapType, BuildMapType(GetType(mapType.Arguments[0]), GetType(result))); + } + return mapTypes[mapType]; + } + + private Sort GetBvType(BvType bvType) + { + if (!bvTypes.ContainsKey(bvType)) + { + Sort typeAst = BuildBvType(bvType); + bvTypes.Add(bvType, typeAst); + } + Sort result; + bool containsKey = bvTypes.TryGetValue(bvType, out result); + Debug.Assert(containsKey); + return result; + } + + private Sort GetBasicType(BasicType basicType) + { + if (!basicTypes.ContainsKey(basicType)) + { + Sort typeAst = BuildBasicType(basicType); + basicTypes.Add(basicType, typeAst); + } + Sort result; + bool containsKey = basicTypes.TryGetValue(basicType, out result); + Debug.Assert(containsKey); + return result; + } + + private Sort GetCtorType(CtorType ctorType) { + if (!ctorTypes.ContainsKey(ctorType)) { + Sort typeAst = BuildCtorType(ctorType); + ctorTypes.Add(ctorType, typeAst); + } + Sort result; + bool containsKey = ctorTypes.TryGetValue(ctorType, out result); + Debug.Assert(containsKey); + return result; + } + + public virtual Sort GetType(Type boogieType) { + System.Type type = boogieType.GetType(); + if (type.Equals(typeof(BvType))) + return GetBvType((BvType)boogieType); + else if (type.Equals(typeof(BasicType))) + return GetBasicType((BasicType)boogieType); + else if (type.Equals(typeof(MapType))) + return GetMapType((MapType)boogieType); + else if (type.Equals(typeof(CtorType))) + return GetCtorType((CtorType)boogieType); + else + throw new Exception("Boogie Type " + boogieType.GetType() + " is unknown"); + } + + public Sort BuildMapType(Sort domain, Sort range) + { + Context z3 = ((Z3apiProverContext)container).z3; + return z3.MkArraySort(domain, range); + } + + public Sort BuildBvType(BvType bvType) + { + Context z3 = ((Z3apiProverContext)container).z3; + return z3.MkBvSort((uint)bvType.Bits); + } + + public Sort BuildBasicType(BasicType basicType) + { + Context z3 = ((Z3apiProverContext)container).z3; + Sort typeAst; + if (basicType.IsBool) + { + typeAst = z3.MkBoolSort(); + } + else if (basicType.IsInt) + { + typeAst = z3.MkIntSort(); + } + else if (basicType.IsReal) + { + typeAst = z3.MkRealSort(); + } + else + throw new Exception("Unknown Basic Type " + basicType.ToString()); + return typeAst; + } + + public Sort BuildCtorType(CtorType ctorType) { + Context z3 = ((Z3apiProverContext)container).z3; + if (ctorType.Arguments.Length > 0) + throw new Exception("Type constructor of non-zero arity are not handled"); + return z3.MkSort(ctorType.Decl.Name); + } + } }
\ No newline at end of file diff --git a/Source/Provers/Z3api/VCExprVisitor.cs b/Source/Provers/Z3api/VCExprVisitor.cs index e56a7950..52c7d8fd 100644 --- a/Source/Provers/Z3api/VCExprVisitor.cs +++ b/Source/Provers/Z3api/VCExprVisitor.cs @@ -1,649 +1,649 @@ -//-----------------------------------------------------------------------------
-//
-// Copyright (C) Microsoft Corporation. All Rights Reserved.
-//
-//-----------------------------------------------------------------------------
-using System;
-using System.Text;
-using System.IO;
-using System.Collections;
-using System.Collections.Generic;
-using System.Diagnostics.Contracts;
-using Microsoft.Basetypes;
-using Microsoft.Boogie.VCExprAST;
-using Microsoft.Z3;
-
-namespace Microsoft.Boogie.Z3
-{
- using System.Numerics.BigInteger;
-
- public class Z3apiExprLineariser : IVCExprVisitor<Term, LineariserOptions>
- {
- private Z3apiOpLineariser opLineariser = null;
- private IVCExprOpVisitor<Term, LineariserOptions> OpLineariser
- {
- get
- {
- Contract.Ensures(Contract.Result<IVCExprOpVisitor<bool, LineariserOptions>>() != null);
- if (opLineariser == null)
- opLineariser = new Z3apiOpLineariser(this);
- return opLineariser;
- }
- }
-
- internal readonly UniqueNamer namer;
- internal readonly Dictionary<VCExprVar, Term> letBindings;
- protected Z3apiProverContext cm;
-
- public Z3apiExprLineariser(Z3apiProverContext cm, UniqueNamer namer)
- {
- this.cm = cm;
- this.namer = namer;
- this.letBindings = new Dictionary<VCExprVar, Term>();
- }
-
- public Term Linearise(VCExpr expr, LineariserOptions options)
- {
- Contract.Requires(options != null);
- Contract.Requires(expr != null);
- return expr.Accept<Term, LineariserOptions>(this, options);
- }
-
- /////////////////////////////////////////////////////////////////////////////////////
-
- public Term Make(VCExprOp op, List<Term> children) {
- Context z3 = cm.z3;
- Term[] unwrapChildren = children.ToArray();
- VCExprBoogieFunctionOp boogieFunctionOp = op as VCExprBoogieFunctionOp;
- if (boogieFunctionOp != null) {
- FuncDecl f = cm.GetFunction(boogieFunctionOp.Func.Name);
- return z3.MkApp(f, unwrapChildren);
- }
- VCExprDistinctOp distinctOp = op as VCExprDistinctOp;
- if (distinctOp != null) {
- return z3.MkDistinct(unwrapChildren);
- }
-
- if (op == VCExpressionGenerator.AndOp) {
- return z3.MkAnd(unwrapChildren);
- }
-
- if (op == VCExpressionGenerator.OrOp) {
- return z3.MkOr(unwrapChildren);
- }
-
- if (op == VCExpressionGenerator.ImpliesOp) {
- return z3.MkImplies(unwrapChildren[0], unwrapChildren[1]);
- }
-
- if (op == VCExpressionGenerator.NotOp) {
- return z3.MkNot(unwrapChildren[0]);
- }
-
- if (op == VCExpressionGenerator.EqOp) {
- return z3.MkEq(unwrapChildren[0], unwrapChildren[1]);
- }
-
- if (op == VCExpressionGenerator.NeqOp) {
- return z3.MkNot(z3.MkEq(unwrapChildren[0], unwrapChildren[1]));
- }
-
- if (op == VCExpressionGenerator.LtOp) {
- return z3.MkLt(unwrapChildren[0], unwrapChildren[1]);
- }
-
- if (op == VCExpressionGenerator.LeOp) {
- return z3.MkLe(unwrapChildren[0], unwrapChildren[1]);
- }
-
- if (op == VCExpressionGenerator.GtOp) {
- return z3.MkGt(unwrapChildren[0], unwrapChildren[1]);
- }
-
- if (op == VCExpressionGenerator.GeOp) {
- return z3.MkGe(unwrapChildren[0], unwrapChildren[1]);
- }
-
- if (op == VCExpressionGenerator.AddOp) {
- return z3.MkAdd(unwrapChildren);
- }
-
- if (op == VCExpressionGenerator.SubOp) {
- return z3.MkSub(unwrapChildren);
- }
-
- if (op == VCExpressionGenerator.DivOp || op == VCExpressionGenerator.RealDivOp) {
- return z3.MkDiv(unwrapChildren[0], unwrapChildren[1]);
- }
-
- if (op == VCExpressionGenerator.MulOp) {
- return z3.MkMul(unwrapChildren);
- }
-
- if (op == VCExpressionGenerator.ModOp) {
- return z3.MkMod(unwrapChildren[0], unwrapChildren[1]);
- }
-
- if (op == VCExpressionGenerator.IfThenElseOp) {
- return z3.MkIte(unwrapChildren[0], unwrapChildren[1], unwrapChildren[2]);
- }
-
- if (op == VCExpressionGenerator.ToIntOp) {
- return z3.MkToInt(unwrapChildren[0]);
- }
-
- if (op == VCExpressionGenerator.ToRealOp) {
- return z3.MkToReal(unwrapChildren[0]);
- }
-
- throw new Exception("unhandled boogie operator");
- }
-
- public Term Visit(VCExprLiteral node, LineariserOptions options)
- {
- Contract.Requires(options != null);
- Contract.Requires(node != null);
-
- if (node == VCExpressionGenerator.True)
- return cm.z3.MkTrue();
- else if (node == VCExpressionGenerator.False)
- return cm.z3.MkFalse();
- else if (node is VCExprIntLit)
- return cm.z3.MkNumeral(((VCExprIntLit)node).Val.ToInt, cm.z3.MkIntSort());
- else if (node is VCExprRealLit) {
- string m = ((VCExprRealLit)node).Val.Mantissa.ToString();
- BigInteger e = ((VCExprRealLit)node).Val.Exponent;
- string f = BigInteger.Pow(10, e.Abs);
-
- if (e == 0) {
- return cm.z3.MkNumeral(m, cm.z3.MkRealSort());
- }
- else if (((VCExprRealLit)node).Val.Exponent > 0) {
- return cm.z3.MkMul(cm.z3.MkNumeral(m, cm.z3.MkRealSort()), cm.z3.MkNumeral(f, cm.z3.MkRealSort()));
- }
- else {
- return cm.z3.MkDiv(cm.z3.MkNumeral(m, cm.z3.MkRealSort()), cm.z3.MkNumeral(f, cm.z3.MkRealSort()));
- }
- }
- else {
- Contract.Assert(false);
- throw new cce.UnreachableException();
- }
- }
-
- public Term Visit(VCExprNAry node, LineariserOptions options)
- {
- Contract.Requires(options != null);
- Contract.Requires(node != null);
- VCExprOp op = node.Op;
- Contract.Assert(op != null);
-
- if (op.Equals(VCExpressionGenerator.AndOp) || op.Equals(VCExpressionGenerator.OrOp))
- {
- // handle these operators without recursion
- List<Term> asts = new List<Term>();
- string opString = op.Equals(VCExpressionGenerator.AndOp) ? "AND" : "OR";
-
- IEnumerator enumerator = new VCExprNAryUniformOpEnumerator(node);
- Contract.Assert(enumerator != null);
- while (enumerator.MoveNext())
- {
- VCExprNAry naryExpr = enumerator.Current as VCExprNAry;
- if (naryExpr == null || !naryExpr.Op.Equals(op))
- {
- asts.Add(Linearise(cce.NonNull((VCExpr)enumerator.Current), options));
- }
- }
-
- return Make(op, asts);
- }
-
- return node.Accept<Term, LineariserOptions>(OpLineariser, options);
- }
-
- public Term Visit(VCExprVar node, LineariserOptions options)
- {
- Contract.Requires(options != null);
- Contract.Requires(node != null);
- if (letBindings.ContainsKey(node))
- {
- return letBindings[node];
- }
- else
- {
- string varName = namer.GetName(node, node.Name);
- return cm.GetConstant(varName, node.Type,node);
- }
- }
-
- public Term Visit(VCExprQuantifier node, LineariserOptions options)
- {
- Contract.Requires(options != null);
- Contract.Requires(node != null);
- Contract.Assert(node.TypeParameters.Count == 0);
-
- namer.PushScope();
- try
- {
- List<string> varNames;
- List<Type> varTypes;
- VisitBounds(node.BoundVars, out varNames, out varTypes);
- List<Pattern> patterns;
- List<Term> no_patterns;
- VisitTriggers(node.Triggers, options, out patterns, out no_patterns);
- Term body = Linearise(node.Body, options);
- Term result;
- uint weight = 1;
- string qid = "";
- int skolemid = 0;
-
- if (options.QuantifierIds)
- {
- VCQuantifierInfos infos = node.Infos;
- Contract.Assert(infos != null);
- if (infos.qid != null)
- {
- qid = infos.qid;
- }
- if (0 <= infos.uniqueId)
- {
- skolemid = infos.uniqueId;
- }
- }
-
- if (options.UseWeights)
- {
- weight = (uint) QKeyValue.FindIntAttribute(node.Infos.attributes, "weight", 1);
- }
-
- switch (node.Quan)
- {
- case Microsoft.Boogie.VCExprAST.Quantifier.ALL:
- result = MakeQuantifier(true, weight, qid, skolemid, varNames, varTypes, patterns, no_patterns, body); break;
- case Microsoft.Boogie.VCExprAST.Quantifier.EX:
- result = MakeQuantifier(false, weight, qid, skolemid, varNames, varTypes, patterns, no_patterns, body); break;
- default:
- throw new Exception("unknown quantifier kind " + node.Quan);
- }
- return result;
- }
- finally
- {
- namer.PopScope();
- }
- }
-
- private Term MakeQuantifier(bool isForall, uint weight, string qid, int skolemid, List<string> varNames, List<Type> boogieTypes, List<Pattern> patterns, List<Term> no_patterns, Term body) {
- List<Term> bound = new List<Term>();
- for (int i = 0; i < varNames.Count; i++) {
- Term t = cm.GetConstant(varNames[i], boogieTypes[i], null);
- bound.Add(t);
- }
-
- Term termAst = cm.z3.MkQuantifier(isForall, weight, cm.z3.MkSymbol(qid), cm.z3.MkSymbol(skolemid.ToString()), patterns.ToArray(), no_patterns.ToArray(), bound.ToArray(), body);
- return termAst;
- }
-
- private void VisitBounds(List<VCExprVar> boundVars, out List<string> varNames, out List<Type> varTypes)
- {
- varNames = new List<string>();
- varTypes = new List<Type>();
- foreach (VCExprVar var in boundVars)
- {
- string varName = namer.GetLocalName(var, var.Name);
- varNames.Add(varName);
- varTypes.Add(var.Type);
- }
- }
-
- private void VisitTriggers(List<VCTrigger> triggers, LineariserOptions options, out List<Pattern> patterns, out List<Term> no_patterns)
- {
- patterns = new List<Pattern>();
- no_patterns = new List<Term>();
- foreach (VCTrigger trigger in triggers)
- {
- List<Term> exprs = new List<Term>();
- foreach (VCExpr expr in trigger.Exprs)
- {
- System.Diagnostics.Debug.Assert(expr != null);
- Term termAst = Linearise(expr, options);
- exprs.Add(termAst);
- }
- if (exprs.Count > 0)
- {
- if (trigger.Pos) {
- Pattern pattern = cm.z3.MkPattern(exprs.ToArray());
- patterns.Add(pattern);
- }
- else {
- System.Diagnostics.Debug.Assert(false, "Z3api currently does not handle nopats");
- foreach (Term expr in exprs)
- no_patterns.Add(expr);
- }
- }
- }
- }
-
- public Term Visit(VCExprLet node, LineariserOptions options)
- {
- foreach (VCExprLetBinding b in node)
- {
- Term defAst = Linearise(b.E, options);
- letBindings.Add(b.V, defAst);
- }
- Term letAst = Linearise(node.Body, options);
- foreach (VCExprLetBinding b in node)
- {
- letBindings.Remove(b.V);
- }
- return letAst;
- }
-
- /////////////////////////////////////////////////////////////////////////////////////
-
- internal class Z3apiOpLineariser : IVCExprOpVisitor<Term, LineariserOptions>
- {
- [ContractInvariantMethod]
- void ObjectInvariant()
- {
- Contract.Invariant(ExprLineariser != null);
- }
-
- private readonly Z3apiExprLineariser ExprLineariser;
-
- public Z3apiOpLineariser(Z3apiExprLineariser ExprLineariser)
- {
- Contract.Requires(ExprLineariser != null);
- this.ExprLineariser = ExprLineariser;
- }
-
- ///////////////////////////////////////////////////////////////////////////////////
-
- private Term WriteApplication(VCExprOp op, IEnumerable<VCExpr> terms, LineariserOptions options)
- {
- Contract.Requires(options != null);
- Contract.Requires(op != null);
- Contract.Requires(cce.NonNullElements(terms));
-
- List<Term> args = new List<Term>();
- foreach (VCExpr e in terms)
- {
- Contract.Assert(e != null);
- args.Add(ExprLineariser.Linearise(e, options));
- }
- return ExprLineariser.Make(op, args);
- }
-
- ///////////////////////////////////////////////////////////////////////////////////
-
- public Term VisitNotOp(VCExprNAry node, LineariserOptions options)
- {
- Contract.Requires(options != null);
- Contract.Requires(node != null);
- return WriteApplication(node.Op, node, options);
- }
-
- public Term VisitEqOp(VCExprNAry node, LineariserOptions options)
- {
- Contract.Requires(options != null);
- Contract.Requires(node != null);
- return WriteApplication(node.Op, node, options);
- }
-
- public Term VisitNeqOp(VCExprNAry node, LineariserOptions options)
- {
- Contract.Requires(options != null);
- Contract.Requires(node != null);
- return WriteApplication(node.Op, node, options);
- }
-
- public Term VisitAndOp(VCExprNAry node, LineariserOptions options)
- {
- Contract.Requires(options != null);
- Contract.Requires(node != null);
- return WriteApplication(node.Op, node, options);
- }
-
- public Term VisitOrOp(VCExprNAry node, LineariserOptions options)
- {
- Contract.Requires(options != null);
- Contract.Requires(node != null);
- return WriteApplication(node.Op, node, options);
- }
-
- public Term VisitImpliesOp(VCExprNAry node, LineariserOptions options)
- {
- Contract.Requires(options != null);
- Contract.Requires(node != null);
- return WriteApplication(node.Op, node, options);
- }
-
- public Term VisitDistinctOp(VCExprNAry node, LineariserOptions options)
- {
- Contract.Requires(options != null);
- Contract.Requires(node != null);
- return WriteApplication(node.Op, node, options);
- }
-
- public Term VisitLabelOp(VCExprNAry node, LineariserOptions options)
- {
- Contract.Requires(options != null);
- Contract.Requires(node != null);
- VCExprLabelOp op = (VCExprLabelOp)node.Op;
- Contract.Assert(op != null);
- return ExprLineariser.cm.MakeLabel(op.label, op.pos, ExprLineariser.Linearise(node[0], options));
- }
-
- public Term VisitSelectOp(VCExprNAry node, LineariserOptions options)
- {
- Contract.Requires(options != null);
- Contract.Requires(node != null);
- List<Term> args = new List<Term>();
- foreach (VCExpr e in node)
- {
- Contract.Assert(e != null);
- args.Add(ExprLineariser.Linearise(e, options));
- }
- System.Diagnostics.Debug.Assert(args.Count >= 2);
-
- Term selectTerm = args[0];
- for (int i = 1; i < args.Count; i++) {
- selectTerm = ExprLineariser.cm.z3.MkArraySelect(selectTerm, args[i]);
- }
- return selectTerm;
- }
-
- private Term ConstructStoreTerm(Term mapTerm, List<Term> args, int index) {
- System.Diagnostics.Debug.Assert(0 < index && index < args.Count - 1);
- if (index == args.Count - 2) {
- return ExprLineariser.cm.z3.MkArrayStore(mapTerm, args[index], args[index + 1]);
- }
- else {
- Term t = ConstructStoreTerm(ExprLineariser.cm.z3.MkArraySelect(mapTerm, args[index]), args, index + 1);
- return ExprLineariser.cm.z3.MkArrayStore(mapTerm, args[index], t);
- }
- }
-
- public Term VisitStoreOp(VCExprNAry node, LineariserOptions options)
- {
- Contract.Requires(options != null);
- Contract.Requires(node != null);
- List<Term> args = new List<Term>();
- foreach (VCExpr e in node)
- {
- Contract.Assert(e != null);
- args.Add(ExprLineariser.Linearise(e, options));
- }
- return ConstructStoreTerm(args[0], args, 1);
- }
-
- public Term VisitBvOp(VCExprNAry node, LineariserOptions options)
- {
- Contract.Requires(options != null);
- Contract.Requires(node != null);
- List<int> args = new List<int>();
- foreach (VCExpr e in node) {
- VCExprIntLit literal = e as VCExprIntLit;
- System.Diagnostics.Debug.Assert(literal != null);
- args.Add(literal.Val.ToInt);
- }
- System.Diagnostics.Debug.Assert(args.Count == 1);
- return ExprLineariser.cm.z3.MkNumeral(args[0], ExprLineariser.cm.z3.MkBvSort((uint)node.Type.BvBits));
- }
-
- public Term VisitBvExtractOp(VCExprNAry node, LineariserOptions options) {
- Contract.Requires(options != null);
- Contract.Requires(node != null);
-
- VCExprBvExtractOp op = (VCExprBvExtractOp)node.Op;
- Contract.Assert(op != null);
- System.Diagnostics.Debug.Assert(0 <= op.Start && op.Start < op.End);
-
- List<Term> args = new List<Term>();
- foreach (VCExpr e in node) {
- Contract.Assert(e != null);
- args.Add(ExprLineariser.Linearise(e, options));
- }
- System.Diagnostics.Debug.Assert(args.Count == 1);
- return ExprLineariser.cm.z3.MkBvExtract((uint) op.End - 1, (uint) op.Start, args[0]);
- }
-
- public Term VisitBvConcatOp(VCExprNAry node, LineariserOptions options) {
- Contract.Requires(options != null);
- Contract.Requires(node != null);
-
- VCExprBvConcatOp op = (VCExprBvConcatOp)node.Op;
- Contract.Assert(op != null);
-
- List<Term> args = new List<Term>();
- foreach (VCExpr e in node) {
- Contract.Assert(e != null);
- args.Add(ExprLineariser.Linearise(e, options));
- }
- System.Diagnostics.Debug.Assert(args.Count == 2);
- return ExprLineariser.cm.z3.MkBvConcat(args[0], args[1]);
- }
-
- public Term VisitIfThenElseOp(VCExprNAry node, LineariserOptions options)
- {
- Contract.Requires(options != null);
- Contract.Requires(node != null);
- return WriteApplication(node.Op, node, options);
- }
-
- public Term VisitCustomOp(VCExprNAry node, LineariserOptions options)
- {
- Contract.Requires(node != null);
- Contract.Requires(options != null);
- return WriteApplication(node.Op, node, options);
- }
-
- public Term VisitAddOp(VCExprNAry node, LineariserOptions options) {
- Contract.Requires(options != null);
- Contract.Requires(node != null);
- return WriteApplication(node.Op, node, options);
- }
-
- public Term VisitSubOp(VCExprNAry node, LineariserOptions options)
- {
- Contract.Requires(options != null);
- Contract.Requires(node != null);
- return WriteApplication(node.Op, node, options);
- }
-
- public Term VisitMulOp(VCExprNAry node, LineariserOptions options)
- {
- Contract.Requires(options != null);
- Contract.Requires(node != null);
- return WriteApplication(node.Op, node, options);
- }
-
- public Term VisitDivOp(VCExprNAry node, LineariserOptions options)
- {
- Contract.Requires(options != null);
- Contract.Requires(node != null);
- return WriteApplication(node.Op, node, options);
- }
-
- public Term VisitModOp(VCExprNAry node, LineariserOptions options)
- {
- Contract.Requires(options != null);
- Contract.Requires(node != null);
- return WriteApplication(node.Op, node, options);
- }
-
- public Term VisitRealDivOp(VCExprNAry node, LineariserOptions options) {
- Contract.Requires(options != null);
- Contract.Requires(node != null);
- return WriteApplication(node.Op, node, options);
- }
-
- public Term VisitPowOp(VCExprNAry node, LineariserOptions options) {
- Contract.Requires(options != null);
- Contract.Requires(node != null);
- return WriteApplication(node.Op, node, options);
- }
-
- public Term VisitLtOp(VCExprNAry node, LineariserOptions options)
- {
- Contract.Requires(options != null);
- Contract.Requires(node != null);
- return WriteApplication(node.Op, node, options);
- }
-
- public Term VisitLeOp(VCExprNAry node, LineariserOptions options)
- {
- Contract.Requires(options != null);
- Contract.Requires(node != null);
- return WriteApplication(node.Op, node, options);
- }
-
- public Term VisitGtOp(VCExprNAry node, LineariserOptions options)
- {
- Contract.Requires(options != null);
- Contract.Requires(node != null);
- return WriteApplication(node.Op, node, options);
- }
-
- public Term VisitGeOp(VCExprNAry node, LineariserOptions options)
- {
- Contract.Requires(options != null);
- Contract.Requires(node != null);
- return WriteApplication(node.Op, node, options);
- }
-
- public Term VisitSubtypeOp(VCExprNAry node, LineariserOptions options)
- {
- Contract.Requires(options != null);
- Contract.Requires(node != null);
- return WriteApplication(node.Op, node, options);
- }
-
- public Term VisitSubtype3Op(VCExprNAry node, LineariserOptions options)
- {
- Contract.Requires(options != null);
- Contract.Requires(node != null);
- return WriteApplication(node.Op, node, options);
- }
-
- public Term VisitToIntOp(VCExprNAry node, LineariserOptions options) {
- Contract.Requires(options != null);
- Contract.Requires(node != null);
- return WriteApplication(node.Op, node, options);
- }
-
- public Term VisitToRealOp(VCExprNAry node, LineariserOptions options) {
- Contract.Requires(options != null);
- Contract.Requires(node != null);
- return WriteApplication(node.Op, node, options);
- }
-
- public Term VisitBoogieFunctionOp(VCExprNAry node, LineariserOptions options)
- {
- Contract.Requires(options != null);
- Contract.Requires(node != null);
- return WriteApplication(node.Op, node, options);
- }
- }
- }
-}
+//----------------------------------------------------------------------------- +// +// Copyright (C) Microsoft Corporation. All Rights Reserved. +// +//----------------------------------------------------------------------------- +using System; +using System.Text; +using System.IO; +using System.Collections; +using System.Collections.Generic; +using System.Diagnostics.Contracts; +using Microsoft.Basetypes; +using Microsoft.Boogie.VCExprAST; +using Microsoft.Z3; + +namespace Microsoft.Boogie.Z3 +{ + using System.Numerics.BigInteger; + + public class Z3apiExprLineariser : IVCExprVisitor<Term, LineariserOptions> + { + private Z3apiOpLineariser opLineariser = null; + private IVCExprOpVisitor<Term, LineariserOptions> OpLineariser + { + get + { + Contract.Ensures(Contract.Result<IVCExprOpVisitor<bool, LineariserOptions>>() != null); + if (opLineariser == null) + opLineariser = new Z3apiOpLineariser(this); + return opLineariser; + } + } + + internal readonly UniqueNamer namer; + internal readonly Dictionary<VCExprVar, Term> letBindings; + protected Z3apiProverContext cm; + + public Z3apiExprLineariser(Z3apiProverContext cm, UniqueNamer namer) + { + this.cm = cm; + this.namer = namer; + this.letBindings = new Dictionary<VCExprVar, Term>(); + } + + public Term Linearise(VCExpr expr, LineariserOptions options) + { + Contract.Requires(options != null); + Contract.Requires(expr != null); + return expr.Accept<Term, LineariserOptions>(this, options); + } + + ///////////////////////////////////////////////////////////////////////////////////// + + public Term Make(VCExprOp op, List<Term> children) { + Context z3 = cm.z3; + Term[] unwrapChildren = children.ToArray(); + VCExprBoogieFunctionOp boogieFunctionOp = op as VCExprBoogieFunctionOp; + if (boogieFunctionOp != null) { + FuncDecl f = cm.GetFunction(boogieFunctionOp.Func.Name); + return z3.MkApp(f, unwrapChildren); + } + VCExprDistinctOp distinctOp = op as VCExprDistinctOp; + if (distinctOp != null) { + return z3.MkDistinct(unwrapChildren); + } + + if (op == VCExpressionGenerator.AndOp) { + return z3.MkAnd(unwrapChildren); + } + + if (op == VCExpressionGenerator.OrOp) { + return z3.MkOr(unwrapChildren); + } + + if (op == VCExpressionGenerator.ImpliesOp) { + return z3.MkImplies(unwrapChildren[0], unwrapChildren[1]); + } + + if (op == VCExpressionGenerator.NotOp) { + return z3.MkNot(unwrapChildren[0]); + } + + if (op == VCExpressionGenerator.EqOp) { + return z3.MkEq(unwrapChildren[0], unwrapChildren[1]); + } + + if (op == VCExpressionGenerator.NeqOp) { + return z3.MkNot(z3.MkEq(unwrapChildren[0], unwrapChildren[1])); + } + + if (op == VCExpressionGenerator.LtOp) { + return z3.MkLt(unwrapChildren[0], unwrapChildren[1]); + } + + if (op == VCExpressionGenerator.LeOp) { + return z3.MkLe(unwrapChildren[0], unwrapChildren[1]); + } + + if (op == VCExpressionGenerator.GtOp) { + return z3.MkGt(unwrapChildren[0], unwrapChildren[1]); + } + + if (op == VCExpressionGenerator.GeOp) { + return z3.MkGe(unwrapChildren[0], unwrapChildren[1]); + } + + if (op == VCExpressionGenerator.AddOp) { + return z3.MkAdd(unwrapChildren); + } + + if (op == VCExpressionGenerator.SubOp) { + return z3.MkSub(unwrapChildren); + } + + if (op == VCExpressionGenerator.DivOp || op == VCExpressionGenerator.RealDivOp) { + return z3.MkDiv(unwrapChildren[0], unwrapChildren[1]); + } + + if (op == VCExpressionGenerator.MulOp) { + return z3.MkMul(unwrapChildren); + } + + if (op == VCExpressionGenerator.ModOp) { + return z3.MkMod(unwrapChildren[0], unwrapChildren[1]); + } + + if (op == VCExpressionGenerator.IfThenElseOp) { + return z3.MkIte(unwrapChildren[0], unwrapChildren[1], unwrapChildren[2]); + } + + if (op == VCExpressionGenerator.ToIntOp) { + return z3.MkToInt(unwrapChildren[0]); + } + + if (op == VCExpressionGenerator.ToRealOp) { + return z3.MkToReal(unwrapChildren[0]); + } + + throw new Exception("unhandled boogie operator"); + } + + public Term Visit(VCExprLiteral node, LineariserOptions options) + { + Contract.Requires(options != null); + Contract.Requires(node != null); + + if (node == VCExpressionGenerator.True) + return cm.z3.MkTrue(); + else if (node == VCExpressionGenerator.False) + return cm.z3.MkFalse(); + else if (node is VCExprIntLit) + return cm.z3.MkNumeral(((VCExprIntLit)node).Val.ToInt, cm.z3.MkIntSort()); + else if (node is VCExprRealLit) { + string m = ((VCExprRealLit)node).Val.Mantissa.ToString(); + BigInteger e = ((VCExprRealLit)node).Val.Exponent; + string f = BigInteger.Pow(10, e.Abs); + + if (e == 0) { + return cm.z3.MkNumeral(m, cm.z3.MkRealSort()); + } + else if (((VCExprRealLit)node).Val.Exponent > 0) { + return cm.z3.MkMul(cm.z3.MkNumeral(m, cm.z3.MkRealSort()), cm.z3.MkNumeral(f, cm.z3.MkRealSort())); + } + else { + return cm.z3.MkDiv(cm.z3.MkNumeral(m, cm.z3.MkRealSort()), cm.z3.MkNumeral(f, cm.z3.MkRealSort())); + } + } + else { + Contract.Assert(false); + throw new cce.UnreachableException(); + } + } + + public Term Visit(VCExprNAry node, LineariserOptions options) + { + Contract.Requires(options != null); + Contract.Requires(node != null); + VCExprOp op = node.Op; + Contract.Assert(op != null); + + if (op.Equals(VCExpressionGenerator.AndOp) || op.Equals(VCExpressionGenerator.OrOp)) + { + // handle these operators without recursion + List<Term> asts = new List<Term>(); + string opString = op.Equals(VCExpressionGenerator.AndOp) ? "AND" : "OR"; + + IEnumerator enumerator = new VCExprNAryUniformOpEnumerator(node); + Contract.Assert(enumerator != null); + while (enumerator.MoveNext()) + { + VCExprNAry naryExpr = enumerator.Current as VCExprNAry; + if (naryExpr == null || !naryExpr.Op.Equals(op)) + { + asts.Add(Linearise(cce.NonNull((VCExpr)enumerator.Current), options)); + } + } + + return Make(op, asts); + } + + return node.Accept<Term, LineariserOptions>(OpLineariser, options); + } + + public Term Visit(VCExprVar node, LineariserOptions options) + { + Contract.Requires(options != null); + Contract.Requires(node != null); + if (letBindings.ContainsKey(node)) + { + return letBindings[node]; + } + else + { + string varName = namer.GetName(node, node.Name); + return cm.GetConstant(varName, node.Type,node); + } + } + + public Term Visit(VCExprQuantifier node, LineariserOptions options) + { + Contract.Requires(options != null); + Contract.Requires(node != null); + Contract.Assert(node.TypeParameters.Count == 0); + + namer.PushScope(); + try + { + List<string> varNames; + List<Type> varTypes; + VisitBounds(node.BoundVars, out varNames, out varTypes); + List<Pattern> patterns; + List<Term> no_patterns; + VisitTriggers(node.Triggers, options, out patterns, out no_patterns); + Term body = Linearise(node.Body, options); + Term result; + uint weight = 1; + string qid = ""; + int skolemid = 0; + + if (options.QuantifierIds) + { + VCQuantifierInfos infos = node.Infos; + Contract.Assert(infos != null); + if (infos.qid != null) + { + qid = infos.qid; + } + if (0 <= infos.uniqueId) + { + skolemid = infos.uniqueId; + } + } + + if (options.UseWeights) + { + weight = (uint) QKeyValue.FindIntAttribute(node.Infos.attributes, "weight", 1); + } + + switch (node.Quan) + { + case Microsoft.Boogie.VCExprAST.Quantifier.ALL: + result = MakeQuantifier(true, weight, qid, skolemid, varNames, varTypes, patterns, no_patterns, body); break; + case Microsoft.Boogie.VCExprAST.Quantifier.EX: + result = MakeQuantifier(false, weight, qid, skolemid, varNames, varTypes, patterns, no_patterns, body); break; + default: + throw new Exception("unknown quantifier kind " + node.Quan); + } + return result; + } + finally + { + namer.PopScope(); + } + } + + private Term MakeQuantifier(bool isForall, uint weight, string qid, int skolemid, List<string> varNames, List<Type> boogieTypes, List<Pattern> patterns, List<Term> no_patterns, Term body) { + List<Term> bound = new List<Term>(); + for (int i = 0; i < varNames.Count; i++) { + Term t = cm.GetConstant(varNames[i], boogieTypes[i], null); + bound.Add(t); + } + + Term termAst = cm.z3.MkQuantifier(isForall, weight, cm.z3.MkSymbol(qid), cm.z3.MkSymbol(skolemid.ToString()), patterns.ToArray(), no_patterns.ToArray(), bound.ToArray(), body); + return termAst; + } + + private void VisitBounds(List<VCExprVar> boundVars, out List<string> varNames, out List<Type> varTypes) + { + varNames = new List<string>(); + varTypes = new List<Type>(); + foreach (VCExprVar var in boundVars) + { + string varName = namer.GetLocalName(var, var.Name); + varNames.Add(varName); + varTypes.Add(var.Type); + } + } + + private void VisitTriggers(List<VCTrigger> triggers, LineariserOptions options, out List<Pattern> patterns, out List<Term> no_patterns) + { + patterns = new List<Pattern>(); + no_patterns = new List<Term>(); + foreach (VCTrigger trigger in triggers) + { + List<Term> exprs = new List<Term>(); + foreach (VCExpr expr in trigger.Exprs) + { + System.Diagnostics.Debug.Assert(expr != null); + Term termAst = Linearise(expr, options); + exprs.Add(termAst); + } + if (exprs.Count > 0) + { + if (trigger.Pos) { + Pattern pattern = cm.z3.MkPattern(exprs.ToArray()); + patterns.Add(pattern); + } + else { + System.Diagnostics.Debug.Assert(false, "Z3api currently does not handle nopats"); + foreach (Term expr in exprs) + no_patterns.Add(expr); + } + } + } + } + + public Term Visit(VCExprLet node, LineariserOptions options) + { + foreach (VCExprLetBinding b in node) + { + Term defAst = Linearise(b.E, options); + letBindings.Add(b.V, defAst); + } + Term letAst = Linearise(node.Body, options); + foreach (VCExprLetBinding b in node) + { + letBindings.Remove(b.V); + } + return letAst; + } + + ///////////////////////////////////////////////////////////////////////////////////// + + internal class Z3apiOpLineariser : IVCExprOpVisitor<Term, LineariserOptions> + { + [ContractInvariantMethod] + void ObjectInvariant() + { + Contract.Invariant(ExprLineariser != null); + } + + private readonly Z3apiExprLineariser ExprLineariser; + + public Z3apiOpLineariser(Z3apiExprLineariser ExprLineariser) + { + Contract.Requires(ExprLineariser != null); + this.ExprLineariser = ExprLineariser; + } + + /////////////////////////////////////////////////////////////////////////////////// + + private Term WriteApplication(VCExprOp op, IEnumerable<VCExpr> terms, LineariserOptions options) + { + Contract.Requires(options != null); + Contract.Requires(op != null); + Contract.Requires(cce.NonNullElements(terms)); + + List<Term> args = new List<Term>(); + foreach (VCExpr e in terms) + { + Contract.Assert(e != null); + args.Add(ExprLineariser.Linearise(e, options)); + } + return ExprLineariser.Make(op, args); + } + + /////////////////////////////////////////////////////////////////////////////////// + + public Term VisitNotOp(VCExprNAry node, LineariserOptions options) + { + Contract.Requires(options != null); + Contract.Requires(node != null); + return WriteApplication(node.Op, node, options); + } + + public Term VisitEqOp(VCExprNAry node, LineariserOptions options) + { + Contract.Requires(options != null); + Contract.Requires(node != null); + return WriteApplication(node.Op, node, options); + } + + public Term VisitNeqOp(VCExprNAry node, LineariserOptions options) + { + Contract.Requires(options != null); + Contract.Requires(node != null); + return WriteApplication(node.Op, node, options); + } + + public Term VisitAndOp(VCExprNAry node, LineariserOptions options) + { + Contract.Requires(options != null); + Contract.Requires(node != null); + return WriteApplication(node.Op, node, options); + } + + public Term VisitOrOp(VCExprNAry node, LineariserOptions options) + { + Contract.Requires(options != null); + Contract.Requires(node != null); + return WriteApplication(node.Op, node, options); + } + + public Term VisitImpliesOp(VCExprNAry node, LineariserOptions options) + { + Contract.Requires(options != null); + Contract.Requires(node != null); + return WriteApplication(node.Op, node, options); + } + + public Term VisitDistinctOp(VCExprNAry node, LineariserOptions options) + { + Contract.Requires(options != null); + Contract.Requires(node != null); + return WriteApplication(node.Op, node, options); + } + + public Term VisitLabelOp(VCExprNAry node, LineariserOptions options) + { + Contract.Requires(options != null); + Contract.Requires(node != null); + VCExprLabelOp op = (VCExprLabelOp)node.Op; + Contract.Assert(op != null); + return ExprLineariser.cm.MakeLabel(op.label, op.pos, ExprLineariser.Linearise(node[0], options)); + } + + public Term VisitSelectOp(VCExprNAry node, LineariserOptions options) + { + Contract.Requires(options != null); + Contract.Requires(node != null); + List<Term> args = new List<Term>(); + foreach (VCExpr e in node) + { + Contract.Assert(e != null); + args.Add(ExprLineariser.Linearise(e, options)); + } + System.Diagnostics.Debug.Assert(args.Count >= 2); + + Term selectTerm = args[0]; + for (int i = 1; i < args.Count; i++) { + selectTerm = ExprLineariser.cm.z3.MkArraySelect(selectTerm, args[i]); + } + return selectTerm; + } + + private Term ConstructStoreTerm(Term mapTerm, List<Term> args, int index) { + System.Diagnostics.Debug.Assert(0 < index && index < args.Count - 1); + if (index == args.Count - 2) { + return ExprLineariser.cm.z3.MkArrayStore(mapTerm, args[index], args[index + 1]); + } + else { + Term t = ConstructStoreTerm(ExprLineariser.cm.z3.MkArraySelect(mapTerm, args[index]), args, index + 1); + return ExprLineariser.cm.z3.MkArrayStore(mapTerm, args[index], t); + } + } + + public Term VisitStoreOp(VCExprNAry node, LineariserOptions options) + { + Contract.Requires(options != null); + Contract.Requires(node != null); + List<Term> args = new List<Term>(); + foreach (VCExpr e in node) + { + Contract.Assert(e != null); + args.Add(ExprLineariser.Linearise(e, options)); + } + return ConstructStoreTerm(args[0], args, 1); + } + + public Term VisitBvOp(VCExprNAry node, LineariserOptions options) + { + Contract.Requires(options != null); + Contract.Requires(node != null); + List<int> args = new List<int>(); + foreach (VCExpr e in node) { + VCExprIntLit literal = e as VCExprIntLit; + System.Diagnostics.Debug.Assert(literal != null); + args.Add(literal.Val.ToInt); + } + System.Diagnostics.Debug.Assert(args.Count == 1); + return ExprLineariser.cm.z3.MkNumeral(args[0], ExprLineariser.cm.z3.MkBvSort((uint)node.Type.BvBits)); + } + + public Term VisitBvExtractOp(VCExprNAry node, LineariserOptions options) { + Contract.Requires(options != null); + Contract.Requires(node != null); + + VCExprBvExtractOp op = (VCExprBvExtractOp)node.Op; + Contract.Assert(op != null); + System.Diagnostics.Debug.Assert(0 <= op.Start && op.Start < op.End); + + List<Term> args = new List<Term>(); + foreach (VCExpr e in node) { + Contract.Assert(e != null); + args.Add(ExprLineariser.Linearise(e, options)); + } + System.Diagnostics.Debug.Assert(args.Count == 1); + return ExprLineariser.cm.z3.MkBvExtract((uint) op.End - 1, (uint) op.Start, args[0]); + } + + public Term VisitBvConcatOp(VCExprNAry node, LineariserOptions options) { + Contract.Requires(options != null); + Contract.Requires(node != null); + + VCExprBvConcatOp op = (VCExprBvConcatOp)node.Op; + Contract.Assert(op != null); + + List<Term> args = new List<Term>(); + foreach (VCExpr e in node) { + Contract.Assert(e != null); + args.Add(ExprLineariser.Linearise(e, options)); + } + System.Diagnostics.Debug.Assert(args.Count == 2); + return ExprLineariser.cm.z3.MkBvConcat(args[0], args[1]); + } + + public Term VisitIfThenElseOp(VCExprNAry node, LineariserOptions options) + { + Contract.Requires(options != null); + Contract.Requires(node != null); + return WriteApplication(node.Op, node, options); + } + + public Term VisitCustomOp(VCExprNAry node, LineariserOptions options) + { + Contract.Requires(node != null); + Contract.Requires(options != null); + return WriteApplication(node.Op, node, options); + } + + public Term VisitAddOp(VCExprNAry node, LineariserOptions options) { + Contract.Requires(options != null); + Contract.Requires(node != null); + return WriteApplication(node.Op, node, options); + } + + public Term VisitSubOp(VCExprNAry node, LineariserOptions options) + { + Contract.Requires(options != null); + Contract.Requires(node != null); + return WriteApplication(node.Op, node, options); + } + + public Term VisitMulOp(VCExprNAry node, LineariserOptions options) + { + Contract.Requires(options != null); + Contract.Requires(node != null); + return WriteApplication(node.Op, node, options); + } + + public Term VisitDivOp(VCExprNAry node, LineariserOptions options) + { + Contract.Requires(options != null); + Contract.Requires(node != null); + return WriteApplication(node.Op, node, options); + } + + public Term VisitModOp(VCExprNAry node, LineariserOptions options) + { + Contract.Requires(options != null); + Contract.Requires(node != null); + return WriteApplication(node.Op, node, options); + } + + public Term VisitRealDivOp(VCExprNAry node, LineariserOptions options) { + Contract.Requires(options != null); + Contract.Requires(node != null); + return WriteApplication(node.Op, node, options); + } + + public Term VisitPowOp(VCExprNAry node, LineariserOptions options) { + Contract.Requires(options != null); + Contract.Requires(node != null); + return WriteApplication(node.Op, node, options); + } + + public Term VisitLtOp(VCExprNAry node, LineariserOptions options) + { + Contract.Requires(options != null); + Contract.Requires(node != null); + return WriteApplication(node.Op, node, options); + } + + public Term VisitLeOp(VCExprNAry node, LineariserOptions options) + { + Contract.Requires(options != null); + Contract.Requires(node != null); + return WriteApplication(node.Op, node, options); + } + + public Term VisitGtOp(VCExprNAry node, LineariserOptions options) + { + Contract.Requires(options != null); + Contract.Requires(node != null); + return WriteApplication(node.Op, node, options); + } + + public Term VisitGeOp(VCExprNAry node, LineariserOptions options) + { + Contract.Requires(options != null); + Contract.Requires(node != null); + return WriteApplication(node.Op, node, options); + } + + public Term VisitSubtypeOp(VCExprNAry node, LineariserOptions options) + { + Contract.Requires(options != null); + Contract.Requires(node != null); + return WriteApplication(node.Op, node, options); + } + + public Term VisitSubtype3Op(VCExprNAry node, LineariserOptions options) + { + Contract.Requires(options != null); + Contract.Requires(node != null); + return WriteApplication(node.Op, node, options); + } + + public Term VisitToIntOp(VCExprNAry node, LineariserOptions options) { + Contract.Requires(options != null); + Contract.Requires(node != null); + return WriteApplication(node.Op, node, options); + } + + public Term VisitToRealOp(VCExprNAry node, LineariserOptions options) { + Contract.Requires(options != null); + Contract.Requires(node != null); + return WriteApplication(node.Op, node, options); + } + + public Term VisitBoogieFunctionOp(VCExprNAry node, LineariserOptions options) + { + Contract.Requires(options != null); + Contract.Requires(node != null); + return WriteApplication(node.Op, node, options); + } + } + } +} diff --git a/Source/Provers/Z3api/Z3api.csproj b/Source/Provers/Z3api/Z3api.csproj index 1627536d..3fb2fe48 100644 --- a/Source/Provers/Z3api/Z3api.csproj +++ b/Source/Provers/Z3api/Z3api.csproj @@ -1,189 +1,189 @@ -<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <ProductVersion>9.0.21022</ProductVersion>
- <SchemaVersion>2.0</SchemaVersion>
- <ProjectGuid>{966DD87B-A29D-4F3C-9406-F680A61DC0E0}</ProjectGuid>
- <OutputType>Library</OutputType>
- <AppDesignerFolder>Properties</AppDesignerFolder>
- <RootNamespace>Microsoft.Boogie.Z3api</RootNamespace>
- <AssemblyName>Provers.Z3api</AssemblyName>
- <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
- <FileAlignment>512</FileAlignment>
- <StartupObject>
- </StartupObject>
- <FileUpgradeFlags>
- </FileUpgradeFlags>
- <OldToolsVersion>3.5</OldToolsVersion>
- <UpgradeBackupLocation />
- <PublishUrl>publish\</PublishUrl>
- <Install>true</Install>
- <InstallFrom>Disk</InstallFrom>
- <UpdateEnabled>false</UpdateEnabled>
- <UpdateMode>Foreground</UpdateMode>
- <UpdateInterval>7</UpdateInterval>
- <UpdateIntervalUnits>Days</UpdateIntervalUnits>
- <UpdatePeriodically>false</UpdatePeriodically>
- <UpdateRequired>false</UpdateRequired>
- <MapFileExtensions>true</MapFileExtensions>
- <ApplicationRevision>0</ApplicationRevision>
- <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
- <IsWebBootstrapper>false</IsWebBootstrapper>
- <UseApplicationTrust>false</UseApplicationTrust>
- <BootstrapperEnabled>true</BootstrapperEnabled>
- <TargetFrameworkProfile Condition=" '$(OS)' == 'Windows_NT'" >Client</TargetFrameworkProfile>
- <CodeContractsAssemblyMode>0</CodeContractsAssemblyMode>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- <DebugSymbols>true</DebugSymbols>
- <DebugType>full</DebugType>
- <Optimize>false</Optimize>
- <OutputPath>bin\Debug\</OutputPath>
- <DefineConstants>DEBUG;TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- <DebugType>pdbonly</DebugType>
- <Optimize>true</Optimize>
- <OutputPath>bin\Release\</OutputPath>
- <DefineConstants>TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'z3apidebug|AnyCPU' ">
- <DebugSymbols>true</DebugSymbols>
- <OutputPath>bin\z3apidebug\</OutputPath>
- <DefineConstants>DEBUG;TRACE</DefineConstants>
- <DebugType>full</DebugType>
- <PlatformTarget>AnyCPU</PlatformTarget>
- <CodeAnalysisRuleAssemblies>
- </CodeAnalysisRuleAssemblies>
- <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
- <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
- <ErrorReport>prompt</ErrorReport>
- <CodeAnalysisRuleSet>Migrated rules for Z3api.ruleset</CodeAnalysisRuleSet>
- <CodeAnalysisIgnoreBuiltInRules>true</CodeAnalysisIgnoreBuiltInRules>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Checked|AnyCPU'">
- <DebugSymbols>true</DebugSymbols>
- <OutputPath>bin\Checked\</OutputPath>
- <DefineConstants>DEBUG;TRACE</DefineConstants>
- <DebugType>full</DebugType>
- <PlatformTarget>AnyCPU</PlatformTarget>
- <CodeAnalysisLogFile>bin\Debug\Provers.Z3api.dll.CodeAnalysisLog.xml</CodeAnalysisLogFile>
- <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
- <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
- <ErrorReport>prompt</ErrorReport>
- <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
- <CodeAnalysisRuleSetDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
- <CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
- <CodeContractsEnableRuntimeChecking>True</CodeContractsEnableRuntimeChecking>
- <CodeContractsRuntimeOnlyPublicSurface>False</CodeContractsRuntimeOnlyPublicSurface>
- <CodeContractsRuntimeThrowOnFailure>True</CodeContractsRuntimeThrowOnFailure>
- <CodeContractsRuntimeCallSiteRequires>False</CodeContractsRuntimeCallSiteRequires>
- <CodeContractsRuntimeSkipQuantifiers>False</CodeContractsRuntimeSkipQuantifiers>
- <CodeContractsRunCodeAnalysis>False</CodeContractsRunCodeAnalysis>
- <CodeContractsNonNullObligations>False</CodeContractsNonNullObligations>
- <CodeContractsBoundsObligations>False</CodeContractsBoundsObligations>
- <CodeContractsArithmeticObligations>False</CodeContractsArithmeticObligations>
- <CodeContractsEnumObligations>False</CodeContractsEnumObligations>
- <CodeContractsPointerObligations>False</CodeContractsPointerObligations>
- <CodeContractsRedundantAssumptions>False</CodeContractsRedundantAssumptions>
- <CodeContractsRunInBackground>True</CodeContractsRunInBackground>
- <CodeContractsShowSquigglies>False</CodeContractsShowSquigglies>
- <CodeContractsUseBaseLine>False</CodeContractsUseBaseLine>
- <CodeContractsEmitXMLDocs>False</CodeContractsEmitXMLDocs>
- <CodeContractsCustomRewriterAssembly />
- <CodeContractsCustomRewriterClass />
- <CodeContractsLibPaths />
- <CodeContractsExtraRewriteOptions />
- <CodeContractsExtraAnalysisOptions />
- <CodeContractsBaseLineFile />
- <CodeContractsCacheAnalysisResults>False</CodeContractsCacheAnalysisResults>
- <CodeContractsRuntimeCheckingLevel>Full</CodeContractsRuntimeCheckingLevel>
- <CodeContractsReferenceAssembly>Build</CodeContractsReferenceAssembly>
- <CodeContractsAnalysisWarningLevel>0</CodeContractsAnalysisWarningLevel>
- </PropertyGroup>
- <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
- <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
- Other similar extension points exist, see Microsoft.Common.targets.
- <Target Name="BeforeBuild">
- </Target>
- <Target Name="AfterBuild">
- </Target>
- -->
- <ItemGroup>
- <Reference Include="ManagedAPI">
- <HintPath>..\..\..\..\..\iZ3\win\iZ3\Debug\ManagedAPI.dll</HintPath>
- </Reference>
- <Reference Include="System" />
- <Reference Include="System.Core">
- <RequiredTargetFramework>3.5</RequiredTargetFramework>
- </Reference>
- <Reference Include="System.Data" />
- <Reference Include="System.XML" />
- </ItemGroup>
- <ItemGroup>
- <ProjectReference Include="..\..\Basetypes\Basetypes.csproj">
- <Project>{43DFAD18-3E35-4558-9BE2-CAFF6B5BA8A0}</Project>
- <Name>Basetypes</Name>
- </ProjectReference>
- <ProjectReference Include="..\..\CodeContractsExtender\CodeContractsExtender.csproj">
- <Project>{ACCC0156-0921-43ED-8F67-AD8BDC8CDE31}</Project>
- <Name>CodeContractsExtender</Name>
- </ProjectReference>
- <ProjectReference Include="..\..\Core\Core.csproj">
- <Project>{B230A69C-C466-4065-B9C1-84D80E76D802}</Project>
- <Name>Core</Name>
- </ProjectReference>
- <ProjectReference Include="..\..\Model\Model.csproj">
- <Project>{ACEF88D5-DADD-46DA-BAE1-2144D63F4C83}</Project>
- <Name>Model</Name>
- </ProjectReference>
- <ProjectReference Include="..\..\ParserHelper\ParserHelper.csproj">
- <Project>{FCD3AC7F-9DFD-46C8-AB1E-09F0B0F16DC5}</Project>
- <Name>ParserHelper</Name>
- </ProjectReference>
- <ProjectReference Include="..\..\VCExpr\VCExpr.csproj">
- <Project>{56FFDBCA-7D14-43B8-A6CA-22A20E417EE1}</Project>
- <Name>VCExpr</Name>
- </ProjectReference>
- <ProjectReference Include="..\..\VCGeneration\VCGeneration.csproj">
- <Project>{E1F10180-C7B9-4147-B51F-FA1B701966DC}</Project>
- <Name>VCGeneration</Name>
- </ProjectReference>
- </ItemGroup>
- <ItemGroup>
- <Compile Include="..\..\version.cs">
- <Link>version.cs</Link>
- </Compile>
- <Compile Include="ContextLayer.cs" />
- <Compile Include="ProverLayer.cs" />
- <Compile Include="TypeAdapter.cs">
- <SubType>Code</SubType>
- </Compile>
- <Compile Include="VCExprVisitor.cs" />
- </ItemGroup>
- <ItemGroup>
- <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
- <Visible>False</Visible>
- <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
- <Install>false</Install>
- </BootstrapperPackage>
- <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
- <Visible>False</Visible>
- <ProductName>.NET Framework 3.5 SP1</ProductName>
- <Install>true</Install>
- </BootstrapperPackage>
- <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
- <Visible>False</Visible>
- <ProductName>Windows Installer 3.1</ProductName>
- <Install>true</Install>
- </BootstrapperPackage>
- </ItemGroup>
+<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProductVersion>9.0.21022</ProductVersion> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{966DD87B-A29D-4F3C-9406-F680A61DC0E0}</ProjectGuid> + <OutputType>Library</OutputType> + <AppDesignerFolder>Properties</AppDesignerFolder> + <RootNamespace>Microsoft.Boogie.Z3api</RootNamespace> + <AssemblyName>Provers.Z3api</AssemblyName> + <TargetFrameworkVersion>v4.0</TargetFrameworkVersion> + <FileAlignment>512</FileAlignment> + <StartupObject> + </StartupObject> + <FileUpgradeFlags> + </FileUpgradeFlags> + <OldToolsVersion>3.5</OldToolsVersion> + <UpgradeBackupLocation /> + <PublishUrl>publish\</PublishUrl> + <Install>true</Install> + <InstallFrom>Disk</InstallFrom> + <UpdateEnabled>false</UpdateEnabled> + <UpdateMode>Foreground</UpdateMode> + <UpdateInterval>7</UpdateInterval> + <UpdateIntervalUnits>Days</UpdateIntervalUnits> + <UpdatePeriodically>false</UpdatePeriodically> + <UpdateRequired>false</UpdateRequired> + <MapFileExtensions>true</MapFileExtensions> + <ApplicationRevision>0</ApplicationRevision> + <ApplicationVersion>1.0.0.%2a</ApplicationVersion> + <IsWebBootstrapper>false</IsWebBootstrapper> + <UseApplicationTrust>false</UseApplicationTrust> + <BootstrapperEnabled>true</BootstrapperEnabled> + <TargetFrameworkProfile Condition=" '$(OS)' == 'Windows_NT'" >Client</TargetFrameworkProfile> + <CodeContractsAssemblyMode>0</CodeContractsAssemblyMode> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + <DebugSymbols>true</DebugSymbols> + <DebugType>full</DebugType> + <Optimize>false</Optimize> + <OutputPath>bin\Debug\</OutputPath> + <DefineConstants>DEBUG;TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + <DebugType>pdbonly</DebugType> + <Optimize>true</Optimize> + <OutputPath>bin\Release\</OutputPath> + <DefineConstants>TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'z3apidebug|AnyCPU' "> + <DebugSymbols>true</DebugSymbols> + <OutputPath>bin\z3apidebug\</OutputPath> + <DefineConstants>DEBUG;TRACE</DefineConstants> + <DebugType>full</DebugType> + <PlatformTarget>AnyCPU</PlatformTarget> + <CodeAnalysisRuleAssemblies> + </CodeAnalysisRuleAssemblies> + <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression> + <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile> + <ErrorReport>prompt</ErrorReport> + <CodeAnalysisRuleSet>Migrated rules for Z3api.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisIgnoreBuiltInRules>true</CodeAnalysisIgnoreBuiltInRules> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Checked|AnyCPU'"> + <DebugSymbols>true</DebugSymbols> + <OutputPath>bin\Checked\</OutputPath> + <DefineConstants>DEBUG;TRACE</DefineConstants> + <DebugType>full</DebugType> + <PlatformTarget>AnyCPU</PlatformTarget> + <CodeAnalysisLogFile>bin\Debug\Provers.Z3api.dll.CodeAnalysisLog.xml</CodeAnalysisLogFile> + <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression> + <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile> + <ErrorReport>prompt</ErrorReport> + <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRuleSetDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories> + <CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories> + <CodeContractsEnableRuntimeChecking>True</CodeContractsEnableRuntimeChecking> + <CodeContractsRuntimeOnlyPublicSurface>False</CodeContractsRuntimeOnlyPublicSurface> + <CodeContractsRuntimeThrowOnFailure>True</CodeContractsRuntimeThrowOnFailure> + <CodeContractsRuntimeCallSiteRequires>False</CodeContractsRuntimeCallSiteRequires> + <CodeContractsRuntimeSkipQuantifiers>False</CodeContractsRuntimeSkipQuantifiers> + <CodeContractsRunCodeAnalysis>False</CodeContractsRunCodeAnalysis> + <CodeContractsNonNullObligations>False</CodeContractsNonNullObligations> + <CodeContractsBoundsObligations>False</CodeContractsBoundsObligations> + <CodeContractsArithmeticObligations>False</CodeContractsArithmeticObligations> + <CodeContractsEnumObligations>False</CodeContractsEnumObligations> + <CodeContractsPointerObligations>False</CodeContractsPointerObligations> + <CodeContractsRedundantAssumptions>False</CodeContractsRedundantAssumptions> + <CodeContractsRunInBackground>True</CodeContractsRunInBackground> + <CodeContractsShowSquigglies>False</CodeContractsShowSquigglies> + <CodeContractsUseBaseLine>False</CodeContractsUseBaseLine> + <CodeContractsEmitXMLDocs>False</CodeContractsEmitXMLDocs> + <CodeContractsCustomRewriterAssembly /> + <CodeContractsCustomRewriterClass /> + <CodeContractsLibPaths /> + <CodeContractsExtraRewriteOptions /> + <CodeContractsExtraAnalysisOptions /> + <CodeContractsBaseLineFile /> + <CodeContractsCacheAnalysisResults>False</CodeContractsCacheAnalysisResults> + <CodeContractsRuntimeCheckingLevel>Full</CodeContractsRuntimeCheckingLevel> + <CodeContractsReferenceAssembly>Build</CodeContractsReferenceAssembly> + <CodeContractsAnalysisWarningLevel>0</CodeContractsAnalysisWarningLevel> + </PropertyGroup> + <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> + <!-- To modify your build process, add your task inside one of the targets below and uncomment it. + Other similar extension points exist, see Microsoft.Common.targets. + <Target Name="BeforeBuild"> + </Target> + <Target Name="AfterBuild"> + </Target> + --> + <ItemGroup> + <Reference Include="ManagedAPI"> + <HintPath>..\..\..\..\..\iZ3\win\iZ3\Debug\ManagedAPI.dll</HintPath> + </Reference> + <Reference Include="System" /> + <Reference Include="System.Core"> + <RequiredTargetFramework>3.5</RequiredTargetFramework> + </Reference> + <Reference Include="System.Data" /> + <Reference Include="System.XML" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\..\Basetypes\Basetypes.csproj"> + <Project>{43DFAD18-3E35-4558-9BE2-CAFF6B5BA8A0}</Project> + <Name>Basetypes</Name> + </ProjectReference> + <ProjectReference Include="..\..\CodeContractsExtender\CodeContractsExtender.csproj"> + <Project>{ACCC0156-0921-43ED-8F67-AD8BDC8CDE31}</Project> + <Name>CodeContractsExtender</Name> + </ProjectReference> + <ProjectReference Include="..\..\Core\Core.csproj"> + <Project>{B230A69C-C466-4065-B9C1-84D80E76D802}</Project> + <Name>Core</Name> + </ProjectReference> + <ProjectReference Include="..\..\Model\Model.csproj"> + <Project>{ACEF88D5-DADD-46DA-BAE1-2144D63F4C83}</Project> + <Name>Model</Name> + </ProjectReference> + <ProjectReference Include="..\..\ParserHelper\ParserHelper.csproj"> + <Project>{FCD3AC7F-9DFD-46C8-AB1E-09F0B0F16DC5}</Project> + <Name>ParserHelper</Name> + </ProjectReference> + <ProjectReference Include="..\..\VCExpr\VCExpr.csproj"> + <Project>{56FFDBCA-7D14-43B8-A6CA-22A20E417EE1}</Project> + <Name>VCExpr</Name> + </ProjectReference> + <ProjectReference Include="..\..\VCGeneration\VCGeneration.csproj"> + <Project>{E1F10180-C7B9-4147-B51F-FA1B701966DC}</Project> + <Name>VCGeneration</Name> + </ProjectReference> + </ItemGroup> + <ItemGroup> + <Compile Include="..\..\version.cs"> + <Link>version.cs</Link> + </Compile> + <Compile Include="ContextLayer.cs" /> + <Compile Include="ProverLayer.cs" /> + <Compile Include="TypeAdapter.cs"> + <SubType>Code</SubType> + </Compile> + <Compile Include="VCExprVisitor.cs" /> + </ItemGroup> + <ItemGroup> + <BootstrapperPackage Include="Microsoft.Net.Client.3.5"> + <Visible>False</Visible> + <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName> + <Install>false</Install> + </BootstrapperPackage> + <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1"> + <Visible>False</Visible> + <ProductName>.NET Framework 3.5 SP1</ProductName> + <Install>true</Install> + </BootstrapperPackage> + <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1"> + <Visible>False</Visible> + <ProductName>Windows Installer 3.1</ProductName> + <Install>true</Install> + </BootstrapperPackage> + </ItemGroup> </Project>
\ No newline at end of file diff --git a/Source/Provers/Z3api/cce.cs b/Source/Provers/Z3api/cce.cs index ef594484..1e0b12a5 100644 --- a/Source/Provers/Z3api/cce.cs +++ b/Source/Provers/Z3api/cce.cs @@ -1,193 +1,193 @@ -using System;
-using SA=System.Attribute;
-using System.Collections.Generic;
-using System.Diagnostics.Contracts;
-using System.Text;
-//using Microsoft.Boogie;
-
-/// <summary>
-/// A class containing static methods to extend the functionality of Code Contracts
-/// </summary>
-
-public static class cce {
- //[Pure]
- //public static bool NonNullElements<T>(Microsoft.Dafny.Graph<T> collection) {
- // return collection != null && cce.NonNullElements(collection.TopologicallySortedComponents());
- //}
- [Pure]
- public static T NonNull<T>(T t) {
- Contract.Assert(t != null);
- return t;
- }
- [Pure]
- public static bool NonNullElements<T>(IEnumerable<T> collection) {
- return collection != null && Contract.ForAll(collection, c => c != null);
- }
- [Pure]
- public static bool NonNullElements<TKey, TValue>(IDictionary<TKey, TValue> collection) {
- return collection != null && Contract.ForAll(collection, pair => NonNullElements(pair));
- }
- //[Pure]
- //public static bool NonNullElements(VariableSeq collection) {
- // return collection != null && Contract.ForAll(0, collection.Length, i => collection[i] != null);
- //}
- /// <summary>
- /// For possibly-null lists of non-null elements
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="collection"></param>
- /// <param name="nullability">If true, the collection is treated as an IEnumerable<T!>?, rather than an IEnumerable<T!>!</param>
- /// <returns></returns>
- [Pure]
- public static bool NonNullElements<T>(IEnumerable<T> collection, bool nullability) {
- return (nullability && collection == null) || cce.NonNullElements(collection);
- //Should be the same as:
- /*if(nullability&&collection==null)
- * return true;
- * return cce.NonNullElements(collection)
- */
-
- }
- [Pure]
- public static bool NonNullElements<TKey, TValue>(KeyValuePair<TKey, TValue> kvp) {
- return kvp.Key != null && kvp.Value != null;
- }
- [Pure]
- public static bool NonNullElements<T>(IEnumerator<T> iEnumerator) {
- return iEnumerator != null;
- }
- //[Pure]
- //public static bool NonNullElements<T>(Graphing.Graph<T> graph) {
- // return cce.NonNullElements(graph.TopologicalSort());
- //}
- [Pure]
- public static void BeginExpose(object o) {
- }
- [Pure]
- public static void EndExpose() {
- }
- [Pure]
- public static bool IsPeerConsistent(object o) {
- return true;
- }
- [Pure]
- public static bool IsConsistent(object o) {
- return true;
- }
- [Pure]
- public static bool IsExposable(object o) {
- return true;
- }
- [Pure]
- public static bool IsExposed(object o) {
- return true;
- }
- [Pure]
- public static bool IsNew(object o) {
- return true;
- }
- public static class Owner {
- [Pure]
- public static bool Same(object o, object p) {
- return true;
- }
- [Pure]
- public static void AssignSame(object o, object p) {
- }
- [Pure]
- public static object ElementProxy(object o) {
- return o;
- }
- [Pure]
- public static bool None(object o) {
- return true;
- }
- [Pure]
- public static bool Different(object o, object p) {
- return true;
- }
- [Pure]
- public static bool New(object o) {
- return true;
- }
- }
- [Pure]
- public static void LoopInvariant(bool p) {
- Contract.Assert(p);
- }
- public class UnreachableException : Exception {
- public UnreachableException() {
- }
- }
- //[Pure]
- //public static bool IsValid(Microsoft.Dafny.Expression expression) {
- // return true;
- //}
- //public static List<T> toList<T>(PureCollections.Sequence s) {
- // List<T> toRet = new List<T>();
- // foreach (T t in s.elems)
- // if(t!=null)
- // toRet.Add(t);
- // return toRet;
- //}
-
- //internal static bool NonNullElements(Set set) {
- // return set != null && Contract.ForAll(0,set.Count, i => set[i] != null);
- //}
-}
-
-public class PeerAttribute : SA {
-}
-public class RepAttribute : SA {
-}
-public class CapturedAttribute : SA {
-}
-public class NotDelayedAttribute : SA {
-}
-public class NoDefaultContractAttribute : SA {
-}
-public class VerifyAttribute : SA {
- public VerifyAttribute(bool b) {
-
- }
-}
-public class StrictReadonlyAttribute : SA {
-}
-public class AdditiveAttribute : SA {
-}
-public class ReadsAttribute : SA {
- public enum Reads {
- Nothing,
- Everything,
- };
- public ReadsAttribute(object o) {
- }
-}
-public class GlobalAccessAttribute : SA {
- public GlobalAccessAttribute(bool b) {
- }
-}
-public class EscapesAttribute : SA {
- public EscapesAttribute(bool b, bool b_2) {
- }
-}
-public class NeedsContractsAttribute : SA {
- public NeedsContractsAttribute() {
- }
- public NeedsContractsAttribute(bool ret, bool parameters) {
- }
- public NeedsContractsAttribute(bool ret, int[] parameters) {
- }
-}
-public class ImmutableAttribute : SA {
-}
-public class InsideAttribute : SA {
-}
-public class SpecPublicAttribute : SA {
-}
-public class ElementsPeerAttribute : SA {
-}
-public class ResultNotNewlyAllocatedAttribute : SA {
-}
-public class OnceAttribute : SA {
+using System; +using SA=System.Attribute; +using System.Collections.Generic; +using System.Diagnostics.Contracts; +using System.Text; +//using Microsoft.Boogie; + +/// <summary> +/// A class containing static methods to extend the functionality of Code Contracts +/// </summary> + +public static class cce { + //[Pure] + //public static bool NonNullElements<T>(Microsoft.Dafny.Graph<T> collection) { + // return collection != null && cce.NonNullElements(collection.TopologicallySortedComponents()); + //} + [Pure] + public static T NonNull<T>(T t) { + Contract.Assert(t != null); + return t; + } + [Pure] + public static bool NonNullElements<T>(IEnumerable<T> collection) { + return collection != null && Contract.ForAll(collection, c => c != null); + } + [Pure] + public static bool NonNullElements<TKey, TValue>(IDictionary<TKey, TValue> collection) { + return collection != null && Contract.ForAll(collection, pair => NonNullElements(pair)); + } + //[Pure] + //public static bool NonNullElements(VariableSeq collection) { + // return collection != null && Contract.ForAll(0, collection.Length, i => collection[i] != null); + //} + /// <summary> + /// For possibly-null lists of non-null elements + /// </summary> + /// <typeparam name="T"></typeparam> + /// <param name="collection"></param> + /// <param name="nullability">If true, the collection is treated as an IEnumerable<T!>?, rather than an IEnumerable<T!>!</param> + /// <returns></returns> + [Pure] + public static bool NonNullElements<T>(IEnumerable<T> collection, bool nullability) { + return (nullability && collection == null) || cce.NonNullElements(collection); + //Should be the same as: + /*if(nullability&&collection==null) + * return true; + * return cce.NonNullElements(collection) + */ + + } + [Pure] + public static bool NonNullElements<TKey, TValue>(KeyValuePair<TKey, TValue> kvp) { + return kvp.Key != null && kvp.Value != null; + } + [Pure] + public static bool NonNullElements<T>(IEnumerator<T> iEnumerator) { + return iEnumerator != null; + } + //[Pure] + //public static bool NonNullElements<T>(Graphing.Graph<T> graph) { + // return cce.NonNullElements(graph.TopologicalSort()); + //} + [Pure] + public static void BeginExpose(object o) { + } + [Pure] + public static void EndExpose() { + } + [Pure] + public static bool IsPeerConsistent(object o) { + return true; + } + [Pure] + public static bool IsConsistent(object o) { + return true; + } + [Pure] + public static bool IsExposable(object o) { + return true; + } + [Pure] + public static bool IsExposed(object o) { + return true; + } + [Pure] + public static bool IsNew(object o) { + return true; + } + public static class Owner { + [Pure] + public static bool Same(object o, object p) { + return true; + } + [Pure] + public static void AssignSame(object o, object p) { + } + [Pure] + public static object ElementProxy(object o) { + return o; + } + [Pure] + public static bool None(object o) { + return true; + } + [Pure] + public static bool Different(object o, object p) { + return true; + } + [Pure] + public static bool New(object o) { + return true; + } + } + [Pure] + public static void LoopInvariant(bool p) { + Contract.Assert(p); + } + public class UnreachableException : Exception { + public UnreachableException() { + } + } + //[Pure] + //public static bool IsValid(Microsoft.Dafny.Expression expression) { + // return true; + //} + //public static List<T> toList<T>(PureCollections.Sequence s) { + // List<T> toRet = new List<T>(); + // foreach (T t in s.elems) + // if(t!=null) + // toRet.Add(t); + // return toRet; + //} + + //internal static bool NonNullElements(Set set) { + // return set != null && Contract.ForAll(0,set.Count, i => set[i] != null); + //} +} + +public class PeerAttribute : SA { +} +public class RepAttribute : SA { +} +public class CapturedAttribute : SA { +} +public class NotDelayedAttribute : SA { +} +public class NoDefaultContractAttribute : SA { +} +public class VerifyAttribute : SA { + public VerifyAttribute(bool b) { + + } +} +public class StrictReadonlyAttribute : SA { +} +public class AdditiveAttribute : SA { +} +public class ReadsAttribute : SA { + public enum Reads { + Nothing, + Everything, + }; + public ReadsAttribute(object o) { + } +} +public class GlobalAccessAttribute : SA { + public GlobalAccessAttribute(bool b) { + } +} +public class EscapesAttribute : SA { + public EscapesAttribute(bool b, bool b_2) { + } +} +public class NeedsContractsAttribute : SA { + public NeedsContractsAttribute() { + } + public NeedsContractsAttribute(bool ret, bool parameters) { + } + public NeedsContractsAttribute(bool ret, int[] parameters) { + } +} +public class ImmutableAttribute : SA { +} +public class InsideAttribute : SA { +} +public class SpecPublicAttribute : SA { +} +public class ElementsPeerAttribute : SA { +} +public class ResultNotNewlyAllocatedAttribute : SA { +} +public class OnceAttribute : SA { }
\ No newline at end of file |