// PrefixTypeSubst.dfy

/*
module _System {
  /* CALL GRAPH for module _System:
   * SCC at height 2:
   *   RotateRight
   * SCC at height 1:
   *   RotateLeft
   * SCC at height 0:
   *   nat
   */
  type string(==) = seq<char>

  type {:axiom} nat(==) = x: int
    | 0 <= x

  trait {:compile false} object { }
  /*-- non-null type
  type {:axiom} object(==) = c: object? | c != null    /*special witness*/
  */

  class {:compile false} array<arg> {
    var Length: int  // immutable
  }
  /*-- non-null type
  type {:axiom} array(==)<arg> = c: array?<arg> | c != null    /*special witness*/
  */

  class {:compile false} /*_#Func0*/ () ~> +R {
    function requires(): bool
      reads reads()

    function reads(): set<object?>
      reads reads()
  }

  type {:compile false} /*_#PartialFunc0*/ () --> +R = f: () ~> R
    | f.reads() == {}
    /*special witness*/

  type {:compile false} /*_#TotalFunc0*/ () -> +R = f: () --> R
    | f.requires()
    /*special witness*/

  class {:compile false} /*_#Func2*/ (-T0, -T1) ~> +R {
    function requires(x0: T0, x1: T1): bool
      reads reads(x0, x1)

    function reads(x0: T0, x1: T1): set<object?>
      reads reads(x0, x1)
  }

  type {:compile false} /*_#PartialFunc2*/ (-T0, -T1) --> +R = f: (T0, T1) ~> R
    | forall x0: T0, x1: T1 :: f.reads(x0, x1) == {}
    /*special witness*/

  type {:compile false} /*_#TotalFunc2*/ (-T0, -T1) -> +R = f: (T0, T1) --> R
    | forall x0: T0, x1: T1 :: f.requires(x0, x1)
    /*special witness*/

  class {:compile false} /*_#Func3*/ (-T0, -T1, -T2) ~> +R {
    function requires(x0: T0, x1: T1, x2: T2): bool
      reads reads(x0, x1, x2)

    function reads(x0: T0, x1: T1, x2: T2): set<object?>
      reads reads(x0, x1, x2)
  }

  type {:compile false} /*_#PartialFunc3*/ (-T0, -T1, -T2) --> +R = f: (T0, T1, T2) ~> R
    | forall x0: T0, x1: T1, x2: T2 :: f.reads(x0, x1, x2) == {}
    /*special witness*/

  type {:compile false} /*_#TotalFunc3*/ (-T0, -T1, -T2) -> +R = f: (T0, T1, T2) --> R
    | forall x0: T0, x1: T1, x2: T2 :: f.requires(x0, x1, x2)
    /*special witness*/

  class {:compile false} /*_#Func1*/ -T0 ~> +R {
    function requires(x0: T0): bool
      reads reads(x0)

    function reads(x0: T0): set<object?>
      reads reads(x0)
  }

  type {:compile false} /*_#PartialFunc1*/ -T0 --> +R = f: T0 ~> R
    | forall x0: T0 :: f.reads(x0) == {}
    /*special witness*/

  type {:compile false} /*_#TotalFunc1*/ -T0 -> +R = f: T0 --> R
    | forall x0: T0 :: f.requires(x0)
    /*special witness*/

  datatype {:compile false} /*_tuple#2*/ (+T0, +T1) = _#Make2(0: T0, 1: T1)

  type bool { }

  type int { }

  type real {
    var Floor: int  // immutable
  }

  type ORDINAL {
    var IsLimit: bool  // immutable
    var IsSucc: bool  // immutable
    var Offset: int  // immutable
    var IsNat: bool  // immutable
  }

  type bv {
    function method RotateLeft(w: nat): selftype

    function method RotateRight(w: nat): selftype
  }

  type map<T, U> {
    var Keys: set<T>  // immutable
    var Values: set<U>  // immutable
    var Items: set<(T, U)>  // immutable
  }

  type imap<T, U> {
    var Keys: iset<T>  // immutable
    var Values: iset<U>  // immutable
    var Items: iset<(T, U)>  // immutable
  }

  datatype /*_tuple#0*/ () = _#Make0
}
// bitvector types in use:
*/

