//-----------------------------------------------------------------------------
//
// Copyright (C) Microsoft Corporation. All Rights Reserved.
//
//-----------------------------------------------------------------------------
namespace Microsoft.AbstractInterpretationFramework
{
using System.Diagnostics.Contracts;
using System.Collections;
using System.Collections.Generic;
//using Microsoft.SpecSharp.Collections;
using Microsoft.Basetypes;
///
/// A basic class for function symbols.
///
public class FunctionSymbol : IFunctionSymbol
{
private readonly string/*!*/ display;
private readonly AIType/*!*/ typ;
[ContractInvariantMethod]
void ObjectInvariant() {
Contract.Invariant(display != null);
Contract.Invariant(typ != null);
}
public FunctionSymbol(AIType/*!*/ typ)
: this("FunctionSymbol", typ) {
Contract.Requires(typ != null);
}
internal FunctionSymbol(string/*!*/ display, AIType/*!*/ typ) {
Contract.Requires(typ != null);
Contract.Requires(display != null);
this.display = display;
this.typ = typ;
// base();
}
public AIType/*!*/ AIType { get { Contract.Ensures(Contract.Result() != null); return typ; } }
[NoDefaultContract]
[Pure]
public override string/*!*/ ToString() {
Contract.Ensures(Contract.Result() != null);
return display;
}
}
///
/// A class for integer constants.
///
public class IntSymbol : FunctionSymbol
{
public readonly BigNum Value;
///
/// The intention is that this constructor be called only from the Int.Const method.
///
internal IntSymbol(BigNum x)
: base(cce.NonNull(x.ToString()), Int.Type) {
this.Value = x;
}
[Pure]
[Reads(ReadsAttribute.Reads.Nothing)]
public override bool Equals(object other) {
IntSymbol isym = other as IntSymbol;
return isym != null && isym.Value.Equals(this.Value);
}
[Pure]
public override int GetHashCode() {
return Value.GetHashCode();
}
}
///
/// A class for bitvector constants.
///
public class BvSymbol : FunctionSymbol
{
public readonly BigNum Value;
public readonly int Bits;
///
/// The intention is that this constructor be called only from the Int.Const method.
///
internal BvSymbol(BigNum x, int y)
: base(x + "bv" + y, Bv.Type) {
this.Value = x;
this.Bits = y;
}
[Pure]
[Reads(ReadsAttribute.Reads.Nothing)]
public override bool Equals(object other) {
BvSymbol isym = other as BvSymbol;
return isym != null && isym.Value == this.Value && isym.Bits == this.Bits;
}
[Pure]
public override int GetHashCode() {
unchecked {
return Value.GetHashCode() ^ Bits;
}
}
}
public class DoubleSymbol : FunctionSymbol
{
public readonly double Value;
///
/// The intention is that this constructor be called only from the Double.Const method.
///
internal DoubleSymbol(double x)
: base(cce.NonNull(x.ToString()), Double.Type) {
this.Value = x;
}
[Pure]
[Reads(ReadsAttribute.Reads.Nothing)]
public override bool Equals(object other) {
DoubleSymbol dsym = other as DoubleSymbol;
return dsym != null && dsym.Value == this.Value;
}
[Pure]
public override int GetHashCode() {
return Value.GetHashCode();
}
}
///
/// Function symbol based on a string. Uses the string equality for determining equality
/// of symbol.
///
public class NamedSymbol : FunctionSymbol
{
public string/*!*/ Value { [NoDefaultContract] get { Contract.Ensures(Contract.Result() != null); return cce.NonNull(this.ToString()); } }
public NamedSymbol(string/*!*/ symbol, AIType/*!*/ typ)
: base(symbol, typ) {
Contract.Requires(typ != null);
Contract.Requires(symbol != null);
}
[NoDefaultContract]
[Pure]
[Reads(ReadsAttribute.Reads.Nothing)]
public override bool Equals(object other) {
NamedSymbol nsym = other as NamedSymbol;
return nsym != null && this.Value.Equals(nsym.Value);
}
[NoDefaultContract]
[Pure]
public override int GetHashCode() {
return Value.GetHashCode();
}
}
//
// In the following, the classes like Value and Prop serve two
// roles. The primary role is to be the base types for AIType.
// The only objects of these classes are the representative
// objects that denote an AIType, which are given by the
// "Type" property. Subtypes in the AIType language are
// encoded by subclassing. This yields some "higher-orderness"
// for checking subtyping in the AIType language, by using
// the Spec#/C# subclassing checks.
//
// The other role is simply as a module for collecting like function
// symbols.
//
//-------------------------- Terms ----------------------------------
///
/// A class with the equality symbol and the ValueType.Type.
///
public class Value : AIType
{
private static readonly AIType/*!*/ valtype = new Value();
public static AIType/*!*/ Type { get { Contract.Ensures(Contract.Result() != null); return valtype; } }
private static readonly FunctionType[]/*!*/ funtypeCache = new FunctionType[5];
public static FunctionType/*!*/ FunctionType(int inParameterCount) {
Contract.Requires((0 <= inParameterCount));
Contract.Ensures(Contract.Result() != null);
// Contract.Ensures(Contract.Result<>().Arity == inParameterCount);
FunctionType result;
if (inParameterCount < funtypeCache.Length) {
result = funtypeCache[inParameterCount];
if (result != null) {
return result;
}
}
AIType[] signature = new AIType[1 + inParameterCount];
for (int i = 0; i < signature.Length; i++) {
signature[i] = valtype;
}
result = new FunctionType(signature);
if (inParameterCount < funtypeCache.Length) {
funtypeCache[inParameterCount] = result;
}
return result;
}
[Once]
private static AIType/*!*/ binreltype;
private static AIType/*!*/ BinrelType {
get {
Contract.Ensures(Contract.Result() != null);
if (binreltype == null) {
binreltype = new FunctionType(Type, Type, Prop.Type);
}
return binreltype;
}
}
[Once]
private static FunctionSymbol/*!*/ _eq;
public static FunctionSymbol/*!*/ Eq {
get {
Contract.Ensures(Contract.Result() != null);
if (_eq == null) {
_eq = new FunctionSymbol("=", BinrelType);
}
return _eq;
}
}
[Once]
private static FunctionSymbol/*!*/ _neq;
public static FunctionSymbol/*!*/ Neq {
get {
Contract.Ensures(Contract.Result() != null);
if (_neq == null) {
_neq = new FunctionSymbol("!=", BinrelType);
}
return _neq;
}
}
[Once]
private static FunctionSymbol/*!*/ _subtype;
public static FunctionSymbol/*!*/ Subtype {
get {
Contract.Ensures(Contract.Result() != null);
if (_subtype == null) {
_subtype = new FunctionSymbol("<:", BinrelType);
}
return _subtype;
}
}
[Once]
private static AIType/*!*/ typeof_type;
private static AIType/*!*/ TypeofType {
get {
Contract.Ensures(Contract.Result() != null);
if (typeof_type == null) {
typeof_type = new FunctionType(Ref.Type, Type);
}
return typeof_type;
}
}
[Once]
private static FunctionSymbol/*!*/ _typeof;
public static FunctionSymbol/*!*/ Typeof {
get {
Contract.Ensures(Contract.Result() != null);
if (_typeof == null) {
_typeof = new FunctionSymbol("typeof", TypeofType);
}
return _typeof;
}
}
///
/// Value should not be instantiated from the outside, except perhaps in
/// subclasses.
///
protected Value() { }
}
public class Int : Value
{
private static readonly AIType/*!*/ inttype = new Int();
public static new AIType/*!*/ Type { get { Contract.Ensures(Contract.Result() != null); return inttype; } }
private static readonly AIType/*!*/ unaryinttype = new FunctionType(Type, Type);
private static readonly AIType/*!*/ bininttype = new FunctionType(Type, Type, Type);
private static readonly AIType/*!*/ relationtype = new FunctionType(Type, Type, Prop.Type);
private static readonly FunctionSymbol/*!*/ _negate = new FunctionSymbol("~", unaryinttype);
private static readonly FunctionSymbol/*!*/ _add = new FunctionSymbol("+", bininttype);
private static readonly FunctionSymbol/*!*/ _sub = new FunctionSymbol("-", bininttype);
private static readonly FunctionSymbol/*!*/ _mul = new FunctionSymbol("*", bininttype);
private static readonly FunctionSymbol/*!*/ _div = new FunctionSymbol("/", bininttype);
private static readonly FunctionSymbol/*!*/ _mod = new FunctionSymbol("%", bininttype);
private static readonly FunctionSymbol/*!*/ _atmost = new FunctionSymbol("<=", relationtype);
private static readonly FunctionSymbol/*!*/ _less = new FunctionSymbol("<", relationtype);
private static readonly FunctionSymbol/*!*/ _greater = new FunctionSymbol(">", relationtype);
private static readonly FunctionSymbol/*!*/ _atleast = new FunctionSymbol(">=", relationtype);
[Pure]
[Reads(ReadsAttribute.Reads.Nothing)]
public static FunctionSymbol/*!*/ Negate { get { Contract.Ensures(Contract.Result() != null); return _negate; } }
[Pure]
[Reads(ReadsAttribute.Reads.Nothing)]
public static FunctionSymbol/*!*/ Add { get { Contract.Ensures(Contract.Result() != null); return _add; } }
[Pure]
[Reads(ReadsAttribute.Reads.Nothing)]
public static FunctionSymbol/*!*/ Sub { get { Contract.Ensures(Contract.Result() != null); return _sub; } }
[Pure]
[Reads(ReadsAttribute.Reads.Nothing)]
public static FunctionSymbol/*!*/ Mul { get { Contract.Ensures(Contract.Result() != null); return _mul; } }
[Pure]
[Reads(ReadsAttribute.Reads.Nothing)]
public static FunctionSymbol/*!*/ Div { get { Contract.Ensures(Contract.Result() != null); return _div; } }
[Pure]
[Reads(ReadsAttribute.Reads.Nothing)]
public static FunctionSymbol/*!*/ Mod { get { Contract.Ensures(Contract.Result() != null); return _mod; } }
[Pure]
[Reads(ReadsAttribute.Reads.Nothing)]
public static FunctionSymbol/*!*/ AtMost { get { Contract.Ensures(Contract.Result() != null); return _atmost; } }
[Pure]
[Reads(ReadsAttribute.Reads.Nothing)]
public static FunctionSymbol/*!*/ Less { get { Contract.Ensures(Contract.Result() != null); return _less; } }
[Pure]
[Reads(ReadsAttribute.Reads.Nothing)]
public static FunctionSymbol/*!*/ Greater { get { Contract.Ensures(Contract.Result() != null); return _greater; } }
[Pure]
[Reads(ReadsAttribute.Reads.Nothing)]
public static FunctionSymbol/*!*/ AtLeast { get { Contract.Ensures(Contract.Result() != null); return _atleast; } }
public static IntSymbol/*!*/ Const(BigNum x) {
Contract.Ensures(Contract.Result() != null);
// We could cache things here, but for now we don't.
return new IntSymbol(x);
}
///
/// Int should not be instantiated from the outside, except perhaps in
/// subclasses.
///
private Int() { }
}
public class Double : Value
{
private static readonly AIType/*!*/ doubletype = new Double();
public static new AIType/*!*/ Type { get { Contract.Ensures(Contract.Result() != null); return doubletype; } }
public static DoubleSymbol/*!*/ Const(double x) {
Contract.Ensures(Contract.Result() != null);
// We could cache things here, but for now we don't.
return new DoubleSymbol(x);
}
///
/// Double should not be instantiated from the outside, except perhaps in
/// subclasses.
///
private Double() { }
}
public class Bv : Value
{
private static readonly AIType/*!*/ bvtype = new Bv();
public static new AIType/*!*/ Type { get { Contract.Ensures(Contract.Result() != null); return bvtype; } }
private static readonly AIType/*!*/ unaryinttype = new FunctionType(Type, Type);
private static readonly AIType/*!*/ bininttype = new FunctionType(Type, Type, Type);
private static readonly AIType/*!*/ relationtype = new FunctionType(Type, Type, Prop.Type);
private static readonly FunctionSymbol/*!*/ _negate = new FunctionSymbol("~", unaryinttype);
private static readonly FunctionSymbol/*!*/ _add = new FunctionSymbol("+", bininttype);
private static readonly FunctionSymbol/*!*/ _sub = new FunctionSymbol("-", bininttype);
private static readonly FunctionSymbol/*!*/ _mul = new FunctionSymbol("*", bininttype);
private static readonly FunctionSymbol/*!*/ _div = new FunctionSymbol("/", bininttype);
private static readonly FunctionSymbol/*!*/ _mod = new FunctionSymbol("%", bininttype);
private static readonly FunctionSymbol/*!*/ _concat = new FunctionSymbol("$concat", bininttype);
private static readonly FunctionSymbol/*!*/ _extract = new FunctionSymbol("$extract", unaryinttype);
private static readonly FunctionSymbol/*!*/ _atmost = new FunctionSymbol("<=", relationtype);
private static readonly FunctionSymbol/*!*/ _less = new FunctionSymbol("<", relationtype);
private static readonly FunctionSymbol/*!*/ _greater = new FunctionSymbol(">", relationtype);
private static readonly FunctionSymbol/*!*/ _atleast = new FunctionSymbol(">=", relationtype);
[Pure]
[Reads(ReadsAttribute.Reads.Nothing)]
public static FunctionSymbol/*!*/ Negate { get { Contract.Ensures(Contract.Result() != null); return _negate; } }
[Pure]
[Reads(ReadsAttribute.Reads.Nothing)]
public static FunctionSymbol/*!*/ Add { get { Contract.Ensures(Contract.Result() != null); return _add; } }
[Pure]
[Reads(ReadsAttribute.Reads.Nothing)]
public static FunctionSymbol/*!*/ Sub { get { Contract.Ensures(Contract.Result() != null); return _sub; } }
[Pure]
[Reads(ReadsAttribute.Reads.Nothing)]
public static FunctionSymbol/*!*/ Mul { get { Contract.Ensures(Contract.Result() != null); return _mul; } }
[Pure]
[Reads(ReadsAttribute.Reads.Nothing)]
public static FunctionSymbol/*!*/ Div { get { Contract.Ensures(Contract.Result() != null); return _div; } }
[Pure]
[Reads(ReadsAttribute.Reads.Nothing)]
public static FunctionSymbol/*!*/ Mod { get { Contract.Ensures(Contract.Result() != null); return _mod; } }
[Pure]
[Reads(ReadsAttribute.Reads.Nothing)]
public static FunctionSymbol/*!*/ AtMost { get { Contract.Ensures(Contract.Result() != null); return _atmost; } }
[Pure]
[Reads(ReadsAttribute.Reads.Nothing)]
public static FunctionSymbol/*!*/ Less { get { Contract.Ensures(Contract.Result() != null); return _less; } }
[Pure]
[Reads(ReadsAttribute.Reads.Nothing)]
public static FunctionSymbol/*!*/ Greater { get { Contract.Ensures(Contract.Result() != null); return _greater; } }
[Pure]
[Reads(ReadsAttribute.Reads.Nothing)]
public static FunctionSymbol/*!*/ AtLeast { get { Contract.Ensures(Contract.Result() != null); return _atleast; } }
[Pure]
[Reads(ReadsAttribute.Reads.Nothing)]
public static FunctionSymbol/*!*/ Extract { get { Contract.Ensures(Contract.Result() != null); return _extract; } }
[Pure]
[Reads(ReadsAttribute.Reads.Nothing)]
public static FunctionSymbol/*!*/ Concat { get { Contract.Ensures(Contract.Result() != null); return _concat; } }
public static BvSymbol/*!*/ Const(BigNum x, int y) {
Contract.Ensures(Contract.Result() != null);
// We could cache things here, but for now we don't.
return new BvSymbol(x, y);
}
///
/// Int should not be instantiated from the outside, except perhaps in
/// subclasses.
///
private Bv() { }
}
public class Ref : Value
{
private static readonly AIType/*!*/ reftype = new Ref();
public static new AIType/*!*/ Type { get { Contract.Ensures(Contract.Result() != null); return reftype; } }
private static readonly FunctionSymbol/*!*/ _null = new FunctionSymbol("null", Type);
public static FunctionSymbol/*!*/ Null { get { Contract.Ensures(Contract.Result() != null); return _null; } }
///
/// Ref should not be instantiated from the outside, except perhaps in
/// subclasses.
///
private Ref() { }
}
public class HeapStructure : Value
{
private static readonly AIType/*!*/ reftype = new HeapStructure();
public static new AIType/*!*/ Type { get { Contract.Ensures(Contract.Result() != null); return reftype; } }
///
/// HeapStructure should not be instantiated from the outside, except perhaps in
/// subclasses.
///
private HeapStructure() { }
}
public class FieldName : Value
{
private static readonly AIType/*!*/ fieldnametype = new FieldName();
public static new AIType/*!*/ Type { get { Contract.Ensures(Contract.Result() != null); return fieldnametype; } }
private static readonly FunctionSymbol/*!*/ _allocated = new FunctionSymbol("$allocated", FieldName.Type);
public static FunctionSymbol/*!*/ Allocated { get { Contract.Ensures(Contract.Result() != null); return _allocated; } }
///
/// Is this a boolean field that monotonically goes from false to true?
///
public static bool IsBooleanMonotonicallyWeakening(IFunctionSymbol/*!*/ f) {
Contract.Requires(f != null);
return f.Equals(Allocated);
}
///
/// FieldName should not be instantiated from the outside, except perhaps in
/// subclasses.
///
private FieldName() { }
}
public class Heap : Value
{
private static readonly AIType/*!*/ heaptype = new Heap();
public static new AIType/*!*/ Type { get { Contract.Ensures(Contract.Result() != null); return heaptype; } }
// the types in the following, select1, select2, are hard-coded;
// these types may not always be appropriate
private static readonly FunctionSymbol/*!*/ _select1 = new FunctionSymbol("sel1",
// Heap x FieldName -> Prop
new FunctionType(Type, FieldName.Type, Prop.Type)
);
public static FunctionSymbol/*!*/ Select1 { get { Contract.Ensures(Contract.Result() != null); return _select1; } }
private static readonly FunctionSymbol/*!*/ _select2 = new FunctionSymbol("sel2",
// Heap x Ref x FieldName -> Value
new FunctionType(Type, Ref.Type, FieldName.Type, Value.Type)
);
public static FunctionSymbol/*!*/ Select2 { get { Contract.Ensures(Contract.Result() != null); return _select2; } }
// the types in the following, store1, store2, are hard-coded;
// these types may not always be appropriate
private static readonly FunctionSymbol/*!*/ _update1 = new FunctionSymbol("upd1",
// Heap x FieldName x Value -> Heap
new FunctionType(Type, FieldName.Type, Value.Type, Type)
);
public static FunctionSymbol/*!*/ Update1 { get { Contract.Ensures(Contract.Result() != null); return _update1; } }
private static readonly FunctionSymbol/*!*/ _update2 = new FunctionSymbol("upd2",
// Heap x Ref x FieldName x Value -> Heap
new FunctionType(Type, Ref.Type, FieldName.Type, Value.Type, Type)
);
public static FunctionSymbol/*!*/ Update2 { get { Contract.Ensures(Contract.Result() != null); return _update2; } }
private static readonly FunctionSymbol/*!*/ _unsupportedHeapOp =
new FunctionSymbol("UnsupportedHeapOp",
// Heap x FieldName -> Prop
new FunctionType(Type, FieldName.Type, Prop.Type)
);
public static FunctionSymbol/*!*/ UnsupportedHeapOp { get { Contract.Ensures(Contract.Result() != null); return _unsupportedHeapOp; } }
///
/// Heap should not be instantiated from the outside, except perhaps in
/// subclasses.
///
private Heap() { }
}
// public class List : Value
// {
// private static IDictionary/**/! lists = new Hashtable();
// public static AIType! Type(AIType! typeParameter)
// {
// if (lists.Contains(typeParameter))
// return lists[typeParameter];
// else
// {
// AIType! result = new List(typeParameter);
// lists[typeParameter] = result;
// return result;
// }
// }
//
// private static IDictionary/**/! nils = new Hashtable();
// public static FunctionSymbol! Nil(AIType! typeParameter)
// {
// if (nils.Contains(typeParameter))
// return nils[typeParameter];
// else
// {
// FunctionSymbol! result = new FunctionSymbol(Type(typeParameter));
// nils[typeParameter] = result;
// return result;
// }
// }
//
// private static IDictionary/**/! cons = new Hashtable();
// public static FunctionSymbol! Cons(AIType! typeParameter)
// {
// if (cons.Contains(typeParameter))
// return cons[typeParameter];
// else
// {
// FunctionSymbol! result = new FunctionSymbol(
// new FunctionType(typeParameter, Type(typeParameter), Type(typeParameter))
// );
// cons[typeParameter] = result;
// return result;
// }
// }
//
// private AIType! typeParameter;
// public AIType(TypeParameter/*!*/ ){
//Contract.Requires( != null);
//return typeParameter; } }
//
// ///
// /// List should not be instantiated from the outside.
// ///
// private List(AIType! typeParameter)
// {
// this.typeParameter = typeParameter;
// }
// }
//
// public class Pair : Value
// {
// private static IDictionary! pairs = new Hashtable();
// public static AIType! Type(AIType! type1, AIType! type2)
// {
// Microsoft.AbstractInterpretationFramework.Collections.Pair typpair
// = new Microsoft.AbstractInterpretationFramework.Collections.Pair(type1, type2);
//
// if (pairs.Contains(typpair))
// return pairs[typpair];
// else
// {
// AIType! result = new Pair(type1, type2);
// pairs[typpair] = result;
// return result;
// }
// }
//
// private static IDictionary! constructs = new Hashtable();
// public static FunctionSymbol! Pair(AIType! type1, AIType! type2)
// {
// Microsoft.AbstractInterpretationFramework.Collections.Pair typpair
// = new Microsoft.AbstractInterpretationFramework.Collections.Pair(type1, type2);
//
// if (constructs.Contains(typpair))
// return constructs[typpair];
// else
// {
// FunctionSymbol! result = new FunctionSymbol(
// new FunctionType(type1, type2, Type(type1, type2))
// );
// constructs[typpair] = result;
// return result;
// }
// }
//
// protected AIType! type1;
// protected AIType! type2;
//
// public AIType(Type1/*!*/ ){
//Contract.Requires( != null);
// return type1; } }
// public AIType(Type2/*!*/ ){
//Contract.Requires( != null);
// return type2; } }
//
// ///
// /// Pair should not be instantiated from the outside, except by subclasses.
// ///
// protected Pair(AIType! type1, AIType! type2)
// {
// this.type1 = type1;
// this.type2 = type2;
// }
// }
//-------------------------- Propositions ---------------------------
///
/// A class with global propositional symbols and the Prop.Type.
///
public sealed class Prop : AIType
{
private static readonly AIType/*!*/ proptype = new Prop();
public static AIType/*!*/ Type { get { Contract.Ensures(Contract.Result() != null); return proptype; } }
private static readonly AIType/*!*/ unaryproptype = new FunctionType(Type, Type);
private static readonly AIType/*!*/ binproptype = new FunctionType(Type, Type, Type);
private static readonly AIType/*!*/ quantifiertype =
new FunctionType(new FunctionType(Value.Type, Type), Type);
private static readonly FunctionSymbol/*!*/ _false = new FunctionSymbol("false", Type);
private static readonly FunctionSymbol/*!*/ _true = new FunctionSymbol("true", Type);
private static readonly FunctionSymbol/*!*/ _not = new FunctionSymbol("!", unaryproptype);
private static readonly FunctionSymbol/*!*/ _and = new FunctionSymbol("/\\", binproptype);
private static readonly FunctionSymbol/*!*/ _or = new FunctionSymbol("\\/", binproptype);
private static readonly FunctionSymbol/*!*/ _implies = new FunctionSymbol("==>", binproptype);
private static readonly FunctionSymbol/*!*/ _exists = new FunctionSymbol("Exists", quantifiertype);
private static readonly FunctionSymbol/*!*/ _forall = new FunctionSymbol("Forall", quantifiertype);
private static readonly FunctionSymbol/*!*/ _lambda = new FunctionSymbol("Lambda", quantifiertype);
[Pure]
[Reads(ReadsAttribute.Reads.Nothing)]
public static FunctionSymbol/*!*/ False { get { Contract.Ensures(Contract.Result() != null); return _false; } }
[Pure]
[Reads(ReadsAttribute.Reads.Nothing)]
public static FunctionSymbol/*!*/ True { get { Contract.Ensures(Contract.Result() != null); return _true; } }
[Pure]
[Reads(ReadsAttribute.Reads.Nothing)]
public static FunctionSymbol/*!*/ Not { get { Contract.Ensures(Contract.Result() != null); return _not; } }
[Pure]
[Reads(ReadsAttribute.Reads.Nothing)]
public static FunctionSymbol/*!*/ And { [Pure] get { Contract.Ensures(Contract.Result() != null); return _and; } }
[Pure]
[Reads(ReadsAttribute.Reads.Nothing)]
public static FunctionSymbol/*!*/ Or { get { Contract.Ensures(Contract.Result() != null); return _or; } }
[Pure]
[Reads(ReadsAttribute.Reads.Nothing)]
public static FunctionSymbol/*!*/ Implies { get { Contract.Ensures(Contract.Result() != null); return _implies; } }
[Pure]
[Reads(ReadsAttribute.Reads.Nothing)]
public static FunctionSymbol/*!*/ Exists { get { Contract.Ensures(Contract.Result() != null); return _exists; } }
[Pure]
[Reads(ReadsAttribute.Reads.Nothing)]
public static FunctionSymbol/*!*/ Forall { get { Contract.Ensures(Contract.Result() != null); return _forall; } }
[Pure]
[Reads(ReadsAttribute.Reads.Nothing)]
public static FunctionSymbol/*!*/ Lambda { get { Contract.Ensures(Contract.Result() != null); return _lambda; } }
///
/// Prop should not be instantiated from the outside.
///
private Prop() { }
//
// Utility Methods
//
public static IExpr/*!*/ SimplifiedAnd(IPropExprFactory/*!*/ factory, IExpr/*!*/ e0, IExpr/*!*/ e1) {
Contract.Requires(e1 != null);
Contract.Requires(e0 != null);
Contract.Requires(factory != null);
Contract.Ensures(Contract.Result() != null);
IFunApp fun0 = e0 as IFunApp;
if (fun0 != null) {
if (fun0.FunctionSymbol.Equals(Prop.True)) {
return e1;
} else if (fun0.FunctionSymbol.Equals(Prop.False)) {
return e0;
}
}
IFunApp fun1 = e1 as IFunApp;
if (fun1 != null) {
if (fun1.FunctionSymbol.Equals(Prop.True)) {
return e0;
} else if (fun1.FunctionSymbol.Equals(Prop.False)) {
return e1;
}
}
return factory.And(e0, e1);
}
public static IExpr/*!*/ SimplifiedAnd(IPropExprFactory/*!*/ factory, IEnumerable/**//*!*/ exprs) {
Contract.Requires(exprs != null);
Contract.Requires(factory != null);
Contract.Ensures(Contract.Result() != null);
IExpr/*!*/ result = factory.True;
Contract.Assert(result != null);
foreach (IExpr/*!*/ conjunct in exprs) {
Contract.Assert(conjunct != null);
result = SimplifiedAnd(factory, result, conjunct);
}
return result;
}
public static IExpr/*!*/ SimplifiedOr(IPropExprFactory/*!*/ factory, IExpr/*!*/ e0, IExpr/*!*/ e1) {
Contract.Requires(e1 != null);
Contract.Requires(e0 != null);
Contract.Requires(factory != null);
Contract.Ensures(Contract.Result() != null);
IFunApp fun0 = e0 as IFunApp;
if (fun0 != null) {
if (fun0.FunctionSymbol.Equals(Prop.False)) {
return e1;
} else if (fun0.FunctionSymbol.Equals(Prop.True)) {
return e0;
}
}
IFunApp fun1 = e1 as IFunApp;
if (fun1 != null) {
if (fun1.FunctionSymbol.Equals(Prop.False)) {
return e0;
} else if (fun1.FunctionSymbol.Equals(Prop.True)) {
return e1;
}
}
return factory.Or(e0, e1);
}
public static IExpr/*!*/ SimplifiedOr(IPropExprFactory/*!*/ factory, IEnumerable/**//*!*/ exprs) {
Contract.Requires(exprs != null);
Contract.Requires(factory != null);
Contract.Ensures(Contract.Result() != null);
IExpr/*!*/ result = factory.False;
Contract.Assert(result != null);
foreach (IExpr/*!*/ disj in exprs) {
Contract.Assert(disj != null);
result = SimplifiedOr(factory, result, disj);
}
return result;
}
///
/// Break top-level conjuncts into a list of sub-expressions.
///
/// The expression to examine.
/// A list of conjuncts.
internal static IList/**//*!*/ BreakConjuncts(IExpr/*!*/ e) {
Contract.Requires(e != null);
Contract.Ensures(Contract.Result() != null);
Contract.Ensures(Contract.ForAll(0, Contract.Result().Count, i => {
var sub = Contract.Result()[i];
return !(sub is IFunApp) || !((IFunApp)sub).FunctionSymbol.Equals(Prop.And);
}));
return BreakJuncts(e, Prop.And);
}
///
/// Break top-level disjuncts into a list of sub-expressions.
///
/// The expression to examine.
/// A list of conjuncts.
internal static IList/**//*!*/ BreakDisjuncts(IExpr/*!*/ e) {
Contract.Requires(e != null);
Contract.Ensures(Contract.Result() != null);
Contract.Ensures(Contract.ForAll(0, Contract.Result().Count, i => {
var sub = Contract.Result()[i];
return !(sub is IFunApp) || !((IFunApp)sub).FunctionSymbol.Equals(Prop.Or);
}));
return BreakJuncts(e, Prop.Or);
}
private static IList/**//*!*/ BreakJuncts(IExpr/*!*/ e, IFunctionSymbol/*!*/ sym) {
Contract.Requires(sym != null);
Contract.Requires(e != null);
Contract.Ensures(Contract.Result() != null);
Contract.Ensures(Contract.ForAll(0, Contract.Result().Count, i => {
var sub = Contract.Result()[i];
return (sub is IFunApp) || !((IFunApp)sub).FunctionSymbol.Equals(sym);
}));
ArrayList/**//*!*/ result = new ArrayList();
IFunApp f = e as IFunApp;
if (f != null) {
// If it is a sym, go down into sub-expressions.
if (f.FunctionSymbol.Equals(sym)) {
foreach (IExpr/*!*/ arg in f.Arguments) {
Contract.Assert(arg != null);
result.AddRange(BreakJuncts(arg, sym));
}
}
// Otherwise, stop.
else {
result.Add(e);
}
} else {
result.Add(e);
}
return result;
}
}
///
/// A callback to produce a function body given the bound variable.
///
/// The bound variable to use.
/// The function body.
public delegate IExpr/*!*/ FunctionBody(IVariable/*!*/ var);
///
/// An interface for constructing propositional expressions.
///
/// This interface should be implemented by the client. An implementation of
/// of this class should generally be used as a singleton object.
///
///
[ContractClass(typeof(IPropExprFactoryContracts))]
public interface IPropExprFactory
{
IFunApp/*!*/ False { get /*ensures result.FunctionSymbol.Equals(Prop.False);*/; }
IFunApp/*!*/ True { get /*ensures result.FunctionSymbol.Equals(Prop.True);*/; }
IFunApp/*!*/ Not(IExpr/*!*/ p) /*ensures result.FunctionSymbol.Equals(Prop.Not);*/;
IFunApp/*!*/ And(IExpr/*!*/ p, IExpr/*!*/ q) /*ensures result.FunctionSymbol.Equals(Prop.And);*/;
IFunApp/*!*/ Or(IExpr/*!*/ p, IExpr/*!*/ q) /*ensures result.FunctionSymbol.Equals(Prop.Or);*/;
IFunApp/*!*/ Implies(IExpr/*!*/ p, IExpr/*!*/ q) /*ensures result.FunctionSymbol.Equals(Prop.Implies);*/;
}
[ContractClassFor(typeof(IPropExprFactory))]
public abstract class IPropExprFactoryContracts : IPropExprFactory
{
#region IPropExprFactory Members
IFunApp IPropExprFactory.Implies(IExpr p, IExpr q) {
Contract.Requires(p != null);
Contract.Requires(q != null);
Contract.Ensures(Contract.Result() != null);
throw new System.NotImplementedException();
}
IFunApp IPropExprFactory.False {
get { Contract.Ensures(Contract.Result() != null); throw new System.NotImplementedException(); }
}
IFunApp IPropExprFactory.True {
get { Contract.Ensures(Contract.Result() != null); throw new System.NotImplementedException(); }
}
IFunApp IPropExprFactory.Not(IExpr p) {
Contract.Requires(p != null);
Contract.Ensures(Contract.Result() != null);
throw new System.NotImplementedException();
}
IFunApp IPropExprFactory.And(IExpr p, IExpr q) {
Contract.Requires(p != null);
Contract.Requires(q != null);
Contract.Ensures(Contract.Result() != null);
throw new System.NotImplementedException();
}
IFunApp IPropExprFactory.Or(IExpr p, IExpr q) {
Contract.Requires(p != null);
Contract.Requires(q != null);
Contract.Ensures(Contract.Result() != null);
throw new System.NotImplementedException();
}
#endregion
}
///
/// An interface for constructing value expressions.
///
/// This interface should be implemented by the client. An implementation of
/// of this class should generally be used as a singleton object.
///
///
[ContractClass(typeof(IValueExprFactoryContracts))]
public interface IValueExprFactory
{
IFunApp/*!*/ Eq(IExpr/*!*/ e0, IExpr/*!*/ e1) /*ensures result.FunctionSymbol.Equals(Value.Eq);*/;
IFunApp/*!*/ Neq(IExpr/*!*/ e0, IExpr/*!*/ e1) /*ensures result.FunctionSymbol.Equals(Value.Neq);*/;
}
[ContractClassFor(typeof(IValueExprFactory))]
public abstract class IValueExprFactoryContracts : IValueExprFactory
{
#region IValueExprFactory Members
IFunApp IValueExprFactory.Eq(IExpr e0, IExpr e1) {
Contract.Requires(e0 != null);
Contract.Requires(e1 != null);
Contract.Ensures(Contract.Result() != null);
throw new System.NotImplementedException();
}
IFunApp IValueExprFactory.Neq(IExpr e0, IExpr e1) {
Contract.Requires(e0 != null);
Contract.Requires(e1 != null);
Contract.Ensures(Contract.Result() != null);
throw new System.NotImplementedException();
}
#endregion
}
///
/// An interface for constructing value expressions having to with null.
///
/// This interface should be implemented by the client. An implementation of
/// of this class should generally be used as a singleton object.
///
///
[ContractClass(typeof(INullnessFactoryContracts))]
public interface INullnessFactory
{
IFunApp/*!*/ Eq(IExpr/*!*/ e0, IExpr/*!*/ e1) /*ensures result.FunctionSymbol.Equals(Value.Eq);*/;
IFunApp/*!*/ Neq(IExpr/*!*/ e0, IExpr/*!*/ e1) /*ensures result.FunctionSymbol.Equals(Value.Neq);*/;
IFunApp/*!*/ Null { get; /*ensures result.FunctionSymbol.Equals(Ref.Null);*/ }
}
[ContractClassFor(typeof(INullnessFactory))]
public abstract class INullnessFactoryContracts : INullnessFactory
{
#region INullnessFactory Members
IFunApp INullnessFactory.Eq(IExpr e0, IExpr e1) {
Contract.Requires(e0 != null);
Contract.Requires(e1 != null);
Contract.Ensures(Contract.Result() != null);
throw new System.NotImplementedException();
}
IFunApp INullnessFactory.Neq(IExpr e0, IExpr e1) {
Contract.Requires(e0 != null);
Contract.Requires(e1 != null);
Contract.Ensures(Contract.Result() != null);
throw new System.NotImplementedException();
}
IFunApp INullnessFactory.Null {
get {
Contract.Ensures(Contract.Result() != null);
throw new System.NotImplementedException();
}
}
#endregion
}
///
/// An interface for constructing integer expressions.
///
/// This interface should be implemented by the client. An implementation of
/// of this class should generally be used as a singleton object.
///
///
[ContractClass(typeof(IIntExprFactoryContracts))]
public interface IIntExprFactory : IValueExprFactory
{
IFunApp/*!*/ Const(BigNum i) /*ensures result.FunctionSymbol.Equals(new IntSymbol(i));*/;
}
[ContractClassFor(typeof(IIntExprFactory))]
public abstract class IIntExprFactoryContracts : IIntExprFactory
{
#region IIntExprFactory Members
IFunApp IIntExprFactory.Const(BigNum i) {
Contract.Ensures(Contract.Result() != null);
throw new System.NotImplementedException();
}
#endregion
#region IValueExprFactory Members
IFunApp IValueExprFactory.Eq(IExpr e0, IExpr e1) {
throw new System.NotImplementedException();
}
IFunApp IValueExprFactory.Neq(IExpr e0, IExpr e1) {
throw new System.NotImplementedException();
}
#endregion
}
///
/// An interface for constructing linear integer expressions.
///
/// This interface should be implemented by the client. An implementation of
/// of this class should generally be used as a singleton object.
///
///
[ContractClass(typeof(ILinearExprFactoryContracts))]
public interface ILinearExprFactory : IIntExprFactory
{
IFunApp/*!*/ AtMost(IExpr/*!*/ e0, IExpr/*!*/ e1) /*ensures result.FunctionSymbol.Equals(Value.AtMost);*/;
IFunApp/*!*/ Add(IExpr/*!*/ e0, IExpr/*!*/ e1) /*ensures result.FunctionSymbol.Equals(Value.Add);*/;
///
/// If "var" is null, returns an expression representing r.
/// Otherwise, returns an expression representing r*var.
///
IExpr/*!*/ Term(Microsoft.Basetypes.Rational r, IVariable var);
IFunApp/*!*/ False { get /*ensures result.FunctionSymbol.Equals(Prop.False);*/; }
IFunApp/*!*/ True { get /*ensures result.FunctionSymbol.Equals(Prop.True);*/; }
IFunApp/*!*/ And(IExpr/*!*/ p, IExpr/*!*/ q) /*ensures result.FunctionSymbol.Equals(Prop.And);*/;
}
[ContractClassFor(typeof(ILinearExprFactory))]
public abstract class ILinearExprFactoryContracts : ILinearExprFactory
{
#region ILinearExprFactory Members
IFunApp ILinearExprFactory.AtMost(IExpr e0, IExpr e1) {
Contract.Requires(e0 != null);
Contract.Requires(e1 != null);
Contract.Ensures(Contract.Result() != null);
throw new System.NotImplementedException();
}
IFunApp ILinearExprFactory.Add(IExpr e0, IExpr e1) {
Contract.Requires(e0 != null);
Contract.Requires(e1 != null); Contract.Ensures(Contract.Result() != null);
throw new System.NotImplementedException();
}
IExpr ILinearExprFactory.Term(Rational r, IVariable var) {
Contract.Ensures(Contract.Result() != null);
throw new System.NotImplementedException();
}
IFunApp ILinearExprFactory.False {
get { Contract.Ensures(Contract.Result() != null); throw new System.NotImplementedException(); }
}
IFunApp ILinearExprFactory.True {
get { Contract.Ensures(Contract.Result() != null); throw new System.NotImplementedException(); }
}
IFunApp ILinearExprFactory.And(IExpr p, IExpr q) {
Contract.Requires(p != null);
Contract.Requires(q != null);
Contract.Ensures(Contract.Result() != null);
throw new System.NotImplementedException();
}
#endregion
#region IIntExprFactory Members
IFunApp IIntExprFactory.Const(BigNum i) {
throw new System.NotImplementedException();
}
#endregion
#region IValueExprFactory Members
IFunApp IValueExprFactory.Eq(IExpr e0, IExpr e1) {
throw new System.NotImplementedException();
}
IFunApp IValueExprFactory.Neq(IExpr e0, IExpr e1) {
throw new System.NotImplementedException();
}
#endregion
}
///
/// An interface for constructing type expressions and performing some type operations.
/// The types are assumed to be arranged in a rooted tree.
///
/// This interface should be implemented by the client. An implementation of
/// of this class should generally be used as a singleton object.
///
///
[ContractClass(typeof(ITypeExprFactoryContracts))]
public interface ITypeExprFactory
{
///
/// Returns an expression denoting the top of the type hierarchy.
///
IExpr/*!*/ RootType { get; }
///
/// Returns true iff "t" denotes a type constant.
///
[Pure]
bool IsTypeConstant(IExpr/*!*/ t);
///
/// Returns true iff t0 and t1 are types such that t0 and t1 are equal.
///
[Pure]
bool IsTypeEqual(IExpr/*!*/ t0, IExpr/*!*/ t1);
///
/// Returns true iff t0 and t1 are types such that t0 is a subtype of t1.
///
[Pure]
bool IsSubType(IExpr/*!*/ t0, IExpr/*!*/ t1);
///
/// Returns the most derived supertype of both "t0" and "t1". A precondition is
/// that "t0" and "t1" both represent types.
///
IExpr/*!*/ JoinTypes(IExpr/*!*/ t0, IExpr/*!*/ t1);
IFunApp/*!*/ IsExactlyA(IExpr/*!*/ e, IExpr/*!*/ type) /*requires IsTypeConstant(type); ensures result.FunctionSymbol.Equals(Value.Eq);*/;
IFunApp/*!*/ IsA(IExpr/*!*/ e, IExpr/*!*/ type) /*requires IsTypeConstant(type); ensures result.FunctionSymbol.Equals(Value.Subtype);*/;
}
[ContractClassFor(typeof(ITypeExprFactory))]
public abstract class ITypeExprFactoryContracts : ITypeExprFactory
{
#region ITypeExprFactory Members
IExpr ITypeExprFactory.RootType {
get { Contract.Ensures(Contract.Result() != null); throw new System.NotImplementedException(); }
}
bool ITypeExprFactory.IsTypeConstant(IExpr t) {
Contract.Requires(t != null);
throw new System.NotImplementedException();
}
bool ITypeExprFactory.IsTypeEqual(IExpr t0, IExpr t1) {
Contract.Requires(t0 != null);
Contract.Requires(t1 != null);
throw new System.NotImplementedException();
}
bool ITypeExprFactory.IsSubType(IExpr t0, IExpr t1) {
Contract.Requires(t0 != null);
Contract.Requires(t1 != null);
throw new System.NotImplementedException();
}
IExpr ITypeExprFactory.JoinTypes(IExpr t0, IExpr t1) {
Contract.Requires(t0 != null);
Contract.Requires(t1 != null);
Contract.Ensures(Contract.Result() != null);
throw new System.NotImplementedException();
}
IFunApp ITypeExprFactory.IsExactlyA(IExpr e, IExpr type) {
Contract.Requires(e != null);
Contract.Requires(type != null);
Contract.Ensures(Contract.Result() != null);
throw new System.NotImplementedException();
}
IFunApp ITypeExprFactory.IsA(IExpr e, IExpr type) {
Contract.Requires(e != null);
Contract.Requires(type != null);
Contract.Ensures(Contract.Result() != null);
throw new System.NotImplementedException();
}
#endregion
}
}