// git-issue228.dfy

newtype NegIsOdd = x
  | x < 0 ==> x % 2 == 1
  witness 1

newtype Byte = x
  | 0 <= x < 256

type Subset_NegIsOdd = x
  | x < 0 ==> x % 2 == 1
  witness 1

type Subset_Byte = x
  | 0 <= x < 256

lemma Sequences(s: seq, t: seq, u: seq)
  ensures s + t + u == s + (t + u)
{
}

lemma Sets(s: set, t: set, u: set)
  ensures s + t + u == s + (t + u)
  ensures s * t * u == s * (t * u)
{
}

method Numerics()
    returns (x: int, n: nat, r: real, o: ORDINAL, b: bv0, c: bv19)
{
  x := x + x + (x + x);
  n := n + n + (n + n);
  r := r + r + (r + r);
  o := o + o + (o + o);
  b := b + b + (b + b);
  c := c + c + (c + c);
}

method ConstrainedIntermediateExpressions(a: NegIsOdd, b: NegIsOdd, x: Byte, z: Byte)
  requires 0 <= b && z == 0
{
  var c0 := a + (b + b);
  var c1 := a + b + b;
  var d0 := x * (x * z);
  var d1 := x * x * z;
}

method SubsetTypes(a: Subset_NegIsOdd, b: Subset_NegIsOdd, x: Subset_Byte, z: Subset_Byte)
  requires 0 <= b && z == 0
{
  var c0 := a + (b + b);
  var c1 := a + b + b;
  var d0 := x * (x * z);
  var d1 := x * x * z;
}
git-issue228.dfy(42,15): Error: result of operation might violate newtype constraint for 'NegIsOdd'
Execution trace:
    (0,0): anon0
git-issue228.dfy(48,15): Error: result of operation might violate newtype constraint for 'Byte'
Execution trace:
    (0,0): anon0

Dafny program verifier finished with 8 verified, 2 errors
// git-issue228.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*/

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

  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*/

  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: bv0 bv19
*/

/* CALL GRAPH for module _module:
 * SCC at height 9:
 *   Sets
 * SCC at height 8:
 *   Sequences
 * SCC at height 7:
 *   SubsetTypes
 * SCC at height 6:
 *   Subset_Byte
 * SCC at height 5:
 *   Subset_NegIsOdd
 * SCC at height 4:
 *   ConstrainedIntermediateExpressions
 * SCC at height 3:
 *   Byte
 * SCC at height 2:
 *   NegIsOdd
 * SCC at height 1:
 *   Numerics
 * SCC at height 0:
 *   nat
 */
newtype NegIsOdd = x: int
  | x < 0 ==> x % 2 == 1
  witness 1

newtype Byte = x: int
  | 0 <= x < 256

type Subset_NegIsOdd = x: int
  | x < 0 ==> x % 2 == 1
  witness 1

type Subset_Byte = x: int
  | 0 <= x < 256

lemma Sequences(s: seq, t: seq, u: seq)
  ensures s + t + u == s + (t + u)
  decreases s, t, u
{
}

lemma Sets(s: set, t: set, u: set)
  ensures s + t + u == s + (t + u)
  ensures s * t * u == s * (t * u)
  decreases s, t, u
{
}

method Numerics()
    returns (x: int, n: nat, r: real, o: ORDINAL, b: bv0, c: bv19)
{
  x := x + x + x + x;
  n := n + n + n + n;
  r := r + r + r + r;
  o := o + o + o + o;
  b := b + b + b + b;
  c := c + c + c + c;
}

method ConstrainedIntermediateExpressions(a: NegIsOdd, b: NegIsOdd, x: Byte, z: Byte)
  requires 0 <= b && z == 0
  decreases a, b, x, z
{
  var c0: NegIsOdd := a + (b + b);
  var c1: NegIsOdd := a + b + b;
  var d0: Byte := x * (x * z);
  var d1: Byte := x * x * z;
}

method SubsetTypes(a: Subset_NegIsOdd, b: Subset_NegIsOdd, x: Subset_Byte, z: Subset_Byte)
  requires 0 <= b && z == 0
  decreases a, b, x, z
{
  var c0: int := a + b + b;
  var c1: int := a + b + b;
  var d0: int := x * x * z;
  var d1: int := x * x * z;
}
git-issue228.dfy(42,15): Error: result of operation might violate newtype constraint for 'NegIsOdd'
Execution trace:
    (0,0): anon0
git-issue228.dfy(48,15): Error: result of operation might violate newtype constraint for 'Byte'
Execution trace:
    (0,0): anon0

Dafny program verifier finished with 8 verified, 2 errors