/* CALL GRAPH for module _module:
 * SCC at height 37:
 *   RstRst10#
 * SCC at height 36:
 *   RstRst10
 * SCC at height 35:
 *   RstRst9
 *   RstRst9#
 * SCC at height 34:
 *   RstRst8
 *   RstRst8#
 * SCC at height 33:
 *   RstRst7#
 * SCC at height 32:
 *   RstRst7
 * SCC at height 31:
 *   RstRst6
 *   RstRst6#
 * SCC at height 30:
 *   RstRst5
 *   RstRst5#
 * SCC at height 29:
 *   RstRst4#
 * SCC at height 28:
 *   RstRst4
 * SCC at height 27:
 *   RstRst3#
 * SCC at height 26:
 *   RstRst3
 * SCC at height 25:
 *   RstRst2#
 * SCC at height 24:
 *   RstRst2
 * SCC at height 23:
 *   RstRst1#
 * SCC at height 22:
 *   RstRst1
 * SCC at height 21:
 *   RstRst0#
 * SCC at height 20:
 *   RstRst0
 * SCC at height 19:
 *   O#
 * SCC at height 18:
 *   O
 * SCC at height 17:
 *   N#
 * SCC at height 16:
 *   N
 * SCC at height 15:
 *   MyClass
 * SCC at height 14:
 *   MyClass.M#
 * SCC at height 13:
 *   MyClass.M
 * SCC at height 12:
 *   MyClass.L#
 * SCC at height 11:
 *   MyClass.L
 * SCC at height 10:
 *   MyClass.RST_Nat#
 * SCC at height 9:
 *   nat
 * SCC at height 8:
 *   MyClass.RST_Nat
 * SCC at height 7:
 *   MyClass.RST#
 * SCC at height 6:
 *   MyClass.RST
 * SCC at height 5:
 *   MyClass.S#
 * SCC at height 4:
 *   MyClass.S
 * SCC at height 3:
 *   MyClass.R#
 * SCC at height 2:
 *   MyClass.R
 * SCC at height 1:
 *   MyClass.P#
 * SCC at height 0:
 *   MyClass.P
 */
class MyClass<A, B> {
  copredicate P<X, Y>(x: X, y: Y)
  {
    P(x, y)
  }
  /*** (note, what is printed here does not show substitutions of calls to prefix predicates)
  predicate P#<X, Y>[_k: ORDINAL](x: X, y: Y)
    decreases _k
  {
    P(x, y)
  }
  ***/

  copredicate R<T>()
  {
    R<T>()
  }
  /*** (note, what is printed here does not show substitutions of calls to prefix predicates)
  predicate R#<T>[_k: ORDINAL]()
    decreases _k
  {
    R<T>()
  }
  ***/

  static copredicate S<Q>()
  {
    S<Q>()
  }
  /*** (note, what is printed here does not show substitutions of calls to prefix predicates)
  static predicate S#<Q>[_k: ORDINAL]()
    decreases _k
  {
    S<Q>()
  }
  ***/

  static copredicate RST<QQ>()
  {
    MyClass<B, A>.RST<QQ>()
  }
  /*** (note, what is printed here does not show substitutions of calls to prefix predicates)
  static predicate RST#<QQ>[_k: ORDINAL]()
    decreases _k
  {
    MyClass<B, A>.RST<QQ>()
  }
  ***/

  static copredicate RST_Nat<QQ>[nat]()
  {
    MyClass<B, A>.RST_Nat<QQ>()
  }
  /*** (note, what is printed here does not show substitutions of calls to prefix predicates)
  static predicate RST_Nat#<QQ>[_k: nat]()
    decreases _k
  {
    MyClass<B, A>.RST_Nat<QQ>()
  }
  ***/

  colemma L<U, V>(u: U, v: V)
    ensures P(u, v)
  {
    L(u, v);
  }
  /***
  lemma /*{:_induction _k}*/ L#<U, V>[_k: ORDINAL](u: U, v: V)
    ensures P#[_k](u, v)
    decreases _k
  {
    if 0 < _k.Offset {
      L#[_k - 1](u, v);
    } else {
      forall _k': ORDINAL, u: U, v: V /*{:_autorequires}*/ /*{:_trustWellformed}*/ {:auto_generated} | _k' < _k
        ensures this.P#[_k'](u, v)
      {
        L#[_k'](u, v)
      }
    }
  }
  ***/

