<commit_before>package arithmetic

import org.junit.Assert._
import org.junit.Test

import scala.util.Random



class TestExpr {

  private val rnd = new Random(0)

  private def rndPositive() : Int = {
    val r = rnd.nextInt(5)
    if (r == 0)
      r+1
    else if (r < 0)
      -r
    else
      r
  }

  private def rndExpr(maxDepth: Int, depth: Int=0) : ArithExpr = {

    if (depth > maxDepth)
      return Cst(rndPositive())

    Random.nextInt(3) match {
      case 0 => rndExpr(maxDepth, depth+1) * rndExpr(maxDepth, depth+1)
      case 1 => rndExpr(maxDepth, depth+1) + rndExpr(maxDepth, depth+1)
      case 2 => rndExpr(maxDepth, depth+1) / rndExpr(maxDepth, depth+1)
    }
  }

  @Test def testRandom() {

    for (a <- 1 to 10) {
      val re = rndExpr(3)
      println("random expression = "+re)

      val oriEval = re.evalDbl()
      val sim = ExprSimplifier.simplify(re)
      println("simplified expression = "+sim)

      val simEval = sim.evalDbl()
      assert(math.abs(oriEval-simEval) <= 1.0/1000000.0, oriEval+" != "+simEval)
    }


  }

  @Test def testSimplifcation() {

    testRandom()

    val c0 = Cst(0)
    val c1 = Cst(1)
    val c2 = Cst(2)
    val c10 = Cst(10)
    //val v = Var(new RangeMul(c0,c2,c10))
    val e = (c0+c1)*(c10+c2)+(c10/c2)

    ExprSimplifier.simplify(e).eval()

    assertEquals(e.eval(), ExprSimplifier.simplify(e).eval())

    //println(e.eval())
    val result = ExprSimplifier.simplify(e)
    //println(result.eval())

    assertEquals(Cst(17),result)

    //val e2 = (c0/v+c1/v)*v*(c10+c2)+(c10/c2)
    //val result2 = ExprSimplifier.simplify(e)
    //println(result2)
  }

  @Test def Division(): Unit = {
    val i = Var("i")
    val M = Var("M")
    assertEquals(i + i % M, ExprSimplifier.simplify(i / M * M + i % M))
  }

  @Test def Fraction(): Unit = {
    val i = Var("i")
    val M = Var("M")
    assertEquals((i div M) * M, ExprSimplifier.simplify((i div M) * M))
  }

  @Test def remainderAndModulo(): Unit = {
    val a = Var("x")
    val d = Var("d")
    assertEquals(a, ExprSimplifier.simplify((a div d) * d + a % d))
  }

  @Test def modOfVarWithVarRange(): Unit = {
    val M = Var("M")
    val i = Var(GoesToRange(M))
    assertEquals(i, ExprSimplifier.simplify(i % M))
  }

  @Test def modOfVarWithConstantRange(): Unit = {
    val c =  Cst(10)
    val i = Var(GoesToRange(c))
    assertEquals(i, ExprSimplifier.simplify(i % c))
  }

  @Test def modOfVarWithConstantRange2(): Unit = {
    val i = Var(GoesToRange(Cst(10)))
    assertEquals(i, ExprSimplifier.simplify(i % Cst(128)))
  }

  @Test def modSameDividendDivisor(): Unit = {
    val N = Var("N")
    assertEquals(Cst(0), ExprSimplifier.simplify(N % N))
  }

