// git-issue228.dfy

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;
}

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
git-issue228.dfy(42,15): Error: result of operation might violate newtype constraint for 'NegIsOdd'
git-issue228.dfy(48,15): Error: result of operation might violate newtype constraint for 'Byte'

Dafny program verifier finished with 8 verified, 2 errors
// git-issue228.dfy

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

  type {:axiom} nat(==,0) = 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> {
    const Length: int
  }
  /*-- non-null type
  type {:axiom} array(==)<arg> = c: array?<arg> | c != null /*special witness*/
  */

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

    ghost 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 {:compile false} /*_#Func0*/ () ~> +R {
    ghost function requires(): bool
      reads reads()

    ghost 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 /*_tuple#2*/ (+T0, +T1) = _#Make2(0: T0, 1: T1)

  type bool { }

  type char { }

  type int { }

  type real {
    const Floor: int
  }

  type ORDINAL {
    const IsLimit: bool
    const IsSucc: bool
    const Offset: int
    const IsNat: bool
  }

  type _bv {
    function RotateLeft(w: nat): selftype

    function RotateRight(w: nat): selftype
  }

  type set<+T> { }

  type iset<*T> { }

  type seq<+T> { }

  type multiset<+T> { }

  type map<+T, +U> {
    const Keys: set<T>
    const Values: set<U>
    const Items: set<(T, U)>
  }

  type imap<*T, +U> {
    const Keys: iset<T>
    const Values: iset<U>
    const Items: iset<(T, U)>
  }

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

/* CALL GRAPH for module _module:
 * SCC at height 1:
 *   ConstrainedIntermediateExpressions
 * SCC at height 1:
 *   SubsetTypes
 * SCC at height 0:
 *   Byte
 * SCC at height 0:
 *   NegIsOdd
 * SCC at height 0:
 *   Numerics
 * SCC at height 0:
 *   Sequences
 * SCC at height 0:
 *   Sets
 * SCC at height 0:
 *   Subset_Byte
 * SCC at height 0:
 *   Subset_NegIsOdd
 */
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;
}

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
git-issue228.dfy(42,15): Error: result of operation might violate newtype constraint for 'NegIsOdd'
git-issue228.dfy(48,15): Error: result of operation might violate newtype constraint for 'Byte'

Dafny program verifier finished with 8 verified, 2 errors