  colemma M<W>()
    ensures R<char>()
  {
    M<W>();
    assert R#<char>[_k - 1]();
  }
  /***
  lemma /*{:_induction _k}*/ M#<W>[_k: ORDINAL]()
    ensures R#<char>[_k]()
    decreases _k
  {
    if 0 < _k.Offset {
      M#<W>[_k - 1]();
      assert R#<char>[_k - 1]();
    } else {
      forall _k': ORDINAL /*{:_autorequires}*/ /*{:_trustWellformed}*/ {:auto_generated} | _k' < _k
        ensures this.R#[_k']()
      {
        M#[_k']()
      }
    }
  }
  ***/
}
/*-- non-null type
type {:axiom} MyClass(==)<A, B> = c: MyClass?<A, B> | c != null  /*special witness*/
*/

colemma N<D0, D1, D2>(o: MyClass<D0, D1>)
  ensures o.R<D2>()
{
  N<D0, D1, D2>(o);
}
/***
lemma /*{:_induction _k}*/ N#<D0, D1, D2>[_k: ORDINAL](o: MyClass<D0, D1>)
  ensures o.R#<D2>[_k]()
  decreases _k, o
{
  if 0 < _k.Offset {
    N#<D0, D1, D2>[_k - 1](o);
  } else {
    forall _k': ORDINAL, o: MyClass<D0, D1> /*{:_autorequires}*/ /*{:_trustWellformed}*/ {:auto_generated} | _k' < _k
      ensures o.R#[_k']()
    {
      N#[_k'](o)
    }
  }
}
***/

colemma O<D0, D1, D2>()
  ensures MyClass<D0, D1>.S<D2>()
{
  O<D0, D1, D2>();
}
/***
lemma /*{:_induction _k}*/ O#<D0, D1, D2>[_k: ORDINAL]()
  ensures MyClass<D0, D1>.S#<D2>[_k]()
  decreases _k
{
  if 0 < _k.Offset {
    O#<D0, D1, D2>[_k - 1]();
  } else {
    forall _k': ORDINAL /*{:_autorequires}*/ /*{:_trustWellformed}*/ {:auto_generated} | _k' < _k
      ensures MyClass<D0, D1>.S#[_k']()
    {
      O#[_k']()
    }
  }
}
***/

colemma {:induction false} RstRst0<alpha, gamma>()
  ensures MyClass<alpha, char>.RST<gamma>()
{
  RstRst0<int, gamma>();
}
/***
lemma {:induction false} RstRst0#<alpha, gamma>[_k: ORDINAL]()
  ensures MyClass<alpha, char>.RST#<gamma>[_k]()
  decreases _k
{
  if 0 < _k.Offset {
    RstRst0#<int, gamma>[_k - 1]();
  } else {
    forall _k': ORDINAL /*{:_autorequires}*/ /*{:_trustWellformed}*/ {:auto_generated} | _k' < _k
      ensures MyClass<alpha, char>.RST#[_k']()
    {
      RstRst0#[_k']()
    }
  }
}
***/

colemma {:induction false} RstRst1<alpha, gamma>()
  ensures MyClass<alpha, char>.RST<gamma>()
{
  RstRst1<int, int>();
}
/***
lemma {:induction false} RstRst1#<alpha, gamma>[_k: ORDINAL]()
  ensures MyClass<alpha, char>.RST#<gamma>[_k]()
  decreases _k
{
  if 0 < _k.Offset {
    RstRst1#<int, int>[_k - 1]();
  } else {
    forall _k': ORDINAL /*{:_autorequires}*/ /*{:_trustWellformed}*/ {:auto_generated} | _k' < _k
      ensures MyClass<alpha, char>.RST#[_k']()
    {
      RstRst1#[_k']()
    }
  }
}
***/