  @Test def modDivisorZero(): Unit = {
    val N = Var("N")
    assertEquals(Cst(0), ExprSimplifier.simplify(0 % N))<commit_msg>New failure: range based arithmetic with modulo and division. Reopen #6.<commit_after>package arithmetic

import org.junit.Assert._
import org.junit.{Ignore, Test}

import scala.util.Random



class TestExpr {

  private val rnd = new Random(0)

  private def rndPositive() : Int = {
    val r = rnd.nextInt(5)
    if (r == 0)
      r+1
    else if (r < 0)
      -r
    else
      r
  }

  private def rndExpr(maxDepth: Int, depth: Int=0) : ArithExpr = {

    if (depth > maxDepth)
      return Cst(rndPositive())

    Random.nextInt(3) match {
      case 0 => rndExpr(maxDepth, depth+1) * rndExpr(maxDepth, depth+1)
      case 1 => rndExpr(maxDepth, depth+1) + rndExpr(maxDepth, depth+1)
      case 2 => rndExpr(maxDepth, depth+1) / rndExpr(maxDepth, depth+1)
    }
  }

  @Test def testRandom() {

    for (a <- 1 to 10) {
      val re = rndExpr(3)
      println("random expression = "+re)

      val oriEval = re.evalDbl()
      val sim = ExprSimplifier.simplify(re)
      println("simplified expression = "+sim)

      val simEval = sim.evalDbl()
      assert(math.abs(oriEval-simEval) <= 1.0/1000000.0, oriEval+" != "+simEval)
    }


  }

  @Test def testSimplifcation() {

    testRandom()

    val c0 = Cst(0)
    val c1 = Cst(1)
    val c2 = Cst(2)
    val c10 = Cst(10)
    //val v = Var(new RangeMul(c0,c2,c10))
    val e = (c0+c1)*(c10+c2)+(c10/c2)

    ExprSimplifier.simplify(e).eval()

    assertEquals(e.eval(), ExprSimplifier.simplify(e).eval())

    //println(e.eval())
    val result = ExprSimplifier.simplify(e)
    //println(result.eval())

    assertEquals(Cst(17),result)

    //val e2 = (c0/v+c1/v)*v*(c10+c2)+(c10/c2)
    //val result2 = ExprSimplifier.simplify(e)
    //println(result2)
  }

  @Test def Division(): Unit = {
    val i = Var("i")
    val M = Var("M")
    assertEquals(i + i % M, ExprSimplifier.simplify(i / M * M + i % M))
  }

  @Test def Fraction(): Unit = {
    val i = Var("i")
    val M = Var("M")
    assertEquals((i div M) * M, ExprSimplifier.simplify((i div M) * M))
  }

  @Test def remainderAndModulo(): Unit = {
    val a = Var("x")
    val d = Var("d")
    assertEquals(a, ExprSimplifier.simplify((a div d) * d + a % d))
  }

  @Test def modOfVarWithVarRange(): Unit = {
    val M = Var("M")
    val i = Var(GoesToRange(M))
    assertEquals(i, ExprSimplifier.simplify(i % M))
  }

  @Test def modOfVarWithConstantRange(): Unit = {
    val c =  Cst(10)
    val i = Var(GoesToRange(c))
    assertEquals(i, ExprSimplifier.simplify(i % c))
  }

  @Ignore
  @Test def DivModOfVarWithConstantRange(): Unit = {
    val c =  Cst(10)
    val i = Var(GoesToRange(c))
    // TODO(tlutz): (i % c) / x = 0 when x > c
    assertEquals(Cst(0), ExprSimplifier.simplify(i % c)/Cst(20))
  }

  @Test def modOfVarWithConstantRange2(): Unit = {
    val i = Var(GoesToRange(Cst(10)))
    assertEquals(i, ExprSimplifier.simplify(i % Cst(128)))
  }

  @Test def modSameDividendDivisor(): Unit = {
    val N = Var("N")
    assertEquals(Cst(0), ExprSimplifier.simplify(N % N))
  }

  @Test def modDivisorZero(): Unit = {
    val N = Var("N")
    assertEquals(Cst(0), ExprSimplifier.simplify(0 % N))
{'fraction_non_alphanumeric': 0.15826612903225806, 'fraction_numerical': 0.026713709677419355, 'mean_word_length': 2.8111395646606914, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 12, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5756020', 'n_tokens_mistral': 2471, 'n_tokens_neox': 2292, 'n_words': 518}