/*++ Copyright (c) 2012 Microsoft Corporation Module Name: Statistics.cs Abstract: Z3 Managed API: Statistics Author: Christoph Wintersteiger (cwinter) 2012-03-22 Notes: --*/ using System; using System.Diagnostics.Contracts; namespace Microsoft.Z3 { /// /// Objects of this class track statistical information about solvers. /// [ContractVerification(true)] public class Statistics : Z3Object { /// /// Statistical data is organized into pairs of [Key, Entry], where every /// Entry is either a DoubleEntry or a UIntEntry /// public class Entry { /// /// The key of the entry. /// readonly public string Key; /// /// The uint-value of the entry. /// public uint UIntValue { get { return m_uint; } } /// /// The double-value of the entry. /// public double DoubleValue { get { return m_double; } } /// /// True if the entry is uint-valued. /// public bool IsUInt { get { return m_is_uint; } } /// /// True if the entry is double-valued. /// public bool IsDouble { get { return m_is_double; } } /// /// The string representation of the the entry's value. /// public string Value { get { Contract.Ensures(Contract.Result() != null); if (IsUInt) return m_uint.ToString(); else if (IsDouble) return m_double.ToString(); else throw new Z3Exception("Unknown statistical entry type"); } } /// /// The string representation of the Entry. /// public override string ToString() { return Key + ": " + Value; } #region Internal readonly private bool m_is_uint = false; readonly private bool m_is_double = false; readonly private uint m_uint = 0; readonly private double m_double = 0.0; internal Entry(string k, uint v) { Key = k; m_is_uint = true; m_uint = v; } internal Entry(string k, double v) { Key = k; m_is_double = true; m_double = v; } #endregion } /// /// A string representation of the statistical data. /// public override string ToString() { return Native.Z3_stats_to_string(Context.nCtx, NativeObject); } /// /// The number of statistical data. /// public uint Size { get { return Native.Z3_stats_size(Context.nCtx, NativeObject); } } /// /// The data entries. /// public Entry[] Entries { get { Contract.Ensures(Contract.Result() != null); Contract.Ensures(Contract.Result().Length == this.Size); Contract.Ensures(Contract.ForAll(0, Contract.Result().Length, j => Contract.Result()[j] != null)); uint n = Size; Entry[] res = new Entry[n]; for (uint i = 0; i < n; i++) { Entry e; string k = Native.Z3_stats_get_key(Context.nCtx, NativeObject, i); if (Native.Z3_stats_is_uint(Context.nCtx, NativeObject, i) != 0) e = new Entry(k, Native.Z3_stats_get_uint_value(Context.nCtx, NativeObject, i)); else if (Native.Z3_stats_is_double(Context.nCtx, NativeObject, i) != 0) e = new Entry(k, Native.Z3_stats_get_double_value(Context.nCtx, NativeObject, i)); else throw new Z3Exception("Unknown data entry value"); res[i] = e; } return res; } } /// /// The statistical counters. /// public string[] Keys { get { Contract.Ensures(Contract.Result() != null); uint n = Size; string[] res = new string[n]; for (uint i = 0; i < n; i++) res[i] = Native.Z3_stats_get_key(Context.nCtx, NativeObject, i); return res; } } /// /// The value of a particular statistical counter. /// /// Returns null if the key is unknown. public Entry this[string key] { get { uint n = Size; Entry[] es = Entries; for (uint i = 0; i < n; i++) if (es[i].Key == key) return es[i]; return null; } } #region Internal internal Statistics(Context ctx, IntPtr obj) : base(ctx, obj) { Contract.Requires(ctx != null); } internal class DecRefQueue : Z3.DecRefQueue { public override void IncRef(Context ctx, IntPtr obj) { Native.Z3_stats_inc_ref(ctx.nCtx, obj); } public override void DecRef(Context ctx, IntPtr obj) { Native.Z3_stats_dec_ref(ctx.nCtx, obj); } }; internal override void IncRef(IntPtr o) { Context.Statistics_DRQ.IncAndClear(Context, o); base.IncRef(o); } internal override void DecRef(IntPtr o) { Context.Statistics_DRQ.Add(o); base.DecRef(o); } #endregion } }