colemma {:induction false} RstRst2<alpha, gamma>()
  ensures MyClass<alpha, char>.RST<gamma>()
{
  RstRst2<alpha, gamma>();
}
/***
lemma {:induction false} RstRst2#<alpha, gamma>[_k: ORDINAL]()
  ensures MyClass<alpha, char>.RST#<gamma>[_k]()
  decreases _k
{
  if 0 < _k.Offset {
    RstRst2#<alpha, gamma>[_k - 1]();
  } else {
    forall _k': ORDINAL /*{:_autorequires}*/ /*{:_trustWellformed}*/ {:auto_generated} | _k' < _k
      ensures MyClass<alpha, char>.RST#[_k']()
    {
      RstRst2#[_k']()
    }
  }
}
***/

colemma {:induction false} RstRst3<alpha, beta, gamma>()
  ensures MyClass<alpha, beta>.RST<gamma>()
{
  RstRst3<alpha, beta, gamma>();
}
/***
lemma {:induction false} RstRst3#<alpha, beta, gamma>[_k: ORDINAL]()
  ensures MyClass<alpha, beta>.RST#<gamma>[_k]()
  decreases _k
{
  if 0 < _k.Offset {
    RstRst3#<alpha, beta, gamma>[_k - 1]();
  } else {
    forall _k': ORDINAL /*{:_autorequires}*/ /*{:_trustWellformed}*/ {:auto_generated} | _k' < _k
      ensures MyClass<alpha, beta>.RST#[_k']()
    {
      RstRst3#[_k']()
    }
  }
}
***/

colemma {:induction false} RstRst4<alpha, beta, gamma>()
  ensures MyClass<alpha, beta>.RST<gamma>()
{
  RstRst4<beta, alpha, gamma>();
}
/***
lemma {:induction false} RstRst4#<alpha, beta, gamma>[_k: ORDINAL]()
  ensures MyClass<alpha, beta>.RST#<gamma>[_k]()
  decreases _k
{
  if 0 < _k.Offset {
    RstRst4#<beta, alpha, gamma>[_k - 1]();
  } else {
    forall _k': ORDINAL /*{:_autorequires}*/ /*{:_trustWellformed}*/ {:auto_generated} | _k' < _k
      ensures MyClass<alpha, beta>.RST#[_k']()
    {
      RstRst4#[_k']()
    }
  }
}
***/

colemma {:induction false} RstRst5<alpha, gamma>()
  ensures MyClass<alpha, char>.RST<gamma>()
{
  if 2 <= _k.Offset {
    RstRst5#<alpha, gamma>[_k - 2]();
  } else {
    assert _k.Offset == 1;
  }
}
/***
lemma {:induction false} RstRst5#<alpha, gamma>[_k: ORDINAL]()
  ensures MyClass<alpha, char>.RST#<gamma>[_k]()
  decreases _k
{
  if 0 < _k.Offset {
    if 2 <= _k.Offset {
      RstRst5#<alpha, gamma>[_k - 2]();
    } else {
      assert _k.Offset == 1;
    }
  } else {
    forall _k': ORDINAL /*{:_autorequires}*/ /*{:_trustWellformed}*/ {:auto_generated} | _k' < _k
      ensures MyClass<alpha, char>.RST#[_k']()
    {
      RstRst5#[_k']()
    }
  }
}
***/

colemma {:induction false} RstRst6<alpha, beta, gamma>()
  ensures MyClass<alpha, beta>.RST<gamma>()
{
  if
  case true =>
    RstRst6<beta, alpha, gamma>();
  case 2 <= _k.Offset =>
    RstRst6#<alpha, beta, gamma>[_k - 2]();
}
/***
lemma {:induction false} RstRst6#<alpha, beta, gamma>[_k: ORDINAL]()
  ensures MyClass<alpha, beta>.RST#<gamma>[_k]()
  decreases _k
{
  if 0 < _k.Offset {
    if
    case true =>
      RstRst6#<beta, alpha, gamma>[_k - 1]();
    case 2 <= _k.Offset =>
      RstRst6#<alpha, beta, gamma>[_k - 2]();
  } else {
    forall _k': ORDINAL /*{:_autorequires}*/ /*{:_trustWellformed}*/ {:auto_generated} | _k' < _k
      ensures MyClass<alpha, beta>.RST#[_k']()
    {
      RstRst6#[_k']()
    }
  }
}
***/

colemma RstRst7<alpha, beta, gamma>()
  ensures MyClass<alpha, beta>.RST<gamma>()
{
  if _k != 1 && _k.Offset == 1 {
    RstRst6<beta, alpha, gamma>();
  } else {
  }
}
/***
lemma /*{:_induction _k}*/ RstRst7#<alpha, beta, gamma>[_k: ORDINAL]()
  ensures MyClass<alpha, beta>.RST#<gamma>[_k]()
  decreases _k
{
  if 0 < _k.Offset {
    if _k != 1 && _k.Offset == 1 {
      RstRst6<beta, alpha, gamma>();
    } else {
    }
  } else {
    forall _k': ORDINAL /*{:_autorequires}*/ /*{:_trustWellformed}*/ {:auto_generated} | _k' < _k
      ensures MyClass<alpha, beta>.RST#[_k']()
    {
      RstRst7#[_k']()
    }
  }
}
***/

colemma {:induction false} RstRst8<alpha, gamma>[nat]()
  ensures MyClass<alpha, char>.RST_Nat<gamma>()
{
  if 2 <= _k {
    RstRst8#<alpha, gamma>[_k - 2]();
  }
}
/***
lemma {:induction false} RstRst8#<alpha, gamma>[_k: nat]()
  ensures MyClass<alpha, char>.RST_Nat#<gamma>[_k]()
  decreases _k
{
  if 0 < _k {
    if 2 <= _k {
      RstRst8#<alpha, gamma>[_k - 2]();
    }
  }
}
***/

colemma {:induction false} RstRst9<alpha, beta, gamma>[nat]()
  ensures MyClass<alpha, beta>.RST_Nat<gamma>()
{
  if 2 <= _k {
    RstRst9#<alpha, beta, gamma>[_k - 2]();
  }
}
/***
lemma {:induction false} RstRst9#<alpha, beta, gamma>[_k: nat]()
  ensures MyClass<alpha, beta>.RST_Nat#<gamma>[_k]()
  decreases _k
{
  if 0 < _k {
    if 2 <= _k {
      RstRst9#<alpha, beta, gamma>[_k - 2]();
    }
  }
}
***/

colemma RstRst10<alpha, beta, gamma>[nat]()
  ensures MyClass<alpha, beta>.RST_Nat<gamma>()
{
}
/***
lemma /*{:_induction _k}*/ RstRst10#<alpha, beta, gamma>[_k: nat]()
  ensures MyClass<alpha, beta>.RST_Nat#<gamma>[_k]()
  decreases _k
{
  if 0 < _k {
  }
}
***/
PrefixTypeSubst.dfy(52,0): Error BP5003: A postcondition might not hold on this return path.
PrefixTypeSubst.dfy(51,30): Related location: This is the postcondition that might not hold.
PrefixTypeSubst.dfy(19,17): Related location
Execution trace:
    (0,0): anon0
    (0,0): anon3_Then
PrefixTypeSubst.dfy(58,0): Error BP5003: A postcondition might not hold on this return path.
PrefixTypeSubst.dfy(57,30): Related location: This is the postcondition that might not hold.
PrefixTypeSubst.dfy(19,17): Related location
Execution trace:
    (0,0): anon0
    (0,0): anon3_Then
PrefixTypeSubst.dfy(64,0): Error BP5003: A postcondition might not hold on this return path.
PrefixTypeSubst.dfy(63,30): Related location: This is the postcondition that might not hold.
PrefixTypeSubst.dfy(19,17): Related location
Execution trace:
    (0,0): anon0
    (0,0): anon3_Then
PrefixTypeSubst.dfy(70,0): Error BP5003: A postcondition might not hold on this return path.
PrefixTypeSubst.dfy(69,30): Related location: This is the postcondition that might not hold.
PrefixTypeSubst.dfy(19,17): Related location
Execution trace:
    (0,0): anon0
    (0,0): anon3_Then
PrefixTypeSubst.dfy(85,9): Error BP5003: A postcondition might not hold on this return path.
PrefixTypeSubst.dfy(81,30): Related location: This is the postcondition that might not hold.
PrefixTypeSubst.dfy(19,17): Related location
Execution trace:
    (0,0): anon0
    (0,0): anon5_Then
    (0,0): anon6_Else

Dafny program verifier finished with 16 verified, 5 errors
