From 3699c6e301affb6e0999b03e26bd683e984eb8ed Mon Sep 17 00:00:00 2001 From: Gianluca Amato Date: Fri, 9 Dec 2016 15:32:00 +0100 Subject: [PATCH 01/99] Use ScalaFix version 0.5.1. --- core/build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/build.sbt b/core/build.sbt index ae9e56fd..f95d9cd9 100644 --- a/core/build.sbt +++ b/core/build.sbt @@ -7,7 +7,7 @@ libraryDependencies ++= Seq( "org.mockito" % "mockito-core" % "2.2.9" % "test", "org.spire-math" %% "spire" % "0.12.0", "org.scalanlp" %% "breeze" % "0.12", - "it.unich.scalafix" %% "scalafix" % "0.5.0", + "it.unich.scalafix" %% "scalafix" % "0.5.1", // for using native linear algebra libraries // "org.scalanlp" %% "breeze-natives" % "0.12", "org.rogach" %% "scallop" % "2.0.3", From 30ade4ba1f3c8d8f6bcc927c9d6b7eb71a455703 Mon Sep 17 00:00:00 2001 From: Gianluca Amato Date: Fri, 9 Dec 2016 15:32:14 +0100 Subject: [PATCH 02/99] Hacks for fixing widening and narrowing. This is only a small hack. A complete redesign of Jandom is required to use the ScalaFix equation solver. --- .../it/unich/jandom/targets/cfg/ControlFlowGraph.scala | 8 ++++---- core/src/main/scala/it/unich/jandom/targets/lts/LTS.scala | 4 ++-- .../scala/it/unich/jandom/targets/slil/WhileStmt.scala | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/core/src/main/scala/it/unich/jandom/targets/cfg/ControlFlowGraph.scala b/core/src/main/scala/it/unich/jandom/targets/cfg/ControlFlowGraph.scala index 81580332..d96a0654 100644 --- a/core/src/main/scala/it/unich/jandom/targets/cfg/ControlFlowGraph.scala +++ b/core/src/main/scala/it/unich/jandom/targets/cfg/ControlFlowGraph.scala @@ -124,6 +124,8 @@ abstract class ControlFlowGraph[Tgt <: ControlFlowGraph[Tgt, Node], Node] extend * The analyzer. At the moment, it implements a work-list based analysis. */ def analyzeFromAnnotation(params: Parameters)(ann: Annotation[ProgramPoint, params.Property]): Annotation[ProgramPoint, params.Property] = { + val widening = params.widening.copy + val narrowing = params.narrowing.copy val annEdge = HashMap[Edge, params.Property]() val taskList = Queue[ProgramPoint](graph.getHeads: _*) @@ -140,8 +142,7 @@ abstract class ControlFlowGraph[Tgt <: ControlFlowGraph[Tgt, Node], Node] extend params.log(s"join $succ : ${ann(succ)} with $out") val succval: params.Property = if (ordering.lteq(succ, node)) { params.log(s" widening") - val widening = params.widening(node) - widening(ann(succ), out) + widening(node)(ann(succ), out) } else ann(succ) union out if (succval > ann(succ)) { @@ -172,8 +173,7 @@ abstract class ControlFlowGraph[Tgt <: ControlFlowGraph[Tgt, Node], Node] extend params.log(s"narrow $succ : ${ann(succ)} with $newinput ") // this may probably cause an infinite loop val succval = if (ordering.lteq(succ, node)) { - val narrowing = params.narrowing(node) - narrowing(ann(succ), newinput) + narrowing(node)(ann(succ), newinput) } else newinput params.log(s"result $succval\n") diff --git a/core/src/main/scala/it/unich/jandom/targets/lts/LTS.scala b/core/src/main/scala/it/unich/jandom/targets/lts/LTS.scala index c7046072..2f793167 100644 --- a/core/src/main/scala/it/unich/jandom/targets/lts/LTS.scala +++ b/core/src/main/scala/it/unich/jandom/targets/lts/LTS.scala @@ -161,14 +161,14 @@ case class LTS(val name: String, val locations: IndexedSeq[Location], val transi val widenings = locations map { l => if (params.wideningLocation == WideningNarrowingLocation.All || (params.wideningLocation == WideningNarrowingLocation.Loop && isJoinNode(l))) - Some(params.widening(l)) + Some(params.widening(l).copy) else None } val narrowings = locations map { l => if (params.narrowingLocation == WideningNarrowingLocation.All || (params.narrowingLocation == WideningNarrowingLocation.Loop && isJoinNode(l))) - Some(params.narrowing(l)) + Some(params.narrowing(l).copy) else None } diff --git a/core/src/main/scala/it/unich/jandom/targets/slil/WhileStmt.scala b/core/src/main/scala/it/unich/jandom/targets/slil/WhileStmt.scala index f77cc434..310bee08 100644 --- a/core/src/main/scala/it/unich/jandom/targets/slil/WhileStmt.scala +++ b/core/src/main/scala/it/unich/jandom/targets/slil/WhileStmt.scala @@ -51,8 +51,8 @@ case class WhileStmt(condition: NumericCondition, body: SLILStmt) extends SLILSt params.nestingLevel += 1 // Determines widening/narrowing operators to use - val widening = params.widening((this, 1)) - val narrowing = params.narrowing((this, 1)) + val widening = params.widening((this, 1)).copy + val narrowing = params.narrowing((this, 1)).copy // Determines initial values for the analysis, depending on the calling phase var (bodyResult, invariant) = From d8281aaf03cdce7fe1e7706adf41937beec6cf7f Mon Sep 17 00:00:00 2001 From: Gianluca Amato Date: Fri, 9 Dec 2016 23:33:48 +0100 Subject: [PATCH 03/99] Replace cappi with sbt-jmh since the latter is better maintained. --- extended/build.sbt | 21 ++- .../benchmarks/BoxDoubleBenchmark.scala | 135 +++++++++++++++++ .../jandom/benchmarks/FASTBenchmark.scala | 77 +++++----- .../ppl/it/unich/jandom/JandomBenchmark.scala | 33 ---- .../numerical/ppl/BoxDoubleBenchmark.scala | 143 ------------------ .../unich/jandom/benchmarks/FASTLoader.scala | 3 +- project/caliper.sbt | 6 - project/jmh.sbt | 1 + 8 files changed, 190 insertions(+), 229 deletions(-) create mode 100644 extended/src/jmh/scala/it/unich/jandom/benchmarks/BoxDoubleBenchmark.scala rename extended/src/{test => jmh}/scala/it/unich/jandom/benchmarks/FASTBenchmark.scala (52%) delete mode 100644 extended/src/test/ppl/it/unich/jandom/JandomBenchmark.scala delete mode 100644 extended/src/test/ppl/it/unich/jandom/domains/numerical/ppl/BoxDoubleBenchmark.scala delete mode 100644 project/caliper.sbt create mode 100644 project/jmh.sbt diff --git a/extended/build.sbt b/extended/build.sbt index 6a745a6b..029bdad2 100644 --- a/extended/build.sbt +++ b/extended/build.sbt @@ -15,14 +15,27 @@ mergeStrategy in assembly <<= (mergeStrategy in assembly) { (old) => } } -//*** Cappi plugin +//*** Eclipse plugin -cappiSettings +EclipseKeys.createSrc := EclipseCreateSrc.ValueSet() -//*** Eclipse plugin +EclipseKeys.configurations += config("jmh") EclipseKeys.executionEnvironment := Some(EclipseExecutionEnvironment.JavaSE17) EclipseKeys.eclipseOutput := Some("target.eclipse") -incOptions := incOptions.value.withLogRecompileOnMacro(false) \ No newline at end of file +incOptions := incOptions.value.withLogRecompileOnMacro(false) + +//*** JMH Plugin + +enablePlugins(JmhPlugin) + +run in Jmh <<= (run in Jmh) dependsOn (compile in Jmh) + +// We prefer to change resourceDirectories instead of resourceDirectory so that directories do not +// appear in the Eclipse project. +resourceDirectories in Jmh := ((baseDirectory in ThisBuild).value / "core" / "src" / "test" / "resources") +: + ( (managedResourceDirectories in Jmh).value ++ (unmanagedResourceDirectories in Jmh).value ) + +dependencyClasspath in Jmh := (fullClasspath in Test).value diff --git a/extended/src/jmh/scala/it/unich/jandom/benchmarks/BoxDoubleBenchmark.scala b/extended/src/jmh/scala/it/unich/jandom/benchmarks/BoxDoubleBenchmark.scala new file mode 100644 index 00000000..088ec7c5 --- /dev/null +++ b/extended/src/jmh/scala/it/unich/jandom/benchmarks/BoxDoubleBenchmark.scala @@ -0,0 +1,135 @@ +/** + * Copyright 2013, 2016 Gianluca Amato + * + * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains + * JANDOM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * JANDOM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of a + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with JANDOM. If not, see . + */ + +package it.unich.jandom.benchmarks + +import it.unich.jandom.domains.numerical._ +import it.unich.jandom.domains.numerical.ppl._ +import org.openjdk.jmh.annotations._ +import parma_polyhedra_library._ +import it.unich.jandom.domains.numerical.LinearForm.c + +/** + * This benchmark compare some operations on the interval domain. This + * shows that PPL is very slow in Jandom, and Reflexive PPL is even + * slower. + * @author Gianluca Amato + */ +@State(Scope.Thread) +@Warmup(iterations = 5) +class BoxDoubleBenchmark { + private val numvars = 100 + private val numpoints = 10 + private val BoxDouble = BoxDoubleDomain() + + PPLInitializer + + @Benchmark + def timePPL() { + // create an empty box + val db = new Double_Box(numvars, Degenerate_Element.EMPTY) + + // initialize a list of linear form (one for each variable) + val vars = new Array[Linear_Expression_Variable](numvars) + for (v <- 0 until numvars) vars(v) = new Linear_Expression_Variable(new Variable(v)) + + // initialize the linear form x_1 + ... + x_n + val diagonal = vars.reduceRight[Linear_Expression](_.sum(_)) + val gs = new Generator_System() + for (i <- 1 to numpoints) { + val point = Generator.point(diagonal times (new Coefficient(i)), new Coefficient(1)) + gs.clear + gs.add(point) + val point_box = new Double_Box(gs) + db.upper_bound_assign(point_box) + } + } + + @Benchmark + def timePPL2() { + val db = new Double_Box(numvars, Degenerate_Element.EMPTY) + val v0 = new Variable(0) + val vlast = new Variable(numvars - 1) + val expr = (new Linear_Expression_Variable(v0)) sum (new Linear_Expression_Variable(vlast)) + val gs = new Generator_System() + val point = Generator.point(expr, new Coefficient(1)) + gs.add(point) + db.upper_bound_assign(new Double_Box(gs)) + val denominator = new Coefficient(1) + for (i <- 1 to numpoints) { + val dbnew = new Double_Box(db) + dbnew.affine_image(v0, expr, denominator) + db.upper_bound_assign(dbnew) + } + } + + @Benchmark + def timeJandomNoPPLOptimized() { + var db = BoxDouble.bottom(numvars) + for (i <- 1 to numpoints) { + val point = Array.fill(numvars)(i.toDouble) + db = db union BoxDouble(point) + } + } + + @Benchmark + def timeJandomNoPPL() { + var db = BoxDouble.bottom(numvars) + val zero = Array.fill(numvars)(0.0) + val full = BoxDouble.top(numvars) + for (i <- 1 to numpoints) { + val point = (0 until numvars).foldLeft(full) { (box, v) => box.linearAssignment(v, i.toDouble) } + db = db union point + } + } + + @Benchmark + def timeJandomPPL() { + val PPLBoxDouble = PPLBoxDoubleDomain() + var db = PPLBoxDouble.bottom(numvars) + val full = PPLBoxDouble.top(numvars) + for (i <- 1 to numpoints) { + val point = (0 until numvars).foldLeft(full) { (box, v) => box.linearAssignment(v, i.toDouble) } + db = db union point + } + } + + @Benchmark + def timeJandomPPLReflexive() { + val domain = PPLDomain[Octagonal_Shape_double]() + var db = domain.bottom(numvars) + val full = domain.top(numvars) + for (i <- 1 to numpoints) { + val point = (0 until numvars).foldLeft(full) { (box, v) => box.linearAssignment(v, i.toDouble) } + db = db union point + } + } + + @Benchmark + def timeJandomPPLMacro() { + // we explicitly type domain in order to avoid generation of existential types. + val domain: NumericalDomain = PPLDomainMacro[Double_Box] + var db = domain.bottom(numvars) + val zero = Array.fill(numvars)(0.0) + val full = domain.top(numvars) + for (i <- 1 to numpoints) { + val point = (0 until numvars).foldLeft(full) { (box, v) => box.linearAssignment(v, i.toDouble) } + db = db union point + } + } +} diff --git a/extended/src/test/scala/it/unich/jandom/benchmarks/FASTBenchmark.scala b/extended/src/jmh/scala/it/unich/jandom/benchmarks/FASTBenchmark.scala similarity index 52% rename from extended/src/test/scala/it/unich/jandom/benchmarks/FASTBenchmark.scala rename to extended/src/jmh/scala/it/unich/jandom/benchmarks/FASTBenchmark.scala index 8d853d2e..283ef378 100644 --- a/extended/src/test/scala/it/unich/jandom/benchmarks/FASTBenchmark.scala +++ b/extended/src/jmh/scala/it/unich/jandom/benchmarks/FASTBenchmark.scala @@ -1,5 +1,5 @@ /** - * Copyright 2015 Gianluca Amato + * Copyright 2015, 2016 Gianluca Amato * * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains * JANDOM is free software: you can redistribute it and/or modify @@ -18,8 +18,6 @@ package it.unich.jandom.benchmarks -import com.google.caliper.SimpleBenchmark - import it.unich.jandom.domains.numerical.BoxDoubleDomain import it.unich.jandom.targets.Parameters import it.unich.jandom.targets.lts.LTS @@ -27,11 +25,14 @@ import it.unich.jandom.targets.lts.Location import it.unich.scalafix.Box.apply import it.unich.scalafix.FixpointSolver._ import it.unich.scalafix.finite.FiniteFixpointSolver +import org.openjdk.jmh.annotations._ /** * This is a program which analyzes the Alice benchmarks with different settings and compares the execution time. */ -class FASTBenchmark extends SimpleBenchmark with FASTLoader { +@State(Scope.Thread) +@Warmup(iterations = 5) +class FASTBenchmark extends FASTLoader { val dom = BoxDoubleDomain() @@ -40,58 +41,50 @@ class FASTBenchmark extends SimpleBenchmark with FASTLoader { val narrowingBox = { (x: dom.Property, y: dom.Property) => x narrowing y } val CC77 = FiniteFixpointSolver.CC77[Location, dom.Property](Solver.WorkListSolver, wideningBox, narrowingBox) - def timeLTS(reps: Int) { - for (_ <- 1 to reps) { - for (lts <- ltss) { - val params = new Parameters[LTS] { val domain = dom } - val ann = lts.analyze(params) - } - } + @Benchmark + def timeLTS() { + val params = new Parameters[LTS] { val domain = dom } + for (lts <- ltss) lts.analyze(params) } - def timeEQSKleene(reps: Int) { - for (_ <- 1 to reps) { - for (lts <- ltss) { - val eqs = lts.toEQS(dom) - val ann = FiniteFixpointSolver(eqs, CC77.copy(solver = Solver.KleeneSolver)) - } + @Benchmark + def timeEQSKleene() { + for (lts <- ltss) { + val eqs = lts.toEQS(dom) + FiniteFixpointSolver(eqs, CC77.copy(solver = Solver.KleeneSolver)) } + } - def timeEQSRoundRobin(reps: Int) { - for (_ <- 1 to reps) { - for (lts <- ltss) { - val eqs = lts.toEQS(dom) - val ann = FiniteFixpointSolver(eqs, CC77.copy(solver = Solver.RoundRobinSolver)) - } + @Benchmark + def timeEQSRoundRobin() { + for (lts <- ltss) { + val eqs = lts.toEQS(dom) + FiniteFixpointSolver(eqs, CC77.copy(solver = Solver.RoundRobinSolver)) } } - def timeEQSDefault(reps: Int) { - for (_ <- 1 to reps) { - for (lts <- ltss) { - val eqs = lts.toEQS(dom) - val ann = FiniteFixpointSolver(eqs, CC77) - } + @Benchmark + def timeEQSDefault() { + for (lts <- ltss) { + val eqs = lts.toEQS(dom) + FiniteFixpointSolver(eqs, CC77) } } - def timeEQSLocalized(reps: Int) { - for (_ <- 1 to reps) { - for (lts <- ltss) { - val eqs = lts.toEQS(dom) - val ann = FiniteFixpointSolver(eqs, CC77.copy(boxscope = BoxScope.Localized)) - } + @Benchmark + def timeEQSLocalized() { + for (lts <- ltss) { + val eqs = lts.toEQS(dom) + FiniteFixpointSolver(eqs, CC77.copy(boxscope = BoxScope.Localized)) } } - def timeEQSMixedLocalized(reps: Int) { - for (_ <- 1 to reps) { - for (lts <- ltss) { - val eqs = lts.toEQS(dom) - val ann = FiniteFixpointSolver(eqs, CC77.copy(boxscope = BoxScope.Localized, boxstrategy = BoxStrategy.Warrowing)) - } + @Benchmark + def timeEQSMixedLocalized() { + for (lts <- ltss) { + val eqs = lts.toEQS(dom) + FiniteFixpointSolver(eqs, CC77.copy(boxscope = BoxScope.Localized, boxstrategy = BoxStrategy.Warrowing)) } } - } diff --git a/extended/src/test/ppl/it/unich/jandom/JandomBenchmark.scala b/extended/src/test/ppl/it/unich/jandom/JandomBenchmark.scala deleted file mode 100644 index 61efb465..00000000 --- a/extended/src/test/ppl/it/unich/jandom/JandomBenchmark.scala +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Copyright 2013 Gianluca Amato - * - * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains - * JANDOM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * JANDOM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty ofa - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with JANDOM. If not, see . - */ - -package it.unich.jandom - -import com.google.caliper.SimpleBenchmark - -/** - * The benchmark suite for Jandom. This is currently only a dummy test. - * @author Gianluca Amato - * - */ - -class JandomBenchmark extends SimpleBenchmark { - def timeDummy(reps: Int) { - for (i <- 0 until reps) System.nanoTime() - } -} diff --git a/extended/src/test/ppl/it/unich/jandom/domains/numerical/ppl/BoxDoubleBenchmark.scala b/extended/src/test/ppl/it/unich/jandom/domains/numerical/ppl/BoxDoubleBenchmark.scala deleted file mode 100644 index 8dd95937..00000000 --- a/extended/src/test/ppl/it/unich/jandom/domains/numerical/ppl/BoxDoubleBenchmark.scala +++ /dev/null @@ -1,143 +0,0 @@ -/** - * Copyright 2013 Gianluca Amato - * - * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains - * JANDOM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * JANDOM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty ofa - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with JANDOM. If not, see . - */ - -package it.unich.jandom.domains.numerical.ppl - -import com.google.caliper.SimpleBenchmark - -import it.unich.jandom.domains.numerical._ - -import parma_polyhedra_library._ - -/** - * This benchmark compare some operations on the interval domain. This - * shows that PPL is very slow in Jandom, and Reflexive PPL is even - * slower. - * @author Gianluca Amato - * - */ - -class BoxDoubleBenchmark extends SimpleBenchmark { - private val numvars = 100 - private val numpoints = 10 - private val BoxDouble = BoxDoubleDomain() - - PPLInitializer - - def timePPL(reps: Int) { - for (iter <- 1 to reps) { - // create an empty box - val db = new Double_Box(numvars, Degenerate_Element.EMPTY) - - // initialize a list of linear form (one for each variable) - val vars = new Array[Linear_Expression_Variable](numvars) - for (v <- 0 until numvars) vars(v) = new Linear_Expression_Variable(new Variable(v)) - - // initialize the linear form x_1 + ... + x_n - val diagonal = vars.reduceRight[Linear_Expression](_.sum(_)) - val gs = new Generator_System() - for (i <- 1 to numpoints) { - val point = Generator.point(diagonal times (new Coefficient(i)), new Coefficient(1)) - gs.clear - gs.add(point) - val point_box = new Double_Box(gs) - db.upper_bound_assign(point_box) - } - } - } - - def timePPL2(reps: Int) { - for (iter <- 1 to reps) { - val db = new Double_Box(numvars, Degenerate_Element.EMPTY) - val v0 = new Variable(0) - val vlast = new Variable(numvars - 1) - val expr = (new Linear_Expression_Variable(v0)) sum (new Linear_Expression_Variable(vlast)) - val gs = new Generator_System() - val point = Generator.point(expr, new Coefficient(1)) - gs.add(point) - db.upper_bound_assign(new Double_Box(gs)) - val denominator = new Coefficient(1) - for (i <- 1 to numpoints) { - val dbnew = new Double_Box(db) - dbnew.affine_image(v0, expr, denominator) - db.upper_bound_assign(dbnew) - } - } - } - - def timeJandomNoPPLOptimized(reps: Int) { - for (iter <- 1 to reps) { - var db = BoxDouble.bottom(numvars) - for (i <- 1 to numpoints) { - val point = Array.fill(numvars)(i.toDouble) - db = db union BoxDouble(point) - } - println(db) - } - } - - def timeJandomNoPPL(reps: Int) { - for (iter <- 1 to reps) { - var db = BoxDouble.bottom(numvars) - val zero = Array.fill(numvars)(0.0) - val full = BoxDouble.top(numvars) - for (i <- 1 to numpoints) { - val point = (0 until numvars).foldLeft(full) { (box, v) => box.linearAssignment(v, i.toDouble) } - db = db union point - } - } - } - - def timeJandomPPL(reps: Int) { - val PPLBoxDouble = PPLBoxDoubleDomain() - for (iter <- 1 to reps) { - var db = PPLBoxDouble.bottom(numvars) - val full = PPLBoxDouble.top(numvars) - for (i <- 1 to numpoints) { - val point = (0 until numvars).foldLeft(full) { (box, v) => box.linearAssignment(v, i.toDouble) } - db = db union point - } - } - } - - def timeJandomPPLReflexive(reps: Int) { - for (iter <- 1 to reps) { - val domain = PPLDomain[Octagonal_Shape_double]() - var db = domain.bottom(numvars) - val full = domain.top(numvars) - for (i <- 1 to numpoints) { - val point = (0 until numvars).foldLeft(full) { (box, v) => box.linearAssignment(v, i.toDouble) } - db = db union point - } - } - } - - def timeJandomPPLMacro(reps: Int) { - for (iter <- 1 to reps) { - // we explicitly type domain in order to avoid generation of existential types. - val domain: NumericalDomain = PPLDomainMacro[Double_Box] - var db = domain.bottom(numvars) - val zero = Array.fill(numvars)(0.0) - val full = domain.top(numvars) - for (i <- 1 to numpoints) { - val point = (0 until numvars).foldLeft(full) { (box, v) => box.linearAssignment(v, i.toDouble) } - db = db union point - } - } - } -} diff --git a/extended/src/test/scala/it/unich/jandom/benchmarks/FASTLoader.scala b/extended/src/test/scala/it/unich/jandom/benchmarks/FASTLoader.scala index d86b1395..8e4c8075 100644 --- a/extended/src/test/scala/it/unich/jandom/benchmarks/FASTLoader.scala +++ b/extended/src/test/scala/it/unich/jandom/benchmarks/FASTLoader.scala @@ -16,11 +16,12 @@ * along with JANDOM. If not, see . */ + + package it.unich.jandom.benchmarks import java.io.File import java.io.FileReader - import it.unich.jandom.parsers.FastParser /** diff --git a/project/caliper.sbt b/project/caliper.sbt deleted file mode 100644 index 167d9211..00000000 --- a/project/caliper.sbt +++ /dev/null @@ -1,6 +0,0 @@ -resolvers += Resolver.url( - "bintray-sbt-plugin-releases", - url("http://dl.bintray.com/content/sbt/sbt-plugin-releases"))( - Resolver.ivyStylePatterns) - -addSbtPlugin("me.lessis" % "cappi" % "0.1.1") diff --git a/project/jmh.sbt b/project/jmh.sbt new file mode 100644 index 00000000..d52c3354 --- /dev/null +++ b/project/jmh.sbt @@ -0,0 +1 @@ +addSbtPlugin("pl.project13.scala" % "sbt-jmh" % "0.2.18") From 61e5decc686498887153eecf4d9e3fd3f19497d5 Mon Sep 17 00:00:00 2001 From: Gianluca Amato Date: Sat, 10 Dec 2016 11:18:22 +0100 Subject: [PATCH 04/99] Do not use withLogRecompileOnMacro in build.sbt. I actually don't know why it got there in the first place. --- extended/build.sbt | 2 -- 1 file changed, 2 deletions(-) diff --git a/extended/build.sbt b/extended/build.sbt index 029bdad2..09fe1213 100644 --- a/extended/build.sbt +++ b/extended/build.sbt @@ -25,8 +25,6 @@ EclipseKeys.executionEnvironment := Some(EclipseExecutionEnvironment.JavaSE17) EclipseKeys.eclipseOutput := Some("target.eclipse") -incOptions := incOptions.value.withLogRecompileOnMacro(false) - //*** JMH Plugin enablePlugins(JmhPlugin) From b2c8ae3f591067eabe256d199371ef635ea4f78c Mon Sep 17 00:00:00 2001 From: Gianluca Amato Date: Sun, 11 Dec 2016 20:58:42 +0100 Subject: [PATCH 05/99] Use ScalaFix 0.5.2, which fixes the Kleene solver. --- core/build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/build.sbt b/core/build.sbt index f95d9cd9..0c2d3809 100644 --- a/core/build.sbt +++ b/core/build.sbt @@ -7,7 +7,7 @@ libraryDependencies ++= Seq( "org.mockito" % "mockito-core" % "2.2.9" % "test", "org.spire-math" %% "spire" % "0.12.0", "org.scalanlp" %% "breeze" % "0.12", - "it.unich.scalafix" %% "scalafix" % "0.5.1", + "it.unich.scalafix" %% "scalafix" % "0.5.2", // for using native linear algebra libraries // "org.scalanlp" %% "breeze-natives" % "0.12", "org.rogach" %% "scallop" % "2.0.3", From 1c809d5bbf5fe603f67792508bf34afb084e0379 Mon Sep 17 00:00:00 2001 From: Gianluca Amato Date: Sun, 11 Dec 2016 22:28:37 +0100 Subject: [PATCH 06/99] Fix narrowing for the sum domain. --- .../scala/it/unich/jandom/domains/numerical/SumDomain.scala | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/core/src/main/scala/it/unich/jandom/domains/numerical/SumDomain.scala b/core/src/main/scala/it/unich/jandom/domains/numerical/SumDomain.scala index e17df2c8..5459dc6c 100644 --- a/core/src/main/scala/it/unich/jandom/domains/numerical/SumDomain.scala +++ b/core/src/main/scala/it/unich/jandom/domains/numerical/SumDomain.scala @@ -76,7 +76,11 @@ abstract class SumDomain[D1 <: NumericalDomain, D2 <: NumericalDomain] extends N def narrowing(that: Property): Property = { require(dimension == that.dimension) - SumDomain.this(p1 narrowing that.p1, p2 narrowing that.p2) + // we can apply component-wise narrowing only when both components in this w.r.t. those in that + if (that.p1 < p1 && that.p2 < p2) + SumDomain.this(p1 narrowing that.p1, p2 narrowing that.p2) + else + this } def intersection(that: Property): Property = { From 8c9db1bc5fbcdd6bc6b1522fe7b748838e03cf3d Mon Sep 17 00:00:00 2001 From: Gianluca Amato Date: Sun, 11 Dec 2016 22:40:16 +0100 Subject: [PATCH 07/99] Remove useless code. --- .../ppl/it/unich/jandom/domains/numerical/ppl/PPLBoxDouble.scala | 1 - .../it/unich/jandom/domains/numerical/ppl/PPLDomainMacro.scala | 1 - 2 files changed, 2 deletions(-) diff --git a/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLBoxDouble.scala b/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLBoxDouble.scala index 6c4b0dd9..5de00462 100644 --- a/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLBoxDouble.scala +++ b/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLBoxDouble.scala @@ -63,7 +63,6 @@ final class PPLBoxDouble(val pplbox: Double_Box) extends NumericalProperty[PPLBo def union(that: PPLBoxDouble): PPLBoxDouble = { val newpplbox = new Double_Box(pplbox) - val x = new Double_Box(pplbox.space_dimension(), Degenerate_Element.EMPTY) newpplbox.upper_bound_assign(that.pplbox) new PPLBoxDouble(newpplbox) } diff --git a/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLDomainMacro.scala b/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLDomainMacro.scala index 438a2f4c..9f015f1a 100644 --- a/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLDomainMacro.scala +++ b/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLDomainMacro.scala @@ -159,7 +159,6 @@ object PPLDomainMacro { def union(that: ThisProperty): ThisProperty = { val newpplobject = new $PPLTypeTag(pplobject) - val x = new $PPLTypeTag(pplobject.space_dimension(), Degenerate_Element.EMPTY) newpplobject.upper_bound_assign(that.pplobject) new ThisProperty(newpplobject) } From 508be703a7562b6e473545239f6d24b19d9a34f2 Mon Sep 17 00:00:00 2001 From: Gianluca Amato Date: Sun, 11 Dec 2016 23:53:34 +0100 Subject: [PATCH 08/99] Fix the tryCompareTo method. --- .../domains/numerical/ProductDomain.scala | 60 ++++++++++--------- 1 file changed, 32 insertions(+), 28 deletions(-) diff --git a/core/src/main/scala/it/unich/jandom/domains/numerical/ProductDomain.scala b/core/src/main/scala/it/unich/jandom/domains/numerical/ProductDomain.scala index d309a562..58867e7f 100644 --- a/core/src/main/scala/it/unich/jandom/domains/numerical/ProductDomain.scala +++ b/core/src/main/scala/it/unich/jandom/domains/numerical/ProductDomain.scala @@ -36,18 +36,17 @@ import it.unich.scalafix.Box * @author Francesca Scozzari */ class ProductDomain[D1 <: NumericalDomain, D2 <: NumericalDomain](val dom1: D1, val dom2: D2)( - implicit val dom1Todom2: DomainTransformation[D1,D2], val dom2Todom1: DomainTransformation[D2,D1]) extends NumericalDomain { + implicit val dom1Todom2: DomainTransformation[D1, D2], val dom2Todom1: DomainTransformation[D2, D1]) extends NumericalDomain { val widenings = { - for (w1 <- dom1.widenings; w2 <- dom2.widenings) yield - WideningDescription(s"${w1.name} X ${w2.name}",s"Component-wise combination of the two widenings.", - Box { (a: Property, b: Property) => - new Property( w1.box(a.p1, b.p1), w2.box(a.p2, b.p2) ) - }) + for (w1 <- dom1.widenings; w2 <- dom2.widenings) yield WideningDescription(s"${w1.name} X ${w2.name}", s"Component-wise combination of the two widenings.", + Box { (a: Property, b: Property) => + new Property(w1.box(a.p1, b.p1), w2.box(a.p2, b.p2)) + }) } - private val d12 = dom1Todom2(dom1,dom2) - private val d21 = dom2Todom1(dom2,dom1) + private val d12 = dom1Todom2(dom1, dom2) + private val d21 = dom2Todom1(dom2, dom1) def top(n: Int) = new Property(dom1.top(n), dom2.top(n)) @@ -70,8 +69,8 @@ class ProductDomain[D1 <: NumericalDomain, D2 <: NumericalDomain](val dom1: D1, def reduce(x1: dom1.Property, x2: dom2.Property): Property = { if (x1.isEmpty || x2.isEmpty) - new Property(x1.bottom,x2.bottom) - else{ + new Property(x1.bottom, x2.bottom) + else { val y1 = x1.intersection(d21(x2)) val y2 = x2.intersection(d12(x1)) new Property(y1, y2) @@ -123,21 +122,21 @@ class ProductDomain[D1 <: NumericalDomain, D2 <: NumericalDomain](val dom1: D1, } def minimize(lf: LinearForm) = { - val q1=p1.minimize(lf) - val q2=p2.minimize(lf) + val q1 = p1.minimize(lf) + val q2 = p2.minimize(lf) q1 max q2 } def maximize(lf: LinearForm) = { - val q1=p1.maximize(lf) - val q2=p2.maximize(lf) + val q1 = p1.maximize(lf) + val q2 = p2.maximize(lf) q1 min q2 } def frequency(lf: LinearForm) = { - // This could be made more precise when the concrete domain is integer + // This could be made more precise when the concrete domain is integer p1.frequency(lf) match { - case v@ Some(c) => v + case v @ Some(c) => v case None => p2.frequency(lf) } } @@ -179,20 +178,25 @@ class ProductDomain[D1 <: NumericalDomain, D2 <: NumericalDomain](val dom1: D1, p1.mkString(vars) + " / " + p2.mkString(vars) } - def tryCompareTo[B >: Property](other: B)(implicit arg0: (B) => PartiallyOrdered[B]): Option[Int] = { - other match { - case other: Property => { - val c1 = p1.tryCompareTo(other.p1) - val c2 = p2.tryCompareTo(other.p2) - if (c1 == Some(0)) - c2 - else if (c2 == Some(0)) - c1 - else if (c1 == c2) - c1 + def tryCompareTo[B >: Property](that: B)(implicit arg0: (B) => PartiallyOrdered[B]): Option[Int] = { + that match { + case that: Property => + if (this.isBottom && that.isBottom) + Option(0) + else if (this.isBottom) + Option(-1) + else if (that.isBottom) + Option(1) + else if (this.isTop && that.isTop) + Option(0) + else if (this.isTop) + Option(1) + else if (that.isTop) + Option(-1) + else if (p1 == this.p1 && p2 == that.p2) + Option(0) else Option.empty - } case _ => Option.empty } } From ac525f377bbd3f9c19e261761c237aca9810d41a Mon Sep 17 00:00:00 2001 From: Gianluca Amato Date: Mon, 12 Dec 2016 00:11:13 +0100 Subject: [PATCH 09/99] Change contract for the narrowing method. --- .../domains/numerical/ppl/PPLBoxDouble.scala | 3 +- .../numerical/ppl/PPLDomainMacro.scala | 3 +- .../domains/numerical/ppl/PPLProperty.scala | 1 + .../jandom/domains/AbstractProperty.scala | 30 ++++++++++++++----- .../domains/numerical/BoxDoubleDomain.scala | 4 +-- .../domains/numerical/BoxRationalDomain.scala | 6 ++-- .../numerical/ParallelotopeDomain.scala | 8 +++-- .../ParallelotopeRationalDomain.scala | 6 ++-- .../domains/numerical/ProductDomain.scala | 5 ++-- .../domains/objects/AliasingDomain.scala | 4 +-- .../domains/objects/PairSharingDomain.scala | 6 ++-- .../jandom/domains/AbstractDomainSuite.scala | 13 ++++---- 12 files changed, 55 insertions(+), 34 deletions(-) diff --git a/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLBoxDouble.scala b/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLBoxDouble.scala index 5de00462..a29f07fd 100644 --- a/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLBoxDouble.scala +++ b/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLBoxDouble.scala @@ -1,5 +1,5 @@ /** - * Copyright 2013, 2016 Gianluca Amato + * Copyright 2013, 2016 Gianluca Amato * * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains * JANDOM is free software: you can redistribute it and/or modify @@ -57,6 +57,7 @@ final class PPLBoxDouble(val pplbox: Double_Box) extends NumericalProperty[PPLBo def narrowing(that: PPLBoxDouble): PPLBoxDouble = { val newpplbox = new Double_Box(that.pplbox) + newpplbox.intersection_assign(this.pplbox) newpplbox.CC76_narrowing_assign(pplbox) new PPLBoxDouble(newpplbox) } diff --git a/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLDomainMacro.scala b/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLDomainMacro.scala index 9f015f1a..69b3f748 100644 --- a/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLDomainMacro.scala +++ b/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLDomainMacro.scala @@ -121,7 +121,8 @@ object PPLDomainMacro { val narrowing = if (supportsCC76Narrowing) q""" def narrowing(that: ThisProperty): ThisProperty = { - val newpplobject = new $PPLTypeTag(pplobject) + val newpplobject = new $PPLTypeTag(that.pplobject) + newpplobject.intersection_assign(pplobject) newpplobject.CC76_narrowing_assign(pplobject) new ThisProperty(newpplobject) } diff --git a/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLProperty.scala b/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLProperty.scala index 67f92670..52949a6b 100644 --- a/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLProperty.scala +++ b/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLProperty.scala @@ -57,6 +57,7 @@ class PPLProperty[PPLNativeProperty <: AnyRef](val domain: PPLDomain[PPLNativePr def narrowing(that: PPLProperty[PPLNativeProperty]): PPLProperty[PPLNativeProperty] = { if (domain.supportsNarrowing) { val newpplobject = domain.copyConstructor(that.pplobject) + domain.intersection_assign(newpplobject, pplobject) domain.narrowing_assign(newpplobject, pplobject) new PPLProperty(domain, newpplobject) } else diff --git a/core/src/main/scala/it/unich/jandom/domains/AbstractProperty.scala b/core/src/main/scala/it/unich/jandom/domains/AbstractProperty.scala index ac578420..ef63b89c 100644 --- a/core/src/main/scala/it/unich/jandom/domains/AbstractProperty.scala +++ b/core/src/main/scala/it/unich/jandom/domains/AbstractProperty.scala @@ -1,5 +1,5 @@ /** - * Copyright 2013 Gianluca Amato + * Copyright 2013, 2016 Gianluca Amato * * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains * JANDOM is free software: you can redistribute it and/or modify @@ -8,7 +8,7 @@ * (at your option) any later version. * * JANDOM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty ofa + * but WITHOUT ANY WARRANTY; without even the implied warranty of a * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * @@ -55,7 +55,7 @@ trait AbstractProperty[Property <: AbstractProperty[Property]] extends Partially def domain: Domain /** - * Compute an upper bound of two abstract properties. If it is possible and convenient, this should compute + * Computes an upper bound of two abstract properties. If it is possible and convenient, this should compute * the least upper bound, but it is not a requirement. * @param that the abstract object to join with `this`. * @note $NOTEFIBER @@ -64,7 +64,7 @@ trait AbstractProperty[Property <: AbstractProperty[Property]] extends Partially def union(that: Property): Property /** - * Compute an upper approximation of the greatest lower bound of two abstract properties. + * Computes an upper approximation of the greatest lower bound of two abstract properties. * @param that the abstract object to meet with `this`. * @note $NOTEFIBER * @return a lower bound of the two abstract properties. @@ -72,15 +72,29 @@ trait AbstractProperty[Property <: AbstractProperty[Property]] extends Partially def intersection(that: Property): Property /** - * The standard widening for two abstract properties. - * @param that the abstract object to be widened with `this`. `that` is NOT assumed to be bigger than `this`. + * The standard widening for two abstract properties. The object `this` should be widened with `that`. The + * result should be an upper bound of the two properties, and converge of the sequence s(i+1) = s(i) widening v(i) + * should be ensured for any sequence of v(i)'s. + * + * Important: `that` is not required to be bigger than `this`. This generality is needed in order to deal with + * non-monotonic domains or initial assignments which are not pre-fixpoints of the equation system. An alternative + * could be requiring `that` to be always bigger than `this` but unconditionally applying union before widening. However, + * this would preclude the possibily to apply heuristics for widening in non-monotonic domains. + * @param that the abstract object to be widened with `this`. * @return the widening of the two abstract properties. */ def widening(that: Property): Property /** - * The standard narrowing for two abstract properties. - * @param that the abstract object to be narrowed with `this`. `that` IS assumed to be smaller than `this`. + * The standard narrowing for two abstract properties. The object `this` should be widened with `that`. The + * result should be smaller than `this` but bigger than `this intersection that` (or, more generally, a correct + * approximation of the concrete intersection). Moreover, converge of the sequence s(i+1) = s(i) narrowing v(i) + * should be ensured for any sequence of v(i)'s. + * + * Important: `that` is not required to be bigger than `this`. This generality is needed in order to deal with + * non-monotonic domains. When the domain is monotonic, `that` is smaller than `this`, we fall in the standard + * notion of narrowing we found in the literature. + * @param that the abstract object to be narrowed with `this`. * @return the narrowing of the two abstract properties. */ def narrowing(that: Property): Property diff --git a/core/src/main/scala/it/unich/jandom/domains/numerical/BoxDoubleDomain.scala b/core/src/main/scala/it/unich/jandom/domains/numerical/BoxDoubleDomain.scala index 1d3638e0..350aa0b9 100644 --- a/core/src/main/scala/it/unich/jandom/domains/numerical/BoxDoubleDomain.scala +++ b/core/src/main/scala/it/unich/jandom/domains/numerical/BoxDoubleDomain.scala @@ -194,8 +194,8 @@ class BoxDoubleDomain(val overReals: Boolean) extends NumericalDomain { if (that.isEmpty) { that } else { - val newlow = (low, that.low).zipped.map((l1, l2) => if (l1 == Double.NegativeInfinity) l2 else l1 min l2) - val newhigh = (high, that.high).zipped.map((l1, l2) => if (l1 == Double.PositiveInfinity) l2 else l1 max l2) + val newlow = (low, that.low).zipped.map((l1, l2) => if (l1 == Double.NegativeInfinity) l2 else l1) + val newhigh = (high, that.high).zipped.map((l1, l2) => if (l1 == Double.PositiveInfinity) l2 else l1) BoxDoubleDomain.this(newlow, newhigh) } } diff --git a/core/src/main/scala/it/unich/jandom/domains/numerical/BoxRationalDomain.scala b/core/src/main/scala/it/unich/jandom/domains/numerical/BoxRationalDomain.scala index ca212db3..9e001c20 100644 --- a/core/src/main/scala/it/unich/jandom/domains/numerical/BoxRationalDomain.scala +++ b/core/src/main/scala/it/unich/jandom/domains/numerical/BoxRationalDomain.scala @@ -131,8 +131,8 @@ class BoxRationalDomain private extends NumericalDomain { if (that.isEmpty) { that } else { - val newlow = (low, that.low).zipped.map((l1, l2) => if (l1 == RationalExt.NegativeInfinity) l2 else l1 min l2) - val newhigh = (high, that.high).zipped.map((l1, l2) => if (l1 == RationalExt.PositiveInfinity) l2 else l1 max l2) + val newlow = (low, that.low).zipped.map((l1, l2) => if (l1 == RationalExt.NegativeInfinity) l2 else l1) + val newhigh = (high, that.high).zipped.map((l1, l2) => if (l1 == RationalExt.PositiveInfinity) l2 else l1) BoxRationalDomain.this(newlow, newhigh) } } @@ -414,7 +414,7 @@ class BoxRationalDomain private extends NumericalDomain { else new Property(low, high, false) } - + val widenings = Seq(WideningDescription.default[Property]) /** diff --git a/core/src/main/scala/it/unich/jandom/domains/numerical/ParallelotopeDomain.scala b/core/src/main/scala/it/unich/jandom/domains/numerical/ParallelotopeDomain.scala index 424e03bd..2c1f90dd 100644 --- a/core/src/main/scala/it/unich/jandom/domains/numerical/ParallelotopeDomain.scala +++ b/core/src/main/scala/it/unich/jandom/domains/numerical/ParallelotopeDomain.scala @@ -1,5 +1,5 @@ /** - * Copyright 2013, 2016 Gianluca Amato + * Copyright 2013, 2016 Gianluca Amato * * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains * JANDOM is free software: you can redistribute it and/or modify @@ -195,13 +195,15 @@ class ParallelotopeDomain private (favorAxes: Boolean) extends NumericalDomain { require(dimension == that.dimension) if (that.isEmpty) { that + } else if (this.isEmpty) { + this } else { val thatRotated = that.rotate(A) val newlow = low.copy val newhigh = high.copy for (i <- 0 until dimension) { - if (low(i).isInfinity) newlow(i) = thatRotated.low(i) else newlow(i) = newlow(i) min thatRotated.low(i) - if (high(i).isInfinity) newhigh(i) = thatRotated.high(i) else newhigh(i) = newhigh(i) max thatRotated.high(i) + if (low(i).isInfinity) newlow(i) = thatRotated.low(i) + if (high(i).isInfinity) newhigh(i) = thatRotated.high(i) } new Property(false, newlow, A, newhigh) } diff --git a/core/src/main/scala/it/unich/jandom/domains/numerical/ParallelotopeRationalDomain.scala b/core/src/main/scala/it/unich/jandom/domains/numerical/ParallelotopeRationalDomain.scala index 67c10f4b..517292c3 100644 --- a/core/src/main/scala/it/unich/jandom/domains/numerical/ParallelotopeRationalDomain.scala +++ b/core/src/main/scala/it/unich/jandom/domains/numerical/ParallelotopeRationalDomain.scala @@ -237,13 +237,15 @@ class ParallelotopeRationalDomain private (favorAxis: Int) extends NumericalDoma require(dimension == that.dimension) if (that.isEmpty) { that + } else if (this.isEmpty) { + this } else { val thatRotated = that.rotate(A) val newlow = low.copy val newhigh = high.copy for (i <- 0 to dimension - 1) { - if (low(i).isInfinity) newlow(i) = thatRotated.low(i) else newlow(i) = newlow(i) min thatRotated.low(i) - if (high(i).isInfinity) newhigh(i) = thatRotated.high(i) else newhigh(i) = newhigh(i) max thatRotated.high(i) + if (low(i).isInfinity) newlow(i) = thatRotated.low(i) + if (high(i).isInfinity) newhigh(i) = thatRotated.high(i) } new Property(false, newlow, A, newhigh) } diff --git a/core/src/main/scala/it/unich/jandom/domains/numerical/ProductDomain.scala b/core/src/main/scala/it/unich/jandom/domains/numerical/ProductDomain.scala index 58867e7f..da0507df 100644 --- a/core/src/main/scala/it/unich/jandom/domains/numerical/ProductDomain.scala +++ b/core/src/main/scala/it/unich/jandom/domains/numerical/ProductDomain.scala @@ -1,5 +1,5 @@ /** - * Copyright 2013, 2016 Gianluca Amato, Francesca Scozzari + * Copyright 2013, 2016 Jandom Team * * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains * JANDOM is free software: you can redistribute it and/or modify @@ -39,7 +39,8 @@ class ProductDomain[D1 <: NumericalDomain, D2 <: NumericalDomain](val dom1: D1, implicit val dom1Todom2: DomainTransformation[D1, D2], val dom2Todom1: DomainTransformation[D2, D1]) extends NumericalDomain { val widenings = { - for (w1 <- dom1.widenings; w2 <- dom2.widenings) yield WideningDescription(s"${w1.name} X ${w2.name}", s"Component-wise combination of the two widenings.", + for (w1 <- dom1.widenings; w2 <- dom2.widenings) + yield WideningDescription(s"${w1.name} X ${w2.name}", s"Component-wise combination of the two widenings.", Box { (a: Property, b: Property) => new Property(w1.box(a.p1, b.p1), w2.box(a.p2, b.p2)) }) diff --git a/core/src/main/scala/it/unich/jandom/domains/objects/AliasingDomain.scala b/core/src/main/scala/it/unich/jandom/domains/objects/AliasingDomain.scala index 8c5e1d1f..112e4ff4 100644 --- a/core/src/main/scala/it/unich/jandom/domains/objects/AliasingDomain.scala +++ b/core/src/main/scala/it/unich/jandom/domains/objects/AliasingDomain.scala @@ -1,5 +1,5 @@ /** - * Copyright 2014 Gianluca Amato + * Copyright 2014, 2016 Gianluca Amato * * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains * JANDOM is free software: you can redistribute it and/or modify @@ -456,7 +456,7 @@ class AliasingDomain[OM <: ObjectModel](val om: OM) extends ObjectDomain[OM] { def widening(that: Property): Property = this union that - def narrowing(that: Property): Property = that + def narrowing(that: Property): Property = this intersection that def union(other: Property): Property = (this unionWithMorphisms other)._1 diff --git a/core/src/main/scala/it/unich/jandom/domains/objects/PairSharingDomain.scala b/core/src/main/scala/it/unich/jandom/domains/objects/PairSharingDomain.scala index 15d5eabe..c6c02a6e 100644 --- a/core/src/main/scala/it/unich/jandom/domains/objects/PairSharingDomain.scala +++ b/core/src/main/scala/it/unich/jandom/domains/objects/PairSharingDomain.scala @@ -1,5 +1,5 @@ /** - * Copyright 2013 Gianluca Amato + * Copyright 2013, 2016 Gianluca Amato * * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains * JANDOM is free software: you can redistribute it and/or modify @@ -8,7 +8,7 @@ * (at your option) any later version. * * JANDOM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty ofa + * but WITHOUT ANY WARRANTY; without even the implied warranty of a * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * @@ -107,7 +107,7 @@ class PairSharingDomain[OM <: ObjectModel](val om: OM) extends ObjectDomain[OM] def widening(that: Property) = union(that) - def narrowing(that: Property) = that + def narrowing(that: Property) = intersection(that) def addUnknownVariable(t: om.Type) = { new Property(ps, t +: rtypes) diff --git a/core/src/test/scala/it/unich/jandom/domains/AbstractDomainSuite.scala b/core/src/test/scala/it/unich/jandom/domains/AbstractDomainSuite.scala index d18871ef..49098935 100644 --- a/core/src/test/scala/it/unich/jandom/domains/AbstractDomainSuite.scala +++ b/core/src/test/scala/it/unich/jandom/domains/AbstractDomainSuite.scala @@ -1,5 +1,5 @@ /** - * Copyright 2014 Gianluca Amato + * Copyright 2014, 2016 Gianluca Amato * * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains * JANDOM is free software: you can redistribute it and/or modify @@ -26,7 +26,7 @@ import org.scalatest.prop.{TableDrivenPropertyChecks, TableFor1, TableFor2} * @author Gianluca Amato */ trait AbstractDomainSuite extends FunSpec with TableDrivenPropertyChecks { - + /** * The abstract domain to test */ @@ -118,11 +118,10 @@ trait AbstractDomainSuite extends FunSpec with TableDrivenPropertyChecks { describe("The narrowing method") { it("it returns an abstract object which is a possible lower bound of the first parameter") { forAll(someCoupleProperties) { (p1, p2) => - if (p2 <= p1) { - // the check is convoluted since we only have an approximation of the abstract ordering - assert(!((p1 narrowing p2) > p1)) - assert(!((p1 narrowing p2) < p2)) - } + // the check is convoluted since we only have an approximation of the abstract ordering + assert(!((p1 narrowing p2) > p1)) + // the following test depends on the fact that intersection is precise enough + assert(!((p1 narrowing p2) < (p1 intersection p2))) } } } From fa6b0abac4ac8cd620553d99f850bbf329753bcc Mon Sep 17 00:00:00 2001 From: Gianluca Amato Date: Mon, 12 Dec 2016 00:12:29 +0100 Subject: [PATCH 10/99] Improve precision of intersection for the sum domain. --- .../it/unich/jandom/domains/numerical/SumDomain.scala | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/core/src/main/scala/it/unich/jandom/domains/numerical/SumDomain.scala b/core/src/main/scala/it/unich/jandom/domains/numerical/SumDomain.scala index 5459dc6c..412ffc49 100644 --- a/core/src/main/scala/it/unich/jandom/domains/numerical/SumDomain.scala +++ b/core/src/main/scala/it/unich/jandom/domains/numerical/SumDomain.scala @@ -1,5 +1,5 @@ /** - * Copyright 2014, 2016 Gianluca Amato, Francesca Scozzari, Simone Di Nardo Di Maio + * Copyright 2014, 2016 Jandom Team * * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains * JANDOM is free software: you can redistribute it and/or modify @@ -85,14 +85,7 @@ abstract class SumDomain[D1 <: NumericalDomain, D2 <: NumericalDomain] extends N def intersection(that: Property): Property = { require(dimension == that.dimension) - if (isEmpty) - this - else if (that.isEmpty) - that - else if (that.isTop) - this - else - that + if (this < that) this else that } def nonDeterministicAssignment(n: Int): Property = { From 14411ade515d9792bea5e64ff666d87b0ffe51eb Mon Sep 17 00:00:00 2001 From: Gianluca Amato Date: Mon, 12 Dec 2016 00:16:54 +0100 Subject: [PATCH 11/99] Fix LTS analyze method and adapt to the new narrowing. --- .../it/unich/jandom/targets/lts/LTS.scala | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/core/src/main/scala/it/unich/jandom/targets/lts/LTS.scala b/core/src/main/scala/it/unich/jandom/targets/lts/LTS.scala index 2f793167..1c4c7ce7 100644 --- a/core/src/main/scala/it/unich/jandom/targets/lts/LTS.scala +++ b/core/src/main/scala/it/unich/jandom/targets/lts/LTS.scala @@ -194,21 +194,29 @@ case class LTS(val name: String, val locations: IndexedSeq[Location], val transi var next = initial var current = initial + params.log("Beginning ascending chain\n") do { current = next next = for ((loc, w) <- locations zip widenings) yield { val propnew = for (t <- loc.incoming) yield t.analyze(current(t.start.id)) - val unionednew = propnew.fold(empty)(_ union _) - if (w.isEmpty) unionednew else w.get(current(loc.id), unionednew) + val unionednew = propnew.fold(initial(loc.id))(_ union _) + params.log(s"Node: ${loc.name} Oldvalue: ${current(loc.id).mkString(env.variables)} Newinput: ${unionednew.mkString(env.variables)}") + val newvalue = if (w.isEmpty) unionednew else w.get(current(loc.id), unionednew) + params.log(s" Newvalue: ${newvalue.mkString(env.variables)}\n") + newvalue } } while (current != next) + params.log("Beginning descending chain\n") do { current = next next = for ((loc, n) <- locations zip narrowings) yield { val propnew = for (t <- loc.incoming) yield t.analyze(current(t.start.id)) - val unionednew = current(loc.id) intersection (propnew.fold(empty)(_ union _) union initial(loc.id)) - if (n.isEmpty) unionednew else n.get(current(loc.id), unionednew) + val unionednew = propnew.fold(initial(loc.id))(_ union _) + params.log(s"Node: ${loc.name} Oldvalue: ${current(loc.id).mkString(env.variables)} Newinput: ${unionednew.mkString(env.variables)}") + val newvalue = if (n.isEmpty) unionednew else n.get(current(loc.id), unionednew) + params.log(s" Newvalue: ${newvalue.mkString(env.variables)}\n") + newvalue } } while (current != next) locations.foreach { loc => ann(loc) = current(loc.id) } @@ -224,29 +232,28 @@ case class LTS(val name: String, val locations: IndexedSeq[Location], val transi val loc = locations(locid) val w = widenings(locid) val propnew = for (t <- loc.incoming) yield t.analyze(current(t.start.id)) - val unionednew = propnew.fold(empty)(_ union _) + val unionednew = propnew.fold(initial(locid))(_ union _) params.log(s"Node: ${loc.name} Oldvalue: ${current(loc.id).mkString(env.variables)} Newinput: ${unionednew.mkString(env.variables)}") val newvalue = if (w.isEmpty) unionednew else w.get(current(locid), unionednew) params.log(s" Newvalue: ${newvalue.mkString(env.variables)}\n") - if (newvalue > current(locid)) { + if (newvalue != current(locid)) { current(locid) = newvalue for (t <- loc.outgoing) { if (!workList.contains(t.end.id)) workList.enqueue(t.end.id) } } } params.log("Beginning descending chain\n") - workList ++= 0 until numlocs while (!workList.isEmpty) { val locid = workList.dequeue() val loc = locations(locid) val n = narrowings(locid) val propnew = for (t <- loc.incoming) yield t.analyze(current(t.start.id)) - val unionednew = current(locid) intersection (propnew.fold(empty)(_ union _) union initial(locid)) + val unionednew = propnew.fold(initial(locid))(_ union _) params.log(s"Node: ${loc.name} Oldvalue: ${current(loc.id).mkString(env.variables)} Newinput: ${unionednew.mkString(env.variables)}") val newvalue = if (n.isEmpty) unionednew else n.get(current(locid), unionednew) params.log(s" Newvalue: ${newvalue.mkString(env.variables)}\n") - if (newvalue < current(locid)) { + if (newvalue != current(locid)) { current(locid) = newvalue for (t <- loc.outgoing) { if (!workList.contains(t.end.id)) workList.enqueue(t.end.id) } } From a52f95f03a9fb02e0a51eae9e356afcd6a645339 Mon Sep 17 00:00:00 2001 From: Gianluca Amato Date: Mon, 12 Dec 2016 12:18:48 +0100 Subject: [PATCH 12/99] Configure output directories when using IntelliJ Idea. --- core/build.sbt | 8 ++++++++ extended/build.sbt | 7 +++++++ project/sbt-ide.sbt | 3 +++ 3 files changed, 18 insertions(+) create mode 100644 project/sbt-ide.sbt diff --git a/core/build.sbt b/core/build.sbt index 0c2d3809..17e766a5 100644 --- a/core/build.sbt +++ b/core/build.sbt @@ -26,6 +26,12 @@ unmanagedSourceDirectories in Compile ++= (pplJar.value map { _ => (sourceDirect unmanagedSourceDirectories in Test ++= (pplJar.value map { _ => (sourceDirectory in Test).value / "ppl" }).toSeq +//*** IntelliJ Idea + +ideOutputDirectory in Compile := Some(new File("core/target/idea/classes")) + +ideOutputDirectory in Test := Some(new File("core/target/idea/test-classes")) + //*** Eclipse plugin EclipseKeys.createSrc := EclipseCreateSrc.Default + EclipseCreateSrc.Managed @@ -51,3 +57,5 @@ gitHeadCommitSHA := Process("git rev-parse HEAD").lines.head buildInfoKeys := Seq[BuildInfoKey](name, version, scalaVersion, sbtVersion, gitHeadCommitSHA) buildInfoPackage := "it.unich.jandom" + + diff --git a/extended/build.sbt b/extended/build.sbt index 09fe1213..c84ac7e5 100644 --- a/extended/build.sbt +++ b/extended/build.sbt @@ -15,6 +15,12 @@ mergeStrategy in assembly <<= (mergeStrategy in assembly) { (old) => } } +//** IntelliJ Idea + +ideOutputDirectory in Compile := Some(new File("extended/target/idea/classes")) + +ideOutputDirectory in Test := Some(new File("extended/target/idea/test-classes")) + //*** Eclipse plugin EclipseKeys.createSrc := EclipseCreateSrc.ValueSet() @@ -37,3 +43,4 @@ resourceDirectories in Jmh := ((baseDirectory in ThisBuild).value / "core" / "sr ( (managedResourceDirectories in Jmh).value ++ (unmanagedResourceDirectories in Jmh).value ) dependencyClasspath in Jmh := (fullClasspath in Test).value + diff --git a/project/sbt-ide.sbt b/project/sbt-ide.sbt new file mode 100644 index 00000000..b1407857 --- /dev/null +++ b/project/sbt-ide.sbt @@ -0,0 +1,3 @@ +resolvers += Resolver.url("jetbrains-bintray", + url("http://dl.bintray.com/jetbrains/sbt-plugins/"))(Resolver.ivyStylePatterns) +addSbtPlugin("org.jetbrains" % "sbt-ide-settings" % "0.1.2") From ddd156e8b37fd7f9cb44258e5d791c367b3fe504 Mon Sep 17 00:00:00 2001 From: Gianluca Amato Date: Mon, 12 Dec 2016 12:30:57 +0100 Subject: [PATCH 13/99] Re-organize .gitignore files. --- .gitignore | 19 ++++++++++++------- core/.gitignore | 2 -- extended/.gitignore | 2 -- 3 files changed, 12 insertions(+), 11 deletions(-) delete mode 100644 core/.gitignore delete mode 100644 extended/.gitignore diff --git a/.gitignore b/.gitignore index 691ecc38..ef7b210f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,17 @@ *~ + +# sbt-specific target/ -.project -.cache + +# eclipse .classpath -.worksheet -.history -*.sc +.worksheet/ .settings/ -.idea/ -.cache-* +.project +target.eclipse/ +.cache-main +.cache-tests +*.sc +# intellij idea +.idea/ diff --git a/core/.gitignore b/core/.gitignore deleted file mode 100644 index 4c4e7f96..00000000 --- a/core/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/target.eclipse/ -/bin/ diff --git a/extended/.gitignore b/extended/.gitignore deleted file mode 100644 index 4c4e7f96..00000000 --- a/extended/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/target.eclipse/ -/bin/ From dbbc83096f09726b8202741880404225bc88126c Mon Sep 17 00:00:00 2001 From: Gianluca Amato Date: Mon, 12 Dec 2016 00:22:39 +0100 Subject: [PATCH 14/99] Add comparison tool for LTS and EQS. --- .../it/unich/jandom/targets/EQSSolver.scala | 71 +++++++++++ .../it/unich/jandom/targets/Target.scala | 6 + .../it/unich/jandom/targets/lts/LTS.scala | 2 +- .../benchmarks/EQSLegacyFASTComparison.scala | 115 ++++++++++++++++++ 4 files changed, 193 insertions(+), 1 deletion(-) create mode 100644 core/src/main/scala/it/unich/jandom/targets/EQSSolver.scala create mode 100644 extended/src/test/scala/it/unich/jandom/benchmarks/EQSLegacyFASTComparison.scala diff --git a/core/src/main/scala/it/unich/jandom/targets/EQSSolver.scala b/core/src/main/scala/it/unich/jandom/targets/EQSSolver.scala new file mode 100644 index 00000000..fac80114 --- /dev/null +++ b/core/src/main/scala/it/unich/jandom/targets/EQSSolver.scala @@ -0,0 +1,71 @@ +/** + * Copyright 2016 Gianluca Amato + * + * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains + * JANDOM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * JANDOM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of a + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with JANDOM. If not, see . + */ + +package it.unich.jandom.targets + +import it.unich.jandom.targets.parameters.NarrowingSpecs._ +import it.unich.jandom.targets.parameters.WideningNarrowingLocation +import it.unich.jandom.targets.parameters.WideningSpecs._ +import it.unich.scalafix._ +import it.unich.scalafix.FixpointSolver._ +import it.unich.scalafix.FixpointSolverListener.EmptyListener +import it.unich.scalafix.finite.FiniteFixpointSolver +import it.unich.scalafix.finite.FiniteFixpointSolver._ +import it.unich.scalafix.finite.GraphEquationSystem +import it.unich.jandom.targets.parameters.IterationStrategy +import it.unich.jandom.domains.AbstractDomain + +/** + * This is a solver for equations systems which takes a Parameters object in order to drive + * the analysis. + */ + +object EQSSolver { + def apply[Tgt <: Target[Tgt]](tgt: Tgt)(dom: tgt.DomainBase) + (params: Parameters[Tgt], listener: FixpointSolverListener[tgt.ProgramPoint, dom.Property] = FixpointSolverListener.EmptyListener) + : Assignment[tgt.ProgramPoint, dom.Property] = { + implicit val scalafixDomain = dom.ScalaFixDomain + + if (params.wideningLocation != params.narrowingLocation) + throw new IllegalArgumentException("widening and narrowing locations shoule be the same"); + + val widening = DefaultWidening.get(dom) + val narrowing = DefaultNarrowing.get(dom) + + val boxlocation = params.wideningLocation match { + case WideningNarrowingLocation.None => BoxLocation.None + case WideningNarrowingLocation.All => BoxLocation.All + case WideningNarrowingLocation.Loop => BoxLocation.Loop + } + + val solver = params.iterationStrategy match { + case IterationStrategy.Kleene => Solver.KleeneSolver + case IterationStrategy.Worklist => Solver.WorkListSolver + } + + val eqs = tgt.toEQS(dom) + val eqsParams = FiniteFixpointSolver.CC77[tgt.ProgramPoint, dom.Property](solver, widening, narrowing).copy( + boxlocation = boxlocation, listener = listener + ) + + eqs match { + case eqs: GraphEquationSystem[tgt.ProgramPoint, dom.Property, _] => FiniteFixpointSolver(eqs, eqsParams) + case _ => ??? + } + } +} diff --git a/core/src/main/scala/it/unich/jandom/targets/Target.scala b/core/src/main/scala/it/unich/jandom/targets/Target.scala index 9e6d7401..6d5e25c5 100644 --- a/core/src/main/scala/it/unich/jandom/targets/Target.scala +++ b/core/src/main/scala/it/unich/jandom/targets/Target.scala @@ -21,6 +21,7 @@ package it.unich.jandom.targets import scala.collection.mutable.HashMap import it.unich.jandom.domains.AbstractDomain +import it.unich.scalafix.EquationSystem /** * The abstract class for targets, which are the static analyzers for the @@ -63,4 +64,9 @@ abstract class Target[Tgt <: Target[Tgt]] { * @return an annotation for the program */ def analyze(params: Parameters): Annotation[ProgramPoint,params.Property] + + /** + * Return an Equation System corresponding to the target + */ + def toEQS(dom: DomainBase): EquationSystem[ProgramPoint, dom.Property] = ??? } diff --git a/core/src/main/scala/it/unich/jandom/targets/lts/LTS.scala b/core/src/main/scala/it/unich/jandom/targets/lts/LTS.scala index 1c4c7ce7..3fa347f6 100644 --- a/core/src/main/scala/it/unich/jandom/targets/lts/LTS.scala +++ b/core/src/main/scala/it/unich/jandom/targets/lts/LTS.scala @@ -116,7 +116,7 @@ case class LTS(val name: String, val locations: IndexedSeq[Location], val transi /** * Converts an LTS into an equation system, given a numerical domain. */ - def toEQS(dom: NumericalDomain): GraphEquationSystem[Location, dom.Property, Either[Transition, Location]] = { + override def toEQS(dom: NumericalDomain): GraphEquationSystem[Location, dom.Property, Either[Transition, Location]] = { type Edge = Either[Transition, Location] implicit val scalafixDomain = dom.ScalaFixDomain diff --git a/extended/src/test/scala/it/unich/jandom/benchmarks/EQSLegacyFASTComparison.scala b/extended/src/test/scala/it/unich/jandom/benchmarks/EQSLegacyFASTComparison.scala new file mode 100644 index 00000000..1ee13202 --- /dev/null +++ b/extended/src/test/scala/it/unich/jandom/benchmarks/EQSLegacyFASTComparison.scala @@ -0,0 +1,115 @@ +/** + * Copyright 2016 Gianluca Amato + * + * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains + * JANDOM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * JANDOM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of a + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with JANDOM. If not, see . + */ + +package it.unich.jandom.benchmarks + +import it.unich.jandom.domains.numerical.BoxDoubleDomain +import it.unich.jandom.targets.EQSSolver +import it.unich.jandom.targets.Parameters +import it.unich.jandom.targets.lts._ +import it.unich.jandom.targets.parameters._ +import it.unich.scalafix.Assignment +import it.unich.jandom.domains.numerical.ParallelotopeDomain +import parma_polyhedra_library.C_Polyhedron +import it.unich.jandom.domains.numerical.ppl.PPLDomainMacro +import java.io.Writer +import java.io.PrintWriter +import java.io.OutputStreamWriter +import it.unich.jandom.domains.numerical.ParallelotopeRationalDomain +import it.unich.scalafix.FixpointSolverListener + +/** + * This program compares standard (legacy) analyzer with the new one based on Scalafix for + * the LTS target. The aim is to compare both precision of results and speed. This should be used to + * guide the progressive removal of legacy analyzers. + */ + +object EQSLegacyFASTComparison extends App with FASTLoader { + + val dom = ParallelotopeDomain() + + def compareResults(locations: Seq[Location], ann1: Assignment[Location, dom.Property], ann2: Assignment[Location, dom.Property]) = { + var lt, eq, gt, un = 0 + for (l <- locations) { + val result = ann1(l) tryCompareTo ann2(l) + result match { + case None => + un += 1 + //println(s"location ${l}: ${ann1(l)} vs ${ann2(l)}") + case Some(0) => eq += 1 + case Some(x) if x < 0 => + lt += 1 + //println(s"location ${l}: ${ann1(l)} vs ${ann2(l)}") + case Some(x) if x > 0 => + gt += 1 + //println(s"location ${l}: ${ann1(l)} vs ${ann2(l)}") + } + } + (eq, lt, gt, un) + } + + val paramsList = Seq( + ("standard", new Parameters[LTS] { + val domain: dom.type = dom + }), + ("kleene standard", new Parameters[LTS] { + val domain: dom.type = dom + iterationStrategy = IterationStrategy.Kleene + }), + ("all widening", new Parameters[LTS] { + val domain: dom.type = dom + wideningLocation = WideningNarrowingLocation.All + narrowingLocation = WideningNarrowingLocation.All + }), + ("kleene all widening", new Parameters[LTS] { + val domain: dom.type = dom + wideningLocation = WideningNarrowingLocation.All + narrowingLocation = WideningNarrowingLocation.All + iterationStrategy = IterationStrategy.Kleene + }) + ) + + for ((name, params) <- paramsList) { + var timeEQS = 0.0 + var timeLTS = 0.0 + var timeTemp = 0.0 + var globaleq, globallt, globalgt, globalun = 0 + for (lts <- ltss; eqs = lts.toEQS(dom)) { + timeTemp = java.lang.System.currentTimeMillis() + val res1 = EQSSolver(lts)(dom)(params, FixpointSolverListener.EmptyListener) + timeEQS += (java.lang.System.currentTimeMillis() - timeTemp) + timeTemp = java.lang.System.currentTimeMillis() + val res2 = lts.analyze(params) + timeLTS += (java.lang.System.currentTimeMillis() - timeTemp) + val comparison = compareResults(lts.locations, res1, res2) + globaleq += comparison._1 + globallt += comparison._2 + globalgt += comparison._3 + globalun += comparison._4 + if (comparison._2 != 0 || comparison._3 != 0 || comparison._4 != 0) + println (s"Found differences in ${lts.name}") + } + println(s"\n-------------------") + println(s"${name} EQS vs Legacy") + println(s"Time ${timeEQS}ms vs ${timeLTS}ms") + println("Equal : " + globaleq) + println("First Better: " + globallt) + println("Second Better: " + globalgt) + println("Uncomparable: " + globalun) + } +} From 4ef2d15296065f0868711b7bc9e2696d387b6ff0 Mon Sep 17 00:00:00 2001 From: Gianluca Amato Date: Wed, 19 Apr 2017 15:42:29 +0200 Subject: [PATCH 15/99] Replace custom Soot URL with the new 3.0.0-SNAPSHOT --- build.sbt | 4 +++- core/build.sbt | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/build.sbt b/build.sbt index 8fb7ea0e..95f718a3 100644 --- a/build.sbt +++ b/build.sbt @@ -28,7 +28,9 @@ fork in ThisBuild := true resolvers in ThisBuild ++= Seq( Resolver.sonatypeRepo("releases"), - Resolver.sonatypeRepo("snapshots") + Resolver.sonatypeRepo("snapshots"), + "Soot snapshot" at "http://soot-build.cs.uni-paderborn.de/nexus/repository/soot-snapshot/", + "Soot release" at "http://soot-build.cs.uni-paderborn.de/nexus/repository/soot-release/" ) //*** Detect PPL diff --git a/core/build.sbt b/core/build.sbt index 17e766a5..c65bfda0 100644 --- a/core/build.sbt +++ b/core/build.sbt @@ -15,7 +15,7 @@ libraryDependencies ++= Seq( "org.scala-lang.modules" %% "scala-parser-combinators" % "1.0.4", "org.scala-lang" % "scala-reflect" % scalaVersion.value, // ASM is included in the Soot Jar - "soot" % "soot" % "2.5.0+git2" from "https://ssebuild.cased.de/nightly/soot/lib/soot-trunk.jar" + "ca.mcgill.sable" % "soot" %"3.0.0-SNAPSHOT" ) //*** Additional source directories for PPL From ecfa34c7df83e72e903d2d4cf2b1beeb22256054 Mon Sep 17 00:00:00 2001 From: Gianluca Amato Date: Wed, 19 Apr 2017 19:51:40 +0200 Subject: [PATCH 16/99] Configure SBT not to update snapshots if one already cached. --- core/build.sbt | 2 ++ extended/build.sbt | 2 ++ 2 files changed, 4 insertions(+) diff --git a/core/build.sbt b/core/build.sbt index c65bfda0..283b0902 100644 --- a/core/build.sbt +++ b/core/build.sbt @@ -18,6 +18,8 @@ libraryDependencies ++= Seq( "ca.mcgill.sable" % "soot" %"3.0.0-SNAPSHOT" ) +updateOptions := updateOptions.value.withLatestSnapshots(false) + //*** Additional source directories for PPL unmanagedJars in Compile ++= (pplJar.value map file).toSeq diff --git a/extended/build.sbt b/extended/build.sbt index c84ac7e5..2487670a 100644 --- a/extended/build.sbt +++ b/extended/build.sbt @@ -1,3 +1,5 @@ +updateOptions := updateOptions.value.withLatestSnapshots(false) + //*** Additional source directories for PPL unmanagedSourceDirectories in Compile ++= (pplJar.value map { _ => (sourceDirectory in Compile).value / "ppl" }).toSeq From 1773c6b9c3828916d63b375cfa869f59e0dfebad Mon Sep 17 00:00:00 2001 From: Gianluca Amato Date: Wed, 19 Apr 2017 22:46:31 +0200 Subject: [PATCH 17/99] Small potential performance improvement for ParallelotopeRationalDomain. --- .../jandom/domains/numerical/ParallelotopeRationalDomain.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/scala/it/unich/jandom/domains/numerical/ParallelotopeRationalDomain.scala b/core/src/main/scala/it/unich/jandom/domains/numerical/ParallelotopeRationalDomain.scala index 517292c3..5702635b 100644 --- a/core/src/main/scala/it/unich/jandom/domains/numerical/ParallelotopeRationalDomain.scala +++ b/core/src/main/scala/it/unich/jandom/domains/numerical/ParallelotopeRationalDomain.scala @@ -501,7 +501,7 @@ class ParallelotopeRationalDomain private (favorAxis: Int) extends NumericalDoma val Aprime = newP.A.copy val j = ((0 until Aprime.rows) find { !Aprime(_, n).isZero }).get for (s <- 0 until dimension if !Aprime(s, n).isZero && s != j) - Aprime(s, ::) :-= Aprime(j, ::) * Aprime(s, n) / Aprime(j, n) + Aprime(s, ::) :-= Aprime(j, ::) * (Aprime(s, n) / Aprime(j, n)) val ei = DenseVector.zeros[Rational](dimension) ei(n) = Rational.one Aprime(j, ::) := (ei - coeff).t From 39cf3c356c3360cfa2079fb98b2df3aa7132a7a5 Mon Sep 17 00:00:00 2001 From: Gianluca Amato Date: Wed, 19 Apr 2017 22:48:04 +0200 Subject: [PATCH 18/99] Add a new implementation of parallelotopes which do not use the Breeze library (ParallelotopeRationalDomainFast). --- .../ParallelotopeRationalDomainFast.scala | 894 ++++++++++++++++++ .../unich/jandom/utils/numberext/Bounds.scala | 86 ++ .../jandom/utils/numberext/DenseMatrix.scala | 418 ++++++++ .../jandom/utils/numberext/DenseVector.scala | 281 ++++++ ...ParallelotopeRationalDomainFastSuite.scala | 255 +++++ 5 files changed, 1934 insertions(+) create mode 100644 core/src/main/scala/it/unich/jandom/domains/numerical/ParallelotopeRationalDomainFast.scala create mode 100644 core/src/main/scala/it/unich/jandom/utils/numberext/Bounds.scala create mode 100644 core/src/main/scala/it/unich/jandom/utils/numberext/DenseMatrix.scala create mode 100644 core/src/main/scala/it/unich/jandom/utils/numberext/DenseVector.scala create mode 100644 core/src/test/scala/it/unich/jandom/domains/numerical/ParallelotopeRationalDomainFastSuite.scala diff --git a/core/src/main/scala/it/unich/jandom/domains/numerical/ParallelotopeRationalDomainFast.scala b/core/src/main/scala/it/unich/jandom/domains/numerical/ParallelotopeRationalDomainFast.scala new file mode 100644 index 00000000..67e9e8be --- /dev/null +++ b/core/src/main/scala/it/unich/jandom/domains/numerical/ParallelotopeRationalDomainFast.scala @@ -0,0 +1,894 @@ +/** + * Copyright 2013, 2017 Jandom Team + * + * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains + * JANDOM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * JANDOM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of a + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with JANDOM. If not, see . + */ + +package it.unich.jandom.domains.numerical + +import it.unich.jandom.domains.{CachedTopBottom, WideningDescription} +import it.unich.jandom.utils.numberext.{Bounds, DenseMatrix, DenseVector, RationalExt} +import spire.math.Rational + +import scala.collection.mutable.ListBuffer +import scala.util.Try + +/** + * This is the abstract domain of parallelotopes as appears in the NSAD 2012 paper. It is written + * using the Breeze Math library and uses rational numbers. + * + * @param favorAxis determines whether the heuristics built into the domain should try to keep constraints + * corresponding to Cartesian axis. If `favorAxis` is `1`, axis are favorite. The opposite happens when favorAxis + * is `-1`. If `favorAxis` is `0`, axis are considered like all the other constraints + * + * @author Gianluca Amato + * @author Francesca Scozzari + * @author Marco Rubino + */ +class ParallelotopeRationalDomainFast private (favorAxis: Int) extends NumericalDomain { + + val widenings = Seq(WideningDescription.default[Property]) + + /** + * Build a non-empty parallelotope. If the parallelotope is not empty, the result is undetermined. + * @param A is the constraint matrix. It should be invertible. + * @param low lower bounds. + * @param high higher bounds. + * @note `low` and `high` should have the same length. The matrix `A` should be invertiible + * of the same size of the two vectors. + * @throws IllegalArgumentException if `low` and `high` are not of the same length, if `A` is not + * square or if `A` has not the same size of `low`. + */ + def apply(low: Bounds, A: DenseMatrix, high: Bounds): Property = { + val isEmpty = (0 until low.length) exists { i => low(i) > high(i) } + val isEmpty2 = (0 until low.length) exists { i => low(i).isInfinity && low(i) == high(i) } + new Property(isEmpty || isEmpty2, low, A, high) + } + + /** + * @inheritdoc + * @note @inheritdoc + * @throws $ILLEGAL + */ + def top(n: Int): Property = { + /* The full parallelotope of dimension 0 is not empty! */ + val low = Bounds.fill(n)(RationalExt.NegativeInfinity) + val high = Bounds.fill(n)(RationalExt.PositiveInfinity) + val A = DenseMatrix.eye(n) + new Property(false, low, A, high) + } + + /** + * Returns an full parallelotope whose shape is given by the matrix A. + * @param A the shape matrix + */ + def top(A: DenseMatrix): Property = { + val n = A.rows + val low = Bounds.fill(n)(RationalExt.NegativeInfinity) + val high = Bounds.fill(n)(RationalExt.PositiveInfinity) + new Property(false, low, A, high) + } + + /** + * @inheritdoc + * @note @inheritdoc + * @throws $ILLEGAL + */ + def bottom(n: Int): Property = { + val low = Bounds.fill(n)(RationalExt.one) + val high = Bounds.fill(n)(RationalExt.zero) + val A = DenseMatrix.eye(n) + new Property(true, low, A, high) + } + + /** + * Returns an empty parallelotope whose shape is given by the matrix A. + * @param A the shape matrix + */ + def bottom(A: DenseMatrix): Property = { + val n = A.rows + val low = Bounds.fill(n)(RationalExt.one) + val high = Bounds.fill(n)(RationalExt.zero) + new Property(true, low, A, high) + } + + /** + * Given the box specified by `low` and `high` and the linear form `lf`, determines the pair + * of the least and greatest value of the linear form in the box. + * @param lf a linear form. + * @param low lower bound of the box. + * @param high higher bound of the box. + * @note `low`, `high` and `lf` should be of the same length. + * @return the least and greatest value of `lf` in the box determine by `low` and `high`. + */ + private def extremalsInBox(lf: DenseVector, low: Bounds, high: Bounds): (RationalExt, RationalExt) = { + var minc = RationalExt.zero + var maxc = RationalExt.zero + for (i <- 0 until lf.length) + if (lf(i) > Rational.zero) { + minc += low(i) * lf(i) + maxc += high(i) * lf(i) + } else if (lf(i) < Rational.zero) { + minc += high(i) * lf(i) + maxc += low(i) * lf(i) + } + (minc, maxc) + } + + /** + * Given a sequence of vectors of the same length `n`, returns a sequence of `n` indexes + * of vectors which are linearly independent. It is based on Gaussian elimination. + * @param m a sequence of vectors, all of the same length. + * @return a sequence of positions in m. + */ + private def pivoting(m: IndexedSeq[DenseVector]): List[Int] = { + val dimension = m(0).length + val indexes = ListBuffer[Int]() + val pivots = ListBuffer[(DenseVector, Int)]() + var i = 0 + while (indexes.length < dimension) { + val row = m(i).copy + for (p <- pivots) row -= p._1 * row(p._2) + val col = (0 until row.length) find (!row(_).isZero) + col match { + case Some(col) => + row /= row(col) + pivots.append(Tuple2(row, col)) + indexes.append(i) + case None => + } + i += 1 + } + indexes.toList + } + + /** + * This is an element of the parallelotope domain. + * + * @constructor Builds a parallelotope + * @param isEmpty is true if the parallelotope is empty. In this case, the other parameters are not relevant. + * @param A is the constraint matrix. It should be invertible. + * @param low lower bounds. + * @param high higher bounds. + * @note `low` and `high` should have the same length. The matrix `A` should be invertible + * of the same size of the two vectors. + * @throws IllegalArgumentException if `low` and `high` are not of the same length, if `A` is not + * square or if `A` has not the same size of `low`. + */ + final class Property( + val isEmpty: Boolean, + val low: Bounds, + val A: DenseMatrix, + val high: Bounds) + extends NumericalProperty[Property] { + + require(low.length == A.rows) + require(low.length == A.cols) + require(Try(A \ DenseMatrix.eye(dimension)).isSuccess, s"The shape matrix ${A} is not invertible") + require(normalized) + + type Domain = ParallelotopeRationalDomainFast + + def domain = ParallelotopeRationalDomainFast.this + + private def normalized: Boolean = { + (isEmpty || (low.length == high.length && ( + (0 until low.length - 1) forall { i => + !low(i).isPosInfinity && + !high(i).isNegInfinity && + (low(i) <= high(i)) + }))) + } + + /** + * @inheritdoc + * @note @inheritdoc + * @throws $ILLEGAL + */ + def widening(that: Property): Property = { + require(dimension == that.dimension) + if (isEmpty) + that + else { + val thatRotated = that.rotate(A) + val thisRotated = this.rotate(that.A) + if (thisRotated < that) { + val newlow = thisRotated.low.copy + val newhigh = thisRotated.high.copy + for (i <- 0 to dimension - 1) { + if (thisRotated.low(i) > that.low(i)) newlow(i) = RationalExt.NegativeInfinity + if (thisRotated.high(i) < that.high(i)) newhigh(i) = RationalExt.PositiveInfinity + } + new Property(false, newlow, that.A, newhigh) + } else { + val newlow = low.copy + val newhigh = high.copy + for (i <- 0 to dimension - 1) { + if (thatRotated.low(i) < low(i)) newlow(i) = RationalExt.NegativeInfinity + if (thatRotated.high(i) > high(i)) newhigh(i) = RationalExt.PositiveInfinity + + } + new Property(false, newlow, A, newhigh) + } + } + } + + /** + * @inheritdoc + * @note @inheritdoc + * @throws $ILLEGAL + */ + def narrowing(that: Property): Property = { + require(dimension == that.dimension) + if (that.isEmpty) { + that + } else if (this.isEmpty) { + this + } else { + val thatRotated = that.rotate(A) + val newlow = low.copy + val newhigh = high.copy + for (i <- 0 to dimension - 1) { + if (low(i).isInfinity) newlow(i) = thatRotated.low(i) + if (high(i).isInfinity) newhigh(i) = thatRotated.high(i) + } + new Property(false, newlow, A, newhigh) + } + } + + /** + * @inheritdoc + * It is equivalent to `intersectionWeak`. + * @note @inheritdoc + * @throws $ILLEGAL + */ + def intersection(that: Property): Property = { + if (that.isEmpty) + that + else if (this.isTop) + that + else + intersectionWeak(that) + } + + /** + * @inheritdoc + * The union of two parallelotopes is not a parallelotope. Moreover, there is no least + * parallelotopes containing the union of two parallelotopes. Hence, this methods uses + * heuristics to find a good result. + * @note @inheritdoc + * @throws $ILLEGAL + */ + def union(that: Property): Property = { + + /* + * A PrioritizedConstraint is a tuple `(a, m, M, p)` where `a` is a vector, `m` and `M` are + * rational and `p` is an integer, whose intended meaning is the constraint `m <= ax <= M` + * with a given priority `p`. + */ + type PrioritizedConstraint = (DenseVector, RationalExt, RationalExt, Int) + + /* + * Given a linear form `v`, compute a prioritized constraint `(v,m,M,p)`. The parameter `ownedBy` + * tells whether the line form under consideration is one of the "native" forms of this (1) or + * that (2). This is used to refine priorities. + */ + def priority(v: DenseVector, ownedBy: Int = 0): PrioritizedConstraint = { + val y1 = A.t \ v + val (l1, u1) = domain.extremalsInBox(y1, low, high) + val y2 = that.A.t \ v + val (l2, u2) = domain.extremalsInBox(y2, that.low, that.high) + + val p = + if (favorAxis == 1 && v.countNonZero == 1) // favorAxes + 0 + else if (favorAxis == -1 && v.countNonZero == 1) // not favorAxes + 101 + else if (l1 == l2 && l2 == u1 && u1 == u2) /// if nothing choose axes + 1 + else if (!l1.isInfinity && !l2.isInfinity && !u1.isInfinity && !u2.isInfinity) { + if (l1 == l2 && u1 == u2) + 10 + else if (l1 >= l2 && u1 <= u2) + if (ownedBy == 2) 20 else 30 + else if (l2 >= l1 && u2 <= u1) + if (ownedBy == 1) 20 else 30 + else if (l2 <= u1 && l2 >= l1 && u2 >= u1) + 30 + else if (l2 <= l1 && u2 >= l1 && u2 <= u1) + 30 + else 40 + } else if (l1 == l2 && !l1.isInfinity && !l2.isInfinity) + 50 + else if (u1 == u2 && !u1.isInfinity && !u2.isInfinity) + 50 + else if (!l1.isInfinity && !l2.isInfinity) + 60 + else if (!u1.isInfinity && !u2.isInfinity) + 60 + else + 100 + + (v, l1 min l2, u1 max u2, p) + } + + /* + * Determines whether `v1` and `v2` are linearly dependent. + * @return `None` if `v1` and `v2` are not linearly dependent, otherwise it is + * `Some(k)` such that `v1 = k * v2`. + */ + def linearDep(v1: DenseVector, v2: DenseVector): Option[Rational] = { + var i: Int = 0 + while (i < dimension && (v1(i).isZero || v2(i).isZero)) i += 1 + if (i == dimension) + Option(Rational.one) + else if (v1 / v1(i) == v2 / v2(i)) + Option(v1(i) / v2(i)) + else + Option.empty + } + + /* + * The inversion join procedure. + * @param vi first vector + * @param vj second vector + * @param min1i least value of v1 in this + * @param min2i least value of v1 in that + * @param min1j least value of v2 in that + * @param min2j least value of v2 in that + * @return None if `v1` and `v2` do not form an inversion, otherwise it is `Some(v)` where `v` is the + * new linear form computed by the inversion procedure. + */ + def newConstraint(vi: DenseVector, vj: DenseVector, min1i: RationalExt, min2i: RationalExt, min1j: RationalExt, min2j: RationalExt): Option[DenseVector] = { + if (min1i.isInfinity || min2i.isInfinity || min1j.isInfinity || min2j.isInfinity) + Option.empty + else if (linearDep(vi, vj).isEmpty) + Option.empty + else { + val (deltai, deltaj) = if (min2j.value - min1j.value >= Rational.zero) + (min1i.value - min2i.value, min2j.value - min1j.value) + else + (min2i.value - min1i.value, min1j.value - min2j.value) + if (deltai * deltaj > Rational.zero) + Option(-vi * deltaj - vj * deltai) + else + Option.empty + } + } + + require(dimension == that.dimension) + + // special cases + if (isEmpty) + that + else if (that.isEmpty) + this + else if (dimension == 0) + this + else { + val thisRotated = this.rotate(that.A) + val thatRotated = that.rotate(this.A) + val Q = scala.collection.mutable.ArrayBuffer[PrioritizedConstraint]() + + val bulk = this.A vertcat that.A + val min1 = this.low vertcat thisRotated.low + val min2 = thatRotated.low vertcat that.low + val max1 = this.high vertcat thisRotated.high + val max2 = thatRotated.high vertcat that.high + for (i <- 0 until dimension) Q += priority(this.A.row(i), 1) + for (i <- 0 until dimension) Q += priority(that.A.row(i), 2) + for (i <- 0 until dimension; j <- i + 1 until dimension) { + val v1 = bulk.row(i) + val v2 = bulk.row(j) + + val nc1 = newConstraint(v1, v2, min1(i), min2(i), min1(j), min2(j)) + if (nc1.isDefined) Q += priority(nc1.get) + val nc2 = newConstraint(v1, -v2, min1(i), min2(i), -max1(j), -max2(j)) + if (nc2.isDefined) Q += priority(nc2.get) + val nc3 = newConstraint(-v1, -v2, -max1(i), -max2(i), -max1(j), -max2(j)) + if (nc3.isDefined) Q += priority(nc3.get) + val nc4 = newConstraint(-v1, v2, -max1(i), -max2(i), min1(j), min2(j)) + if (nc4.isDefined) Q += priority(nc4.get) + } + + val Qsorted = Q.sortBy(_._4) + val pvt = domain.pivoting(Qsorted map (_._1)) + val newA = DenseMatrix(pvt map (Qsorted(_)._1): _*) + val newlow = Bounds(pvt map (Qsorted(_)._2): _*) + val newhigh = Bounds(pvt map (Qsorted(_)._3): _*) + + new Property(false, newlow, newA, newhigh) + } + } + + /** + * This is a variant of `union` using weak join. The shape of the resulting + * parallelotope is the same shap of `this`. + * @param that the abstract object to be joined with `this`. + * @note $NOTEDIMENSION + * @return the weak union of the two abstract objects. + */ + def unionWeak(that: Property): Property = { + require(dimension == that.dimension) + if (isEmpty) + that.rotate(A) + else if (that.isEmpty) + this + else { + val result = that.rotate(A) + for (i <- 0 until dimension) { + result.low(i) = result.low(i) min low(i) + result.high(i) = result.high(i) max high(i) + } + new Property(false, result.low, result.A, result.high) //this is to normalize + } + } + + /** + * This is the weak intersection of two abstract objects. The shape of the resulting + * parallelotope is the same shape of `this`. + * @param that the abstract object to be intersected with `this`. + * @note $NOTEDIMENSION + * @return the intersection of the two abstract objects. + */ + def intersectionWeak(that: Property): Property = { + require(dimension == that.dimension) + if (isEmpty) + this + else if (that.isEmpty) + ParallelotopeRationalDomainFast.this.bottom(A) + else { + val result = that.rotate(A) + for (i <- 0 until dimension) { + result.low(i) = result.low(i) max low(i) + result.high(i) = result.high(i) min high(i) + } + if ((0 until result.low.length) exists { i => (result.low(i) > result.high(i)) }) + bottom + else + new Property(false, result.low, result.A, result.high) //this is to normalize + } + } + + /** + * @inheritdoc + * @note @inheritdoc + * @todo @inheritdoc + * @throws $ILLEGAL + */ + def linearAssignment(n: Int, lf: LinearForm): Property = { + require(n <= dimension && lf.dimension <= dimension) + val tcoeff = lf.homcoeffs + val known = lf.known + if (isEmpty) + this + else { + val coeff = DenseVector(tcoeff.padTo(dimension, Rational.zero): _*) + if (! coeff(n).isZero) { + // invertible assignment + val increment = A.col(n) * known / coeff(n) + val newlow = low.copy + val newhigh = high.copy + // cannot use Breeze here since they are RationalExt + for (i <- 0 until dimension) { + newlow(i) += increment(i) + newhigh(i) += increment(i) + } + val ei = DenseVector.zeros(dimension) + ei(n) = Rational.one + val newA = A - (A.col(n) * (coeff - ei).t) / coeff(n) + + new Property(false, newlow, newA, newhigh) + } else { + // non-invertible assignment + val newP = nonDeterministicAssignment(n) + val Aprime = newP.A.copy + val j = ((0 until Aprime.rows) find { !Aprime(_, n).isZero }).get + for (s <- 0 until dimension if !Aprime(s, n).isZero && s != j) + Aprime.rowUpdate(s, Aprime.row(s) - Aprime.row(j) * (Aprime(s, n) / Aprime(j, n))) + val ei = DenseVector.zeros(dimension) + ei(n) = Rational.one + Aprime.rowUpdate(j, ei - coeff) + val newlow = newP.low.copy + val newhigh = newP.high.copy + newlow(j) = known + newhigh(j) = known + + new Property(false, newlow, Aprime, newhigh) + } + } + } + + /** + * Computes the dot product of `x` and `y` with the proviso that if `x` is zero, then `x*y` + * is zero even when `y` is an infinite value (which is not the standard behaviour). + */ + private def dotprod(x: DenseVector, y: Bounds, remove: Int = -1): RationalExt = { + var sum = RationalExt.zero + for (i <- 0 until x.length if i != remove if x(i) != Rational.zero) sum = sum + y(i) * x(i) + sum + } + + /** + * @inheritdoc + * @note @inheritdoc + * @todo @inheritdoc + * @throws ILLEGAL + */ + def linearInequality(lf: LinearForm): Property = { + require(lf.dimension <= dimension) + if (isEmpty) + this + else if (dimension == 0) + if (lf.known > Rational.zero) + bottom + else + this + else { + val known = lf.known + val coeffs = DenseVector(lf.homcoeffs.padTo(dimension, Rational.zero): _*) + val coeffsTransformed = A.t \ coeffs + + val removeCandidates = (0 until dimension) find { i => !coeffsTransformed(i).isZero && low(i).isInfinity && high(i).isInfinity } + removeCandidates match { + case None => { + val newlow = low.copy + val newhigh = high.copy + val (minc, maxc) = domain.extremalsInBox(coeffsTransformed, newlow, newhigh) + if (minc > -known) + bottom + else { + val lfArgmin = coeffsTransformed mapPairs { case (i, c) => if (c > Rational.zero) low(i) else high(i) } + + val infinities = (0 until dimension) filter { i => lfArgmin(i).isInfinity && coeffsTransformed(i) != Rational.zero } + infinities.size match { + case 0 => + for (i <- 0 until dimension) { + if (coeffsTransformed(i) > Rational.zero) + newhigh(i) = high(i) min (lfArgmin(i) + (-RationalExt(known) - minc) / coeffsTransformed(i)) + else if (coeffsTransformed(i) < Rational.zero) + newlow(i) = low(i) max (lfArgmin(i) + (-RationalExt(known) - minc) / coeffsTransformed(i)) + } + case 1 => { + val posinf = infinities.head + if (coeffsTransformed(posinf) < Rational.zero) + newlow(posinf) = low(posinf) max ((-dotprod(coeffsTransformed, lfArgmin, posinf) - known) / coeffsTransformed(posinf)) + else + newhigh(posinf) = high(posinf) min ((-dotprod(coeffsTransformed, lfArgmin, posinf) - known) / coeffsTransformed(posinf)) + } + case _ => + } + new Property(false, newlow, A, newhigh) + } + } + case Some(chosen) => { + // TODO: check.. I think this may generate non-invertible matrices + val newA = A.copy + val newhigh = high.copy + newA.rowUpdate(chosen, coeffs) + newhigh(chosen) = -known + new Property(false, low, newA, newhigh) + } + } + } + } + + /** + * @inheritdoc + * @note @inheritdoc + * @throws $ILLEGAL + */ + def linearDisequality(lf: LinearForm): Property = { + val tcoeff = lf.homcoeffs + val known = lf.known + if (tcoeff.forall(_.isZero)) { + if (known.isZero) + bottom + else + this + } else { + val row = (0 until dimension).find { (r) => + val v1 = A.row(r) + val v2 = DenseVector(tcoeff: _*) + v1.data sameElements v2.data + } + row match { + case None => this + case Some(row) => + if (low(row) == known && high(row) == known) bottom else this + } + } + } + + /** + * @inheritdoc + * @note @inheritdoc + * @throws $ILLEGAL + */ + def nonDeterministicAssignment(n: Int): Property = { + require(n <= dimension) + if (isEmpty) + this + else { + val unsortedCandidates = (0 until dimension) filter { i => A(i, n) != Rational.zero && (!low(i).isNegInfinity || !high(i).isPosInfinity) } + if (unsortedCandidates.isEmpty) + this + else { + // We prever to use as a pivot a simple constraint. Therefore, we order constraints by the number of + // non-zero coefficients. + val countNonZeroInRows = A.countNonZeroInRows + val removeCandidates = unsortedCandidates.sortBy({ i => countNonZeroInRows(i) }) + val removeCandidatesEq = removeCandidates filter { i => low(i) == high(i) } + val removeCandidatesBounded = removeCandidates filter { i => !low(i).isInfinity && !high(i).isInfinity } + + val pivot = + if (!removeCandidatesEq.isEmpty) removeCandidatesEq.head + else if (!removeCandidatesBounded.isEmpty) removeCandidatesBounded.head + else removeCandidates.head + val rowPivot = A.row(pivot) + + val newA = A.copy + val newlow = low.copy + val newhigh = high.copy + + for (i <- removeCandidates if i != pivot) { + val value1 = rowPivot(n) + val value2 = A(i, n) + val rowi = A.row(i) + newA.rowUpdate(i, rowPivot * value2 - rowi * value1) + val (minPivot, maxPivot) = if (A(i, n) < Rational.zero) (high(pivot), low(pivot)) else (low(pivot), high(pivot)) + val (mini, maxi) = if (-A(pivot, n) < Rational.zero) (high(i), low(i)) else (low(i), high(i)) + newlow(i) = minPivot * value2 - mini * value1 + newhigh(i) = maxPivot * value2 - maxi * value1 + } + newlow(pivot) = RationalExt.NegativeInfinity + newhigh(pivot) = RationalExt.PositiveInfinity + new Property(false, newlow, newA, newhigh) + } + } + } + + def addVariable(): Property = { + if (isEmpty) + ParallelotopeRationalDomainFast.this.bottom(dimension + 1) + else { + val e = DenseMatrix.zeros(dimension + 1, 1) + e(dimension, 0) = Rational.one + val newA = (A vertcat DenseMatrix.zeros(1, dimension)) horzcat e + val newlow = low vertcat Bounds(RationalExt.NegativeInfinity) + val newhigh = high vertcat Bounds(RationalExt.PositiveInfinity) + + new Property(false, newlow, newA, newhigh) + } + } + + def constraints = { + if (isEmpty) + Seq(LinearForm(1)) + else { + val set1 = for (i <- 0 until dimension; if !low(i).isInfinity) yield -LinearForm(-low(i).value +: A.row(i).toScalaVector: _*) + val set2 = for (i <- 0 until dimension; if !high(i).isInfinity) yield LinearForm(-high(i).value +: A.row(i).toScalaVector: _*) + set1 ++ set2 + } + } + + def isPolyhedral = true + + /** + * @inheritdoc + * @note @inheritdoc + * @throws $ILLEGAL + */ + def delVariable(n: Int): Property = { + def rowToSeq(M: DenseMatrix, i: Int, n: Int): Seq[Rational] = + for (j <- 0 until A.rows; if j != n) yield M(i, j) + + if (isEmpty) + ParallelotopeRationalDomainFast.this.bottom(A.rows - 1) + else { + val forgot = this.nonDeterministicAssignment(n) + val set1 = for (i <- 0 until dimension; if !forgot.low(i).isInfinity; if forgot.A(i, n) == Rational.zero) yield -LinearForm(-forgot.low(i).value +: rowToSeq(forgot.A, i, n): _*) + val set2 = for (i <- 0 until dimension; if !forgot.high(i).isInfinity; if forgot.A(i, n) == Rational.zero) yield LinearForm(-forgot.high(i).value +: rowToSeq(forgot.A, i, n): _*) + (set1 ++ set2).foldLeft(ParallelotopeRationalDomainFast.this.top(A.rows - 1)) { (p, lf) => p.linearInequality(lf) } + } + } + + /** + * @inheritdoc + */ + def mapVariables(rho: Seq[Int]): Property = { + if (isEmpty) + this + else { + val slice = for (i <- 0 until dimension; j = rho.indexOf(i); if j != -1) yield j + val newA = A(slice, slice) + val newlow = low(slice) + val newhigh = high(slice) + + new Property(false, newlow, newA, newhigh) + } + } + + /** + * Compute the minimum and maximum value of a linear form in a parallelotope. + * @todo should be generalized to linear forms over arbitrary types. + * @return a tuple with two components: the first component is the least value, the second component is the greatest value + * of the linear form over the box. + */ + def linearEvaluation(lf: LinearForm): (RationalExt, RationalExt) = { + val tcoeff = lf.homcoeffs + if (isEmpty && tcoeff.exists { _ != Rational.zero }) + (RationalExt.PositiveInfinity, RationalExt.NegativeInfinity) + else if (dimension == 0) + (lf.known, lf.known) + else { + val coeff = tcoeff.padTo(dimension, Rational.zero).toArray + val vec = new DenseVector(coeff) + val newvec = A.t \ vec + val (min, max) = domain.extremalsInBox(newvec, low, high) + (min + lf.known, max + lf.known) + } + } + + def minimize(lf: LinearForm) = linearEvaluation(lf)._1 + + def maximize(lf: LinearForm) = linearEvaluation(lf)._2 + + def frequency(lf: LinearForm) = { + val (min, max) = linearEvaluation(lf) + if (min == max) Option(min.value) else Option.empty + } + + def dimension = A.rows + + def isTop = !isEmpty && low.forall(_.isNegInfinity) && high.forall(_.isPosInfinity) + + def isBottom = isEmpty + + def bottom = ParallelotopeRationalDomainFast.this.bottom(dimension) + + def top = ParallelotopeRationalDomainFast.this.top(dimension) + + def tryCompareTo[B >: Property](that: B)(implicit arg0: (B) => PartiallyOrdered[B]): Option[Int] = that match { + case that: Property => + val lte = this <= that + val gte = that <= this + if (lte && gte) + Option(0) + else if (lte) + Option(-1) + else if (gte) + Option(1) + else + Option.empty + case _ => Option.empty + } + + /** + * It computes the smallest parallelotope which contains `this` and is definable + * over a new shape matrix `Aprime`. + * @param Aprime the new shape matrix. + * @note `Aprime` should be an invertible matrix of the same dimension as `this`. + * @throws IllegalArgumentException if `Aprime` is not square or has not the correct dimension. + */ + def rotate(Aprime: DenseMatrix): Property = { + require(dimension == Aprime.rows && dimension == Aprime.cols) + if (isEmpty) + this + else { + val B = Aprime * (A \ DenseMatrix.eye(dimension)) + val newlow = Bounds.fill(dimension)(RationalExt.zero) + val newhigh = Bounds.fill(dimension)(RationalExt.zero) + B.foreachPair { + case ((i, j), v) => + if (v > Rational.zero) { + newlow(i) += low(j) * v + newhigh(i) += high(j) * v + } else if (v < Rational.zero) { + newhigh(i) += low(j) * v + newlow(i) += high(j) * v + } + } + new Property(false, newlow, Aprime, newhigh) + } + } + + def <=[B >: Property](that: Property)(implicit arg0: (B) => PartiallyOrdered[B]): Boolean = { + if (isEmpty) + true + else if (that.isEmpty) + false + else if (that.isTop) + true + else { + val ptemp = this.rotate(that.A) + (0 to ptemp.low.length - 1) forall { i => ptemp.low(i) >= that.low(i) && ptemp.high(i) <= that.high(i) } + } + } + + def >=[B >: Property](that: Property)(implicit arg0: (B) => PartiallyOrdered[B]): Boolean = + that <= this + + def <[B >: Property](that: Property)(implicit arg0: (B) => PartiallyOrdered[B]): Boolean = + (this <= that) && !(this >= that) + + def >[B >: Property](that: Property)(implicit arg0: (B) => PartiallyOrdered[B]): Boolean = + (this >= that) && !(this <= that) + + def mkString(vars: Seq[String]): String = { + + /* + * Returns a string representation of the linear form `lf`. + */ + def lfToString(lf: DenseVector): String = { + var first = true + val s = new StringBuilder + val minusOne = -Rational.one + + for (index <- 0 until dimension) { + val coeff = lf(index) + val term = coeff match { + case Rational.zero => "" + case Rational.one => vars(index) + case `minusOne` => "-" + vars(index) + case c => c.toString + "*" + vars(index) + } + if (!coeff.isZero) { + if (first || coeff < Rational.zero) { + s ++= term + first = false + } else if (coeff != Rational.zero) + s ++= "+" + term + } + } + if (s.isEmpty) "0" else s.toString + } + + if (isEmpty) + "empty" + else { + val eqns = for (i <- 0 until dimension) yield { + if (low(i) < high(i)) + s"${if (low(i).isNegInfinity) "-∞" else low(i)} ≤ ${lfToString(A.col(i))} ≤ ${if (high(i).isPosInfinity) "+∞" else high(i)}" + else + s"${lfToString(A.col(i))} = ${high(i)}" + } + eqns.mkString("[ ", " , ", " ]") + } + } + } +} + +/** + * Companion class for the parallelotope domain + */ +object ParallelotopeRationalDomainFast { + private lazy val standard = new ParallelotopeRationalDomainFast(0) with CachedTopBottom + private lazy val favoring = new ParallelotopeRationalDomainFast(1) with CachedTopBottom + private lazy val unfavoring = new ParallelotopeRationalDomainFast(-1) with CachedTopBottom + + /** + * Returns an abstract domain for parallelotopes. + * @param favorAxis determines whether the heuristics built into the domain should try to keep constraints + * corresponding to Cartesian axis. If favorAxis is `1`, axis are favorite. The opposite happens when favorAxis + * is -1. If favorAxis is 0, axis are considered like all the other constraints + */ + def apply(favorAxis: Int = 0) = favorAxis match { + case -1 => unfavoring + case 0 => standard + case 1 => favoring + case _ => throw new IllegalArgumentException("The field favorAxis should be -1, 0 or 1") + } +} diff --git a/core/src/main/scala/it/unich/jandom/utils/numberext/Bounds.scala b/core/src/main/scala/it/unich/jandom/utils/numberext/Bounds.scala new file mode 100644 index 00000000..60afa6c2 --- /dev/null +++ b/core/src/main/scala/it/unich/jandom/utils/numberext/Bounds.scala @@ -0,0 +1,86 @@ +/** + * Copyright 2016, 2017 Gianluca Amato + * + * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains + * JANDOM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * JANDOM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of a + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with JANDOM. If not, see . + */ + +package it.unich.jandom.utils.numberext + +/** + * This is a value class which implements some useful methods over arrays of extended rationals. + * @param data the underlying array of extended rationals. + */ +final class Bounds(val data: Array[RationalExt]) extends AnyVal { + /** + * Returns the length of the array. + */ + def length = data.length + + /** + * Returns the `i`-th element of the array. + */ + def apply(i: Int) = data(i) + + /** + * Returns a copy of the array. + */ + def copy = new Bounds(data.clone) + + /** + * Update the i-th element of the array with value `v`. + */ + def update(i: Int, v: RationalExt) = data.update(i,v) + + /** + * Append `that` to `this`. + */ + def vertcat(that: Bounds) = { + val newdata = new Array[RationalExt](data.length + that.data.length) + Array.copy(data, 0, newdata, 0, data.length) + Array.copy(that.data, 0, newdata, data.length, that.data.length) + new Bounds(newdata) + } + + /** + * Returns a subarray of the elements in the array, whose index is in `slice`. + */ + def apply(slice: Seq[Int]) = { + val newdata = new Array[RationalExt](slice.length) + for ((idx, i) <- slice.zipWithIndex) { + newdata(i) = data(idx) + } + new Bounds(newdata) + } + + /** + * Returns true if the map `f` is true for all elements of the array. + */ + def forall(f: RationalExt => Boolean) = data.forall(f) +} + +/** + * The compaion object of Bounds. + */ +object Bounds { + /** + * Create a bound vector of dimension `n` filled with `value`. + */ + def fill(n: Int)(value: RationalExt) = new Bounds(Array.fill[RationalExt](n)(value)) + + /** + * Builds a bound vector for a sequence of extended rationals. + */ + def apply(elem: RationalExt*) = new Bounds(elem.toArray) +} \ No newline at end of file diff --git a/core/src/main/scala/it/unich/jandom/utils/numberext/DenseMatrix.scala b/core/src/main/scala/it/unich/jandom/utils/numberext/DenseMatrix.scala new file mode 100644 index 00000000..47688df4 --- /dev/null +++ b/core/src/main/scala/it/unich/jandom/utils/numberext/DenseMatrix.scala @@ -0,0 +1,418 @@ +/** + * Copyright 2016, 2017 Gianluca Amato + * + * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains + * JANDOM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * JANDOM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of a + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with JANDOM. If not, see . + */ + +package it.unich.jandom.utils.numberext + +import spire.syntax.cfor._ +import spire.math.Rational + +/** + * A DenseMatrix is a matrix of rationals. It is implemented as a single array + * in column order. + * @param data the underlying array containing the data + * @param rows the number of rows in the matrix + */ +final class DenseMatrix(val data: Array[Rational], val rows: Int) { + /** + * The number of columns in the matrix. + */ + val cols = if (data.length == 0 && rows == 0) 0 else data.length / rows + + /** + * Returns the element in position (`i`,`j`). + */ + def apply(i: Int, j: Int): Rational = data(i + j * rows) + + /** + * Modify the element in position (`i`,`j`) with value `v`. + */ + def update(i: Int, j: Int, v: Rational) = data.update(i + j * rows, v) + + /** + * Returns a copy of the matrix. + */ + def copy = new DenseMatrix(data.clone, rows) + + /** + * Add the matrix `that` to `this`. + */ + def +=(that: DenseMatrix): DenseMatrix = { + cfor(0)(_ < data.length, _ + 1) { (i) => + data(i) += that.data(i) + } + this + } + + /** + * Subtract the matrix `that` from `this`. + */ + def -=(that: DenseMatrix): DenseMatrix = { + cfor(0)(_ < data.length, _ + 1) { (i) => + data(i) -= that.data(i) + } + this + } + + /** + * Returns the sum of `this` and `that`. + */ + def +(that: DenseMatrix) = { + val result = this.copy + result += that + } + + /** + * Returns the `this` - `that`. + */ + def -(that: DenseMatrix) = { + val result = this.copy + result -= that + } + + /** + * Sum the rational `that` to all elements in the matrix. + */ + def +=(that: Rational): DenseMatrix = { + cfor(0)(_ < data.length, _ + 1) { (i) => + data(i) += that + } + this + } + + /** + * Returns the matrix obtained by summing `that` to all elements in `this`. + */ + def +(that: Rational) = { + val result = this.copy + result += that + } + + /** + * Sum the rational `that` from all elements in the matrix. + */ + def -=(that: Rational): DenseMatrix = { + cfor(0)(_ < data.length, _ + 1) { (i) => + data(i) -= that + } + this + } + + /** + * Returns the matrix obtained by subtracting `that` from all elements in `this`. + */ + def -(that: Rational) = { + val result = this.copy + result -= that + } + + /** + * Multiplies all the elements in the matrix by `that` + */ + def *=(that: Rational): DenseMatrix = { + cfor(0)(_ < data.length, _ + 1) { (i) => + data(i) *= that + } + this + } + + /** + * Returns the matrix obtained by multipling all elements in `this` by `that`. + */ + def *(that: Rational) = { + val result = this.copy + result *= that + } + + /** + * Divides all elements in the matrix by `that` + */ + def /=(that: Rational): DenseMatrix = { + cfor(0)(_ < data.length, _ + 1) { (i) => + data(i) /= that + } + this + } + + /** + * Returns the matrix obtained by dividing all elements in `this` by `that`. + */ + def /(that: Rational) = { + val result = this.copy + result /= that + } + + /** + * Returns the row-by-column product of `this` and `that`. + */ + def *(that: DenseMatrix): DenseMatrix = { + require(this.cols == that.rows) + var result = DenseMatrix.raw(this.rows, that.cols) + cfor(0)(_ < rows, _ + 1) { (i) => + cfor(0)(_ < that.cols, _ + 1) { (j) => + result(i, j) = Rational(0) + cfor(0)(_ < cols, _ + 1) { (k) => + result(i, j) += this(i, k) * that(k, j) + } + } + } + result + } + + /** + * Returns a matrix `A` such that `this * A = that`. + */ + def \(that: DenseMatrix): DenseMatrix = { + require(this.rows == that.rows, "Non-conformant matrices size") + if (data.size == 0) + DenseMatrix.zeros(0, 0) + else { + val A = data.clone + val X = that.data.clone + val Y = DenseMatrix.LUSolveArray(X, A, that.rows, that.cols) + new DenseMatrix(Y, rows) + } + } + + /** + * Returns a vector `v` such that `this * v = that`. + */ + def \(that: DenseVector): DenseVector = { + val M = new DenseMatrix(that.data, that.length) + val res = this \ M + new DenseVector(res.data) + } + + /** + * Returns the transpose of `this`. + */ + def t: DenseMatrix = { + val result = new DenseMatrix(new Array[Rational](data.length), cols) + cfor(0)(_ < rows, _ + 1) { (i) => + cfor(0)(_ < cols, _ + 1) { (j) => + result(j, i) = this(i, j) + } + } + result + } + + /** + * Horizontally concatenates `that` to `this`. The two matrices are required to have the same number + * of rows, and the columns of `that` are added as additional columns to `this`. + */ + def horzcat(that: DenseMatrix) = { + require(rows == that.rows) + val result = new DenseMatrix(new Array[Rational](this.rows * (this.cols + that.cols)), rows) + Array.copy(this.data, 0, result.data, 0, data.length) + Array.copy(that.data, 0, result.data, data.length, that.data.length) + result + } + + /** + * Vertically concatenates `that` to `this`. The two matrices are required to have the same number + * of columns, and the rows of `that` are added as additional rows to `this`. + */ + def vertcat(that: DenseMatrix) = { + require(cols == that.cols) + val result = new DenseMatrix(new Array[Rational]((this.rows + that.rows) * this.cols), this.rows + that.rows) + cfor(0)(_ < cols, _ + 1) { (j) => + cfor(0)(_ < this.rows, _ + 1) { (i) => + result(i, j) = this(i, j) + } + cfor(0)(_ < that.rows, _ + 1) { (i) => + result(i + rows, j) = that(i, j) + } + } + result + } + + /** + * Returns the `i`-th row of `this` as a vector. + */ + def row(i: Int): DenseVector = { + val data = new Array[Rational](cols) + cfor(0)(_ < cols, _ + 1) { (j) => + data(j) = this(i, j) + } + new DenseVector(data) + } + + /** + * Replaces the `i`-th row of `this` with `v`. + */ + def rowUpdate(i: Int, v: DenseVector): Unit = { + cfor(0)(_ < cols, _ + 1) { (j) => + this(i,j) = v(j) + } + } + + /** + * Returns the `i`-th column of `this` as a vector. + */ + def col(j: Int) = { + val data = new Array[Rational](rows) + cfor(0)(_ < rows, _ + 1) { (i) => + data(i) = this(i, j) + } + new DenseVector(data) + } + + /** + * Returns an array `a` such that `a(i)` contains the number of non-zero elements + * in the `i`-th row of `this`. + */ + def countNonZeroInRows: Array[Int] = { + val res = new Array[Int](rows) + var tot = 0 + cfor(0) (_ < rows, _ +1 ) { (i) => + tot = 0 + cfor(0) ( _ < cols, _ + 1) { (j) => + if (this(i,j) != 0) tot += 1 + } + res(i) = tot + } + res + } + + /** + * Returns a submatrix of `this`. + * @param slicer the sequence of rows to extract from `this` + * @param slicec the sequence of columns to extract from `this` + * @return the resulting submatrix + */ + def apply(slicer: Seq[Int], slicec: Seq[Int]): DenseMatrix = { + val result = new DenseMatrix(new Array[Rational](slicer.length*slicec.length), slicer.length) + for ((i, idxi) <- slicer.zipWithIndex; (j, idxj) <- slicec.zipWithIndex) { + result(idxi,idxj) = this(i, j) + } + result + } + + /** + * For each position `(i,j)` in `this`, `f` is called with parameters + * `(i,j)` and `this((i,j))`. + */ + def foreachPair(f: ((Int, Int), Rational) => Unit): Unit = { + cfor (0)(_ < rows, _ +1) { (i) => + cfor(0) ( _ < cols, _ +1 ) { (j) => + f((i,j), this(i,j)) + } + } + } + + override def toString = { + val sb = new StringBuilder + cfor (0)(_ < rows, _ + 1) { (i) => + cfor (0)(_ < cols, _ + 1) { (j) => + sb ++= this(i,j).toString + sb += ' ' + } + sb += '\n' + } + sb.toString + } +} + +/** + * The compaion object for DenseMatrix + */ +object DenseMatrix { + + /** + * Returns a matrix with `n` rows and `m` columns. Elements of the matrix + * are not initialized. + */ + def raw(n: Int, m: Int) = new DenseMatrix(new Array[Rational](n * m), n) + + /** + * Returns a diagonal matrix of order `n`. + */ + def eye(n: Int) = { + val data = new Array[Rational](n * n) + cfor(0)(_ < n, _ + 1) { (i) => + cfor(0)(_ < n, _ + 1) { (j) => + data(i + j * n) = if (i == j) Rational.one else Rational.zero + } + } + new DenseMatrix(data, n) + } + + /** + * Returns a matrix with `n` rows and `m` columns filled with zero. + */ + def zeros(n: Int, m: Int) = { + val data = Array.fill[Rational](m * n)(Rational.zero) + new DenseMatrix(data, n) + } + + /** + * Build a matrix from a sequence of vectors. Each vector will be a row + * in the resulting matrix. + */ + def apply(rows: DenseVector*) = { + if (rows.isEmpty) + new DenseMatrix(new Array[Rational](0), 0) + else { + val cols = rows(0).length + val result = new DenseMatrix(new Array[Rational](cols * rows.length), rows.length) + for ((row, i) <- rows.zipWithIndex) { + cfor(0)(_ < cols, _ + 1) { (j) => + result(i, j) = row(j) + } + } + result + } + } + + /** + * An helper private method which implements Gaussian elimination. + */ + private def LUSolveArray(X: Array[Rational], A: Array[Rational], Xrows: Int, Xcols: Int): Array[Rational] = { + val perm = (0 until Xrows).toArray + for (i <- 0 until Xrows - 1) { + val optPivot = (i until Xrows) find { p => !A(perm(p) + i * Xrows).isZero } + val pivotRow = optPivot.getOrElse(throw new IllegalArgumentException("Non invertible matrix")) + val tmp = perm(i) + perm(i) = perm(pivotRow) + perm(pivotRow) = tmp + val pivot = A(perm(i) + i * Xrows) + for (j <- i + 1 until Xrows) { + val coeff = A(perm(j) + i * Xrows) / pivot + cfor(0)(_ < Xrows, _ + 1) { (k) => + A(perm(j) + k * Xrows) -= A(perm(i) + k * Xrows) * coeff + } + cfor(0)(_ < Xcols, _ + 1) { (k) => + X(perm(j) + k * Xrows) -= X(perm(i) + k * Xrows) * coeff + } + } + } + val X1 = new Array[Rational](Xrows * Xcols) + for (i <- Xrows - 1 to (0, -1)) { + cfor(0)(_ < Xcols, _ + 1) { (k) => + X1(i + k * Xrows) = X(perm(i) + k * Xrows) + } + for (j <- i + 1 until Xrows) + cfor(0)(_ < Xcols, _ + 1) { (k) => + X1(i + k * Xrows) -= X1(j + k * Xrows) * A(perm(i) + j * Xrows) + } + cfor(0)(_ < Xcols, _ + 1) { (k) => + X1(i + k * Xrows) /= A(perm(i) + i * Xrows) + } + } + X1 + } +} diff --git a/core/src/main/scala/it/unich/jandom/utils/numberext/DenseVector.scala b/core/src/main/scala/it/unich/jandom/utils/numberext/DenseVector.scala new file mode 100644 index 00000000..765e2d9a --- /dev/null +++ b/core/src/main/scala/it/unich/jandom/utils/numberext/DenseVector.scala @@ -0,0 +1,281 @@ +/** + * Copyright 2016, 2017 Gianluca Amato + * + * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains + * JANDOM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * JANDOM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of a + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with JANDOM. If not, see . + */ + +package it.unich.jandom.utils.numberext + +import spire.math.Rational +import spire.syntax.cfor._ +import scala.language.implicitConversions + +/** + * This is a value class which implements some useful methods over arrays of rationals. + * @param data the underlying array containing the data + */ +final class DenseVector(val data: Array[Rational]) extends AnyVal { + /** + * Length of the vector. + */ + def length = data.length + + /** + * Returns the `i`-th element of the vector. + */ + def apply(i: Int) = data(i) + + /** + * Updates the `i`-th element of the vector with value `v`. + */ + def update(i: Int, v: Rational) = data.update(i, v) + + /** + * Returns a copy of the vector. + */ + def copy = new DenseVector(data.clone) + + /** + * Add vector `that` to `this`. + */ + def +=(that: DenseVector) = { + cfor(0)(_ < data.length, _ + 1) { (i) => + data(i) += that.data(i) + } + this + } + + /** + * Subtract vector `that` from `this`. + */ + def -=(that: DenseVector) = { + cfor(0)(_ < data.length, _ + 1) { (i) => + data(i) -= that.data(i) + } + this + } + + /** + * Component-wise multiply `this` by `that`. + */ + def *=(that: DenseVector) = { + cfor(0)(_ < data.length, _ + 1) { (i) => + data(i) *= that.data(i) + } + this + } + + /** + * Component-wise divide `this` by `that`. + */ + def /=(that: DenseVector) = { + cfor(0)(_ < data.length, _ + 1) { (i) => + data(i) /= that.data(i) + } + this + } + + /** + * Add the rational `that` to all elements of `this`. + */ + def +=(that: Rational) = { + cfor(0)(_ < data.length, _ + 1) { (i) => + data(i) += that + } + this + } + + /** + * Subtract the rational `that` from all elements of `this`. + */ + def -=(that: Rational) = { + cfor(0)(_ < data.length, _ + 1) { (i) => + data(i) -= that + } + this + } + + /** + * Multiplies all elements of `this` by `that`. + */ + def *=(that: Rational) = { + cfor(0)(_ < data.length, _ + 1) { (i) => + data(i) *= that + } + this + } + + /** + * Divides all elements of `this` by `that`. + */ + def /=(that: Rational) = { + cfor(0)(_ < data.length, _ + 1) { (i) => + data(i) /= that + } + this + } + + /** + * Transform `this` into its opposite. + */ + def oppose() = { + cfor(0)(_ < data.length, _ + 1) { (i) => + data(i) = -data(i) + } + this + } + + /** + * Returns the sum of `this` and `that`. + */ + def +(that: DenseVector) = { + val result = this.copy + result += that + } + + /** + * Returns the sum of `this` and `that`. + */ + def -(that: DenseVector) = { + val result = this.copy + result -= that + } + + /** + * Returns the component-wise product of `this` and `that`. + */ + def *(that: DenseVector) = { + val result = this.copy + result *= that + } + + /** + * Returns the component-wise division of `this` by `that`. + */ + def /(that: DenseVector) = { + val result = this.copy + result /= that + } + + /** + * Returns the vector obtained by adding `that` to all elements of `this`. + */ + def +(that: Rational) = { + val result = this.copy + result += that + } + + /** + * Returns the vector obtained by subtracting `that` from all elements of `this`. + */ + def -(that: Rational) = { + val result = this.copy + result -= that + } + + /** + * Returns the vector obtained by multiplying all elements of `this` with `that`. + */ + def *(that: Rational) = { + val result = this.copy + result *= that + } + + /** + * Returns the product of the column vector `this` by matrix `that`. + */ + def *(that: DenseMatrix) = { + val m = new DenseMatrix(data, data.length) + m * that + } + + /** + * Returns the vector obtained by dividing all elements of `this` by `that`. + */ + def /(that: Rational) = { + val result = this.copy + result /= that + } + + /** + * Returns the opposite of `this`. + */ + def unary_- = { + val result = this.copy + result.oppose() + } + + /** + * Returns the number of non-zero elements in `this`. + */ + def countNonZero: Int = { + var tot = 0 + cfor(0)(_ < data.length, _ + 1) { (i) => + if (data(i) != 0) tot += 1 + } + tot + } + + /** + * Returns the row vector which is the transpose of `t`. The row + * vector is represented as a dense matrix. + */ + def t: DenseMatrix = { + new DenseMatrix(data.clone, 1) + } + + /** + * It returns a bound vector obtained by applying `f` to each element + * of `this`. The map `f` is called with box the index and the value + * of each element. + */ + def mapPairs(f: (Int, Rational) => RationalExt) = { + val newdata = new Array[RationalExt](data.length) + cfor(0)(_ < data.length, _ + 1) { (i) => + newdata(i) = f(i, data(i)) + } + new Bounds(newdata) + } + + /** + * Returns `this` as a Scala Vector. + */ + def toScalaVector: Vector[Rational] = Vector(data: _*) + +} + +/** + * The companion object for DenseVector. + */ +object DenseVector { + /** + * Implicit conversion from a pair to a DenseVector. + */ + implicit def fromTuple2(x: Tuple2[Rational, Rational]) = DenseVector(x._1, x._2) + implicit def fromTuple3(x: Tuple3[Rational, Rational, Rational]) = DenseVector(x._1, x._2, x._3) + + /** + * Builds a DenseVector from a sequence of rationals. + */ + def apply(elem: Rational*): DenseVector = new DenseVector(elem.toArray) + + /** + * Returns the null vector of dimension `n`. + */ + def zeros(n: Int) = { + val data = Array.fill[Rational](n)(Rational.zero) + new DenseVector(data) + } +} \ No newline at end of file diff --git a/core/src/test/scala/it/unich/jandom/domains/numerical/ParallelotopeRationalDomainFastSuite.scala b/core/src/test/scala/it/unich/jandom/domains/numerical/ParallelotopeRationalDomainFastSuite.scala new file mode 100644 index 00000000..4b3a333a --- /dev/null +++ b/core/src/test/scala/it/unich/jandom/domains/numerical/ParallelotopeRationalDomainFastSuite.scala @@ -0,0 +1,255 @@ +/** + * Copyright 2017 Gianluca Amato + * + * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains + * JANDOM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * JANDOM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of a + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with JANDOM. If not, see . + */ + +package it.unich.jandom.domains.numerical + +import scala.language.implicitConversions + +import it.unich.jandom.domains.EmptyExistsSuite +import it.unich.jandom.domains.SeparatedTopAndBottomSuite +import it.unich.jandom.utils.numberext.RationalExt +import it.unich.jandom.utils.numberext.Bounds +import it.unich.jandom.utils.numberext.DenseMatrix +import it.unich.jandom.utils.numberext.Bounds +import spire.math.Rational +import spire.syntax.literals._ + +/** + * Test suite for the parallelotope domain over rationals. + * @author Gianluca Amato + */ +class ParallelotopeRationalDomainFastSuite extends NumericalDomainSuite with SeparatedTopAndBottomSuite with EmptyExistsSuite { + lazy val dom = ParallelotopeRationalDomainFast() + + val box = dom(Bounds(r"-1",r"-1"), DenseMatrix.eye(2), Bounds(r"1", r"1")) + val diamond = dom(Bounds(r"-1", r"-1"), DenseMatrix((r"1", r"1"), (r"1", r"-1")), Bounds(r"1", r"1")) + val empty = dom.bottom(2) + val full = dom.top(2) + + implicit def r(x: Int) = RationalExt(x) + + override lazy val someProperties = Table("property", dom.bottom(0), dom.bottom(1), dom.bottom(2), dom.bottom(3), dom.bottom(4), dom.bottom(4), + dom.top(0), dom.top(1), dom.top(2), dom.top(3), dom.top(4), dom.top(5), box, diamond) + + describe("constructors") { + they("should only work with compatible sizes of bounds and shapes") { + intercept[IllegalArgumentException] { dom(Bounds(r"0", r"2"), DenseMatrix.eye(2), Bounds(r"0", r"2", r"3")) } + } + } + + describe("constructors and extractors for non-trivial parallelotopes") { + they("should behave as expected") { + assertResult(2) { box.dimension } + assertResult(false) { box.isEmpty } + assertResult(false) { box.isTop } + } + } + + describe("constructors and extractors for full parallelotopes") { + they("should behave as expected") { + assertResult(2) { full.dimension } + assertResult(false) { full.isEmpty } + assertResult(true) { full.isTop } + } + } + + describe("constructors and extractors for empty parallelotopes") { + they("should behave as expected") { + assertResult(2) { empty.dimension } + assertResult(true) { empty.isEmpty } + assertResult(false) { empty.isTop } + } + } + + describe("comparison of parallelotopes") { + it("should behave as expected") { + assert(empty < box) + assert(box < full) + assert(empty < full) + assert(diamond < box) + assert(diamond <= box) + assert(box > diamond) + assert(box >= diamond) + assertResult(Some(1)) { box.tryCompareTo(diamond) } + assertResult(Some(-1)) { diamond.tryCompareTo(box) } + assert(box == box) + assertResult(Some(0)) { box.tryCompareTo(box) } + val box2 = dom(Bounds(r"-1/2", r"-1/2"), DenseMatrix.eye(2), Bounds(r"1/2", r"1/2")) + assert(box2 <= box) + assert(box >= box2) + assert(box2 < box) + assert(box > box2) + val box3 = dom(Bounds(r"0", r"0"), DenseMatrix.eye(2), Bounds(r"2", r"2")) + assertResult(None) { box.tryCompareTo(box3) } + } + } + + describe("rotation of shapes") { + it("should behave as expected") { + val m = DenseMatrix((r"1", r"1"), (r"-1", r"1")) + val m1 = DenseMatrix.zeros(m.rows, m.cols) + for (i <- 0 until m.rows) { for (j <- 0 until m.cols) { m1(i, j) = m(i, j) } } + val protcalc = box.rotate(m1) + val protdef = dom(Bounds(r"-2", r"-2"), m, Bounds(r"2", r"2")) + assertResult(protdef) { protcalc } + } + } + + describe("linear invertible assignment") { + they("should behave as expected") { + val li1 = dom(Bounds(r"0", r"-1"), DenseMatrix((r"1", -r"1"), (r"0", r"1")), Bounds(r"2", r"1")) + assertResult(li1) { box.linearAssignment(0, LinearForm(1, 1, 1)) } + val li2 = dom(Bounds(r"1", r"-1"), DenseMatrix((r"1", r"0"), (r"-1", r"1")), Bounds(r"1", r"0")) + val li3 = dom(Bounds(r"2", r"-2"), DenseMatrix((r"1", r"0"), (r"-1", r"1")), Bounds(r"2", r"-1")) + assertResult(li3) { li2.linearAssignment(0, LinearForm(1, 1, 0)) } + assertResult(li3) { li2.linearAssignment(0, LinearForm(1, 1)) } + val li4 = dom(Bounds(r"-1", r"-2"), DenseMatrix((r"1", r"0"), (r"-1", r"1")), Bounds(r"1", r"2")) + assertResult(li4) { box.linearAssignment(1, LinearForm(0, 1, 2)) } + assert(empty.linearAssignment(1, LinearForm(0, 1, 1)).isEmpty) + } + } + + describe("non-invertible linear assignment") { + they("should behave as expected") { + val ln1 = dom(Bounds(r"2", r"-1"), DenseMatrix((r"1", r"-1"), (r"0", r"1")), Bounds(r"2", r"1")) + assertResult(ln1) { box.linearAssignment(0, LinearForm(2, 0, 1)) } + val ln2 = dom(Bounds(r"0", RationalExt.NegativeInfinity), DenseMatrix((r"-1", r"1"), (r"0", r"1")), Bounds(r"0", RationalExt.PositiveInfinity)) + val ln3 = dom(Bounds(RationalExt.NegativeInfinity, r"0"), DenseMatrix((r"1", r"-1"), (r"0", r"1")), Bounds(RationalExt.PositiveInfinity, r"0")) + assertResult(ln2) { ln3.linearAssignment(1, LinearForm(0, 1, 0)) } + assertResult(ln2) { ln3.linearAssignment(1, LinearForm(0, 1)) } + assert(empty.linearAssignment(1, LinearForm(0, 1, 0)).isEmpty) + } + } + + describe("non-deterministic assignment") { + they("should behave as expected") { + val nd1 = dom(Bounds(RationalExt.NegativeInfinity, r"-1"), DenseMatrix.eye(2), Bounds(RationalExt.PositiveInfinity, r"1")) + assert(nd1<=box.nonDeterministicAssignment(0)) + assert(nd1>=box.nonDeterministicAssignment(0)) + assertResult(nd1) { box.nonDeterministicAssignment(0) } + assertResult(nd1) { nd1.nonDeterministicAssignment(0) } + assertResult(nd1) { diamond.nonDeterministicAssignment(0) } + val nd2 = dom(Bounds(r"0", r"0"), DenseMatrix((r"2", r"1"), (r"2", -r"1")), Bounds(r"1", r"1")) + val nd3 = dom(Bounds(RationalExt.NegativeInfinity, r"-1"), DenseMatrix((r"2", r"1"), (r"0", r"-2")), Bounds(RationalExt.PositiveInfinity, r"1")) + assertResult(nd3) { nd2.nonDeterministicAssignment(0) } + val nd4 = dom(Bounds(RationalExt.NegativeInfinity, r"0"), DenseMatrix((r"2", r"1"), (r"4", r"0")), Bounds(RationalExt.PositiveInfinity, r"2")) + assertResult(nd4) { nd2.nonDeterministicAssignment(1) } + val nd5 = dom(Bounds(r"10", r"-1"), DenseMatrix((r"1", r"0"), (r"1", r"1")), Bounds(r"10", r"1")) + val nd6 = dom(Bounds(RationalExt.NegativeInfinity, r"-11"), DenseMatrix.eye(2), Bounds(RationalExt.PositiveInfinity, r"-9")) + assertResult(nd6) { nd5.nonDeterministicAssignment(0) } + assert(empty.nonDeterministicAssignment(0).isEmpty) + } + } + + describe("linear inequalities") { + they("should behave as expected") { + val li1 = dom(Bounds(r"-1", r"-1"), DenseMatrix((r"1", r"1"), (r"1", r"-1")), Bounds(r"0", r"0")) + assertResult(li1) { diamond.linearInequality(LinearForm(1, 2, 0)) } + assertResult(li1) { diamond.linearInequality(LinearForm(1, 2)) } + assert(empty.linearInequality(LinearForm(-1, 1, 0)).isEmpty) + } + } + + describe("linear disequalities") { + they("should behave as expected") { + val li1 = dom(Bounds(r"-1", r"0"), DenseMatrix((r"1",r"1"),(r"1",r"-2")), Bounds(r"0", r"0")) + assertResult(li1) { li1.linearDisequality(1) } + assertResult(empty) { li1.linearDisequality(0) } + assertResult(li1) { li1.linearDisequality(LinearForm(1, 0, 1)) } + assertResult(li1) { li1.linearDisequality(LinearForm(0.5, 1, -2)) } + assertResult(empty) { li1.linearDisequality(LinearForm(0, 1, -2)) } + } + } + + describe("union") { + it("should behave as expected") { + val u1 = dom(Bounds(2, 0), DenseMatrix.eye(2), Bounds(4, 2)) + val u2 = dom(Bounds(-4, -1), DenseMatrix((r"-1",r"3"), (r"0",r"1")), Bounds(4, 2)) + assertResult(u2) { box union u1 } + val u3 = dom(Bounds(-1, -1), DenseMatrix((r"0",r"1"), (r"1", r"-1")), Bounds(2, 4)) + assertResult(u3) { u1 union diamond } + val u4 = dom(Bounds(-4, 0), DenseMatrix.eye(2), Bounds(-2, 2)) + val u5 = dom(Bounds(-4, 0), DenseMatrix.eye(2), Bounds(4, 2)) + assertResult(u5) { u4 union u1 } + val u6 = dom(Bounds(1, RationalExt.NegativeInfinity), DenseMatrix((r"1", r"0"), (r"1", r"-1")), Bounds(1, 1)) + val u7 = dom(Bounds(0, RationalExt.NegativeInfinity), DenseMatrix((r"1", r"0"), (r"0", r"-1")), Bounds(0, 0)) + val u8 = dom(Bounds(0, 0), DenseMatrix.eye(2), Bounds(1, RationalExt.PositiveInfinity)) + assertResult(u8) { u6 union u7 } + val u9 = dom(Bounds(0, 0), DenseMatrix.eye(2), Bounds(0, RationalExt.PositiveInfinity)) + assertResult(u8) { u9 union u8 } + assertResult(u8) { u8 union u9 } + val u10 = dom(Bounds(2, 0), DenseMatrix.eye(2), Bounds(2, 0)) + val u11 = dom(Bounds(0, 2), DenseMatrix((r"0", r"1"), (r"1", r"-2")), Bounds(1, 6)) + assertResult(u11) { u10 union u11 } + } + } + + describe("minimization, maximization and frequency methods") { + they("should behave as expected") { + val i = dom(Bounds(-4, -1, 0), DenseMatrix((r"-1", r"3", r"0"), (r"0", r"1", r"0"), (r"-1", r"-1", r"1")), Bounds(4, 2, 0)) + assertResult(12)(i.maximize(LinearForm(0, 1, 1, 0))) + assertResult(-8)(i.minimize(LinearForm(0, 1, 1, 0))) + assertResult(None)(i.frequency(LinearForm(0, 1, 1, 0))) + assertResult(Some(0), i)(i.frequency(LinearForm(0, -1, -1, 1))) + } + } + + describe("dimensional variation") { + it("should behave as expected") { + val i = diamond + val j = dom(Bounds(-1, -1, RationalExt.NegativeInfinity), DenseMatrix((r"1",r"1",r"0"), + (r"1",r"-1",r"0"), (r"0",r"0",r"1")), Bounds(1, 1, RationalExt.PositiveInfinity)) + val h = dom(Bounds(-1, RationalExt.NegativeInfinity), DenseMatrix((r"1", r"0"), + (r"0",r"1")), Bounds(1, RationalExt.PositiveInfinity)) + assertResult(j)(i.addVariable()) + assertResult(h)(j.delVariable(0)) + assertResult(h)(j.delVariable(1)) + assertResult(i)(j.delVariable(2)) + } + } + + describe("dimensional maps") { + they("should behave as expected") { + val i = diamond + val h = dom(Bounds(-1), DenseMatrix.eye(1), Bounds(1)) + assertResult(diamond)(diamond.mapVariables(Seq(1, 0))) + assertResult(diamond)(i.mapVariables(Seq(0, 1))) + assertResult(h)(i.mapVariables(Seq(-1, 0))) + assertResult(diamond)(diamond.addVariable.mapVariables(Seq(1, 0, -1))) + } + } + + describe("string representation") { + they("should behave as expected") { + assertResult("[ -1 ≤ x+y ≤ 1 , -1 ≤ x-y ≤ 1 ]") { diamond.mkString(Seq("x", "y")) } + assertResult("empty") { empty.toString } + assertResult("[ -∞ ≤ v0 ≤ +∞ , -∞ ≤ v1 ≤ +∞ ]", full.toString) { full.toString } + } + } + + describe("all parallelotopes") { + they("are polyehdral") { + forAll(someProperties) { (p) => assert(p.isPolyhedral) } + } + they("may be rebuilt from constraints") { + forAll(someProperties) { (p) => + assertResult(p) { p.constraints.foldLeft(p.top) { (prop, lf) => prop.linearInequality(lf) } } + } + } + } +} From d43b00a4bedfc1fbd43f653f0866a302e3bb3925 Mon Sep 17 00:00:00 2001 From: Gianluca Amato Date: Thu, 20 Apr 2017 22:38:43 +0200 Subject: [PATCH 19/99] Remove old Parallelotope domains and all dependencies from Breeze. --- core/build.sbt | 3 - .../jandom/domains/DomainTransformation.scala | 39 +- .../numerical/ParallelotopeDomain.scala | 824 ---------------- .../ParallelotopeRationalDomain.scala | 175 ++-- .../ParallelotopeRationalDomainFast.scala | 894 ------------------ .../numerical/SumIntParallelotopeDomain.scala | 16 +- .../it/unich/jandom/ui/NumericalDomains.scala | 6 +- .../utils/breeze/RationalForBreeze.scala | 174 ---- .../jandom/utils/breeze/countNonZero.scala | 38 - .../unich/jandom/utils/numberext/Bounds.scala | 5 + .../jandom/utils/numberext/DenseVector.scala | 5 + .../it/unich/jandom/JandomSumBench.scala | 8 +- .../domains/DomainTransformationSuite.scala | 21 +- .../numerical/ParallelotopeDomainSuite.scala | 211 ----- ...ParallelotopeRationalDomainFastSuite.scala | 2 +- .../ParallelotopeRationalDomainSuite.scala | 255 ----- .../numerical/ProductDomainSuite.scala | 2 +- .../SumIntParallelotopeDomainSuite.scala | 11 +- .../utils/breeze/CountNonZeroTestSuite.scala | 34 - .../benchmarks/EQSLegacyFASTComparison.scala | 17 +- 20 files changed, 137 insertions(+), 2603 deletions(-) delete mode 100644 core/src/main/scala/it/unich/jandom/domains/numerical/ParallelotopeDomain.scala delete mode 100644 core/src/main/scala/it/unich/jandom/domains/numerical/ParallelotopeRationalDomainFast.scala delete mode 100644 core/src/main/scala/it/unich/jandom/utils/breeze/RationalForBreeze.scala delete mode 100644 core/src/main/scala/it/unich/jandom/utils/breeze/countNonZero.scala delete mode 100644 core/src/test/scala/it/unich/jandom/domains/numerical/ParallelotopeDomainSuite.scala delete mode 100644 core/src/test/scala/it/unich/jandom/domains/numerical/ParallelotopeRationalDomainSuite.scala delete mode 100644 core/src/test/scala/it/unich/jandom/utils/breeze/CountNonZeroTestSuite.scala diff --git a/core/build.sbt b/core/build.sbt index 283b0902..233653bc 100644 --- a/core/build.sbt +++ b/core/build.sbt @@ -6,10 +6,7 @@ libraryDependencies ++= Seq( "org.scalacheck" %% "scalacheck" % "1.13.3" % "test", "org.mockito" % "mockito-core" % "2.2.9" % "test", "org.spire-math" %% "spire" % "0.12.0", - "org.scalanlp" %% "breeze" % "0.12", "it.unich.scalafix" %% "scalafix" % "0.5.2", - // for using native linear algebra libraries - // "org.scalanlp" %% "breeze-natives" % "0.12", "org.rogach" %% "scallop" % "2.0.3", "org.scala-lang.modules" %% "scala-swing" % "1.0.2", "org.scala-lang.modules" %% "scala-parser-combinators" % "1.0.4", diff --git a/core/src/main/scala/it/unich/jandom/domains/DomainTransformation.scala b/core/src/main/scala/it/unich/jandom/domains/DomainTransformation.scala index 68024571..2658a885 100644 --- a/core/src/main/scala/it/unich/jandom/domains/DomainTransformation.scala +++ b/core/src/main/scala/it/unich/jandom/domains/DomainTransformation.scala @@ -19,8 +19,7 @@ package it.unich.jandom.domains import it.unich.jandom.domains.numerical._ -import it.unich.jandom.utils.breeze.RationalForBreeze._ -import it.unich.jandom.utils.numberext.RationalExt +import it.unich.jandom.utils.numberext.{DenseMatrix, Bounds, RationalExt} /** * This is the trait for domain transformations, i.e. maps from properties of one abstract domain to @@ -48,64 +47,38 @@ trait DomainTransformation[-DomA <: AbstractDomain, -DomB <: AbstractDomain] ext * @author Francesca Scozzari */ object DomainTransformation { - implicit object ParallelotopeToBoxDouble extends DomainTransformation[ParallelotopeDomain, BoxDoubleDomain] { - import breeze.linalg.DenseMatrix - def apply(src: ParallelotopeDomain, dst: BoxDoubleDomain): src.Property => dst.Property = { (x) => - val newPar = x.rotate(DenseMatrix.eye(x.dimension)) - if (newPar.isEmpty) - dst.bottom(newPar.dimension) - else - dst(newPar.low.toArray, newPar.high.toArray) - } - } - implicit object ParallelotopeRationalToBoxDouble extends DomainTransformation[ParallelotopeRationalDomain, BoxDoubleDomain] { - import breeze.linalg.DenseMatrix def apply(src: ParallelotopeRationalDomain, dst: BoxDoubleDomain): src.Property => dst.Property = { (x) => val newPar = x.rotate(DenseMatrix.eye(x.dimension)) if (newPar.isEmpty) dst.bottom(newPar.dimension) else - dst(newPar.low.toArray map (_.toDouble), newPar.high.toArray map (_.toDouble)) + dst(newPar.low.data map (_.toDouble), newPar.high.data map (_.toDouble)) } } implicit object ParallelotopeRationalToBoxRational extends DomainTransformation[ParallelotopeRationalDomain, BoxRationalDomain] { - import breeze.linalg.DenseMatrix def apply(src: ParallelotopeRationalDomain, dst: BoxRationalDomain): src.Property => dst.Property = { (x) => val newPar = x.rotate(DenseMatrix.eye(x.dimension)) if (newPar.isEmpty) dst.bottom(newPar.dimension) else - dst(newPar.low.toArray, newPar.high.toArray) - } - } - - implicit object BoxDoubleToParallelotope extends DomainTransformation[BoxDoubleDomain, ParallelotopeDomain] { - import breeze.linalg.{ DenseMatrix, DenseVector } - def apply(src: BoxDoubleDomain, dst: ParallelotopeDomain): src.Property => dst.Property = { (x) => - dst(DenseVector(x.low), DenseMatrix.eye(x.dimension), DenseVector(x.high)) + dst(newPar.low.data, newPar.high.data) } } implicit object BoxDoubleToParallelotopeRational extends DomainTransformation[BoxDoubleDomain, ParallelotopeRationalDomain] { - import breeze.linalg.{ DenseMatrix, DenseVector } def apply(src: BoxDoubleDomain, dst: ParallelotopeRationalDomain): src.Property => dst.Property = { (x) => - dst(DenseVector(x.low map { RationalExt(_) }), DenseMatrix.eye(x.dimension), DenseVector(x.high map { RationalExt(_) })) + dst(Bounds(x.low map { RationalExt(_) }), DenseMatrix.eye(x.dimension), Bounds(x.high map { RationalExt(_) })) } } implicit object BoxRationalToParallelotopeRational extends DomainTransformation[BoxRationalDomain, ParallelotopeRationalDomain] { - import breeze.linalg.{ DenseMatrix, DenseVector } - def apply(src: BoxRationalDomain, dst: ParallelotopeRationalDomain): src.Property => dst.Property = { (x) => - dst(DenseVector(x.low), DenseMatrix.eye(x.dimension), DenseVector(x.high)) + def apply(src: BoxRationalDomain, dst: ParallelotopeRationalDomain ): src.Property => dst.Property = { (x) => + dst(Bounds(x.low), DenseMatrix.eye(x.dimension), Bounds(x.high)) } } - implicit object ParallelotopeToParallelotope extends DomainTransformation[ParallelotopeDomain, ParallelotopeDomain] { - def apply(src: ParallelotopeDomain, dst: ParallelotopeDomain): src.Property => dst.Property = { (x) => new dst.Property(x.isEmpty, x.low, x.A, x.high) } - } - implicit object ParallelotopeRationalParallelotopeRational extends DomainTransformation[ParallelotopeRationalDomain, ParallelotopeRationalDomain] { def apply(src: ParallelotopeRationalDomain, dst: ParallelotopeRationalDomain): src.Property => dst.Property = { (x) => new dst.Property(x.isEmpty, x.low, x.A, x.high) } } diff --git a/core/src/main/scala/it/unich/jandom/domains/numerical/ParallelotopeDomain.scala b/core/src/main/scala/it/unich/jandom/domains/numerical/ParallelotopeDomain.scala deleted file mode 100644 index 2c1f90dd..00000000 --- a/core/src/main/scala/it/unich/jandom/domains/numerical/ParallelotopeDomain.scala +++ /dev/null @@ -1,824 +0,0 @@ -/** - * Copyright 2013, 2016 Gianluca Amato - * - * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains - * JANDOM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * JANDOM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of a - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with JANDOM. If not, see . - */ - -package it.unich.jandom.domains.numerical - -import scala.collection.mutable.ListBuffer -import scala.util.Try -import breeze.linalg._ -import it.unich.jandom.domains.CachedTopBottom -import it.unich.jandom.domains.WideningDescription -import it.unich.jandom.utils.breeze.countNonZero -import it.unich.jandom.utils.numberext.RationalExt - -/** - * This is the abstract domain of parallelotopes as appears in the NSAD 2012 paper. It is written - * using the Breeze Math library. It is not safe, due to rounding problem of arithmetic. - * - * @author Gianluca Amato - * @author Francesca Scozzari - */ -class ParallelotopeDomain private (favorAxes: Boolean) extends NumericalDomain { - val widenings = Seq(WideningDescription.default[Property]) - - /** - * Build a non-empty parallelotope. If the parallelotope is not empty, the result is undetermined. - * @param A is the constraint matrix. It should be invertible. - * @param low lower bounds. - * @param high higher bounds. - * @note `low` and `high` should have the same length. The matrix `A` should be invertible - * of the same size of the two vectors. - * @throws IllegalArgumentException if `low` and `high` are not of the same length, if `A` is not - * square or if `A` has not the same size of `low`. - */ - def apply(low: DenseVector[Double], A: DenseMatrix[Double], high: DenseVector[Double]): Property = { - val isEmpty = (0 until low.size) exists { i => low(i) > high(i) } - val isEmpty2 = (0 until low.size) exists { i => low(i).isInfinite() && low(i) == high(i) } - new Property(isEmpty || isEmpty2, low, A, high) - } - - /** - * @inheritdoc - * @note @inheritdoc - * @throws $ILLEGAL - */ - def top(n: Int): Property = { - val low = DenseVector.fill(n)(Double.NegativeInfinity) - val high = DenseVector.fill(n)(Double.PositiveInfinity) - val A = DenseMatrix.eye[Double](n) - // the full parallelotope of dimension 0 is not empty! - new Property(false, low, A, high) - } - - /** - * @inheritdoc - * @note @inheritdoc - * @throws $ILLEGAL - */ - def bottom(n: Int): Property = { - val low = DenseVector.fill(n)(1.0) - val high = DenseVector.fill(n)(0.0) - val A = DenseMatrix.eye[Double](n) - new Property(true, low, A, high) - } - - /** - * Given the box specified by `low` and `high` and the linear form `lf`, determines the pair - * of the least and greatest value of the linear form in the box. - * @param lf a linear form. - * @param low lower bound of the box. - * @param high higher bound of the box. - * @note `low`, `high` and `lf` should be of the same length. - * @return the least and greatest value of `lf` in the box determine by `low` and `high`. - */ - private def extremalsInBox(lf: DenseVector[Double], low: DenseVector[Double], high: DenseVector[Double]): (Double, Double) = { - var minc = 0.0 - var maxc = 0.0 - for (i <- 0 until lf.length) - if (lf(i) > 0) { - minc += lf(i) * low(i) - maxc += lf(i) * high(i) - } else if (lf(i) < 0) { - minc += lf(i) * high(i) - maxc += lf(i) * low(i) - } - (minc, maxc) - } - - /** - * Given a sequence of vectors of the same length `n`, returns a sequence of `n` indexes - * of vectors which are linearly independent. It is based on Gaussian elimination. - * @param m a sequence of vectors, all of the same length. - * @return a sequence of positions in m. - */ - private def pivoting(m: IndexedSeq[DenseVector[Double]]): Seq[Int] = { - val dimension = m(0).length - val indexes = ListBuffer[Int]() - val pivots = ListBuffer[(DenseVector[Double], Int)]() - var i = 0 - while (indexes.length < dimension) { - val row = m(i).copy - for (p <- pivots) row -= p._1 * row(p._2) - val col = (0 until row.length) find (row(_) != 0) - col match { - case Some(col) => - row /= row(col) - pivots.append(Tuple2(row, col)) - indexes.append(i) - case None => - } - i += 1 - } - indexes.toList - } - - /** - * This is an element of the parallelotope domain. - * - * @constructor Builds a parallelotope - * @param isEmpty is true if the parallelotope is empty. In this case, the other parameters are not relevant. - * @param A is the constraint matrix. It should be invertible. - * @param low lower bounds. - * @param high higher bounds. - * @note `low` and `high` should have the same length. The matrix `A` should be invertible - * of the same size of the two vectors. - * @throws IllegalArgumentException if `low` and `high` are not of the same length, if `A` is not - * square or if `A` has not the same size of `low`. - */ - final class Property( - val isEmpty: Boolean, - val low: DenseVector[Double], - val A: DenseMatrix[Double], - val high: DenseVector[Double]) - extends NumericalProperty[Property] { - - require(low.length == A.rows) - require(low.length == A.cols) - require(Try(A \ DenseMatrix.eye[Double](dimension)).isSuccess, s"The shape matrix ${A} is not invertible") - require(normalized) - - type Domain = ParallelotopeDomain - - def domain = ParallelotopeDomain.this - - private def normalized: Boolean = { - low.length == high.length && ( - (0 until low.length - 1) forall { i => - !low(i).isPosInfinity && - !high(i).isNegInfinity && - (low(i) <= high(i) || isEmpty) - }) - } - - /** - * @inheritdoc - * @note @inheritdoc - * @throws $ILLEGAL - */ - def widening(that: Property): Property = { - require(dimension == that.dimension) - if (isEmpty) - that - else { - val thatRotated = that.rotate(A) - val newlow = low.copy - val newhigh = high.copy - for (i <- 0 until dimension) { - if (thatRotated.low(i) < low(i)) newlow(i) = Double.NegativeInfinity - if (thatRotated.high(i) > high(i)) newhigh(i) = Double.PositiveInfinity - } - new Property(false, newlow, A, newhigh) - } - } - - /** - * @inheritdoc - * @note @inheritdoc - * @throws $ILLEGAL - */ - def narrowing(that: Property): Property = { - require(dimension == that.dimension) - if (that.isEmpty) { - that - } else if (this.isEmpty) { - this - } else { - val thatRotated = that.rotate(A) - val newlow = low.copy - val newhigh = high.copy - for (i <- 0 until dimension) { - if (low(i).isInfinity) newlow(i) = thatRotated.low(i) - if (high(i).isInfinity) newhigh(i) = thatRotated.high(i) - } - new Property(false, newlow, A, newhigh) - } - } - - /** - * @inheritdoc - * It is equivalent to `intersectionWeak`. - * @note @inheritdoc - * @throws $ILLEGAL - */ - def intersection(that: Property): Property = intersectionWeak(that) - - /** - * @inheritdoc - * The union of two parallelotopes is not a parallelotope. Moreover, there is no least - * parallelotopes containing the union of two parallelotopes. Hence, this methods uses - * heuristics to find a good result. - * @note @inheritdoc - * @throws $ILLEGAL - */ - def union(that: Property): Property = { - - /* - * A PrioritizedConstraint is a tuple `(a, m, M, p)` where `a` is a vector, `m` and `M` are - * reals and `p` is an integer, whose intended meaning is the constraint `m <= ax <= M` - * with a given priority `p`. - */ - type PrioritizedConstraint = (DenseVector[Double], Double, Double, Int) - - /* - * Given a linear form `v`, compute a prioritized constraint `(v,m,M,p)`. The parameter `ownedBy` - * tells whether the line form under consideration is one of the "native" forms of this (1) or - * that (2). This is used to refine priorities. - */ - def priority(v: DenseVector[Double], ownedBy: Int = 0): PrioritizedConstraint = { - val y1 = A.t \ v - val (l1, u1) = domain.extremalsInBox(y1, low, high) - val y2 = that.A.t \ v - val (l2, u2) = domain.extremalsInBox(y2, that.low, that.high) - val p = - if (l1 == l2 && l2 == u1 && u1 == u2) - 0 - else if (favorAxes && countNonZero(v) == 1) - 25 // previous value for test: 10 - else if (!l1.isInfinity && !l2.isInfinity && !u1.isInfinity && !u2.isInfinity) { - if (l1 == l2 && u1 == u2) - 10 - else if (l1 >= l2 && u1 <= u2) - if (ownedBy == 2) 20 else 30 - else if (l2 >= l1 && u2 <= u1) - if (ownedBy == 1) 20 else 30 - else if (l2 <= u1 && l2 >= l1 && u2 >= u1) - 30 - else if (l2 <= l1 && u2 >= l1 && u2 <= u1) - 30 - else 40 - } else if (l1 == l2 && !l1.isInfinity && !l2.isInfinity) - 50 - else if (u1 == u2 && !u1.isInfinity && !u2.isInfinity) - 50 - else if (!l1.isInfinity && !l2.isInfinity) - 60 - else if (!u1.isInfinity && !u2.isInfinity) - 60 - else 100 - (v, l1 min l2, u1 max u2, p) - } - - /* - * Determines whether `v1` and `v2` are linearly dependent. - * @return `None` if `v1` and `v2` are not linearly dependent, otherwise it is - * `Some(k)` such that `v1 = k * v2`. - */ - def linearDep(v1: DenseVector[Double], v2: DenseVector[Double]): Option[Double] = { - var i: Int = 0 - while (i < dimension && (v1(i) == 0 || v2(i) == 0)) i += 1 - if (i == dimension) - Option(1) - else if (v1 / v1(i) == v2 / v2(i)) - Option(v1(i) / v2(i)) - else - Option.empty - } - - /* - * The inversion join procedure. - * @param vi first vector - * @param vj second vector - * @param min1i least value of v1 in this - * @param min2i least value of v1 in that - * @param min1j least value of v2 in that - * @param min2j least value of v2 in that - * @return None if `v1` and `v2` do not form an inversion, otherwise it is `Some(v)` where `v` is the - * new linear form computed by the inversion procedure. - */ - def newConstraint(vi: DenseVector[Double], vj: DenseVector[Double], min1i: Double, min2i: Double, min1j: Double, min2j: Double): Option[DenseVector[Double]] = { - if (min1i.isInfinity || min2i.isInfinity || min1j.isInfinity || min2j.isInfinity) - Option.empty - else if (linearDep(vi, vj).isEmpty) - Option.empty - else { - val (deltai, deltaj) = if (min2j - min1j >= 0) (min1i - min2i, min2j - min1j) else (min2i - min1i, min1j - min2j) - if (deltai * deltaj > 0) - Option(-vi * deltaj - vj * deltai) - else - Option.empty - } - } - - require(dimension == that.dimension) - - // special cases - if (isEmpty) - that - else if (that.isEmpty) - this - else if (dimension == 0) - this - else { - val thisRotated = this.rotate(that.A) - val thatRotated = that.rotate(this.A) - val Q = scala.collection.mutable.ArrayBuffer[PrioritizedConstraint]() - - val bulk = DenseMatrix.vertcat(this.A, that.A) - val min1 = DenseVector.vertcat(this.low, thisRotated.low) - val min2 = DenseVector.vertcat(thatRotated.low, that.low) - val max1 = DenseVector.vertcat(this.high, thisRotated.high) - val max2 = DenseVector.vertcat(thatRotated.high, that.high) - - for (i <- 0 until dimension) Q += priority(this.A.t(::, i), 1) - for (i <- 0 until dimension) Q += priority(that.A.t(::, i), 2) - for (i <- 0 until dimension; j <- i + 1 until dimension) { - val v1 = bulk.t(::, i) - val v2 = bulk.t(::, j) - val nc1 = newConstraint(v1, v2, min1(i), min2(i), min1(j), min2(j)) - if (nc1.isDefined) Q += priority(nc1.get) - val nc2 = newConstraint(v1, -v2, min1(i), min2(i), -max1(j), -max2(j)) - if (nc2.isDefined) Q += priority(nc2.get) - val nc3 = newConstraint(-v1, -v2, -max1(i), -max2(i), -max1(j), -max2(j)) - if (nc3.isDefined) Q += priority(nc3.get) - val nc4 = newConstraint(-v1, v2, -max1(i), -max2(i), min1(j), min2(j)) - if (nc4.isDefined) Q += priority(nc4.get) - } - val Qsorted = Q.sortBy(_._4) - val pvt = domain.pivoting(Qsorted map (_._1)) - - val newA = DenseMatrix(pvt map (Qsorted(_)._1): _*) - val newlow = DenseVector(pvt map (Qsorted(_)._2): _*) - val newhigh = DenseVector(pvt map (Qsorted(_)._3): _*) - - new Property(false, newlow, newA, newhigh) - } - } - - /** - * This is a variant of `union` using weak join. The shape of the resulting - * parallelotope is the same shap of `this`. - * @param that the abstract object to be joined with `this`. - * @note $NOTEDIMENSION - * @return the weak union of the two abstract objects. - */ - def unionWeak(that: Property): Property = { - require(dimension == that.dimension) - if (isEmpty) - that - else if (that.isEmpty) - this - else { - val result = that.rotate(A) - for (i <- 0 until dimension) { - result.low(i) = result.low(i) min low(i) - result.high(i) = result.high(i) max high(i) - } - new Property(false, result.low, result.A, result.high) //this is to normalize - } - } - - /** - * This is the weak intersection of two abstract objects. The shape of the resulting - * parallelotope is the same shap of `this`. - * @param that the abstract object to be intersected with `this`. - * @note $NOTEDIMENSION - * @return the intersection of the two abstract objects. - */ - def intersectionWeak(that: Property): Property = { - require(dimension == that.dimension) - if (isEmpty) - this - else if (that.isEmpty) - that - else { - val result = that.rotate(A) - for (i <- 0 until dimension) { - result.low(i) = result.low(i) max low(i) - result.high(i) = result.high(i) min high(i) - } - if ((0 until result.low.length) exists { i => (result.low(i) > result.high(i)) }) - bottom - else - new Property(false, result.low, result.A, result.high) //this is to normalize - } - } - - /** - * @inheritdoc - * @note @inheritdoc - * @todo @inheritdoc - * @throws $ILLEGAL - */ - def linearAssignment(n: Int, lf: LinearForm): Property = { - require(n <= dimension && lf.dimension <= dimension) - val tcoeff = lf.homcoeffs map (_.toDouble) - val known = lf.known.toDouble - if (isEmpty) - this - else { - val coeff = DenseVector(tcoeff.padTo(dimension, 0.0): _*) - if (coeff(n) != 0) { - // invertible assignment - val increment = A(::, n) * known / coeff(n) - val newlow = low + increment - val newhigh = high + increment - // in the past we could use SparseVector instead of DenseVector, but this does not work anymore - val ei = DenseVector.zeros[Double](dimension) - ei(n) = 1 - val newA = A - (A(::, n) * (coeff - ei).t) / coeff(n) - new Property(false, newlow, newA, newhigh) - } else { - // non-invertible assignment - val newP = nonDeterministicAssignment(n) - val Aprime = newP.A.copy - val j = ((0 until Aprime.rows) find { Aprime(_, n) != 0 }).get - for (s <- 0 until dimension if Aprime(s, n) != 0 && s != j) - Aprime(s, ::) :-= Aprime(j, ::) * Aprime(s, n) / Aprime(j, n) - val ei = DenseVector.zeros[Double](dimension) - ei(n) = 1 - Aprime(j, ::) := (ei - coeff).t - val newlow = newP.low.copy - val newhigh = newP.high.copy - newlow(j) = known - newhigh(j) = known - new Property(false, newlow, Aprime, newhigh) - } - } - } - - private def dotprod(x: DenseVector[Double], y: DenseVector[Double], remove: Int = -1): Double = { - var sum: Double = 0 - for (i <- 0 until x.length if i != remove if x(i) != 0) sum = sum + x(i) * y(i) - sum - } - - /** - * @inheritdoc - * @note @inheritdoc - * @todo @inheritdoc - * @throws ILLEGAL - */ - def linearInequality(lf: LinearForm): Property = { - require(lf.dimension <= dimension) - if (isEmpty) - this - else if (dimension == 0) - if (lf.known > 0) - bottom - else - this - else { - val known = lf.known.toDouble - val coeffs = DenseVector(lf.homcoeffs map (_.toDouble) padTo (dimension, 0.0): _*) - val coeffsTransformed = A.t \ coeffs - - val removeCandidates = (0 until dimension) find { i => coeffsTransformed(i) != 0 && low(i).isInfinity && high(i).isInfinity } - removeCandidates match { - case None => { - val newlow = low.copy - val newhigh = high.copy - val (minc, maxc) = domain.extremalsInBox(coeffsTransformed, newlow, newhigh) - if (minc > -known) - bottom - else { - val lfArgmin = coeffsTransformed mapPairs { case (i, c) => if (c > 0) low(i) else high(i) } - val infinities = (0 until dimension) filter { i => lfArgmin(i).isInfinity && coeffsTransformed(i) != 0 } - infinities.size match { - case 0 => - for (i <- 0 until dimension) { - if (coeffsTransformed(i) > 0) newhigh(i) = high(i) min (lfArgmin(i) + (-known - minc) / coeffsTransformed(i)) - else if (coeffsTransformed(i) < 0) newlow(i) = low(i) max (lfArgmin(i) + (-known - minc) / coeffsTransformed(i)) - } - case 1 => { - val posinf = infinities.head - if (coeffsTransformed(posinf) < 0) - newlow(posinf) = low(posinf) max ((-dotprod(coeffsTransformed, lfArgmin, posinf) - known) / coeffsTransformed(posinf)) - else - newhigh(posinf) = high(posinf) min ((-dotprod(coeffsTransformed, lfArgmin, posinf) - known) / coeffsTransformed(posinf)) - } - case _ => - } - new Property(false, newlow, A, newhigh) - } - } - case Some(chosen) => { - // TODO: check.. I think this may generate non-invertible matrices - val newA = A.copy - val newhigh = high.copy - newA(chosen, ::) := coeffs.t - newhigh(chosen) = -known - new Property(false, low, newA, newhigh) - } - } - } - } - - /** - * @inheritdoc - * @note @inheritdoc - * @throws $ILLEGAL - */ - def linearDisequality(lf: LinearForm): Property = { - val tcoeff = lf.homcoeffs - val known = lf.known.toDouble - if (tcoeff.forall(_.isZero)) - if (known == 0) bottom else this - else { - val row = (0 until dimension).find(A(_, ::).t == DenseVector(tcoeff map { _.toDouble }: _*)) - row match { - case None => this - case Some(row) => - if (low(row) == known && high(row) == known) bottom else this - } - } - } - - /** - * @inheritdoc - * @note @inheritdoc - * @throws $ILLEGAL - */ - def nonDeterministicAssignment(n: Int): Property = { - require(n <= dimension) - if (isEmpty) - this - else { - val unsortedCandidates = (0 until dimension) filter { i => A(i, n) != 0 && (!low(i).isNegInfinity || !high(i).isPosInfinity) } - if (unsortedCandidates.isEmpty) - this - else { - // We prever to use as a pivot a simple constraint. Therefore, we order constraints by the number of - // non-zero coefficients. - val countNonZeroInRows = countNonZero(A(*, ::)) - val removeCandidates = unsortedCandidates.sortBy({ i => countNonZeroInRows(i) }) - val removeCandidatesEq = removeCandidates filter { i => low(i) == high(i) } - val removeCandidatesBounded = removeCandidates filter { i => !low(i).isInfinity && !high(i).isInfinity } - - val pivot = - if (!removeCandidatesEq.isEmpty) removeCandidatesEq.head - else if (!removeCandidatesBounded.isEmpty) removeCandidatesBounded.head - else removeCandidates.head - val rowPivot = A(pivot, ::) - - val newA = A.copy - val newlow = low.copy - val newhigh = high.copy - - for (i <- removeCandidates if i != pivot) { - val value1 = rowPivot(n) - val value2 = A(i, n) - val rowi = A(i, ::) - newA(i, ::) := rowPivot * value2 - rowi * value1 - val (minPivot, maxPivot) = if (A(i, n) < 0) (high(pivot), low(pivot)) else (low(pivot), high(pivot)) - val (mini, maxi) = if (-A(pivot, n) < 0) (high(i), low(i)) else (low(i), high(i)) - newlow(i) = minPivot * value2 - mini * value1 - newhigh(i) = maxPivot * value2 - maxi * value1 - } - newlow(pivot) = Double.NegativeInfinity - newhigh(pivot) = Double.PositiveInfinity - new Property(false, newlow, newA, newhigh) - } - } - } - - def addVariable(): Property = { - if (isEmpty) - ParallelotopeDomain.this.bottom(A.rows + 1) - else { - val e = DenseMatrix.zeros[Double](dimension + 1, 1) - e(dimension, 0) = 1.0 - val newA = DenseMatrix.horzcat(DenseMatrix.vertcat(A, DenseMatrix.zeros[Double](1, dimension)), e) - val newlow = DenseVector.vertcat(low, DenseVector(Double.NegativeInfinity)) - val newhigh = DenseVector.vertcat(high, DenseVector(Double.PositiveInfinity)) - new Property(false, newlow, newA, newhigh) - } - } - - def constraints = { - if (isEmpty) - Seq(LinearForm(1)) - else { - val set1 = for { - i <- 0 until dimension - if !low(i).isInfinity - } yield -LinearForm(-low(i) +: A(i, ::).t.toScalaVector: _*) - val set2 = for { - i <- 0 until dimension - if !high(i).isInfinity - } yield LinearForm(-high(i) +: A(i, ::).t.toScalaVector: _*) - set1 ++ set2 - } - } - - def isPolyhedral = true - - /** - * @inheritdoc - * @note @inheritdoc - * @throws $ILLEGAL - */ - def delVariable(n: Int): Property = { - def rowToSeq(M: DenseMatrix[Double], i: Int, n: Int): Seq[Double] = - for (j <- 0 until A.rows; if j != n) yield M(i, j) - - if (isEmpty) - ParallelotopeDomain.this.bottom(A.rows - 1) - else { - val forgot = this.nonDeterministicAssignment(n) - val set1 = for { - i <- 0 until dimension - if !forgot.low(i).isInfinity && forgot.A(i, n) == 0 - } yield -LinearForm(-forgot.low(i) +: rowToSeq(forgot.A, i, n): _*) - val set2 = for { - i <- 0 until dimension - if !forgot.high(i).isInfinity && forgot.A(i, n) == 0 - } yield LinearForm(-forgot.high(i) +: rowToSeq(forgot.A, i, n): _*) - - (set1 ++ set2).foldLeft(ParallelotopeDomain.this.top(A.rows - 1)) { (p, lf) => p.linearInequality(lf) } - } - } - - /** - * @inheritdoc - */ - def mapVariables(rho: Seq[Int]): Property = { - if (isEmpty) - this - else { - val slice = for (i <- 0 until dimension; j = rho.indexOf(i); if j != -1) yield j - val newA = A(slice, slice).toDenseMatrix - val newlow = low(slice).toDenseVector - val newhigh = high(slice).toDenseVector - new Property(false, newlow, newA, newhigh) - } - } - - /** - * Compute the minimum and maximum value of a linear form in a parallelotope. - * @todo should be generalized to linear forms over arbitrary types. - * @return a tuple with two components: the first component is the least value, the second component is the greatest value - * of the linear form over the box. - */ - def linearEvaluation(lf: LinearForm): (RationalExt, RationalExt) = { - val tcoeff = lf.homcoeffs - if (isEmpty && tcoeff.exists { !_.isZero }) - (RationalExt.PositiveInfinity, RationalExt.NegativeInfinity) - else if (dimension == 0) - (lf.known, lf.known) - else { - val vec = DenseVector(tcoeff map { _.toDouble } padTo (dimension, 0.0): _*) - val newvec = A.t \ vec - val (min, max) = domain.extremalsInBox(newvec, low, high) - (RationalExt(min) + lf.known, RationalExt(max) + lf.known) - } - } - - def minimize(lf: LinearForm) = linearEvaluation(lf)._1 - - def maximize(lf: LinearForm) = linearEvaluation(lf)._2 - - def frequency(lf: LinearForm) = { - val (min, max) = linearEvaluation(lf) - if (min == max) Option(min.value) else Option.empty - } - - def dimension = A.rows - - def isTop = low.forall(_.isNegInfinity) && high.forall(_.isPosInfinity) - - def isBottom = isEmpty - - def bottom = ParallelotopeDomain.this.bottom(dimension) - - def top = ParallelotopeDomain.this.top(dimension) - - def tryCompareTo[B >: Property](that: B)(implicit arg0: (B) => PartiallyOrdered[B]): Option[Int] = that match { - case that: Property => - val lte = this <= that - val gte = that <= this - if (lte && gte) - Option(0) - else if (lte) - Option(-1) - else if (gte) - Option(1) - else - Option.empty - case _ => Option.empty - } - - /** - * It computes the smallest parallelotope which contains `this` and is definable - * over a new shape matrix `Aprime`. - * @param Aprime the new shape matrix. - * @note `Aprime` should be an invertible matrix of the same dimension as `this`. - * @throws IllegalArgumentException if `Aprime` is not square or has not the correct dimension. - */ - def rotate(Aprime: DenseMatrix[Double]): Property = { - require(dimension == Aprime.rows && dimension == Aprime.cols) - if (isEmpty) - this - else { - val B = Aprime * (A \ DenseMatrix.eye[Double](dimension)) - val newlow = DenseVector.zeros[Double](dimension) - val newhigh = DenseVector.zeros[Double](dimension) - B.foreachPair { - case ((i, j), v) => - if (v > 0) { - newlow(i) += v * low(j) - newhigh(i) += v * high(j) - } else if (v < 0) { - newhigh(i) += v * low(j) - newlow(i) += v * high(j) - } - } - new Property(false, newlow, Aprime, newhigh) - } - } - - def <=[B >: Property](that: Property)(implicit arg0: (B) => PartiallyOrdered[B]): Boolean = { - if (isEmpty) - true - else if (that.isEmpty) - false - else if (that.isTop) - true - else { - val ptemp = this.rotate(that.A) - (0 until ptemp.low.length) forall { i => ptemp.low(i) >= that.low(i) && ptemp.high(i) <= that.high(i) } - } - } - - def >=[B >: Property](that: Property)(implicit arg0: (B) => PartiallyOrdered[B]): Boolean = - that <= this - - def <[B >: Property](that: Property)(implicit arg0: (B) => PartiallyOrdered[B]): Boolean = - (this <= that) && !(this >= that) - - def >[B >: Property](that: Property)(implicit arg0: (B) => PartiallyOrdered[B]): Boolean = - (this >= that) && !(this <= that) - - def mkString(vars: Seq[String]): String = { - - /* - * Returns a string representation of the linear form `lf`. - */ - def lfToString(lf: DenseVector[Double]): String = { - var first = true - val s = new StringBuilder - - for (index <- 0 until dimension) { - val coeff = lf(index) - val term = coeff match { - case 0 => "" - case 1 => vars(index) - case -1 => "-" + vars(index) - case c => c.toString + "*" + vars(index) - } - if (coeff != 0) { - if (first || coeff < 0) { - s ++= term - first = false - } else if (coeff != 0) - s ++= "+" + term - } - } - if (s.isEmpty) "0" else s.toString - } - - if (isEmpty) - "empty" - else { - val eqns = for (i <- 0 until dimension) yield { - if (low(i) < high(i)) - s"${if (low(i).isNegInfinity) "-∞" else low(i)} ≤ ${lfToString(A.t(::, i))} ≤ ${if (high(i).isPosInfinity) "+∞" else high(i)}" - else - s"${lfToString(A.t(::, i))} = ${high(i)}" - } - eqns.mkString("[ ", " , ", " ]") - } - } - } - -} - -/** - * Companion class for the parallelotope domain - */ -object ParallelotopeDomain { - private lazy val standard = new ParallelotopeDomain(false) with CachedTopBottom - private lazy val favoring = new ParallelotopeDomain(true) with CachedTopBottom - - /** - * Returns an abstract domain for parallelotopes. - * @param favorAxes determines whether the heuristics built into the domain should try to keep the variability - * along axes at the minimum. This is generally useful when the domain is one of the component of the sum - * combinator. - */ - def apply(favorAxes: Boolean = false) = if (favorAxes) favoring else standard -} diff --git a/core/src/main/scala/it/unich/jandom/domains/numerical/ParallelotopeRationalDomain.scala b/core/src/main/scala/it/unich/jandom/domains/numerical/ParallelotopeRationalDomain.scala index 5702635b..dfe73224 100644 --- a/core/src/main/scala/it/unich/jandom/domains/numerical/ParallelotopeRationalDomain.scala +++ b/core/src/main/scala/it/unich/jandom/domains/numerical/ParallelotopeRationalDomain.scala @@ -1,5 +1,5 @@ /** - * Copyright 2013, 2016 Jandom Team + * Copyright 2013, 2017 Jandom Team * * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains * JANDOM is free software: you can redistribute it and/or modify @@ -18,15 +18,12 @@ package it.unich.jandom.domains.numerical +import it.unich.jandom.domains.{CachedTopBottom, WideningDescription} +import it.unich.jandom.utils.numberext.{Bounds, DenseMatrix, DenseVector, RationalExt} +import spire.math.Rational + import scala.collection.mutable.ListBuffer import scala.util.Try -import breeze.linalg._ -import it.unich.jandom.domains.CachedTopBottom -import it.unich.jandom.domains.WideningDescription -import it.unich.jandom.utils.breeze.RationalForBreeze._ -import it.unich.jandom.utils.breeze.countNonZero -import it.unich.jandom.utils.numberext.RationalExt -import spire.math.Rational /** * This is the abstract domain of parallelotopes as appears in the NSAD 2012 paper. It is written @@ -40,7 +37,7 @@ import spire.math.Rational * @author Francesca Scozzari * @author Marco Rubino */ -class ParallelotopeRationalDomain private (favorAxis: Int) extends NumericalDomain { +class ParallelotopeRationalDomain private(favorAxis: Int) extends NumericalDomain { val widenings = Seq(WideningDescription.default[Property]) @@ -54,9 +51,9 @@ class ParallelotopeRationalDomain private (favorAxis: Int) extends NumericalDoma * @throws IllegalArgumentException if `low` and `high` are not of the same length, if `A` is not * square or if `A` has not the same size of `low`. */ - def apply(low: DenseVector[RationalExt], A: DenseMatrix[Rational], high: DenseVector[RationalExt]): Property = { - val isEmpty = (0 until low.size) exists { i => low(i) > high(i) } - val isEmpty2 = (0 until low.size) exists { i => low(i).isInfinity && low(i) == high(i) } + def apply(low: Bounds, A: DenseMatrix, high: Bounds): Property = { + val isEmpty = (0 until low.length) exists { i => low(i) > high(i) } + val isEmpty2 = (0 until low.length) exists { i => low(i).isInfinity && low(i) == high(i) } new Property(isEmpty || isEmpty2, low, A, high) } @@ -67,9 +64,9 @@ class ParallelotopeRationalDomain private (favorAxis: Int) extends NumericalDoma */ def top(n: Int): Property = { /* The full parallelotope of dimension 0 is not empty! */ - val low = DenseVector.fill(n)(RationalExt.NegativeInfinity) - val high = DenseVector.fill(n)(RationalExt.PositiveInfinity) - val A = DenseMatrix.eye[Rational](n) + val low = Bounds.fill(n)(RationalExt.NegativeInfinity) + val high = Bounds.fill(n)(RationalExt.PositiveInfinity) + val A = DenseMatrix.eye(n) new Property(false, low, A, high) } @@ -77,10 +74,10 @@ class ParallelotopeRationalDomain private (favorAxis: Int) extends NumericalDoma * Returns an full parallelotope whose shape is given by the matrix A. * @param A the shape matrix */ - def top(A: DenseMatrix[Rational]): Property = { + def top(A: DenseMatrix): Property = { val n = A.rows - val low = DenseVector.fill(n)(RationalExt.NegativeInfinity) - val high = DenseVector.fill(n)(RationalExt.PositiveInfinity) + val low = Bounds.fill(n)(RationalExt.NegativeInfinity) + val high = Bounds.fill(n)(RationalExt.PositiveInfinity) new Property(false, low, A, high) } @@ -90,9 +87,9 @@ class ParallelotopeRationalDomain private (favorAxis: Int) extends NumericalDoma * @throws $ILLEGAL */ def bottom(n: Int): Property = { - val low = DenseVector.fill(n)(RationalExt.one) - val high = DenseVector.fill(n)(RationalExt.zero) - val A = DenseMatrix.eye[Rational](n) + val low = Bounds.fill(n)(RationalExt.one) + val high = Bounds.fill(n)(RationalExt.zero) + val A = DenseMatrix.eye(n) new Property(true, low, A, high) } @@ -100,10 +97,10 @@ class ParallelotopeRationalDomain private (favorAxis: Int) extends NumericalDoma * Returns an empty parallelotope whose shape is given by the matrix A. * @param A the shape matrix */ - def bottom(A: DenseMatrix[Rational]): Property = { + def bottom(A: DenseMatrix): Property = { val n = A.rows - val low = DenseVector.fill(n)(RationalExt.one) - val high = DenseVector.fill(n)(RationalExt.zero) + val low = Bounds.fill(n)(RationalExt.one) + val high = Bounds.fill(n)(RationalExt.zero) new Property(true, low, A, high) } @@ -116,7 +113,7 @@ class ParallelotopeRationalDomain private (favorAxis: Int) extends NumericalDoma * @note `low`, `high` and `lf` should be of the same length. * @return the least and greatest value of `lf` in the box determine by `low` and `high`. */ - private def extremalsInBox(lf: DenseVector[Rational], low: DenseVector[RationalExt], high: DenseVector[RationalExt]): (RationalExt, RationalExt) = { + private def extremalsInBox(lf: DenseVector, low: Bounds, high: Bounds): (RationalExt, RationalExt) = { var minc = RationalExt.zero var maxc = RationalExt.zero for (i <- 0 until lf.length) @@ -136,10 +133,10 @@ class ParallelotopeRationalDomain private (favorAxis: Int) extends NumericalDoma * @param m a sequence of vectors, all of the same length. * @return a sequence of positions in m. */ - private def pivoting(m: IndexedSeq[DenseVector[Rational]]): List[Int] = { + private def pivoting(m: IndexedSeq[DenseVector]): List[Int] = { val dimension = m(0).length val indexes = ListBuffer[Int]() - val pivots = ListBuffer[(DenseVector[Rational], Int)]() + val pivots = ListBuffer[(DenseVector, Int)]() var i = 0 while (indexes.length < dimension) { val row = m(i).copy @@ -172,14 +169,14 @@ class ParallelotopeRationalDomain private (favorAxis: Int) extends NumericalDoma */ final class Property( val isEmpty: Boolean, - val low: DenseVector[RationalExt], - val A: DenseMatrix[Rational], - val high: DenseVector[RationalExt]) + val low: Bounds, + val A: DenseMatrix, + val high: Bounds) extends NumericalProperty[Property] { require(low.length == A.rows) require(low.length == A.cols) - require(Try(A \ DenseMatrix.eye[Rational](dimension)).isSuccess, s"The shape matrix ${A} is not invertible") + require(Try(A \ DenseMatrix.eye(dimension)).isSuccess, s"The shape matrix ${A} is not invertible") require(normalized) type Domain = ParallelotopeRationalDomain @@ -281,23 +278,23 @@ class ParallelotopeRationalDomain private (favorAxis: Int) extends NumericalDoma * rational and `p` is an integer, whose intended meaning is the constraint `m <= ax <= M` * with a given priority `p`. */ - type PrioritizedConstraint = (DenseVector[Rational], RationalExt, RationalExt, Int) + type PrioritizedConstraint = (DenseVector, RationalExt, RationalExt, Int) /* * Given a linear form `v`, compute a prioritized constraint `(v,m,M,p)`. The parameter `ownedBy` * tells whether the line form under consideration is one of the "native" forms of this (1) or * that (2). This is used to refine priorities. */ - def priority(v: DenseVector[Rational], ownedBy: Int = 0): PrioritizedConstraint = { + def priority(v: DenseVector, ownedBy: Int = 0): PrioritizedConstraint = { val y1 = A.t \ v val (l1, u1) = domain.extremalsInBox(y1, low, high) val y2 = that.A.t \ v val (l2, u2) = domain.extremalsInBox(y2, that.low, that.high) val p = - if (favorAxis == 1 && countNonZero(v) == 1) // favorAxes + if (favorAxis == 1 && v.countNonZero == 1) // favorAxes 0 - else if (favorAxis == -1 && countNonZero(v) == 1) // not favorAxes + else if (favorAxis == -1 && v.countNonZero == 1) // not favorAxes 101 else if (l1 == l2 && l2 == u1 && u1 == u2) /// if nothing choose axes 1 @@ -332,7 +329,7 @@ class ParallelotopeRationalDomain private (favorAxis: Int) extends NumericalDoma * @return `None` if `v1` and `v2` are not linearly dependent, otherwise it is * `Some(k)` such that `v1 = k * v2`. */ - def linearDep(v1: DenseVector[Rational], v2: DenseVector[Rational]): Option[Rational] = { + def linearDep(v1: DenseVector, v2: DenseVector): Option[Rational] = { var i: Int = 0 while (i < dimension && (v1(i).isZero || v2(i).isZero)) i += 1 if (i == dimension) @@ -354,7 +351,7 @@ class ParallelotopeRationalDomain private (favorAxis: Int) extends NumericalDoma * @return None if `v1` and `v2` do not form an inversion, otherwise it is `Some(v)` where `v` is the * new linear form computed by the inversion procedure. */ - def newConstraint(vi: DenseVector[Rational], vj: DenseVector[Rational], min1i: RationalExt, min2i: RationalExt, min1j: RationalExt, min2j: RationalExt): Option[DenseVector[Rational]] = { + def newConstraint(vi: DenseVector, vj: DenseVector, min1i: RationalExt, min2i: RationalExt, min1j: RationalExt, min2j: RationalExt): Option[DenseVector] = { if (min1i.isInfinity || min2i.isInfinity || min1j.isInfinity || min2j.isInfinity) Option.empty else if (linearDep(vi, vj).isEmpty) @@ -385,16 +382,16 @@ class ParallelotopeRationalDomain private (favorAxis: Int) extends NumericalDoma val thatRotated = that.rotate(this.A) val Q = scala.collection.mutable.ArrayBuffer[PrioritizedConstraint]() - val bulk = DenseMatrix.vertcat(this.A, that.A) - val min1 = DenseVector.vertcat(this.low, thisRotated.low) - val min2 = DenseVector.vertcat(thatRotated.low, that.low) - val max1 = DenseVector.vertcat(this.high, thisRotated.high) - val max2 = DenseVector.vertcat(thatRotated.high, that.high) - for (i <- 0 until dimension) Q += priority(this.A.t(::, i), 1) - for (i <- 0 until dimension) Q += priority(that.A.t(::, i), 2) + val bulk = this.A vertcat that.A + val min1 = this.low vertcat thisRotated.low + val min2 = thatRotated.low vertcat that.low + val max1 = this.high vertcat thisRotated.high + val max2 = thatRotated.high vertcat that.high + for (i <- 0 until dimension) Q += priority(this.A.row(i), 1) + for (i <- 0 until dimension) Q += priority(that.A.row(i), 2) for (i <- 0 until dimension; j <- i + 1 until dimension) { - val v1 = bulk.t(::, i) - val v2 = bulk.t(::, j) + val v1 = bulk.row(i) + val v2 = bulk.row(j) val nc1 = newConstraint(v1, v2, min1(i), min2(i), min1(j), min2(j)) if (nc1.isDefined) Q += priority(nc1.get) @@ -404,14 +401,13 @@ class ParallelotopeRationalDomain private (favorAxis: Int) extends NumericalDoma if (nc3.isDefined) Q += priority(nc3.get) val nc4 = newConstraint(-v1, v2, -max1(i), -max2(i), min1(j), min2(j)) if (nc4.isDefined) Q += priority(nc4.get) - } val Qsorted = Q.sortBy(_._4) val pvt = domain.pivoting(Qsorted map (_._1)) val newA = DenseMatrix(pvt map (Qsorted(_)._1): _*) - val newlow = DenseVector(pvt map (Qsorted(_)._2): _*) - val newhigh = DenseVector(pvt map (Qsorted(_)._3): _*) + val newlow = Bounds(pvt map (Qsorted(_)._2): _*) + val newhigh = Bounds(pvt map (Qsorted(_)._3): _*) new Property(false, newlow, newA, newhigh) } @@ -479,10 +475,10 @@ class ParallelotopeRationalDomain private (favorAxis: Int) extends NumericalDoma if (isEmpty) this else { - val coeff = DenseVector(tcoeff.padTo(dimension, Rational.zero) :_*) - if (coeff(n) != Rational.zero) { + val coeff = DenseVector(tcoeff.padTo(dimension, Rational.zero): _*) + if (! coeff(n).isZero) { // invertible assignment - val increment = A(::, n) * known / coeff(n) + val increment = A.col(n) * known / coeff(n) val newlow = low.copy val newhigh = high.copy // cannot use Breeze here since they are RationalExt @@ -490,9 +486,9 @@ class ParallelotopeRationalDomain private (favorAxis: Int) extends NumericalDoma newlow(i) += increment(i) newhigh(i) += increment(i) } - val ei = DenseVector.zeros[Rational](dimension) + val ei = DenseVector.zeros(dimension) ei(n) = Rational.one - val newA = A - (A(::, n) * (coeff - ei).t) / coeff(n) + val newA = A - (A.col(n) * (coeff - ei).t) / coeff(n) new Property(false, newlow, newA, newhigh) } else { @@ -501,10 +497,10 @@ class ParallelotopeRationalDomain private (favorAxis: Int) extends NumericalDoma val Aprime = newP.A.copy val j = ((0 until Aprime.rows) find { !Aprime(_, n).isZero }).get for (s <- 0 until dimension if !Aprime(s, n).isZero && s != j) - Aprime(s, ::) :-= Aprime(j, ::) * (Aprime(s, n) / Aprime(j, n)) - val ei = DenseVector.zeros[Rational](dimension) + Aprime.rowUpdate(s, Aprime.row(s) - Aprime.row(j) * (Aprime(s, n) / Aprime(j, n))) + val ei = DenseVector.zeros(dimension) ei(n) = Rational.one - Aprime(j, ::) := (ei - coeff).t + Aprime.rowUpdate(j, ei - coeff) val newlow = newP.low.copy val newhigh = newP.high.copy newlow(j) = known @@ -519,7 +515,7 @@ class ParallelotopeRationalDomain private (favorAxis: Int) extends NumericalDoma * Computes the dot product of `x` and `y` with the proviso that if `x` is zero, then `x*y` * is zero even when `y` is an infinite value (which is not the standard behaviour). */ - private def dotprod(x: DenseVector[Rational], y: DenseVector[RationalExt], remove: Int = -1): RationalExt = { + private def dotprod(x: DenseVector, y: Bounds, remove: Int = -1): RationalExt = { var sum = RationalExt.zero for (i <- 0 until x.length if i != remove if x(i) != Rational.zero) sum = sum + y(i) * x(i) sum @@ -581,7 +577,7 @@ class ParallelotopeRationalDomain private (favorAxis: Int) extends NumericalDoma // TODO: check.. I think this may generate non-invertible matrices val newA = A.copy val newhigh = high.copy - newA(chosen, ::) := coeffs.t + newA.rowUpdate(chosen, coeffs) newhigh(chosen) = -known new Property(false, low, newA, newhigh) } @@ -597,13 +593,16 @@ class ParallelotopeRationalDomain private (favorAxis: Int) extends NumericalDoma def linearDisequality(lf: LinearForm): Property = { val tcoeff = lf.homcoeffs val known = lf.known - if (tcoeff.forall(_ == Rational.zero)) - if (known == Rational.zero) bottom else this - else { + if (tcoeff.forall(_.isZero)) { + if (known.isZero) + bottom + else + this + } else { val row = (0 until dimension).find { (r) => - val v1 = A(r, ::).t - val v2 = DenseVector[Rational](tcoeff: _*) - v1 == v2 + val v1 = A.row(r) + val v2 = DenseVector(tcoeff: _*) + v1.data sameElements v2.data } row match { case None => this @@ -629,7 +628,7 @@ class ParallelotopeRationalDomain private (favorAxis: Int) extends NumericalDoma else { // We prever to use as a pivot a simple constraint. Therefore, we order constraints by the number of // non-zero coefficients. - val countNonZeroInRows = countNonZero(A(*, ::)) + val countNonZeroInRows = A.countNonZeroInRows val removeCandidates = unsortedCandidates.sortBy({ i => countNonZeroInRows(i) }) val removeCandidatesEq = removeCandidates filter { i => low(i) == high(i) } val removeCandidatesBounded = removeCandidates filter { i => !low(i).isInfinity && !high(i).isInfinity } @@ -638,7 +637,7 @@ class ParallelotopeRationalDomain private (favorAxis: Int) extends NumericalDoma if (!removeCandidatesEq.isEmpty) removeCandidatesEq.head else if (!removeCandidatesBounded.isEmpty) removeCandidatesBounded.head else removeCandidates.head - val rowPivot = A(pivot, ::) + val rowPivot = A.row(pivot) val newA = A.copy val newlow = low.copy @@ -647,8 +646,8 @@ class ParallelotopeRationalDomain private (favorAxis: Int) extends NumericalDoma for (i <- removeCandidates if i != pivot) { val value1 = rowPivot(n) val value2 = A(i, n) - val rowi = A(i, ::) - newA(i, ::) := rowPivot * value2 - rowi * value1 + val rowi = A.row(i) + newA.rowUpdate(i, rowPivot * value2 - rowi * value1) val (minPivot, maxPivot) = if (A(i, n) < Rational.zero) (high(pivot), low(pivot)) else (low(pivot), high(pivot)) val (mini, maxi) = if (-A(pivot, n) < Rational.zero) (high(i), low(i)) else (low(i), high(i)) newlow(i) = minPivot * value2 - mini * value1 @@ -663,13 +662,13 @@ class ParallelotopeRationalDomain private (favorAxis: Int) extends NumericalDoma def addVariable(): Property = { if (isEmpty) - ParallelotopeRationalDomain.this.bottom(A.rows + 1) + ParallelotopeRationalDomain.this.bottom(dimension + 1) else { - val e = DenseMatrix.zeros[Rational](dimension + 1, 1) + val e = DenseMatrix.zeros(dimension + 1, 1) e(dimension, 0) = Rational.one - val newA = DenseMatrix.horzcat(DenseMatrix.vertcat(A, DenseMatrix.zeros[Rational](1, dimension)), e) - val newlow = DenseVector.vertcat(low, DenseVector(RationalExt.NegativeInfinity)) - val newhigh = DenseVector.vertcat(high, DenseVector(RationalExt.PositiveInfinity)) + val newA = (A vertcat DenseMatrix.zeros(1, dimension)) horzcat e + val newlow = low vertcat Bounds(RationalExt.NegativeInfinity) + val newhigh = high vertcat Bounds(RationalExt.PositiveInfinity) new Property(false, newlow, newA, newhigh) } @@ -679,8 +678,8 @@ class ParallelotopeRationalDomain private (favorAxis: Int) extends NumericalDoma if (isEmpty) Seq(LinearForm(1)) else { - val set1 = for (i <- 0 until dimension; if !low(i).isInfinity) yield -LinearForm(-low(i).value +: A(i, ::).t.toScalaVector: _*) - val set2 = for (i <- 0 until dimension; if !high(i).isInfinity) yield LinearForm(-high(i).value +: A(i, ::).t.toScalaVector: _*) + val set1 = for (i <- 0 until dimension; if !low(i).isInfinity) yield -LinearForm(-low(i).value +: A.row(i).toScalaVector: _*) + val set2 = for (i <- 0 until dimension; if !high(i).isInfinity) yield LinearForm(-high(i).value +: A.row(i).toScalaVector: _*) set1 ++ set2 } } @@ -693,7 +692,7 @@ class ParallelotopeRationalDomain private (favorAxis: Int) extends NumericalDoma * @throws $ILLEGAL */ def delVariable(n: Int): Property = { - def rowToSeq(M: DenseMatrix[Rational], i: Int, n: Int): Seq[Rational] = + def rowToSeq(M: DenseMatrix, i: Int, n: Int): Seq[Rational] = for (j <- 0 until A.rows; if j != n) yield M(i, j) if (isEmpty) @@ -714,9 +713,9 @@ class ParallelotopeRationalDomain private (favorAxis: Int) extends NumericalDoma this else { val slice = for (i <- 0 until dimension; j = rho.indexOf(i); if j != -1) yield j - val newA = A(slice, slice).toDenseMatrix - val newlow = low(slice).toDenseVector - val newhigh = high(slice).toDenseVector + val newA = A(slice, slice) + val newlow = low(slice) + val newhigh = high(slice) new Property(false, newlow, newA, newhigh) } @@ -736,7 +735,7 @@ class ParallelotopeRationalDomain private (favorAxis: Int) extends NumericalDoma (lf.known, lf.known) else { val coeff = tcoeff.padTo(dimension, Rational.zero).toArray - val vec = DenseVector(coeff) + val vec = new DenseVector(coeff) val newvec = A.t \ vec val (min, max) = domain.extremalsInBox(newvec, low, high) (min + lf.known, max + lf.known) @@ -784,14 +783,14 @@ class ParallelotopeRationalDomain private (favorAxis: Int) extends NumericalDoma * @note `Aprime` should be an invertible matrix of the same dimension as `this`. * @throws IllegalArgumentException if `Aprime` is not square or has not the correct dimension. */ - def rotate(Aprime: DenseMatrix[Rational]): Property = { + def rotate(Aprime: DenseMatrix): Property = { require(dimension == Aprime.rows && dimension == Aprime.cols) if (isEmpty) this else { - val B = Aprime * (A \ DenseMatrix.eye[Rational](dimension)) - val newlow = DenseVector.fill(dimension)(RationalExt.zero) - val newhigh = DenseVector.fill(dimension)(RationalExt.zero) + val B = Aprime * (A \ DenseMatrix.eye(dimension)) + val newlow = Bounds.fill(dimension)(RationalExt.zero) + val newhigh = Bounds.fill(dimension)(RationalExt.zero) B.foreachPair { case ((i, j), v) => if (v > Rational.zero) { @@ -833,7 +832,7 @@ class ParallelotopeRationalDomain private (favorAxis: Int) extends NumericalDoma /* * Returns a string representation of the linear form `lf`. */ - def lfToString(lf: DenseVector[Rational]): String = { + def lfToString(lf: DenseVector): String = { var first = true val s = new StringBuilder val minusOne = -Rational.one @@ -862,9 +861,9 @@ class ParallelotopeRationalDomain private (favorAxis: Int) extends NumericalDoma else { val eqns = for (i <- 0 until dimension) yield { if (low(i) < high(i)) - s"${if (low(i).isNegInfinity) "-∞" else low(i)} ≤ ${lfToString(A.t(::, i))} ≤ ${if (high(i).isPosInfinity) "+∞" else high(i)}" + s"${if (low(i).isNegInfinity) "-∞" else low(i)} ≤ ${lfToString(A.col(i))} ≤ ${if (high(i).isPosInfinity) "+∞" else high(i)}" else - s"${lfToString(A.t(::, i))} = ${high(i)}" + s"${lfToString(A.col(i))} = ${high(i)}" } eqns.mkString("[ ", " , ", " ]") } diff --git a/core/src/main/scala/it/unich/jandom/domains/numerical/ParallelotopeRationalDomainFast.scala b/core/src/main/scala/it/unich/jandom/domains/numerical/ParallelotopeRationalDomainFast.scala deleted file mode 100644 index 67e9e8be..00000000 --- a/core/src/main/scala/it/unich/jandom/domains/numerical/ParallelotopeRationalDomainFast.scala +++ /dev/null @@ -1,894 +0,0 @@ -/** - * Copyright 2013, 2017 Jandom Team - * - * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains - * JANDOM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * JANDOM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of a - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with JANDOM. If not, see . - */ - -package it.unich.jandom.domains.numerical - -import it.unich.jandom.domains.{CachedTopBottom, WideningDescription} -import it.unich.jandom.utils.numberext.{Bounds, DenseMatrix, DenseVector, RationalExt} -import spire.math.Rational - -import scala.collection.mutable.ListBuffer -import scala.util.Try - -/** - * This is the abstract domain of parallelotopes as appears in the NSAD 2012 paper. It is written - * using the Breeze Math library and uses rational numbers. - * - * @param favorAxis determines whether the heuristics built into the domain should try to keep constraints - * corresponding to Cartesian axis. If `favorAxis` is `1`, axis are favorite. The opposite happens when favorAxis - * is `-1`. If `favorAxis` is `0`, axis are considered like all the other constraints - * - * @author Gianluca Amato - * @author Francesca Scozzari - * @author Marco Rubino - */ -class ParallelotopeRationalDomainFast private (favorAxis: Int) extends NumericalDomain { - - val widenings = Seq(WideningDescription.default[Property]) - - /** - * Build a non-empty parallelotope. If the parallelotope is not empty, the result is undetermined. - * @param A is the constraint matrix. It should be invertible. - * @param low lower bounds. - * @param high higher bounds. - * @note `low` and `high` should have the same length. The matrix `A` should be invertiible - * of the same size of the two vectors. - * @throws IllegalArgumentException if `low` and `high` are not of the same length, if `A` is not - * square or if `A` has not the same size of `low`. - */ - def apply(low: Bounds, A: DenseMatrix, high: Bounds): Property = { - val isEmpty = (0 until low.length) exists { i => low(i) > high(i) } - val isEmpty2 = (0 until low.length) exists { i => low(i).isInfinity && low(i) == high(i) } - new Property(isEmpty || isEmpty2, low, A, high) - } - - /** - * @inheritdoc - * @note @inheritdoc - * @throws $ILLEGAL - */ - def top(n: Int): Property = { - /* The full parallelotope of dimension 0 is not empty! */ - val low = Bounds.fill(n)(RationalExt.NegativeInfinity) - val high = Bounds.fill(n)(RationalExt.PositiveInfinity) - val A = DenseMatrix.eye(n) - new Property(false, low, A, high) - } - - /** - * Returns an full parallelotope whose shape is given by the matrix A. - * @param A the shape matrix - */ - def top(A: DenseMatrix): Property = { - val n = A.rows - val low = Bounds.fill(n)(RationalExt.NegativeInfinity) - val high = Bounds.fill(n)(RationalExt.PositiveInfinity) - new Property(false, low, A, high) - } - - /** - * @inheritdoc - * @note @inheritdoc - * @throws $ILLEGAL - */ - def bottom(n: Int): Property = { - val low = Bounds.fill(n)(RationalExt.one) - val high = Bounds.fill(n)(RationalExt.zero) - val A = DenseMatrix.eye(n) - new Property(true, low, A, high) - } - - /** - * Returns an empty parallelotope whose shape is given by the matrix A. - * @param A the shape matrix - */ - def bottom(A: DenseMatrix): Property = { - val n = A.rows - val low = Bounds.fill(n)(RationalExt.one) - val high = Bounds.fill(n)(RationalExt.zero) - new Property(true, low, A, high) - } - - /** - * Given the box specified by `low` and `high` and the linear form `lf`, determines the pair - * of the least and greatest value of the linear form in the box. - * @param lf a linear form. - * @param low lower bound of the box. - * @param high higher bound of the box. - * @note `low`, `high` and `lf` should be of the same length. - * @return the least and greatest value of `lf` in the box determine by `low` and `high`. - */ - private def extremalsInBox(lf: DenseVector, low: Bounds, high: Bounds): (RationalExt, RationalExt) = { - var minc = RationalExt.zero - var maxc = RationalExt.zero - for (i <- 0 until lf.length) - if (lf(i) > Rational.zero) { - minc += low(i) * lf(i) - maxc += high(i) * lf(i) - } else if (lf(i) < Rational.zero) { - minc += high(i) * lf(i) - maxc += low(i) * lf(i) - } - (minc, maxc) - } - - /** - * Given a sequence of vectors of the same length `n`, returns a sequence of `n` indexes - * of vectors which are linearly independent. It is based on Gaussian elimination. - * @param m a sequence of vectors, all of the same length. - * @return a sequence of positions in m. - */ - private def pivoting(m: IndexedSeq[DenseVector]): List[Int] = { - val dimension = m(0).length - val indexes = ListBuffer[Int]() - val pivots = ListBuffer[(DenseVector, Int)]() - var i = 0 - while (indexes.length < dimension) { - val row = m(i).copy - for (p <- pivots) row -= p._1 * row(p._2) - val col = (0 until row.length) find (!row(_).isZero) - col match { - case Some(col) => - row /= row(col) - pivots.append(Tuple2(row, col)) - indexes.append(i) - case None => - } - i += 1 - } - indexes.toList - } - - /** - * This is an element of the parallelotope domain. - * - * @constructor Builds a parallelotope - * @param isEmpty is true if the parallelotope is empty. In this case, the other parameters are not relevant. - * @param A is the constraint matrix. It should be invertible. - * @param low lower bounds. - * @param high higher bounds. - * @note `low` and `high` should have the same length. The matrix `A` should be invertible - * of the same size of the two vectors. - * @throws IllegalArgumentException if `low` and `high` are not of the same length, if `A` is not - * square or if `A` has not the same size of `low`. - */ - final class Property( - val isEmpty: Boolean, - val low: Bounds, - val A: DenseMatrix, - val high: Bounds) - extends NumericalProperty[Property] { - - require(low.length == A.rows) - require(low.length == A.cols) - require(Try(A \ DenseMatrix.eye(dimension)).isSuccess, s"The shape matrix ${A} is not invertible") - require(normalized) - - type Domain = ParallelotopeRationalDomainFast - - def domain = ParallelotopeRationalDomainFast.this - - private def normalized: Boolean = { - (isEmpty || (low.length == high.length && ( - (0 until low.length - 1) forall { i => - !low(i).isPosInfinity && - !high(i).isNegInfinity && - (low(i) <= high(i)) - }))) - } - - /** - * @inheritdoc - * @note @inheritdoc - * @throws $ILLEGAL - */ - def widening(that: Property): Property = { - require(dimension == that.dimension) - if (isEmpty) - that - else { - val thatRotated = that.rotate(A) - val thisRotated = this.rotate(that.A) - if (thisRotated < that) { - val newlow = thisRotated.low.copy - val newhigh = thisRotated.high.copy - for (i <- 0 to dimension - 1) { - if (thisRotated.low(i) > that.low(i)) newlow(i) = RationalExt.NegativeInfinity - if (thisRotated.high(i) < that.high(i)) newhigh(i) = RationalExt.PositiveInfinity - } - new Property(false, newlow, that.A, newhigh) - } else { - val newlow = low.copy - val newhigh = high.copy - for (i <- 0 to dimension - 1) { - if (thatRotated.low(i) < low(i)) newlow(i) = RationalExt.NegativeInfinity - if (thatRotated.high(i) > high(i)) newhigh(i) = RationalExt.PositiveInfinity - - } - new Property(false, newlow, A, newhigh) - } - } - } - - /** - * @inheritdoc - * @note @inheritdoc - * @throws $ILLEGAL - */ - def narrowing(that: Property): Property = { - require(dimension == that.dimension) - if (that.isEmpty) { - that - } else if (this.isEmpty) { - this - } else { - val thatRotated = that.rotate(A) - val newlow = low.copy - val newhigh = high.copy - for (i <- 0 to dimension - 1) { - if (low(i).isInfinity) newlow(i) = thatRotated.low(i) - if (high(i).isInfinity) newhigh(i) = thatRotated.high(i) - } - new Property(false, newlow, A, newhigh) - } - } - - /** - * @inheritdoc - * It is equivalent to `intersectionWeak`. - * @note @inheritdoc - * @throws $ILLEGAL - */ - def intersection(that: Property): Property = { - if (that.isEmpty) - that - else if (this.isTop) - that - else - intersectionWeak(that) - } - - /** - * @inheritdoc - * The union of two parallelotopes is not a parallelotope. Moreover, there is no least - * parallelotopes containing the union of two parallelotopes. Hence, this methods uses - * heuristics to find a good result. - * @note @inheritdoc - * @throws $ILLEGAL - */ - def union(that: Property): Property = { - - /* - * A PrioritizedConstraint is a tuple `(a, m, M, p)` where `a` is a vector, `m` and `M` are - * rational and `p` is an integer, whose intended meaning is the constraint `m <= ax <= M` - * with a given priority `p`. - */ - type PrioritizedConstraint = (DenseVector, RationalExt, RationalExt, Int) - - /* - * Given a linear form `v`, compute a prioritized constraint `(v,m,M,p)`. The parameter `ownedBy` - * tells whether the line form under consideration is one of the "native" forms of this (1) or - * that (2). This is used to refine priorities. - */ - def priority(v: DenseVector, ownedBy: Int = 0): PrioritizedConstraint = { - val y1 = A.t \ v - val (l1, u1) = domain.extremalsInBox(y1, low, high) - val y2 = that.A.t \ v - val (l2, u2) = domain.extremalsInBox(y2, that.low, that.high) - - val p = - if (favorAxis == 1 && v.countNonZero == 1) // favorAxes - 0 - else if (favorAxis == -1 && v.countNonZero == 1) // not favorAxes - 101 - else if (l1 == l2 && l2 == u1 && u1 == u2) /// if nothing choose axes - 1 - else if (!l1.isInfinity && !l2.isInfinity && !u1.isInfinity && !u2.isInfinity) { - if (l1 == l2 && u1 == u2) - 10 - else if (l1 >= l2 && u1 <= u2) - if (ownedBy == 2) 20 else 30 - else if (l2 >= l1 && u2 <= u1) - if (ownedBy == 1) 20 else 30 - else if (l2 <= u1 && l2 >= l1 && u2 >= u1) - 30 - else if (l2 <= l1 && u2 >= l1 && u2 <= u1) - 30 - else 40 - } else if (l1 == l2 && !l1.isInfinity && !l2.isInfinity) - 50 - else if (u1 == u2 && !u1.isInfinity && !u2.isInfinity) - 50 - else if (!l1.isInfinity && !l2.isInfinity) - 60 - else if (!u1.isInfinity && !u2.isInfinity) - 60 - else - 100 - - (v, l1 min l2, u1 max u2, p) - } - - /* - * Determines whether `v1` and `v2` are linearly dependent. - * @return `None` if `v1` and `v2` are not linearly dependent, otherwise it is - * `Some(k)` such that `v1 = k * v2`. - */ - def linearDep(v1: DenseVector, v2: DenseVector): Option[Rational] = { - var i: Int = 0 - while (i < dimension && (v1(i).isZero || v2(i).isZero)) i += 1 - if (i == dimension) - Option(Rational.one) - else if (v1 / v1(i) == v2 / v2(i)) - Option(v1(i) / v2(i)) - else - Option.empty - } - - /* - * The inversion join procedure. - * @param vi first vector - * @param vj second vector - * @param min1i least value of v1 in this - * @param min2i least value of v1 in that - * @param min1j least value of v2 in that - * @param min2j least value of v2 in that - * @return None if `v1` and `v2` do not form an inversion, otherwise it is `Some(v)` where `v` is the - * new linear form computed by the inversion procedure. - */ - def newConstraint(vi: DenseVector, vj: DenseVector, min1i: RationalExt, min2i: RationalExt, min1j: RationalExt, min2j: RationalExt): Option[DenseVector] = { - if (min1i.isInfinity || min2i.isInfinity || min1j.isInfinity || min2j.isInfinity) - Option.empty - else if (linearDep(vi, vj).isEmpty) - Option.empty - else { - val (deltai, deltaj) = if (min2j.value - min1j.value >= Rational.zero) - (min1i.value - min2i.value, min2j.value - min1j.value) - else - (min2i.value - min1i.value, min1j.value - min2j.value) - if (deltai * deltaj > Rational.zero) - Option(-vi * deltaj - vj * deltai) - else - Option.empty - } - } - - require(dimension == that.dimension) - - // special cases - if (isEmpty) - that - else if (that.isEmpty) - this - else if (dimension == 0) - this - else { - val thisRotated = this.rotate(that.A) - val thatRotated = that.rotate(this.A) - val Q = scala.collection.mutable.ArrayBuffer[PrioritizedConstraint]() - - val bulk = this.A vertcat that.A - val min1 = this.low vertcat thisRotated.low - val min2 = thatRotated.low vertcat that.low - val max1 = this.high vertcat thisRotated.high - val max2 = thatRotated.high vertcat that.high - for (i <- 0 until dimension) Q += priority(this.A.row(i), 1) - for (i <- 0 until dimension) Q += priority(that.A.row(i), 2) - for (i <- 0 until dimension; j <- i + 1 until dimension) { - val v1 = bulk.row(i) - val v2 = bulk.row(j) - - val nc1 = newConstraint(v1, v2, min1(i), min2(i), min1(j), min2(j)) - if (nc1.isDefined) Q += priority(nc1.get) - val nc2 = newConstraint(v1, -v2, min1(i), min2(i), -max1(j), -max2(j)) - if (nc2.isDefined) Q += priority(nc2.get) - val nc3 = newConstraint(-v1, -v2, -max1(i), -max2(i), -max1(j), -max2(j)) - if (nc3.isDefined) Q += priority(nc3.get) - val nc4 = newConstraint(-v1, v2, -max1(i), -max2(i), min1(j), min2(j)) - if (nc4.isDefined) Q += priority(nc4.get) - } - - val Qsorted = Q.sortBy(_._4) - val pvt = domain.pivoting(Qsorted map (_._1)) - val newA = DenseMatrix(pvt map (Qsorted(_)._1): _*) - val newlow = Bounds(pvt map (Qsorted(_)._2): _*) - val newhigh = Bounds(pvt map (Qsorted(_)._3): _*) - - new Property(false, newlow, newA, newhigh) - } - } - - /** - * This is a variant of `union` using weak join. The shape of the resulting - * parallelotope is the same shap of `this`. - * @param that the abstract object to be joined with `this`. - * @note $NOTEDIMENSION - * @return the weak union of the two abstract objects. - */ - def unionWeak(that: Property): Property = { - require(dimension == that.dimension) - if (isEmpty) - that.rotate(A) - else if (that.isEmpty) - this - else { - val result = that.rotate(A) - for (i <- 0 until dimension) { - result.low(i) = result.low(i) min low(i) - result.high(i) = result.high(i) max high(i) - } - new Property(false, result.low, result.A, result.high) //this is to normalize - } - } - - /** - * This is the weak intersection of two abstract objects. The shape of the resulting - * parallelotope is the same shape of `this`. - * @param that the abstract object to be intersected with `this`. - * @note $NOTEDIMENSION - * @return the intersection of the two abstract objects. - */ - def intersectionWeak(that: Property): Property = { - require(dimension == that.dimension) - if (isEmpty) - this - else if (that.isEmpty) - ParallelotopeRationalDomainFast.this.bottom(A) - else { - val result = that.rotate(A) - for (i <- 0 until dimension) { - result.low(i) = result.low(i) max low(i) - result.high(i) = result.high(i) min high(i) - } - if ((0 until result.low.length) exists { i => (result.low(i) > result.high(i)) }) - bottom - else - new Property(false, result.low, result.A, result.high) //this is to normalize - } - } - - /** - * @inheritdoc - * @note @inheritdoc - * @todo @inheritdoc - * @throws $ILLEGAL - */ - def linearAssignment(n: Int, lf: LinearForm): Property = { - require(n <= dimension && lf.dimension <= dimension) - val tcoeff = lf.homcoeffs - val known = lf.known - if (isEmpty) - this - else { - val coeff = DenseVector(tcoeff.padTo(dimension, Rational.zero): _*) - if (! coeff(n).isZero) { - // invertible assignment - val increment = A.col(n) * known / coeff(n) - val newlow = low.copy - val newhigh = high.copy - // cannot use Breeze here since they are RationalExt - for (i <- 0 until dimension) { - newlow(i) += increment(i) - newhigh(i) += increment(i) - } - val ei = DenseVector.zeros(dimension) - ei(n) = Rational.one - val newA = A - (A.col(n) * (coeff - ei).t) / coeff(n) - - new Property(false, newlow, newA, newhigh) - } else { - // non-invertible assignment - val newP = nonDeterministicAssignment(n) - val Aprime = newP.A.copy - val j = ((0 until Aprime.rows) find { !Aprime(_, n).isZero }).get - for (s <- 0 until dimension if !Aprime(s, n).isZero && s != j) - Aprime.rowUpdate(s, Aprime.row(s) - Aprime.row(j) * (Aprime(s, n) / Aprime(j, n))) - val ei = DenseVector.zeros(dimension) - ei(n) = Rational.one - Aprime.rowUpdate(j, ei - coeff) - val newlow = newP.low.copy - val newhigh = newP.high.copy - newlow(j) = known - newhigh(j) = known - - new Property(false, newlow, Aprime, newhigh) - } - } - } - - /** - * Computes the dot product of `x` and `y` with the proviso that if `x` is zero, then `x*y` - * is zero even when `y` is an infinite value (which is not the standard behaviour). - */ - private def dotprod(x: DenseVector, y: Bounds, remove: Int = -1): RationalExt = { - var sum = RationalExt.zero - for (i <- 0 until x.length if i != remove if x(i) != Rational.zero) sum = sum + y(i) * x(i) - sum - } - - /** - * @inheritdoc - * @note @inheritdoc - * @todo @inheritdoc - * @throws ILLEGAL - */ - def linearInequality(lf: LinearForm): Property = { - require(lf.dimension <= dimension) - if (isEmpty) - this - else if (dimension == 0) - if (lf.known > Rational.zero) - bottom - else - this - else { - val known = lf.known - val coeffs = DenseVector(lf.homcoeffs.padTo(dimension, Rational.zero): _*) - val coeffsTransformed = A.t \ coeffs - - val removeCandidates = (0 until dimension) find { i => !coeffsTransformed(i).isZero && low(i).isInfinity && high(i).isInfinity } - removeCandidates match { - case None => { - val newlow = low.copy - val newhigh = high.copy - val (minc, maxc) = domain.extremalsInBox(coeffsTransformed, newlow, newhigh) - if (minc > -known) - bottom - else { - val lfArgmin = coeffsTransformed mapPairs { case (i, c) => if (c > Rational.zero) low(i) else high(i) } - - val infinities = (0 until dimension) filter { i => lfArgmin(i).isInfinity && coeffsTransformed(i) != Rational.zero } - infinities.size match { - case 0 => - for (i <- 0 until dimension) { - if (coeffsTransformed(i) > Rational.zero) - newhigh(i) = high(i) min (lfArgmin(i) + (-RationalExt(known) - minc) / coeffsTransformed(i)) - else if (coeffsTransformed(i) < Rational.zero) - newlow(i) = low(i) max (lfArgmin(i) + (-RationalExt(known) - minc) / coeffsTransformed(i)) - } - case 1 => { - val posinf = infinities.head - if (coeffsTransformed(posinf) < Rational.zero) - newlow(posinf) = low(posinf) max ((-dotprod(coeffsTransformed, lfArgmin, posinf) - known) / coeffsTransformed(posinf)) - else - newhigh(posinf) = high(posinf) min ((-dotprod(coeffsTransformed, lfArgmin, posinf) - known) / coeffsTransformed(posinf)) - } - case _ => - } - new Property(false, newlow, A, newhigh) - } - } - case Some(chosen) => { - // TODO: check.. I think this may generate non-invertible matrices - val newA = A.copy - val newhigh = high.copy - newA.rowUpdate(chosen, coeffs) - newhigh(chosen) = -known - new Property(false, low, newA, newhigh) - } - } - } - } - - /** - * @inheritdoc - * @note @inheritdoc - * @throws $ILLEGAL - */ - def linearDisequality(lf: LinearForm): Property = { - val tcoeff = lf.homcoeffs - val known = lf.known - if (tcoeff.forall(_.isZero)) { - if (known.isZero) - bottom - else - this - } else { - val row = (0 until dimension).find { (r) => - val v1 = A.row(r) - val v2 = DenseVector(tcoeff: _*) - v1.data sameElements v2.data - } - row match { - case None => this - case Some(row) => - if (low(row) == known && high(row) == known) bottom else this - } - } - } - - /** - * @inheritdoc - * @note @inheritdoc - * @throws $ILLEGAL - */ - def nonDeterministicAssignment(n: Int): Property = { - require(n <= dimension) - if (isEmpty) - this - else { - val unsortedCandidates = (0 until dimension) filter { i => A(i, n) != Rational.zero && (!low(i).isNegInfinity || !high(i).isPosInfinity) } - if (unsortedCandidates.isEmpty) - this - else { - // We prever to use as a pivot a simple constraint. Therefore, we order constraints by the number of - // non-zero coefficients. - val countNonZeroInRows = A.countNonZeroInRows - val removeCandidates = unsortedCandidates.sortBy({ i => countNonZeroInRows(i) }) - val removeCandidatesEq = removeCandidates filter { i => low(i) == high(i) } - val removeCandidatesBounded = removeCandidates filter { i => !low(i).isInfinity && !high(i).isInfinity } - - val pivot = - if (!removeCandidatesEq.isEmpty) removeCandidatesEq.head - else if (!removeCandidatesBounded.isEmpty) removeCandidatesBounded.head - else removeCandidates.head - val rowPivot = A.row(pivot) - - val newA = A.copy - val newlow = low.copy - val newhigh = high.copy - - for (i <- removeCandidates if i != pivot) { - val value1 = rowPivot(n) - val value2 = A(i, n) - val rowi = A.row(i) - newA.rowUpdate(i, rowPivot * value2 - rowi * value1) - val (minPivot, maxPivot) = if (A(i, n) < Rational.zero) (high(pivot), low(pivot)) else (low(pivot), high(pivot)) - val (mini, maxi) = if (-A(pivot, n) < Rational.zero) (high(i), low(i)) else (low(i), high(i)) - newlow(i) = minPivot * value2 - mini * value1 - newhigh(i) = maxPivot * value2 - maxi * value1 - } - newlow(pivot) = RationalExt.NegativeInfinity - newhigh(pivot) = RationalExt.PositiveInfinity - new Property(false, newlow, newA, newhigh) - } - } - } - - def addVariable(): Property = { - if (isEmpty) - ParallelotopeRationalDomainFast.this.bottom(dimension + 1) - else { - val e = DenseMatrix.zeros(dimension + 1, 1) - e(dimension, 0) = Rational.one - val newA = (A vertcat DenseMatrix.zeros(1, dimension)) horzcat e - val newlow = low vertcat Bounds(RationalExt.NegativeInfinity) - val newhigh = high vertcat Bounds(RationalExt.PositiveInfinity) - - new Property(false, newlow, newA, newhigh) - } - } - - def constraints = { - if (isEmpty) - Seq(LinearForm(1)) - else { - val set1 = for (i <- 0 until dimension; if !low(i).isInfinity) yield -LinearForm(-low(i).value +: A.row(i).toScalaVector: _*) - val set2 = for (i <- 0 until dimension; if !high(i).isInfinity) yield LinearForm(-high(i).value +: A.row(i).toScalaVector: _*) - set1 ++ set2 - } - } - - def isPolyhedral = true - - /** - * @inheritdoc - * @note @inheritdoc - * @throws $ILLEGAL - */ - def delVariable(n: Int): Property = { - def rowToSeq(M: DenseMatrix, i: Int, n: Int): Seq[Rational] = - for (j <- 0 until A.rows; if j != n) yield M(i, j) - - if (isEmpty) - ParallelotopeRationalDomainFast.this.bottom(A.rows - 1) - else { - val forgot = this.nonDeterministicAssignment(n) - val set1 = for (i <- 0 until dimension; if !forgot.low(i).isInfinity; if forgot.A(i, n) == Rational.zero) yield -LinearForm(-forgot.low(i).value +: rowToSeq(forgot.A, i, n): _*) - val set2 = for (i <- 0 until dimension; if !forgot.high(i).isInfinity; if forgot.A(i, n) == Rational.zero) yield LinearForm(-forgot.high(i).value +: rowToSeq(forgot.A, i, n): _*) - (set1 ++ set2).foldLeft(ParallelotopeRationalDomainFast.this.top(A.rows - 1)) { (p, lf) => p.linearInequality(lf) } - } - } - - /** - * @inheritdoc - */ - def mapVariables(rho: Seq[Int]): Property = { - if (isEmpty) - this - else { - val slice = for (i <- 0 until dimension; j = rho.indexOf(i); if j != -1) yield j - val newA = A(slice, slice) - val newlow = low(slice) - val newhigh = high(slice) - - new Property(false, newlow, newA, newhigh) - } - } - - /** - * Compute the minimum and maximum value of a linear form in a parallelotope. - * @todo should be generalized to linear forms over arbitrary types. - * @return a tuple with two components: the first component is the least value, the second component is the greatest value - * of the linear form over the box. - */ - def linearEvaluation(lf: LinearForm): (RationalExt, RationalExt) = { - val tcoeff = lf.homcoeffs - if (isEmpty && tcoeff.exists { _ != Rational.zero }) - (RationalExt.PositiveInfinity, RationalExt.NegativeInfinity) - else if (dimension == 0) - (lf.known, lf.known) - else { - val coeff = tcoeff.padTo(dimension, Rational.zero).toArray - val vec = new DenseVector(coeff) - val newvec = A.t \ vec - val (min, max) = domain.extremalsInBox(newvec, low, high) - (min + lf.known, max + lf.known) - } - } - - def minimize(lf: LinearForm) = linearEvaluation(lf)._1 - - def maximize(lf: LinearForm) = linearEvaluation(lf)._2 - - def frequency(lf: LinearForm) = { - val (min, max) = linearEvaluation(lf) - if (min == max) Option(min.value) else Option.empty - } - - def dimension = A.rows - - def isTop = !isEmpty && low.forall(_.isNegInfinity) && high.forall(_.isPosInfinity) - - def isBottom = isEmpty - - def bottom = ParallelotopeRationalDomainFast.this.bottom(dimension) - - def top = ParallelotopeRationalDomainFast.this.top(dimension) - - def tryCompareTo[B >: Property](that: B)(implicit arg0: (B) => PartiallyOrdered[B]): Option[Int] = that match { - case that: Property => - val lte = this <= that - val gte = that <= this - if (lte && gte) - Option(0) - else if (lte) - Option(-1) - else if (gte) - Option(1) - else - Option.empty - case _ => Option.empty - } - - /** - * It computes the smallest parallelotope which contains `this` and is definable - * over a new shape matrix `Aprime`. - * @param Aprime the new shape matrix. - * @note `Aprime` should be an invertible matrix of the same dimension as `this`. - * @throws IllegalArgumentException if `Aprime` is not square or has not the correct dimension. - */ - def rotate(Aprime: DenseMatrix): Property = { - require(dimension == Aprime.rows && dimension == Aprime.cols) - if (isEmpty) - this - else { - val B = Aprime * (A \ DenseMatrix.eye(dimension)) - val newlow = Bounds.fill(dimension)(RationalExt.zero) - val newhigh = Bounds.fill(dimension)(RationalExt.zero) - B.foreachPair { - case ((i, j), v) => - if (v > Rational.zero) { - newlow(i) += low(j) * v - newhigh(i) += high(j) * v - } else if (v < Rational.zero) { - newhigh(i) += low(j) * v - newlow(i) += high(j) * v - } - } - new Property(false, newlow, Aprime, newhigh) - } - } - - def <=[B >: Property](that: Property)(implicit arg0: (B) => PartiallyOrdered[B]): Boolean = { - if (isEmpty) - true - else if (that.isEmpty) - false - else if (that.isTop) - true - else { - val ptemp = this.rotate(that.A) - (0 to ptemp.low.length - 1) forall { i => ptemp.low(i) >= that.low(i) && ptemp.high(i) <= that.high(i) } - } - } - - def >=[B >: Property](that: Property)(implicit arg0: (B) => PartiallyOrdered[B]): Boolean = - that <= this - - def <[B >: Property](that: Property)(implicit arg0: (B) => PartiallyOrdered[B]): Boolean = - (this <= that) && !(this >= that) - - def >[B >: Property](that: Property)(implicit arg0: (B) => PartiallyOrdered[B]): Boolean = - (this >= that) && !(this <= that) - - def mkString(vars: Seq[String]): String = { - - /* - * Returns a string representation of the linear form `lf`. - */ - def lfToString(lf: DenseVector): String = { - var first = true - val s = new StringBuilder - val minusOne = -Rational.one - - for (index <- 0 until dimension) { - val coeff = lf(index) - val term = coeff match { - case Rational.zero => "" - case Rational.one => vars(index) - case `minusOne` => "-" + vars(index) - case c => c.toString + "*" + vars(index) - } - if (!coeff.isZero) { - if (first || coeff < Rational.zero) { - s ++= term - first = false - } else if (coeff != Rational.zero) - s ++= "+" + term - } - } - if (s.isEmpty) "0" else s.toString - } - - if (isEmpty) - "empty" - else { - val eqns = for (i <- 0 until dimension) yield { - if (low(i) < high(i)) - s"${if (low(i).isNegInfinity) "-∞" else low(i)} ≤ ${lfToString(A.col(i))} ≤ ${if (high(i).isPosInfinity) "+∞" else high(i)}" - else - s"${lfToString(A.col(i))} = ${high(i)}" - } - eqns.mkString("[ ", " , ", " ]") - } - } - } -} - -/** - * Companion class for the parallelotope domain - */ -object ParallelotopeRationalDomainFast { - private lazy val standard = new ParallelotopeRationalDomainFast(0) with CachedTopBottom - private lazy val favoring = new ParallelotopeRationalDomainFast(1) with CachedTopBottom - private lazy val unfavoring = new ParallelotopeRationalDomainFast(-1) with CachedTopBottom - - /** - * Returns an abstract domain for parallelotopes. - * @param favorAxis determines whether the heuristics built into the domain should try to keep constraints - * corresponding to Cartesian axis. If favorAxis is `1`, axis are favorite. The opposite happens when favorAxis - * is -1. If favorAxis is 0, axis are considered like all the other constraints - */ - def apply(favorAxis: Int = 0) = favorAxis match { - case -1 => unfavoring - case 0 => standard - case 1 => favoring - case _ => throw new IllegalArgumentException("The field favorAxis should be -1, 0 or 1") - } -} diff --git a/core/src/main/scala/it/unich/jandom/domains/numerical/SumIntParallelotopeDomain.scala b/core/src/main/scala/it/unich/jandom/domains/numerical/SumIntParallelotopeDomain.scala index 0961e172..a5ff7ea4 100644 --- a/core/src/main/scala/it/unich/jandom/domains/numerical/SumIntParallelotopeDomain.scala +++ b/core/src/main/scala/it/unich/jandom/domains/numerical/SumIntParallelotopeDomain.scala @@ -25,33 +25,33 @@ package it.unich.jandom.domains.numerical * @author Simone Di Nardo Di Maio */ -class SumIntParallelotopeDomain(val dom1: BoxDoubleDomain, val dom2: ParallelotopeDomain) extends SumDomain[BoxDoubleDomain, ParallelotopeDomain] { - type Property = SumIntParallelotope +class SumBoxDoubleParallelotopeRationDomain(val dom1: BoxDoubleDomain, val dom2: ParallelotopeRationalDomain) extends SumDomain[BoxDoubleDomain, ParallelotopeRationalDomain] { + type Property = SumBoxDoubleParallelotopeRational - class SumIntParallelotope(val p1: dom1.Property, val p2: dom2.Property) extends Sum { + class SumBoxDoubleParallelotopeRational(val p1: dom1.Property, val p2: dom2.Property) extends Sum { override def linearAssignment(n: Int, lf: LinearForm): Property = { if ((n >= lf.homcoeffs.size) || (lf.homcoeffs(n) == 0)) { val q1 = p1.linearAssignment(n, lf) val q2 = p2.linearAssignment(n, lf.hom) - SumIntParallelotopeDomain.this(q1, q2) + SumBoxDoubleParallelotopeRationDomain.this(q1, q2) } else { val q1 = p1.linearAssignment(n, lf.hom) val q2 = p2.linearAssignment(n,lf) - SumIntParallelotopeDomain.this(q1, q2) + SumBoxDoubleParallelotopeRationDomain.this(q1, q2) } } } - def apply(p1: dom1.Property, p2: dom2.Property) = new SumIntParallelotope(p1, p2) + def apply(p1: dom1.Property, p2: dom2.Property) = new SumBoxDoubleParallelotopeRational(p1, p2) } /** * Companion class for the Int+Parallelotope domain */ -object SumIntParallelotopeDomain { +object SumBoxDoubleParallelotopeRationDomain { /** * Returns the standard Int+Parallelotope Domain */ def apply() = v - private lazy val v = new SumIntParallelotopeDomain(BoxDoubleDomain(), ParallelotopeDomain(favorAxes = true)) + private lazy val v = new SumBoxDoubleParallelotopeRationDomain(BoxDoubleDomain(), ParallelotopeRationalDomain(favorAxis = 1)) } diff --git a/core/src/main/scala/it/unich/jandom/ui/NumericalDomains.scala b/core/src/main/scala/it/unich/jandom/ui/NumericalDomains.scala index ae650244..a143409c 100644 --- a/core/src/main/scala/it/unich/jandom/ui/NumericalDomains.scala +++ b/core/src/main/scala/it/unich/jandom/ui/NumericalDomains.scala @@ -33,10 +33,8 @@ object NumericalDomains extends ParameterEnumeration[NumericalDomain] { "w.r.t. double arithmetics."), ParameterValue(BoxDoubleDomain(overReals=true), "BoxDouble over Reals", "This is a native Scala implementation of boxes. It is safe " + "w.r.t. reals."), - ParameterValue(ParallelotopeDomain(), "Parallelotope", "This is a native Scala implementation of parallelotopes. It is " + - "not safe and should not be used."), - ParameterValue(SumIntParallelotopeDomain(), "BoxDouble + Parallelotope", "Sum of boxes and parallelotopes."), - ParameterValue(ParallelotopeRationalDomain(), "Parallelotope over Rationals", "This is a native Scala implementation of parallelotopes using rational numbers.") + ParameterValue(ParallelotopeRationalDomain(), "Parallelotope over Rationals", "This is a native Scala implementation of parallelotopes using rational numbers."), + ParameterValue(SumBoxDoubleParallelotopeRationDomain(), "BoxDouble + ParallelotopeRational", "Sum of boxes and parallelotopes.") ) val default = values.last diff --git a/core/src/main/scala/it/unich/jandom/utils/breeze/RationalForBreeze.scala b/core/src/main/scala/it/unich/jandom/utils/breeze/RationalForBreeze.scala deleted file mode 100644 index 1035d2ef..00000000 --- a/core/src/main/scala/it/unich/jandom/utils/breeze/RationalForBreeze.scala +++ /dev/null @@ -1,174 +0,0 @@ -/** - * Copyright 2016 Gianluca Amato - * - * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains - * JANDOM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * JANDOM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of a - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with JANDOM. If not, see . - */ - -package it.unich.jandom.utils.breeze - -import breeze.linalg._ -import breeze.linalg.operators._ -import breeze.linalg.support.CanTraverseValues -import breeze.linalg.support.CanTraverseValues.ValuesVisitor -import breeze.math.Field -import breeze.storage.Zero -import spire.math.Rational -import spire.syntax.cfor._ - -/** - * This object contains the implicit type classes which are needed to make Rational - * work with the Breeze library. This is just what is strictly necessary for implementing - * the ParallelotopeRational domain, and might not work in a different context. - */ -object RationalForBreeze { - - implicit object fieldRational extends Field[Rational] { - def zero = Rational.zero - - def one = Rational.one - - def ==(a: Rational, b: Rational) = a == b - - def !=(a: Rational, b: Rational) = a != b - - def +(a: Rational, b: Rational) = a + b - - def -(a: Rational, b: Rational) = a - b - - def *(a: Rational, b: Rational) = a * b - - def /(a: Rational, b: Rational) = a / b - - def %(a: Rational, b: Rational) = Rational.zero - - def pow(a: Rational, b: Rational) = ??? - - def >(a: Rational, b: Rational) = a > b - - def >=(a: Rational, b: Rational) = a >= b - - def <(a: Rational, b: Rational) = a < b - - def <=(a: Rational, b: Rational) = a <= b - - def abs(a: Rational) = a.abs - - implicit val normImpl: norm.Impl[Rational, Double] = new norm.Impl[Rational, Double] { - def apply(v: Rational): Double = v.doubleValue() - } - } - - implicit object Rational_MulMM extends OpMulMatrix.Impl2[Rational, Rational, Rational] { def apply(a: Rational, b: Rational) = a * b } - - implicit object Rational_MulDM extends OpDiv.Impl2[Double, Rational, Rational] { def apply(a: Double, b: Rational) = Rational(a) * b } - - implicit object RationalIsZero extends Zero[Rational] { - val zero = Rational.zero - } - - implicit def dv_s_Op_Rational_OpMulMatrix: OpMulMatrix.Impl2[DenseVector[Rational], Rational, DenseVector[Rational]] = - new OpMulMatrix.Impl2[DenseVector[Rational], Rational, DenseVector[Rational]] { - def apply(a: DenseVector[Rational], b: Rational): DenseVector[Rational] = { - val ad = a.data - var aoff = a.offset - val result = DenseVector.zeros[Rational](a.length) - val rd = result.data - var i = 0 - while (i < a.length) { - rd(i) = ad(aoff) * b - aoff += a.stride - i += 1 - } - result - } - implicitly[BinaryRegistry[Vector[Rational], Rational, OpMulMatrix.type, Vector[Rational]]].register(this) - } - - implicit object Rational_implOpSolveMatrixBy_DRR_DRR_eq_DRR - extends OpSolveMatrixBy.Impl2[DenseMatrix[Rational], DenseMatrix[Rational], DenseMatrix[Rational]] { - - def LUSolveArray(X: Array[Rational], A: Array[Rational], Xrows: Int, Xcols: Int): Array[Rational] = { - val perm = (0 until Xrows).toArray - for (i <- 0 until Xrows - 1) { - val optPivot = (i until Xrows) find { p => !A(perm(p) + i * Xrows).isZero } - val pivotRow = optPivot.getOrElse(throw new MatrixSingularException()) - val tmp = perm(i) - perm(i) = perm(pivotRow) - perm(pivotRow) = tmp - val pivot = A(perm(i) + i * Xrows) - for (j <- i + 1 until Xrows) { - val coeff = A(perm(j) + i * Xrows) / pivot - cfor(0)(_ < Xrows, _ + 1) { (k) => - A(perm(j) + k * Xrows) -= A(perm(i) + k * Xrows) * coeff - } - cfor(0)(_ < Xcols, _ + 1) { (k) => - X(perm(j) + k * Xrows) -= X(perm(i) + k * Xrows) * coeff - } - } - } - val X1 = new Array[Rational](Xrows * Xcols) - for (i <- Xrows - 1 to (0, -1)) { - cfor(0)(_ < Xcols, _ + 1) { (k) => - X1(i + k * Xrows) = X(perm(i) + k * Xrows) - } - for (j <- i + 1 until Xrows) - cfor(0)(_ < Xcols, _ + 1) { (k) => - X1(i + k * Xrows) -= X1(j + k * Xrows) * A(perm(i) + j * Xrows) - } - cfor(0)(_ < Xcols, _ + 1) { (k) => - X1(i + k * Xrows) /= A(perm(i) + i * Xrows) - } - } - X1 - } - - def apply(A: DenseMatrix[Rational], V: DenseMatrix[Rational]): DenseMatrix[Rational] = { - require(A.rows == V.rows, "Non-conformant matrix sizes") - - if (A.size == 0) { - DenseMatrix.zeros[Rational](0, 0) - } else if (A.rows == A.cols) { - val X = DenseMatrix.zeros[Rational](V.rows, V.cols) - val Y = DenseMatrix.zeros[Rational](A.rows, A.cols) - X := V - Y := A - new DenseMatrix(X.rows, X.cols, LUSolveArray(X.data, Y.data, X.rows, X.cols), 0, X.rows) - } else - throw new IllegalArgumentException("We only support solving a square matrix") - } - } - - implicit object Rational_implOpSolveMatrixBy_DMR_DVR_eq_DVR - extends OpSolveMatrixBy.Impl2[DenseMatrix[Rational], DenseVector[Rational], DenseVector[Rational]] { - - def apply(a: DenseMatrix[Rational], b: DenseVector[Rational]): DenseVector[Rational] = { - val rv: DenseMatrix[Rational] = a \ new DenseMatrix[Rational](b.size, 1, b.data, b.offset, b.stride, true) - new DenseVector[Rational](rv.data) - } - } - - implicit def countFromTraverseModRational[T](implicit traverse: CanTraverseValues[T, Rational]): countNonZero.Impl[T, Int] = { - new countNonZero.Impl[T, Int] { - def apply(t: T): Int = { - var count: Int = 0 - traverse.traverse(t, new ValuesVisitor[Rational] { - def visit(a: Rational) = { if (a != Rational.zero) count += 1 } - def zeros(count: Int, zeroValue: Rational) {} - }) - count - } - } - } -} diff --git a/core/src/main/scala/it/unich/jandom/utils/breeze/countNonZero.scala b/core/src/main/scala/it/unich/jandom/utils/breeze/countNonZero.scala deleted file mode 100644 index 6be53f44..00000000 --- a/core/src/main/scala/it/unich/jandom/utils/breeze/countNonZero.scala +++ /dev/null @@ -1,38 +0,0 @@ -/** - * Copyright 2014 Gianluca Amato - * - * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains - * JANDOM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * JANDOM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty ofa - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with JANDOM. If not, see . - */ - -package it.unich.jandom.utils.breeze - -import breeze.generic.UFunc -import breeze.linalg.support.CanTraverseValues -import breeze.linalg.support.CanTraverseValues.ValuesVisitor - -object countNonZero extends UFunc { - implicit def countFromTraverseDoubles[T](implicit traverse: CanTraverseValues[T, Double]): Impl[T, Int] = { - new Impl[T, Int] { - def apply(t: T): Int = { - var count: Int = 0 - traverse.traverse(t, new ValuesVisitor[Double] { - def visit(a: Double) = { if (a != 0) count += 1 } - def zeros(count: Int, zeroValue: Double) {} - }) - count - } - } - } -} diff --git a/core/src/main/scala/it/unich/jandom/utils/numberext/Bounds.scala b/core/src/main/scala/it/unich/jandom/utils/numberext/Bounds.scala index 60afa6c2..7b990000 100644 --- a/core/src/main/scala/it/unich/jandom/utils/numberext/Bounds.scala +++ b/core/src/main/scala/it/unich/jandom/utils/numberext/Bounds.scala @@ -83,4 +83,9 @@ object Bounds { * Builds a bound vector for a sequence of extended rationals. */ def apply(elem: RationalExt*) = new Bounds(elem.toArray) + + /** + * Builds a bound vector for an array of extended rationals. + */ + def apply(data: Array[RationalExt]) = new Bounds(data) } \ No newline at end of file diff --git a/core/src/main/scala/it/unich/jandom/utils/numberext/DenseVector.scala b/core/src/main/scala/it/unich/jandom/utils/numberext/DenseVector.scala index 765e2d9a..bf7f9c73 100644 --- a/core/src/main/scala/it/unich/jandom/utils/numberext/DenseVector.scala +++ b/core/src/main/scala/it/unich/jandom/utils/numberext/DenseVector.scala @@ -271,6 +271,11 @@ object DenseVector { */ def apply(elem: Rational*): DenseVector = new DenseVector(elem.toArray) + /** + * Builds a DenseVector from an arrray of rationals. + */ + def apply(data: Array[Rational]): DenseVector = new DenseVector(data) + /** * Returns the null vector of dimension `n`. */ diff --git a/core/src/test/scala/it/unich/jandom/JandomSumBench.scala b/core/src/test/scala/it/unich/jandom/JandomSumBench.scala index 6ace694c..6ed4623a 100644 --- a/core/src/test/scala/it/unich/jandom/JandomSumBench.scala +++ b/core/src/test/scala/it/unich/jandom/JandomSumBench.scala @@ -24,8 +24,8 @@ import java.io.FileReader import it.unich.jandom.domains.DimensionFiberedProperty import it.unich.jandom.domains.numerical.BoxDoubleDomain import it.unich.jandom.domains.numerical.LinearForm -import it.unich.jandom.domains.numerical.ParallelotopeDomain -import it.unich.jandom.domains.numerical.SumIntParallelotopeDomain +import it.unich.jandom.domains.numerical.ParallelotopeRationalDomain +import it.unich.jandom.domains.numerical.SumBoxDoubleParallelotopeRationDomain import it.unich.jandom.domains.numerical.ppl.PPLDomain import it.unich.jandom.parsers.FastParser import it.unich.jandom.targets.lts.LTS @@ -74,7 +74,7 @@ object JandomSumBench extends App { val ann1 = program.analyze(params) val tann1 = System.currentTimeMillis - t1 - val params2 = new targets.Parameters[LTS] { val domain = SumIntParallelotopeDomain() } + val params2 = new targets.Parameters[LTS] { val domain = SumBoxDoubleParallelotopeRationDomain() } params2.widening = DelayedWidening(DefaultWidening, 3) // needed for parallelotopes //params2.debugWriter = new java.io.PrintWriter(System.out) program.analyze(params2) // warmup JVM @@ -84,7 +84,7 @@ object JandomSumBench extends App { val ann2 = program.analyze(params2) val tann2 = System.currentTimeMillis - t2 - val params3 = new targets.Parameters[LTS] { val domain = ParallelotopeDomain() } + val params3 = new targets.Parameters[LTS] { val domain = ParallelotopeRationalDomain() } params3.widening = DelayedWidening(DefaultWidening, 3) // needed for parallelotopes //params3.debugWriter = new java.io.PrintWriter(System.out) diff --git a/core/src/test/scala/it/unich/jandom/domains/DomainTransformationSuite.scala b/core/src/test/scala/it/unich/jandom/domains/DomainTransformationSuite.scala index 79f5e35b..2fa68f0b 100644 --- a/core/src/test/scala/it/unich/jandom/domains/DomainTransformationSuite.scala +++ b/core/src/test/scala/it/unich/jandom/domains/DomainTransformationSuite.scala @@ -20,11 +20,10 @@ package it.unich.jandom.domains import org.scalatest.FunSuite -import breeze.linalg.DenseMatrix -import breeze.linalg.DenseVector +import it.unich.jandom.utils.numberext._ import it.unich.jandom.domains.numerical.BoxDoubleDomain import it.unich.jandom.domains.numerical.NumericalDomain -import it.unich.jandom.domains.numerical.ParallelotopeDomain +import it.unich.jandom.domains.numerical.ParallelotopeRationalDomain /** * The test suite for domain transformations. @@ -32,31 +31,31 @@ import it.unich.jandom.domains.numerical.ParallelotopeDomain */ class DomainTransformationSuite extends FunSuite { val boxdom = BoxDoubleDomain() - val pardom = ParallelotopeDomain() + val pardom = ParallelotopeRationalDomain() test("Parallelotope to BoxDouble") { - val transform = implicitly[DomainTransformation[ParallelotopeDomain, BoxDoubleDomain]] - val diamond = pardom(DenseVector(-1, -1), DenseMatrix((1.0, 1.0), (1.0, -1.0)), DenseVector(1, 1)) + val transform = implicitly[DomainTransformation[ParallelotopeRationalDomain, BoxDoubleDomain]] + val diamond = pardom(Bounds(-1, -1), DenseMatrix(DenseVector(1.0, 1.0), DenseVector(1.0, -1.0)), Bounds(1, 1)) val box = boxdom(Array(-1, -1), Array(1, 1)) assertResult(box) { transform(pardom,boxdom)(diamond) } } test("Parallelotope to Parallelotope") { - val transform = implicitly[DomainTransformation[ParallelotopeDomain, ParallelotopeDomain]] - val diamond = pardom(DenseVector(-1, -1), DenseMatrix((1.0, 1.0), (1.0, -1.0)), DenseVector(1, 1)) + val transform = implicitly[DomainTransformation[ParallelotopeRationalDomain, ParallelotopeRationalDomain]] + val diamond = pardom(Bounds(-1, -1), DenseMatrix(DenseVector(1.0, 1.0), DenseVector(1.0, -1.0)), Bounds(1, 1)) assertResult(diamond) { transform(pardom,pardom)(diamond) } } test("Box to Parallelotope") { - val transform = implicitly[DomainTransformation[BoxDoubleDomain, ParallelotopeDomain]] - val boxptope = pardom(DenseVector(-1, -1), DenseMatrix.eye(2), DenseVector(1, 1)) + val transform = implicitly[DomainTransformation[BoxDoubleDomain, ParallelotopeRationalDomain]] + val boxptope = pardom(Bounds(-1, -1), DenseMatrix.eye(2), Bounds(1, 1)) val box = boxdom(Array(-1, -1), Array(1, 1)) assertResult(boxptope) { transform(boxdom,pardom)(box) } } test("General transformation to Box") { val transform = new DomainTransformation.TopTransformation[NumericalDomain, BoxDoubleDomain] - val diamond = pardom(DenseVector(-1, -1), DenseMatrix((1.0, 1.0), (1.0, -1.0)), DenseVector(1, 1)) + val diamond = pardom(Bounds(-1, -1), DenseMatrix(DenseVector(1.0, 1.0), DenseVector(1.0, -1.0)), Bounds(1, 1)) val box = boxdom(Array(-1, -1), Array(1, 1)) assertResult(boxdom.top(2)) { transform(pardom,boxdom)(diamond) } } diff --git a/core/src/test/scala/it/unich/jandom/domains/numerical/ParallelotopeDomainSuite.scala b/core/src/test/scala/it/unich/jandom/domains/numerical/ParallelotopeDomainSuite.scala deleted file mode 100644 index c55a6d38..00000000 --- a/core/src/test/scala/it/unich/jandom/domains/numerical/ParallelotopeDomainSuite.scala +++ /dev/null @@ -1,211 +0,0 @@ -/** - * Copyright 2013, 2016 Gianluca Amato - * - * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains - * JANDOM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * JANDOM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of a - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with JANDOM. If not, see . - */ - -package it.unich.jandom.domains.numerical - -import breeze.linalg.DenseMatrix -import breeze.linalg.DenseVector -import it.unich.jandom.domains.EmptyExistsSuite -import it.unich.jandom.domains.SeparatedTopAndBottomSuite - -/** - * Test suite for the parallelotope domain. - * @author Gianluca Amato - */ -class ParallelotopeDomainSuite extends NumericalDomainSuite with SeparatedTopAndBottomSuite with EmptyExistsSuite { - lazy val dom = ParallelotopeDomain() - - val box = dom(DenseVector(-1, -1), DenseMatrix.eye(2), DenseVector(1, 1)) - val diamond = dom(DenseVector(-1, -1), DenseMatrix((1.0, 1.0), (1.0, -1.0)), DenseVector(1, 1)) - val empty = dom.bottom(2) - val full = dom.top(2) - - describe("constructors") { - they("should only work with compatible sizes of bounds and shapes") { - intercept[IllegalArgumentException] { dom(DenseVector(0, 2), DenseMatrix.eye(2), DenseVector(0, 2, 3)) } - } - } - - describe("constructors and extractors for non-trivial parallelotopes") { - assertResult(2) { box.dimension } - assertResult(false) { box.isEmpty } - assertResult(false) { box.isTop } - } - - describe("constructors and extractors for full parallelotopes") { - assertResult(2) { full.dimension } - assertResult(false) { full.isEmpty } - assertResult(true) { full.isTop } - } - - describe("constructors and extractors for empty parallelotopes") { - assertResult(2) { empty.dimension } - assertResult(true) { empty.isEmpty } - assertResult(false) { empty.isTop } - } - - describe("comparison of parallelotopes") { - assert(empty < box) - assert(box < full) - assert(empty < full) - assert(diamond < box) - assert(diamond <= box) - assert(box > diamond) - assert(box >= diamond) - assertResult(Some(1)) { box.tryCompareTo(diamond) } - assertResult(Some(-1)) { diamond.tryCompareTo(box) } - assert(box == box) - assertResult(Some(0)) { box.tryCompareTo(box) } - val box2 = dom(DenseVector(-0.5, -0.5), DenseMatrix.eye(2), DenseVector(0.5, 0.5)) - assert(box2 <= box) - assert(box >= box2) - assert(box2 < box) - assert(box > box2) - val box3 = dom(DenseVector(0, 0), DenseMatrix.eye(2), DenseVector(2, 2)) - assertResult(None) { box.tryCompareTo(box3) } - } - - describe("rotation of shapes") { - val m = DenseMatrix((1.0, 1.0), (-1.0, 1.0)) - val protcalc = box.rotate(m) - val protdef = dom(DenseVector(-2, -2), m, DenseVector(2, 2)) - assertResult(protdef) { protcalc } - } - - describe("linear invertible assignment") { - val li1 = dom(DenseVector(0, -1), DenseMatrix((1.0, -1.0), (0.0, 1.0)), DenseVector(2, 1)) - assertResult(li1) { box.linearAssignment(0, LinearForm(1, 1, 1)) } - val li2 = dom(DenseVector(1, -1), DenseMatrix((1.0, 0.0), (-1.0, 1.0)), DenseVector(1, 0)) - val li3 = dom(DenseVector(2, -2), DenseMatrix((1.0, 0.0), (-1.0, 1.0)), DenseVector(2, -1)) - assertResult(li3) { li2.linearAssignment(0, LinearForm(1, 1, 0)) } - assertResult(li3) { li2.linearAssignment(0, LinearForm(1, 1)) } - val li4 = dom(DenseVector(-1, -2), DenseMatrix((1.0, 0.0), (-1.0, 1.0)), DenseVector(1, 2)) - assertResult(li4) { box.linearAssignment(1, LinearForm(0, 1, 2)) } - assert(empty.linearAssignment(1, LinearForm(0.0, 1, 1)).isEmpty) - } - - describe("non-invertible linear assignment") { - val ln1 = dom(DenseVector(2, -1), DenseMatrix((1.0, -1.0), (0.0, 1.0)), DenseVector(2, 1)) - assertResult(ln1) { box.linearAssignment(0, LinearForm(2, 0, 1)) } - val ln2 = dom(DenseVector(0, Double.NegativeInfinity), DenseMatrix((-1.0, 1.0), (0.0, 1.0)), DenseVector(0, Double.PositiveInfinity)) - val ln3 = dom(DenseVector(Double.NegativeInfinity, 0), DenseMatrix((1.0, -1.0), (0.0, 1.0)), DenseVector(Double.PositiveInfinity, 0)) - assertResult(ln2) { ln3.linearAssignment(1, LinearForm(0, 1, 0)) } - assertResult(ln2) { ln3.linearAssignment(1, LinearForm(0, 1)) } - assert(empty.linearAssignment(1, LinearForm(0, 1, 0)).isEmpty) - } - - describe("non-deterministic assignment") { - val nd1 = dom(DenseVector(Double.NegativeInfinity, -1), DenseMatrix.eye(2), DenseVector(Double.PositiveInfinity, 1)) - assertResult(nd1) { box.nonDeterministicAssignment(0) } - assertResult(nd1) { nd1.nonDeterministicAssignment(0) } - assertResult(nd1) { diamond.nonDeterministicAssignment(0) } - val nd2 = dom(DenseVector(0, 0), DenseMatrix((2.0, 1.0), (2.0, -1.0)), DenseVector(1, 1)) - val nd3 = dom(DenseVector(Double.NegativeInfinity, -1), DenseMatrix((2.0, 1.0), (0.0, -2.0)), DenseVector(Double.PositiveInfinity, 1)) - assertResult(nd3) { nd2.nonDeterministicAssignment(0) } - val nd4 = dom(DenseVector(Double.NegativeInfinity, 0), DenseMatrix((2.0, 1.0), (4.0, 0.0)), DenseVector(Double.PositiveInfinity, 2)) - assertResult(nd4) { nd2.nonDeterministicAssignment(1) } - val nd5 = dom(DenseVector(10, -1), DenseMatrix((1.0, 0.0), (1.0, 1.0)), DenseVector(10, 1)) - val nd6 = dom(DenseVector(Double.NegativeInfinity, -11), DenseMatrix.eye(2), DenseVector(Double.PositiveInfinity, -9)) - assertResult(nd6) { nd5.nonDeterministicAssignment(0) } - assert(empty.nonDeterministicAssignment(0).isEmpty) - } - - describe("linear inequalities") { - val li1 = dom(DenseVector(-1, -1), DenseMatrix((1.0, 1.0), (1.0, -1.0)), DenseVector(0, 0)) - assertResult(li1) { diamond.linearInequality(LinearForm(1, 2, 0)) } - assertResult(li1) { diamond.linearInequality(LinearForm(1, 2)) } - assert(empty.linearInequality(LinearForm(-1, 1, 0)).isEmpty) - } - - describe("linear disequalities") { - val li1 = dom(DenseVector(-1, 0), DenseMatrix((1.0, 1.0), (1.0, -2.0)), DenseVector(0, 0)) - assertResult(li1) { li1.linearDisequality(1.0) } - assertResult(empty) { li1.linearDisequality(0.0) } - assertResult(li1) { li1.linearDisequality(LinearForm(1, 0, 1)) } - assertResult(li1) { li1.linearDisequality(LinearForm(0.5, 1, -2)) } - assertResult(empty) { li1.linearDisequality(LinearForm(0, 1, -2)) } - } - - describe("union") { - val u1 = dom(DenseVector(2, 0), DenseMatrix.eye(2), DenseVector(4, 2)) - val u2 = dom(DenseVector(-4, -1), DenseMatrix((-1.0, 3.0), (0.0, 1.0)), DenseVector(4, 2)) - assertResult(u2) { box union u1 } - val u3 = dom(DenseVector(-1, -1), DenseMatrix((0.0, 1.0), (1.0, -1.0)), DenseVector(2, 4)) - assertResult(u3) { u1 union diamond } - val u4 = dom(DenseVector(-4, 0), DenseMatrix.eye(2), DenseVector(-2, 2)) - val u5 = dom(DenseVector(-4, 0), DenseMatrix.eye(2), DenseVector(4, 2)) - assertResult(u5) { u4 union u1 } - val u6 = dom(DenseVector(1, Double.NegativeInfinity), DenseMatrix((1.0, 0.0), (1.0, -1.0)), DenseVector(1, 1)) - val u7 = dom(DenseVector(0, Double.NegativeInfinity), DenseMatrix((1.0, 0.0), (0.0, -1.0)), DenseVector(0, 0)) - val u8 = dom(DenseVector(0, 0), DenseMatrix.eye(2), DenseVector(1, Double.PositiveInfinity)) - assertResult(u8) { u6 union u7 } - val u9 = dom(DenseVector(0, 0), DenseMatrix.eye(2), DenseVector(0, Double.PositiveInfinity)) - assertResult(u8) { u9 union u8 } - assertResult(u8) { u8 union u9 } - val u10 = dom(DenseVector(2, 0), DenseMatrix.eye(2), DenseVector(2, 0)) - val u11 = dom(DenseVector(0, 2), DenseMatrix((0.0, 1.0), (1.0, -2.0)), DenseVector(1, 6)) - assertResult(u11) { u10 union u11 } - } - - describe("minimization, maximization and frequency") { - val i = dom(DenseVector(-4, -1, 0), DenseMatrix((-1.0, 3.0, 0.0), (0.0, 1.0, 0.0), (-1.0, -1.0, 1.0)), DenseVector(4, 2, 0)) - assertResult(12)(i.maximize(LinearForm(0, 1, 1, 0))) - assertResult(-8)(i.minimize(LinearForm(0, 1, 1, 0))) - assertResult(None)(i.frequency(LinearForm(0, 1, 1, 0))) - assertResult(Some(0))(i.frequency(LinearForm(0, -1, -1, 1))) - } - - describe("dimensional variation") { - val i = diamond - val j = dom(DenseVector(-1, -1, Double.NegativeInfinity), DenseMatrix((1.0, 1.0, 0.0), - (1.0, -1.0, 0.0), (0.0, 0.0, 1.0)), DenseVector(1, 1, Double.PositiveInfinity)) - val h = dom(DenseVector(-1, Double.NegativeInfinity), DenseMatrix((1.0, 0.0), - (0.0, 1.0)), DenseVector(1, Double.PositiveInfinity)) - assertResult(j)(i.addVariable()) - assertResult(h)(j.delVariable(0)) - assertResult(h)(j.delVariable(1)) - assertResult(i)(j.delVariable(2)) - } - - describe("dimensional maps") { - val i = diamond - val h = dom(DenseVector(-1), DenseMatrix((1.0)), DenseVector(1)) - assertResult(diamond)(diamond.mapVariables(Seq(1, 0))) - assertResult(diamond)(i.mapVariables(Seq(0, 1))) - assertResult(h)(i.mapVariables(Seq(-1, 0))) - assertResult(diamond)(diamond.addVariable.mapVariables(Seq(1, 0, -1))) - } - - describe("string representation") { - assertResult("[ -1.0 ≤ x+y ≤ 1.0 , -1.0 ≤ x-y ≤ 1.0 ]") { diamond.mkString(Seq("x", "y")) } - assertResult("empty") { empty.toString } - assertResult("[ -∞ ≤ v0 ≤ +∞ , -∞ ≤ v1 ≤ +∞ ]", full.toString) { full.toString } - } - - describe("all parallelotopes are polyhedral") { - forAll(someProperties) { (p) => assert(p.isPolyhedral) } - } - - // I am not sure it works for all possible cases due to rounding errors. - describe("all parallelotopes may be rebuilt from constraints") { - forAll(someProperties) { (p) => - assertResult(p) { p.constraints.foldLeft(p.top) { (prop, lf) => prop.linearInequality(lf) } } - } - } - -} diff --git a/core/src/test/scala/it/unich/jandom/domains/numerical/ParallelotopeRationalDomainFastSuite.scala b/core/src/test/scala/it/unich/jandom/domains/numerical/ParallelotopeRationalDomainFastSuite.scala index 4b3a333a..f24c554a 100644 --- a/core/src/test/scala/it/unich/jandom/domains/numerical/ParallelotopeRationalDomainFastSuite.scala +++ b/core/src/test/scala/it/unich/jandom/domains/numerical/ParallelotopeRationalDomainFastSuite.scala @@ -34,7 +34,7 @@ import spire.syntax.literals._ * @author Gianluca Amato */ class ParallelotopeRationalDomainFastSuite extends NumericalDomainSuite with SeparatedTopAndBottomSuite with EmptyExistsSuite { - lazy val dom = ParallelotopeRationalDomainFast() + lazy val dom = ParallelotopeRationalDomain() val box = dom(Bounds(r"-1",r"-1"), DenseMatrix.eye(2), Bounds(r"1", r"1")) val diamond = dom(Bounds(r"-1", r"-1"), DenseMatrix((r"1", r"1"), (r"1", r"-1")), Bounds(r"1", r"1")) diff --git a/core/src/test/scala/it/unich/jandom/domains/numerical/ParallelotopeRationalDomainSuite.scala b/core/src/test/scala/it/unich/jandom/domains/numerical/ParallelotopeRationalDomainSuite.scala deleted file mode 100644 index 70440dc7..00000000 --- a/core/src/test/scala/it/unich/jandom/domains/numerical/ParallelotopeRationalDomainSuite.scala +++ /dev/null @@ -1,255 +0,0 @@ -/** - * Copyright 2013 Gianluca Amato - * - * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains - * JANDOM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * JANDOM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty ofa - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with JANDOM. If not, see . - */ - -package it.unich.jandom.domains.numerical - -import scala.language.implicitConversions - -import breeze.linalg.DenseMatrix -import breeze.linalg.DenseVector -import it.unich.jandom.domains.EmptyExistsSuite -import it.unich.jandom.domains.SeparatedTopAndBottomSuite -import it.unich.jandom.utils.breeze.RationalForBreeze._ -import it.unich.jandom.utils.numberext.RationalExt -import spire.math.Rational -import spire.syntax.literals._ - -/** - * Test suite for the parallelotope domain over rationals. - * @author Gianluca Amato - */ -class ParallelotopeRationalDomainSuite extends NumericalDomainSuite with SeparatedTopAndBottomSuite with EmptyExistsSuite { - lazy val dom = ParallelotopeRationalDomain() - - val box = dom(DenseVector(r"-1",r"-1"), DenseMatrix.eye[Rational](2), DenseVector(r"1", r"1")) - val diamond = dom(DenseVector(r"-1", r"-1"), DenseMatrix((r"1", r"1"), (r"1", r"-1")), DenseVector(r"1", r"1")) - val empty = dom.bottom(2) - val full = dom.top(2) - - implicit def r(x: Int) = RationalExt(x) - - override lazy val someProperties = Table("property", dom.bottom(0), dom.bottom(1), dom.bottom(2), dom.bottom(3), dom.bottom(4), dom.bottom(4), - dom.top(0), dom.top(1), dom.top(2), dom.top(3), dom.top(4), dom.top(5), box, diamond) - - describe("constructors") { - they("should only work with compatible sizes of bounds and shapes") { - intercept[IllegalArgumentException] { dom(DenseVector(r"0", r"2"), DenseMatrix.eye(2), DenseVector(r"0", r"2", r"3")) } - } - } - - describe("constructors and extractors for non-trivial parallelotopes") { - they("should behave as expected") { - assertResult(2) { box.dimension } - assertResult(false) { box.isEmpty } - assertResult(false) { box.isTop } - } - } - - describe("constructors and extractors for full parallelotopes") { - they("should behave as expected") { - assertResult(2) { full.dimension } - assertResult(false) { full.isEmpty } - assertResult(true) { full.isTop } - } - } - - describe("constructors and extractors for empty parallelotopes") { - they("should behave as expected") { - assertResult(2) { empty.dimension } - assertResult(true) { empty.isEmpty } - assertResult(false) { empty.isTop } - } - } - - describe("comparison of parallelotopes") { - it("should behave as expected") { - assert(empty < box) - assert(box < full) - assert(empty < full) - assert(diamond < box) - assert(diamond <= box) - assert(box > diamond) - assert(box >= diamond) - assertResult(Some(1)) { box.tryCompareTo(diamond) } - assertResult(Some(-1)) { diamond.tryCompareTo(box) } - assert(box == box) - assertResult(Some(0)) { box.tryCompareTo(box) } - val box2 = dom(DenseVector(r"-1/2", r"-1/2"), DenseMatrix.eye(2), DenseVector(r"1/2", r"1/2")) - assert(box2 <= box) - assert(box >= box2) - assert(box2 < box) - assert(box > box2) - val box3 = dom(DenseVector(r"0", r"0"), DenseMatrix.eye(2), DenseVector(r"2", r"2")) - assertResult(None) { box.tryCompareTo(box3) } - } - } - - describe("rotation of shapes") { - it("should behave as expected") { - val m = DenseMatrix((r"1", r"1"), (r"-1", r"1")) - val m1 = DenseMatrix.zeros[Rational](m.rows, m.cols) - for (i <- 0 until m.rows) { for (j <- 0 until m.cols) { m1(i, j) = m(i, j) } } - val protcalc = box.rotate(m1) - val protdef = dom(DenseVector(r"-2", r"-2"), m, DenseVector(r"2", r"2")) - assertResult(protdef) { protcalc } - } - } - - describe("linear invertible assignment") { - they("should behave as expected") { - val li1 = dom(DenseVector(r"0", r"-1"), DenseMatrix((r"1", -r"1"), (r"0", r"1")), DenseVector(r"2", r"1")) - assertResult(li1) { box.linearAssignment(0, LinearForm(1, 1, 1)) } - val li2 = dom(DenseVector(r"1", r"-1"), DenseMatrix((r"1", r"0"), (r"-1", r"1")), DenseVector(r"1", r"0")) - val li3 = dom(DenseVector(r"2", r"-2"), DenseMatrix((r"1", r"0"), (r"-1", r"1")), DenseVector(r"2", r"-1")) - assertResult(li3) { li2.linearAssignment(0, LinearForm(1, 1, 0)) } - assertResult(li3) { li2.linearAssignment(0, LinearForm(1, 1)) } - val li4 = dom(DenseVector(r"-1", r"-2"), DenseMatrix((r"1", r"0"), (r"-1", r"1")), DenseVector(r"1", r"2")) - assertResult(li4) { box.linearAssignment(1, LinearForm(0, 1, 2)) } - assert(empty.linearAssignment(1, LinearForm(0, 1, 1)).isEmpty) - } - } - - describe("non-invertible linear assignment") { - they("should behave as expected") { - val ln1 = dom(DenseVector(r"2", r"-1"), DenseMatrix((r"1", r"-1"), (r"0", r"1")), DenseVector(r"2", r"1")) - assertResult(ln1) { box.linearAssignment(0, LinearForm(2, 0, 1)) } - val ln2 = dom(DenseVector(r"0", RationalExt.NegativeInfinity), DenseMatrix((r"-1", r"1"), (r"0", r"1")), DenseVector(r"0", RationalExt.PositiveInfinity)) - val ln3 = dom(DenseVector(RationalExt.NegativeInfinity, r"0"), DenseMatrix((r"1", r"-1"), (r"0", r"1")), DenseVector(RationalExt.PositiveInfinity, r"0")) - assertResult(ln2) { ln3.linearAssignment(1, LinearForm(0, 1, 0)) } - assertResult(ln2) { ln3.linearAssignment(1, LinearForm(0, 1)) } - assert(empty.linearAssignment(1, LinearForm(0, 1, 0)).isEmpty) - } - } - - describe("non-deterministic assignment") { - they("should behave as expected") { - val nd1 = dom(DenseVector(RationalExt.NegativeInfinity, r"-1"), DenseMatrix.eye(2), DenseVector(RationalExt.PositiveInfinity, r"1")) - assert(nd1<=box.nonDeterministicAssignment(0)) - assert(nd1>=box.nonDeterministicAssignment(0)) - assertResult(nd1) { box.nonDeterministicAssignment(0) } - assertResult(nd1) { nd1.nonDeterministicAssignment(0) } - assertResult(nd1) { diamond.nonDeterministicAssignment(0) } - val nd2 = dom(DenseVector(r"0", r"0"), DenseMatrix((r"2", r"1"), (r"2", -r"1")), DenseVector(r"1", r"1")) - val nd3 = dom(DenseVector(RationalExt.NegativeInfinity, r"-1"), DenseMatrix((r"2", r"1"), (r"0", r"-2")), DenseVector(RationalExt.PositiveInfinity, r"1")) - assertResult(nd3) { nd2.nonDeterministicAssignment(0) } - val nd4 = dom(DenseVector(RationalExt.NegativeInfinity, r"0"), DenseMatrix((r"2", r"1"), (r"4", r"0")), DenseVector(RationalExt.PositiveInfinity, r"2")) - assertResult(nd4) { nd2.nonDeterministicAssignment(1) } - val nd5 = dom(DenseVector(r"10", r"-1"), DenseMatrix((r"1", r"0"), (r"1", r"1")), DenseVector(r"10", r"1")) - val nd6 = dom(DenseVector(RationalExt.NegativeInfinity, r"-11"), DenseMatrix.eye[Rational](2), DenseVector(RationalExt.PositiveInfinity, r"-9")) - assertResult(nd6) { nd5.nonDeterministicAssignment(0) } - assert(empty.nonDeterministicAssignment(0).isEmpty) - } - } - - describe("linear inequalities") { - they("should behave as expected") { - val li1 = dom(DenseVector(r"-1", r"-1"), DenseMatrix((r"1", r"1"), (r"1", r"-1")), DenseVector(r"0", r"0")) - assertResult(li1) { diamond.linearInequality(LinearForm(1, 2, 0)) } - assertResult(li1) { diamond.linearInequality(LinearForm(1, 2)) } - assert(empty.linearInequality(LinearForm(-1, 1, 0)).isEmpty) - } - } - - describe("linear disequalities") { - they("should behave as expected") { - val li1 = dom(DenseVector(r"-1", r"0"), DenseMatrix((r"1",r"1"),(r"1",r"-2")), DenseVector(r"0", r"0")) - assertResult(li1) { li1.linearDisequality(1) } - assertResult(empty) { li1.linearDisequality(0) } - assertResult(li1) { li1.linearDisequality(LinearForm(1, 0, 1)) } - assertResult(li1) { li1.linearDisequality(LinearForm(0.5, 1, -2)) } - assertResult(empty) { li1.linearDisequality(LinearForm(0, 1, -2)) } - } - } - - describe("union") { - it("should behave as expected") { - val u1 = dom(DenseVector(2, 0), DenseMatrix.eye(2), DenseVector(4, 2)) - val u2 = dom(DenseVector(-4, -1), DenseMatrix((r"-1",r"3"), (r"0",r"1")), DenseVector(4, 2)) - assertResult(u2) { box union u1 } - val u3 = dom(DenseVector(-1, -1), DenseMatrix((r"0",r"1"), (r"1", r"-1")), DenseVector(2, 4)) - assertResult(u3) { u1 union diamond } - val u4 = dom(DenseVector(-4, 0), DenseMatrix.eye(2), DenseVector(-2, 2)) - val u5 = dom(DenseVector(-4, 0), DenseMatrix.eye(2), DenseVector(4, 2)) - assertResult(u5) { u4 union u1 } - val u6 = dom(DenseVector(1, RationalExt.NegativeInfinity), DenseMatrix((r"1", r"0"), (r"1", r"-1")), DenseVector(1, 1)) - val u7 = dom(DenseVector(0, RationalExt.NegativeInfinity), DenseMatrix((r"1", r"0"), (r"0", r"-1")), DenseVector(0, 0)) - val u8 = dom(DenseVector(0, 0), DenseMatrix.eye(2), DenseVector(1, RationalExt.PositiveInfinity)) - assertResult(u8) { u6 union u7 } - val u9 = dom(DenseVector(0, 0), DenseMatrix.eye(2), DenseVector(0, RationalExt.PositiveInfinity)) - assertResult(u8) { u9 union u8 } - assertResult(u8) { u8 union u9 } - val u10 = dom(DenseVector(2, 0), DenseMatrix.eye(2), DenseVector(2, 0)) - val u11 = dom(DenseVector(0, 2), DenseMatrix((r"0", r"1"), (r"1", r"-2")), DenseVector(1, 6)) - assertResult(u11) { u10 union u11 } - } - } - - describe("minimization, maximization and frequency methods") { - they("should behave as expected") { - val i = dom(DenseVector(-4, -1, 0), DenseMatrix((r"-1", r"3", r"0"), (r"0", r"1", r"0"), (r"-1", r"-1", r"1")), DenseVector(4, 2, 0)) - assertResult(12)(i.maximize(LinearForm(0, 1, 1, 0))) - assertResult(-8)(i.minimize(LinearForm(0, 1, 1, 0))) - assertResult(None)(i.frequency(LinearForm(0, 1, 1, 0))) - assertResult(Some(0), i)(i.frequency(LinearForm(0, -1, -1, 1))) - } - } - - describe("dimensional variation") { - it("should behave as expected") { - val i = diamond - val j = dom(DenseVector(-1, -1, RationalExt.NegativeInfinity), DenseMatrix((r"1",r"1",r"0"), - (r"1",r"-1",r"0"), (r"0",r"0",r"1")), DenseVector(1, 1, RationalExt.PositiveInfinity)) - val h = dom(DenseVector(-1, RationalExt.NegativeInfinity), DenseMatrix((r"1", r"0"), - (r"0",r"1")), DenseVector(1, RationalExt.PositiveInfinity)) - assertResult(j)(i.addVariable()) - assertResult(h)(j.delVariable(0)) - assertResult(h)(j.delVariable(1)) - assertResult(i)(j.delVariable(2)) - } - } - - describe("dimensional maps") { - they("should behave as expected") { - val i = diamond - val h = dom(DenseVector(-1), DenseMatrix.eye(1), DenseVector(1)) - assertResult(diamond)(diamond.mapVariables(Seq(1, 0))) - assertResult(diamond)(i.mapVariables(Seq(0, 1))) - assertResult(h)(i.mapVariables(Seq(-1, 0))) - assertResult(diamond)(diamond.addVariable.mapVariables(Seq(1, 0, -1))) - } - } - - describe("string representation") { - they("should behave as expected") { - assertResult("[ -1 ≤ x+y ≤ 1 , -1 ≤ x-y ≤ 1 ]") { diamond.mkString(Seq("x", "y")) } - assertResult("empty") { empty.toString } - assertResult("[ -∞ ≤ v0 ≤ +∞ , -∞ ≤ v1 ≤ +∞ ]", full.toString) { full.toString } - } - } - - describe("all parallelotopes") { - they("are polyehdral") { - forAll(someProperties) { (p) => assert(p.isPolyhedral) } - } - they("may be rebuilt from constraints") { - forAll(someProperties) { (p) => - assertResult(p) { p.constraints.foldLeft(p.top) { (prop, lf) => prop.linearInequality(lf) } } - } - } - } -} diff --git a/core/src/test/scala/it/unich/jandom/domains/numerical/ProductDomainSuite.scala b/core/src/test/scala/it/unich/jandom/domains/numerical/ProductDomainSuite.scala index 0ad9a5fa..cc5c7304 100644 --- a/core/src/test/scala/it/unich/jandom/domains/numerical/ProductDomainSuite.scala +++ b/core/src/test/scala/it/unich/jandom/domains/numerical/ProductDomainSuite.scala @@ -24,7 +24,7 @@ package it.unich.jandom.domains.numerical */ class ProductDomainSuite extends NumericalDomainSuite { - val dom = new ProductDomain(BoxDoubleDomain(), ParallelotopeDomain()) + val dom = new ProductDomain(BoxDoubleDomain(), ParallelotopeRationalDomain()) val n = 2 diff --git a/core/src/test/scala/it/unich/jandom/domains/numerical/SumIntParallelotopeDomainSuite.scala b/core/src/test/scala/it/unich/jandom/domains/numerical/SumIntParallelotopeDomainSuite.scala index c7bb752e..444fc431 100644 --- a/core/src/test/scala/it/unich/jandom/domains/numerical/SumIntParallelotopeDomainSuite.scala +++ b/core/src/test/scala/it/unich/jandom/domains/numerical/SumIntParallelotopeDomainSuite.scala @@ -19,23 +19,20 @@ package it.unich.jandom.domains.numerical import org.scalatest.FunSpec - import it.unich.jandom.domains.{EmptyExistsSuite, SeparatedTopAndBottomSuite} - -import breeze.linalg.DenseMatrix -import breeze.linalg.DenseVector +import it.unich.jandom.utils.numberext.{Bounds, DenseMatrix, DenseVector} /** * Test suite for the sum of interval and parallelotope domains. * @author Gianluca Amato */ class SumIntParallelotopeDomainSuite extends FunSpec with NumericalDomainSuite with SeparatedTopAndBottomSuite with EmptyExistsSuite { - lazy val dom = SumIntParallelotopeDomain() + lazy val dom = SumBoxDoubleParallelotopeRationDomain() val box1 = dom.dom1(Array(-1, -1),Array(1,1)) - val par1 = dom.dom2(DenseVector(-1,-1), DenseMatrix.eye(2), DenseVector(1,1)) - val par2 = dom.dom2(DenseVector(-1, -1), DenseMatrix((1.0, 1.0), (1.0, -1.0)), DenseVector(1, 1)) + val par1 = dom.dom2(Bounds(-1,-1), DenseMatrix.eye(2), Bounds(1,1)) + val par2 = dom.dom2(Bounds(-1, -1), DenseMatrix(DenseVector(1.0, 1.0), DenseVector(1.0, -1.0)), Bounds(1, 1)) override lazy val someProperties = Table("property", dom.bottom(0), dom.bottom(1), dom.bottom(2), dom.bottom(3), dom.bottom(4), dom.bottom(4), dom.top(0), dom.top(1), dom.top(2), dom.top(3), dom.top(4), dom.top(5), dom(box1, par1), dom(box1, par2)) diff --git a/core/src/test/scala/it/unich/jandom/utils/breeze/CountNonZeroTestSuite.scala b/core/src/test/scala/it/unich/jandom/utils/breeze/CountNonZeroTestSuite.scala deleted file mode 100644 index 53119e54..00000000 --- a/core/src/test/scala/it/unich/jandom/utils/breeze/CountNonZeroTestSuite.scala +++ /dev/null @@ -1,34 +0,0 @@ -/** - * Copyright 2014 Gianluca Amato - * - * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains - * JANDOM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * JANDOM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty ofa - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with JANDOM. If not, see . - */ - -package it.unich.jandom.utils.breeze - -import org.scalatest.FunSuite - -/** - * Test suite for the countNonZero universal function. - */ -class CountNonZeroTestSuite extends FunSuite { - - test("countNonZero only counts non-zero elements") { - assertResult(2) { countNonZero(Seq[Double](0,1,2))} - assertResult(3) { countNonZero(Seq[Double](1,1,2))} - assertResult(0) { countNonZero(Seq[Double](0,0,0))} - } - -} diff --git a/extended/src/test/scala/it/unich/jandom/benchmarks/EQSLegacyFASTComparison.scala b/extended/src/test/scala/it/unich/jandom/benchmarks/EQSLegacyFASTComparison.scala index 1ee13202..7fac55a8 100644 --- a/extended/src/test/scala/it/unich/jandom/benchmarks/EQSLegacyFASTComparison.scala +++ b/extended/src/test/scala/it/unich/jandom/benchmarks/EQSLegacyFASTComparison.scala @@ -18,20 +18,11 @@ package it.unich.jandom.benchmarks -import it.unich.jandom.domains.numerical.BoxDoubleDomain -import it.unich.jandom.targets.EQSSolver -import it.unich.jandom.targets.Parameters +import it.unich.jandom.domains.numerical.ParallelotopeRationalDomain +import it.unich.jandom.targets.{EQSSolver, Parameters} import it.unich.jandom.targets.lts._ import it.unich.jandom.targets.parameters._ -import it.unich.scalafix.Assignment -import it.unich.jandom.domains.numerical.ParallelotopeDomain -import parma_polyhedra_library.C_Polyhedron -import it.unich.jandom.domains.numerical.ppl.PPLDomainMacro -import java.io.Writer -import java.io.PrintWriter -import java.io.OutputStreamWriter -import it.unich.jandom.domains.numerical.ParallelotopeRationalDomain -import it.unich.scalafix.FixpointSolverListener +import it.unich.scalafix.{Assignment, FixpointSolverListener} /** * This program compares standard (legacy) analyzer with the new one based on Scalafix for @@ -41,7 +32,7 @@ import it.unich.scalafix.FixpointSolverListener object EQSLegacyFASTComparison extends App with FASTLoader { - val dom = ParallelotopeDomain() + val dom = ParallelotopeRationalDomain() def compareResults(locations: Seq[Location], ann1: Assignment[Location, dom.Property], ann2: Assignment[Location, dom.Property]) = { var lt, eq, gt, un = 0 From bcce3bd0d6ee8b3de80008d53c6f15d1319650c8 Mon Sep 17 00:00:00 2001 From: Gianluca Amato Date: Wed, 31 May 2017 11:16:41 +0200 Subject: [PATCH 20/99] Fix mkString for parallelotopes. --- .../domains/numerical/ParallelotopeRationalDomain.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/main/scala/it/unich/jandom/domains/numerical/ParallelotopeRationalDomain.scala b/core/src/main/scala/it/unich/jandom/domains/numerical/ParallelotopeRationalDomain.scala index dfe73224..873203e7 100644 --- a/core/src/main/scala/it/unich/jandom/domains/numerical/ParallelotopeRationalDomain.scala +++ b/core/src/main/scala/it/unich/jandom/domains/numerical/ParallelotopeRationalDomain.scala @@ -861,9 +861,9 @@ class ParallelotopeRationalDomain private(favorAxis: Int) extends NumericalDomai else { val eqns = for (i <- 0 until dimension) yield { if (low(i) < high(i)) - s"${if (low(i).isNegInfinity) "-∞" else low(i)} ≤ ${lfToString(A.col(i))} ≤ ${if (high(i).isPosInfinity) "+∞" else high(i)}" + s"${if (low(i).isNegInfinity) "-∞" else low(i)} ≤ ${lfToString(A.row(i))} ≤ ${if (high(i).isPosInfinity) "+∞" else high(i)}" else - s"${lfToString(A.col(i))} = ${high(i)}" + s"${lfToString(A.row(i))} = ${high(i)}" } eqns.mkString("[ ", " , ", " ]") } From 3c0e73e18b124266345b0b5f2f1931c9a42555e4 Mon Sep 17 00:00:00 2001 From: Gianluca Amato Date: Mon, 24 Apr 2017 14:57:46 +0200 Subject: [PATCH 21/99] Remove useless code in EQSLegacyFASTComparison. --- .../it/unich/jandom/benchmarks/EQSLegacyFASTComparison.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extended/src/test/scala/it/unich/jandom/benchmarks/EQSLegacyFASTComparison.scala b/extended/src/test/scala/it/unich/jandom/benchmarks/EQSLegacyFASTComparison.scala index 7fac55a8..0322d595 100644 --- a/extended/src/test/scala/it/unich/jandom/benchmarks/EQSLegacyFASTComparison.scala +++ b/extended/src/test/scala/it/unich/jandom/benchmarks/EQSLegacyFASTComparison.scala @@ -80,7 +80,7 @@ object EQSLegacyFASTComparison extends App with FASTLoader { var timeLTS = 0.0 var timeTemp = 0.0 var globaleq, globallt, globalgt, globalun = 0 - for (lts <- ltss; eqs = lts.toEQS(dom)) { + for (lts <- ltss) { timeTemp = java.lang.System.currentTimeMillis() val res1 = EQSSolver(lts)(dom)(params, FixpointSolverListener.EmptyListener) timeEQS += (java.lang.System.currentTimeMillis() - timeTemp) From b7414ea2e132cc7fbab4810b1251165a01f4e824 Mon Sep 17 00:00:00 2001 From: Gianluca Amato Date: Tue, 25 Apr 2017 18:11:42 +0200 Subject: [PATCH 22/99] Fix toDot method to work with multiple locations with same label. --- .../src/main/scala/it/unich/jandom/targets/lts/LTS.scala | 9 ++++++--- .../test/scala/it/unich/jandom/targets/LTSSuite.scala | 6 ++++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/core/src/main/scala/it/unich/jandom/targets/lts/LTS.scala b/core/src/main/scala/it/unich/jandom/targets/lts/LTS.scala index 3fa347f6..e362c179 100644 --- a/core/src/main/scala/it/unich/jandom/targets/lts/LTS.scala +++ b/core/src/main/scala/it/unich/jandom/targets/lts/LTS.scala @@ -103,11 +103,14 @@ case class LTS(val name: String, val locations: IndexedSeq[Location], val transi val builder = new StringBuilder() builder ++= "digraph {\n" - val initState = regions find { _.name == "init" } flatMap { _.state } + val initState = regions find (_.name == "init") flatMap (_.state) if (initState.isDefined) - builder ++= s""" "${StringEscapeUtils.escapeJava(initState.get.name)}" [shape=doublecircle]\n""" + builder ++= s""" "${initState.get.id}" [shape=doublecircle]\n""" + for (l <- locations) { + builder ++= s""" "${l.id}" [label="${StringEscapeUtils.escapeJava(l.name)}"]\n""" + } for (t <- transitions) { - builder ++= s""" "${StringEscapeUtils.escapeJava(t.start.name)}" -> "${ StringEscapeUtils.escapeJava(t.end.name)}" [label="${StringEscapeUtils.escapeJava(t.name)}"]\n""" + builder ++= s""" "${t.start.id}" -> "${t.end.id}" [label="${StringEscapeUtils.escapeJava(t.name)}"]\n""" } builder ++= "}\n" builder.toString diff --git a/core/src/test/scala/it/unich/jandom/targets/LTSSuite.scala b/core/src/test/scala/it/unich/jandom/targets/LTSSuite.scala index a0047186..f57b7c2d 100644 --- a/core/src/test/scala/it/unich/jandom/targets/LTSSuite.scala +++ b/core/src/test/scala/it/unich/jandom/targets/LTSSuite.scala @@ -54,8 +54,10 @@ class LTSSuite extends FunSuite { test("dot translation") { val output = """digraph { - | "start" -> "ciclo" [label="init"] - | "ciclo" -> "ciclo" [label="loop"] + | "0" [label="start"] + | "1" [label="ciclo"] + | "0" -> "1" [label="init"] + | "1" -> "1" [label="loop"] |} |""".stripMargin('|') assertResult(output)(LTS1.lts.toDot) From ed32c3fbc94fe410df847e9d5c5e1f243324db9a Mon Sep 17 00:00:00 2001 From: Gianluca Amato Date: Thu, 20 Jul 2017 23:27:51 +0200 Subject: [PATCH 23/99] Fix URL for Soot repositories. --- build.sbt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.sbt b/build.sbt index 95f718a3..22a4f0c1 100644 --- a/build.sbt +++ b/build.sbt @@ -29,8 +29,8 @@ fork in ThisBuild := true resolvers in ThisBuild ++= Seq( Resolver.sonatypeRepo("releases"), Resolver.sonatypeRepo("snapshots"), - "Soot snapshot" at "http://soot-build.cs.uni-paderborn.de/nexus/repository/soot-snapshot/", - "Soot release" at "http://soot-build.cs.uni-paderborn.de/nexus/repository/soot-release/" + "Soot snapshot" at "https://soot-build.cs.uni-paderborn.de/nexus/repository/soot-snapshot/", + "Soot release" at "https://soot-build.cs.uni-paderborn.de/nexus/repository/soot-release/" ) //*** Detect PPL From 17be1b0869d71d64a805fc2ee477bf331662f216 Mon Sep 17 00:00:00 2001 From: Gianluca Amato Date: Mon, 7 Aug 2017 14:35:57 +0200 Subject: [PATCH 24/99] Fix minimize/maximize methods. --- .../numerical/ppl/PPLDomainMacro.scala | 44 +++++++++++-------- 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLDomainMacro.scala b/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLDomainMacro.scala index 69b3f748..7f8ee846 100644 --- a/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLDomainMacro.scala +++ b/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLDomainMacro.scala @@ -201,27 +201,35 @@ object PPLDomainMacro { } def minimize(lf: LinearForm) = { - val (le, den) = PPLUtils.toPPLLinearExpression(lf) - val exact = new By_Reference[java.lang.Boolean](false) - val val_n = new Coefficient(0) - val val_d = new Coefficient(0) - val result = pplobject.minimize(le, val_n, val_d, exact) - if (!result) - RationalExt.NegativeInfinity - else - RationalExt(val_n.getBigInteger(), val_d.getBigInteger().multiply(den.getBigInteger())) + if (pplobject.is_empty()) + RationalExt.PositiveInfinity + else { + val (le, den) = PPLUtils.toPPLLinearExpression(lf) + val exact = new By_Reference[java.lang.Boolean](false) + val val_n = new Coefficient(0) + val val_d = new Coefficient(0) + val result = pplobject.minimize(le, val_n, val_d, exact) + if (!result) + RationalExt.NegativeInfinity + else + RationalExt(val_n.getBigInteger(), val_d.getBigInteger().multiply(den.getBigInteger())) + } } def maximize(lf: LinearForm) = { - val (le, den) = PPLUtils.toPPLLinearExpression(lf) - val exact = new By_Reference[java.lang.Boolean](false) - val val_n = new Coefficient(0) - val val_d = new Coefficient(0) - val result = pplobject.maximize(le, val_n, val_d, exact) - if (!result) - RationalExt.PositiveInfinity - else - RationalExt(val_n.getBigInteger(), val_d.getBigInteger().multiply(den.getBigInteger())) + if (pplobject.is_empty()) + RationalExt.NegativeInfinity + else { + val (le, den) = PPLUtils.toPPLLinearExpression(lf) + val exact = new By_Reference[java.lang.Boolean](false) + val val_n = new Coefficient(0) + val val_d = new Coefficient(0) + val result = pplobject.maximize(le, val_n, val_d, exact) + if (!result) + RationalExt.PositiveInfinity + else + RationalExt(val_n.getBigInteger(), val_d.getBigInteger().multiply(den.getBigInteger())) + } } def frequency(lf: LinearForm) = { From fad5eb599e479870988e31c6b44b90e55aae6c9f Mon Sep 17 00:00:00 2001 From: Gianluca Amato Date: Mon, 7 Aug 2017 14:37:24 +0200 Subject: [PATCH 25/99] Add default widening as the first widening for PPL domains. --- .../it/unich/jandom/domains/numerical/ppl/PPLDomainMacro.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLDomainMacro.scala b/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLDomainMacro.scala index 7f8ee846..c952d2d6 100644 --- a/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLDomainMacro.scala +++ b/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLDomainMacro.scala @@ -328,7 +328,7 @@ object PPLDomainMacro { def apply(x: $PPLTypeTag): ThisProperty = new ThisProperty(x) - val widenings = Seq(..$widenings) + val widenings = WideningDescription.default[Property] +: Seq(..$widenings) } ThisDomain From 24e92782d9d9b3dd556b5a8dfe7aa346ceeb1622 Mon Sep 17 00:00:00 2001 From: Gianluca Amato Date: Mon, 7 Aug 2017 14:46:58 +0200 Subject: [PATCH 26/99] Do not use doubles for coefficients in linear forms. --- .../unich/jandom/domains/numerical/ppl/PPLBoxDouble.scala | 4 ++-- .../unich/jandom/domains/numerical/ppl/PPLProperty.scala | 6 +++--- .../it/unich/jandom/targets/jvmsoot/JimpleMethod.scala | 2 +- .../jandom/domains/numerical/ppl/PPLDomainSuite.scala | 4 ++-- .../jandom/domains/numerical/ProductDomainSuite.scala | 8 ++++---- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLBoxDouble.scala b/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLBoxDouble.scala index a29f07fd..060e0510 100644 --- a/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLBoxDouble.scala +++ b/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLBoxDouble.scala @@ -129,7 +129,7 @@ final class PPLBoxDouble(val pplbox: Double_Box) extends NumericalProperty[PPLBo def maximize(lf: LinearForm) = { if (isEmpty) { - if (lf.homcoeffs.forall(_ == 0.0)) + if (lf.homcoeffs.forall(_ == Rational.zero)) RationalExt(lf.known) else RationalExt.NegativeInfinity @@ -148,7 +148,7 @@ final class PPLBoxDouble(val pplbox: Double_Box) extends NumericalProperty[PPLBo def frequency(lf: LinearForm) = { if (isEmpty) { - if (lf.homcoeffs.forall(_ == 0.0)) + if (lf.homcoeffs.forall(_ == Rational.zero)) Option(lf.known) else Option.empty diff --git a/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLProperty.scala b/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLProperty.scala index 52949a6b..34f3cdcc 100644 --- a/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLProperty.scala +++ b/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLProperty.scala @@ -113,7 +113,7 @@ class PPLProperty[PPLNativeProperty <: AnyRef](val domain: PPLDomain[PPLNativePr def minimize(lf: LinearForm) = { if (isEmpty) { - if (lf.homcoeffs.forall(_ == 0.0)) + if (lf.homcoeffs.forall(_ == Rational.zero)) lf.known else RationalExt.PositiveInfinity @@ -132,7 +132,7 @@ class PPLProperty[PPLNativeProperty <: AnyRef](val domain: PPLDomain[PPLNativePr def maximize(lf: LinearForm) = { if (isEmpty) { - if (lf.homcoeffs.forall(_ == 0.0)) + if (lf.homcoeffs.forall(_ == Rational.zero)) lf.known else RationalExt.NegativeInfinity @@ -151,7 +151,7 @@ class PPLProperty[PPLNativeProperty <: AnyRef](val domain: PPLDomain[PPLNativePr def frequency(lf: LinearForm) = { if (isEmpty) { - if (lf.homcoeffs.forall(_ == 0.0)) + if (lf.homcoeffs.forall(_ == Rational.zero)) Option(lf.known) else Option.empty diff --git a/core/src/main/scala/it/unich/jandom/targets/jvmsoot/JimpleMethod.scala b/core/src/main/scala/it/unich/jandom/targets/jvmsoot/JimpleMethod.scala index d8aa6509..b8d4e0c8 100644 --- a/core/src/main/scala/it/unich/jandom/targets/jvmsoot/JimpleMethod.scala +++ b/core/src/main/scala/it/unich/jandom/targets/jvmsoot/JimpleMethod.scala @@ -48,7 +48,7 @@ class JimpleMethod(method: SootMethod) extends SootCFG[JimpleMethod, Block](meth */ def jimpleExprToLinearForm(v: Value): Option[Array[Rational]] = { val a = Array.fill(size + 1)(Rational.zero) - var c = 0.0 + var c = Rational.zero v match { case v: IntConstant => a(0) = v.value diff --git a/core/src/test/ppl/it/unich/jandom/domains/numerical/ppl/PPLDomainSuite.scala b/core/src/test/ppl/it/unich/jandom/domains/numerical/ppl/PPLDomainSuite.scala index 9d7f61af..fe7672bb 100644 --- a/core/src/test/ppl/it/unich/jandom/domains/numerical/ppl/PPLDomainSuite.scala +++ b/core/src/test/ppl/it/unich/jandom/domains/numerical/ppl/PPLDomainSuite.scala @@ -121,8 +121,8 @@ class PPLDomainSuiteOctagon extends { val dom = PPLDomain[Octagonal_Shape_double } describe("Test string conversion for high-dimensional spaces") { - val a = Array.fill(34)(0.0) - a(27) = 1.0 + val a = Array.fill(34)(0) + a(27) = 1 val obj3 = dom.top(33).linearInequality(LinearForm.v(27)) assertResult("[ -v27 >= 0 ]") { obj3.toString } } diff --git a/core/src/test/scala/it/unich/jandom/domains/numerical/ProductDomainSuite.scala b/core/src/test/scala/it/unich/jandom/domains/numerical/ProductDomainSuite.scala index cc5c7304..e1232d7c 100644 --- a/core/src/test/scala/it/unich/jandom/domains/numerical/ProductDomainSuite.scala +++ b/core/src/test/scala/it/unich/jandom/domains/numerical/ProductDomainSuite.scala @@ -65,16 +65,16 @@ class ProductDomainSuite extends NumericalDomainSuite { } describe("assignment on product") { - val x2 = full.linearAssignment(0, 0.0) + val x2 = full.linearAssignment(0, 0) assertResult(x2) { new dom.Property( - dom.dom1.top(2).linearAssignment(0, 0.0), - ptopeFull.linearAssignment(0, 0.0)) + dom.dom1.top(2).linearAssignment(0, 0), + ptopeFull.linearAssignment(0, 0)) } } describe("dimension on product") { - val x2 = full.linearAssignment(0, 0.0) + val x2 = full.linearAssignment(0, 0) assertResult(3) { x2.addVariable().dimension } assertResult(n + 1) { full.addVariable().dimension } } From 6979141f81e94e417a3751e9b160e3af5ed2642b Mon Sep 17 00:00:00 2001 From: Gianluca Amato Date: Mon, 7 Aug 2017 15:01:53 +0200 Subject: [PATCH 27/99] Fix comments. --- .../domains/numerical/ppl/PPLBoxDoubleDomain.scala | 1 - .../unich/jandom/domains/WideningDescription.scala | 12 ++++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLBoxDoubleDomain.scala b/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLBoxDoubleDomain.scala index 251d75cd..fe8c5b5a 100644 --- a/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLBoxDoubleDomain.scala +++ b/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLBoxDoubleDomain.scala @@ -32,7 +32,6 @@ import parma_polyhedra_library.Double_Box * * This class could me removed in favor of `PPLDomain[C_Polyehdron]` and the analogous macro-based * domain, but we keep it here since it the simplest PPL class in which to tinker around. - * @param pplbox an object of class `Double_Box` which is the $PPL wrapped object. * @author Gianluca Amato */ class PPLBoxDoubleDomain extends NumericalDomain { diff --git a/core/src/main/scala/it/unich/jandom/domains/WideningDescription.scala b/core/src/main/scala/it/unich/jandom/domains/WideningDescription.scala index 8fe14701..8afe71e4 100644 --- a/core/src/main/scala/it/unich/jandom/domains/WideningDescription.scala +++ b/core/src/main/scala/it/unich/jandom/domains/WideningDescription.scala @@ -21,14 +21,14 @@ import it.unich.scalafix.Box /** * The description of a widening. - * @tparam the type of objects on which the widening operates. - * @param box the box which implements the widening. + * @tparam Property type of objects on which the widening operates. * @param name short name of the widening. - * @param description long description of the widening. + * @param description long description of the widening + * @param box the box which implements the widening. */ class WideningDescription[Property](val name: String, val description: String, val box: Box[Property]) { /** - * Application of widening is equivalent to the application of the underlying box. + * Application of widening description is equivalent to the application of the underlying box. */ def apply(a: Property, b: Property) = box(a, b) } @@ -39,10 +39,10 @@ class WideningDescription[Property](val name: String, val description: String, v object WideningDescription { /** * Builds a widening description. - * @tparam the type of objects on which the widening operates. - * @param box the box which implements the widening. + * @tparam Property type of objects on which the widening operates. * @param name short name of the widening. * @param description long description of the widening. + * @param box the box which implements the widening. */ def apply[Property](name: String, description: String, box: Box[Property]) = new WideningDescription(name, description, box) From 4555978ad5484e11d2cf8185d1f55bd2c9557bcb Mon Sep 17 00:00:00 2001 From: Gianluca Amato Date: Mon, 7 Aug 2017 15:03:09 +0200 Subject: [PATCH 28/99] Small optimization for widening. --- .../jandom/domains/numerical/ParallelotopeRationalDomain.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/scala/it/unich/jandom/domains/numerical/ParallelotopeRationalDomain.scala b/core/src/main/scala/it/unich/jandom/domains/numerical/ParallelotopeRationalDomain.scala index 873203e7..06ddb78e 100644 --- a/core/src/main/scala/it/unich/jandom/domains/numerical/ParallelotopeRationalDomain.scala +++ b/core/src/main/scala/it/unich/jandom/domains/numerical/ParallelotopeRationalDomain.scala @@ -202,7 +202,6 @@ class ParallelotopeRationalDomain private(favorAxis: Int) extends NumericalDomai if (isEmpty) that else { - val thatRotated = that.rotate(A) val thisRotated = this.rotate(that.A) if (thisRotated < that) { val newlow = thisRotated.low.copy @@ -213,6 +212,7 @@ class ParallelotopeRationalDomain private(favorAxis: Int) extends NumericalDomai } new Property(false, newlow, that.A, newhigh) } else { + val thatRotated = that.rotate(A) val newlow = low.copy val newhigh = high.copy for (i <- 0 to dimension - 1) { From 30d6a0a4edc5aa87d550a5f97f6fc636a528dd2d Mon Sep 17 00:00:00 2001 From: Gianluca Amato Date: Mon, 7 Aug 2017 15:08:16 +0200 Subject: [PATCH 29/99] Add support for multiple widenings to PPLDomain. --- .../domains/numerical/ppl/PPLDomain.scala | 41 ++++++++++--------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLDomain.scala b/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLDomain.scala index 824c2969..bb541a62 100644 --- a/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLDomain.scala +++ b/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLDomain.scala @@ -1,5 +1,5 @@ /** - * Copyright 2013, 2016 Gianluca Amato + * Copyright 2013, 2016, 2017 Gianluca Amato * * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains * JANDOM is free software: you can redistribute it and/or modify @@ -18,21 +18,10 @@ package it.unich.jandom.domains.numerical.ppl -import it.unich.jandom.domains.DomainTransformation -import it.unich.jandom.domains.WideningDescription import it.unich.jandom.domains.numerical.NumericalDomain -import parma_polyhedra_library.By_Reference -import parma_polyhedra_library.Coefficient -import parma_polyhedra_library.Complexity_Class -import parma_polyhedra_library.Congruence_System -import parma_polyhedra_library.Constraint -import parma_polyhedra_library.Constraint_System -import parma_polyhedra_library.Degenerate_Element -import parma_polyhedra_library.Linear_Expression -import parma_polyhedra_library.Partial_Function -import parma_polyhedra_library.Polyhedron -import parma_polyhedra_library.Variable -import parma_polyhedra_library.Variables_Set +import it.unich.jandom.domains.{DomainTransformation, WideningDescription} +import it.unich.scalafix.Box +import parma_polyhedra_library._ /** * This is the domain of PPL properties. It is able to represent (almost) any property @@ -50,8 +39,6 @@ class PPLDomain[PPLNativeProperty <: AnyRef: Manifest] extends NumericalDomain { PPLInitializer - val widenings = Seq(WideningDescription.default[Property]) - /* * The class object corresponding to PPLNativeProperty */ @@ -123,11 +110,28 @@ class PPLDomain[PPLNativeProperty <: AnyRef: Manifest] extends NumericalDomain { private[domains] def frequency(me: PPLNativeProperty, le: Linear_Expression, freq_n: Coefficient, freq_d: Coefficient, val_n: Coefficient, val_d: Coefficient) = frequencyHandle.invoke(me, le, freq_n, freq_d, val_n, val_d).asInstanceOf[java.lang.Boolean].booleanValue() - /** + /** * It is true if `PPLNativeProperty` has the `CC76_narrowing_assign` method. */ val supportsNarrowing = narrowingAssignHandle != null + private val wideningsList = for { + m <- myClass.getMethods() + name = m.getName + if name.toString.endsWith("_widening_assign") + wideningName = name.toString.stripSuffix("_widening_assign") + } yield + WideningDescription(wideningName, s"The PPL widening using the ${name.toString} method", + Box.apply[Property] { (a: Property, b: Property) => { + val newpplobject = copyConstructor(a.pplobject) + upper_bound_assign(newpplobject,b.pplobject) + m.invoke(newpplobject, a.pplobject, null) + new PPLProperty(this, newpplobject) + } + }) + + val widenings = WideningDescription.default[Property] +: wideningsList.toSeq + def top(n: Int): Property = { val pplobject = constructor(n, Degenerate_Element.UNIVERSE) new PPLProperty(this, pplobject) @@ -141,7 +145,6 @@ class PPLDomain[PPLNativeProperty <: AnyRef: Manifest] extends NumericalDomain { /** * Build a PPL property from a PPL property of other type. Conversion is slow because the right constructor * is looked up at runtime. - * @tparam PPLSourceProperty the class of the native PPL property * @param x the source `PPLProperty` * @return x transformed into a `PPLPropert[PPLNativeProperty]` */ From a4b50dd3c6e5f0d69845339cd2d2a4112aa24bf5 Mon Sep 17 00:00:00 2001 From: Gianluca Amato Date: Mon, 7 Aug 2017 15:11:28 +0200 Subject: [PATCH 30/99] Add support for narrowing descriptions in abstract domains. This is similar to the current support for widening descriptions. --- .../unich/jandom/domains/AbstractDomain.scala | 17 ++++++ .../jandom/domains/NarrowingDescription.scala | 55 +++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 core/src/main/scala/it/unich/jandom/domains/NarrowingDescription.scala diff --git a/core/src/main/scala/it/unich/jandom/domains/AbstractDomain.scala b/core/src/main/scala/it/unich/jandom/domains/AbstractDomain.scala index 83047678..45c40cc1 100644 --- a/core/src/main/scala/it/unich/jandom/domains/AbstractDomain.scala +++ b/core/src/main/scala/it/unich/jandom/domains/AbstractDomain.scala @@ -37,17 +37,34 @@ trait AbstractDomain { */ def defaultWidening = widenings.head.box + /** + * Returns the default narrowing of the domain. It should correspond to the narrowing method of + * the ``it.unich.jandom.domains.AbstractProperty`` class. + */ + def defaultNarrowing = narrowings.head.box + /** * Returns the widening with the given name. */ def widening(name: String) = widenings.find ( _.name == name ).get.box + /** + * Returns the narrowing with the given name. + */ + def narrowing(name: String) = narrowings.find ( _.name == name ).get.box + /** * A non-empty set of widenings supported by the abstract domain. The first element is supposed to be * the default widening. */ def widenings: Seq[WideningDescription[Property]] + /** + * A non-empty set of narrowings supported by the abstract domain. The first element is supposed to be + * the default narrowing. + */ + def narrowings: Seq[NarrowingDescription[Property]] = Seq(NarrowingDescription.default[Property]) + /** * ScalaFixDomain is an instance of the ScalaFix type-class Domain for this abstract domain. */ diff --git a/core/src/main/scala/it/unich/jandom/domains/NarrowingDescription.scala b/core/src/main/scala/it/unich/jandom/domains/NarrowingDescription.scala new file mode 100644 index 00000000..344c28ef --- /dev/null +++ b/core/src/main/scala/it/unich/jandom/domains/NarrowingDescription.scala @@ -0,0 +1,55 @@ +/** + * Copyright 2017 Gianluca Amato + * + * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains + * JANDOM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * JANDOM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of a + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with JANDOM. If not, see . + */ +package it.unich.jandom.domains + +import it.unich.scalafix.Box + +/** + * The description of a narrowing. + * @tparam Property type of objects on which the narrowing operates. + * @param name short name of the narrowing. + * @param description long description of the narrowing. + * @param box the box which implements the narrowing. + */ +class NarrowingDescription[Property](val name: String, val description: String, val box: Box[Property]) { + /** + * Application of narrowing description is equivalent to the application of the underlying box. + */ + def apply(a: Property, b: Property) = box(a, b) +} + +/** + * Companion object for narrowing description. It contains factory methods. + */ +object NarrowingDescription { + /** + * Builds a narrowing description. + * @tparam Property type of objects on which the narrowing operates. + * @param name short name of the narrowing. + * @param description long description of the narrowing. + * @param box the box which implements the narrowing. + */ + def apply[Property](name: String, description: String, box: Box[Property]) = + new NarrowingDescription(name, description, box) + + /** + * Returns the description of the standard narrowing for abstract property `Property`. + */ + def default[Property <: AbstractProperty[Property]] = + NarrowingDescription("default", "The default narrowing.", Box { (a: Property, b: Property) => a narrowing b }) +} From 4bbb506151e154f0feeed791c89ac3460a423e2d Mon Sep 17 00:00:00 2001 From: Gianluca Amato Date: Mon, 7 Aug 2017 18:43:29 +0200 Subject: [PATCH 31/99] Upgrade to ScalaFix 0.6 and support non-default boxes in EQSSolver. --- core/build.sbt | 2 +- .../it/unich/jandom/targets/EQSSolver.scala | 44 +++++++++---------- .../it/unich/jandom/targets/Parameters.scala | 4 +- .../jandom/targets/cfg/ControlFlowGraph.scala | 11 ++--- .../it/unich/jandom/targets/lts/LTS.scala | 4 +- .../unich/jandom/targets/slil/WhileStmt.scala | 4 +- .../benchmarks/EQSLegacyFASTComparison.scala | 2 +- .../jandom/benchmarks/FASTComparison.scala | 2 +- 8 files changed, 32 insertions(+), 41 deletions(-) diff --git a/core/build.sbt b/core/build.sbt index 233653bc..ef292ecb 100644 --- a/core/build.sbt +++ b/core/build.sbt @@ -6,7 +6,7 @@ libraryDependencies ++= Seq( "org.scalacheck" %% "scalacheck" % "1.13.3" % "test", "org.mockito" % "mockito-core" % "2.2.9" % "test", "org.spire-math" %% "spire" % "0.12.0", - "it.unich.scalafix" %% "scalafix" % "0.5.2", + "it.unich.scalafix" %% "scalafix" % "0.6.0", "org.rogach" %% "scallop" % "2.0.3", "org.scala-lang.modules" %% "scala-swing" % "1.0.2", "org.scala-lang.modules" %% "scala-parser-combinators" % "1.0.4", diff --git a/core/src/main/scala/it/unich/jandom/targets/EQSSolver.scala b/core/src/main/scala/it/unich/jandom/targets/EQSSolver.scala index fac80114..1f2cfc6e 100644 --- a/core/src/main/scala/it/unich/jandom/targets/EQSSolver.scala +++ b/core/src/main/scala/it/unich/jandom/targets/EQSSolver.scala @@ -18,17 +18,10 @@ package it.unich.jandom.targets -import it.unich.jandom.targets.parameters.NarrowingSpecs._ -import it.unich.jandom.targets.parameters.WideningNarrowingLocation -import it.unich.jandom.targets.parameters.WideningSpecs._ -import it.unich.scalafix._ +import it.unich.jandom.targets.parameters.{IterationStrategy, WideningNarrowingLocation, WideningScope} import it.unich.scalafix.FixpointSolver._ -import it.unich.scalafix.FixpointSolverListener.EmptyListener -import it.unich.scalafix.finite.FiniteFixpointSolver -import it.unich.scalafix.finite.FiniteFixpointSolver._ -import it.unich.scalafix.finite.GraphEquationSystem -import it.unich.jandom.targets.parameters.IterationStrategy -import it.unich.jandom.domains.AbstractDomain +import it.unich.scalafix._ +import it.unich.scalafix.finite.{FiniteFixpointSolver, GraphEquationSystem} /** * This is a solver for equations systems which takes a Parameters object in order to drive @@ -36,35 +29,38 @@ import it.unich.jandom.domains.AbstractDomain */ object EQSSolver { - def apply[Tgt <: Target[Tgt]](tgt: Tgt)(dom: tgt.DomainBase) - (params: Parameters[Tgt], listener: FixpointSolverListener[tgt.ProgramPoint, dom.Property] = FixpointSolverListener.EmptyListener) - : Assignment[tgt.ProgramPoint, dom.Property] = { - implicit val scalafixDomain = dom.ScalaFixDomain + def apply[Tgt <: Target[Tgt]](tgt: Tgt)(dom: tgt.DomainBase)(params: Parameters[Tgt] { val domain: dom.type })(listener: FixpointSolverListener[tgt.ProgramPoint, params.domain.Property] = FixpointSolverListener.EmptyListener) + : Assignment[tgt.ProgramPoint, params.domain.Property] = { + import params._ + implicit val scalafixDomain = params.domain.ScalaFixDomain if (params.wideningLocation != params.narrowingLocation) - throw new IllegalArgumentException("widening and narrowing locations shoule be the same"); - - val widening = DefaultWidening.get(dom) - val narrowing = DefaultNarrowing.get(dom) + throw new IllegalArgumentException("widening and narrowing locations should be the same"); - val boxlocation = params.wideningLocation match { + val boxlocation = wideningLocation match { case WideningNarrowingLocation.None => BoxLocation.None case WideningNarrowingLocation.All => BoxLocation.All case WideningNarrowingLocation.Loop => BoxLocation.Loop } - val solver = params.iterationStrategy match { + val solver = iterationStrategy match { case IterationStrategy.Kleene => Solver.KleeneSolver case IterationStrategy.Worklist => Solver.WorkListSolver } - val eqs = tgt.toEQS(dom) - val eqsParams = FiniteFixpointSolver.CC77[tgt.ProgramPoint, dom.Property](solver, widening, narrowing).copy( - boxlocation = boxlocation, listener = listener + val scope = wideningScope match { + case WideningScope.Output => BoxScope.Standard + case WideningScope.Random => BoxScope.Localized + case WideningScope.BackEdges => ??? + } + + val eqs = tgt.toEQS(params.domain) + val eqsParams = FiniteFixpointSolver.CC77[tgt.ProgramPoint, params.domain.Property](solver, widening, narrowing).copy( + boxlocation = boxlocation, boxscope = scope, listener = listener ) eqs match { - case eqs: GraphEquationSystem[tgt.ProgramPoint, dom.Property, _] => FiniteFixpointSolver(eqs, eqsParams) + case eqs: GraphEquationSystem[tgt.ProgramPoint, domain.Property, _] => FiniteFixpointSolver(eqs, eqsParams) case _ => ??? } } diff --git a/core/src/main/scala/it/unich/jandom/targets/Parameters.scala b/core/src/main/scala/it/unich/jandom/targets/Parameters.scala index 318cce52..6e599e57 100644 --- a/core/src/main/scala/it/unich/jandom/targets/Parameters.scala +++ b/core/src/main/scala/it/unich/jandom/targets/Parameters.scala @@ -21,8 +21,6 @@ package it.unich.jandom.targets import it.unich.jandom.targets.parameters._ import it.unich.jandom.targets.parameters.NarrowingSpecs._ import it.unich.jandom.targets.parameters.WideningSpecs._ -import it.unich.jandom.ui.NarrowingStrategies -import it.unich.jandom.ui.WideningScopes import it.unich.scalafix.BoxAssignment /** @@ -75,7 +73,7 @@ abstract class Parameters[Tgt <: Target[Tgt]] { /** * The current narrowing, returned as a box assignment. */ - def narrowing = { + def narrowing: BoxAssignment[Tgt#ProgramPoint, domain.Property] = { if (_narrowing == null) _narrowing = DefaultNarrowing.get(domain) _narrowing } diff --git a/core/src/main/scala/it/unich/jandom/targets/cfg/ControlFlowGraph.scala b/core/src/main/scala/it/unich/jandom/targets/cfg/ControlFlowGraph.scala index d96a0654..2cce1123 100644 --- a/core/src/main/scala/it/unich/jandom/targets/cfg/ControlFlowGraph.scala +++ b/core/src/main/scala/it/unich/jandom/targets/cfg/ControlFlowGraph.scala @@ -19,7 +19,6 @@ package it.unich.jandom.targets.cfg import scala.collection.mutable.HashMap import scala.collection.mutable.Queue - import it.unich.jandom.targets.Annotation import it.unich.jandom.targets.Target import soot.toolkits.graph.DirectedGraph @@ -98,7 +97,7 @@ abstract class ControlFlowGraph[Tgt <: ControlFlowGraph[Tgt, Node], Node] extend /** * Analyzes the target, starting from a given property. - * @param param the parameters which drive the analyzer + * @param params the parameters which drive the analyzer * @param input the starting property * @return the resulting annotation * @note this should be moved in the Target class. @@ -111,7 +110,7 @@ abstract class ControlFlowGraph[Tgt <: ControlFlowGraph[Tgt, Node], Node] extend /** * Perform a static analysis over the target, from a standard initial annotation - * @param param the parameters which drive the analyzer + * @param params the parameters which drive the analyzer * @return an annotation for the program */ def analyze(params: Parameters): Annotation[ProgramPoint, params.Property] = { @@ -124,8 +123,6 @@ abstract class ControlFlowGraph[Tgt <: ControlFlowGraph[Tgt, Node], Node] extend * The analyzer. At the moment, it implements a work-list based analysis. */ def analyzeFromAnnotation(params: Parameters)(ann: Annotation[ProgramPoint, params.Property]): Annotation[ProgramPoint, params.Property] = { - val widening = params.widening.copy - val narrowing = params.narrowing.copy val annEdge = HashMap[Edge, params.Property]() val taskList = Queue[ProgramPoint](graph.getHeads: _*) @@ -142,7 +139,7 @@ abstract class ControlFlowGraph[Tgt <: ControlFlowGraph[Tgt, Node], Node] extend params.log(s"join $succ : ${ann(succ)} with $out") val succval: params.Property = if (ordering.lteq(succ, node)) { params.log(s" widening") - widening(node)(ann(succ), out) + params.widening(node)(ann(succ), out) } else ann(succ) union out if (succval > ann(succ)) { @@ -173,7 +170,7 @@ abstract class ControlFlowGraph[Tgt <: ControlFlowGraph[Tgt, Node], Node] extend params.log(s"narrow $succ : ${ann(succ)} with $newinput ") // this may probably cause an infinite loop val succval = if (ordering.lteq(succ, node)) { - narrowing(node)(ann(succ), newinput) + params.narrowing(node)(ann(succ), newinput) } else newinput params.log(s"result $succval\n") diff --git a/core/src/main/scala/it/unich/jandom/targets/lts/LTS.scala b/core/src/main/scala/it/unich/jandom/targets/lts/LTS.scala index e362c179..c91bc712 100644 --- a/core/src/main/scala/it/unich/jandom/targets/lts/LTS.scala +++ b/core/src/main/scala/it/unich/jandom/targets/lts/LTS.scala @@ -164,14 +164,14 @@ case class LTS(val name: String, val locations: IndexedSeq[Location], val transi val widenings = locations map { l => if (params.wideningLocation == WideningNarrowingLocation.All || (params.wideningLocation == WideningNarrowingLocation.Loop && isJoinNode(l))) - Some(params.widening(l).copy) + Some(params.widening(l)) else None } val narrowings = locations map { l => if (params.narrowingLocation == WideningNarrowingLocation.All || (params.narrowingLocation == WideningNarrowingLocation.Loop && isJoinNode(l))) - Some(params.narrowing(l).copy) + Some(params.narrowing(l)) else None } diff --git a/core/src/main/scala/it/unich/jandom/targets/slil/WhileStmt.scala b/core/src/main/scala/it/unich/jandom/targets/slil/WhileStmt.scala index 310bee08..cf1e500c 100644 --- a/core/src/main/scala/it/unich/jandom/targets/slil/WhileStmt.scala +++ b/core/src/main/scala/it/unich/jandom/targets/slil/WhileStmt.scala @@ -51,8 +51,8 @@ case class WhileStmt(condition: NumericCondition, body: SLILStmt) extends SLILSt params.nestingLevel += 1 // Determines widening/narrowing operators to use - val widening = params.widening((this, 1)).copy - val narrowing = params.narrowing((this, 1)).copy + val widening = params.widening((this,1)) + val narrowing = params.narrowing((this,1)) // Determines initial values for the analysis, depending on the calling phase var (bodyResult, invariant) = diff --git a/extended/src/test/scala/it/unich/jandom/benchmarks/EQSLegacyFASTComparison.scala b/extended/src/test/scala/it/unich/jandom/benchmarks/EQSLegacyFASTComparison.scala index 0322d595..ec336476 100644 --- a/extended/src/test/scala/it/unich/jandom/benchmarks/EQSLegacyFASTComparison.scala +++ b/extended/src/test/scala/it/unich/jandom/benchmarks/EQSLegacyFASTComparison.scala @@ -82,7 +82,7 @@ object EQSLegacyFASTComparison extends App with FASTLoader { var globaleq, globallt, globalgt, globalun = 0 for (lts <- ltss) { timeTemp = java.lang.System.currentTimeMillis() - val res1 = EQSSolver(lts)(dom)(params, FixpointSolverListener.EmptyListener) + val res1 = EQSSolver(lts)(dom)(params)(FixpointSolverListener.EmptyListener) timeEQS += (java.lang.System.currentTimeMillis() - timeTemp) timeTemp = java.lang.System.currentTimeMillis() val res2 = lts.analyze(params) diff --git a/extended/src/test/scala/it/unich/jandom/benchmarks/FASTComparison.scala b/extended/src/test/scala/it/unich/jandom/benchmarks/FASTComparison.scala index 44364949..b964f19f 100644 --- a/extended/src/test/scala/it/unich/jandom/benchmarks/FASTComparison.scala +++ b/extended/src/test/scala/it/unich/jandom/benchmarks/FASTComparison.scala @@ -44,7 +44,7 @@ object FASTComparison extends App with FASTLoader { ("localized", CC77.copy(boxscope = BoxScope.Localized)), ("mixed", SCP), ("mixed localized", SCP.copy(boxscope = BoxScope.Localized)), - ("mixed localized restart", SCP.copy(boxscope = BoxScope.Localized, restartstrategy = true))) + ("mixed localized restart", SCP.copy(boxscope = BoxScope.Localized, restartstrategy = RestartStrategy.Restart))) val results = (for (lts <- ltss; eqs = lts.toEQS(dom); (name, p) <- parameters) yield { val l = new PerformanceListener From f98afd6ebff1b01436bdc9c3c89702dfe4db9e99 Mon Sep 17 00:00:00 2001 From: Gianluca Amato Date: Tue, 8 Aug 2017 12:49:28 +0200 Subject: [PATCH 32/99] Small fixes on widening, narrowing, and their specifications. --- .../jandom/domains/AbstractProperty.scala | 6 ++--- .../targets/parameters/NarrowingSpecs.scala | 22 +++++++++++++++---- .../targets/parameters/WideningSpecs.scala | 5 +++-- 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/core/src/main/scala/it/unich/jandom/domains/AbstractProperty.scala b/core/src/main/scala/it/unich/jandom/domains/AbstractProperty.scala index ef63b89c..abcfab92 100644 --- a/core/src/main/scala/it/unich/jandom/domains/AbstractProperty.scala +++ b/core/src/main/scala/it/unich/jandom/domains/AbstractProperty.scala @@ -73,7 +73,7 @@ trait AbstractProperty[Property <: AbstractProperty[Property]] extends Partially /** * The standard widening for two abstract properties. The object `this` should be widened with `that`. The - * result should be an upper bound of the two properties, and converge of the sequence s(i+1) = s(i) widening v(i) + * result should be an upper bound of the two properties, and convergemce of the sequence s(i+1) = s(i) widening v(i) * should be ensured for any sequence of v(i)'s. * * Important: `that` is not required to be bigger than `this`. This generality is needed in order to deal with @@ -86,9 +86,9 @@ trait AbstractProperty[Property <: AbstractProperty[Property]] extends Partially def widening(that: Property): Property /** - * The standard narrowing for two abstract properties. The object `this` should be widened with `that`. The + * The standard narrowing for two abstract properties. The object `this` should be narrowed with `that`. The * result should be smaller than `this` but bigger than `this intersection that` (or, more generally, a correct - * approximation of the concrete intersection). Moreover, converge of the sequence s(i+1) = s(i) narrowing v(i) + * approximation of the concrete intersection). Moreover, convergence of the sequence s(i+1) = s(i) narrowing v(i) * should be ensured for any sequence of v(i)'s. * * Important: `that` is not required to be bigger than `this`. This generality is needed in order to deal with diff --git a/core/src/main/scala/it/unich/jandom/targets/parameters/NarrowingSpecs.scala b/core/src/main/scala/it/unich/jandom/targets/parameters/NarrowingSpecs.scala index 80aeeed7..b18a3b86 100644 --- a/core/src/main/scala/it/unich/jandom/targets/parameters/NarrowingSpecs.scala +++ b/core/src/main/scala/it/unich/jandom/targets/parameters/NarrowingSpecs.scala @@ -1,5 +1,5 @@ /** - * Copyright 2016 Gianluca Amato + * Copyright 2016, 2017 Gianluca Amato * * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains * JANDOM is free software: you can redistribute it and/or modify @@ -18,12 +18,15 @@ package it.unich.jandom.targets.parameters +import scala.language.implicitConversions + import it.unich.jandom.domains.AbstractDomain import it.unich.scalafix.Box /** * This object contains the NarrowingSpec class and its subclasses. They are used - * to specify which kind of narrowing to use for the analyses. + * to specify which kind of narrowing to use for the analyses, in a way which is indepedent + * from abstract domains and targets. * @author Gianluca Amato */ object NarrowingSpecs { @@ -56,9 +59,9 @@ object NarrowingSpecs { /** * This always returns its right argument. Therefore, this is not formally a - * real widening since it may lead to non-terminating computations. + * real narrowing since it may lead to non-terminating computations. */ - case object LowerBoundNarrowing extends NarrowingSpec { + case object RightNarrowing extends NarrowingSpec { def get(dom: AbstractDomain) = Box.right[dom.Property] } @@ -68,4 +71,15 @@ object NarrowingSpecs { case class DelayedNarrowing(base: NarrowingSpec, d: Int) extends NarrowingSpec { def get(dom: AbstractDomain) = base.get(dom).delayed(d) } + + /** + * This specified a narrowing given its name + */ + case class NamedNarrowing(name: String) extends NarrowingSpec { + def get(dom: AbstractDomain) = dom.narrowing(name) + + } + + implicit def stringToNameNarrowing(name: String): NarrowingSpec = NamedNarrowing(name) + } diff --git a/core/src/main/scala/it/unich/jandom/targets/parameters/WideningSpecs.scala b/core/src/main/scala/it/unich/jandom/targets/parameters/WideningSpecs.scala index d09a5de3..bfbec81b 100644 --- a/core/src/main/scala/it/unich/jandom/targets/parameters/WideningSpecs.scala +++ b/core/src/main/scala/it/unich/jandom/targets/parameters/WideningSpecs.scala @@ -1,5 +1,5 @@ /** - * Copyright 2016 Gianluca Amato + * Copyright 2016, 2017 Gianluca Amato * * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains * JANDOM is free software: you can redistribute it and/or modify @@ -25,7 +25,8 @@ import it.unich.scalafix.Box /** * This object contains the WideningSpec class and its subclasses. They are used - * to specify which kind of widening to use for the analyses. + * to specify which kind of widening to use for the analyses, in a way which is indepedent + * from abstract domains and targets. * @author Gianluca Amato */ object WideningSpecs { From ee8885fcb58d0e64a4e3cb160a4eed2c236f6ed8 Mon Sep 17 00:00:00 2001 From: Gianluca Amato Date: Fri, 22 Sep 2017 19:58:50 +0200 Subject: [PATCH 33/99] Update to SBT 1.0 and new plugins. --- build.sbt | 61 +++++++++++-------- core/build.sbt | 45 ++++---------- .../unich/jandom/targets/jvmasm/package.scala | 26 -------- .../it/unich/jandom/JandomFasterBench.scala | 2 +- extended/build.sbt | 33 +++------- project/{Build.scala => CustomKeys.scala} | 3 +- project/assembly.sbt | 1 - project/build.properties | 2 +- project/buildinfo.sbt | 1 - project/eclipse.sbt | 1 - project/jmh.sbt | 1 - project/plugins.sbt | 5 ++ project/sbt-ide.sbt | 3 - 13 files changed, 65 insertions(+), 119 deletions(-) delete mode 100644 core/src/main/scala/it/unich/jandom/targets/jvmasm/package.scala rename project/{Build.scala => CustomKeys.scala} (82%) delete mode 100644 project/assembly.sbt delete mode 100644 project/buildinfo.sbt delete mode 100644 project/eclipse.sbt delete mode 100644 project/jmh.sbt create mode 100644 project/plugins.sbt delete mode 100644 project/sbt-ide.sbt diff --git a/build.sbt b/build.sbt index 22a4f0c1..7c8e4e96 100644 --- a/build.sbt +++ b/build.sbt @@ -1,20 +1,28 @@ +import CustomKeys._ + //*** Declare projects -val Jandom = project in file("core") enablePlugins(BuildInfoPlugin) +lazy val JandomCore = project in file("core") enablePlugins(BuildInfoPlugin) + +lazy val JandomExtended = project in file("extended") dependsOn JandomCore % "compile->compile;test->test" + +lazy val Jandom = project in file(".") aggregate (JandomCore, JandomExtended) + +//*** This delegates the Jandom run task to execute the run task in the Jandom sub-projects -val JandomExtended = project in file("extended") dependsOn Jandom % "compile->compile;test->test" +aggregate in assembly := false -val root = project in file(".") aggregate (Jandom, JandomExtended) +assembly := (assembly in JandomExtended).value -// This delegates the root run task to the run task in the Jandom project +run := (run in JandomCore in Compile).evaluated -run <<= run in ("Jandom", Compile) +run in Test := (run in JandomCore in Test).evaluated -run in Test <<= run in ("Jandom", Test) +run in Jmh := (run in JandomExtended in Jmh).evaluated -// Add a new benchmark configuration... -// val Bench = config("bench") extend(Test) -// val root = project in file(".") configs(Bench) settings( inConfig(Bench) (Defaults.testSettings):_*) aggregate (Jandom, JandomExtended) +//*** Do not update snapshots every time + +updateOptions in ThisBuild := updateOptions.value.withLatestSnapshots(false) //*** Scala configuration @@ -26,31 +34,34 @@ fork in ThisBuild := true //*** Resolvers -resolvers in ThisBuild ++= Seq( +resolvers in ThisBuild ++= Seq ( Resolver.sonatypeRepo("releases"), Resolver.sonatypeRepo("snapshots"), "Soot snapshot" at "https://soot-build.cs.uni-paderborn.de/nexus/repository/soot-snapshot/", - "Soot release" at "https://soot-build.cs.uni-paderborn.de/nexus/repository/soot-release/" + "Soot release" at + "https://soot-build.cs.uni-paderborn.de/nexus/repository/soot-release/" ) -//*** Detect PPL +//*** Custom keys -val optionalPPLPathName = try { - val PPLPathName = Process("ppl-config -l").lines.head+"/ppl/ppl_java.jar" +pplJar in ThisBuild := { + try { + val PPLPathName = scala.sys.process.Process("ppl-config -l").lineStream.head+"/ppl/ppl_java.jar" if (file(PPLPathName).exists) Some(PPLPathName) else None } catch { case _ : Exception => None } +} + +gitHeadCommitSHA in ThisBuild := scala.sys.process.Process("git rev-parse HEAD").lineStream.head + +//*** Eclipse plugin -pplJar in ThisBuild := optionalPPLPathName +// unfortunately, it is not possible to choose the compiler version with the eclipse plugin. -// for removing warnings when Breeze does not find native libraries -// -// javaOptions in ThisBuild ++= Seq("-Dcom.github.fommil.netlib.BLAS=com.github.fommil.netlib.F2jBLAS", -// "-Dcom.github.fommil.netlib.LAPACK=com.github.fommil.netlib.F2jLAPACK", -// "-Dcom.github.fommil.netlib.ARPACK=com.github.fommil.netlib.F2jARPACK") +EclipseKeys.eclipseOutput := Some("target.eclipse") -// Metadata +//*** Metadata for the build name in ThisBuild := "Jandom" @@ -66,20 +77,20 @@ homepage in ThisBuild := Some(url("https://github.com/jandom-devel/Jandom")) startYear in ThisBuild := Some(2011) -developers := List( - new Developer( +developers in ThisBuild := List( + Developer( "amato", "Gianluca Amato", "gianluca.amato@unich.it", url("http://www.sci.unich.it/~amato/") ), - new Developer( + Developer( "scozzari", "Francesca Scozzari", "francesca.scozzari@unich.it", url("http://www.sci.unich.it/~scozzari/") ) ) -scmInfo := Some(new ScmInfo( +scmInfo in ThisBuild := Some(ScmInfo( url("https://github.com/jandom-devel/Jandom"), "scm:git:https://github.com/jandom-devel/Jandom.git", Some("scm:git:https://github.com/jandom-devel/Jandom.git") diff --git a/core/build.sbt b/core/build.sbt index ef292ecb..314144c9 100644 --- a/core/build.sbt +++ b/core/build.sbt @@ -1,10 +1,12 @@ +import CustomKeys._ + //*** Libraries libraryDependencies ++= Seq( "org.apache.commons" % "commons-lang3" % "3.5", - "org.scalatest" %% "scalatest" % "3.0.0" % "test", - "org.scalacheck" %% "scalacheck" % "1.13.3" % "test", - "org.mockito" % "mockito-core" % "2.2.9" % "test", + "org.scalatest" %% "scalatest" % "3.0.0" % Test, + "org.scalacheck" %% "scalacheck" % "1.13.3" % Test, + "org.mockito" % "mockito-core" % "2.2.9" % Test, "org.spire-math" %% "spire" % "0.12.0", "it.unich.scalafix" %% "scalafix" % "0.6.0", "org.rogach" %% "scallop" % "2.0.3", @@ -15,46 +17,23 @@ libraryDependencies ++= Seq( "ca.mcgill.sable" % "soot" %"3.0.0-SNAPSHOT" ) -updateOptions := updateOptions.value.withLatestSnapshots(false) - //*** Additional source directories for PPL -unmanagedJars in Compile ++= (pplJar.value map file).toSeq - unmanagedSourceDirectories in Compile ++= (pplJar.value map { _ => (sourceDirectory in Compile).value / "ppl" }).toSeq unmanagedSourceDirectories in Test ++= (pplJar.value map { _ => (sourceDirectory in Test).value / "ppl" }).toSeq -//*** IntelliJ Idea - -ideOutputDirectory in Compile := Some(new File("core/target/idea/classes")) - -ideOutputDirectory in Test := Some(new File("core/target/idea/test-classes")) - -//*** Eclipse plugin - -EclipseKeys.createSrc := EclipseCreateSrc.Default + EclipseCreateSrc.Managed - -EclipseKeys.executionEnvironment := Some(EclipseExecutionEnvironment.JavaSE17) - -EclipseKeys.eclipseOutput := Some("target.eclipse") - -// It would be nice to be able to exclude resource directories from compilation. - -managedSourceDirectories in Test := Seq() - -managedResourceDirectories in Test := Seq() - -managedResourceDirectories in Compile := Seq() - -unmanagedResourceDirectories in Compile := Seq() +unmanagedJars in Compile ++= (pplJar.value map file).toSeq //*** BuildInfo plugin -gitHeadCommitSHA := Process("git rev-parse HEAD").lines.head - -buildInfoKeys := Seq[BuildInfoKey](name, version, scalaVersion, sbtVersion, gitHeadCommitSHA) +buildInfoKeys ++= Seq[BuildInfoKey](name, version, scalaVersion, sbtVersion, gitHeadCommitSHA) buildInfoPackage := "it.unich.jandom" +//*** IDEA plugin + +ideOutputDirectory in Compile := Some(file("core/target/idea/classes")) + +ideOutputDirectory in Test := Some(file("core/target/idea/test-classes")) diff --git a/core/src/main/scala/it/unich/jandom/targets/jvmasm/package.scala b/core/src/main/scala/it/unich/jandom/targets/jvmasm/package.scala deleted file mode 100644 index 21a353bb..00000000 --- a/core/src/main/scala/it/unich/jandom/targets/jvmasm/package.scala +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Copyright 2013 Gianluca Amato - * - * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains - * JANDOM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * JANDOM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty ofa - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with JANDOM. If not, see . - */ - -/** - * This is the Scala package containing the targets for the analysis of Java bytecode. It uses the - * libraries ASM and Soot to read class files - * @author Gianluca Amato - */ -package it.unich.jandom.targets.jvmasm { - -} diff --git a/core/src/test/scala/it/unich/jandom/JandomFasterBench.scala b/core/src/test/scala/it/unich/jandom/JandomFasterBench.scala index e7a064c1..03502c37 100644 --- a/core/src/test/scala/it/unich/jandom/JandomFasterBench.scala +++ b/core/src/test/scala/it/unich/jandom/JandomFasterBench.scala @@ -78,7 +78,7 @@ object JandomFasterBench extends App { } } - val resources = getClass.getResource("/fast/").toURI; + val resources = getClass.getResource("/fast/").toURI // This analyzes all models (does not terminate for descending2 with for (model <- new File(resources).listFiles()) fastModelAnalyze(model) diff --git a/extended/build.sbt b/extended/build.sbt index 2487670a..c31993cf 100644 --- a/extended/build.sbt +++ b/extended/build.sbt @@ -1,4 +1,4 @@ -updateOptions := updateOptions.value.withLatestSnapshots(false) +import CustomKeys._ //*** Additional source directories for PPL @@ -8,41 +8,26 @@ unmanagedSourceDirectories in Test ++= (pplJar.value map { _ => (sourceDirectory //*** Assembly plugin -test in assembly := {} +test in assembly := { } -mergeStrategy in assembly <<= (mergeStrategy in assembly) { (old) => - { +assemblyMergeStrategy in assembly ~= { (oldStrategy) => { case PathList(ps @ _*) if ps.last.endsWith(".class") => MergeStrategy.last - case x => old(x) + case x => oldStrategy(x) } } -//** IntelliJ Idea - -ideOutputDirectory in Compile := Some(new File("extended/target/idea/classes")) - -ideOutputDirectory in Test := Some(new File("extended/target/idea/test-classes")) - //*** Eclipse plugin -EclipseKeys.createSrc := EclipseCreateSrc.ValueSet() +EclipseKeys.configurations += Jmh -EclipseKeys.configurations += config("jmh") +//*** IDEA plugin -EclipseKeys.executionEnvironment := Some(EclipseExecutionEnvironment.JavaSE17) +ideOutputDirectory in Compile := Some(file("extended/target/idea/classes")) -EclipseKeys.eclipseOutput := Some("target.eclipse") +ideOutputDirectory in Test := Some(file("extended/target/idea/test-classes")) //*** JMH Plugin enablePlugins(JmhPlugin) -run in Jmh <<= (run in Jmh) dependsOn (compile in Jmh) - -// We prefer to change resourceDirectories instead of resourceDirectory so that directories do not -// appear in the Eclipse project. -resourceDirectories in Jmh := ((baseDirectory in ThisBuild).value / "core" / "src" / "test" / "resources") +: - ( (managedResourceDirectories in Jmh).value ++ (unmanagedResourceDirectories in Jmh).value ) - -dependencyClasspath in Jmh := (fullClasspath in Test).value - +dependencyClasspath in Jmh ++= (exportedProducts in Test).value diff --git a/project/Build.scala b/project/CustomKeys.scala similarity index 82% rename from project/Build.scala rename to project/CustomKeys.scala index d13d8607..2db3c65a 100644 --- a/project/Build.scala +++ b/project/CustomKeys.scala @@ -1,8 +1,7 @@ import sbt._ import Keys._ -object JandomBuild extends Build { +object CustomKeys { val pplJar = settingKey[Option[String]]("Location of the PPL library") val gitHeadCommitSHA = taskKey[String]("Current git commit SHA") } - diff --git a/project/assembly.sbt b/project/assembly.sbt deleted file mode 100644 index 39c1bb84..00000000 --- a/project/assembly.sbt +++ /dev/null @@ -1 +0,0 @@ -addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.3") diff --git a/project/build.properties b/project/build.properties index 35c88bab..b7dd3cb2 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=0.13.12 +sbt.version=1.0.2 diff --git a/project/buildinfo.sbt b/project/buildinfo.sbt deleted file mode 100644 index 04935e45..00000000 --- a/project/buildinfo.sbt +++ /dev/null @@ -1 +0,0 @@ -addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.6.1") diff --git a/project/eclipse.sbt b/project/eclipse.sbt deleted file mode 100644 index 2728de12..00000000 --- a/project/eclipse.sbt +++ /dev/null @@ -1 +0,0 @@ -addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "5.0.1") diff --git a/project/jmh.sbt b/project/jmh.sbt deleted file mode 100644 index d52c3354..00000000 --- a/project/jmh.sbt +++ /dev/null @@ -1 +0,0 @@ -addSbtPlugin("pl.project13.scala" % "sbt-jmh" % "0.2.18") diff --git a/project/plugins.sbt b/project/plugins.sbt new file mode 100644 index 00000000..2b511cc7 --- /dev/null +++ b/project/plugins.sbt @@ -0,0 +1,5 @@ +addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.5") +addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.7.0") +addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "5.2.2") +addSbtPlugin("pl.project13.scala" % "sbt-jmh" % "0.2.27") +addSbtPlugin("org.jetbrains" % "sbt-ide-settings" % "1.0.0") diff --git a/project/sbt-ide.sbt b/project/sbt-ide.sbt deleted file mode 100644 index b1407857..00000000 --- a/project/sbt-ide.sbt +++ /dev/null @@ -1,3 +0,0 @@ -resolvers += Resolver.url("jetbrains-bintray", - url("http://dl.bintray.com/jetbrains/sbt-plugins/"))(Resolver.ivyStylePatterns) -addSbtPlugin("org.jetbrains" % "sbt-ide-settings" % "0.1.2") From f35432ec77652a62f3ed1c463b069b6010a20134 Mon Sep 17 00:00:00 2001 From: Gianluca Amato Date: Sat, 23 Sep 2017 19:02:38 +0200 Subject: [PATCH 34/99] Fix FAST benchmarks to work also when Jandom is a packaged jar. --- .../unich/jandom/benchmark/FASTLoader.scala | 64 +++++++++ .../it/unich/jandom/JandomFasterBench.scala | 77 +++++------ .../jandom/JandomParallelotopeBench.scala | 127 +++++++++--------- .../it/unich/jandom/JandomSumBench.scala | 122 ++++++++--------- .../jandom/benchmarks/FASTBenchmark.scala | 57 ++++---- .../benchmarks/EQSLegacyFASTComparison.scala | 48 +++---- .../jandom/benchmarks/FASTComparison.scala | 17 +-- .../unich/jandom/benchmarks/FASTLoader.scala | 48 ------- 8 files changed, 277 insertions(+), 283 deletions(-) create mode 100644 core/src/main/scala/it/unich/jandom/benchmark/FASTLoader.scala delete mode 100644 extended/src/test/scala/it/unich/jandom/benchmarks/FASTLoader.scala diff --git a/core/src/main/scala/it/unich/jandom/benchmark/FASTLoader.scala b/core/src/main/scala/it/unich/jandom/benchmark/FASTLoader.scala new file mode 100644 index 00000000..33ed7668 --- /dev/null +++ b/core/src/main/scala/it/unich/jandom/benchmark/FASTLoader.scala @@ -0,0 +1,64 @@ +/** + * Copyright 2015, 2016, 2017 Gianluca Amato + * + * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains + * JANDOM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * JANDOM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of a + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with JANDOM. If not, see . + */ + + +package it.unich.jandom.benchmark + +import java.io.File +import java.util.jar.JarFile + +import it.unich.jandom.parsers.FastParser +import it.unich.jandom.targets.lts.LTS + +import scala.collection.JavaConversions._ + +/** + * This trait loads and parser all models in /fast/ resource directory. + * + * @author Gianluca Amato + */ + +trait FASTLoader { + private val path = "fast/" + private val jarFile = new File(getClass.getProtectionDomain.getCodeSource.getLocation.getPath) + + // determine resource names when the program is packaged as a jar and when not + private val uris = if (jarFile.isFile) { // Run with JAR file + val jar = new JarFile(jarFile) + val entries = jar.entries //gives ALL entries in jar + val result = (for (element <- entries; name = element.getName + if (name startsWith path) && (name.length > path.length)) yield "/"+name).toList + jar.close() + result + } + else { // Run with IDE + val resources = getClass.getResource(path).toURI + val dir = new File(resources) + dir.list().toList + } + + /** + * A sequence of Alice models. + */ + val ltss: Seq[LTS] = for (uri <- uris) yield { + val stream = getClass.getResourceAsStream(uri) + val content = scala.io.Source.fromInputStream(stream).getLines.mkString("\n") + val result = FastParser().parse(content).get + result.copy(name = s"${result.name} -- $uri") + } +} diff --git a/core/src/test/scala/it/unich/jandom/JandomFasterBench.scala b/core/src/test/scala/it/unich/jandom/JandomFasterBench.scala index 03502c37..7d70d5dc 100644 --- a/core/src/test/scala/it/unich/jandom/JandomFasterBench.scala +++ b/core/src/test/scala/it/unich/jandom/JandomFasterBench.scala @@ -1,51 +1,46 @@ /** - * Copyright 2014, 2016 Gianluca Amato - * - * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains - * JANDOM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * JANDOM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of a - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with JANDOM. If not, see . - */ + * Copyright 2014, 2016, 2017 Gianluca Amato + * + * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains + * JANDOM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * JANDOM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of a + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with JANDOM. If not, see . + */ package it.unich.jandom -import java.io.File -import java.io.FileReader - -import it.unich.jandom.domains.numerical.BoxDoubleDomain -import it.unich.jandom.parsers.FastParser +import it.unich.jandom.benchmark.FASTLoader +import it.unich.jandom.domains.numerical.NumericalDomain +import it.unich.jandom.domains.numerical.ppl.PPLDomainMacro import it.unich.jandom.targets.lts.LTS import it.unich.jandom.targets.parameters.IterationStrategy import it.unich.jandom.targets.parameters.NarrowingSpecs._ import it.unich.jandom.targets.parameters.WideningSpecs._ -import it.unich.jandom.domains.numerical.ppl.PPLDomainMacro import parma_polyhedra_library.C_Polyhedron /** - * Example program using ''Jandom'' to analyze the Alice benchmarks and - * compare the results with different parameters. In this moment, it compares - * the result of the analyisis with standard Kleene iteration and worklist - * based ones. - */ -object JandomFasterBench extends App { + * Example program using ''Jandom'' to analyze the Alice benchmarks and + * compare the results with different parameters. In this moment, it compares + * the result of the analyisis with standard Kleene iteration and worklist + * based ones. + */ +object JandomFasterBench extends App with FASTLoader { - def fastModelAnalyze(model: File) = { - println(s"------>${model}") + def fastModelAnalyze(program: LTS) { + println(s"------> ${program.name}") - val source = new FileReader(model) - val parsed = FastParser().parse(source) - source.close() - val program = parsed.get - val params = new targets.Parameters[LTS] { val domain = PPLDomainMacro[C_Polyhedron] } + val params = new targets.Parameters[LTS] { + val domain: NumericalDomain = PPLDomainMacro[C_Polyhedron] + } // We specify some parameters for the analysis, although these are the standard ones. params.widening = DefaultWidening @@ -68,8 +63,8 @@ object JandomFasterBench extends App { // params.debugWriter.flush() if (program.locations exists (loc => ann(loc) != ann2(loc))) { - println("DIFFERENT BEHAVIOURS: " + model) - println(s"Times: ${tann1} vs ${tann2}") + println("DIFFERENT BEHAVIOURS: " + program.name) + println(s"Times: $tann1 vs $tann2") println("WIDENINGS: " + program.locations.filter(program.isJoinNode).map(_.name).mkString(", ")) println("BETTER 1: " + program.locations.filter(loc => ann(loc) < ann2(loc)).map(_.name).mkString(", ")) println("BETTER 2: " + program.locations.filter(loc => ann(loc) > ann2(loc)).map(_.name).mkString(", ")) @@ -78,11 +73,5 @@ object JandomFasterBench extends App { } } - val resources = getClass.getResource("/fast/").toURI - - // This analyzes all models (does not terminate for descending2 with - for (model <- new File(resources).listFiles()) fastModelAnalyze(model) - - // This is if we want to analyze a specificic model - // fastModelAnalyze(new File(resources.resolve("descending.fst"))) + for (lts <- ltss) fastModelAnalyze(lts) } diff --git a/core/src/test/scala/it/unich/jandom/JandomParallelotopeBench.scala b/core/src/test/scala/it/unich/jandom/JandomParallelotopeBench.scala index 5b42f07e..6642772e 100644 --- a/core/src/test/scala/it/unich/jandom/JandomParallelotopeBench.scala +++ b/core/src/test/scala/it/unich/jandom/JandomParallelotopeBench.scala @@ -1,44 +1,39 @@ /** - * Copyright 2016 Jandom Team - * - * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains - * JANDOM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * JANDOM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of a - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with JANDOM. If not, see . - */ + * Copyright 2016, 2017 Jandom Team + * + * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains + * JANDOM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * JANDOM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of a + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with JANDOM. If not, see . + */ package it.unich.jandom -import java.io.File - +import it.unich.jandom.benchmark.FASTLoader import it.unich.jandom.domains.DimensionFiberedProperty -import it.unich.jandom.domains.numerical.BoxRationalDomain -import it.unich.jandom.domains.numerical.LinearForm -import it.unich.jandom.domains.numerical.ParallelotopeRationalDomain -import it.unich.jandom.domains.numerical.ProductDomain +import it.unich.jandom.domains.numerical._ import it.unich.jandom.domains.numerical.ppl.PPLDomain -import it.unich.jandom.parsers.FastParser import it.unich.jandom.targets.lts.LTS import it.unich.jandom.targets.parameters.NarrowingSpecs._ import it.unich.jandom.targets.parameters.WideningSpecs._ import parma_polyhedra_library.C_Polyhedron /** - * Example program using ''Jandom'' to analyze the Alice benchmarks and - * compare the results with different parameters. At the moment, it compares - * the result of separately computing using box and parallelotope with respect - * to using their product. - */ -object JandomParallelotopeBench extends App { + * Example program using ''Jandom'' to analyze the Alice benchmarks and + * compare the results with different parameters. At the moment, it compares + * the result of separately computing using box and parallelotope with respect + * to using their product. + */ +object JandomParallelotopeBench extends App with FASTLoader { var totalEquals = 0 var totalBestReduced = 0 @@ -47,7 +42,7 @@ object JandomParallelotopeBench extends App { var totalPrograms = 0 def CStoPolyehdra(dimension: Int, c: Seq[LinearForm]) = { - val d = PPLDomain[C_Polyhedron] + val d = PPLDomain[C_Polyhedron]() c.foldLeft(d.top(dimension)) { (p: d.Property, lf: LinearForm) => p.linearInequality(lf) } } @@ -55,17 +50,15 @@ object JandomParallelotopeBench extends App { (for ((loc, prop) <- m) yield loc.name + " => " + prop.mkString(program.env.variables)).mkString(", ") } - def fastModelAnalyze(model: File) = { + def fastModelAnalyze(program: LTS) { totalPrograms += 1 - println(s"------>${model}") - - val source = scala.io.Source.fromFile(model).getLines.mkString("\n") - val parsed = FastParser().parse(source) - val program = parsed.get + println(s"------>${program.name}") println("WIDENINGS: " + program.locations.filter(program.isJoinNode).map(_.name).mkString(", ")) - val params1 = new targets.Parameters[LTS] { val domain = new ProductDomain(BoxRationalDomain(), ParallelotopeRationalDomain(-1)) } + val params1 = new targets.Parameters[LTS] { + val domain = new ProductDomain(BoxRationalDomain(), ParallelotopeRationalDomain(-1)) + } params1.widening = DelayedWidening(DefaultWidening, 1) params1.narrowing = DelayedNarrowing(DefaultNarrowing, 1) //params1.debugWriter = new java.io.PrintWriter(System.out) @@ -76,7 +69,9 @@ object JandomParallelotopeBench extends App { val productAnn = program.analyze(params1) val tann1 = System.currentTimeMillis - t1 - val params2 = new targets.Parameters[LTS] { val domain = BoxRationalDomain() } + val params2 = new targets.Parameters[LTS] { + val domain = BoxRationalDomain() + } params2.widening = DelayedWidening(DefaultWidening, 1) params2.narrowing = DelayedNarrowing(DefaultNarrowing, 1) // params2.debugWriter = new java.io.PrintWriter(System.out) @@ -87,7 +82,9 @@ object JandomParallelotopeBench extends App { val boxAnn = program.analyze(params2) val tann2 = System.currentTimeMillis - t2 - val params3 = new targets.Parameters[LTS] { val domain = ParallelotopeRationalDomain(1) } + val params3 = new targets.Parameters[LTS] { + val domain = ParallelotopeRationalDomain(1) + } params3.widening = DelayedWidening(DefaultWidening, 1) params3.narrowing = DelayedNarrowing(DefaultNarrowing, 1) //params6Bis.debugWriter = new java.io.PrintWriter(System.out) @@ -98,7 +95,7 @@ object JandomParallelotopeBench extends App { val parAnn = program.analyze(params3) val tann3 = System.currentTimeMillis - t3 - val cprod = productAnn mapValues { p => CStoPolyehdra(p.p1.dimension, p.p1.constraints) intersection (CStoPolyehdra(p.p2.dimension, p.p2.constraints)) } + val cprod = productAnn mapValues { p => CStoPolyehdra(p.p1.dimension, p.p1.constraints) intersection CStoPolyehdra(p.p2.dimension, p.p2.constraints) } val cbox = boxAnn mapValues { p => CStoPolyehdra(p.dimension, p.constraints) } val cpar = parAnn mapValues { p => CStoPolyehdra(p.dimension, p.constraints) } @@ -109,29 +106,28 @@ object JandomParallelotopeBench extends App { print("Product: ") println(mkString(program, cprod)) - val comp = cprod map { case (loc, v) => (loc -> v.tryCompareTo(cbox(loc) intersection (cpar(loc)))) } - - println("COUNT EQUALS: " + comp.count(_._2 == Some(0))) - println("COUNT BETTER REDUCED PRODUCT: " + comp.count(_._2 == Some(-1))) - println("COUNT BETTER SEPARATE ANALYSIS: " + comp.count(_._2 == Some(1))) - println("COUNT UNCOMPARABLES: " + comp.count(_._2 == None)) - totalEquals += comp.count(_._2 == Some(0)) - totalBestReduced += comp.count(_._2 == Some(-1)) - totalBestSeparate += comp.count(_._2 == Some(1)) - totalUncomparable += comp.count(_._2 == None) - - println("EQUALS: " + program.locations.filter(comp(_) == Some(0)).map(_.name).mkString(", ")) - println("BETTER PRO: " + program.locations.filter(comp(_) == Some(-1)).map(_.name).mkString(", ")) - println("BETTER INT: " + program.locations.filter(comp(_) == Some(1)).map(_.name).mkString(", ")) - println("UNCOMPARABLES: " + program.locations.filter(comp(_) == None).map(_.name).mkString(", ")) + val comp = cprod map { case (loc, v) => loc -> v.tryCompareTo(cbox(loc) intersection cpar(loc)) } + + println("COUNT EQUALS: " + comp.count(_._2 contains 0)) + println("COUNT BETTER REDUCED PRODUCT: " + comp.count(_._2 contains -1)) + println("COUNT BETTER SEPARATE ANALYSIS: " + comp.count(_._2 contains 1)) + println("COUNT UNCOMPARABLES: " + comp.count(_._2.isEmpty)) + totalEquals += comp.count(_._2 contains 0) + totalBestReduced += comp.count(_._2 contains -1) + totalBestSeparate += comp.count(_._2 contains 1) + totalUncomparable += comp.count(_._2.isEmpty) + + println("EQUALS: " + program.locations.filter(comp(_) contains 0).map(_.name).mkString(", ")) + println("BETTER PRO: " + program.locations.filter(comp(_) contains -1).map(_.name).mkString(", ")) + println("BETTER INT: " + program.locations.filter(comp(_) contains 1).map(_.name).mkString(", ")) + println("UNCOMPARABLES: " + program.locations.filter(comp(_).isEmpty).map(_.name).mkString(", ")) } val program: Option[String] = None - var badPrograms = Seq[File]() + var badPrograms = Seq[LTS]() if (program.isEmpty) { - val resources = getClass.getResource("/fast/").toURI; - for (model <- new File(resources).listFiles()) { + for (model <- ltss) { try { fastModelAnalyze(model) } catch { @@ -140,17 +136,16 @@ object JandomParallelotopeBench extends App { } } } else { - val resources2 = getClass.getResource("/fast/"+program.get).toURI; - val file = new File(resources2) - fastModelAnalyze(file) + val model = ltss find (lts => program contains lts.name) + model foreach fastModelAnalyze } println("\nFinal results:") println("---------------") - println(s"Number of programs: ${totalPrograms}") + println(s"Number of programs: $totalPrograms") println(s"Bad programs: ${badPrograms.mkString("\n")}") - println(s"Total equals: ${totalEquals}") - println(s"Total best reduced product: ${totalBestReduced}") - println(s"Total best separate analysis: ${totalBestSeparate}") - println(s"Total uncomparables: ${totalUncomparable}") + println(s"Total equals: $totalEquals") + println(s"Total best reduced product: $totalBestReduced") + println(s"Total best separate analysis: $totalBestSeparate") + println(s"Total uncomparables: $totalUncomparable") } diff --git a/core/src/test/scala/it/unich/jandom/JandomSumBench.scala b/core/src/test/scala/it/unich/jandom/JandomSumBench.scala index 6ed4623a..31a85940 100644 --- a/core/src/test/scala/it/unich/jandom/JandomSumBench.scala +++ b/core/src/test/scala/it/unich/jandom/JandomSumBench.scala @@ -1,44 +1,38 @@ /** - * Copyright 2014, 2016 Gianluca Amato - * - * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains - * JANDOM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * JANDOM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of a - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with JANDOM. If not, see . - */ + * Copyright 2014, 2016, 2017 Gianluca Amato + * + * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains + * JANDOM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * JANDOM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of a + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with JANDOM. If not, see . + */ package it.unich.jandom -import java.io.File -import java.io.FileReader - +import it.unich.jandom.benchmark.FASTLoader import it.unich.jandom.domains.DimensionFiberedProperty -import it.unich.jandom.domains.numerical.BoxDoubleDomain -import it.unich.jandom.domains.numerical.LinearForm -import it.unich.jandom.domains.numerical.ParallelotopeRationalDomain -import it.unich.jandom.domains.numerical.SumBoxDoubleParallelotopeRationDomain +import it.unich.jandom.domains.numerical._ import it.unich.jandom.domains.numerical.ppl.PPLDomain -import it.unich.jandom.parsers.FastParser import it.unich.jandom.targets.lts.LTS import it.unich.jandom.targets.parameters.WideningSpecs._ import parma_polyhedra_library.C_Polyhedron /** - * Example program using ''Jandom'' to analyze the Alice benchmarks and - * compare the results with different parameters. In this moment, it compares - * the result of the analyisis with standard Kleene iteration and worklist - * based ones. - */ -object JandomSumBench extends App { + * Example program using ''Jandom'' to analyze the Alice benchmarks and + * compare the results with different parameters. In this moment, it compares + * the result of the analyisis with standard Kleene iteration and worklist + * based ones. + */ +object JandomSumBench extends App with FASTLoader { var totalEquals = 0 var totalBestSum = 0 @@ -47,7 +41,7 @@ object JandomSumBench extends App { var totalPrograms = 0 def CStoPolyehdra(dimension: Int, c: Seq[LinearForm]) = { - val d = PPLDomain[C_Polyhedron] + val d = PPLDomain[C_Polyhedron]() c.foldLeft(d.top(dimension)) { (p: d.Property, lf: LinearForm) => p.linearInequality(lf) } } @@ -55,18 +49,15 @@ object JandomSumBench extends App { (for ((loc, prop) <- m) yield loc.name + " => " + prop.mkString(program.env.variables)).mkString(", ") } - def fastModelAnalyze(model: File) = { + def fastModelAnalyze(program: LTS) { totalPrograms += 1 - println(s"------>${model}") - - val source = new FileReader(model) - val parsed = FastParser().parse(source) - source.close() - val program = parsed.get + println(s"------>${program.name}") println("WIDENINGS: " + program.locations.filter(program.isJoinNode).map(_.name).mkString(", ")) - val params = new targets.Parameters[LTS] { val domain = BoxDoubleDomain(false) } + val params = new targets.Parameters[LTS] { + val domain = BoxDoubleDomain() + } params.widening = DelayedWidening(DefaultWidening, 3) // needed for parallelotopes program.analyze(params) // warmup JVM @@ -74,7 +65,9 @@ object JandomSumBench extends App { val ann1 = program.analyze(params) val tann1 = System.currentTimeMillis - t1 - val params2 = new targets.Parameters[LTS] { val domain = SumBoxDoubleParallelotopeRationDomain() } + val params2 = new targets.Parameters[LTS] { + val domain = SumBoxDoubleParallelotopeRationDomain() + } params2.widening = DelayedWidening(DefaultWidening, 3) // needed for parallelotopes //params2.debugWriter = new java.io.PrintWriter(System.out) program.analyze(params2) // warmup JVM @@ -84,7 +77,9 @@ object JandomSumBench extends App { val ann2 = program.analyze(params2) val tann2 = System.currentTimeMillis - t2 - val params3 = new targets.Parameters[LTS] { val domain = ParallelotopeRationalDomain() } + val params3 = new targets.Parameters[LTS] { + val domain = ParallelotopeRationalDomain() + } params3.widening = DelayedWidening(DefaultWidening, 3) // needed for parallelotopes //params3.debugWriter = new java.io.PrintWriter(System.out) @@ -99,7 +94,7 @@ object JandomSumBench extends App { val cann2 = ann2 mapValues { p => CStoPolyehdra(p.dimension, p.constraints) } val cann3 = ann3 mapValues { p => CStoPolyehdra(p.dimension, p.constraints) } - println(s"Times: ${tann1} vs ${tann2}") + println(s"Times: $tann1 vs $tann2") print("Box: ") println(mkString(program, cann1)) print("PTope: ") @@ -108,7 +103,7 @@ object JandomSumBench extends App { println(mkString(program, cann2)) // SOSTITUIRE cann1 con cann3 se si vuole il confronto con i Parallelotopi. - val comp = cann2 map { case (loc, v) => (loc -> v.tryCompareTo(cann1(loc) intersection cann3(loc))) } + val comp = cann2 map { case (loc, v) => loc -> v.tryCompareTo(cann1(loc) intersection cann3(loc)) } //comparing sum with box //val comp = cann2 map { case (loc, v) => (loc -> v.tryCompareTo(cann1(loc))) } @@ -116,32 +111,30 @@ object JandomSumBench extends App { //comparing sum with parallelotope //val comp = cann2 map { case (loc, v) => (loc -> v.tryCompareTo(cann3(loc))) } - println("COUNT EQUALS: " + comp.count(_._2 == Some(0))) - println("COUNT BETTER SUM: " + comp.count(_._2 == Some(-1))) - println("COUNT BETTER OTHER: " + comp.count(_._2 == Some(1))) - println("COUNT UNCOMPARABLES: " + comp.count(_._2 == None)) + println("COUNT EQUALS: " + comp.count(_._2 contains 0)) + println("COUNT BETTER SUM: " + comp.count(_._2 contains -1)) + println("COUNT BETTER OTHER: " + comp.count(_._2 contains 1)) + println("COUNT UNCOMPARABLES: " + comp.count(_._2.isEmpty)) - totalEquals += comp.count(_._2 == Some(0)) - totalBestSum += comp.count(_._2 == Some(-1)) - totalBestOther += comp.count(_._2 == Some(1)) - totalUncomparable += comp.count(_._2 == None) + totalEquals += comp.count(_._2 contains 0) + totalBestSum += comp.count(_._2 contains -1) + totalBestOther += comp.count(_._2 contains 1) + totalUncomparable += comp.count(_._2.isEmpty) //println("DIFFERENT BEHAVIOURS: " + model) //println(s"Times: ${tann1} vs ${tann2}") //println("WIDENINGS: " + program.locations.filter(program.isJoinNode).map(_.name).mkString(", ")) - println("EQUALS: " + program.locations.filter(comp(_) == Some(0)).map(_.name).mkString(", ")) - println("BETTER SUM: " + program.locations.filter(comp(_) == Some(-1)).map(_.name).mkString(", ")) - println("BETTER OTHER: " + program.locations.filter(comp(_) == Some(1)).map(_.name).mkString(", ")) - println("UNCOMPARABLES: " + program.locations.filter(comp(_) == None).map(_.name).mkString(", ")) + println("EQUALS: " + program.locations.filter(comp(_) contains 0).map(_.name).mkString(", ")) + println("BETTER SUM: " + program.locations.filter(comp(_) contains -1).map(_.name).mkString(", ")) + println("BETTER OTHER: " + program.locations.filter(comp(_) contains 1).map(_.name).mkString(", ")) + println("UNCOMPARABLES: " + program.locations.filter(comp(_).isEmpty).map(_.name).mkString(", ")) } - val resources = getClass.getResource("/fast/").toURI; - - var badPrograms = Seq[File]() + var badPrograms = Seq[LTS]() // This analyzes all models (does not terminate for descending2 with - for (model <- new File(resources).listFiles()) { + for (model <- ltss) { try { fastModelAnalyze(model) } catch { @@ -155,11 +148,10 @@ object JandomSumBench extends App { println("\nFinal results:") println("---------------") - println(s"Number of programs: ${totalPrograms}") + println(s"Number of programs: $totalPrograms") println(s"""Bad programs: ${badPrograms.mkString("\n")}""") - println(s"Total equals: ${totalEquals}") - println(s"Total best sum: ${totalBestSum}") - println(s"Total best other: ${totalBestOther}") - println(s"Total uncomparables: ${totalUncomparable}") - + println(s"Total equals: $totalEquals") + println(s"Total best sum: $totalBestSum") + println(s"Total best other: $totalBestOther") + println(s"Total uncomparables: $totalUncomparable") } diff --git a/extended/src/jmh/scala/it/unich/jandom/benchmarks/FASTBenchmark.scala b/extended/src/jmh/scala/it/unich/jandom/benchmarks/FASTBenchmark.scala index 283ef378..e5fa96a2 100644 --- a/extended/src/jmh/scala/it/unich/jandom/benchmarks/FASTBenchmark.scala +++ b/extended/src/jmh/scala/it/unich/jandom/benchmarks/FASTBenchmark.scala @@ -1,49 +1,51 @@ /** - * Copyright 2015, 2016 Gianluca Amato - * - * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains - * JANDOM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * JANDOM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of a - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with JANDOM. If not, see . - */ + * Copyright 2015, 2016 Gianluca Amato + * + * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains + * JANDOM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * JANDOM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of a + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with JANDOM. If not, see . + */ package it.unich.jandom.benchmarks -import it.unich.jandom.domains.numerical.BoxDoubleDomain +import it.unich.jandom.benchmark.FASTLoader +import it.unich.jandom.domains.numerical.{BoxDoubleDomain, NumericalDomain} import it.unich.jandom.targets.Parameters -import it.unich.jandom.targets.lts.LTS -import it.unich.jandom.targets.lts.Location -import it.unich.scalafix.Box.apply +import it.unich.jandom.targets.lts.{LTS, Location} import it.unich.scalafix.FixpointSolver._ import it.unich.scalafix.finite.FiniteFixpointSolver +import it.unich.scalafix.lattice.Domain import org.openjdk.jmh.annotations._ /** - * This is a program which analyzes the Alice benchmarks with different settings and compares the execution time. - */ + * This is a program which analyzes the Alice benchmarks with different settings and compares the execution time. + */ @State(Scope.Thread) @Warmup(iterations = 5) class FASTBenchmark extends FASTLoader { val dom = BoxDoubleDomain() - implicit val scalafixDomain = dom.ScalaFixDomain - val wideningBox = { (x: dom.Property, y: dom.Property) => x widening y } - val narrowingBox = { (x: dom.Property, y: dom.Property) => x narrowing y } - val CC77 = FiniteFixpointSolver.CC77[Location, dom.Property](Solver.WorkListSolver, wideningBox, narrowingBox) + private implicit val scalafixDomain: Domain[dom.Property] = dom.ScalaFixDomain + private val wideningBox = { (x: dom.Property, y: dom.Property) => x widening y } + private val narrowingBox = { (x: dom.Property, y: dom.Property) => x narrowing y } + private val CC77 = FiniteFixpointSolver.CC77[Location, dom.Property](Solver.WorkListSolver, wideningBox, narrowingBox) @Benchmark def timeLTS() { - val params = new Parameters[LTS] { val domain = dom } + val params = new Parameters[LTS] { + val domain: NumericalDomain = dom + } for (lts <- ltss) lts.analyze(params) } @@ -53,7 +55,6 @@ class FASTBenchmark extends FASTLoader { val eqs = lts.toEQS(dom) FiniteFixpointSolver(eqs, CC77.copy(solver = Solver.KleeneSolver)) } - } @Benchmark diff --git a/extended/src/test/scala/it/unich/jandom/benchmarks/EQSLegacyFASTComparison.scala b/extended/src/test/scala/it/unich/jandom/benchmarks/EQSLegacyFASTComparison.scala index ec336476..e54166a9 100644 --- a/extended/src/test/scala/it/unich/jandom/benchmarks/EQSLegacyFASTComparison.scala +++ b/extended/src/test/scala/it/unich/jandom/benchmarks/EQSLegacyFASTComparison.scala @@ -1,35 +1,35 @@ /** - * Copyright 2016 Gianluca Amato - * - * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains - * JANDOM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * JANDOM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of a - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with JANDOM. If not, see . - */ + * Copyright 2016, 2017 Gianluca Amato + * + * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains + * JANDOM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * JANDOM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of a + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with JANDOM. If not, see . + */ package it.unich.jandom.benchmarks +import it.unich.jandom.benchmark.FASTLoader import it.unich.jandom.domains.numerical.ParallelotopeRationalDomain -import it.unich.jandom.targets.{EQSSolver, Parameters} import it.unich.jandom.targets.lts._ import it.unich.jandom.targets.parameters._ +import it.unich.jandom.targets.{EQSSolver, Parameters} import it.unich.scalafix.{Assignment, FixpointSolverListener} /** - * This program compares standard (legacy) analyzer with the new one based on Scalafix for - * the LTS target. The aim is to compare both precision of results and speed. This should be used to - * guide the progressive removal of legacy analyzers. - */ - + * This program compares standard (legacy) analyzer with the new one based on Scalafix for + * the LTS target. The aim is to compare both precision of results and speed. This should be used to + * guide the progressive removal of legacy analyzers. + */ object EQSLegacyFASTComparison extends App with FASTLoader { val dom = ParallelotopeRationalDomain() @@ -93,10 +93,10 @@ object EQSLegacyFASTComparison extends App with FASTLoader { globalgt += comparison._3 globalun += comparison._4 if (comparison._2 != 0 || comparison._3 != 0 || comparison._4 != 0) - println (s"Found differences in ${lts.name}") + println(s"Found differences in ${lts.name}") } println(s"\n-------------------") - println(s"${name} EQS vs Legacy") + println(s"$name EQS vs Legacy") println(s"Time ${timeEQS}ms vs ${timeLTS}ms") println("Equal : " + globaleq) println("First Better: " + globallt) diff --git a/extended/src/test/scala/it/unich/jandom/benchmarks/FASTComparison.scala b/extended/src/test/scala/it/unich/jandom/benchmarks/FASTComparison.scala index b964f19f..ed081424 100644 --- a/extended/src/test/scala/it/unich/jandom/benchmarks/FASTComparison.scala +++ b/extended/src/test/scala/it/unich/jandom/benchmarks/FASTComparison.scala @@ -1,5 +1,5 @@ /** - * Copyright 2015 Gianluca Amato + * Copyright 2015, 2017 Gianluca Amato * * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains * JANDOM is free software: you can redistribute it and/or modify @@ -18,12 +18,13 @@ package it.unich.jandom.benchmarks +import it.unich.jandom.benchmark.FASTLoader import it.unich.jandom.domains.numerical.BoxDoubleDomain import it.unich.jandom.targets.lts.Location -import it.unich.scalafix.Box.apply import it.unich.scalafix.FixpointSolver._ import it.unich.scalafix.FixpointSolverListener.PerformanceListener import it.unich.scalafix.finite.FiniteFixpointSolver +import it.unich.scalafix.lattice.Domain /** * An example application which compares the precision of different analysis for Alice benchmarks. @@ -32,7 +33,7 @@ object FASTComparison extends App with FASTLoader { //val dom = PPLDomain[C_Polyhedron] val dom = BoxDoubleDomain() - implicit val scalafixDomain = dom.ScalaFixDomain + implicit val scalafixDomain: Domain[dom.Property] = dom.ScalaFixDomain val widening = { (x: dom.Property, y: dom.Property) => x widening y } val narrowing = { (x: dom.Property, y: dom.Property) => x narrowing y } @@ -55,10 +56,10 @@ object FASTComparison extends App with FASTLoader { for ((name, _) <- parameters) { var numiters = 0 for (l <- ltss) numiters += results((l, name))._2 - println(s"solver ${name} iterations ${numiters}") + println(s"solver $name iterations $numiters") } - for (i <- 0 until parameters.size; j <- i + 1 until parameters.size) { + for (i <- parameters.indices; j <- i + 1 until parameters.size) { val name1 = parameters(i)._1 val name2 = parameters(j)._1 var globalun, globaleq, globallt, globalgt = 0 @@ -95,7 +96,7 @@ object FASTComparison extends App with FASTLoader { } // for comparison, the old solver integrated in the LTS class has 1170 evaluations for worklist based analysis and 1706 evaluations for Kleene. println(s"\n-------------------") - println(s"${name1} vs ${name2}") + println(s"$name1 vs $name2") println("Uncomparable: " + globalun) println("Equal : " + globaleq) println("First Better: " + globallt) @@ -105,9 +106,9 @@ object FASTComparison extends App with FASTLoader { for (lts <- ltss; if lts.name.indexOf("amato") >= 0) { println(lts.name) for ((name, _) <- parameters) { - print(s"Solver ${name} -> ") + print(s"Solver $name -> ") val result = results((lts, name)) - for (l <- lts.locations) print(s"${l} : ${result._1(l)} ") + for (l <- lts.locations) print(s"$l : ${result._1(l)} ") println("") } } diff --git a/extended/src/test/scala/it/unich/jandom/benchmarks/FASTLoader.scala b/extended/src/test/scala/it/unich/jandom/benchmarks/FASTLoader.scala deleted file mode 100644 index 8e4c8075..00000000 --- a/extended/src/test/scala/it/unich/jandom/benchmarks/FASTLoader.scala +++ /dev/null @@ -1,48 +0,0 @@ -/** - * Copyright 2015, 2016 Gianluca Amato - * - * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains - * JANDOM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * JANDOM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of a - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with JANDOM. If not, see . - */ - - - -package it.unich.jandom.benchmarks - -import java.io.File -import java.io.FileReader -import it.unich.jandom.parsers.FastParser - -/** - * This trait loads and parser all models in Alice directory. - * @author Gianluca Amato - */ - -trait FASTLoader { - /** - * The directory from where benchmarks are loaded - */ - val dir = new File(getClass.getResource("/fast/").toURI); - - /** - * A sequence of Alice models. - */ - val ltss = for (model <- dir.listFiles()) yield { - val source = new FileReader(model) - val result = FastParser().parse(source).get - source.close() - // add filename to the model name to have an unique identifier - result.copy(name = s"${result.name} -- ${model.getName}") - } -} From 85e1b5335d52f6b75e467bdc2106476e8a6e8173 Mon Sep 17 00:00:00 2001 From: Gianluca Amato Date: Sun, 24 Sep 2017 12:49:13 +0200 Subject: [PATCH 35/99] Upgrade Scala and library versions. --- build.sbt | 4 ++-- core/build.sbt | 18 +++++++++--------- .../unich/jandom/ui/gui/ParametersPane.scala | 9 +++++---- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/build.sbt b/build.sbt index 7c8e4e96..0db7a2ab 100644 --- a/build.sbt +++ b/build.sbt @@ -26,9 +26,9 @@ updateOptions in ThisBuild := updateOptions.value.withLatestSnapshots(false) //*** Scala configuration -scalaVersion in ThisBuild := "2.11.8" +scalaVersion in ThisBuild := "2.11.11" -scalacOptions in ThisBuild ++= Seq("-deprecation", "-feature", "-Xlint", "-Xlint:-delayedinit-select", "-Xlint:-missing-interpolator") +scalacOptions in ThisBuild ++= Seq("-deprecation", "-feature", "-unchecked", "-Xlint", "-Xlint:-missing-interpolator") fork in ThisBuild := true diff --git a/core/build.sbt b/core/build.sbt index 314144c9..d378606b 100644 --- a/core/build.sbt +++ b/core/build.sbt @@ -3,15 +3,15 @@ import CustomKeys._ //*** Libraries libraryDependencies ++= Seq( - "org.apache.commons" % "commons-lang3" % "3.5", - "org.scalatest" %% "scalatest" % "3.0.0" % Test, - "org.scalacheck" %% "scalacheck" % "1.13.3" % Test, - "org.mockito" % "mockito-core" % "2.2.9" % Test, - "org.spire-math" %% "spire" % "0.12.0", - "it.unich.scalafix" %% "scalafix" % "0.6.0", - "org.rogach" %% "scallop" % "2.0.3", - "org.scala-lang.modules" %% "scala-swing" % "1.0.2", - "org.scala-lang.modules" %% "scala-parser-combinators" % "1.0.4", + "org.apache.commons" % "commons-lang3" % "3.6", + "org.scalatest" %% "scalatest" % "3.0.4" % Test, + "org.scalacheck" %% "scalacheck" % "1.13.5" % Test, + "org.mockito" % "mockito-core" % "2.10.0" % Test, + "org.typelevel" %% "spire" % "0.14.1", + "it.unich.scalafix" %% "scalafix" % "0.7.0-SNAPSHOT", + "org.rogach" %% "scallop" % "3.1.0", + "org.scala-lang.modules" %% "scala-swing" % "2.0.0", + "org.scala-lang.modules" %% "scala-parser-combinators" % "1.0.6", "org.scala-lang" % "scala-reflect" % scalaVersion.value, // ASM is included in the Soot Jar "ca.mcgill.sable" % "soot" %"3.0.0-SNAPSHOT" diff --git a/core/src/main/scala/it/unich/jandom/ui/gui/ParametersPane.scala b/core/src/main/scala/it/unich/jandom/ui/gui/ParametersPane.scala index 5fe8a9d4..ce566cdc 100644 --- a/core/src/main/scala/it/unich/jandom/ui/gui/ParametersPane.scala +++ b/core/src/main/scala/it/unich/jandom/ui/gui/ParametersPane.scala @@ -52,13 +52,14 @@ class ParametersPane extends GridBagPanel { GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0) object ParameterRenderer extends Renderer[ParameterValue[_]] { - val r = implicitly[Renderer[String]] - def componentFor(list: ListView[_], isSelected: Boolean, + private val r = implicitly[Renderer[String]] + def componentFor(list: ListView[_ <: ParameterValue[_]], isSelected: Boolean, focused: Boolean, a: ParameterValue[_], index: Int): Component = { - val c = r.componentFor(list, isSelected, focused, a.name, index) + // The asInstanceOf in the line below is a bad trick... it works for now. + val c = r.componentFor(list.asInstanceOf[ListView[String]], isSelected, focused, a.name, index) c.tooltip = a.description - return c + c } } From 0544770734be45dbf8af365cc186220435c2fcaa Mon Sep 17 00:00:00 2001 From: Gianluca Amato Date: Sun, 24 Sep 2017 22:22:24 +0200 Subject: [PATCH 36/99] Fix JandomCLI parameter parsing. --- core/src/main/scala/it/unich/jandom/ui/cli/Conf.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/main/scala/it/unich/jandom/ui/cli/Conf.scala b/core/src/main/scala/it/unich/jandom/ui/cli/Conf.scala index 31a66762..1d530325 100644 --- a/core/src/main/scala/it/unich/jandom/ui/cli/Conf.scala +++ b/core/src/main/scala/it/unich/jandom/ui/cli/Conf.scala @@ -34,4 +34,5 @@ class Conf(arguments: Seq[String]) extends ScallopConf(arguments) { val wideningScope = opt[WideningScope.Value]("widening", default = Some(WideningScopes.default.value))(enumConverter(WideningScope)) val narrowingStrategy = opt[NarrowingStrategy.Value]("narrowing", default = Some(NarrowingStrategies.default.value))(enumConverter(NarrowingStrategy)) val file = opt[String]("input", required = true) + verify() } From 9cd6857de0c686dbf6f556315260238a4eb34087 Mon Sep 17 00:00:00 2001 From: Gianluca Amato Date: Wed, 27 Sep 2017 11:20:35 +0200 Subject: [PATCH 37/99] Move to Scala 2.12 and remove all warnings. --- build.sbt | 4 +- .../domains/numerical/ppl/PPLBoxDouble.scala | 9 +- .../numerical/ppl/PPLDomainMacro.scala | 13 +- .../domains/numerical/ppl/PPLProperty.scala | 9 +- .../domains/numerical/ppl/PPLUtils.scala | 6 +- .../unich/jandom/benchmark/FASTLoader.scala | 6 +- .../domains/numerical/BoxDoubleDomain.scala | 18 +- .../domains/numerical/BoxRationalDomain.scala | 16 +- .../ParallelotopeRationalDomain.scala | 372 +++++++++--------- .../jandom/domains/numerical/SumDomain.scala | 8 +- .../it/unich/jandom/parsers/FastParser.scala | 2 - .../it/unich/jandom/parsers/LPInvParser.scala | 1 - .../parsers/NumericConditionParser.scala | 1 - .../jandom/targets/NumericAssignment.scala | 3 +- .../jandom/targets/cfg/ControlFlowGraph.scala | 23 +- .../jandom/targets/jvmasm/AsmMethod.scala | 6 +- .../targets/jvmasm/JVMEnvFixedFrame.scala | 2 - .../jvmasm/UnsupportedASMInsnException.scala | 1 - .../jandom/targets/jvmsoot/BafMethod.scala | 6 +- .../jandom/targets/jvmsoot/JimpleMethod.scala | 10 +- .../jandom/targets/jvmsoot/SootCFG.scala | 17 +- .../targets/jvmsoot/SootFrameDomain.scala | 2 - .../jvmsoot/SootFrameObjectDomain.scala | 7 +- .../targets/jvmsoot/SootInterpretation.scala | 10 +- .../targets/jvmsoot/SootObjectModel.scala | 13 +- .../it/unich/jandom/targets/lts/LTS.scala | 1 - .../unich/jandom/targets/lts/Transition.scala | 2 - .../jandom/targets/slil/AssignStmt.scala | 1 - .../it/unich/jandom/targets/slil/IfStmt.scala | 1 - .../jandom/targets/slil/SLILProgram.scala | 3 +- .../it/unich/jandom/ui/OutputInterface.scala | 11 +- .../unich/jandom/ui/gui/ASMEditorPane.scala | 5 +- .../unich/jandom/ui/gui/ParametersPane.scala | 1 - .../unich/jandom/ui/gui/SootEditorPane.scala | 8 +- .../unich/jandom/utils/DisjointSetsImpl.scala | 3 - .../it/unich/jandom/utils/Relation.scala | 2 +- .../jandom/utils/numberext/DenseMatrix.scala | 2 +- .../numerical/ppl/PPLDomainSuite.scala | 4 +- .../unich/jandom/targets/JVMSootSuite.scala | 6 +- .../SootFrameNumericalDomainSuite.scala | 2 - .../jandom/JandomParallelotopeBench.scala | 5 +- .../it/unich/jandom/JandomSumBench.scala | 4 +- .../domains/DomainTransformationSuite.scala | 1 - .../domains/numerical/LinearFormSuite.scala | 3 +- ...ParallelotopeRationalDomainFastSuite.scala | 1 - .../domains/objects/ObjectDomainSuite.scala | 1 - .../domains/objects/PairSharingSuite.scala | 1 - .../objects/PreciseDefiniteNullness.scala | 3 - .../domains/objects/PreciseObjectDomain.scala | 4 - .../objectmodels/ObjectModelSuite.scala | 2 +- .../objectmodels/TestObjectModelSuite.scala | 1 - .../TrivialObjectModelSuite.scala | 1 - .../it/unich/jandom/targets/JVMASMSuite.scala | 8 +- .../targets/JimpleParametersSuite.scala | 1 - .../jandom/targets/SootObjectModelSuite.scala | 1 - .../soot/jandom/BriefBigBlockGraphSuite.scala | 13 +- .../soot/jandom/UnitBlockGraphSuite.scala | 18 +- .../benchmarks/BoxDoubleBenchmark.scala | 2 - .../numerical/ppl/PPLMacroPropertySuite.scala | 5 +- 59 files changed, 308 insertions(+), 384 deletions(-) diff --git a/build.sbt b/build.sbt index 0db7a2ab..973d03f1 100644 --- a/build.sbt +++ b/build.sbt @@ -26,9 +26,9 @@ updateOptions in ThisBuild := updateOptions.value.withLatestSnapshots(false) //*** Scala configuration -scalaVersion in ThisBuild := "2.11.11" +scalaVersion in ThisBuild := "2.12.3" -scalacOptions in ThisBuild ++= Seq("-deprecation", "-feature", "-unchecked", "-Xlint", "-Xlint:-missing-interpolator") +scalacOptions in ThisBuild ++= Seq("-deprecation", "-feature", "-unchecked", "-Xlint:_,-missing-interpolator", "-Ywarn-unused:-implicits") fork in ThisBuild := true diff --git a/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLBoxDouble.scala b/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLBoxDouble.scala index 060e0510..9066754c 100644 --- a/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLBoxDouble.scala +++ b/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLBoxDouble.scala @@ -18,6 +18,8 @@ package it.unich.jandom.domains.numerical.ppl +import scala.collection.JavaConverters._ + import it.unich.jandom.domains.numerical.LinearForm import it.unich.jandom.domains.numerical.NumericalProperty import it.unich.jandom.utils.numberext.RationalExt @@ -167,16 +169,13 @@ final class PPLBoxDouble(val pplbox: Double_Box) extends NumericalProperty[PPLBo } def constraints = { - import scala.collection.JavaConversions._ - val cs = pplbox.constraints() - cs flatMap PPLUtils.fromPPLConstraint + cs.asScala flatMap PPLUtils.fromPPLConstraint } def isPolyhedral = { - import scala.collection.JavaConversions._ val cs = pplbox.constraints() - cs forall PPLUtils.isRepresentableAsLinearForms + cs.asScala forall PPLUtils.isRepresentableAsLinearForms } def addVariable: PPLBoxDouble = { diff --git a/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLDomainMacro.scala b/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLDomainMacro.scala index c952d2d6..3d1a3d44 100644 --- a/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLDomainMacro.scala +++ b/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLDomainMacro.scala @@ -79,7 +79,6 @@ object PPLDomainMacro { val outputTree = q""" import it.unich.jandom.domains.DomainTransformation - import parma_polyhedra_library._ object PPLtoPPL extends DomainTransformation[PPLDomainMacro[$PPLSourceTypeTag], PPLDomainMacro[$PPLDestTypeTag]] { def apply(src: PPLDomainMacro[$PPLSourceTypeTag], dst: PPLDomainMacro[$PPLDestTypeTag]): src.Property => dst.Property = { (x) => @@ -135,6 +134,7 @@ object PPLDomainMacro { """ val outputTree = q""" + import collection.JavaConverters._ import it.unich.jandom.domains.WideningDescription import it.unich.jandom.domains.numerical.LinearForm import it.unich.jandom.domains.numerical.ppl._ @@ -184,14 +184,14 @@ object PPLDomainMacro { } def linearInequality(lf: LinearForm): ThisProperty = { - val (le, den) = PPLUtils.toPPLLinearExpression(lf) + val (le, _) = PPLUtils.toPPLLinearExpression(lf) val newpplobject = new $PPLTypeTag(pplobject) newpplobject.refine_with_constraint(new Constraint(le, Relation_Symbol.LESS_OR_EQUAL, new Linear_Expression_Coefficient(new Coefficient(0)))) new ThisProperty(newpplobject) } def linearDisequality(lf: LinearForm): ThisProperty = { - val (le, den) = PPLUtils.toPPLLinearExpression(lf) + val (le, _) = PPLUtils.toPPLLinearExpression(lf) val newpplobject1 = new $PPLTypeTag(pplobject) val newpplobject2 = new $PPLTypeTag(pplobject) newpplobject1.refine_with_constraint(new Constraint(le, Relation_Symbol.LESS_THAN, new Linear_Expression_Coefficient(new Coefficient(0)))) @@ -246,15 +246,12 @@ object PPLDomainMacro { } def constraints = { - import collection.JavaConversions._ - - val cs = pplobject.minimized_constraints() + val cs = pplobject.minimized_constraints().asScala cs flatMap PPLUtils.fromPPLConstraint } def isPolyhedral = { - import collection.JavaConversions._ - val cs = pplobject.minimized_constraints() + val cs = pplobject.minimized_constraints().asScala (cs forall PPLUtils.isRepresentableAsLinearForms) && pplobject.minimized_congruences().isEmpty() } diff --git a/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLProperty.scala b/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLProperty.scala index 34f3cdcc..b5f9e6b8 100644 --- a/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLProperty.scala +++ b/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLProperty.scala @@ -18,6 +18,8 @@ package it.unich.jandom.domains.numerical.ppl +import scala.collection.JavaConverters._ + import it.unich.jandom.domains.numerical.LinearForm import it.unich.jandom.domains.numerical.NumericalProperty import it.unich.jandom.utils.numberext.RationalExt @@ -170,18 +172,15 @@ class PPLProperty[PPLNativeProperty <: AnyRef](val domain: PPLDomain[PPLNativePr } def constraints = { - import scala.collection.JavaConversions._ - val cs = domain.minimized_constraints(pplobject) - cs flatMap PPLUtils.fromPPLConstraint + cs.asScala flatMap PPLUtils.fromPPLConstraint } def isPolyhedral = { - import scala.collection.JavaConversions._ val cs = domain.minimized_constraints(pplobject) // we explicitly check if the object is empty since, in this case, it has a unsatisfiable // congruence. - isEmpty || ((cs forall PPLUtils.isRepresentableAsLinearForms) && domain.minimized_congruences(pplobject).isEmpty()) + isEmpty || ((cs.asScala forall PPLUtils.isRepresentableAsLinearForms) && domain.minimized_congruences(pplobject).isEmpty()) } def addVariable = { diff --git a/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLUtils.scala b/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLUtils.scala index b26fc0bb..9e7756a1 100644 --- a/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLUtils.scala +++ b/core/src/main/ppl/it/unich/jandom/domains/numerical/ppl/PPLUtils.scala @@ -18,6 +18,8 @@ package it.unich.jandom.domains.numerical.ppl +import scala.collection.JavaConverters._ + import it.unich.jandom.domains.numerical.LinearForm import parma_polyhedra_library._ import spire.math.Rational @@ -93,13 +95,11 @@ private[jandom] object PPLUtils { * @param vars the variables to use for the string form */ def constraintsToString(cs: Constraint_System, vars: Seq[String]): String = { - import scala.collection.JavaConversions._ - val vs = new Variable_Stringifier { def stringify(x: Long) = vars(x.toInt) } Variable.setStringifier(vs) - val result = for (c <- cs) yield c.toString + val result = for (c <- cs.asScala) yield c.toString Variable.setStringifier(null) result.mkString("[ ", " , ", " ]") } diff --git a/core/src/main/scala/it/unich/jandom/benchmark/FASTLoader.scala b/core/src/main/scala/it/unich/jandom/benchmark/FASTLoader.scala index 33ed7668..08f75694 100644 --- a/core/src/main/scala/it/unich/jandom/benchmark/FASTLoader.scala +++ b/core/src/main/scala/it/unich/jandom/benchmark/FASTLoader.scala @@ -19,14 +19,14 @@ package it.unich.jandom.benchmark +import scala.collection.JavaConverters._ + import java.io.File import java.util.jar.JarFile import it.unich.jandom.parsers.FastParser import it.unich.jandom.targets.lts.LTS -import scala.collection.JavaConversions._ - /** * This trait loads and parser all models in /fast/ resource directory. * @@ -41,7 +41,7 @@ trait FASTLoader { private val uris = if (jarFile.isFile) { // Run with JAR file val jar = new JarFile(jarFile) val entries = jar.entries //gives ALL entries in jar - val result = (for (element <- entries; name = element.getName + val result = (for (element <- entries.asScala; name = element.getName if (name startsWith path) && (name.length > path.length)) yield "/"+name).toList jar.close() result diff --git a/core/src/main/scala/it/unich/jandom/domains/numerical/BoxDoubleDomain.scala b/core/src/main/scala/it/unich/jandom/domains/numerical/BoxDoubleDomain.scala index 350aa0b9..c7f73e0b 100644 --- a/core/src/main/scala/it/unich/jandom/domains/numerical/BoxDoubleDomain.scala +++ b/core/src/main/scala/it/unich/jandom/domains/numerical/BoxDoubleDomain.scala @@ -130,7 +130,7 @@ class BoxDoubleDomain(val overReals: Boolean) extends NumericalDomain { * If `remove` is a valid index in `x` and `y`, the factor `x(remove) * y(remove)` is * removed from the dot product. */ - private def dotprod_lo(x: Seq[Double], y: Seq[Double], remove: Int = -1): Double = { + private def dotprod_lo(x: Seq[Double], y: Seq[Double], remove: Int): Double = { var sum: Double = 0 for (i <- x.indices; if i != remove && x(i) != 0) sum = add_lo(sum, mul_lo(x(i), y(i))) sum @@ -142,7 +142,7 @@ class BoxDoubleDomain(val overReals: Boolean) extends NumericalDomain { * If `remove` is a valid index in `x` and `y`, the factor `x(remove) * y(remove)` is * removed from the dot product. */ - private def dotprod_hi(x: Seq[Double], y: Seq[Double], remove: Int = -1): Double = { + private def dotprod_hi(x: Seq[Double], y: Seq[Double], remove: Int): Double = { var sum: Double = 0 for (i <- x.indices; if i != remove && x(i) != 0) sum = add_hi(sum, mul_hi(x(i), y(i))) sum @@ -259,17 +259,6 @@ class BoxDoubleDomain(val overReals: Boolean) extends NumericalDomain { (lf.homcoeffs.zipWithIndex) map { case (c, i) => if (c > Rational.zero) low(i) else high(i) } } - /** - * Compute the corner of the box which maximizes a linear form. - * @todo should be generalized to linear forms over arbitrary types. - * @param coeff the homogeneous coefficients - * @return the coordinates of the point which maximizes the linear form - */ - private def linearArgmax(lf: LinearForm): Seq[Double] = { - require(lf.dimension <= dimension) - (lf.homcoeffs.zipWithIndex) map { case (c, i) => if (c < Rational.zero) low(i) else high(i) } - } - /** * @inheritdoc * @note @inheritdoc @@ -454,7 +443,8 @@ class BoxDoubleDomain(val overReals: Boolean) extends NumericalDomain { def top = BoxDoubleDomain.this.top(low.length) def tryCompareTo[B >: Property](other: B)(implicit arg0: (B) => PartiallyOrdered[B]): Option[Int] = other match { - case other: Property => + // we use BoxDoubleDomain#Property instead of just Property to avoid a warning + case other: BoxDoubleDomain#Property => require(dimension == other.dimension) (isEmpty, other.isEmpty) match { case (true, true) => Option(0) diff --git a/core/src/main/scala/it/unich/jandom/domains/numerical/BoxRationalDomain.scala b/core/src/main/scala/it/unich/jandom/domains/numerical/BoxRationalDomain.scala index 9e001c20..c97f94a0 100644 --- a/core/src/main/scala/it/unich/jandom/domains/numerical/BoxRationalDomain.scala +++ b/core/src/main/scala/it/unich/jandom/domains/numerical/BoxRationalDomain.scala @@ -79,7 +79,7 @@ class BoxRationalDomain private extends NumericalDomain { * If `remove` is a valid index in `x` and `y`, the factor `x(remove) * y(remove)` is * removed from the dot product. */ - private def dotprod(x: Seq[Rational], y: Seq[RationalExt], remove: Int = -1): RationalExt = { + private def dotprod(x: Seq[Rational], y: Seq[RationalExt], remove: Int): RationalExt = { var sum = RationalExt.zero for (i <- x.indices; if i != remove && !x(i).isZero) sum += x(i) * y(i) sum @@ -185,17 +185,6 @@ class BoxRationalDomain private extends NumericalDomain { (lf.homcoeffs,low,high).zipped.map{(c, l, h) => if (c > Rational.zero) l else h } } - /** - * Compute the corner of the box which maximizes a linear form. - * @todo should be generalized to linear forms over arbitrary types. - * @param coeff the homogeneous coefficients - * @return the coordinates of the point which maximizes the linear form - */ - private def linearArgmax(lf: LinearForm): Seq[RationalExt] = { - require(lf.dimension <= dimension) - (lf.homcoeffs,low,high).zipped.map{(c, l, h) => if (c < Rational.zero) l else h } - } - /** * @inheritdoc * @note @inheritdoc @@ -375,7 +364,8 @@ class BoxRationalDomain private extends NumericalDomain { def top = BoxRationalDomain.this.top(low.length) def tryCompareTo[B >: Property](other: B)(implicit arg0: (B) => PartiallyOrdered[B]): Option[Int] = other match { - case other: Property => + // we use BoxRationalDomain#Property instead of just Property to avoid a warning + case other: BoxRationalDomain#Property => require(dimension == other.dimension) (isEmpty, other.isEmpty) match { case (true, true) => Option(0) diff --git a/core/src/main/scala/it/unich/jandom/domains/numerical/ParallelotopeRationalDomain.scala b/core/src/main/scala/it/unich/jandom/domains/numerical/ParallelotopeRationalDomain.scala index 06ddb78e..d0981af7 100644 --- a/core/src/main/scala/it/unich/jandom/domains/numerical/ParallelotopeRationalDomain.scala +++ b/core/src/main/scala/it/unich/jandom/domains/numerical/ParallelotopeRationalDomain.scala @@ -1,20 +1,20 @@ /** - * Copyright 2013, 2017 Jandom Team - * - * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains - * JANDOM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * JANDOM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of a - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with JANDOM. If not, see . - */ + * Copyright 2013, 2017 Jandom Team + * + * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains + * JANDOM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * JANDOM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of a + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with JANDOM. If not, see . + */ package it.unich.jandom.domains.numerical @@ -26,31 +26,31 @@ import scala.collection.mutable.ListBuffer import scala.util.Try /** - * This is the abstract domain of parallelotopes as appears in the NSAD 2012 paper. It is written - * using the Breeze Math library and uses rational numbers. - * - * @param favorAxis determines whether the heuristics built into the domain should try to keep constraints - * corresponding to Cartesian axis. If `favorAxis` is `1`, axis are favorite. The opposite happens when favorAxis - * is `-1`. If `favorAxis` is `0`, axis are considered like all the other constraints - * - * @author Gianluca Amato - * @author Francesca Scozzari - * @author Marco Rubino - */ + * This is the abstract domain of parallelotopes as appears in the NSAD 2012 paper. It is written + * using the Breeze Math library and uses rational numbers. + * + * @param favorAxis determines whether the heuristics built into the domain should try to keep constraints + * corresponding to Cartesian axis. If `favorAxis` is `1`, axis are favorite. The opposite happens when favorAxis + * is `-1`. If `favorAxis` is `0`, axis are considered like all the other constraints + * @author Gianluca Amato + * @author Francesca Scozzari + * @author Marco Rubino + */ class ParallelotopeRationalDomain private(favorAxis: Int) extends NumericalDomain { val widenings = Seq(WideningDescription.default[Property]) /** - * Build a non-empty parallelotope. If the parallelotope is not empty, the result is undetermined. - * @param A is the constraint matrix. It should be invertible. - * @param low lower bounds. - * @param high higher bounds. - * @note `low` and `high` should have the same length. The matrix `A` should be invertiible - * of the same size of the two vectors. - * @throws IllegalArgumentException if `low` and `high` are not of the same length, if `A` is not - * square or if `A` has not the same size of `low`. - */ + * Build a non-empty parallelotope. If the parallelotope is not empty, the result is undetermined. + * + * @param A is the constraint matrix. It should be invertible. + * @param low lower bounds. + * @param high higher bounds. + * @note `low` and `high` should have the same length. The matrix `A` should be invertiible + * of the same size of the two vectors. + * @throws IllegalArgumentException if `low` and `high` are not of the same length, if `A` is not + * square or if `A` has not the same size of `low`. + */ def apply(low: Bounds, A: DenseMatrix, high: Bounds): Property = { val isEmpty = (0 until low.length) exists { i => low(i) > high(i) } val isEmpty2 = (0 until low.length) exists { i => low(i).isInfinity && low(i) == high(i) } @@ -58,10 +58,10 @@ class ParallelotopeRationalDomain private(favorAxis: Int) extends NumericalDomai } /** - * @inheritdoc - * @note @inheritdoc - * @throws $ILLEGAL - */ + * @inheritdoc + * @note @inheritdoc + * @throws $ILLEGAL + */ def top(n: Int): Property = { /* The full parallelotope of dimension 0 is not empty! */ val low = Bounds.fill(n)(RationalExt.NegativeInfinity) @@ -71,9 +71,10 @@ class ParallelotopeRationalDomain private(favorAxis: Int) extends NumericalDomai } /** - * Returns an full parallelotope whose shape is given by the matrix A. - * @param A the shape matrix - */ + * Returns an full parallelotope whose shape is given by the matrix A. + * + * @param A the shape matrix + */ def top(A: DenseMatrix): Property = { val n = A.rows val low = Bounds.fill(n)(RationalExt.NegativeInfinity) @@ -82,10 +83,10 @@ class ParallelotopeRationalDomain private(favorAxis: Int) extends NumericalDomai } /** - * @inheritdoc - * @note @inheritdoc - * @throws $ILLEGAL - */ + * @inheritdoc + * @note @inheritdoc + * @throws $ILLEGAL + */ def bottom(n: Int): Property = { val low = Bounds.fill(n)(RationalExt.one) val high = Bounds.fill(n)(RationalExt.zero) @@ -94,9 +95,10 @@ class ParallelotopeRationalDomain private(favorAxis: Int) extends NumericalDomai } /** - * Returns an empty parallelotope whose shape is given by the matrix A. - * @param A the shape matrix - */ + * Returns an empty parallelotope whose shape is given by the matrix A. + * + * @param A the shape matrix + */ def bottom(A: DenseMatrix): Property = { val n = A.rows val low = Bounds.fill(n)(RationalExt.one) @@ -105,14 +107,15 @@ class ParallelotopeRationalDomain private(favorAxis: Int) extends NumericalDomai } /** - * Given the box specified by `low` and `high` and the linear form `lf`, determines the pair - * of the least and greatest value of the linear form in the box. - * @param lf a linear form. - * @param low lower bound of the box. - * @param high higher bound of the box. - * @note `low`, `high` and `lf` should be of the same length. - * @return the least and greatest value of `lf` in the box determine by `low` and `high`. - */ + * Given the box specified by `low` and `high` and the linear form `lf`, determines the pair + * of the least and greatest value of the linear form in the box. + * + * @param lf a linear form. + * @param low lower bound of the box. + * @param high higher bound of the box. + * @note `low`, `high` and `lf` should be of the same length. + * @return the least and greatest value of `lf` in the box determine by `low` and `high`. + */ private def extremalsInBox(lf: DenseVector, low: Bounds, high: Bounds): (RationalExt, RationalExt) = { var minc = RationalExt.zero var maxc = RationalExt.zero @@ -128,11 +131,12 @@ class ParallelotopeRationalDomain private(favorAxis: Int) extends NumericalDomai } /** - * Given a sequence of vectors of the same length `n`, returns a sequence of `n` indexes - * of vectors which are linearly independent. It is based on Gaussian elimination. - * @param m a sequence of vectors, all of the same length. - * @return a sequence of positions in m. - */ + * Given a sequence of vectors of the same length `n`, returns a sequence of `n` indexes + * of vectors which are linearly independent. It is based on Gaussian elimination. + * + * @param m a sequence of vectors, all of the same length. + * @return a sequence of positions in m. + */ private def pivoting(m: IndexedSeq[DenseVector]): List[Int] = { val dimension = m(0).length val indexes = ListBuffer[Int]() @@ -155,24 +159,24 @@ class ParallelotopeRationalDomain private(favorAxis: Int) extends NumericalDomai } /** - * This is an element of the parallelotope domain. - * - * @constructor Builds a parallelotope - * @param isEmpty is true if the parallelotope is empty. In this case, the other parameters are not relevant. - * @param A is the constraint matrix. It should be invertible. - * @param low lower bounds. - * @param high higher bounds. - * @note `low` and `high` should have the same length. The matrix `A` should be invertible - * of the same size of the two vectors. - * @throws IllegalArgumentException if `low` and `high` are not of the same length, if `A` is not - * square or if `A` has not the same size of `low`. - */ + * This is an element of the parallelotope domain. + * + * @constructor Builds a parallelotope + * @param isEmpty is true if the parallelotope is empty. In this case, the other parameters are not relevant. + * @param A is the constraint matrix. It should be invertible. + * @param low lower bounds. + * @param high higher bounds. + * @note `low` and `high` should have the same length. The matrix `A` should be invertible + * of the same size of the two vectors. + * @throws IllegalArgumentException if `low` and `high` are not of the same length, if `A` is not + * square or if `A` has not the same size of `low`. + */ final class Property( - val isEmpty: Boolean, - val low: Bounds, - val A: DenseMatrix, - val high: Bounds) - extends NumericalProperty[Property] { + val isEmpty: Boolean, + val low: Bounds, + val A: DenseMatrix, + val high: Bounds) + extends NumericalProperty[Property] { require(low.length == A.rows) require(low.length == A.cols) @@ -193,10 +197,10 @@ class ParallelotopeRationalDomain private(favorAxis: Int) extends NumericalDomai } /** - * @inheritdoc - * @note @inheritdoc - * @throws $ILLEGAL - */ + * @inheritdoc + * @note @inheritdoc + * @throws $ILLEGAL + */ def widening(that: Property): Property = { require(dimension == that.dimension) if (isEmpty) @@ -226,10 +230,10 @@ class ParallelotopeRationalDomain private(favorAxis: Int) extends NumericalDomai } /** - * @inheritdoc - * @note @inheritdoc - * @throws $ILLEGAL - */ + * @inheritdoc + * @note @inheritdoc + * @throws $ILLEGAL + */ def narrowing(that: Property): Property = { require(dimension == that.dimension) if (that.isEmpty) { @@ -249,11 +253,11 @@ class ParallelotopeRationalDomain private(favorAxis: Int) extends NumericalDomai } /** - * @inheritdoc - * It is equivalent to `intersectionWeak`. - * @note @inheritdoc - * @throws $ILLEGAL - */ + * @inheritdoc + * It is equivalent to `intersectionWeak`. + * @note @inheritdoc + * @throws $ILLEGAL + */ def intersection(that: Property): Property = { if (that.isEmpty) that @@ -264,13 +268,13 @@ class ParallelotopeRationalDomain private(favorAxis: Int) extends NumericalDomai } /** - * @inheritdoc - * The union of two parallelotopes is not a parallelotope. Moreover, there is no least - * parallelotopes containing the union of two parallelotopes. Hence, this methods uses - * heuristics to find a good result. - * @note @inheritdoc - * @throws $ILLEGAL - */ + * @inheritdoc + * The union of two parallelotopes is not a parallelotope. Moreover, there is no least + * parallelotopes containing the union of two parallelotopes. Hence, this methods uses + * heuristics to find a good result. + * @note @inheritdoc + * @throws $ILLEGAL + */ def union(that: Property): Property = { /* @@ -414,12 +418,13 @@ class ParallelotopeRationalDomain private(favorAxis: Int) extends NumericalDomai } /** - * This is a variant of `union` using weak join. The shape of the resulting - * parallelotope is the same shap of `this`. - * @param that the abstract object to be joined with `this`. - * @note $NOTEDIMENSION - * @return the weak union of the two abstract objects. - */ + * This is a variant of `union` using weak join. The shape of the resulting + * parallelotope is the same shap of `this`. + * + * @param that the abstract object to be joined with `this`. + * @note $NOTEDIMENSION + * @return the weak union of the two abstract objects. + */ def unionWeak(that: Property): Property = { require(dimension == that.dimension) if (isEmpty) @@ -437,12 +442,13 @@ class ParallelotopeRationalDomain private(favorAxis: Int) extends NumericalDomai } /** - * This is the weak intersection of two abstract objects. The shape of the resulting - * parallelotope is the same shape of `this`. - * @param that the abstract object to be intersected with `this`. - * @note $NOTEDIMENSION - * @return the intersection of the two abstract objects. - */ + * This is the weak intersection of two abstract objects. The shape of the resulting + * parallelotope is the same shape of `this`. + * + * @param that the abstract object to be intersected with `this`. + * @note $NOTEDIMENSION + * @return the intersection of the two abstract objects. + */ def intersectionWeak(that: Property): Property = { require(dimension == that.dimension) if (isEmpty) @@ -463,11 +469,11 @@ class ParallelotopeRationalDomain private(favorAxis: Int) extends NumericalDomai } /** - * @inheritdoc - * @note @inheritdoc - * @todo @inheritdoc - * @throws $ILLEGAL - */ + * @inheritdoc + * @note @inheritdoc + * @todo @inheritdoc + * @throws $ILLEGAL + */ def linearAssignment(n: Int, lf: LinearForm): Property = { require(n <= dimension && lf.dimension <= dimension) val tcoeff = lf.homcoeffs @@ -476,7 +482,7 @@ class ParallelotopeRationalDomain private(favorAxis: Int) extends NumericalDomai this else { val coeff = DenseVector(tcoeff.padTo(dimension, Rational.zero): _*) - if (! coeff(n).isZero) { + if (!coeff(n).isZero) { // invertible assignment val increment = A.col(n) * known / coeff(n) val newlow = low.copy @@ -495,7 +501,9 @@ class ParallelotopeRationalDomain private(favorAxis: Int) extends NumericalDomai // non-invertible assignment val newP = nonDeterministicAssignment(n) val Aprime = newP.A.copy - val j = ((0 until Aprime.rows) find { !Aprime(_, n).isZero }).get + val j = ((0 until Aprime.rows) find { + !Aprime(_, n).isZero + }).get for (s <- 0 until dimension if !Aprime(s, n).isZero && s != j) Aprime.rowUpdate(s, Aprime.row(s) - Aprime.row(j) * (Aprime(s, n) / Aprime(j, n))) val ei = DenseVector.zeros(dimension) @@ -512,21 +520,21 @@ class ParallelotopeRationalDomain private(favorAxis: Int) extends NumericalDomai } /** - * Computes the dot product of `x` and `y` with the proviso that if `x` is zero, then `x*y` - * is zero even when `y` is an infinite value (which is not the standard behaviour). - */ - private def dotprod(x: DenseVector, y: Bounds, remove: Int = -1): RationalExt = { + * Computes the dot product of `x` and `y` with the proviso that if `x` is zero, then `x*y` + * is zero even when `y` is an infinite value (which is not the standard behaviour). + */ + private def dotprod(x: DenseVector, y: Bounds, remove: Int): RationalExt = { var sum = RationalExt.zero for (i <- 0 until x.length if i != remove if x(i) != Rational.zero) sum = sum + y(i) * x(i) sum } /** - * @inheritdoc - * @note @inheritdoc - * @todo @inheritdoc - * @throws ILLEGAL - */ + * @inheritdoc + * @note @inheritdoc + * @todo @inheritdoc + * @throws ILLEGAL + */ def linearInequality(lf: LinearForm): Property = { require(lf.dimension <= dimension) if (isEmpty) @@ -586,10 +594,10 @@ class ParallelotopeRationalDomain private(favorAxis: Int) extends NumericalDomai } /** - * @inheritdoc - * @note @inheritdoc - * @throws $ILLEGAL - */ + * @inheritdoc + * @note @inheritdoc + * @throws $ILLEGAL + */ def linearDisequality(lf: LinearForm): Property = { val tcoeff = lf.homcoeffs val known = lf.known @@ -613,10 +621,10 @@ class ParallelotopeRationalDomain private(favorAxis: Int) extends NumericalDomai } /** - * @inheritdoc - * @note @inheritdoc - * @throws $ILLEGAL - */ + * @inheritdoc + * @note @inheritdoc + * @throws $ILLEGAL + */ def nonDeterministicAssignment(n: Int): Property = { require(n <= dimension) if (isEmpty) @@ -687,10 +695,10 @@ class ParallelotopeRationalDomain private(favorAxis: Int) extends NumericalDomai def isPolyhedral = true /** - * @inheritdoc - * @note @inheritdoc - * @throws $ILLEGAL - */ + * @inheritdoc + * @note @inheritdoc + * @throws $ILLEGAL + */ def delVariable(n: Int): Property = { def rowToSeq(M: DenseMatrix, i: Int, n: Int): Seq[Rational] = for (j <- 0 until A.rows; if j != n) yield M(i, j) @@ -706,8 +714,8 @@ class ParallelotopeRationalDomain private(favorAxis: Int) extends NumericalDomai } /** - * @inheritdoc - */ + * @inheritdoc + */ def mapVariables(rho: Seq[Int]): Property = { if (isEmpty) this @@ -722,14 +730,17 @@ class ParallelotopeRationalDomain private(favorAxis: Int) extends NumericalDomai } /** - * Compute the minimum and maximum value of a linear form in a parallelotope. - * @todo should be generalized to linear forms over arbitrary types. - * @return a tuple with two components: the first component is the least value, the second component is the greatest value - * of the linear form over the box. - */ + * Compute the minimum and maximum value of a linear form in a parallelotope. + * + * @todo should be generalized to linear forms over arbitrary types. + * @return a tuple with two components: the first component is the least value, the second component is the greatest value + * of the linear form over the box. + */ def linearEvaluation(lf: LinearForm): (RationalExt, RationalExt) = { val tcoeff = lf.homcoeffs - if (isEmpty && tcoeff.exists { _ != Rational.zero }) + if (isEmpty && tcoeff.exists { + _ != Rational.zero + }) (RationalExt.PositiveInfinity, RationalExt.NegativeInfinity) else if (dimension == 0) (lf.known, lf.known) @@ -762,7 +773,8 @@ class ParallelotopeRationalDomain private(favorAxis: Int) extends NumericalDomai def top = ParallelotopeRationalDomain.this.top(dimension) def tryCompareTo[B >: Property](that: B)(implicit arg0: (B) => PartiallyOrdered[B]): Option[Int] = that match { - case that: Property => + // we use ParallelotopeRationalDomain#Property instead of just Property to avoid a warning + case that: ParallelotopeRationalDomain#Property => val lte = this <= that val gte = that <= this if (lte && gte) @@ -777,12 +789,13 @@ class ParallelotopeRationalDomain private(favorAxis: Int) extends NumericalDomai } /** - * It computes the smallest parallelotope which contains `this` and is definable - * over a new shape matrix `Aprime`. - * @param Aprime the new shape matrix. - * @note `Aprime` should be an invertible matrix of the same dimension as `this`. - * @throws IllegalArgumentException if `Aprime` is not square or has not the correct dimension. - */ + * It computes the smallest parallelotope which contains `this` and is definable + * over a new shape matrix `Aprime`. + * + * @param Aprime the new shape matrix. + * @note `Aprime` should be an invertible matrix of the same dimension as `this`. + * @throws IllegalArgumentException if `Aprime` is not square or has not the correct dimension. + */ def rotate(Aprime: DenseMatrix): Property = { require(dimension == Aprime.rows && dimension == Aprime.cols) if (isEmpty) @@ -805,26 +818,31 @@ class ParallelotopeRationalDomain private(favorAxis: Int) extends NumericalDomai } } - def <=[B >: Property](that: Property)(implicit arg0: (B) => PartiallyOrdered[B]): Boolean = { - if (isEmpty) - true - else if (that.isEmpty) - false - else if (that.isTop) - true - else { - val ptemp = this.rotate(that.A) - (0 to ptemp.low.length - 1) forall { i => ptemp.low(i) >= that.low(i) && ptemp.high(i) <= that.high(i) } + override def <=[B >: Property](that: B)(implicit arg0: (B) => PartiallyOrdered[B]): Boolean = + that match { + // we use ParallelotopeRationalDomain#Property instead of just Property to avoid a warning + case that: ParallelotopeRationalDomain#Property => + if (isEmpty) + true + else if (that.isEmpty) + false + else if (that.isTop) + true + else { + val ptemp = this.rotate(that.A) + (0 to ptemp.low.length - 1) forall { i => ptemp.low(i) >= that.low(i) && ptemp.high(i) <= that.high(i) } + } + case _ => false } - } - def >=[B >: Property](that: Property)(implicit arg0: (B) => PartiallyOrdered[B]): Boolean = + + override def >=[B >: Property](that: B)(implicit arg0: (B) => PartiallyOrdered[B]): Boolean = that <= this - def <[B >: Property](that: Property)(implicit arg0: (B) => PartiallyOrdered[B]): Boolean = + override def <[B >: Property](that: B)(implicit arg0: (B) => PartiallyOrdered[B]): Boolean = (this <= that) && !(this >= that) - def >[B >: Property](that: Property)(implicit arg0: (B) => PartiallyOrdered[B]): Boolean = + override def >[B >: Property](that: B)(implicit arg0: (B) => PartiallyOrdered[B]): Boolean = (this >= that) && !(this <= that) def mkString(vars: Seq[String]): String = { @@ -869,22 +887,24 @@ class ParallelotopeRationalDomain private(favorAxis: Int) extends NumericalDomai } } } + } /** - * Companion class for the parallelotope domain - */ + * Companion class for the parallelotope domain + */ object ParallelotopeRationalDomain { private lazy val standard = new ParallelotopeRationalDomain(0) with CachedTopBottom private lazy val favoring = new ParallelotopeRationalDomain(1) with CachedTopBottom private lazy val unfavoring = new ParallelotopeRationalDomain(-1) with CachedTopBottom /** - * Returns an abstract domain for parallelotopes. - * @param favorAxis determines whether the heuristics built into the domain should try to keep constraints - * corresponding to Cartesian axis. If favorAxis is `1`, axis are favorite. The opposite happens when favorAxis - * is -1. If favorAxis is 0, axis are considered like all the other constraints - */ + * Returns an abstract domain for parallelotopes. + * + * @param favorAxis determines whether the heuristics built into the domain should try to keep constraints + * corresponding to Cartesian axis. If favorAxis is `1`, axis are favorite. The opposite happens when favorAxis + * is -1. If favorAxis is 0, axis are considered like all the other constraints + */ def apply(favorAxis: Int = 0) = favorAxis match { case -1 => unfavoring case 0 => standard diff --git a/core/src/main/scala/it/unich/jandom/domains/numerical/SumDomain.scala b/core/src/main/scala/it/unich/jandom/domains/numerical/SumDomain.scala index 412ffc49..eeb0490b 100644 --- a/core/src/main/scala/it/unich/jandom/domains/numerical/SumDomain.scala +++ b/core/src/main/scala/it/unich/jandom/domains/numerical/SumDomain.scala @@ -103,8 +103,8 @@ abstract class SumDomain[D1 <: NumericalDomain, D2 <: NumericalDomain] extends N // we divide the known coefficient evenly between the two domains // a better choice could be performed by knowing some info on the two domains val newlf = new DenseLinearForm(lf.known / 2 +: lf.homcoeffs) - var q1 = p1.linearAssignment(n, newlf) - var q2 = p2.linearAssignment(n, newlf) + val q1 = p1.linearAssignment(n, newlf) + val q2 = p2.linearAssignment(n, newlf) SumDomain.this(q1, q2) } @@ -112,8 +112,8 @@ abstract class SumDomain[D1 <: NumericalDomain, D2 <: NumericalDomain] extends N if (p1.isEmpty || p2.isEmpty) this else { - var w1 = p1.minimize(lf) - var w2 = p2.minimize(lf) + val w1 = p1.minimize(lf) + val w2 = p2.minimize(lf) if (!w1.isInfinity && !w2.isInfinity) { val lf_k1 = new DenseLinearForm(w2.value +: lf.homcoeffs) val lf_k2 = new DenseLinearForm(w1.value +: lf.homcoeffs) diff --git a/core/src/main/scala/it/unich/jandom/parsers/FastParser.scala b/core/src/main/scala/it/unich/jandom/parsers/FastParser.scala index fa8471fc..1ddc8c19 100644 --- a/core/src/main/scala/it/unich/jandom/parsers/FastParser.scala +++ b/core/src/main/scala/it/unich/jandom/parsers/FastParser.scala @@ -25,9 +25,7 @@ import it.unich.jandom.targets.Environment import it.unich.jandom.targets.NumericAssignment import it.unich.jandom.targets.NumericCondition import it.unich.jandom.targets.NumericCondition._ -import it.unich.jandom.targets.NumericExpression._ import it.unich.jandom.targets.lts._ -import it.unich.jandom.targets.NumericAssignmentMultiple /** * Parser for transition systems as they appear in the Fast analyzer. diff --git a/core/src/main/scala/it/unich/jandom/parsers/LPInvParser.scala b/core/src/main/scala/it/unich/jandom/parsers/LPInvParser.scala index 98243aba..14aee117 100644 --- a/core/src/main/scala/it/unich/jandom/parsers/LPInvParser.scala +++ b/core/src/main/scala/it/unich/jandom/parsers/LPInvParser.scala @@ -25,7 +25,6 @@ import it.unich.jandom.targets.lts.LTS import it.unich.jandom.targets.lts.Location import it.unich.jandom.targets.lts.Transition import it.unich.jandom.targets.NumericAssignment -import it.unich.jandom.targets.NumericAssignmentMultiple /** * Parser for transition systems as they appear in the [[http://www.cs.colorado.edu/~srirams/Software/lpinv.html LPInv]] diff --git a/core/src/main/scala/it/unich/jandom/parsers/NumericConditionParser.scala b/core/src/main/scala/it/unich/jandom/parsers/NumericConditionParser.scala index 93877bb7..b081acc9 100644 --- a/core/src/main/scala/it/unich/jandom/parsers/NumericConditionParser.scala +++ b/core/src/main/scala/it/unich/jandom/parsers/NumericConditionParser.scala @@ -19,7 +19,6 @@ package it.unich.jandom.parsers import scala.util.parsing.combinator.JavaTokenParsers -import it.unich.jandom.domains.numerical.LinearForm import it.unich.jandom.targets.NumericExpression import it.unich.jandom.targets.NumericCondition import it.unich.jandom.targets.NumericCondition._ diff --git a/core/src/main/scala/it/unich/jandom/targets/NumericAssignment.scala b/core/src/main/scala/it/unich/jandom/targets/NumericAssignment.scala index e758e2cf..4f8936b7 100644 --- a/core/src/main/scala/it/unich/jandom/targets/NumericAssignment.scala +++ b/core/src/main/scala/it/unich/jandom/targets/NumericAssignment.scala @@ -18,8 +18,7 @@ package it.unich.jandom.targets -import it.unich.jandom.domains.numerical.{ LinearForm, NumericalProperty } -import it.unich.jandom.targets.NumericExpression._ +import it.unich.jandom.domains.numerical.NumericalProperty /** * This is a target class for the numeric assignments "v := exp". diff --git a/core/src/main/scala/it/unich/jandom/targets/cfg/ControlFlowGraph.scala b/core/src/main/scala/it/unich/jandom/targets/cfg/ControlFlowGraph.scala index 2cce1123..0f24a504 100644 --- a/core/src/main/scala/it/unich/jandom/targets/cfg/ControlFlowGraph.scala +++ b/core/src/main/scala/it/unich/jandom/targets/cfg/ControlFlowGraph.scala @@ -19,6 +19,7 @@ package it.unich.jandom.targets.cfg import scala.collection.mutable.HashMap import scala.collection.mutable.Queue +import scala.collection.JavaConverters._ import it.unich.jandom.targets.Annotation import it.unich.jandom.targets.Target import soot.toolkits.graph.DirectedGraph @@ -32,8 +33,6 @@ import soot.toolkits.graph.DirectedGraph * @author Francesca Scozzari */ abstract class ControlFlowGraph[Tgt <: ControlFlowGraph[Tgt, Node], Node] extends Target[Tgt] { - import scala.collection.JavaConversions._ - /** * The `ProgramPoint` type is defined as an alias for the `Node`. We are wondering whether to make * `ProgramPoint` an alias for `Edge`. @@ -68,7 +67,7 @@ abstract class ControlFlowGraph[Tgt <: ControlFlowGraph[Tgt, Node], Node] extend * of the CFG, so be careful to preserve this property. */ def extractOutput(params: Parameters)(ann: Annotation[ProgramPoint, params.Property]): params.Property = { - graph.getTails map { (node) => analyzeBlock(params)(node, ann(node)).last } reduce { _ union _ } + graph.getTails.asScala map { (node) => analyzeBlock(params)(node, ann(node)).last } reduce { _ union _ } } /** @@ -104,7 +103,7 @@ abstract class ControlFlowGraph[Tgt <: ControlFlowGraph[Tgt, Node], Node] extend */ def analyzeFromInput(params: Parameters)(input: params.Property): Annotation[ProgramPoint, params.Property] = { val ann = getAnnotation[params.Property] - for (node <- graph.getHeads()) ann(node) = expandPropertyWithLocalVariables(params)(input) + for (node <- graph.getHeads().asScala) ann(node) = expandPropertyWithLocalVariables(params)(input) analyzeFromAnnotation(params)(ann) } @@ -115,7 +114,7 @@ abstract class ControlFlowGraph[Tgt <: ControlFlowGraph[Tgt, Node], Node] extend */ def analyze(params: Parameters): Annotation[ProgramPoint, params.Property] = { val ann = getAnnotation[params.Property] - for (node <- graph.getHeads) ann(node) = topProperty(node, params) + for (node <- graph.getHeads.asScala) ann(node) = topProperty(node, params) analyzeFromAnnotation(params)(ann) } @@ -124,7 +123,7 @@ abstract class ControlFlowGraph[Tgt <: ControlFlowGraph[Tgt, Node], Node] extend */ def analyzeFromAnnotation(params: Parameters)(ann: Annotation[ProgramPoint, params.Property]): Annotation[ProgramPoint, params.Property] = { val annEdge = HashMap[Edge, params.Property]() - val taskList = Queue[ProgramPoint](graph.getHeads: _*) + val taskList = Queue[ProgramPoint](graph.getHeads.asScala: _*) // ASCENDING phase params.log("Ascening Phase\n") @@ -133,9 +132,9 @@ abstract class ControlFlowGraph[Tgt <: ControlFlowGraph[Tgt, Node], Node] extend params.log(s"node ${node}input ${ann(node)}\n") val result = analyzeBlock(params)(node, ann(node)) params.log("result " + result.mkString(",") + "\n") - for ((succ, out) <- graph.getSuccsOf(node) zip result) { + for ((succ, out) <- graph.getSuccsOf(node).asScala zip result) { annEdge((node, succ)) = out - if (graph.getPredsOf(succ).length > 1 && (ann contains succ)) { + if (graph.getPredsOf(succ).size() > 1 && (ann contains succ)) { params.log(s"join $succ : ${ann(succ)} with $out") val succval: params.Property = if (ordering.lteq(succ, node)) { params.log(s" widening") @@ -157,16 +156,16 @@ abstract class ControlFlowGraph[Tgt <: ControlFlowGraph[Tgt, Node], Node] extend } // DESCENDING phase - taskList.enqueue(graph.toSeq: _*) + taskList.enqueue(graph.asScala.toSeq: _*) params.log("Descending Phase\n") while (!taskList.isEmpty) { val node = taskList.dequeue params.log(s"node ${node} input ${ann(node)} ") val result = analyzeBlock(params)(node, ann(node)) - params.log("result " + (graph.getSuccsOf(node) zip result).mkString(" ; ") + "\n") - for ((succ, out) <- graph.getSuccsOf(node) zip result) { + params.log("result " + (graph.getSuccsOf(node).asScala zip result).mkString(" ; ") + "\n") + for ((succ, out) <- graph.getSuccsOf(node).asScala zip result) { annEdge((node, succ)) = out - val newinput = ann(succ) intersection (graph.getPredsOf(succ) map { e => annEdge((e, succ)) } reduce { _ union _ }) + val newinput = ann(succ) intersection (graph.getPredsOf(succ).asScala map { e => annEdge((e, succ)) } reduce { _ union _ }) params.log(s"narrow $succ : ${ann(succ)} with $newinput ") // this may probably cause an infinite loop val succval = if (ordering.lteq(succ, node)) { diff --git a/core/src/main/scala/it/unich/jandom/targets/jvmasm/AsmMethod.scala b/core/src/main/scala/it/unich/jandom/targets/jvmasm/AsmMethod.scala index c21608c5..31d7d40d 100644 --- a/core/src/main/scala/it/unich/jandom/targets/jvmasm/AsmMethod.scala +++ b/core/src/main/scala/it/unich/jandom/targets/jvmasm/AsmMethod.scala @@ -27,7 +27,6 @@ import org.objectweb.asm._ import org.objectweb.asm.tree._ import org.objectweb.asm.util._ -import it.unich.jandom.domains.numerical.NumericalProperty import it.unich.jandom.targets.Annotation import it.unich.jandom.targets.Target import it.unich.jandom.targets.NumericCondition._ @@ -86,7 +85,7 @@ class AsmMethod(val methodNode: MethodNode) extends Target[AsmMethod] { import Opcodes._ val s = state.clone var node = startNode - var lastNode = endNode.getNext() + val lastNode = endNode.getNext() var exits = Seq[(BasicBlock, Property)]() while (node != lastNode) { val op = node.getOpcode @@ -167,9 +166,6 @@ class AsmMethod(val methodNode: MethodNode) extends Target[AsmMethod] { * It is called by the constructor. */ private def createControlFlowGraph(): (BasicBlock, BasicBlock) = { - import scala.collection.JavaConversions._ - import AbstractInsnNode._ - // the use of asInstanceOf is needed because the standard // asm library in the maven repositories is compiled without // support for generics diff --git a/core/src/main/scala/it/unich/jandom/targets/jvmasm/JVMEnvFixedFrame.scala b/core/src/main/scala/it/unich/jandom/targets/jvmasm/JVMEnvFixedFrame.scala index d4717232..c5ade7bc 100644 --- a/core/src/main/scala/it/unich/jandom/targets/jvmasm/JVMEnvFixedFrame.scala +++ b/core/src/main/scala/it/unich/jandom/targets/jvmasm/JVMEnvFixedFrame.scala @@ -18,8 +18,6 @@ package it.unich.jandom.targets.jvmasm -import scala.collection.mutable.ArrayStack - import it.unich.jandom.domains.numerical.LinearForm import it.unich.jandom.domains.numerical.NumericalDomain import it.unich.jandom.domains.numerical.NumericalProperty diff --git a/core/src/main/scala/it/unich/jandom/targets/jvmasm/UnsupportedASMInsnException.scala b/core/src/main/scala/it/unich/jandom/targets/jvmasm/UnsupportedASMInsnException.scala index 7b6e4bce..3bab84c4 100644 --- a/core/src/main/scala/it/unich/jandom/targets/jvmasm/UnsupportedASMInsnException.scala +++ b/core/src/main/scala/it/unich/jandom/targets/jvmasm/UnsupportedASMInsnException.scala @@ -19,7 +19,6 @@ package it.unich.jandom.targets.jvmasm import org.objectweb.asm.tree._ -import soot.baf.Inst /** * This exception is generated by the ASM analyzer when an unknown opcode is diff --git a/core/src/main/scala/it/unich/jandom/targets/jvmsoot/BafMethod.scala b/core/src/main/scala/it/unich/jandom/targets/jvmsoot/BafMethod.scala index a1d29517..dfa48e15 100644 --- a/core/src/main/scala/it/unich/jandom/targets/jvmsoot/BafMethod.scala +++ b/core/src/main/scala/it/unich/jandom/targets/jvmsoot/BafMethod.scala @@ -17,6 +17,8 @@ package it.unich.jandom.targets.jvmsoot +import scala.collection.JavaConverters._ + import soot._ import soot.baf._ import soot.jimple._ @@ -30,8 +32,6 @@ import soot.toolkits.graph._ * @author Luca Mangifesta */ class BafMethod(method: SootMethod) extends SootCFG[BafMethod, Block](method) { - import scala.collection.JavaConversions._ - val body = Baf.v().newBody(method.retrieveActiveBody()) val graph = new soot.jandom.UnitBlockGraph(body) @@ -62,7 +62,7 @@ class BafMethod(method: SootMethod) extends SootCFG[BafMethod, Block](method) { case _: IfNullInst => prop.evalNull().testEq } - for (unit <- node.iterator()) + for (unit <- node.iterator().asScala) currprop = unit match { case unit: AddInst => unit.getOpType() match { diff --git a/core/src/main/scala/it/unich/jandom/targets/jvmsoot/JimpleMethod.scala b/core/src/main/scala/it/unich/jandom/targets/jvmsoot/JimpleMethod.scala index b8d4e0c8..4a978fb8 100644 --- a/core/src/main/scala/it/unich/jandom/targets/jvmsoot/JimpleMethod.scala +++ b/core/src/main/scala/it/unich/jandom/targets/jvmsoot/JimpleMethod.scala @@ -18,6 +18,8 @@ package it.unich.jandom.targets.jvmsoot +import scala.collection.JavaConverters._ + import it.unich.jandom.domains.numerical.LinearForm import it.unich.jandom.targets._ import it.unich.jandom.targets.NumericCondition._ @@ -35,8 +37,6 @@ import spire.math.Rational * @author Francesca Scozzari */ class JimpleMethod(method: SootMethod) extends SootCFG[JimpleMethod, Block](method) { - import scala.collection.JavaConversions._ - val body = method.retrieveActiveBody() val graph = new soot.jandom.UnitBlockGraph(body) @@ -48,7 +48,6 @@ class JimpleMethod(method: SootMethod) extends SootCFG[JimpleMethod, Block](meth */ def jimpleExprToLinearForm(v: Value): Option[Array[Rational]] = { val a = Array.fill(size + 1)(Rational.zero) - var c = Rational.zero v match { case v: IntConstant => a(0) = v.value @@ -163,7 +162,7 @@ class JimpleMethod(method: SootMethod) extends SootCFG[JimpleMethod, Block](meth case v: DynamicInvokeExpr => throw new IllegalArgumentException("Invoke dynamic not yet supported") } - val callprop = v.getArgs().foldLeft(baseprop) { case (p, arg) => analyzeExpr(arg, p) } + val callprop = v.getArgs().asScala.foldLeft(baseprop) { case (p, arg) => analyzeExpr(arg, p) } val inputprop = callprop.extract(v.getArgCount() + implicitArgs) val exitprop = params.interpretation match { case Some(inte) => inte(method, inputprop) @@ -221,7 +220,6 @@ class JimpleMethod(method: SootMethod) extends SootCFG[JimpleMethod, Block](meth case v: NeExpr => res2.evalNe } case v: UnopExpr => - val res = analyzeExpr(v.getOp(), prop) v match { case v: LengthExpr => prop.evalLength case v: NegExpr => prop.evalNeg @@ -236,7 +234,7 @@ class JimpleMethod(method: SootMethod) extends SootCFG[JimpleMethod, Block](meth var exits = Seq[params.Property]() var currprop = initprop - for (unit <- node.iterator()) + for (unit <- node.asScala) unit match { case unit: AssignStmt => val expr = analyzeExpr(unit.getRightOp(), currprop) diff --git a/core/src/main/scala/it/unich/jandom/targets/jvmsoot/SootCFG.scala b/core/src/main/scala/it/unich/jandom/targets/jvmsoot/SootCFG.scala index eebdf170..53d46d34 100644 --- a/core/src/main/scala/it/unich/jandom/targets/jvmsoot/SootCFG.scala +++ b/core/src/main/scala/it/unich/jandom/targets/jvmsoot/SootCFG.scala @@ -20,7 +20,8 @@ package it.unich.jandom.targets.jvmsoot import java.io._ -import it.unich.jandom.domains.AbstractProperty +import scala.collection.JavaConverters._ + import it.unich.jandom.targets.Annotation import it.unich.jandom.targets.Environment import it.unich.jandom.targets.cfg.ControlFlowGraph @@ -40,14 +41,12 @@ import soot.toolkits.graph.PseudoTopologicalOrderer * @author Francesca Scozzari */ abstract class SootCFG[Tgt <: SootCFG[Tgt, Node], Node <: Block](val method: SootMethod) extends ControlFlowGraph[Tgt, Node] { - import scala.collection.JavaConversions._ - type DomainBase = SootFrameDomain val body: Body // local variables of the method. - def locals = body.getLocals().toIndexedSeq + def locals = body.getLocals().asScala.toIndexedSeq // These are lazy values since body is not initialized when they are executed @@ -59,7 +58,7 @@ abstract class SootCFG[Tgt <: SootCFG[Tgt, Node], Node <: Block](val method: Soo // An ordering on nodes gives by a pseudo-topological orderer lazy val ordering = new Ordering[Node] { - val order = new PseudoTopologicalOrderer[Node].newList(graph, false).zipWithIndex.toMap + val order = new PseudoTopologicalOrderer[Node].newList(graph, false).asScala.zipWithIndex.toMap def compare(x: Node, y: Node) = order(x) - order(y) } @@ -121,7 +120,7 @@ abstract class SootCFG[Tgt <: SootCFG[Tgt, Node], Node <: Block](val method: Soo * It expands the input property adding new variables until exhausting locals. */ protected def expandPropertyWithLocalVariables(params: Parameters)(input: params.Property): params.Property = { - body.getLocals.foldLeft(input) { (current, local) => current.evalUnknown(local.getType()) } + body.getLocals.asScala.foldLeft(input) { (current, local) => current.evalUnknown(local.getType()) } } /** @@ -147,7 +146,7 @@ abstract class SootCFG[Tgt <: SootCFG[Tgt, Node], Node <: Block](val method: Soo if (params.io) { expandPropertyWithLocalVariables(params)(params.domain.top(inputTypes)) } else { - params.domain.top(method.getActiveBody.getLocals.toSeq map { (l) => l.getType }) + params.domain.top(method.getActiveBody.getLocals.asScala.toSeq map { (l) => l.getType }) } } @@ -235,7 +234,6 @@ object SootCFG { * - type of return value (only if the return type is not void) */ def outputTypes(method: SootMethod) = { - import scala.collection.JavaConversions._ val returnTypes = if (method.getReturnType() == VoidType.v()) Seq() @@ -251,13 +249,12 @@ object SootCFG { * - types of parameters @parameter0, @parameter1, ... */ def inputTypes(method: SootMethod) = { - import scala.collection.JavaConversions._ val thisType = if (method.isStatic()) Seq() else Seq(method.getDeclaringClass().getType()) - val parameterTypes = method.getParameterTypes().toSeq.asInstanceOf[Seq[Type]] + val parameterTypes = method.getParameterTypes().asScala thisType ++ parameterTypes } } diff --git a/core/src/main/scala/it/unich/jandom/targets/jvmsoot/SootFrameDomain.scala b/core/src/main/scala/it/unich/jandom/targets/jvmsoot/SootFrameDomain.scala index 19820c7c..fa8485a7 100644 --- a/core/src/main/scala/it/unich/jandom/targets/jvmsoot/SootFrameDomain.scala +++ b/core/src/main/scala/it/unich/jandom/targets/jvmsoot/SootFrameDomain.scala @@ -19,8 +19,6 @@ package it.unich.jandom.targets.jvmsoot import it.unich.jandom.targets.NumericCondition -import it.unich.jandom.domains.AbstractDomain -import it.unich.jandom.domains.AbstractProperty import it.unich.jandom.domains.CartesianFiberedProperty import it.unich.jandom.domains.CartesianFiberedDomain diff --git a/core/src/main/scala/it/unich/jandom/targets/jvmsoot/SootFrameObjectDomain.scala b/core/src/main/scala/it/unich/jandom/targets/jvmsoot/SootFrameObjectDomain.scala index 1f4d33d8..0c9c74b1 100644 --- a/core/src/main/scala/it/unich/jandom/targets/jvmsoot/SootFrameObjectDomain.scala +++ b/core/src/main/scala/it/unich/jandom/targets/jvmsoot/SootFrameObjectDomain.scala @@ -66,12 +66,7 @@ class SootFrameObjectDomain(val dom: ObjectDomain[SootObjectModel]) extends Soot invariantCheck - /** - * Returns the SootClass of a given frame variable - */ - private def classOfVar(i: Int): SootClass = stack(size - i - 1).asInstanceOf[RefType].getSootClass() - - /** + /** * Remove the top frame variable. */ private def delUntrackedVariable = Property(prop.delVariable(size - 1), stack.tail, globals) diff --git a/core/src/main/scala/it/unich/jandom/targets/jvmsoot/SootInterpretation.scala b/core/src/main/scala/it/unich/jandom/targets/jvmsoot/SootInterpretation.scala index 9edaef43..430d3adb 100644 --- a/core/src/main/scala/it/unich/jandom/targets/jvmsoot/SootInterpretation.scala +++ b/core/src/main/scala/it/unich/jandom/targets/jvmsoot/SootInterpretation.scala @@ -18,6 +18,8 @@ package it.unich.jandom.targets.jvmsoot +import scala.collection.JavaConverters._ + import it.unich.jandom.targets._ import soot.SootMethod @@ -86,8 +88,6 @@ class JimpleInterpretation[Params <: Parameters[JimpleMethod]](val params: Param * with a work-list based approach. Each method has a single possible input context, which is top. */ class JimpleRecursiveInterpretation[Params <: Parameters[JimpleMethod]](scene: Scene, val params: Params) extends Interpretation[JimpleMethod, Params] { - import scala.collection.JavaConversions._ - val inte = scala.collection.mutable.HashMap[SootMethod, params.Property]() val targets = scala.collection.mutable.HashMap[SootMethod, Option[JimpleMethod]]() @@ -110,8 +110,8 @@ class JimpleRecursiveInterpretation[Params <: Parameters[JimpleMethod]](scene: S val tpo = new TopologicalOrderer(cg) tpo.go() - val order = tpo.order().reverse // it is enough to get the set of all the elements - if (order.isEmpty()) order.add(method) + val order = tpo.order().asScala.reverse // it is enough to get the set of all the elements + if (order.isEmpty) order += method for (m <- order; if !(targets contains m)) { targets(m) = if (m.isConcrete()) Some(new JimpleMethod(m)) else None @@ -133,7 +133,7 @@ class JimpleRecursiveInterpretation[Params <: Parameters[JimpleMethod]](scene: S if (!(inte(m) >= output)) { inte(m) = inte(m) widening output val sources = new Sources(cg.edgesInto(m)).asInstanceOf[java.util.Iterator[SootMethod]] - worklist.enqueue(sources.toSeq: _*) + worklist.enqueue(sources.asScala.toSeq: _*) } } } diff --git a/core/src/main/scala/it/unich/jandom/targets/jvmsoot/SootObjectModel.scala b/core/src/main/scala/it/unich/jandom/targets/jvmsoot/SootObjectModel.scala index 660937cb..bf41964f 100644 --- a/core/src/main/scala/it/unich/jandom/targets/jvmsoot/SootObjectModel.scala +++ b/core/src/main/scala/it/unich/jandom/targets/jvmsoot/SootObjectModel.scala @@ -18,6 +18,8 @@ package it.unich.jandom.targets.jvmsoot +import scala.collection.JavaConverters._ + import it.unich.jandom.objectmodels.ObjectModel import it.unich.jandom.objectmodels.ObjectModelHelper @@ -31,7 +33,6 @@ import soot.jandom.MyFastHierarchy */ class SootObjectModel(scene: soot.Scene) extends ObjectModel with ObjectModelHelper { - import scala.collection.JavaConversions._ type Type = soot.Type @@ -50,7 +51,7 @@ class SootObjectModel(scene: soot.Scene) extends ObjectModel with ObjectModelHel } def declaredFields(t: Type) = t match { - case t: RefType => t.getSootClass().getFields().toSet + case t: RefType => t.getSootClass().getFields().asScala.toSet case _: PrimType => Set() case _: ArrayType => Set() case _: NullType => Set() @@ -91,7 +92,7 @@ class SootObjectModel(scene: soot.Scene) extends ObjectModel with ObjectModelHel case t: RefType => val k = t.getSootClass() val ifs: Set[Type] = (for { - i <- k.getInterfaces() + i <- k.getInterfaces().asScala } yield i.getType())(collection.breakOut) if (k.hasSuperclass()) ifs + k.getSuperclass().getType() @@ -106,10 +107,10 @@ class SootObjectModel(scene: soot.Scene) extends ObjectModel with ObjectModelHel case t: RefType => val k = t.getSootClass() if (k.isInterface()) { - (fh.getAllImplementersOfInterface(k) map { _.getType() }).toSet ++ - (fh.getSubinterfaces(k) map { _.getType() }).toSet + (fh.getAllImplementersOfInterface(k).asScala map { _.getType() }).toSet ++ + (fh.getSubinterfaces(k).asScala map { _.getType() }).toSet } else { - (fh.getSubclassesOf(k) map { _.getType() }).toSet + (fh.getSubclassesOf(k).asScala map { _.getType() }).toSet } case _: PrimType => Set() case t: ArrayType => children(t.baseType) map { (ArrayType.v(_, t.numDimensions)) } diff --git a/core/src/main/scala/it/unich/jandom/targets/lts/LTS.scala b/core/src/main/scala/it/unich/jandom/targets/lts/LTS.scala index c91bc712..c2b9bd75 100644 --- a/core/src/main/scala/it/unich/jandom/targets/lts/LTS.scala +++ b/core/src/main/scala/it/unich/jandom/targets/lts/LTS.scala @@ -139,7 +139,6 @@ case class LTS(val name: String, val locations: IndexedSeq[Location], val transi } }, locations) } - val edges: Set[Edge] = ((transitions map { Left(_) }) ++ (inputlocs map { Right(_) })).toSet GraphEquationSystem[Location, dom.Property, Edge]( unknowns = locations, inputUnknowns = inputlocs.toSet, diff --git a/core/src/main/scala/it/unich/jandom/targets/lts/Transition.scala b/core/src/main/scala/it/unich/jandom/targets/lts/Transition.scala index ea8e1dda..420deadc 100644 --- a/core/src/main/scala/it/unich/jandom/targets/lts/Transition.scala +++ b/core/src/main/scala/it/unich/jandom/targets/lts/Transition.scala @@ -19,9 +19,7 @@ package it.unich.jandom.targets.lts import it.unich.jandom.domains.numerical.NumericalProperty -import it.unich.jandom.targets.NumericAssignment import it.unich.jandom.targets.NumericCondition -import it.unich.jandom.targets.NumericAssignment import it.unich.jandom.targets.NumericAssignmentMultiple /** diff --git a/core/src/main/scala/it/unich/jandom/targets/slil/AssignStmt.scala b/core/src/main/scala/it/unich/jandom/targets/slil/AssignStmt.scala index a9239f36..b3018753 100644 --- a/core/src/main/scala/it/unich/jandom/targets/slil/AssignStmt.scala +++ b/core/src/main/scala/it/unich/jandom/targets/slil/AssignStmt.scala @@ -19,7 +19,6 @@ package it.unich.jandom.targets.slil import it.unich.jandom.domains.numerical.NumericalProperty -import it.unich.jandom.domains.numerical.LinearForm import it.unich.jandom.targets.Annotation import AnalysisPhase.AnalysisPhase import it.unich.jandom.targets.NumericExpression diff --git a/core/src/main/scala/it/unich/jandom/targets/slil/IfStmt.scala b/core/src/main/scala/it/unich/jandom/targets/slil/IfStmt.scala index 9de434dd..1b481daf 100644 --- a/core/src/main/scala/it/unich/jandom/targets/slil/IfStmt.scala +++ b/core/src/main/scala/it/unich/jandom/targets/slil/IfStmt.scala @@ -43,7 +43,6 @@ case class IfStmt(condition: NumericCondition, then_branch: SLILStmt, else_branc override def mkString[U <: NumericalProperty[_]](ann: Annotation[ProgramPoint,U], ppspec: SLILPrinterSpec, row: Int, level: Int): String = { val spaces = ppspec.indent(level) - val innerspaces = ppspec.indent(level+1) val then_string = then_branch.mkString(ann, ppspec, row + 1, level + 1) val else_string = else_branch.mkString(ann, ppspec, row + 2 + then_string.count(_ == '\n'), level + 1) val s = spaces + "if (" + condition.mkString(ppspec.env.names) + ") {\n" + diff --git a/core/src/main/scala/it/unich/jandom/targets/slil/SLILProgram.scala b/core/src/main/scala/it/unich/jandom/targets/slil/SLILProgram.scala index badabab9..64c2a8e1 100644 --- a/core/src/main/scala/it/unich/jandom/targets/slil/SLILProgram.scala +++ b/core/src/main/scala/it/unich/jandom/targets/slil/SLILProgram.scala @@ -36,7 +36,6 @@ import it.unich.jandom.targets.slil.AnalysisPhase._ case class SLILProgram(val env: Environment, val inputVars: Seq[Int], val stmt: SLILStmt) extends SLILTarget { def mkString[U <: NumericalProperty[_]](ann: Annotation[ProgramPoint,U], ppspec: SLILPrinterSpec = SLILPrinterSpecInline(env)) = { val spaces = ppspec.indent(0) - val innerspaces = ppspec.indent(1) spaces + "function (" + (inputVars map { v: Int => env(v) }).mkString(",") + ") {\n" + stmt.mkString(ann, ppspec, 1, 1) + spaces + "}\n" @@ -45,7 +44,7 @@ case class SLILProgram(val env: Environment, val inputVars: Seq[Int], val stmt: override def analyze(params: Parameters): Annotation[ProgramPoint,params.Property] = { val input = params.domain.top(env.size) val ann = getAnnotation[params.Property] - val output = params.narrowingStrategy match { + params.narrowingStrategy match { case NarrowingStrategy.Separate => stmt.analyzeStmt(params)(input, Ascending, ann) stmt.analyzeStmt(params)(input, Descending, ann) diff --git a/core/src/main/scala/it/unich/jandom/ui/OutputInterface.scala b/core/src/main/scala/it/unich/jandom/ui/OutputInterface.scala index a4d7cb33..5b31d308 100644 --- a/core/src/main/scala/it/unich/jandom/ui/OutputInterface.scala +++ b/core/src/main/scala/it/unich/jandom/ui/OutputInterface.scala @@ -23,13 +23,11 @@ import java.io.IOException import java.nio.file._ import java.nio.file.attribute.BasicFileAttributes -import scala.collection.JavaConversions._ +import scala.collection.JavaConverters._ import scala.util.Try - import org.objectweb.asm.ClassReader import org.objectweb.asm.tree.ClassNode import org.objectweb.asm.tree.MethodNode - import it.unich.jandom.domains.numerical.NumericalDomain import it.unich.jandom.domains.objects.ObjectDomainFactory import it.unich.jandom.targets.parameters.WideningSpecs._ @@ -43,7 +41,6 @@ import it.unich.jandom.targets.lts._ import it.unich.jandom.targets.slil._ import soot.Scene import soot.toolkits.graph.Block -import it.unich.scalafix.Box /** * An output interface is a collection of methods for implementing an external interface. @@ -183,7 +180,7 @@ object OutputInterface { def getMethods(dir: Path, klassIndex: Int) = { val scene = getScene(dir) val sootKlass = scene.loadClassAndSupport(getClasses(dir)(klassIndex)) - sootKlass.getMethods().map(x => x.getName()) + sootKlass.getMethods().asScala.map(x => x.getName()) } private def getSootMethods(dir: Path, klassIndex: Int) = { @@ -235,7 +232,7 @@ object OutputInterface { } def getASMMethods(dir: String, klassName: String) = { - getASMMethodsList(dir, klassName) map { _.name } + getASMMethodsList(dir, klassName).asScala map { _.name } } def analyzeASM(dir: String, klassName: String, methodIndex: Int, domain: Int, wideningIndex: Int, @@ -317,7 +314,7 @@ private class ClassFileVisitor(rootPath: Path) extends SimpleFileVisitor[Path] { private val privateClassNamesList = scala.collection.mutable.SortedSet[String]() def classNameList = privateClassNamesList.toSeq override def visitFile(aFile: Path, aAttrs: BasicFileAttributes): FileVisitResult = { - val relativePath = rootPath.relativize(aFile) + val relativePath = rootPath.relativize(aFile).asScala val className = (relativePath.head.toString /: relativePath.tail)(_ + "." + _.toString) if (className endsWith ".class") privateClassNamesList += className stripSuffix ".class" diff --git a/core/src/main/scala/it/unich/jandom/ui/gui/ASMEditorPane.scala b/core/src/main/scala/it/unich/jandom/ui/gui/ASMEditorPane.scala index 16c95dbb..264f916d 100644 --- a/core/src/main/scala/it/unich/jandom/ui/gui/ASMEditorPane.scala +++ b/core/src/main/scala/it/unich/jandom/ui/gui/ASMEditorPane.scala @@ -18,6 +18,7 @@ package it.unich.jandom.ui.gui +import scala.collection.JavaConverters._ import java.awt.event.{ InputEvent, KeyEvent } import java.io.{ File, FileInputStream } import scala.swing.{Action, BorderPanel, BoxPanel, ComboBox, EditorPane, FileChooser, Label, MenuItem, Orientation, ScrollPane} @@ -77,8 +78,6 @@ class ASMEditorPane(val frame: MainFrame) extends BorderPanel with TargetPane { val openAction = new Action("Open...") { accelerator = Some(KeyStroke.getKeyStroke(KeyEvent.VK_O, InputEvent.CTRL_MASK)) def apply() { - import scala.collection.JavaConversions._ - val returnVal = fileChooser.showOpenDialog(ASMEditorPane.this) if (returnVal != FileChooser.Result.Approve) return ; val file = fileChooser.selectedFile @@ -86,7 +85,7 @@ class ASMEditorPane(val frame: MainFrame) extends BorderPanel with TargetPane { val cr = new ClassReader(is) val node = new ClassNode() cr.accept(node, ClassReader.SKIP_DEBUG) - methodList = node.methods.asInstanceOf[java.util.List[MethodNode]] + methodList = node.methods.asScala methodComboBox = new ComboBox(methodList map { _.name }) methodComboBox.peer.setAction(methodSelectAction.peer) methodSelector.contents(1) = methodComboBox diff --git a/core/src/main/scala/it/unich/jandom/ui/gui/ParametersPane.scala b/core/src/main/scala/it/unich/jandom/ui/gui/ParametersPane.scala index ce566cdc..d146cd23 100644 --- a/core/src/main/scala/it/unich/jandom/ui/gui/ParametersPane.scala +++ b/core/src/main/scala/it/unich/jandom/ui/gui/ParametersPane.scala @@ -30,7 +30,6 @@ import it.unich.jandom.targets.parameters.WideningSpecs._ import it.unich.jandom.targets.parameters.NarrowingSpecs._ import javax.swing.JSpinner import javax.swing.SpinnerNumberModel -import it.unich.scalafix.Box class ParametersPane extends GridBagPanel { border = Swing.EmptyBorder(5, 5, 5, 5) diff --git a/core/src/main/scala/it/unich/jandom/ui/gui/SootEditorPane.scala b/core/src/main/scala/it/unich/jandom/ui/gui/SootEditorPane.scala index 6841f0b0..53983419 100644 --- a/core/src/main/scala/it/unich/jandom/ui/gui/SootEditorPane.scala +++ b/core/src/main/scala/it/unich/jandom/ui/gui/SootEditorPane.scala @@ -24,7 +24,7 @@ import java.io.File import java.nio.file._ import java.nio.file.attribute.BasicFileAttributes -import scala.collection.JavaConversions._ +import scala.collection.JavaConverters._ import scala.swing._ import scala.swing.event.ActionEvent import scala.swing.event.EditDone @@ -144,9 +144,9 @@ class SootEditorPane(val frame: MainFrame) extends BorderPanel with TargetPane { case SelectionChanged(`classComboBox`) => val klass = sootScene.loadClassAndSupport(classComboBox.selection.item) - val methodList = klass.getMethods() + val methodList = klass.getMethods().asScala // these two lines are a mess because Scala Swing does not play well with Java 1.7 - val comboModel = ComboBox.newConstantModel(methodList).asInstanceOf[javax.swing.ComboBoxModel[SootMethod]] + val comboModel = ComboBox.newConstantModel(methodList) methodComboBox.peer.asInstanceOf[javax.swing.JComboBox[SootMethod]].setModel(comboModel) publish(SelectionChanged(methodComboBox)) @@ -169,7 +169,7 @@ class SootEditorPane(val frame: MainFrame) extends BorderPanel with TargetPane { private val privateClassNamesList = scala.collection.mutable.SortedSet[String]() def classNameList = privateClassNamesList.toSeq override def visitFile(aFile: Path, aAttrs: BasicFileAttributes): FileVisitResult = { - val relativePath = rootPath.relativize(aFile) + val relativePath = rootPath.relativize(aFile).asScala val className = (relativePath.head.toString /: relativePath.tail)(_ + "." + _.toString) if (className endsWith ".class") privateClassNamesList += className stripSuffix ".class" diff --git a/core/src/main/scala/it/unich/jandom/utils/DisjointSetsImpl.scala b/core/src/main/scala/it/unich/jandom/utils/DisjointSetsImpl.scala index 1931cd72..48995505 100644 --- a/core/src/main/scala/it/unich/jandom/utils/DisjointSetsImpl.scala +++ b/core/src/main/scala/it/unich/jandom/utils/DisjointSetsImpl.scala @@ -19,7 +19,6 @@ package it.unich.jandom.utils import scala.collection.mutable.{ Map => MMap } -import scala.collection.TraversableProxy /** * This class implements a disjoint-sets algorithm with @@ -55,8 +54,6 @@ class DisjointSetsImpl[T](initialElements: Seq[T]) extends DisjointSets[T] { def size = nodes.size - private def self = nodes.values.toTraversable - /** * Add a new single-node forest to the disjoint-set forests. It will * be placed into its own set. It returns the new node. diff --git a/core/src/main/scala/it/unich/jandom/utils/Relation.scala b/core/src/main/scala/it/unich/jandom/utils/Relation.scala index fa4f939e..5c4c8829 100644 --- a/core/src/main/scala/it/unich/jandom/utils/Relation.scala +++ b/core/src/main/scala/it/unich/jandom/utils/Relation.scala @@ -101,7 +101,7 @@ object Relation { * This is a trait which may be mixed in with a Relation to automatically derive * compare and equality functions. */ - trait AutomaticPartialOrdering[U, V] { + trait AutomaticPartialOrdering[U, V] extends PartiallyOrdered[Relation[U,V]] { original: Relation[U, V] => def tryCompareTo[B >: Relation[U, V]](that: B)(implicit arg0: (B) ⇒ PartiallyOrdered[B]): Option[Int] = { diff --git a/core/src/main/scala/it/unich/jandom/utils/numberext/DenseMatrix.scala b/core/src/main/scala/it/unich/jandom/utils/numberext/DenseMatrix.scala index 47688df4..0346ddc4 100644 --- a/core/src/main/scala/it/unich/jandom/utils/numberext/DenseMatrix.scala +++ b/core/src/main/scala/it/unich/jandom/utils/numberext/DenseMatrix.scala @@ -161,7 +161,7 @@ final class DenseMatrix(val data: Array[Rational], val rows: Int) { */ def *(that: DenseMatrix): DenseMatrix = { require(this.cols == that.rows) - var result = DenseMatrix.raw(this.rows, that.cols) + val result = DenseMatrix.raw(this.rows, that.cols) cfor(0)(_ < rows, _ + 1) { (i) => cfor(0)(_ < that.cols, _ + 1) { (j) => result(i, j) = Rational(0) diff --git a/core/src/test/ppl/it/unich/jandom/domains/numerical/ppl/PPLDomainSuite.scala b/core/src/test/ppl/it/unich/jandom/domains/numerical/ppl/PPLDomainSuite.scala index fe7672bb..e9d03294 100644 --- a/core/src/test/ppl/it/unich/jandom/domains/numerical/ppl/PPLDomainSuite.scala +++ b/core/src/test/ppl/it/unich/jandom/domains/numerical/ppl/PPLDomainSuite.scala @@ -85,8 +85,6 @@ class PPLDomainSuiteOctagon extends { val dom = PPLDomain[Octagonal_Shape_double } describe("Test for various operations") { - val obj = full.linearAssignment(0, 0) - val obj2 = full.linearAssignment(1, 0) val obj3 = full.linearAssignment(2, 0) val obj4 = full.linearAssignment(2, 1) val obj5 = obj4 union obj3 @@ -110,7 +108,7 @@ class PPLDomainSuiteOctagon extends { val dom = PPLDomain[Octagonal_Shape_double describe("Test that disequality do not crash") { val obj = full.linearAssignment(0, 0) - val dis = obj.linearDisequality(LinearForm(0, 1, 0, 0)) + obj.linearDisequality(LinearForm(0, 1, 0, 0)) } describe("Test string conversion") { diff --git a/core/src/test/ppl/it/unich/jandom/targets/JVMSootSuite.scala b/core/src/test/ppl/it/unich/jandom/targets/JVMSootSuite.scala index 88e8f14a..242dd555 100644 --- a/core/src/test/ppl/it/unich/jandom/targets/JVMSootSuite.scala +++ b/core/src/test/ppl/it/unich/jandom/targets/JVMSootSuite.scala @@ -18,6 +18,7 @@ package it.unich.jandom.targets +import scala.collection.JavaConverters._ import org.scalatest.FunSuite import it.unich.jandom.domains.numerical.ppl.PPLDomain import it.unich.jandom.domains.objects.PairSharingDomain @@ -25,7 +26,6 @@ import it.unich.jandom.domains.objects.UP import it.unich.jandom.parsers.NumericalPropertyParser import it.unich.jandom.targets.jvmsoot._ import parma_polyhedra_library.C_Polyhedron -import soot._ import it.unich.jandom.domains.objects.PairSharingDomain /** @@ -35,7 +35,6 @@ import it.unich.jandom.domains.objects.PairSharingDomain * */ class JVMSootSuite extends FunSuite with SootTests { - import scala.collection.JavaConversions._ val scene = initSoot() val c = scene.loadClassAndSupport("javatest.SimpleTest") @@ -95,7 +94,7 @@ class JVMSootSuite extends FunSuite with SootTests { val inte = new JimpleRecursiveInterpretation[params.type](scene, params) params.interpretation = Some(inte) test(s"Jimple inter-procedural sharing analysis: ${methodName}") { - val input = params.domain.top(c.getMethodByName(methodName).getParameterTypes().asInstanceOf[java.util.List[Type]]) + val input = params.domain.top(c.getMethodByName(methodName).getParameterTypes().asScala) try { inte.compute(method, input) assert(inte(method, input).prop === psdom(prop, jmethod.outputTypes)) @@ -116,7 +115,6 @@ class JVMSootSuite extends FunSuite with SootTests { for ((methodName, propString) <- jimpleNumericalTests) { val method = c.getMethodByName(methodName) - val jmethod = new JimpleMethod(method) val params = new Parameters[JimpleMethod] { val domain = new SootFrameNumericalDomain(JVMSootSuite.this.numdomain) io = true diff --git a/core/src/test/ppl/it/unich/jandom/targets/SootFrameNumericalDomainSuite.scala b/core/src/test/ppl/it/unich/jandom/targets/SootFrameNumericalDomainSuite.scala index a799096e..2595e9a9 100644 --- a/core/src/test/ppl/it/unich/jandom/targets/SootFrameNumericalDomainSuite.scala +++ b/core/src/test/ppl/it/unich/jandom/targets/SootFrameNumericalDomainSuite.scala @@ -46,11 +46,9 @@ class SootFrameNumericalDomainSuite extends FunSuite { val env = Environment() val parser = new NumericalPropertyParser(env) val prop = parser.parseProperty("v0 == v0 && v1 + v2 == 0 && v1 <= 4", dom.numdom).get - val absframe = dom(prop, types) intercept[AssertionError] { dom(prop, Seq(soot.IntType.v(), classAType, soot.DoubleType.v())) } intercept[AssertionError] { dom(prop, Seq(soot.IntType.v(), soot.DoubleType.v(), classAType)) } intercept[AssertionError] { dom(prop, Seq(classAType, soot.IntType.v())) } - val fullnumframe = dom(prop, soot.IntType.v()) intercept[AssertionError] { dom(prop, classAType) } } diff --git a/core/src/test/scala/it/unich/jandom/JandomParallelotopeBench.scala b/core/src/test/scala/it/unich/jandom/JandomParallelotopeBench.scala index 6642772e..e60c25d3 100644 --- a/core/src/test/scala/it/unich/jandom/JandomParallelotopeBench.scala +++ b/core/src/test/scala/it/unich/jandom/JandomParallelotopeBench.scala @@ -67,7 +67,7 @@ object JandomParallelotopeBench extends App with FASTLoader { val t1 = System.currentTimeMillis val productAnn = program.analyze(params1) - val tann1 = System.currentTimeMillis - t1 + val tann1 = System.currentTimeMillis - t1 val params2 = new targets.Parameters[LTS] { val domain = BoxRationalDomain() @@ -75,7 +75,7 @@ object JandomParallelotopeBench extends App with FASTLoader { params2.widening = DelayedWidening(DefaultWidening, 1) params2.narrowing = DelayedNarrowing(DefaultNarrowing, 1) // params2.debugWriter = new java.io.PrintWriter(System.out) - program.analyze(params2) // warmup JVM + program.analyze(params2) // warmup JVMunchecked //params2.debugWriter.flush() val t2 = System.currentTimeMillis @@ -108,6 +108,7 @@ object JandomParallelotopeBench extends App with FASTLoader { val comp = cprod map { case (loc, v) => loc -> v.tryCompareTo(cbox(loc) intersection cpar(loc)) } + println(s"TIME REQUIRED: product: $tann1 box: $tann2 ptope: $tann3") println("COUNT EQUALS: " + comp.count(_._2 contains 0)) println("COUNT BETTER REDUCED PRODUCT: " + comp.count(_._2 contains -1)) println("COUNT BETTER SEPARATE ANALYSIS: " + comp.count(_._2 contains 1)) diff --git a/core/src/test/scala/it/unich/jandom/JandomSumBench.scala b/core/src/test/scala/it/unich/jandom/JandomSumBench.scala index 31a85940..dbd7996f 100644 --- a/core/src/test/scala/it/unich/jandom/JandomSumBench.scala +++ b/core/src/test/scala/it/unich/jandom/JandomSumBench.scala @@ -81,7 +81,7 @@ object JandomSumBench extends App with FASTLoader { val domain = ParallelotopeRationalDomain() } params3.widening = DelayedWidening(DefaultWidening, 3) // needed for parallelotopes - //params3.debugWriter = new java.io.PrintWriter(System.out) + //params3.debugWriter = tann1new java.io.PrintWriter(System.out) program.analyze(params3) // warmup JVM //params3.debugWriter.flush() @@ -94,7 +94,7 @@ object JandomSumBench extends App with FASTLoader { val cann2 = ann2 mapValues { p => CStoPolyehdra(p.dimension, p.constraints) } val cann3 = ann3 mapValues { p => CStoPolyehdra(p.dimension, p.constraints) } - println(s"Times: $tann1 vs $tann2") + println(s"Times: box $tann1 sum: $tann2 ptope: $tann3") print("Box: ") println(mkString(program, cann1)) print("PTope: ") diff --git a/core/src/test/scala/it/unich/jandom/domains/DomainTransformationSuite.scala b/core/src/test/scala/it/unich/jandom/domains/DomainTransformationSuite.scala index 2fa68f0b..da2e1952 100644 --- a/core/src/test/scala/it/unich/jandom/domains/DomainTransformationSuite.scala +++ b/core/src/test/scala/it/unich/jandom/domains/DomainTransformationSuite.scala @@ -56,7 +56,6 @@ class DomainTransformationSuite extends FunSuite { test("General transformation to Box") { val transform = new DomainTransformation.TopTransformation[NumericalDomain, BoxDoubleDomain] val diamond = pardom(Bounds(-1, -1), DenseMatrix(DenseVector(1.0, 1.0), DenseVector(1.0, -1.0)), Bounds(1, 1)) - val box = boxdom(Array(-1, -1), Array(1, 1)) assertResult(boxdom.top(2)) { transform(pardom,boxdom)(diamond) } } } diff --git a/core/src/test/scala/it/unich/jandom/domains/numerical/LinearFormSuite.scala b/core/src/test/scala/it/unich/jandom/domains/numerical/LinearFormSuite.scala index 4b377f2e..c0c399ce 100644 --- a/core/src/test/scala/it/unich/jandom/domains/numerical/LinearFormSuite.scala +++ b/core/src/test/scala/it/unich/jandom/domains/numerical/LinearFormSuite.scala @@ -28,7 +28,7 @@ import org.scalatest.FunSuite class LinearFormSuite extends FunSuite { test("Variable constructor") { - var lf = LinearForm.v(1) + val lf = LinearForm.v(1) assertResult(LinearForm(0, 0, 1)) { lf } } @@ -50,7 +50,6 @@ class LinearFormSuite extends FunSuite { test("Arithmetic operations") { val lf1 = LinearForm(1, 2, -1) val lf2 = LinearForm(1, 0, 3) - val lf3 = LinearForm(2, 2, 2) assertResult(LinearForm(-1, -2, 1)) { -lf1 } assertResult(LinearForm(2, 2, 2)) { lf1 + lf2 } assertResult(LinearForm(0, 2, -4)) { lf1 - lf2 } diff --git a/core/src/test/scala/it/unich/jandom/domains/numerical/ParallelotopeRationalDomainFastSuite.scala b/core/src/test/scala/it/unich/jandom/domains/numerical/ParallelotopeRationalDomainFastSuite.scala index f24c554a..d1cd17bd 100644 --- a/core/src/test/scala/it/unich/jandom/domains/numerical/ParallelotopeRationalDomainFastSuite.scala +++ b/core/src/test/scala/it/unich/jandom/domains/numerical/ParallelotopeRationalDomainFastSuite.scala @@ -26,7 +26,6 @@ import it.unich.jandom.utils.numberext.RationalExt import it.unich.jandom.utils.numberext.Bounds import it.unich.jandom.utils.numberext.DenseMatrix import it.unich.jandom.utils.numberext.Bounds -import spire.math.Rational import spire.syntax.literals._ /** diff --git a/core/src/test/scala/it/unich/jandom/domains/objects/ObjectDomainSuite.scala b/core/src/test/scala/it/unich/jandom/domains/objects/ObjectDomainSuite.scala index 1c306a6b..a4ccff74 100644 --- a/core/src/test/scala/it/unich/jandom/domains/objects/ObjectDomainSuite.scala +++ b/core/src/test/scala/it/unich/jandom/domains/objects/ObjectDomainSuite.scala @@ -20,7 +20,6 @@ package it.unich.jandom.domains.objects import org.scalatest.FunSpec import org.scalatest.prop.TableDrivenPropertyChecks -import org.scalatest.prop.TableFor1 import it.unich.jandom.domains.CartesianFiberedDomainSuite import it.unich.jandom.objectmodels.ObjectModel diff --git a/core/src/test/scala/it/unich/jandom/domains/objects/PairSharingSuite.scala b/core/src/test/scala/it/unich/jandom/domains/objects/PairSharingSuite.scala index bf084240..5c7ff34d 100644 --- a/core/src/test/scala/it/unich/jandom/domains/objects/PairSharingSuite.scala +++ b/core/src/test/scala/it/unich/jandom/domains/objects/PairSharingSuite.scala @@ -95,7 +95,6 @@ class PairSharingSuite extends FunSuite { test("Delete variables in the middle") { val ps1 = dom(Set((0, 0), (0, 1), (1, 1), (3, 1), (3, 3)), 4) assertResult(dom(Set((0, 0), (1, 1)), 2))(ps1.delVariables(1 to 2)) - val ps2 = dom(Set((0, 0), (0, 1), (1, 1), (3, 1), (3, 3)), 4) assertResult(dom(Set((0, 0), (2, 2)), 3))(ps1.delVariable(1)) } diff --git a/core/src/test/scala/it/unich/jandom/domains/objects/PreciseDefiniteNullness.scala b/core/src/test/scala/it/unich/jandom/domains/objects/PreciseDefiniteNullness.scala index 93ea2472..20b79773 100644 --- a/core/src/test/scala/it/unich/jandom/domains/objects/PreciseDefiniteNullness.scala +++ b/core/src/test/scala/it/unich/jandom/domains/objects/PreciseDefiniteNullness.scala @@ -1,9 +1,6 @@ package it.unich.jandom.domains.objects -import org.scalatest.FunSpec -import org.scalatest.prop.TableFor1 - /** * This suite implements tests for those object domain which precisely track * definite nullness. diff --git a/core/src/test/scala/it/unich/jandom/domains/objects/PreciseObjectDomain.scala b/core/src/test/scala/it/unich/jandom/domains/objects/PreciseObjectDomain.scala index 0c1340d4..c9aa5dd5 100644 --- a/core/src/test/scala/it/unich/jandom/domains/objects/PreciseObjectDomain.scala +++ b/core/src/test/scala/it/unich/jandom/domains/objects/PreciseObjectDomain.scala @@ -18,10 +18,6 @@ package it.unich.jandom.domains.objects -import org.scalatest.FunSpec -import org.scalatest.prop.TableDrivenPropertyChecks -import org.scalatest.prop.TableFor1 - /** * A test trait for object domains with precise operators. * @author Gianluca Amato diff --git a/core/src/test/scala/it/unich/jandom/objectmodels/ObjectModelSuite.scala b/core/src/test/scala/it/unich/jandom/objectmodels/ObjectModelSuite.scala index e5f99f7f..c8a72155 100644 --- a/core/src/test/scala/it/unich/jandom/objectmodels/ObjectModelSuite.scala +++ b/core/src/test/scala/it/unich/jandom/objectmodels/ObjectModelSuite.scala @@ -53,7 +53,7 @@ trait ObjectModelSuite extends FunSpec with TableDrivenPropertyChecks { for (t <- someTypes) { val fields = declaredFields(t) // I want to check absence of exception, I do not know if there is a standard method - val types = fields map { typeOf(_) } + fields map { typeOf(_) } } } } diff --git a/core/src/test/scala/it/unich/jandom/objectmodels/TestObjectModelSuite.scala b/core/src/test/scala/it/unich/jandom/objectmodels/TestObjectModelSuite.scala index 1d05d11d..8888b415 100644 --- a/core/src/test/scala/it/unich/jandom/objectmodels/TestObjectModelSuite.scala +++ b/core/src/test/scala/it/unich/jandom/objectmodels/TestObjectModelSuite.scala @@ -19,7 +19,6 @@ package it.unich.jandom.objectmodels import org.scalatest.FunSpec -import org.scalatest.prop.TableFor1 /** * A test for the TestObjectModel. diff --git a/core/src/test/scala/it/unich/jandom/objectmodels/TrivialObjectModelSuite.scala b/core/src/test/scala/it/unich/jandom/objectmodels/TrivialObjectModelSuite.scala index 9f1caca5..21250e0a 100644 --- a/core/src/test/scala/it/unich/jandom/objectmodels/TrivialObjectModelSuite.scala +++ b/core/src/test/scala/it/unich/jandom/objectmodels/TrivialObjectModelSuite.scala @@ -19,7 +19,6 @@ package it.unich.jandom.objectmodels import org.scalatest.FunSpec -import org.scalacheck.Gen /** * A test for the TrivialObjectModel. diff --git a/core/src/test/scala/it/unich/jandom/targets/JVMASMSuite.scala b/core/src/test/scala/it/unich/jandom/targets/JVMASMSuite.scala index 2c5a9e50..4ac145ba 100644 --- a/core/src/test/scala/it/unich/jandom/targets/JVMASMSuite.scala +++ b/core/src/test/scala/it/unich/jandom/targets/JVMASMSuite.scala @@ -18,16 +18,14 @@ package it.unich.jandom.targets -import scala.collection.JavaConversions.asScalaBuffer +import scala.collection.JavaConverters._ import org.objectweb.asm.ClassReader -import org.objectweb.asm.tree.{ClassNode, MethodNode} +import org.objectweb.asm.tree.ClassNode import org.scalatest.FunSuite import it.unich.jandom.domains.numerical.BoxDoubleDomain import it.unich.jandom.targets.jvmasm.{AsmMethod, JVMEnvFixedFrame, JVMEnvFixedFrameDomain, UnsupportedASMInsnException} -import polyglot.util.Base64.InputStream class JVMASMSuite extends FunSuite { - import scala.collection.JavaConversions.asScalaBuffer val BoxDouble = BoxDoubleDomain() test("simple method analysis") { @@ -35,7 +33,7 @@ class JVMASMSuite extends FunSuite { val cr = new ClassReader(is) val node = new ClassNode() cr.accept(node, ClassReader.SKIP_DEBUG) - val methodList = node.methods.asInstanceOf[java.util.List[MethodNode]] + val methodList = node.methods.asScala val method = new AsmMethod(methodList.find(_.name == "conditional").get) val params = new Parameters[AsmMethod] { val domain = new JVMEnvFixedFrameDomain(BoxDouble) diff --git a/core/src/test/scala/it/unich/jandom/targets/JimpleParametersSuite.scala b/core/src/test/scala/it/unich/jandom/targets/JimpleParametersSuite.scala index f5acfe86..c9be53c6 100644 --- a/core/src/test/scala/it/unich/jandom/targets/JimpleParametersSuite.scala +++ b/core/src/test/scala/it/unich/jandom/targets/JimpleParametersSuite.scala @@ -21,7 +21,6 @@ package it.unich.jandom.targets import org.scalatest.FunSuite import it.unich.jandom.domains.numerical.BoxDoubleDomain import it.unich.jandom.domains.objects.PairSharingDomain -import it.unich.jandom.parsers.NumericalPropertyParser import it.unich.jandom.targets.jvmsoot._ import soot._ import it.unich.jandom.parsers.PairSharingParser diff --git a/core/src/test/scala/it/unich/jandom/targets/SootObjectModelSuite.scala b/core/src/test/scala/it/unich/jandom/targets/SootObjectModelSuite.scala index 6d8a5cc2..2cdb427b 100644 --- a/core/src/test/scala/it/unich/jandom/targets/SootObjectModelSuite.scala +++ b/core/src/test/scala/it/unich/jandom/targets/SootObjectModelSuite.scala @@ -19,7 +19,6 @@ package it.unich.jandom.targets import org.scalatest._ -import org.scalacheck._ import it.unich.jandom.targets.jvmsoot.SootObjectModel import it.unich.jandom.objectmodels.ObjectModelSuite diff --git a/core/src/test/scala/soot/jandom/BriefBigBlockGraphSuite.scala b/core/src/test/scala/soot/jandom/BriefBigBlockGraphSuite.scala index f1b17110..a7324476 100644 --- a/core/src/test/scala/soot/jandom/BriefBigBlockGraphSuite.scala +++ b/core/src/test/scala/soot/jandom/BriefBigBlockGraphSuite.scala @@ -18,8 +18,9 @@ package soot.jandom +import scala.collection.JavaConverters._ + import org.scalatest.FunSpec -import soot._ import it.unich.jandom.targets.SootTests /** @@ -32,10 +33,8 @@ class BriefBigBlockGraphSuite extends FunSpec with SootTests { val c = scene.loadClassAndSupport("javatest.SimpleTest") describe("The BriefBigBlockGraph for the nested method") { - import scala.collection.JavaConversions._ - val body = c.getMethodByName("nested").retrieveActiveBody() - val graph = new BriefBigBlockGraph(body) + val graph = new BriefBigBlockGraph(body).asScala val expectedGraph = Seq( (Seq(), Seq(1)), (Seq(0,3), Seq(2,4)), @@ -43,11 +42,11 @@ class BriefBigBlockGraphSuite extends FunSpec with SootTests { (Seq(2), Seq(1)), (Seq(1), Seq())) - it("should have five nodes") { assert(graph.size() === expectedGraph.length ) } + it("should have five nodes") { assert(graph.size === expectedGraph.length ) } it("should be isomorphic to the expected graph") { for ( (block, (preds, succs)) <- graph zip expectedGraph) { - assert ( (block.getPreds() map { _.getIndexInMethod() }) === preds) - assert ( ( block.getSuccs() map { _.getIndexInMethod() }) === succs) + assert ( (block.getPreds().asScala map { _.getIndexInMethod() }) === preds) + assert ( ( block.getSuccs().asScala map { _.getIndexInMethod() }) === succs) } } } diff --git a/core/src/test/scala/soot/jandom/UnitBlockGraphSuite.scala b/core/src/test/scala/soot/jandom/UnitBlockGraphSuite.scala index f8df0009..9fa63428 100644 --- a/core/src/test/scala/soot/jandom/UnitBlockGraphSuite.scala +++ b/core/src/test/scala/soot/jandom/UnitBlockGraphSuite.scala @@ -18,12 +18,10 @@ package soot.jandom +import scala.collection.JavaConverters._ + import org.scalatest.FunSpec -import soot.Scene -import soot.Unit import soot.toolkits.graph.BriefUnitGraph -import soot.toolkits.graph.Block -import soot.options.Options import it.unich.jandom.targets.SootTests /** @@ -33,26 +31,24 @@ import it.unich.jandom.targets.SootTests */ class UnitBlockGraphSuite extends FunSpec with SootTests { - import scala.collection.JavaConversions._ - val scene = initSoot() val c = scene.loadClassAndSupport("javatest.SimpleTest") - for (m <- c.getMethods(); body = m.retrieveActiveBody()) { + for (m <- c.getMethods().asScala; body = m.retrieveActiveBody()) { describe("The UnitBlockGraph for the "+m.getName()+" method") { val graph = new UnitBlockGraph(body) val unitGraph = new BriefUnitGraph(body) it("should only have blocks with head equal to tail") { - for (b <- graph) assert(b.getHead() === b.getTail()) + for (b <- graph.asScala) assert(b.getHead() === b.getTail()) } it("should be isomorphic to the unit graph") { assert(graph.size() === unitGraph.size()) - for (b <- graph; u = b.getHead()) { - assert((graph.getPredsOf(b) map { _.getHead() }) === asScalaBuffer(unitGraph.getPredsOf(u))) - assert((graph.getSuccsOf(b) map { _.getHead() }) === asScalaBuffer(unitGraph.getSuccsOf(u))) + for (b <- graph.asScala; u = b.getHead()) { + assert((graph.getPredsOf(b).asScala map { _.getHead() }) === unitGraph.getPredsOf(u).asScala) + assert((graph.getSuccsOf(b).asScala map { _.getHead() }) === unitGraph.getSuccsOf(u).asScala) } } } diff --git a/extended/src/jmh/scala/it/unich/jandom/benchmarks/BoxDoubleBenchmark.scala b/extended/src/jmh/scala/it/unich/jandom/benchmarks/BoxDoubleBenchmark.scala index 088ec7c5..0fcda4dd 100644 --- a/extended/src/jmh/scala/it/unich/jandom/benchmarks/BoxDoubleBenchmark.scala +++ b/extended/src/jmh/scala/it/unich/jandom/benchmarks/BoxDoubleBenchmark.scala @@ -90,7 +90,6 @@ class BoxDoubleBenchmark { @Benchmark def timeJandomNoPPL() { var db = BoxDouble.bottom(numvars) - val zero = Array.fill(numvars)(0.0) val full = BoxDouble.top(numvars) for (i <- 1 to numpoints) { val point = (0 until numvars).foldLeft(full) { (box, v) => box.linearAssignment(v, i.toDouble) } @@ -125,7 +124,6 @@ class BoxDoubleBenchmark { // we explicitly type domain in order to avoid generation of existential types. val domain: NumericalDomain = PPLDomainMacro[Double_Box] var db = domain.bottom(numvars) - val zero = Array.fill(numvars)(0.0) val full = domain.top(numvars) for (i <- 1 to numpoints) { val point = (0 until numvars).foldLeft(full) { (box, v) => box.linearAssignment(v, i.toDouble) } diff --git a/extended/src/test/ppl/it/unich/jandom/domains/numerical/ppl/PPLMacroPropertySuite.scala b/extended/src/test/ppl/it/unich/jandom/domains/numerical/ppl/PPLMacroPropertySuite.scala index 948f574c..cafc9269 100644 --- a/extended/src/test/ppl/it/unich/jandom/domains/numerical/ppl/PPLMacroPropertySuite.scala +++ b/extended/src/test/ppl/it/unich/jandom/domains/numerical/ppl/PPLMacroPropertySuite.scala @@ -69,8 +69,6 @@ class PPLMacroPropertySuite extends FunSuite { } test("various operations") { - val obj = full.linearAssignment(0, 0.0) - val obj2 = full.linearAssignment(1, 0.0) val obj3 = full.linearAssignment(2, 0.0) val obj4 = full.linearAssignment(2, 1.0) val obj5 = obj4 union obj3 @@ -83,8 +81,7 @@ class PPLMacroPropertySuite extends FunSuite { test("disequality do not crash") { val obj = full.linearAssignment(0, 0.0) - val dis = obj.linearDisequality(LinearForm(0, 1, 0, 0)) - assert(true) + obj.linearDisequality(LinearForm(0, 1, 0, 0)) } test("disequality is precise on boxes") { From ec16280af2b723b0d311778677de9179e3a81585 Mon Sep 17 00:00:00 2001 From: herrBez Date: Sun, 12 Nov 2017 17:49:45 +0100 Subject: [PATCH 38/99] Add missing dependencies in DomainTransformation --- .../it/unich/jandom/domains/DomainTransformation.scala | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/core/src/main/scala/it/unich/jandom/domains/DomainTransformation.scala b/core/src/main/scala/it/unich/jandom/domains/DomainTransformation.scala index 5d044521..a36b6d7b 100644 --- a/core/src/main/scala/it/unich/jandom/domains/DomainTransformation.scala +++ b/core/src/main/scala/it/unich/jandom/domains/DomainTransformation.scala @@ -19,6 +19,14 @@ package it.unich.jandom.domains import it.unich.jandom.domains.numerical._ +import it.unipd.jandom.domains.numerical.congruence._ +import it.unipd.jandom.domains.numerical.congruence.Congruence._ +import it.unipd.jandom.domains.numerical.sign._ +import it.unipd.jandom.domains.numerical.sign.Sign.Zero +import it.unipd.jandom.domains.numerical.mod._ + +import it.unipd.jandom.domains.numerical.constant._ +import it.unipd.jandom.domains.numerical.parity._ import it.unich.jandom.utils.numberext.{DenseMatrix, Bounds, RationalExt} From f65cffde79d317fcd0720bf91c4f3a811d8d93da Mon Sep 17 00:00:00 2001 From: herrBez Date: Sun, 12 Nov 2017 17:54:50 +0100 Subject: [PATCH 39/99] Fixed warnings by removing unused imports and changing variables into "val" --- .../FullyReducedProductCongruenceBoxDoubleDomain.scala | 7 +++---- .../unipd/jandom/domains/numerical/SumSignModKDomain.scala | 1 - 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/FullyReducedProductCongruenceBoxDoubleDomain.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/FullyReducedProductCongruenceBoxDoubleDomain.scala index eacf330c..c0118f25 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/FullyReducedProductCongruenceBoxDoubleDomain.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/FullyReducedProductCongruenceBoxDoubleDomain.scala @@ -4,7 +4,7 @@ import it.unich.jandom.domains.DomainTransformation import it.unich.jandom.domains.numerical.ProductDomain import it.unich.jandom.domains.numerical.BoxDoubleDomain import it.unipd.jandom.domains.numerical.congruence.Congruence.{Congruence, CongruenceBottom} -import it.unipd.jandom.domains.numerical.congruence.{Congruence, CongruenceDomain, CongruenceDomainCore} +import it.unipd.jandom.domains.numerical.congruence.{Congruence, CongruenceDomain} import it.unipd.jandom.domains.numerical.utils.MathLibrary /** @@ -43,9 +43,8 @@ class FullyReducedProductCongruenceBoxDoubleDomain(override val dom1 : Congruenc /* Calculate the point-wise fully-reduct product of an array of cogruence and low- and upperbound of box double */ val res : Array[(Congruence, Double, Double)] = (x1.elements, x2.low, x2.high).zipped.map( (congruence,_low, _high) => { - var low: Int = _low.toInt - - var high: Int = _high.toInt + val low: Int = _low.toInt + val high: Int = _high.toInt congruence match { case Congruence.Mod(a, b) => val (a1, b1) = transform(low, high, a, b) diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/SumSignModKDomain.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/SumSignModKDomain.scala index 7573dde7..9ec4946a 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/SumSignModKDomain.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/SumSignModKDomain.scala @@ -2,7 +2,6 @@ package it.unipd.jandom.domains.numerical import it.unich.jandom.domains.numerical.SumDomain import it.unipd.jandom.domains.numerical.mod.ModKDomain -import it.unipd.jandom.domains.numerical.parity.ParityDomain import it.unipd.jandom.domains.numerical.sign.SignDomain /** From b6eb8280dfd67572dec0e0e002094e7f9e27f08e Mon Sep 17 00:00:00 2001 From: herrBez Date: Mon, 13 Nov 2017 12:03:56 +0100 Subject: [PATCH 40/99] Add .travis.yml to allow continuous integration --- .travis.yml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..f4f9bf72 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,6 @@ +language: scala +scala: + - 2.12.4 + +script: + - sbt compile From ab5afb5b3d3e8a6bd4be79496dc2c1f5c4c4d3af Mon Sep 17 00:00:00 2001 From: herrBez Date: Sat, 18 Nov 2017 15:22:30 +0100 Subject: [PATCH 41/99] Fix warnings due to the updated scala version Fix some warnings due to "non-exhaustive" pattern matching. Indeed Congruence/Modk/Constant and Parity traits were not marked as sealed. Add redundant pattern matching case in CongruenceToBoxDouble function to suppress non-exhaustive pattern-matching --- .../jandom/domains/DomainTransformation.scala | 21 +++++++++---------- .../numerical/congruence/Congruence.scala | 4 ++-- .../domains/numerical/constant/Constant.scala | 2 +- .../jandom/domains/numerical/mod/ModK.scala | 2 +- .../domains/numerical/parity/Parity.scala | 2 +- 5 files changed, 15 insertions(+), 16 deletions(-) diff --git a/core/src/main/scala/it/unich/jandom/domains/DomainTransformation.scala b/core/src/main/scala/it/unich/jandom/domains/DomainTransformation.scala index a36b6d7b..985ca294 100644 --- a/core/src/main/scala/it/unich/jandom/domains/DomainTransformation.scala +++ b/core/src/main/scala/it/unich/jandom/domains/DomainTransformation.scala @@ -25,7 +25,6 @@ import it.unipd.jandom.domains.numerical.sign._ import it.unipd.jandom.domains.numerical.sign.Sign.Zero import it.unipd.jandom.domains.numerical.mod._ -import it.unipd.jandom.domains.numerical.constant._ import it.unipd.jandom.domains.numerical.parity._ import it.unich.jandom.utils.numberext.{DenseMatrix, Bounds, RationalExt} @@ -138,16 +137,16 @@ object DomainTransformation { p => if (p.isEmpty || p.elements.contains(CongruenceBottom)) //If the property is unreachable return bottom dst.bottom(p.dimension) - else - dst( - p.elements.map { - case Mod(None, constant) => constant.toDouble - case Mod(a, b) => Double.NegativeInfinity - }, - p.elements.map { - case Mod(None, constant) => constant.toDouble - case Mod(a, b) => Double.PositiveInfinity - }) + else { + val (low, high) = (p.elements.map { + case Mod(None, constant) => (constant.toDouble, constant.toDouble) + case Mod(a, b) => (Double.NegativeInfinity, Double.PositiveInfinity) + case CongruenceBottom => (Double.PositiveInfinity, Double.NegativeInfinity) + //This case is already covered in the previous if, but otherwise sbt gave a warning + //due to non exhaustive pattern matching + }).unzip + dst(low, high) + } } implicit object BoxDoubleToCongruence extends DomainTransformation[BoxDoubleDomain, CongruenceDomain] { diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/congruence/Congruence.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/congruence/Congruence.scala index ef46e785..82ce62e4 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/congruence/Congruence.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/congruence/Congruence.scala @@ -9,7 +9,7 @@ package it.unipd.jandom.domains.numerical.congruence * @author Sebastiano Valle */ object Congruence { - trait Congruence + sealed trait Congruence /** * Represents the elements of the domain of the form aZ + b. @@ -30,7 +30,7 @@ object Congruence { * @inheritdoc */ override def toString: String = { - var s : String = "\u2208 " + val s : String = "\u2208 " (a, b) match { case (None, 0) => s + "{0}" case (None, _) => s + "{" + b + "}" diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/constant/Constant.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/constant/Constant.scala index 6f52ae73..564819aa 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/constant/Constant.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/constant/Constant.scala @@ -10,7 +10,7 @@ package it.unipd.jandom.domains.numerical.constant * @author Sebastiano Valle */ object Constant { - trait Constant + sealed trait Constant // constant value case class Const (num : Int) extends Constant { diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/mod/ModK.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/mod/ModK.scala index d4c54554..2026b463 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/mod/ModK.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/mod/ModK.scala @@ -10,7 +10,7 @@ package it.unipd.jandom.domains.numerical.mod object ModK { private var k = 1 - trait ModK + sealed trait ModK /** Represents the elements in the equivalence class num modulo k */ case class RestClass(num : Int) extends ModK { override def toString: String = k match { diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/parity/Parity.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/parity/Parity.scala index f7555104..b114e9ca 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/parity/Parity.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/parity/Parity.scala @@ -1,7 +1,7 @@ package it.unipd.jandom.domains.numerical.parity object Parity { - trait Parity + sealed trait Parity // multiples of 2 case object Even extends Parity // multiples of 2 plus 1 From 95db44b398d0cdb678b74b8e421d7f7dd1206a4e Mon Sep 17 00:00:00 2001 From: herrBez Date: Sat, 30 Dec 2017 18:41:21 +0100 Subject: [PATCH 42/99] Add license notice to each scala file in unipd subfolder --- .../it/unipd/jandom/domains/Abstraction.scala | 17 +++++++++++++++++ .../domains/CompleteLatticeOperator.scala | 17 +++++++++++++++++ .../it/unipd/jandom/domains/IntOperator.scala | 17 +++++++++++++++++ .../it/unipd/jandom/domains/NumOperator.scala | 17 +++++++++++++++++ .../domains/numerical/BaseNumericalDomain.scala | 17 +++++++++++++++++ ...educedProductCongruenceBoxDoubleDomain.scala | 17 +++++++++++++++++ .../ProductCongruenceBoxDoubleDomain.scala | 17 +++++++++++++++++ .../numerical/ProductESeqParityDomain.scala | 17 +++++++++++++++++ .../numerical/ProductSignModKDomain.scala | 17 +++++++++++++++++ .../domains/numerical/SumSignModKDomain.scala | 17 +++++++++++++++++ .../numerical/congruence/Congruence.scala | 17 +++++++++++++++++ .../numerical/congruence/CongruenceDomain.scala | 17 +++++++++++++++++ .../congruence/CongruenceDomainCore.scala | 17 +++++++++++++++++ .../domains/numerical/constant/Constant.scala | 17 +++++++++++++++++ .../numerical/constant/ConstantDomain.scala | 17 +++++++++++++++++ .../numerical/constant/ConstantDomainCore.scala | 17 +++++++++++++++++ .../jandom/domains/numerical/mod/ModK.scala | 17 +++++++++++++++++ .../domains/numerical/mod/ModKDomain.scala | 17 +++++++++++++++++ .../domains/numerical/mod/ModKDomainCore.scala | 17 +++++++++++++++++ .../domains/numerical/parity/Parity.scala | 17 +++++++++++++++++ .../domains/numerical/parity/ParityDomain.scala | 17 +++++++++++++++++ .../numerical/parity/ParityDomainCore.scala | 17 +++++++++++++++++ .../jandom/domains/numerical/sign/ES01.scala | 17 +++++++++++++++++ .../jandom/domains/numerical/sign/ESeq.scala | 17 +++++++++++++++++ .../domains/numerical/sign/ESeqDomain.scala | 17 +++++++++++++++++ .../domains/numerical/sign/ESeqDomainCore.scala | 17 +++++++++++++++++ .../numerical/sign/ExtendedSigns01Domain.scala | 17 +++++++++++++++++ .../sign/ExtendedSigns01DomainCore.scala | 17 +++++++++++++++++ .../jandom/domains/numerical/sign/Sign.scala | 17 +++++++++++++++++ .../domains/numerical/sign/SignDomain.scala | 17 +++++++++++++++++ .../domains/numerical/sign/SignDomainCore.scala | 17 +++++++++++++++++ .../domains/numerical/utils/MathLibrary.scala | 17 +++++++++++++++++ 32 files changed, 544 insertions(+) diff --git a/core/src/main/scala/it/unipd/jandom/domains/Abstraction.scala b/core/src/main/scala/it/unipd/jandom/domains/Abstraction.scala index b871edbd..c05e3d54 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/Abstraction.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/Abstraction.scala @@ -1,3 +1,20 @@ +/** + * Copyright 2017 Mirko Bez, Stefano Munari, Sebastiano Valle + * + * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains + * JANDOM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * JANDOM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of a + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You shosuld have received a copy of the GNU General Public License + * along with JANDOM. If not, see . + */ package it.unipd.jandom.domains /** diff --git a/core/src/main/scala/it/unipd/jandom/domains/CompleteLatticeOperator.scala b/core/src/main/scala/it/unipd/jandom/domains/CompleteLatticeOperator.scala index 9acd9fb8..f73610c2 100755 --- a/core/src/main/scala/it/unipd/jandom/domains/CompleteLatticeOperator.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/CompleteLatticeOperator.scala @@ -1,3 +1,20 @@ +/** + * Copyright 2017 Mirko Bez, Stefano Munari, Sebastiano Valle + * + * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains + * JANDOM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * JANDOM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of a + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You shosuld have received a copy of the GNU General Public License + * along with JANDOM. If not, see . + */ package it.unipd.jandom.domains /** diff --git a/core/src/main/scala/it/unipd/jandom/domains/IntOperator.scala b/core/src/main/scala/it/unipd/jandom/domains/IntOperator.scala index 3b762fa3..0dcbadbc 100755 --- a/core/src/main/scala/it/unipd/jandom/domains/IntOperator.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/IntOperator.scala @@ -1,3 +1,20 @@ +/** + * Copyright 2017 Mirko Bez, Stefano Munari, Sebastiano Valle + * + * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains + * JANDOM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * JANDOM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of a + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You shosuld have received a copy of the GNU General Public License + * along with JANDOM. If not, see . + */ package it.unipd.jandom.domains /** diff --git a/core/src/main/scala/it/unipd/jandom/domains/NumOperator.scala b/core/src/main/scala/it/unipd/jandom/domains/NumOperator.scala index 5fb3d93f..64473079 100755 --- a/core/src/main/scala/it/unipd/jandom/domains/NumOperator.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/NumOperator.scala @@ -1,3 +1,20 @@ +/** + * Copyright 2017 Mirko Bez, Stefano Munari, Sebastiano Valle + * + * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains + * JANDOM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * JANDOM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of a + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You shosuld have received a copy of the GNU General Public License + * along with JANDOM. If not, see . + */ package it.unipd.jandom.domains /** diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/BaseNumericalDomain.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/BaseNumericalDomain.scala index 64e27fe7..3c44e86a 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/BaseNumericalDomain.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/BaseNumericalDomain.scala @@ -1,3 +1,20 @@ +/** + * Copyright 2017 Mirko Bez, Stefano Munari, Sebastiano Valle + * + * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains + * JANDOM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * JANDOM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of a + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You shosuld have received a copy of the GNU General Public License + * along with JANDOM. If not, see . + */ package it.unipd.jandom.domains.numerical import it.unich.jandom.domains.WideningDescription diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/FullyReducedProductCongruenceBoxDoubleDomain.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/FullyReducedProductCongruenceBoxDoubleDomain.scala index c0118f25..c2e6271c 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/FullyReducedProductCongruenceBoxDoubleDomain.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/FullyReducedProductCongruenceBoxDoubleDomain.scala @@ -1,3 +1,20 @@ +/** + * Copyright 2017 Mirko Bez, Stefano Munari, Sebastiano Valle + * + * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains + * JANDOM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * JANDOM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of a + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You shosuld have received a copy of the GNU General Public License + * along with JANDOM. If not, see . + */ package it.unipd.jandom.domains.numerical import it.unich.jandom.domains.DomainTransformation diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/ProductCongruenceBoxDoubleDomain.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/ProductCongruenceBoxDoubleDomain.scala index 4865012c..10491c40 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/ProductCongruenceBoxDoubleDomain.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/ProductCongruenceBoxDoubleDomain.scala @@ -1,3 +1,20 @@ +/** + * Copyright 2017 Mirko Bez, Stefano Munari, Sebastiano Valle + * + * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains + * JANDOM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * JANDOM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of a + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You shosuld have received a copy of the GNU General Public License + * along with JANDOM. If not, see . + */ package it.unipd.jandom.domains.numerical import it.unich.jandom.domains.DomainTransformation diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/ProductESeqParityDomain.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/ProductESeqParityDomain.scala index 50932bde..681550e1 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/ProductESeqParityDomain.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/ProductESeqParityDomain.scala @@ -1,3 +1,20 @@ +/** + * Copyright 2017 Mirko Bez, Stefano Munari, Sebastiano Valle + * + * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains + * JANDOM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * JANDOM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of a + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You shosuld have received a copy of the GNU General Public License + * along with JANDOM. If not, see . + */ package it.unipd.jandom.domains.numerical import it.unich.jandom.domains.DomainTransformation diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/ProductSignModKDomain.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/ProductSignModKDomain.scala index 09b4df72..fbbbcb4d 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/ProductSignModKDomain.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/ProductSignModKDomain.scala @@ -1,3 +1,20 @@ +/** + * Copyright 2017 Mirko Bez, Stefano Munari, Sebastiano Valle + * + * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains + * JANDOM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * JANDOM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of a + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You shosuld have received a copy of the GNU General Public License + * along with JANDOM. If not, see . + */ package it.unipd.jandom.domains.numerical import it.unich.jandom.domains.DomainTransformation diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/SumSignModKDomain.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/SumSignModKDomain.scala index 9ec4946a..61510c04 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/SumSignModKDomain.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/SumSignModKDomain.scala @@ -1,3 +1,20 @@ +/** + * Copyright 2017 Mirko Bez, Stefano Munari, Sebastiano Valle + * + * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains + * JANDOM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * JANDOM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of a + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You shosuld have received a copy of the GNU General Public License + * along with JANDOM. If not, see . + */ package it.unipd.jandom.domains.numerical import it.unich.jandom.domains.numerical.SumDomain diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/congruence/Congruence.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/congruence/Congruence.scala index 82ce62e4..19621fac 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/congruence/Congruence.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/congruence/Congruence.scala @@ -1,3 +1,20 @@ +/** + * Copyright 2017 Mirko Bez, Stefano Munari, Sebastiano Valle + * + * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains + * JANDOM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * JANDOM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of a + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You shosuld have received a copy of the GNU General Public License + * along with JANDOM. If not, see . + */ package it.unipd.jandom.domains.numerical.congruence /** diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/congruence/CongruenceDomain.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/congruence/CongruenceDomain.scala index 6bda40fa..09979cef 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/congruence/CongruenceDomain.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/congruence/CongruenceDomain.scala @@ -1,3 +1,20 @@ +/** + * Copyright 2017 Mirko Bez, Stefano Munari, Sebastiano Valle + * + * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains + * JANDOM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * JANDOM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of a + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You shosuld have received a copy of the GNU General Public License + * along with JANDOM. If not, see . + */ package it.unipd.jandom.domains.numerical.congruence import it.unich.jandom.domains.numerical.LinearForm diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/congruence/CongruenceDomainCore.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/congruence/CongruenceDomainCore.scala index 84d5e6e8..4271a7a9 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/congruence/CongruenceDomainCore.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/congruence/CongruenceDomainCore.scala @@ -1,3 +1,20 @@ +/** + * Copyright 2017 Mirko Bez, Stefano Munari, Sebastiano Valle + * + * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains + * JANDOM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * JANDOM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of a + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You shosuld have received a copy of the GNU General Public License + * along with JANDOM. If not, see . + */ package it.unipd.jandom.domains.numerical.congruence import it.unipd.jandom.domains.numerical.utils.{MathLibrary => M} diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/constant/Constant.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/constant/Constant.scala index 564819aa..b040021c 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/constant/Constant.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/constant/Constant.scala @@ -1,3 +1,20 @@ +/** + * Copyright 2017 Mirko Bez, Stefano Munari, Sebastiano Valle + * + * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains + * JANDOM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * JANDOM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of a + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You shosuld have received a copy of the GNU General Public License + * along with JANDOM. If not, see . + */ package it.unipd.jandom.domains.numerical.constant /** diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/constant/ConstantDomain.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/constant/ConstantDomain.scala index ac1395bb..282cb20c 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/constant/ConstantDomain.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/constant/ConstantDomain.scala @@ -1,3 +1,20 @@ +/** + * Copyright 2017 Mirko Bez, Stefano Munari, Sebastiano Valle + * + * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains + * JANDOM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * JANDOM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of a + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You shosuld have received a copy of the GNU General Public License + * along with JANDOM. If not, see . + */ package it.unipd.jandom.domains.numerical.constant import it.unich.jandom.domains.numerical.LinearForm diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/constant/ConstantDomainCore.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/constant/ConstantDomainCore.scala index ac5b8fd8..091bd96d 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/constant/ConstantDomainCore.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/constant/ConstantDomainCore.scala @@ -1,3 +1,20 @@ +/** + * Copyright 2017 Mirko Bez, Stefano Munari, Sebastiano Valle + * + * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains + * JANDOM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * JANDOM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of a + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You shosuld have received a copy of the GNU General Public License + * along with JANDOM. If not, see . + */ package it.unipd.jandom.domains.numerical.constant import it.unipd.jandom.domains.{Abstraction, CompleteLatticeOperator, IntOperator} diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/mod/ModK.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/mod/ModK.scala index 2026b463..df24eef5 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/mod/ModK.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/mod/ModK.scala @@ -1,3 +1,20 @@ +/** + * Copyright 2017 Mirko Bez, Stefano Munari, Sebastiano Valle + * + * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains + * JANDOM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * JANDOM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of a + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You shosuld have received a copy of the GNU General Public License + * along with JANDOM. If not, see . + */ package it.unipd.jandom.domains.numerical.mod /** diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/mod/ModKDomain.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/mod/ModKDomain.scala index 14057695..f232ec48 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/mod/ModKDomain.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/mod/ModKDomain.scala @@ -1,3 +1,20 @@ +/** + * Copyright 2017 Mirko Bez, Stefano Munari, Sebastiano Valle + * + * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains + * JANDOM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * JANDOM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of a + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You shosuld have received a copy of the GNU General Public License + * along with JANDOM. If not, see . + */ /** * Copyright 201K, 2016 Gianluca Amato * diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/mod/ModKDomainCore.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/mod/ModKDomainCore.scala index 4309cec8..f96e82ee 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/mod/ModKDomainCore.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/mod/ModKDomainCore.scala @@ -1,3 +1,20 @@ +/** + * Copyright 2017 Mirko Bez, Stefano Munari, Sebastiano Valle + * + * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains + * JANDOM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * JANDOM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of a + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You shosuld have received a copy of the GNU General Public License + * along with JANDOM. If not, see . + */ package it.unipd.jandom.domains.numerical.mod import it.unipd.jandom.domains.{Abstraction, CompleteLatticeOperator, IntOperator} diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/parity/Parity.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/parity/Parity.scala index b114e9ca..19e82558 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/parity/Parity.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/parity/Parity.scala @@ -1,3 +1,20 @@ +/** + * Copyright 2017 Mirko Bez, Stefano Munari, Sebastiano Valle + * + * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains + * JANDOM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * JANDOM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of a + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You shosuld have received a copy of the GNU General Public License + * along with JANDOM. If not, see . + */ package it.unipd.jandom.domains.numerical.parity object Parity { diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/parity/ParityDomain.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/parity/ParityDomain.scala index ef5f410d..9544de74 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/parity/ParityDomain.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/parity/ParityDomain.scala @@ -1,3 +1,20 @@ +/** + * Copyright 2017 Mirko Bez, Stefano Munari, Sebastiano Valle + * + * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains + * JANDOM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * JANDOM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of a + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You shosuld have received a copy of the GNU General Public License + * along with JANDOM. If not, see . + */ /** * Copyright 2013, 2016 Gianluca Amato * diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/parity/ParityDomainCore.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/parity/ParityDomainCore.scala index f1edbb00..81b59bd0 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/parity/ParityDomainCore.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/parity/ParityDomainCore.scala @@ -1,3 +1,20 @@ +/** + * Copyright 2017 Mirko Bez, Stefano Munari, Sebastiano Valle + * + * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains + * JANDOM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * JANDOM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of a + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You shosuld have received a copy of the GNU General Public License + * along with JANDOM. If not, see . + */ package it.unipd.jandom.domains.numerical.parity import it.unipd.jandom.domains.{Abstraction, CompleteLatticeOperator, IntOperator} diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/sign/ES01.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/sign/ES01.scala index 3f2e8c4a..6dc249ae 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/sign/ES01.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/sign/ES01.scala @@ -1,3 +1,20 @@ +/** + * Copyright 2017 Mirko Bez, Stefano Munari, Sebastiano Valle + * + * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains + * JANDOM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * JANDOM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of a + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You shosuld have received a copy of the GNU General Public License + * along with JANDOM. If not, see . + */ package it.unipd.jandom.domains.numerical.sign diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/sign/ESeq.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/sign/ESeq.scala index 89cc7e63..dfb17265 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/sign/ESeq.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/sign/ESeq.scala @@ -1,3 +1,20 @@ +/** + * Copyright 2017 Mirko Bez, Stefano Munari, Sebastiano Valle + * + * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains + * JANDOM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * JANDOM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of a + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You shosuld have received a copy of the GNU General Public License + * along with JANDOM. If not, see . + */ package it.unipd.jandom.domains.numerical.sign import Sign._ diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/sign/ESeqDomain.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/sign/ESeqDomain.scala index 3f92e071..9a27b0e9 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/sign/ESeqDomain.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/sign/ESeqDomain.scala @@ -1,3 +1,20 @@ +/** + * Copyright 2017 Mirko Bez, Stefano Munari, Sebastiano Valle + * + * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains + * JANDOM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * JANDOM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of a + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You shosuld have received a copy of the GNU General Public License + * along with JANDOM. If not, see . + */ package it.unipd.jandom.domains.numerical.sign import it.unich.jandom.domains.numerical.LinearForm diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/sign/ESeqDomainCore.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/sign/ESeqDomainCore.scala index b10281b8..c164c30b 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/sign/ESeqDomainCore.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/sign/ESeqDomainCore.scala @@ -1,3 +1,20 @@ +/** + * Copyright 2017 Mirko Bez, Stefano Munari, Sebastiano Valle + * + * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains + * JANDOM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * JANDOM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of a + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You shosuld have received a copy of the GNU General Public License + * along with JANDOM. If not, see . + */ package it.unipd.jandom.domains.numerical.sign import it.unipd.jandom.domains.numerical.sign.Sign._ diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/sign/ExtendedSigns01Domain.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/sign/ExtendedSigns01Domain.scala index aa9be590..0b0fda7f 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/sign/ExtendedSigns01Domain.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/sign/ExtendedSigns01Domain.scala @@ -1,3 +1,20 @@ +/** + * Copyright 2017 Mirko Bez, Stefano Munari, Sebastiano Valle + * + * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains + * JANDOM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * JANDOM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of a + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You shosuld have received a copy of the GNU General Public License + * along with JANDOM. If not, see . + */ package it.unipd.jandom.domains.numerical.sign import it.unich.jandom.domains.numerical.LinearForm diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/sign/ExtendedSigns01DomainCore.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/sign/ExtendedSigns01DomainCore.scala index abc50070..55eb9029 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/sign/ExtendedSigns01DomainCore.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/sign/ExtendedSigns01DomainCore.scala @@ -1,3 +1,20 @@ +/** + * Copyright 2017 Mirko Bez, Stefano Munari, Sebastiano Valle + * + * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains + * JANDOM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * JANDOM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of a + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You shosuld have received a copy of the GNU General Public License + * along with JANDOM. If not, see . + */ package it.unipd.jandom.domains.numerical.sign import it.unipd.jandom.domains.{Abstraction, CompleteLatticeOperator, IntOperator} diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/sign/Sign.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/sign/Sign.scala index 1358de1c..e1113eec 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/sign/Sign.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/sign/Sign.scala @@ -1,3 +1,20 @@ +/** + * Copyright 2017 Mirko Bez, Stefano Munari, Sebastiano Valle + * + * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains + * JANDOM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * JANDOM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of a + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You shosuld have received a copy of the GNU General Public License + * along with JANDOM. If not, see . + */ package it.unipd.jandom.domains.numerical.sign /** diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/sign/SignDomain.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/sign/SignDomain.scala index 9e911637..cc2df048 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/sign/SignDomain.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/sign/SignDomain.scala @@ -1,3 +1,20 @@ +/** + * Copyright 2017 Mirko Bez, Stefano Munari, Sebastiano Valle + * + * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains + * JANDOM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * JANDOM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of a + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You shosuld have received a copy of the GNU General Public License + * along with JANDOM. If not, see . + */ /** * Copyright 2013, 2016 Gianluca Amato * diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/sign/SignDomainCore.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/sign/SignDomainCore.scala index 0f67fe6c..54ea4028 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/sign/SignDomainCore.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/sign/SignDomainCore.scala @@ -1,3 +1,20 @@ +/** + * Copyright 2017 Mirko Bez, Stefano Munari, Sebastiano Valle + * + * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains + * JANDOM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * JANDOM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of a + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You shosuld have received a copy of the GNU General Public License + * along with JANDOM. If not, see . + */ package it.unipd.jandom.domains.numerical.sign import it.unipd.jandom.domains.{Abstraction, CompleteLatticeOperator, IntOperator} diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/utils/MathLibrary.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/utils/MathLibrary.scala index 85b5e446..5e920057 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/utils/MathLibrary.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/utils/MathLibrary.scala @@ -1,3 +1,20 @@ +/** + * Copyright 2017 Mirko Bez, Stefano Munari, Sebastiano Valle + * + * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains + * JANDOM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * JANDOM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of a + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You shosuld have received a copy of the GNU General Public License + * along with JANDOM. If not, see . + */ package it.unipd.jandom.domains.numerical.utils /** From 8bab8009dede2e0f4cd8dc4dd687cc59f7a01c29 Mon Sep 17 00:00:00 2001 From: herrBez Date: Sun, 31 Dec 2017 11:29:38 +0100 Subject: [PATCH 43/99] =?UTF-8?q?Split=20UniPDTest=20into=20SVBenchmark=20?= =?UTF-8?q?and=20NumericalTestExtra=20Add=20Copyright=20notice=20to=20the?= =?UTF-8?q?=20examples=20to=20be=20compliant=20with=20GPLv3=20+=20Add=20re?= =?UTF-8?q?ference=20to=20Min=C3=A8=20slides=20and=20sv-benchmark=20from?= =?UTF-8?q?=20which=20we=20took=20some=20examples?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/examples/Java/Congruence.class | Bin 693 -> 715 bytes core/examples/Java/Congruence.java | 31 ++++++++- core/examples/Java/NumericalTestExtra.class | Bin 0 -> 753 bytes core/examples/Java/NumericalTestExtra.java | 58 +++++++++++++++++ core/examples/Java/SvBenchmark.class | Bin 0 -> 571 bytes core/examples/Java/SvBenchmark.java | 52 +++++++++++++++ core/examples/Java/UniPDTests.class | Bin 1094 -> 0 bytes core/examples/Java/UniPDTests.java | 68 -------------------- 8 files changed, 139 insertions(+), 70 deletions(-) create mode 100644 core/examples/Java/NumericalTestExtra.class create mode 100644 core/examples/Java/NumericalTestExtra.java create mode 100644 core/examples/Java/SvBenchmark.class create mode 100644 core/examples/Java/SvBenchmark.java delete mode 100644 core/examples/Java/UniPDTests.class delete mode 100644 core/examples/Java/UniPDTests.java diff --git a/core/examples/Java/Congruence.class b/core/examples/Java/Congruence.class index ed6f022ce634aefb836b8ec0c813fda168b60bbe..a6fdb69d80e64386a31fe5ef158784be5a73738d 100644 GIT binary patch delta 192 zcmdnWdYW~Dy^TmxVsU12d~$wXdQoX=UUF)DVoC}l18;CiVsf@`VnIk^Qcfx(1E#Xv z(wvE@s~LqS3o=@XiZU=Uh%vA-h%<0ANH7R8NHK^oNKZ~+^c0l?%E&XYFeor^Feozc zF(@&JGN?@6#~7`s3zX3V%IGt2F&F@43>kzOjDWh08RQsD7}OZdCR;K2iP{5IIWTZC VI5G$@I0MahVUT2SojjLG0sv)mCNKa1 delta 190 zcmX@jx|MZ;y&6kNYHWo&RYz#~c>4h8a=82A7H%NwKs diff --git a/core/examples/Java/Congruence.java b/core/examples/Java/Congruence.java index f6622569..1c1c21a8 100644 --- a/core/examples/Java/Congruence.java +++ b/core/examples/Java/Congruence.java @@ -1,8 +1,23 @@ /** + * Copyright 2017 Mirko Bez, Stefano Munari, Sebastiano Valle + * + * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains + * JANDOM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * JANDOM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of a + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with JANDOM. If not, see . */ class Congruence { - static void test() { + static void basic_congruence_add() { int x = 3; int y = 12; if(x < 12) @@ -11,7 +26,7 @@ static void test() { x += 2; } - static void testCongruence() { + static void basic_congruence_mul() { int x = 2; int y = 3; int z = x*y; @@ -20,6 +35,12 @@ static void testCongruence() { } } + /** + * Example taken from + * + * this slides of Minè (91/103) + * + */ static void mineCongruence() { int x = 0; int y = 2; @@ -32,6 +53,12 @@ static void mineCongruence() { } } + /** + * Example taken from + * + * this slides of Minè (96/103) + * + */ static void mineProductIntervalCongruence() { int x = 1; while(x-10 <= 0) { diff --git a/core/examples/Java/NumericalTestExtra.class b/core/examples/Java/NumericalTestExtra.class new file mode 100644 index 0000000000000000000000000000000000000000..77f21c9bb335ff81e4d346949035024b180b0c73 GIT binary patch literal 753 zcmZXQOK;Oa6ota-B2=`i}BO`j!Apt5ab_x)=*oVxp&8c3b=R2HRsQJN4f?CIF3j9Gg6P>*<4 z=VSCqWvPI-osP4vdZq0VON^;9=81Qh<>isdU*Jo+V;Jm*?+e= zXX>;C7O7bxe+?B}CtaHH>x|$~Q6?Xl&_53P?f>Z}=^Lb%aS1m`doy}-8nm1XgU?vV zhbL#hEbW}<{d=};@;2!^r0?>v%{sr~2-`+^W_6D;+g>pr2JSGNXQ-a{XUi*eStV4N zL0i-F8*Vtk&)^uP3B(Bs6P(Rs1jK*`G*~0pV)N^$VFPtMoX4pNhtAcRvz6PqmU5xn YZU*s%kv^v235WZX*fYkcQS89~17aw9TmS$7 literal 0 HcmV?d00001 diff --git a/core/examples/Java/NumericalTestExtra.java b/core/examples/Java/NumericalTestExtra.java new file mode 100644 index 00000000..0294ffed --- /dev/null +++ b/core/examples/Java/NumericalTestExtra.java @@ -0,0 +1,58 @@ +/** + * Copyright 2017 Mirko Bez, Stefano Munari, Sebastiano Valle + * + * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains + * JANDOM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * JANDOM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of a + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with JANDOM. If not, see . + */ + +public class NumericalTestExtra { + + static void simple_multiplication_test() { + int a = 10; + int b = -2; + int c = 10 + a*b; + } + static void simple_algebra_example() { + int a = 10; + a = -a; + int c = -100 * + a; + } + + static void simple_loop_with_exit() { + int a = 0; + while(a <= 0) + a = 1; + } + + static void remainder_of_one() { + int x = 1; + x = x % 2; + } + + @SuppressWarnings("ALL") + static void filter() { + int a = 2; + a += -12; + if(a < 0) + a++; + else + a--; + } + + static void divison_by_zero() { + int x = 0; + int y = 2; + int z = y / x; + } +} diff --git a/core/examples/Java/SvBenchmark.class b/core/examples/Java/SvBenchmark.class new file mode 100644 index 0000000000000000000000000000000000000000..bdf5a2c50da5ba0bd5bda044887418d2c78878e3 GIT binary patch literal 571 zcmY*VJ#W)c6g@A`j@#5}BC4v$PK!Vkn$k8^s9;Fw01^`)Ll6Ut^I~4GTgR?kyT2e? ze*psv44pe6G4KQUFN|zJIClA}E!}tDz2}~D?)&od(`NvCXx1Q6x3FlTAyDmyahUB3 z$c^?(0pn5fS_?Fugt2~>PewX@p+*ra?c;p1yXTEnbgaERPPOs_&sS08WofRxOsA7D zR#}+D0`)97bVG&*S#3KM0CM@iK#Y7^3>Ol!@@#yaPm;c zelSt#;m(0NQ8o;i0t^4ui7GmsNX2hD&qoK^&u|?TZd`m4+z=*XmA6%%f~UFp5#pSQ zfW=rXiz}Gp{|EYt6czSdqbK`LbM6C{9P2$S*Btg8W7s>JeJuzoCBa%59o}53wNRr{ z18Z2qH8{9|c_QZ_f4~r8u}YQNU!7B0G}-P*>c|IfD{zA5O*d!-!~NBFFwTv8hU_gH zZ(&b`m_nS*zD~87j3gnCc RIud-6?@a1^hJ|t``xl&8Z5;pr literal 0 HcmV?d00001 diff --git a/core/examples/Java/SvBenchmark.java b/core/examples/Java/SvBenchmark.java new file mode 100644 index 00000000..6c885dfd --- /dev/null +++ b/core/examples/Java/SvBenchmark.java @@ -0,0 +1,52 @@ +/** + * Copyright 2017 Mirko Bez, Stefano Munari, Sebastiano Valle + * + * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains + * JANDOM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * JANDOM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of a + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with JANDOM. If not, see . + */ + +/** + * These examples are a Java-Translation of some C examples taken from the the + * sv-benchmark + */ +public class SvBenchmark { + // taken from sv-benchmarks repository + static void sum04_false_unreach_call_true_termination(){ + int i = 1; + int sn = 0; + while(i <= 8) { + if (i < 4) + sn = sn + (2); + i = i + 1; + } + // POST CONDITION: sn == 6 + } + + static void for_infinite_loop_2_true_unreach_call_false_termination() { + int i_U = 0; + int x = 0; + int y = 0; + int n = x*y*i_U + 12*3*x*y; + if(!(n > 0)) { + return; + } + boolean z = true; + for(i_U = 0; z; i_U++) { + x++; + //verifierAssert(!x ? 1 : 0); + } + //UNREACHABLE CODE + x += 12; + } +} diff --git a/core/examples/Java/UniPDTests.class b/core/examples/Java/UniPDTests.class deleted file mode 100644 index aea041103d545a87cc7ccd2c4931d5d3c0c98119..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1094 zcmZXRO;giQ6o$`j(og#lS^*~oMif6lp-cxsP0Nhn=my0Z&;^?`ZEwlNG^uHdy6?_k z;0$bZ!J3sbF8l%h7k9dGkoqQ+cF<(&*!+2?S>^7wQMIt5wnejLalP5GJkhd5&G3X{>mF}=jK&S! z5}t?cs_=BDp&QmNuet`K(LQE5PD_6)JX7cI1c=m@XVhLlGg^K5jLYkt8sDtfAKCS% z{0)pXgynG;rFF3{+K#>UeuujbquF++xwxb^46Ducj_q=zX6iM=vUJbwa5!?C!VcUq zT4^}0F6@RsBi92H#j~;t;F;D1GO^`!+!}u({NXb%ZSmsqHfC)v>>2w;l4J@qN(`47 zDgH*mGVI;LW_6F(JesBulJ<`{Az2FJ9>Lcno(#|M+!tcUcwrR9JrXQ3is3vjEkeMT zNGl0VIV~v(HE&kRLnaGZ!X<%-;7ma&hIZ%tA}oYZkp!=LnsT6;rGM!-=mgkHIFq0g z1G?Ndnv^v4kYciS)cftzp}_B1?+m^a&?BI;xCncp6ACeZjO0M-7RvmYqq3%kTiVb= zI+$+^+v8BV0w^_rHv0W@VXaF))dPxmi5*d-OTD2D6&O(-0uulyG5i!|=qk)i5A9@F z2+HY!@;u7@T;q}!F6CA0zeum6UWm(cj<&Tu?GUf-<`_*O1Veca1C%T8;%jms=nC_$R1LXV=IhPPw knXb_)Ml8eK8eFXhezGL>Pyj~^f9wP=Dg1{KXoV>I7g{T|fdBvi diff --git a/core/examples/Java/UniPDTests.java b/core/examples/Java/UniPDTests.java deleted file mode 100644 index b2954a62..00000000 --- a/core/examples/Java/UniPDTests.java +++ /dev/null @@ -1,68 +0,0 @@ -public class UniPDTests { - - static void simple_multiplication_test() { - int a = 10; - int b = -2; - int c = 10 + a*b; - } - static void a_little_bit_of_algebra() { - int a = 10; - a = -a; - int c = -100 * + a; - } - - static void simple_loop_with_exit() { - int a = 0; - while(a <= 0) - a = 1; - } - - static void reduceOddAndGeq() { - int x = 1; - x = x % 2; - } - - @SuppressWarnings("ALL") - static void filter() { - int a = 2; - a += -12; - if(a < 0) - a++; - else - a--; - } - static void divisonByZero() { - int x = 0; - int y = 2; - int z = y / x; - } - - // taken from sv-benchmarks repository - static void sum04_false_unreach_call_true_termination(){ - int i = 1; - int sn = 0; - while(i <= 8) { - if (i < 4) - sn = sn + (2); - i = i + 1; - } - // POST CONDITION: sn == 6 - } - - static void for_infinite_loop_2_true_unreach_call_false_termination() { - int i_U = 0; - int x = 0; - int y = 0; - int n = x*y*i_U + 12*3*x*y; - if(!(n > 0)) { - return; - } - boolean z = true; - for(i_U = 0; z; i_U++) { - x++; - //verifierAssert(!x ? 1 : 0); - } - //UNREACHABLE CODE - x += 12; - } -} From 625cb4f6bc88ca13cc19c40988332bb39c6b8861 Mon Sep 17 00:00:00 2001 From: herrBez Date: Tue, 2 Jan 2018 12:10:31 +0100 Subject: [PATCH 44/99] Fix error in BaseNumericalDomain's LinearEvaluation that causes errors in computing variables multiplied by costants --- .../domains/numerical/BaseNumericalDomain.scala | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/BaseNumericalDomain.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/BaseNumericalDomain.scala index 3c44e86a..b78a620a 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/BaseNumericalDomain.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/BaseNumericalDomain.scala @@ -351,11 +351,12 @@ abstract class BaseNumericalDomain if (unreachable && homcoeffs.exists { _ != 0 }) return core.top var acc: T = core.alpha(known) - for (i <- homcoeffs.indices) - if (homcoeffs(i) < 0) - acc = core.sum(acc, core.inverse(elements(i))) - else if(homcoeffs(i) > 0) - acc = core.sum(acc, elements(i)) + for (i <- homcoeffs.indices) { + if (homcoeffs(i) != 0) { + val t = core.mult(core.alpha(homcoeffs(i)), elements(i)) + acc = core.sum(acc, t) + } + } acc } From 4b3b0afb911cda3887ec025e89f432137517d21d Mon Sep 17 00:00:00 2001 From: herrBez Date: Tue, 2 Jan 2018 12:22:50 +0100 Subject: [PATCH 45/99] Improve efficiency of compare function of CongruenceDomainCore Add in standardForm computation of absolute value --- .../congruence/CongruenceDomainCore.scala | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/congruence/CongruenceDomainCore.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/congruence/CongruenceDomainCore.scala index 4271a7a9..c2735ad8 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/congruence/CongruenceDomainCore.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/congruence/CongruenceDomainCore.scala @@ -63,7 +63,7 @@ class CongruenceDomainCore extends CompleteLatticeOperator[Congruence] case (Mod(a0, b0), Mod(a1, b1)) => val a = M.gcd(a0, a1) val b = b0 + b1 - alpha(a,b) + alpha(a, b) } } @@ -125,7 +125,7 @@ class CongruenceDomainCore extends CompleteLatticeOperator[Congruence] case (Mod(a0, b0), Mod(a1, b1)) => val a = M.gcd(a0,M.gcd(a1, Some(b1))) val b = b0 - alpha(a,b) + alpha(a, b) } } @@ -145,7 +145,7 @@ class CongruenceDomainCore extends CompleteLatticeOperator[Congruence] } val a = M.gcd(a0, M.gcd(a1, btmp)) val b = Math.min(b0,b1) - alpha(a,b) + alpha(a, b) } } @@ -219,12 +219,9 @@ class CongruenceDomainCore extends CompleteLatticeOperator[Congruence] case (_, CongruenceBottom) => Option(1) case (Mod(a0, b0), Mod(a1, b1)) => - var cleqd = false - var dleqc = false - if(M.isDivisor(a1, a0) && M.isCongruent(b0,b1,a1)) - cleqd = true - if(M.isDivisor(a0,a1) && M.isCongruent(b1, b0, a0)) - dleqc = true + val cleqd = M.isDivisor(a1, a0) && M.isCongruent(b0, b1, a1) + val dleqc = M.isDivisor(a0, a1) && M.isCongruent(b1, b0, a0) + if(cleqd && dleqc) Option(0) @@ -252,13 +249,15 @@ class CongruenceDomainCore extends CompleteLatticeOperator[Congruence] /** * Reduce the congruence abstract domain by removing redundant elements. * All the congruences are converted in the form: - * aZ+b with a > 0 and 0<= b < a + * aZ+b with a > 0 and 0 <= b < a */ private def standardForm(c : Congruence) : Congruence = { c match { case CongruenceBottom => CongruenceBottom case Mod(None, _) => c - case Mod(Some(a), b) => Mod(Some(a), ((b % a) + a) % a) + case Mod(Some(a), b) => + val a1 = Math.abs(a) + Mod(Some(a1), ((b % a1) + a1) % a1) } } From ae15e3b6d26dafc1cc16c45f575b80951057465e Mon Sep 17 00:00:00 2001 From: BottCode Date: Thu, 8 Mar 2018 16:20:10 +0100 Subject: [PATCH 46/99] First progress in Box Domain --- .../jandom/domains/numerical/box/Box.scala | 43 +++++ .../domains/numerical/box/BoxDomain.scala | 0 .../domains/numerical/box/BoxDomainCore.scala | 177 ++++++++++++++++++ 3 files changed, 220 insertions(+) create mode 100644 core/src/main/scala/it/unipd/jandom/domains/numerical/box/Box.scala create mode 100644 core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala create mode 100644 core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/Box.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/Box.scala new file mode 100644 index 00000000..77bec1c0 --- /dev/null +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/Box.scala @@ -0,0 +1,43 @@ +/** + * Copyright 2017 Mattia Bottaro, Mauro Carlin + * + * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains + * JANDOM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * JANDOM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of a + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You shosuld have received a copy of the GNU General Public License + * along with JANDOM. If not, see . + */ +package it.unipd.jandom.domains.numerical.box + +/** + * The elements of the constant domain. + * It is a flat domain composed of constant elements, top and bottom. + * This domain is useful for the constant propagation analysis. + * + * @author Mattia Bottaro + * @author Mauro Carlin + */ +object Box { + sealed trait Box + + // interval + case class Interval (low : Int, high : Int) extends Box { + override def toString : String = "= [" + low + "," + high + "]" + } + // no accurate info available for variable + case object IntervalTop extends Box { + override def toString : String = "= \u22a4" + } + // no possible value + case object IntervalBottom extends Box { + override def toString: String = "= \u22a5" + } +} diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala new file mode 100644 index 00000000..e69de29b diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala new file mode 100644 index 00000000..d2f956f9 --- /dev/null +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala @@ -0,0 +1,177 @@ +/** + * Copyright 2017 Mattia Bottaro, Mauro Carlin + * + * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains + * JANDOM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * JANDOM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of a + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You shosuld have received a copy of the GNU General Public License + * along with JANDOM. If not, see . + */ + +package it.unipd.jandom.domains.numerical.box + +import it.unipd.jandom.domains.numerical.utils.{MathLibrary => M} +import it.unipd.jandom.domains.{Abstraction, CompleteLatticeOperator, IntOperator} +import Box._ + +/** + * The Box domain + */ + + // TODO: define reminder function + +class BoxDomainCore extends CompleteLatticeOperator[Box] + with IntOperator[Box] with Abstraction[Int,Box]{ + + /** + * @inheritdoc + */ + def alpha(num : Int) : Box = Interval(num,num) + + /** + * @inheritdoc + */ + def sum(x : Box, y : Box) : Box = { + (x,y) match { + case (IntervalBottom, _) => IntervalBottom + case (_, IntervalBottom) => IntervalBottom + case (IntervalTop, _) => IntervalTop + case (_, IntervalTop) => IntervalTop + case (Interval(low1, high1), Interval(low2,high2)) => Interval((low1 + low2), (high1 + high2)) + } + } + + /** + * @inheritdoc + */ + def inverse(x : Box) : Box = { + (x,y) match { + case (IntervalBottom) => IntervalBottom + case (IntervalTop) => IntervalTop + case (Interval (low, high)) => Interval (-high, -low) + } + } + + /** + * @inheritdoc + */ + def mult(x : Box, y : Box) : Box = { + (x,y) match { + case (IntervalBottom, _) => IntervalBottom + case (_, IntervalBottom) => IntervalBottom + case (IntervalTop, _) => IntervalTop + case (_, IntervalTop) => IntervalTop + case (Interval (low1, high1), Interval (low2,high2)) => + val comb = Array(low1 * low2, high1 * high2, low1 * high2, high1 * low2) + val new_low = comb.reduceLeft(_ min _) + val new_high = comb.reduceLeft(_ max _) + Interval (min, max) + } + } + + /** + * @inheritdoc + */ + def division(x : Box, y : Box) : Box = { + (x,y) match { + case (IntervalBottom, _) => IntervalBottom + case (_, IntervalBottom) => IntervalBottom + case (IntervalTop, _) => IntervalTop + case (_, IntervalTop) => IntervalTop + case (Interval (low1, high1), Interval (low2,high2)) => + if (low2 >=1){ + val new_low = (low1 / low2) min (low1 / high2) + val new_high = (high1 / low2) max (high1 / high2) + Interval (new_low, new_high) + } else if (high2 <= -1){ + val new_low = (high1 / low2) min (high1 / high2) + val new_high = (low1 / low2) max (low1 / high2) + Interval (new_low, new_high) + } else { + // TODO: MODELLARE L'INFINITO "INTERO" + lub(division(x, glb(y, Interval(1,Double.PositiveInfinity)), division(x, glb(y, Interval(Double.NegativeInfinity, -1)))) + } + } + } + + /** + * @inheritdoc + */ + def lub(x : Box, y : Box) : Box = { + (x, y) match { + case (IntervalTop, _) => IntervalTop + case (_, IntervalTop) => IntervalTop + case (IntervalBottom, _) => y + case (_, IntervalBottom) => x + case (Interval (low1, high1), Interval (low2, high2)) => + val new_low = low1 min low2 + val new_high = high1 max high2 + Interval (new_low, new_high) + } + } + + /** + * @inheritdoc + */ + def glb(x : Box, y : Box) : Box = { + (x, y) match { + case (IntervalTop, _) => y + case (_, IntervalTop) => x + case (IntervalBottom, _) => IntervalBottom + case (_, IntervalBottom) => IntervalBottom + case (Interval (low1, high1), Interval (low2, high2)) => + val new_low = low1 max low2 + val new_high = high1 min high2 + if (new_low > new_high) IntervalBottom else Interval (new_low, new_high) + } + } + + /** + * @inheritdoc + */ + def compare(x : Box, y : Box) : Option[Int] = { + (x, y) match { + case (IntervalBottom, IntervalBottom) => Option(0) + case (IntervalBottom, _) => Option(-1) + case (_, IntervalBottom) => Option(1) + case (IntervalTop, IntervalTop) => Option(0) + case (IntervalTop, _) => Option(1) + case (_, IntervalTop) => Option(-1) + case (Interval(low1, high1), Interval(low2, high2))) => + if (low1 == low2 && high1 == high2) + Option(0) + else if (low1 >= low2 && high1 <= high2) + Option(-1) + else if (low2 >= low1 && high2 >= high1) + Option(1) + else + Option.empty + } + } + + /** + * @inheritdoc + */ + override def top: Box = IntervalTop + + /** + * @inheritdoc + */ + override def bottom: Box = IntervalBottom + +} + +object BoxDomainCore { + /** + * Factory method of BoxDomainCore + */ + def apply() = new BoxDomainCore +} // end of BoxDomainCore companion object From d42b1fd6156685285a7715c24aeb7b2d53a28b01 Mon Sep 17 00:00:00 2001 From: Mou95 Date: Thu, 8 Mar 2018 16:57:32 +0100 Subject: [PATCH 47/99] Corretto errori BoxDomainCore --- .../domains/numerical/box/BoxDomainCore.scala | 46 +++++++++++-------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala index d2f956f9..2c68c8fa 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala @@ -43,7 +43,7 @@ class BoxDomainCore extends CompleteLatticeOperator[Box] (x,y) match { case (IntervalBottom, _) => IntervalBottom case (_, IntervalBottom) => IntervalBottom - case (IntervalTop, _) => IntervalTop + case (IntervalTop, _) => IntervalTop case (_, IntervalTop) => IntervalTop case (Interval(low1, high1), Interval(low2,high2)) => Interval((low1 + low2), (high1 + high2)) } @@ -53,9 +53,9 @@ class BoxDomainCore extends CompleteLatticeOperator[Box] * @inheritdoc */ def inverse(x : Box) : Box = { - (x,y) match { + x match { case (IntervalBottom) => IntervalBottom - case (IntervalTop) => IntervalTop + case (IntervalTop) => IntervalTop case (Interval (low, high)) => Interval (-high, -low) } } @@ -67,51 +67,57 @@ class BoxDomainCore extends CompleteLatticeOperator[Box] (x,y) match { case (IntervalBottom, _) => IntervalBottom case (_, IntervalBottom) => IntervalBottom - case (IntervalTop, _) => IntervalTop + case (IntervalTop, _) => IntervalTop case (_, IntervalTop) => IntervalTop - case (Interval (low1, high1), Interval (low2,high2)) => + case (Interval (low1, high1), Interval (low2,high2)) => val comb = Array(low1 * low2, high1 * high2, low1 * high2, high1 * low2) val new_low = comb.reduceLeft(_ min _) val new_high = comb.reduceLeft(_ max _) - Interval (min, max) + Interval (new_low, new_high) } } /** * @inheritdoc - */ + */ def division(x : Box, y : Box) : Box = { (x,y) match { case (IntervalBottom, _) => IntervalBottom case (_, IntervalBottom) => IntervalBottom - case (IntervalTop, _) => IntervalTop + case (IntervalTop, _) => IntervalTop case (_, IntervalTop) => IntervalTop - case (Interval (low1, high1), Interval (low2,high2)) => + case (Interval (low1, high1), Interval (low2,high2)) => if (low2 >=1){ val new_low = (low1 / low2) min (low1 / high2) val new_high = (high1 / low2) max (high1 / high2) - Interval (new_low, new_high) - } else if (high2 <= -1){ + Interval (new_low, new_high) + } else if (high2 <= -1) { val new_low = (high1 / low2) min (high1 / high2) val new_high = (low1 / low2) max (low1 / high2) Interval (new_low, new_high) } else { // TODO: MODELLARE L'INFINITO "INTERO" - lub(division(x, glb(y, Interval(1,Double.PositiveInfinity)), division(x, glb(y, Interval(Double.NegativeInfinity, -1)))) - } + Interval(1,1) + //lub(division(Interval (low1, high1), glb(Interval (low2,high2), Interval(1,Double.PositiveInfinity)), division(Interval (low1, high1), glb(Interval (low2,high2), Interval(Double.NegativeInfinity, -1))))) + } } } + //TODO + def remainder(x : Box, y : Box) : Box = { + x + } + /** * @inheritdoc - */ + */ def lub(x : Box, y : Box) : Box = { (x, y) match { case (IntervalTop, _) => IntervalTop case (_, IntervalTop) => IntervalTop case (IntervalBottom, _) => y case (_, IntervalBottom) => x - case (Interval (low1, high1), Interval (low2, high2)) => + case (Interval (low1, high1), Interval (low2, high2)) => val new_low = low1 min low2 val new_high = high1 max high2 Interval (new_low, new_high) @@ -127,7 +133,7 @@ class BoxDomainCore extends CompleteLatticeOperator[Box] case (_, IntervalTop) => x case (IntervalBottom, _) => IntervalBottom case (_, IntervalBottom) => IntervalBottom - case (Interval (low1, high1), Interval (low2, high2)) => + case (Interval (low1, high1), Interval (low2, high2)) => val new_low = low1 max low2 val new_high = high1 min high2 if (new_low > new_high) IntervalBottom else Interval (new_low, new_high) @@ -145,14 +151,14 @@ class BoxDomainCore extends CompleteLatticeOperator[Box] case (IntervalTop, IntervalTop) => Option(0) case (IntervalTop, _) => Option(1) case (_, IntervalTop) => Option(-1) - case (Interval(low1, high1), Interval(low2, high2))) => - if (low1 == low2 && high1 == high2) + case (Interval(low1, high1), Interval(low2, high2)) => + if (low1 == low2 && high1 == high2) Option(0) else if (low1 >= low2 && high1 <= high2) Option(-1) else if (low2 >= low1 && high2 >= high1) Option(1) - else + else Option.empty } } @@ -161,7 +167,7 @@ class BoxDomainCore extends CompleteLatticeOperator[Box] * @inheritdoc */ override def top: Box = IntervalTop - + /** * @inheritdoc */ From 1b48f6af49b869aa941035f5a8d2583d181d2d88 Mon Sep 17 00:00:00 2001 From: BottCode Date: Fri, 9 Mar 2018 10:35:42 +0100 Subject: [PATCH 48/99] Add boxdomain's skeleton and add it to the gui --- .../it/unich/jandom/ui/NumericalDomains.scala | 2 + .../domains/numerical/box/BoxDomain.scala | 69 +++++++++++++++++++ .../domains/numerical/box/BoxDomainCore.scala | 2 +- 3 files changed, 72 insertions(+), 1 deletion(-) diff --git a/core/src/main/scala/it/unich/jandom/ui/NumericalDomains.scala b/core/src/main/scala/it/unich/jandom/ui/NumericalDomains.scala index 824b448c..2f72688c 100644 --- a/core/src/main/scala/it/unich/jandom/ui/NumericalDomains.scala +++ b/core/src/main/scala/it/unich/jandom/ui/NumericalDomains.scala @@ -26,6 +26,7 @@ import it.unipd.jandom.domains.numerical.parity.ParityDomain import it.unipd.jandom.domains.numerical.constant.ConstantDomain import it.unipd.jandom.domains.numerical.mod.ModKDomain import it.unipd.jandom.domains.numerical.sign.{ESeqDomain, ExtendedSigns01Domain, SignDomain} +import it.unipd.jandom.domains.numerical.box.BoxDomain /** * The ParameterEnumeration for numerical domains. @@ -35,6 +36,7 @@ object NumericalDomains extends ParameterEnumeration[NumericalDomain] { val description = "The numerical domain to use for the analysis." val values: Buffer[ParameterValue[NumericalDomain]] = Buffer( + ParameterValue(BoxDomain(), "Box (Interval) Domain", "This is a native Scala implementation of the Box (that is Interval) integer domain"), ParameterValue(SignDomain(), "Sign Domain", "This is a native Scala implementation of the simple sign domain " + "(<0, =0, >0)"), ParameterValue(ParityDomain(), "Parity Domain", "This is a native Scala implementation of even/odd domain."), diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala index e69de29b..5b7b933c 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala @@ -0,0 +1,69 @@ +/** + * Copyright 2018 Mattia Bottaro, Mauro Carlin + * + * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains + * JANDOM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * JANDOM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of a + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You shosuld have received a copy of the GNU General Public License + * along with JANDOM. If not, see . + */ +package it.unipd.jandom.domains.numerical.box + +import it.unich.jandom.domains.numerical.LinearForm +import it.unipd.jandom.domains.numerical.BaseNumericalDomain +import it.unipd.jandom.domains.numerical.box.Box._ +import it.unipd.jandom.domains.numerical.box.BoxDomainCore._ + + +/** + * Box Domain ... @TODO a better explanation is required + * + * @author Mattia Bottaro + * @author Mauro Carlin + */ +class BoxDomain extends BaseNumericalDomain[Box, BoxDomainCore](BoxDomainCore()) { + + /** + * @inheritdoc + */ + override def createProperty(constants: Array[Box], unreachable: Boolean): Property = + new Property(Box, unreachable) + + /** + * Numerical property that tells whether the variables in a certain point of the CFG are constant or not. + * @param boxes array of the variables' constant status + * @param unreachable tells if a given program point is unreachable + */ + class Property (boxes : Array[Box], unreachable: Boolean) extends BaseProperty(boxes, unreachable) { + + /** + * @inheritdoc + */ + override def linearDisequality(lf: LinearForm): Property = { + + } + + /** + * @inheritdoc + */ + override def linearInequality(lf: LinearForm): Property = { + + } + + } // end of Property +} // end of BoxDomain (class) + +object BoxDomain { + /** + * Factory method of BoxDomain + */ + def apply() = new BoxDomain() +} \ No newline at end of file diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala index 2c68c8fa..13c0078a 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala @@ -1,5 +1,5 @@ /** - * Copyright 2017 Mattia Bottaro, Mauro Carlin + * Copyright 2018 Mattia Bottaro, Mauro Carlin * * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains * JANDOM is free software: you can redistribute it and/or modify From 4374cc7cfbaf856229b01c501ad697fa3acb516a Mon Sep 17 00:00:00 2001 From: mcarlin Date: Fri, 9 Mar 2018 10:52:57 +0100 Subject: [PATCH 49/99] Scheletro BoxDomain --- .../domains/numerical/box/BoxDomain.scala | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala index 5b7b933c..59f0646b 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala @@ -34,16 +34,17 @@ class BoxDomain extends BaseNumericalDomain[Box, BoxDomainCore](BoxDomainCore()) /** * @inheritdoc */ - override def createProperty(constants: Array[Box], unreachable: Boolean): Property = - new Property(Box, unreachable) + override def createProperty(boxes: Array[Box], unreachable: Boolean): Property = + new Property(boxes, unreachable) /** * Numerical property that tells whether the variables in a certain point of the CFG are constant or not. - * @param boxes array of the variables' constant status + * @param boxes array of the variables' boxes status * @param unreachable tells if a given program point is unreachable */ class Property (boxes : Array[Box], unreachable: Boolean) extends BaseProperty(boxes, unreachable) { + def apply(boxes: Array[Box], unreachable: Boolean) : Property = new Property(boxes, unreachable) /** * @inheritdoc */ @@ -57,6 +58,14 @@ class BoxDomain extends BaseNumericalDomain[Box, BoxDomainCore](BoxDomainCore()) override def linearInequality(lf: LinearForm): Property = { } + + override def widening(that : Property) : Property = { + + } + + override def narrowing(that : Property) : Property = { + + } } // end of Property } // end of BoxDomain (class) @@ -66,4 +75,4 @@ object BoxDomain { * Factory method of BoxDomain */ def apply() = new BoxDomain() -} \ No newline at end of file +} From 34bcc444557b933bfcd6337ab78cf2b820f3f066 Mon Sep 17 00:00:00 2001 From: Mou95 Date: Tue, 13 Mar 2018 18:05:48 +0100 Subject: [PATCH 50/99] Implemented linearDisequality for Interval --- core/examples/Java/TestBug.class | Bin 0 -> 390 bytes core/examples/Java/TestBug.java | 11 ++++++++ .../jandom/domains/numerical/box/Box.scala | 4 +-- .../domains/numerical/box/BoxDomain.scala | 24 +++++++++++++----- 4 files changed, 30 insertions(+), 9 deletions(-) create mode 100644 core/examples/Java/TestBug.class create mode 100644 core/examples/Java/TestBug.java diff --git a/core/examples/Java/TestBug.class b/core/examples/Java/TestBug.class new file mode 100644 index 0000000000000000000000000000000000000000..b9ee88fa6fbe5064f170f1043f419ec21e508448 GIT binary patch literal 390 zcmZ{ey-veG5QJy_AKOV>K!Zd<2NXm|NFaeILPW(+k%<0mPSFKpL*k2|=RJ4^DkKUX zfL8(`_8coTaK-N4Xy(&=e80T|*h3P+M%zcnN0;CosX|r91bcJqir}1-*OJgZQ-!?H zx2c?tM4Gd*(k~wdrRIB}X7XN(Tvd;R_OKG!&AGU1Y^#6Sb_wCI)YD9!D#MCLa#r>A zcxNK!B8CH(;5Ql}F={Ut#khBwPGnYL0~S{{&jwe7%hTiEI&b3bZoh(F_+SiAuNDa{ z1WW4yBaAgpJ`dM|XLwJGgjFXxHQwgwAmU7GLHR;tDB+T_-%z69Ur4|f6A6DIp=lX0 H(n9 bottom + case Interval(low,high) => if (low == high && low == 0) bottom else this + case _ => this + } } /** * @inheritdoc */ override def linearInequality(lf: LinearForm): Property = { - + if (isEmpty) + return this + val result : Box = linearEvaluation(lf); } - + override def widening(that : Property) : Property = { - + } - + override def narrowing(that : Property) : Property = { - + } } // end of Property @@ -75,4 +85,4 @@ object BoxDomain { * Factory method of BoxDomain */ def apply() = new BoxDomain() -} +} From 71f400bbccea5c23142f120a5d2237037c642808 Mon Sep 17 00:00:00 2001 From: Mou95 Date: Wed, 14 Mar 2018 15:57:21 +0100 Subject: [PATCH 51/99] Implemented widening and narrowing BoxDomain --- .../domains/numerical/box/BoxDomain.scala | 43 ++++++++++++++++--- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala index 09fc1571..37e8d536 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala @@ -64,18 +64,47 @@ class BoxDomain extends BaseNumericalDomain[Box, BoxDomainCore](BoxDomainCore()) * @inheritdoc */ override def linearInequality(lf: LinearForm): Property = { - if (isEmpty) + /*if (isEmpty) return this - val result : Box = linearEvaluation(lf); + val result : Box = linearEvaluation(lf);*/ + return this } override def widening(that : Property) : Property = { + createProperty((this.elements, that.elements).zipped.map((x, y) => { + (x,y) match { + case (IntervalBottom, _) => y + case (_ , IntervalBottom) => x + case (IntervalTop, _) => IntervalTop + case (_ , IntervalTop) => IntervalTop + case (Interval(low1, high1), Interval(low2,high2)) => + // TODO + var newlow = Double.NegativeInfinity.toInt + var newhigh = Double.PositiveInfinity.toInt + if (low1 <= low2) newlow = low1 + if (high1 >= high2) newhigh = high1 + Interval(newlow,newhigh) + } + }), this.isEmpty && that.isEmpty) + } - } - - override def narrowing(that : Property) : Property = { - - } + override def narrowing(that : Property) : Property = { + createProperty((this.elements, that.elements).zipped.map((x, y) => { + (x,y) match { + case (IntervalBottom, _) => IntervalBottom + case (_ , IntervalBottom) => x + case (IntervalTop, _) => y + case (_ , IntervalTop) => x + case (Interval(low1, high1), Interval(low2,high2)) => + // TODO + var newlow = low1 + var newhigh = high1 + if (low1 == Double.NegativeInfinity.toInt) newlow = low2 + if (high1 == Double.PositiveInfinity.toInt) newhigh = high2 + Interval(newlow,newhigh) + } + }), this.isEmpty && that.isEmpty) + } } // end of Property } // end of BoxDomain (class) From 0b84f9bef2a929f2f8c1df1bdd03454e92a4eb1e Mon Sep 17 00:00:00 2001 From: Mou95 Date: Thu, 15 Mar 2018 17:12:57 +0100 Subject: [PATCH 52/99] Improve on LinearInequality --- .../domains/numerical/box/BoxDomain.scala | 46 +++++++++++++++++-- .../domains/numerical/box/BoxDomainCore.scala | 6 +-- .../constant/ConstantDomainCore.scala | 2 +- 3 files changed, 45 insertions(+), 9 deletions(-) diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala index 37e8d536..75ee3ed0 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala @@ -44,7 +44,23 @@ class BoxDomain extends BaseNumericalDomain[Box, BoxDomainCore](BoxDomainCore()) */ class Property (boxes : Array[Box], unreachable: Boolean) extends BaseProperty(boxes, unreachable) { - def apply(boxes: Array[Box], unreachable: Boolean) : Property = new Property(boxes, unreachable) + def projectLow (box : Box) : Int = { + box match { + case IntervalBottom => Double.PositiveInfinity.toInt + case IntervalTop => Double.NegativeInfinity.toInt + case Interval(low,high) => low + } + } + + def projectHigh (box : Box) : Int = { + box match { + case IntervalBottom => Double.NegativeInfinity.toInt + case IntervalTop => Double.PositiveInfinity.toInt + case Interval(low,high) => high + } + } + + def apply(boxes: Array[Box], unreachable: Boolean) : Property = new Property(boxes, unreachable) // x != 0 /** * @inheritdoc @@ -64,10 +80,30 @@ class BoxDomain extends BaseNumericalDomain[Box, BoxDomainCore](BoxDomainCore()) * @inheritdoc */ override def linearInequality(lf: LinearForm): Property = { - /*if (isEmpty) + if (isEmpty) return this - val result : Box = linearEvaluation(lf);*/ - return this + val homcoeffs = lf.homcoeffs.toArray + val known = lf.known + val lowresult = projectLow(linearEvaluation(lf)) + val lfArgmin = linearArgmin(lf); + print(lowresult) + if (lowresult > 0) + bottom + else { + var newboxes : Array[Box] = boxes + for (i <- homcoeffs.indices) { + if (homcoeffs(i) < 0) newboxes(i) = Interval(projectLow(boxes(i)) max (lfArgmin(i) - (lowresult / homcoeffs(i)).toInt), projectHigh(newboxes(i))) + if (homcoeffs(i) > 0) newboxes(i) = Interval(projectLow(newboxes(i)), projectHigh(boxes(i)) min (lfArgmin(i) - (lowresult / homcoeffs(i)).toInt)) + } + print(newboxes) + new Property(newboxes,false) + } + } + + private def linearArgmin(lf: LinearForm): Seq[Int] = { + (lf.homcoeffs.zipWithIndex) map { + case (c, i) => if (c > 0) projectLow(boxes(i)) else projectHigh(boxes(i)) + } } override def widening(that : Property) : Property = { @@ -100,7 +136,7 @@ class BoxDomain extends BaseNumericalDomain[Box, BoxDomainCore](BoxDomainCore()) var newlow = low1 var newhigh = high1 if (low1 == Double.NegativeInfinity.toInt) newlow = low2 - if (high1 == Double.PositiveInfinity.toInt) newhigh = high2 + if (high1 == Double.PositiveInfinity.toInt) newhigh = high2 Interval(newlow,newhigh) } }), this.isEmpty && that.isEmpty) diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala index 13c0078a..16cdce73 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala @@ -149,14 +149,14 @@ class BoxDomainCore extends CompleteLatticeOperator[Box] case (IntervalBottom, _) => Option(-1) case (_, IntervalBottom) => Option(1) case (IntervalTop, IntervalTop) => Option(0) - case (IntervalTop, _) => Option(1) - case (_, IntervalTop) => Option(-1) + case (IntervalTop, _) => Option(1); + case (_, IntervalTop) => Option(-1); case (Interval(low1, high1), Interval(low2, high2)) => if (low1 == low2 && high1 == high2) Option(0) else if (low1 >= low2 && high1 <= high2) Option(-1) - else if (low2 >= low1 && high2 >= high1) + else if (low2 >= low1 && high2 <= high1) Option(1) else Option.empty diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/constant/ConstantDomainCore.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/constant/ConstantDomainCore.scala index 091bd96d..4b689754 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/constant/ConstantDomainCore.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/constant/ConstantDomainCore.scala @@ -21,7 +21,7 @@ import it.unipd.jandom.domains.{Abstraction, CompleteLatticeOperator, IntOperato import Constant._ /** - * Constant domain, checks if a given variable is constant + * Constant domain, checks if a given variable is constant * (and equal to a value `num`) in a program point. * * @author Mirko Bez From 41494f4c704b25ffeeb6522b94946a511c6de13f Mon Sep 17 00:00:00 2001 From: Mou95 Date: Mon, 19 Mar 2018 12:28:18 +0100 Subject: [PATCH 53/99] Implemented safe sum between Intervals --- .../jandom/domains/numerical/box/Box.scala | 6 +++- .../domains/numerical/box/BoxDomain.scala | 21 +++++++------- .../domains/numerical/box/BoxDomainCore.scala | 28 +++++++++++++++++-- 3 files changed, 41 insertions(+), 14 deletions(-) diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/Box.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/Box.scala index ac3a53a3..8219938d 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/Box.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/Box.scala @@ -30,7 +30,11 @@ object Box { // interval case class Interval (low : Int, high : Int) extends Box { - override def toString : String = "= [" + low + "," + high + "]" + override def toString : String = { + if (low == Int.MinValue) return "= [" + "-\u221E" + "," + high + "]" + else if (high == Int.MaxValue) return "= [" + low + "," + "+\u221E" + "]" + return "= [" + low + "," + high + "]" + } } // no accurate info available for variable case object IntervalTop extends Box { diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala index 75ee3ed0..50e969ed 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala @@ -46,16 +46,16 @@ class BoxDomain extends BaseNumericalDomain[Box, BoxDomainCore](BoxDomainCore()) def projectLow (box : Box) : Int = { box match { - case IntervalBottom => Double.PositiveInfinity.toInt - case IntervalTop => Double.NegativeInfinity.toInt + case IntervalBottom => Int.MaxValue + case IntervalTop => Int.MinValue case Interval(low,high) => low } } def projectHigh (box : Box) : Int = { box match { - case IntervalBottom => Double.NegativeInfinity.toInt - case IntervalTop => Double.PositiveInfinity.toInt + case IntervalBottom => Int.MinValue + case IntervalTop => Int.MaxValue case Interval(low,high) => high } } @@ -90,12 +90,13 @@ class BoxDomain extends BaseNumericalDomain[Box, BoxDomainCore](BoxDomainCore()) if (lowresult > 0) bottom else { - var newboxes : Array[Box] = boxes + var newboxes = boxes.clone for (i <- homcoeffs.indices) { if (homcoeffs(i) < 0) newboxes(i) = Interval(projectLow(boxes(i)) max (lfArgmin(i) - (lowresult / homcoeffs(i)).toInt), projectHigh(newboxes(i))) if (homcoeffs(i) > 0) newboxes(i) = Interval(projectLow(newboxes(i)), projectHigh(boxes(i)) min (lfArgmin(i) - (lowresult / homcoeffs(i)).toInt)) } - print(newboxes) + for (i <- newboxes.indices) + print("boxes:",newboxes(i)) new Property(newboxes,false) } } @@ -115,8 +116,8 @@ class BoxDomain extends BaseNumericalDomain[Box, BoxDomainCore](BoxDomainCore()) case (_ , IntervalTop) => IntervalTop case (Interval(low1, high1), Interval(low2,high2)) => // TODO - var newlow = Double.NegativeInfinity.toInt - var newhigh = Double.PositiveInfinity.toInt + var newlow = Int.MinValue + var newhigh = Int.MaxValue if (low1 <= low2) newlow = low1 if (high1 >= high2) newhigh = high1 Interval(newlow,newhigh) @@ -135,8 +136,8 @@ class BoxDomain extends BaseNumericalDomain[Box, BoxDomainCore](BoxDomainCore()) // TODO var newlow = low1 var newhigh = high1 - if (low1 == Double.NegativeInfinity.toInt) newlow = low2 - if (high1 == Double.PositiveInfinity.toInt) newhigh = high2 + if (low1 == Int.MinValue) newlow = low2 + if (high1 == Int.MaxValue) newhigh = high2 Interval(newlow,newhigh) } }), this.isEmpty && that.isEmpty) diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala index 16cdce73..28a1a091 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala @@ -45,10 +45,30 @@ class BoxDomainCore extends CompleteLatticeOperator[Box] case (_, IntervalBottom) => IntervalBottom case (IntervalTop, _) => IntervalTop case (_, IntervalTop) => IntervalTop - case (Interval(low1, high1), Interval(low2,high2)) => Interval((low1 + low2), (high1 + high2)) + case (Interval(low1, high1), Interval(low2,high2)) => + + /*if (low1 == Int.MinValue || low2 == Int.MinValue) + Interval(Int.MinValue, high1 + high2) + + else if (high1 == Int.MaxValue || high2 == Int.MaxValue) { + print("DFASDFAFKJAHSDHKFJ") + Interval(low1 + low2, Int.MaxValue) + }*/ + + Interval(safeSum(low1,low2), safeSum(high1,high2)) } } + private def safeSum(left : Int, right : Int) : Int = { + if (right > 0 && left > Int.MaxValue - right) + return Int.MaxValue + + if (right < 0 && left < Int.MinValue - right) + return Int.MinValue + + return left + right + } + /** * @inheritdoc */ @@ -87,18 +107,20 @@ class BoxDomainCore extends CompleteLatticeOperator[Box] case (IntervalTop, _) => IntervalTop case (_, IntervalTop) => IntervalTop case (Interval (low1, high1), Interval (low2,high2)) => - if (low2 >=1){ + if (low2 >= 1) { val new_low = (low1 / low2) min (low1 / high2) val new_high = (high1 / low2) max (high1 / high2) Interval (new_low, new_high) + } else if (high2 <= -1) { val new_low = (high1 / low2) min (high1 / high2) val new_high = (low1 / low2) max (low1 / high2) Interval (new_low, new_high) + } else { // TODO: MODELLARE L'INFINITO "INTERO" Interval(1,1) - //lub(division(Interval (low1, high1), glb(Interval (low2,high2), Interval(1,Double.PositiveInfinity)), division(Interval (low1, high1), glb(Interval (low2,high2), Interval(Double.NegativeInfinity, -1))))) + //lub(division(Interval (low1, high1), glb(Interval (low2,high2), Interval(1,Int.MaxValue)), division(Interval (low1, high1), glb(Interval (low2,high2), Interval(Int.MinValue, -1))))) } } } From 07c5f1c4fee02a9150a9ff0f4b45dc5c73b4dde7 Mon Sep 17 00:00:00 2001 From: Mou95 Date: Tue, 20 Mar 2018 08:41:37 +0100 Subject: [PATCH 54/99] Trying to implement infinity --- .../jandom/domains/numerical/box/Box.scala | 17 ++- .../domains/numerical/box/BoxDomainCore.scala | 120 ++++++++++++++++-- 2 files changed, 121 insertions(+), 16 deletions(-) diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/Box.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/Box.scala index 8219938d..bd0e760f 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/Box.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/Box.scala @@ -30,16 +30,23 @@ object Box { // interval case class Interval (low : Int, high : Int) extends Box { - override def toString : String = { - if (low == Int.MinValue) return "= [" + "-\u221E" + "," + high + "]" - else if (high == Int.MaxValue) return "= [" + low + "," + "+\u221E" + "]" - return "= [" + low + "," + high + "]" - } + override def toString : String = "= [" + low + "," + high + "]" + } + + // represent an interval with the lower bound = -infinity + case class IntervalNegative (high : Int) extends Box { + override def toString : String = "= [" + "-\u221E" + "," + high + "]" + } + + // represent an interval with the upper bound = +infinity + case class IntervalPositive (low : Int) extends Box { + override def toString : String = "= [" + low + "," + "+\u221E" + "]" } // no accurate info available for variable case object IntervalTop extends Box { override def toString : String = "= \u22a4" } + // no possible value case object IntervalBottom extends Box { override def toString: String = "= \u22a5" diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala index 28a1a091..83a5731f 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala @@ -45,17 +45,38 @@ class BoxDomainCore extends CompleteLatticeOperator[Box] case (_, IntervalBottom) => IntervalBottom case (IntervalTop, _) => IntervalTop case (_, IntervalTop) => IntervalTop - case (Interval(low1, high1), Interval(low2,high2)) => + case (IntervalNegative(_), IntervalPositive(_)) => IntervalTop + case (IntervalNegative(high1), IntervalNegative(high2)) => + val res = safeSum(high1, high2) + //[-inifinity,-infinity] = T + if (res < Int.MaxValue && res > Int.MinValue ) + return IntervalNegative(res) + return IntervalTop - /*if (low1 == Int.MinValue || low2 == Int.MinValue) - Interval(Int.MinValue, high1 + high2) + case(IntervalNegative(high1), Interval(low2,high2)) => + val res = safeSum(high1, high2) + //[-inifinity,-infinity] = T + if (res < Int.MaxValue && res > Int.MinValue ) + return IntervalNegative(res) + return IntervalTop - else if (high1 == Int.MaxValue || high2 == Int.MaxValue) { - print("DFASDFAFKJAHSDHKFJ") - Interval(low1 + low2, Int.MaxValue) - }*/ + case(IntervalPositive(_), IntervalNegative(_)) => IntervalTop - Interval(safeSum(low1,low2), safeSum(high1,high2)) + case(IntervalPositive(low1), IntervalPositive(low2)) => + val res = safeSum(low1, low2) + if (res < Int.MaxValue && res > Int.MinValue) + return IntervalPositive(res) + return IntervalTop + + case(IntervalPositive(low1), Interval(low2,high2)) => + val res = safeSum(low1, low2) + if (res < Int.MaxValue && res > Int.MinValue) + return IntervalPositive(res) + return IntervalTop + + case (Interval(low1, high1), Interval(low2,high2)) => Interval(safeSum(low1,low2), safeSum(high1,high2)) + + case(_,_) => sum(y,x) //due casi mancanti } } @@ -73,29 +94,106 @@ class BoxDomainCore extends CompleteLatticeOperator[Box] * @inheritdoc */ def inverse(x : Box) : Box = { + print("INVERSE") x match { case (IntervalBottom) => IntervalBottom case (IntervalTop) => IntervalTop - case (Interval (low, high)) => Interval (-high, -low) + case (IntervalNegative(high)) => IntervalPositive(-high) + case (IntervalPositive(low)) => + if (low == Int.MinValue) + return IntervalTop + return IntervalNegative(-low) + case (Interval(low,high)) => + if (low == Int.MinValue) + IntervalPositive(-high) + Interval(-high,-low) } } /** * @inheritdoc - */ + def mult(x : Box, y : Box) : Box = { (x,y) match { case (IntervalBottom, _) => IntervalBottom case (_, IntervalBottom) => IntervalBottom case (IntervalTop, _) => IntervalTop case (_, IntervalTop) => IntervalTop + case (IntervalNegative(_), IntervalPositive(_)) => IntervalTop + case (IntervalPositive(_), IntervalNegative(_)) => IntervalTop + case (IntervalNegative(high1), IntervalNegative(high2)) => + val res = safeMult(high1,high2) + if (res < Int.MaxValue && res > Int.MinValue) + return IntervalPositive(res) + return IntervalTop + + case(IntervalNegative(high1), Interval(low2,high2)) => + val res = Array(safeMult(high1,low2), safeMult(high1,high2)) + val min_res = res.reduceLeft(_ min _) + val max_res = res.reduceLeft(_ max _) + + if (low2 < 0) { + if (min_res < Int.MaxValue && min_res > Int.MinValue) + return IntervalPositive(min_res) + return IntervalTop + } + if (low2 > 0) { + if (high1 > 0) + } + if (res < Int.MaxValue && res > Int.MinValue) + return IntervalTop + return IntervalPositive(res) + + case(IntervalPositive(low1), IntervalPositive(low2)) => + + + case(IntervalPositive(low1), Interval(low2,high2)) => + case (Interval (low1, high1), Interval (low2,high2)) => - val comb = Array(low1 * low2, high1 * high2, low1 * high2, high1 * low2) + val comb = Array(safeMult(low1, low2), safeMult(high1, high2), safeMult(low1, high2), safeMult(high1, low2)) val new_low = comb.reduceLeft(_ min _) val new_high = comb.reduceLeft(_ max _) Interval (new_low, new_high) } } +*/ + +def mult(x : Box, y : Box) : Box = { + var bounds = Array(projectLow(x),projectHigh(x),projectLow(y),projectHigh(y)) + for(i <- bounds.indices){ + if(bounds(i).toInt == Int.MinValue) bounds(i) = Double.NegativeInfinity + else if(bounds(i).toInt == Int.MaxValue) bounds(i) = Double.PositiveInfinity + } + var comb = Array(bounds(0)*bounds(2),bounds(0)*bounds(3),bounds(1)*bounds(2),bounds(1)*bounds(3)) + var left = comb.reduceLeft(_ min _) + var right = comb.reduceLeft(_ max _) + if(left == Double.NegativeInfinity && (right == Double.PositiveInfinity || right == Double.NegativeInfinity)) return IntervalTop + if(left == Double.NegativeInfinity) return IntervalNegative(right.toInt) + + +} + private def safeMult(left : Int, right : Int) : Int = { + print(" LEFT "+left+" RIGHt "+right) + if (right > 0) { + if (left > Int.MaxValue / right) + return Int.MaxValue + if (left < Int.MinValue / right) + return Int.MinValue + } + else if (right < -1) { + if (left > Int.MinValue / right) + return Int.MinValue + if (left < Int.MaxValue / right) + return Int.MaxValue + } + else if (right == -1) { + if (left == Int.MinValue) + return Int.MaxValue + if (left == Int.MaxValue) + return Int.MinValue + } + return left * right + } /** * @inheritdoc From 1272d77e126abdd1f7f6fefcc7bf11fd0def66e0 Mon Sep 17 00:00:00 2001 From: BottCode Date: Tue, 20 Mar 2018 21:35:44 +0100 Subject: [PATCH 55/99] Working on Infinity Int --- .../it/unipd/jandom/domains/InfInt.scala | 124 +++++++++ .../jandom/domains/numerical/box/Box.scala | 7 +- .../domains/numerical/box/BoxDomain.scala | 45 ++-- .../domains/numerical/box/BoxDomainCore.scala | 242 +++++++----------- 4 files changed, 250 insertions(+), 168 deletions(-) create mode 100644 core/src/main/scala/it/unipd/jandom/domains/InfInt.scala diff --git a/core/src/main/scala/it/unipd/jandom/domains/InfInt.scala b/core/src/main/scala/it/unipd/jandom/domains/InfInt.scala new file mode 100644 index 00000000..c25e4d63 --- /dev/null +++ b/core/src/main/scala/it/unipd/jandom/domains/InfInt.scala @@ -0,0 +1,124 @@ +/** + * Copyright 2018 Mattia Bottaro, Mauro Carlin + * + * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains + * JANDOM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * JANDOM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of a + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You shosuld have received a copy of the GNU General Public License + * along with JANDOM. If not, see . + */ +package it.unipd.jandom.domains + +/* +final abstract class InfInt(val self: Any) private extends AnyVal { + + def +(val x: NegativeInfinity()): InfInt = self match { + case NegativeInfinity()=> return InfInt(x) + case PositiveInfinity() => return InfInt(-1) // dobbiamo ritornare una forma indeterminata + case Int => return NegativeInfinity() + } + + def +(valx: PositiveInfinity()): InfInt + +}*/ + +trait InfInt{ + def +(x: InfInt): InfInt + def >(x: InfInt): Boolean + def -(x: InfInt): InfInt + def /(x: InfInt): InfInt + def >=(x: InfInt): Boolean + def <=(x: InfInt): InfInt + def max(x: InfInt): InfInt + def min(x: InfInt): InfInt +} + +case class IntNumber(n: Int) extends InfInt { + + def +(x: InfInt): InfInt = { + x match { + case NegativeInfinity() => return NegativeInfinity() + case PositiveInfinity() => return PositiveInfinity() + case Undetermined() => return Undetermined() + case IntNumber(x) => return safeAdd(n,x) + } + } + + def >(x: InfInt): Boolean = { + x match { + case PositiveInfinity() => return false + case IntNumber(x) => return n > x + case _ => true + } + } + + def safeAdd(left: Int, right: Int): InfInt = { + // require(left should be anIstanceOf[Int]) + if (right > 0 && left > Int.MaxValue - right) + return PositiveInfinity() + if (right < 0 && left < Int.MinValue - right) + return NegativeInfinity() + return IntNumber(left + right) + } + +} + +case class NegativeInfinity() extends InfInt { + def +(x: InfInt): InfInt = { + x match { + case PositiveInfinity() => return Undetermined() + case Undetermined() => return Undetermined() + case _ => NegativeInfinity() + } + } + + def >(x: InfInt): Boolean = { + x match { + case NegativeInfinity() => return false + case Undetermined() => return false + case _ => true + } + } + +} + +case class PositiveInfinity() extends InfInt { + def +(x: InfInt): InfInt = { + x match { + case NegativeInfinity()=> return Undetermined() + case Undetermined() => return Undetermined() + case _ => return PositiveInfinity() + } + } + + def >(x: InfInt): Boolean = { + x match { + case NegativeInfinity() => return true + case Undetermined() => return true + case _ => false + } + } + +} + +// case infinity - infinity +case class Undetermined() extends InfInt { + def +(x: InfInt): InfInt = { + Undetermined() + } + + def >(x:InfInt): Boolean = { + x match { + case _ => false + } + } + +} diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/Box.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/Box.scala index bd0e760f..90e0537b 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/Box.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/Box.scala @@ -16,6 +16,7 @@ * along with JANDOM. If not, see . */ package it.unipd.jandom.domains.numerical.box +import it.unipd.jandom.domains.InfInt /** * The elements of the constant domain. @@ -29,17 +30,17 @@ object Box { sealed trait Box // interval - case class Interval (low : Int, high : Int) extends Box { + case class Interval (low : InfInt, high : InfInt) extends Box { override def toString : String = "= [" + low + "," + high + "]" } // represent an interval with the lower bound = -infinity - case class IntervalNegative (high : Int) extends Box { + case class IntervalNegative (high : InfInt) extends Box { override def toString : String = "= [" + "-\u221E" + "," + high + "]" } // represent an interval with the upper bound = +infinity - case class IntervalPositive (low : Int) extends Box { + case class IntervalPositive (low : InfInt) extends Box { override def toString : String = "= [" + low + "," + "+\u221E" + "]" } // no accurate info available for variable diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala index 50e969ed..39134d73 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala @@ -21,7 +21,7 @@ import it.unich.jandom.domains.numerical.LinearForm import it.unipd.jandom.domains.numerical.BaseNumericalDomain import it.unipd.jandom.domains.numerical.box.Box._ import it.unipd.jandom.domains.numerical.box.BoxDomainCore._ - +import it.unipd.jandom.domains.{InfInt, PositiveInfinity, NegativeInfinity, IntNumber} /** * Box Domain ... @TODO a better explanation is required @@ -44,18 +44,18 @@ class BoxDomain extends BaseNumericalDomain[Box, BoxDomainCore](BoxDomainCore()) */ class Property (boxes : Array[Box], unreachable: Boolean) extends BaseProperty(boxes, unreachable) { - def projectLow (box : Box) : Int = { + def projectLow (box : Box) : InfInt = { box match { - case IntervalBottom => Int.MaxValue - case IntervalTop => Int.MinValue + case IntervalBottom => PositiveInfinity() + case IntervalTop => NegativeInfinity() case Interval(low,high) => low } } - def projectHigh (box : Box) : Int = { + def projectHigh (box : Box) : InfInt = { box match { - case IntervalBottom => Int.MinValue - case IntervalTop => Int.MaxValue + case IntervalBottom => NegativeInfinity() + case IntervalTop => PositiveInfinity() case Interval(low,high) => high } } @@ -87,13 +87,13 @@ class BoxDomain extends BaseNumericalDomain[Box, BoxDomainCore](BoxDomainCore()) val lowresult = projectLow(linearEvaluation(lf)) val lfArgmin = linearArgmin(lf); print(lowresult) - if (lowresult > 0) - bottom + if (lowresult > IntNumber(0)) + return bottom else { var newboxes = boxes.clone for (i <- homcoeffs.indices) { - if (homcoeffs(i) < 0) newboxes(i) = Interval(projectLow(boxes(i)) max (lfArgmin(i) - (lowresult / homcoeffs(i)).toInt), projectHigh(newboxes(i))) - if (homcoeffs(i) > 0) newboxes(i) = Interval(projectLow(newboxes(i)), projectHigh(boxes(i)) min (lfArgmin(i) - (lowresult / homcoeffs(i)).toInt)) + if (homcoeffs(i) < 0) newboxes(i) = Interval(projectLow(boxes(i)) max (lfArgmin(i) - (lowresult / IntNumber(homcoeffs(i).toInt))), projectHigh(newboxes(i))) + if (homcoeffs(i) > 0) newboxes(i) = Interval(projectLow(newboxes(i)), projectHigh(boxes(i)) min (lfArgmin(i) - (lowresult / IntNumber(homcoeffs(i).toInt)))) } for (i <- newboxes.indices) print("boxes:",newboxes(i)) @@ -101,7 +101,7 @@ class BoxDomain extends BaseNumericalDomain[Box, BoxDomainCore](BoxDomainCore()) } } - private def linearArgmin(lf: LinearForm): Seq[Int] = { + private def linearArgmin(lf: LinearForm): Seq[InfInt] = { (lf.homcoeffs.zipWithIndex) map { case (c, i) => if (c > 0) projectLow(boxes(i)) else projectHigh(boxes(i)) } @@ -116,10 +116,19 @@ class BoxDomain extends BaseNumericalDomain[Box, BoxDomainCore](BoxDomainCore()) case (_ , IntervalTop) => IntervalTop case (Interval(low1, high1), Interval(low2,high2)) => // TODO - var newlow = Int.MinValue - var newhigh = Int.MaxValue - if (low1 <= low2) newlow = low1 - if (high1 >= high2) newhigh = high1 + var newhigh = high1 + var newlow = low1 + + if (low2 >= low1) + newlow = low1 + else + newlow = NegativeInfinity() + + if (high1 >= high2) + newhigh = high1 + else + newhigh = PositiveInfinity() + Interval(newlow,newhigh) } }), this.isEmpty && that.isEmpty) @@ -136,8 +145,8 @@ class BoxDomain extends BaseNumericalDomain[Box, BoxDomainCore](BoxDomainCore()) // TODO var newlow = low1 var newhigh = high1 - if (low1 == Int.MinValue) newlow = low2 - if (high1 == Int.MaxValue) newhigh = high2 + if (low1 == NegativeInfinity()) newlow = low2 + if (high1 == PositiveInfinity()) newhigh = high2 Interval(newlow,newhigh) } }), this.isEmpty && that.isEmpty) diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala index 83a5731f..759fb061 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala @@ -19,7 +19,7 @@ package it.unipd.jandom.domains.numerical.box import it.unipd.jandom.domains.numerical.utils.{MathLibrary => M} -import it.unipd.jandom.domains.{Abstraction, CompleteLatticeOperator, IntOperator} +import it.unipd.jandom.domains.{Abstraction, CompleteLatticeOperator, IntOperator, InfInt, IntNumber} import Box._ /** @@ -29,12 +29,12 @@ import Box._ // TODO: define reminder function class BoxDomainCore extends CompleteLatticeOperator[Box] - with IntOperator[Box] with Abstraction[Int,Box]{ + with IntOperator[Box] with Abstraction[InfInt,Box]{ /** * @inheritdoc */ - def alpha(num : Int) : Box = Interval(num,num) + def alpha(num : Int) : Box = Interval(IntNumber(num),IntNumber(num)) /** * @inheritdoc @@ -45,74 +45,35 @@ class BoxDomainCore extends CompleteLatticeOperator[Box] case (_, IntervalBottom) => IntervalBottom case (IntervalTop, _) => IntervalTop case (_, IntervalTop) => IntervalTop - case (IntervalNegative(_), IntervalPositive(_)) => IntervalTop - case (IntervalNegative(high1), IntervalNegative(high2)) => - val res = safeSum(high1, high2) - //[-inifinity,-infinity] = T - if (res < Int.MaxValue && res > Int.MinValue ) - return IntervalNegative(res) - return IntervalTop - - case(IntervalNegative(high1), Interval(low2,high2)) => - val res = safeSum(high1, high2) - //[-inifinity,-infinity] = T - if (res < Int.MaxValue && res > Int.MinValue ) - return IntervalNegative(res) - return IntervalTop - - case(IntervalPositive(_), IntervalNegative(_)) => IntervalTop - - case(IntervalPositive(low1), IntervalPositive(low2)) => - val res = safeSum(low1, low2) - if (res < Int.MaxValue && res > Int.MinValue) - return IntervalPositive(res) - return IntervalTop - - case(IntervalPositive(low1), Interval(low2,high2)) => - val res = safeSum(low1, low2) - if (res < Int.MaxValue && res > Int.MinValue) - return IntervalPositive(res) - return IntervalTop - - case (Interval(low1, high1), Interval(low2,high2)) => Interval(safeSum(low1,low2), safeSum(high1,high2)) - - case(_,_) => sum(y,x) //due casi mancanti + case (Interval(low1,high1),Interval(low2,high2)) => Interval(low1.+(low2), high1.+(high2)) } } - private def safeSum(left : Int, right : Int) : Int = { - if (right > 0 && left > Int.MaxValue - right) - return Int.MaxValue - - if (right < 0 && left < Int.MinValue - right) - return Int.MinValue - - return left + right - } - /** * @inheritdoc */ def inverse(x : Box) : Box = { - print("INVERSE") - x match { - case (IntervalBottom) => IntervalBottom - case (IntervalTop) => IntervalTop - case (IntervalNegative(high)) => IntervalPositive(-high) - case (IntervalPositive(low)) => - if (low == Int.MinValue) - return IntervalTop - return IntervalNegative(-low) - case (Interval(low,high)) => - if (low == Int.MinValue) - IntervalPositive(-high) - Interval(-high,-low) - } + x + // print("INVERSE") + // x match { + // case (IntervalBottom) => IntervalBottom + // case (IntervalTop) => IntervalTop + // case (IntervalNegative(high)) => IntervalPositive(-high) + // case (IntervalPositive(low)) => + // if (low == InfInt.MinValue) + // return IntervalTop + // return IntervalNegative(-low) + // case (Interval(low,high)) => + // if (low == InfInt.MinValue) + // IntervalPositive(-high) + // Interval(-high,-low) + // } } /** * @inheritdoc - + */ + /* def mult(x : Box, y : Box) : Box = { (x,y) match { case (IntervalBottom, _) => IntervalBottom @@ -123,7 +84,7 @@ class BoxDomainCore extends CompleteLatticeOperator[Box] case (IntervalPositive(_), IntervalNegative(_)) => IntervalTop case (IntervalNegative(high1), IntervalNegative(high2)) => val res = safeMult(high1,high2) - if (res < Int.MaxValue && res > Int.MinValue) + if (res < InfInt.MaxValue && res > InfInt.MinValue) return IntervalPositive(res) return IntervalTop @@ -133,14 +94,14 @@ class BoxDomainCore extends CompleteLatticeOperator[Box] val max_res = res.reduceLeft(_ max _) if (low2 < 0) { - if (min_res < Int.MaxValue && min_res > Int.MinValue) + if (min_res < InfInt.MaxValue && min_res > InfInt.MinValue) return IntervalPositive(min_res) return IntervalTop } if (low2 > 0) { if (high1 > 0) } - if (res < Int.MaxValue && res > Int.MinValue) + if (res < InfInt.MaxValue && res > InfInt.MinValue) return IntervalTop return IntervalPositive(res) @@ -157,12 +118,12 @@ class BoxDomainCore extends CompleteLatticeOperator[Box] } } */ - +/* def mult(x : Box, y : Box) : Box = { var bounds = Array(projectLow(x),projectHigh(x),projectLow(y),projectHigh(y)) for(i <- bounds.indices){ - if(bounds(i).toInt == Int.MinValue) bounds(i) = Double.NegativeInfinity - else if(bounds(i).toInt == Int.MaxValue) bounds(i) = Double.PositiveInfinity + if(bounds(i).toInt == InfInt.MinValue) bounds(i) = Double.NegativeInfinity + else if(bounds(i).toInt == InfInt.MaxValue) bounds(i) = Double.PositiveInfinity } var comb = Array(bounds(0)*bounds(2),bounds(0)*bounds(3),bounds(1)*bounds(2),bounds(1)*bounds(3)) var left = comb.reduceLeft(_ min _) @@ -172,55 +133,39 @@ def mult(x : Box, y : Box) : Box = { } - private def safeMult(left : Int, right : Int) : Int = { - print(" LEFT "+left+" RIGHt "+right) - if (right > 0) { - if (left > Int.MaxValue / right) - return Int.MaxValue - if (left < Int.MinValue / right) - return Int.MinValue - } - else if (right < -1) { - if (left > Int.MinValue / right) - return Int.MinValue - if (left < Int.MaxValue / right) - return Int.MaxValue - } - else if (right == -1) { - if (left == Int.MinValue) - return Int.MaxValue - if (left == Int.MaxValue) - return Int.MinValue - } - return left * right +*/ + + def mult(x : Box, y : Box) : Box = { + x } /** * @inheritdoc */ def division(x : Box, y : Box) : Box = { - (x,y) match { - case (IntervalBottom, _) => IntervalBottom - case (_, IntervalBottom) => IntervalBottom - case (IntervalTop, _) => IntervalTop - case (_, IntervalTop) => IntervalTop - case (Interval (low1, high1), Interval (low2,high2)) => - if (low2 >= 1) { - val new_low = (low1 / low2) min (low1 / high2) - val new_high = (high1 / low2) max (high1 / high2) - Interval (new_low, new_high) - - } else if (high2 <= -1) { - val new_low = (high1 / low2) min (high1 / high2) - val new_high = (low1 / low2) max (low1 / high2) - Interval (new_low, new_high) - - } else { - // TODO: MODELLARE L'INFINITO "INTERO" - Interval(1,1) - //lub(division(Interval (low1, high1), glb(Interval (low2,high2), Interval(1,Int.MaxValue)), division(Interval (low1, high1), glb(Interval (low2,high2), Interval(Int.MinValue, -1))))) - } - } + x + // (x,y) match { + // case (IntervalBottom, _) => IntervalBottom + // case (_, IntervalBottom) => IntervalBottom + // case (IntervalTop, _) => IntervalTop + // case (_, IntervalTop) => IntervalTop + // case (Interval (low1, high1), Interval (low2,high2)) => + // if (low2 >= 1) { + // val new_low = (low1 / low2) min (low1 / high2) + // val new_high = (high1 / low2) max (high1 / high2) + // Interval (new_low, new_high) + + // } else if (high2 <= -1) { + // val new_low = (high1 / low2) min (high1 / high2) + // val new_high = (low1 / low2) max (low1 / high2) + // Interval (new_low, new_high) + + // } else { + // // TODO: MODELLARE L'INFINITO "INTERO" + // Interval(1,1) + // //lub(division(Interval (low1, high1), glb(Interval (low2,high2), Interval(1,InfInt.MaxValue)), division(Interval (low1, high1), glb(Interval (low2,high2), Interval(InfInt.MinValue, -1))))) + // } + // } } //TODO @@ -232,55 +177,58 @@ def mult(x : Box, y : Box) : Box = { * @inheritdoc */ def lub(x : Box, y : Box) : Box = { - (x, y) match { - case (IntervalTop, _) => IntervalTop - case (_, IntervalTop) => IntervalTop - case (IntervalBottom, _) => y - case (_, IntervalBottom) => x - case (Interval (low1, high1), Interval (low2, high2)) => - val new_low = low1 min low2 - val new_high = high1 max high2 - Interval (new_low, new_high) - } + x + // (x, y) match { + // case (IntervalTop, _) => IntervalTop + // case (_, IntervalTop) => IntervalTop + // case (IntervalBottom, _) => y + // case (_, IntervalBottom) => x + // case (Interval (low1, high1), Interval (low2, high2)) => + // val new_low = low1 min low2 + // val new_high = high1 max high2 + // Interval (new_low, new_high) + // } } /** * @inheritdoc */ def glb(x : Box, y : Box) : Box = { - (x, y) match { - case (IntervalTop, _) => y - case (_, IntervalTop) => x - case (IntervalBottom, _) => IntervalBottom - case (_, IntervalBottom) => IntervalBottom - case (Interval (low1, high1), Interval (low2, high2)) => - val new_low = low1 max low2 - val new_high = high1 min high2 - if (new_low > new_high) IntervalBottom else Interval (new_low, new_high) - } + x + // (x, y) match { + // case (IntervalTop, _) => y + // case (_, IntervalTop) => x + // case (IntervalBottom, _) => IntervalBottom + // case (_, IntervalBottom) => IntervalBottom + // case (Interval (low1, high1), Interval (low2, high2)) => + // val new_low = low1 max low2 + // val new_high = high1 min high2 + // if (new_low > new_high) IntervalBottom else Interval (new_low, new_high) + // } } /** * @inheritdoc */ - def compare(x : Box, y : Box) : Option[Int] = { - (x, y) match { - case (IntervalBottom, IntervalBottom) => Option(0) - case (IntervalBottom, _) => Option(-1) - case (_, IntervalBottom) => Option(1) - case (IntervalTop, IntervalTop) => Option(0) - case (IntervalTop, _) => Option(1); - case (_, IntervalTop) => Option(-1); - case (Interval(low1, high1), Interval(low2, high2)) => - if (low1 == low2 && high1 == high2) - Option(0) - else if (low1 >= low2 && high1 <= high2) - Option(-1) - else if (low2 >= low1 && high2 <= high1) - Option(1) - else - Option.empty - } + def compare(x : Box, y : Box) : Option[InfInt] = { + x + // (x, y) match { + // case (IntervalBottom, IntervalBottom) => Option(0) + // case (IntervalBottom, _) => Option(-1) + // case (_, IntervalBottom) => Option(1) + // case (IntervalTop, IntervalTop) => Option(0) + // case (IntervalTop, _) => Option(1); + // case (_, IntervalTop) => Option(-1); + // case (Interval(low1, high1), Interval(low2, high2)) => + // if (low1 == low2 && high1 == high2) + // Option(0) + // else if (low1 >= low2 && high1 <= high2) + // Option(-1) + // else if (low2 >= low1 && high2 <= high1) + // Option(1) + // else + // Option.empty + // } } /** From bc777b0959e90b47396c061c30ad369ac2b92117 Mon Sep 17 00:00:00 2001 From: BottCode Date: Tue, 20 Mar 2018 21:58:36 +0100 Subject: [PATCH 56/99] still working on Int Infinity --- .../scala/it/unipd/jandom/domains/InfInt.scala | 17 +++++++++++++++-- .../domains/numerical/box/BoxDomainCore.scala | 4 ++-- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/core/src/main/scala/it/unipd/jandom/domains/InfInt.scala b/core/src/main/scala/it/unipd/jandom/domains/InfInt.scala index c25e4d63..ec4b4a76 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/InfInt.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/InfInt.scala @@ -33,12 +33,25 @@ final abstract class InfInt(val self: Any) private extends AnyVal { trait InfInt{ def +(x: InfInt): InfInt def >(x: InfInt): Boolean - def -(x: InfInt): InfInt def /(x: InfInt): InfInt def >=(x: InfInt): Boolean def <=(x: InfInt): InfInt def max(x: InfInt): InfInt def min(x: InfInt): InfInt + + def inverse(x: InfInt): InfInt = { + x match { + case PositiveInfinity() => return NegativeInfinity() + case NegativeInfinity() => return PositiveInfinity() + case IntNumber(x) => return IntNumber(-x) + case _ => return Undetermined() + } + } + + def -(x: InfInt): InfInt = { + return this.+(inverse(x)) + } + } case class IntNumber(n: Int) extends InfInt { @@ -56,7 +69,7 @@ case class IntNumber(n: Int) extends InfInt { x match { case PositiveInfinity() => return false case IntNumber(x) => return n > x - case _ => true + case _ => return true } } diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala index 759fb061..066edac5 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala @@ -210,8 +210,8 @@ def mult(x : Box, y : Box) : Box = { /** * @inheritdoc */ - def compare(x : Box, y : Box) : Option[InfInt] = { - x + def compare(x : Box, y : Box) : Option[Int] = { + Option(0) // (x, y) match { // case (IntervalBottom, IntervalBottom) => Option(0) // case (IntervalBottom, _) => Option(-1) From 383be69c073949a5ee589f830aa58f435cd8b01f Mon Sep 17 00:00:00 2001 From: BottCode Date: Tue, 20 Mar 2018 23:32:35 +0100 Subject: [PATCH 57/99] more InfInt method are now defined --- .../it/unipd/jandom/domains/InfInt.scala | 113 ++++++++++++++++-- 1 file changed, 106 insertions(+), 7 deletions(-) diff --git a/core/src/main/scala/it/unipd/jandom/domains/InfInt.scala b/core/src/main/scala/it/unipd/jandom/domains/InfInt.scala index ec4b4a76..83227c83 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/InfInt.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/InfInt.scala @@ -34,10 +34,10 @@ trait InfInt{ def +(x: InfInt): InfInt def >(x: InfInt): Boolean def /(x: InfInt): InfInt - def >=(x: InfInt): Boolean - def <=(x: InfInt): InfInt + // def <=(x: InfInt): InfInt def max(x: InfInt): InfInt def min(x: InfInt): InfInt + // def ==(x: InfInt): InfInt // TODO def inverse(x: InfInt): InfInt = { x match { @@ -52,6 +52,10 @@ trait InfInt{ return this.+(inverse(x)) } + def >=(x: InfInt): Boolean = { + return this.>(x.+(IntNumber(1))) + } + } case class IntNumber(n: Int) extends InfInt { @@ -73,6 +77,39 @@ case class IntNumber(n: Int) extends InfInt { } } + def /(x: InfInt): InfInt = { + x match { + case IntNumber(x) => + if (x != 0) + return IntNumber(n / x) + if (n > 0) // && x == 0 + return PositiveInfinity() + else if (n < 0) + return NegativeInfinity() + return IntNumber(0) + case Undetermined() => return Undetermined() + case _ => IntNumber(0) + } + } + + def max(x: InfInt): InfInt = { + x match { + case IntNumber(x) => return IntNumber(n max x) + case PositiveInfinity() => return PositiveInfinity() + case NegativeInfinity() => return IntNumber(n) + case _ => return Undetermined() + } + } + + def min(x: InfInt): InfInt = { + x match { + case IntNumber(x) => return IntNumber(n min x) + case PositiveInfinity() => return IntNumber(n) + case NegativeInfinity() => return NegativeInfinity() + case _ => return Undetermined() + } + } + def safeAdd(left: Int, right: Int): InfInt = { // require(left should be anIstanceOf[Int]) if (right > 0 && left > Int.MaxValue - right) @@ -99,8 +136,34 @@ case class NegativeInfinity() extends InfInt { case Undetermined() => return false case _ => true } + } + + def /(x: InfInt): InfInt = { + x match { + case IntNumber(x) => + if(x < 0) + return PositiveInfinity() + return NegativeInfinity() + case _ => return Undetermined() + } } + def max(x: InfInt): InfInt = { + x match { + case IntNumber(x) => return IntNumber(x) + case PositiveInfinity() => return PositiveInfinity() + case NegativeInfinity() => return NegativeInfinity() + case _ => Undetermined() + } + } + + def min(x: InfInt): InfInt = { + x match { + case Undetermined() => return Undetermined() + case _ => return NegativeInfinity() + } + } + } case class PositiveInfinity() extends InfInt { @@ -118,20 +181,56 @@ case class PositiveInfinity() extends InfInt { case Undetermined() => return true case _ => false } - } + } + + def /(x: InfInt): InfInt = { + x match { + case IntNumber(x) => + if(x < 0) + return NegativeInfinity() + return PositiveInfinity() + case _ => return Undetermined() + } + } + + def max(x: InfInt): InfInt = { + x match { + case Undetermined() => Undetermined() + case _ => PositiveInfinity() + } + } + + def min(x: InfInt): InfInt = { + x match { + case Undetermined() => return Undetermined() + case NegativeInfinity() => return NegativeInfinity() + case PositiveInfinity() => return PositiveInfinity() + case IntNumber(x) => return IntNumber(x) + } + } } // case infinity - infinity case class Undetermined() extends InfInt { def +(x: InfInt): InfInt = { - Undetermined() + return Undetermined() } def >(x:InfInt): Boolean = { - x match { - case _ => false - } + return false + } + + def /(x: InfInt): InfInt = { + return Undetermined() + } + + def max(x: InfInt): InfInt = { + Undetermined(); + } + + def min(x: InfInt): InfInt = { + return Undetermined() } } From 71c1b81e464b6c4f23bc72dc11b4894cf8a3fd32 Mon Sep 17 00:00:00 2001 From: BottCode Date: Wed, 21 Mar 2018 12:13:27 +0100 Subject: [PATCH 58/99] Now compile --- .../main/scala/it/unipd/jandom/domains/InfInt.scala | 13 +++++++++++-- .../it/unipd/jandom/domains/numerical/box/Box.scala | 2 +- .../domains/numerical/box/BoxDomainCore.scala | 10 +++++++--- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/core/src/main/scala/it/unipd/jandom/domains/InfInt.scala b/core/src/main/scala/it/unipd/jandom/domains/InfInt.scala index 83227c83..34e26a6e 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/InfInt.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/InfInt.scala @@ -61,6 +61,7 @@ trait InfInt{ case class IntNumber(n: Int) extends InfInt { def +(x: InfInt): InfInt = { + print("IntNumber+",n," + ",x) x match { case NegativeInfinity() => return NegativeInfinity() case PositiveInfinity() => return PositiveInfinity() @@ -112,10 +113,16 @@ case class IntNumber(n: Int) extends InfInt { def safeAdd(left: Int, right: Int): InfInt = { // require(left should be anIstanceOf[Int]) - if (right > 0 && left > Int.MaxValue - right) + print("safeadd",left,right) + if (right > 0 && left > Int.MaxValue - right){ + print("Ritorno il positiveInf") return PositiveInfinity() - if (right < 0 && left < Int.MinValue - right) + } + if (right < 0 && left < Int.MinValue - right){ + print("ritnorno il neginf") return NegativeInfinity() + } + print("ritorno: ",left+right) return IntNumber(left + right) } @@ -123,6 +130,7 @@ case class IntNumber(n: Int) extends InfInt { case class NegativeInfinity() extends InfInt { def +(x: InfInt): InfInt = { + print("NegativeInf+",x) x match { case PositiveInfinity() => return Undetermined() case Undetermined() => return Undetermined() @@ -168,6 +176,7 @@ case class NegativeInfinity() extends InfInt { case class PositiveInfinity() extends InfInt { def +(x: InfInt): InfInt = { + print("NegativeInf+",x) x match { case NegativeInfinity()=> return Undetermined() case Undetermined() => return Undetermined() diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/Box.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/Box.scala index 90e0537b..faf9bbc8 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/Box.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/Box.scala @@ -9,7 +9,7 @@ * * JANDOM is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of a - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSEin. See the * GNU General Public License for more details. * * You shosuld have received a copy of the GNU General Public License diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala index 066edac5..fea8ec5b 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala @@ -29,23 +29,27 @@ import Box._ // TODO: define reminder function class BoxDomainCore extends CompleteLatticeOperator[Box] - with IntOperator[Box] with Abstraction[InfInt,Box]{ + with IntOperator[Box] with Abstraction[Int,Box]{ /** * @inheritdoc */ - def alpha(num : Int) : Box = Interval(IntNumber(num),IntNumber(num)) + def alpha(num : Int) : Box = { + print("Astraggo ",num) + return Interval(IntNumber(num),IntNumber(num)) + } /** * @inheritdoc */ def sum(x : Box, y : Box) : Box = { + print("sum",x,y) (x,y) match { case (IntervalBottom, _) => IntervalBottom case (_, IntervalBottom) => IntervalBottom case (IntervalTop, _) => IntervalTop case (_, IntervalTop) => IntervalTop - case (Interval(low1,high1),Interval(low2,high2)) => Interval(low1.+(low2), high1.+(high2)) + case (Interval(low1,high1),Interval(low2,high2)) => Interval(low1 + low2, high1 + high2) } } From 7f523b6a618322aa34535d66fc106e630cfd80c7 Mon Sep 17 00:00:00 2001 From: BottCode Date: Wed, 21 Mar 2018 14:29:44 +0100 Subject: [PATCH 59/99] BoxDomainCore (maybe) done --- .../it/unipd/jandom/domains/InfInt.scala | 120 ++++++++-- .../jandom/domains/numerical/box/Box.scala | 9 - .../domains/numerical/box/BoxDomain.scala | 2 +- .../domains/numerical/box/BoxDomainCore.scala | 209 +++++++----------- 4 files changed, 176 insertions(+), 164 deletions(-) diff --git a/core/src/main/scala/it/unipd/jandom/domains/InfInt.scala b/core/src/main/scala/it/unipd/jandom/domains/InfInt.scala index 34e26a6e..a15092ff 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/InfInt.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/InfInt.scala @@ -17,27 +17,15 @@ */ package it.unipd.jandom.domains -/* -final abstract class InfInt(val self: Any) private extends AnyVal { - - def +(val x: NegativeInfinity()): InfInt = self match { - case NegativeInfinity()=> return InfInt(x) - case PositiveInfinity() => return InfInt(-1) // dobbiamo ritornare una forma indeterminata - case Int => return NegativeInfinity() - } - - def +(valx: PositiveInfinity()): InfInt - -}*/ - -trait InfInt{ +trait InfInt { def +(x: InfInt): InfInt - def >(x: InfInt): Boolean def /(x: InfInt): InfInt - // def <=(x: InfInt): InfInt + def *(x: InfInt): InfInt + def >(x: InfInt): Boolean + // def <=(x: InfInt): InfInt TODO ?? def max(x: InfInt): InfInt def min(x: InfInt): InfInt - // def ==(x: InfInt): InfInt // TODO + def ==(x: InfInt): Boolean def inverse(x: InfInt): InfInt = { x match { @@ -70,6 +58,17 @@ case class IntNumber(n: Int) extends InfInt { } } + def *(x: InfInt): InfInt = { + if(n == 0) return IntNumber(0) + x match { + case IntNumber(x) => return safeMul(n,x) + case Undetermined() => return Undetermined() + case _ => + if(n > 0) return x + return inverse(x) + } + } + def >(x: InfInt): Boolean = { x match { case PositiveInfinity() => return false @@ -93,6 +92,13 @@ case class IntNumber(n: Int) extends InfInt { } } + def ==(x: InfInt): Boolean = { + x match { + case IntNumber(x) => return x == n + case _ => return false + } + } + def max(x: InfInt): InfInt = { x match { case IntNumber(x) => return IntNumber(n max x) @@ -126,6 +132,29 @@ case class IntNumber(n: Int) extends InfInt { return IntNumber(left + right) } + def safeMul(left: Int, right: Int): InfInt = { + if (right > 0) { + if (left > Int.MaxValue / right) + return PositiveInfinity() + if (left < Int.MinValue / right) + return NegativeInfinity() + } + if (right < -1) { + if (left > Int.MinValue / right) + return NegativeInfinity() + if (left < Int.MaxValue / right) + return PositiveInfinity() + } + if (right == -1) { + if (left == Int.MinValue) + return PositiveInfinity() + if (left == Int.MaxValue) + return NegativeInfinity() + } + + return IntNumber(left * right) + } + } case class NegativeInfinity() extends InfInt { @@ -138,7 +167,21 @@ case class NegativeInfinity() extends InfInt { } } - def >(x: InfInt): Boolean = { + def *(x: InfInt): InfInt = { + x match { + case IntNumber(x) => + if (x > 0) + return NegativeInfinity() + if (x < 0) + return PositiveInfinity() + return IntNumber(0) + case Undetermined() => return Undetermined() + case PositiveInfinity() => return NegativeInfinity() + case NegativeInfinity() => return PositiveInfinity() + } + } + + def >(x: InfInt): Boolean = { x match { case NegativeInfinity() => return false case Undetermined() => return false @@ -156,6 +199,13 @@ case class NegativeInfinity() extends InfInt { } } + def ==(x: InfInt): Boolean = { + x match { + case NegativeInfinity() => return true + case _ => return false + } + } + def max(x: InfInt): InfInt = { x match { case IntNumber(x) => return IntNumber(x) @@ -175,6 +225,7 @@ case class NegativeInfinity() extends InfInt { } case class PositiveInfinity() extends InfInt { + def +(x: InfInt): InfInt = { print("NegativeInf+",x) x match { @@ -184,7 +235,21 @@ case class PositiveInfinity() extends InfInt { } } - def >(x: InfInt): Boolean = { + def *(x: InfInt): InfInt = { + x match { + case IntNumber(x) => + if (x > 0) + return PositiveInfinity() + if (x < 0) + return NegativeInfinity() + return IntNumber(0) + case Undetermined() => return Undetermined() + case PositiveInfinity() => return PositiveInfinity() + case NegativeInfinity() => return NegativeInfinity() + } + } + + def >(x: InfInt): Boolean = { x match { case NegativeInfinity() => return true case Undetermined() => return true @@ -192,6 +257,13 @@ case class PositiveInfinity() extends InfInt { } } + def ==(x: InfInt): Boolean = { + x match { + case PositiveInfinity() => return true + case _ => return false + } + } + def /(x: InfInt): InfInt = { x match { case IntNumber(x) => @@ -226,16 +298,24 @@ case class Undetermined() extends InfInt { return Undetermined() } + def *(x: InfInt): InfInt = { + return Undetermined() + } + def >(x:InfInt): Boolean = { return false } + def ==(x: InfInt): Boolean = { + return false + } + def /(x: InfInt): InfInt = { return Undetermined() } def max(x: InfInt): InfInt = { - Undetermined(); + return Undetermined(); } def min(x: InfInt): InfInt = { diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/Box.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/Box.scala index faf9bbc8..0a2cad46 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/Box.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/Box.scala @@ -34,15 +34,6 @@ object Box { override def toString : String = "= [" + low + "," + high + "]" } - // represent an interval with the lower bound = -infinity - case class IntervalNegative (high : InfInt) extends Box { - override def toString : String = "= [" + "-\u221E" + "," + high + "]" - } - - // represent an interval with the upper bound = +infinity - case class IntervalPositive (low : InfInt) extends Box { - override def toString : String = "= [" + low + "," + "+\u221E" + "]" - } // no accurate info available for variable case object IntervalTop extends Box { override def toString : String = "= \u22a4" diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala index 39134d73..aae6c603 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala @@ -71,7 +71,7 @@ class BoxDomain extends BaseNumericalDomain[Box, BoxDomainCore](BoxDomainCore()) val result : Box = linearEvaluation(lf); result match { case IntervalBottom => bottom - case Interval(low,high) => if (low == high && low == 0) bottom else this + case Interval(low,high) => if (low == high && low == IntNumber(0)) bottom else this case _ => this } } diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala index fea8ec5b..230a1e6c 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala @@ -19,7 +19,7 @@ package it.unipd.jandom.domains.numerical.box import it.unipd.jandom.domains.numerical.utils.{MathLibrary => M} -import it.unipd.jandom.domains.{Abstraction, CompleteLatticeOperator, IntOperator, InfInt, IntNumber} +import it.unipd.jandom.domains.{Abstraction, CompleteLatticeOperator, IntOperator, InfInt, IntNumber, PositiveInfinity, NegativeInfinity} import Box._ /** @@ -57,119 +57,60 @@ class BoxDomainCore extends CompleteLatticeOperator[Box] * @inheritdoc */ def inverse(x : Box) : Box = { - x - // print("INVERSE") - // x match { - // case (IntervalBottom) => IntervalBottom - // case (IntervalTop) => IntervalTop - // case (IntervalNegative(high)) => IntervalPositive(-high) - // case (IntervalPositive(low)) => - // if (low == InfInt.MinValue) - // return IntervalTop - // return IntervalNegative(-low) - // case (Interval(low,high)) => - // if (low == InfInt.MinValue) - // IntervalPositive(-high) - // Interval(-high,-low) - // } + print("INVERSE") + x match { + case IntervalBottom => IntervalBottom + case IntervalTop => IntervalTop + case Interval(low,high) => Interval(high.inverse(high),low.inverse(low)) // TODO, bruttino + } } /** * @inheritdoc */ - /* + def mult(x : Box, y : Box) : Box = { (x,y) match { case (IntervalBottom, _) => IntervalBottom case (_, IntervalBottom) => IntervalBottom case (IntervalTop, _) => IntervalTop case (_, IntervalTop) => IntervalTop - case (IntervalNegative(_), IntervalPositive(_)) => IntervalTop - case (IntervalPositive(_), IntervalNegative(_)) => IntervalTop - case (IntervalNegative(high1), IntervalNegative(high2)) => - val res = safeMult(high1,high2) - if (res < InfInt.MaxValue && res > InfInt.MinValue) - return IntervalPositive(res) - return IntervalTop - - case(IntervalNegative(high1), Interval(low2,high2)) => - val res = Array(safeMult(high1,low2), safeMult(high1,high2)) - val min_res = res.reduceLeft(_ min _) - val max_res = res.reduceLeft(_ max _) - - if (low2 < 0) { - if (min_res < InfInt.MaxValue && min_res > InfInt.MinValue) - return IntervalPositive(min_res) - return IntervalTop - } - if (low2 > 0) { - if (high1 > 0) - } - if (res < InfInt.MaxValue && res > InfInt.MinValue) - return IntervalTop - return IntervalPositive(res) - - case(IntervalPositive(low1), IntervalPositive(low2)) => - - - case(IntervalPositive(low1), Interval(low2,high2)) => - - case (Interval (low1, high1), Interval (low2,high2)) => - val comb = Array(safeMult(low1, low2), safeMult(high1, high2), safeMult(low1, high2), safeMult(high1, low2)) + case (Interval(low1,high1),Interval(low2,high2)) => + val comb = Array(low1 * low2, high1 * high2, low1 * high2, high1 * low2) val new_low = comb.reduceLeft(_ min _) val new_high = comb.reduceLeft(_ max _) - Interval (new_low, new_high) + return Interval(new_low,new_high) } } -*/ -/* -def mult(x : Box, y : Box) : Box = { - var bounds = Array(projectLow(x),projectHigh(x),projectLow(y),projectHigh(y)) - for(i <- bounds.indices){ - if(bounds(i).toInt == InfInt.MinValue) bounds(i) = Double.NegativeInfinity - else if(bounds(i).toInt == InfInt.MaxValue) bounds(i) = Double.PositiveInfinity - } - var comb = Array(bounds(0)*bounds(2),bounds(0)*bounds(3),bounds(1)*bounds(2),bounds(1)*bounds(3)) - var left = comb.reduceLeft(_ min _) - var right = comb.reduceLeft(_ max _) - if(left == Double.NegativeInfinity && (right == Double.PositiveInfinity || right == Double.NegativeInfinity)) return IntervalTop - if(left == Double.NegativeInfinity) return IntervalNegative(right.toInt) - - -} -*/ - - def mult(x : Box, y : Box) : Box = { - x - } /** * @inheritdoc */ def division(x : Box, y : Box) : Box = { - x - // (x,y) match { - // case (IntervalBottom, _) => IntervalBottom - // case (_, IntervalBottom) => IntervalBottom - // case (IntervalTop, _) => IntervalTop - // case (_, IntervalTop) => IntervalTop - // case (Interval (low1, high1), Interval (low2,high2)) => - // if (low2 >= 1) { - // val new_low = (low1 / low2) min (low1 / high2) - // val new_high = (high1 / low2) max (high1 / high2) - // Interval (new_low, new_high) - - // } else if (high2 <= -1) { - // val new_low = (high1 / low2) min (high1 / high2) - // val new_high = (low1 / low2) max (low1 / high2) - // Interval (new_low, new_high) - - // } else { - // // TODO: MODELLARE L'INFINITO "INTERO" - // Interval(1,1) - // //lub(division(Interval (low1, high1), glb(Interval (low2,high2), Interval(1,InfInt.MaxValue)), division(Interval (low1, high1), glb(Interval (low2,high2), Interval(InfInt.MinValue, -1))))) - // } - // } + (x,y) match { + case (IntervalBottom, _) => IntervalBottom + case (_, IntervalBottom) => IntervalBottom + case (IntervalTop, _) => IntervalTop + case (_, IntervalTop) => IntervalTop + case (Interval (low1, high1), Interval (low2,high2)) => + if (low2 >= IntNumber(1)) { + val new_low = (low1 / low2) min (low1 / high2) + val new_high = (high1 / low2) max (high1 / high2) + return Interval (new_low, new_high) + } + if (IntNumber(-1) >= high2) { + val new_low = (high1 / low2) min (high1 / high2) + val new_high = (low1 / low2) max (low1 / high2) + return Interval (new_low, new_high) + } + + val one_to_infinite = Interval(IntNumber(1),PositiveInfinity()) + val minus_infinite_to_minus_one = Interval(NegativeInfinity(),IntNumber(-1)) + return lub ( + division(Interval (low1, high1), glb(Interval (low2,high2), one_to_infinite)), // first argument + division(Interval (low1, high1), glb(Interval (low2,high2), minus_infinite_to_minus_one)) // second argument + ) + } } //TODO @@ -181,58 +122,58 @@ def mult(x : Box, y : Box) : Box = { * @inheritdoc */ def lub(x : Box, y : Box) : Box = { - x - // (x, y) match { - // case (IntervalTop, _) => IntervalTop - // case (_, IntervalTop) => IntervalTop - // case (IntervalBottom, _) => y - // case (_, IntervalBottom) => x - // case (Interval (low1, high1), Interval (low2, high2)) => - // val new_low = low1 min low2 - // val new_high = high1 max high2 - // Interval (new_low, new_high) - // } + (x, y) match { + case (IntervalTop, _) => return IntervalTop + case (_, IntervalTop) => return IntervalTop + case (IntervalBottom, _) => return y + case (_, IntervalBottom) => return x + case (Interval (low1, high1), Interval (low2, high2)) => + val new_low = low1 min low2 + val new_high = high1 max high2 + return Interval (new_low, new_high) + } } /** * @inheritdoc */ def glb(x : Box, y : Box) : Box = { - x - // (x, y) match { - // case (IntervalTop, _) => y - // case (_, IntervalTop) => x - // case (IntervalBottom, _) => IntervalBottom - // case (_, IntervalBottom) => IntervalBottom - // case (Interval (low1, high1), Interval (low2, high2)) => - // val new_low = low1 max low2 - // val new_high = high1 min high2 - // if (new_low > new_high) IntervalBottom else Interval (new_low, new_high) - // } + (x, y) match { + case (IntervalTop, _) => return y + case (_, IntervalTop) => return x + case (IntervalBottom, _) => return IntervalBottom + case (_, IntervalBottom) => return IntervalBottom + case (Interval (low1, high1), Interval (low2, high2)) => + val new_low = low1 max low2 + val new_high = high1 min high2 + if (new_low > new_high) + return IntervalBottom + + return Interval (new_low, new_high) + } } /** * @inheritdoc */ def compare(x : Box, y : Box) : Option[Int] = { - Option(0) - // (x, y) match { - // case (IntervalBottom, IntervalBottom) => Option(0) - // case (IntervalBottom, _) => Option(-1) - // case (_, IntervalBottom) => Option(1) - // case (IntervalTop, IntervalTop) => Option(0) - // case (IntervalTop, _) => Option(1); - // case (_, IntervalTop) => Option(-1); - // case (Interval(low1, high1), Interval(low2, high2)) => - // if (low1 == low2 && high1 == high2) - // Option(0) - // else if (low1 >= low2 && high1 <= high2) - // Option(-1) - // else if (low2 >= low1 && high2 <= high1) - // Option(1) - // else - // Option.empty - // } + (x, y) match { + case (IntervalBottom, IntervalBottom) => return Option(0) + case (IntervalBottom, _) => return Option(-1) + case (_, IntervalBottom) => return Option(1) + case (IntervalTop, IntervalTop) => return Option(0) + case (IntervalTop, _) => return Option(1); + case (_, IntervalTop) => return Option(-1); + case (Interval(low1, high1), Interval(low2, high2)) => + if (low1 == low2 && high1 == high2) + return Option(0) + if (low1 >= low2 && high2 >= high1) + return Option(-1) + if (low2 >= low1 && high1 >= high2) + return Option(1) + + return Option.empty + } } /** From dec30f16faaeab2b734b42b322b82f244857ec49 Mon Sep 17 00:00:00 2001 From: Mou95 Date: Wed, 21 Mar 2018 15:47:12 +0100 Subject: [PATCH 60/99] Print interval implemented --- .../it/unipd/jandom/domains/InfInt.scala | 57 ++++++++++--------- .../jandom/domains/numerical/box/Box.scala | 2 +- 2 files changed, 32 insertions(+), 27 deletions(-) diff --git a/core/src/main/scala/it/unipd/jandom/domains/InfInt.scala b/core/src/main/scala/it/unipd/jandom/domains/InfInt.scala index a15092ff..79a76539 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/InfInt.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/InfInt.scala @@ -25,7 +25,7 @@ trait InfInt { // def <=(x: InfInt): InfInt TODO ?? def max(x: InfInt): InfInt def min(x: InfInt): InfInt - def ==(x: InfInt): Boolean + def ==(x: InfInt): Boolean def inverse(x: InfInt): InfInt = { x match { @@ -42,15 +42,15 @@ trait InfInt { def >=(x: InfInt): Boolean = { return this.>(x.+(IntNumber(1))) - } + } } case class IntNumber(n: Int) extends InfInt { - + def +(x: InfInt): InfInt = { print("IntNumber+",n," + ",x) - x match { + x match { case NegativeInfinity() => return NegativeInfinity() case PositiveInfinity() => return PositiveInfinity() case Undetermined() => return Undetermined() @@ -63,28 +63,28 @@ case class IntNumber(n: Int) extends InfInt { x match { case IntNumber(x) => return safeMul(n,x) case Undetermined() => return Undetermined() - case _ => + case _ => if(n > 0) return x return inverse(x) - } + } } - + def >(x: InfInt): Boolean = { x match { case PositiveInfinity() => return false case IntNumber(x) => return n > x - case _ => return true + case _ => return true } } def /(x: InfInt): InfInt = { x match { - case IntNumber(x) => + case IntNumber(x) => if (x != 0) return IntNumber(n / x) - if (n > 0) // && x == 0 + if (n > 0) // && x == 0 return PositiveInfinity() - else if (n < 0) + else if (n < 0) return NegativeInfinity() return IntNumber(0) case Undetermined() => return Undetermined() @@ -152,9 +152,10 @@ case class IntNumber(n: Int) extends InfInt { return NegativeInfinity() } - return IntNumber(left * right) + return IntNumber(left * right) } + override def toString : String = n.toString } case class NegativeInfinity() extends InfInt { @@ -169,8 +170,8 @@ case class NegativeInfinity() extends InfInt { def *(x: InfInt): InfInt = { x match { - case IntNumber(x) => - if (x > 0) + case IntNumber(x) => + if (x > 0) return NegativeInfinity() if (x < 0) return PositiveInfinity() @@ -178,26 +179,26 @@ case class NegativeInfinity() extends InfInt { case Undetermined() => return Undetermined() case PositiveInfinity() => return NegativeInfinity() case NegativeInfinity() => return PositiveInfinity() - } + } } def >(x: InfInt): Boolean = { x match { case NegativeInfinity() => return false case Undetermined() => return false - case _ => true + case _ => true } } def /(x: InfInt): InfInt = { x match { - case IntNumber(x) => - if(x < 0) + case IntNumber(x) => + if(x < 0) return PositiveInfinity() return NegativeInfinity() case _ => return Undetermined() } - } + } def ==(x: InfInt): Boolean = { x match { @@ -222,8 +223,10 @@ case class NegativeInfinity() extends InfInt { } } + override def toString : String = "-\u221E" + } - + case class PositiveInfinity() extends InfInt { def +(x: InfInt): InfInt = { @@ -237,8 +240,8 @@ case class PositiveInfinity() extends InfInt { def *(x: InfInt): InfInt = { x match { - case IntNumber(x) => - if (x > 0) + case IntNumber(x) => + if (x > 0) return PositiveInfinity() if (x < 0) return NegativeInfinity() @@ -246,14 +249,14 @@ case class PositiveInfinity() extends InfInt { case Undetermined() => return Undetermined() case PositiveInfinity() => return PositiveInfinity() case NegativeInfinity() => return NegativeInfinity() - } + } } def >(x: InfInt): Boolean = { x match { case NegativeInfinity() => return true case Undetermined() => return true - case _ => false + case _ => false } } @@ -266,7 +269,7 @@ case class PositiveInfinity() extends InfInt { def /(x: InfInt): InfInt = { x match { - case IntNumber(x) => + case IntNumber(x) => if(x < 0) return NegativeInfinity() return PositiveInfinity() @@ -290,6 +293,8 @@ case class PositiveInfinity() extends InfInt { } } + override def toString : String = "+\u221E" + } // case infinity - infinity @@ -299,7 +304,7 @@ case class Undetermined() extends InfInt { } def *(x: InfInt): InfInt = { - return Undetermined() + return Undetermined() } def >(x:InfInt): Boolean = { diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/Box.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/Box.scala index 0a2cad46..5e2a32bf 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/Box.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/Box.scala @@ -31,7 +31,7 @@ object Box { // interval case class Interval (low : InfInt, high : InfInt) extends Box { - override def toString : String = "= [" + low + "," + high + "]" + override def toString : String = "= [" + low.toString + "," + high.toString + "]" } // no accurate info available for variable From 3778d87a6dd3648158124651c6218e10580e776f Mon Sep 17 00:00:00 2001 From: BottCode Date: Wed, 21 Mar 2018 15:51:43 +0100 Subject: [PATCH 61/99] some checks on InfInt --- .../it/unipd/jandom/domains/InfInt.scala | 144 ++++++++---------- .../domains/numerical/box/BoxDomainCore.scala | 2 +- 2 files changed, 65 insertions(+), 81 deletions(-) diff --git a/core/src/main/scala/it/unipd/jandom/domains/InfInt.scala b/core/src/main/scala/it/unipd/jandom/domains/InfInt.scala index a15092ff..cb0068eb 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/InfInt.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/InfInt.scala @@ -27,8 +27,8 @@ trait InfInt { def min(x: InfInt): InfInt def ==(x: InfInt): Boolean - def inverse(x: InfInt): InfInt = { - x match { + def inverse(): InfInt = { + this match { case PositiveInfinity() => return NegativeInfinity() case NegativeInfinity() => return PositiveInfinity() case IntNumber(x) => return IntNumber(-x) @@ -37,7 +37,7 @@ trait InfInt { } def -(x: InfInt): InfInt = { - return this.+(inverse(x)) + return this.+(inverse()) } def >=(x: InfInt): Boolean = { @@ -51,88 +51,76 @@ case class IntNumber(n: Int) extends InfInt { def +(x: InfInt): InfInt = { print("IntNumber+",n," + ",x) x match { - case NegativeInfinity() => return NegativeInfinity() - case PositiveInfinity() => return PositiveInfinity() - case Undetermined() => return Undetermined() - case IntNumber(x) => return safeAdd(n,x) + case NegativeInfinity() => NegativeInfinity() + case PositiveInfinity() => PositiveInfinity() + case Undetermined() => Undetermined() + case IntNumber(m) => safeAdd(n,m) } } def *(x: InfInt): InfInt = { if(n == 0) return IntNumber(0) x match { - case IntNumber(x) => return safeMul(n,x) - case Undetermined() => return Undetermined() + case IntNumber(m) => safeMul(n,m) + case Undetermined() => Undetermined() case _ => if(n > 0) return x - return inverse(x) + return x.inverse() } } def >(x: InfInt): Boolean = { x match { - case PositiveInfinity() => return false - case IntNumber(x) => return n > x - case _ => return true + case PositiveInfinity() => false + case IntNumber(m) => n > m + case _ => true // TODO } } def /(x: InfInt): InfInt = { x match { - case IntNumber(x) => - if (x != 0) - return IntNumber(n / x) - if (n > 0) // && x == 0 - return PositiveInfinity() - else if (n < 0) - return NegativeInfinity() - return IntNumber(0) - case Undetermined() => return Undetermined() + case IntNumber(m) => IntNumber(n / m) + case Undetermined() => Undetermined() case _ => IntNumber(0) } } def ==(x: InfInt): Boolean = { x match { - case IntNumber(x) => return x == n - case _ => return false + case IntNumber(x) => x == n + case _ => false } } def max(x: InfInt): InfInt = { x match { - case IntNumber(x) => return IntNumber(n max x) - case PositiveInfinity() => return PositiveInfinity() - case NegativeInfinity() => return IntNumber(n) - case _ => return Undetermined() + case IntNumber(m) => IntNumber(n max m) + case PositiveInfinity() => PositiveInfinity() + case NegativeInfinity() => IntNumber(n) + case _ => Undetermined() } } def min(x: InfInt): InfInt = { x match { - case IntNumber(x) => return IntNumber(n min x) - case PositiveInfinity() => return IntNumber(n) - case NegativeInfinity() => return NegativeInfinity() - case _ => return Undetermined() + case IntNumber(m) => IntNumber(n min m) + case PositiveInfinity() => IntNumber(n) + case NegativeInfinity() => NegativeInfinity() + case _ => Undetermined() } } def safeAdd(left: Int, right: Int): InfInt = { - // require(left should be anIstanceOf[Int]) - print("safeadd",left,right) - if (right > 0 && left > Int.MaxValue - right){ - print("Ritorno il positiveInf") + if (right > 0 && left > Int.MaxValue - right) return PositiveInfinity() - } - if (right < 0 && left < Int.MinValue - right){ - print("ritnorno il neginf") + + if (right < 0 && left < Int.MinValue - right) return NegativeInfinity() - } - print("ritorno: ",left+right) + return IntNumber(left + right) } - def safeMul(left: Int, right: Int): InfInt = { + def safeMul(left: Int, right: Int): InfInt = { // TODO if (right > 0) { if (left > Int.MaxValue / right) return PositiveInfinity() @@ -161,30 +149,30 @@ case class NegativeInfinity() extends InfInt { def +(x: InfInt): InfInt = { print("NegativeInf+",x) x match { - case PositiveInfinity() => return Undetermined() - case Undetermined() => return Undetermined() + case PositiveInfinity() => Undetermined() + case Undetermined() => Undetermined() case _ => NegativeInfinity() } } def *(x: InfInt): InfInt = { x match { - case IntNumber(x) => - if (x > 0) + case IntNumber(m) => + if (m > 0) return NegativeInfinity() - if (x < 0) + if (m < 0) return PositiveInfinity() return IntNumber(0) - case Undetermined() => return Undetermined() - case PositiveInfinity() => return NegativeInfinity() - case NegativeInfinity() => return PositiveInfinity() + case Undetermined() => Undetermined() + case PositiveInfinity() => NegativeInfinity() + case NegativeInfinity() => PositiveInfinity() } } def >(x: InfInt): Boolean = { x match { - case NegativeInfinity() => return false - case Undetermined() => return false + case NegativeInfinity() => false + case Undetermined() => false case _ => true } } @@ -192,33 +180,32 @@ case class NegativeInfinity() extends InfInt { def /(x: InfInt): InfInt = { x match { case IntNumber(x) => - if(x < 0) + if(x < 0) // TODO THORW /0 return PositiveInfinity() return NegativeInfinity() - case _ => return Undetermined() + case Undetermined() => Undetermined() + case _ => IntNumber(0) // Inf / Inf = Inf * (1 / Inf) = Inf * 0 } } def ==(x: InfInt): Boolean = { x match { - case NegativeInfinity() => return true - case _ => return false + case NegativeInfinity() => true + case _ => false } } def max(x: InfInt): InfInt = { x match { - case IntNumber(x) => return IntNumber(x) - case PositiveInfinity() => return PositiveInfinity() - case NegativeInfinity() => return NegativeInfinity() - case _ => Undetermined() + case IntNumber(m) => IntNumber(m) + case _ => x } } def min(x: InfInt): InfInt = { x match { - case Undetermined() => return Undetermined() - case _ => return NegativeInfinity() + case Undetermined() => Undetermined() + case _ => NegativeInfinity() } } @@ -229,9 +216,9 @@ case class PositiveInfinity() extends InfInt { def +(x: InfInt): InfInt = { print("NegativeInf+",x) x match { - case NegativeInfinity()=> return Undetermined() - case Undetermined() => return Undetermined() - case _ => return PositiveInfinity() + case NegativeInfinity() => Undetermined() + case Undetermined() => Undetermined() + case _ => PositiveInfinity() } } @@ -243,34 +230,33 @@ case class PositiveInfinity() extends InfInt { if (x < 0) return NegativeInfinity() return IntNumber(0) - case Undetermined() => return Undetermined() - case PositiveInfinity() => return PositiveInfinity() - case NegativeInfinity() => return NegativeInfinity() + case _ => x } } def >(x: InfInt): Boolean = { x match { - case NegativeInfinity() => return true - case Undetermined() => return true + case NegativeInfinity() => true + case Undetermined() => true // todo think case _ => false } } def ==(x: InfInt): Boolean = { x match { - case PositiveInfinity() => return true - case _ => return false + case PositiveInfinity() => true + case _ => false } } def /(x: InfInt): InfInt = { x match { - case IntNumber(x) => - if(x < 0) + case IntNumber(m) => + if(m < 0) return NegativeInfinity() - return PositiveInfinity() - case _ => return Undetermined() + return PositiveInfinity() // TODO EXCEPTION /0 + case Undetermined() => Undetermined() + case _ => IntNumber(0) // Inf / Inf = Inf * (1 / Inf) = Inf * 0 } } @@ -283,10 +269,8 @@ case class PositiveInfinity() extends InfInt { def min(x: InfInt): InfInt = { x match { - case Undetermined() => return Undetermined() - case NegativeInfinity() => return NegativeInfinity() - case PositiveInfinity() => return PositiveInfinity() - case IntNumber(x) => return IntNumber(x) + case Undetermined() => Undetermined() + case _ => x } } diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala index 230a1e6c..65d084d0 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala @@ -61,7 +61,7 @@ class BoxDomainCore extends CompleteLatticeOperator[Box] x match { case IntervalBottom => IntervalBottom case IntervalTop => IntervalTop - case Interval(low,high) => Interval(high.inverse(high),low.inverse(low)) // TODO, bruttino + case Interval(low,high) => Interval(high.inverse(),low.inverse()) // TODO, bruttino } } From 254c669675c908cbbef5a026a207c4181fa47348 Mon Sep 17 00:00:00 2001 From: Mou95 Date: Wed, 21 Mar 2018 17:21:09 +0100 Subject: [PATCH 62/99] Created java class for testing --- core/examples/Java/TestBox.class | Bin 0 -> 349 bytes core/examples/Java/TestBox.java | 14 ++++ .../it/unipd/jandom/domains/InfInt.scala | 77 +++++++++++++----- .../domains/numerical/box/BoxDomainCore.scala | 18 ++-- 4 files changed, 78 insertions(+), 31 deletions(-) create mode 100644 core/examples/Java/TestBox.class create mode 100644 core/examples/Java/TestBox.java diff --git a/core/examples/Java/TestBox.class b/core/examples/Java/TestBox.class new file mode 100644 index 0000000000000000000000000000000000000000..ff5e7c9dc42d72afd5487aaf2f58f7b58a82b44b GIT binary patch literal 349 zcmZWjyH3ME5S%^7PaNzD2_y?^?Z=4D``}MgIWCxWsN3-j~ zOh>wy5Q+Bc`?Jf+wcTN(%d10u^M^XIRc!^yu%1mzGidkHk-2Rs+ZyXTouUI@5dLC< z+@ZaRwimtQVr<_qMR4bLzKEhvZ)%~uD+6uCT4cB1~u yBjN{ 0) { + y++; + } + } + + public static void BoxUnion() { + + } + +} diff --git a/core/src/main/scala/it/unipd/jandom/domains/InfInt.scala b/core/src/main/scala/it/unipd/jandom/domains/InfInt.scala index ca137052..a7d07d18 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/InfInt.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/InfInt.scala @@ -22,26 +22,34 @@ trait InfInt { def /(x: InfInt): InfInt def *(x: InfInt): InfInt def >(x: InfInt): Boolean - // def <=(x: InfInt): InfInt TODO ?? + def >=(x: InfInt): Boolean def max(x: InfInt): InfInt def min(x: InfInt): InfInt def ==(x: InfInt): Boolean def inverse(): InfInt = { this match { - case PositiveInfinity() => return NegativeInfinity() - case NegativeInfinity() => return PositiveInfinity() - case IntNumber(x) => return IntNumber(-x) - case _ => return Undetermined() + case PositiveInfinity() => NegativeInfinity() + case NegativeInfinity() => PositiveInfinity() + case IntNumber(x) => IntNumber(-x) + case _ => Undetermined() } } def -(x: InfInt): InfInt = { - return this.+(inverse()) + this + x.inverse() } - def >=(x: InfInt): Boolean = { - return this.>(x.+(IntNumber(1))) + def !=(x: InfInt): Boolean = { + !(this == x) + } + + def <(x: InfInt): Boolean = { + !(this >= x) + } + + def <=(x: InfInt): Boolean = { + !(this > x) } } @@ -50,7 +58,7 @@ case class IntNumber(n: Int) extends InfInt { def +(x: InfInt): InfInt = { print("IntNumber+",n," + ",x) - x match { + x match { case NegativeInfinity() => NegativeInfinity() case PositiveInfinity() => PositiveInfinity() case Undetermined() => Undetermined() @@ -63,10 +71,10 @@ case class IntNumber(n: Int) extends InfInt { x match { case IntNumber(m) => safeMul(n,m) case Undetermined() => Undetermined() - case _ => + case _ => if(n > 0) return x return x.inverse() - } + } } def >(x: InfInt): Boolean = { @@ -78,6 +86,14 @@ case class IntNumber(n: Int) extends InfInt { } } + def >=(x: InfInt): Boolean = { + x match { + case IntNumber(m) => n >= m + case PositiveInfinity() => false + case _ => true + } + } + def /(x: InfInt): InfInt = { x match { case IntNumber(m) => IntNumber(n / m) @@ -114,14 +130,14 @@ case class IntNumber(n: Int) extends InfInt { def safeAdd(left: Int, right: Int): InfInt = { if (right > 0 && left > Int.MaxValue - right) return PositiveInfinity() - + if (right < 0 && left < Int.MinValue - right) return NegativeInfinity() - + return IntNumber(left + right) } - def safeMul(left: Int, right: Int): InfInt = { // TODO + def safeMul(left: Int, right: Int): InfInt = { // TODO if (right > 0) { if (left > Int.MaxValue / right) return PositiveInfinity() @@ -159,8 +175,8 @@ case class NegativeInfinity() extends InfInt { def *(x: InfInt): InfInt = { x match { - case IntNumber(m) => - if (m > 0) + case IntNumber(m) => + if (m > 0) return NegativeInfinity() if (m < 0) return PositiveInfinity() @@ -168,7 +184,7 @@ case class NegativeInfinity() extends InfInt { case Undetermined() => Undetermined() case PositiveInfinity() => NegativeInfinity() case NegativeInfinity() => PositiveInfinity() - } + } } @@ -176,13 +192,20 @@ case class NegativeInfinity() extends InfInt { x match { case NegativeInfinity() => false case Undetermined() => false - case _ => true + case _ => true + } + } + + def >=(x: InfInt): Boolean = { + x match { + case NegativeInfinity() => true + case _ => false } } def /(x: InfInt): InfInt = { x match { - case IntNumber(x) => + case IntNumber(x) => if(x < 0) // TODO THORW /0 return PositiveInfinity() @@ -237,14 +260,20 @@ case class PositiveInfinity() extends InfInt { return NegativeInfinity() return IntNumber(0) case _ => x - } + } } def >(x: InfInt): Boolean = { x match { case NegativeInfinity() => true case Undetermined() => true // todo think - case _ => false + case _ => false + } + } + + def >=(x: InfInt): Boolean = { + x match { + case _ => true } } @@ -257,7 +286,7 @@ case class PositiveInfinity() extends InfInt { def /(x: InfInt): InfInt = { x match { - case IntNumber(m) => + case IntNumber(m) => if(m < 0) return NegativeInfinity() return PositiveInfinity() // TODO EXCEPTION /0 @@ -298,6 +327,10 @@ case class Undetermined() extends InfInt { return false } + def >=(x: InfInt): Boolean = { + return false + } + def ==(x: InfInt): Boolean = { return false } diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala index 65d084d0..51e06d0b 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala @@ -68,7 +68,7 @@ class BoxDomainCore extends CompleteLatticeOperator[Box] /** * @inheritdoc */ - + def mult(x : Box, y : Box) : Box = { (x,y) match { case (IntervalBottom, _) => IntervalBottom @@ -102,20 +102,20 @@ class BoxDomainCore extends CompleteLatticeOperator[Box] val new_low = (high1 / low2) min (high1 / high2) val new_high = (low1 / low2) max (low1 / high2) return Interval (new_low, new_high) - } - + } + val one_to_infinite = Interval(IntNumber(1),PositiveInfinity()) val minus_infinite_to_minus_one = Interval(NegativeInfinity(),IntNumber(-1)) - return lub ( + return lub ( division(Interval (low1, high1), glb(Interval (low2,high2), one_to_infinite)), // first argument division(Interval (low1, high1), glb(Interval (low2,high2), minus_infinite_to_minus_one)) // second argument - ) + ) } } //TODO def remainder(x : Box, y : Box) : Box = { - x + sum(x,inverse(mult(division(x,y),y))) // (10%4) = 10 - (10/4)*4 } /** @@ -146,8 +146,8 @@ class BoxDomainCore extends CompleteLatticeOperator[Box] case (Interval (low1, high1), Interval (low2, high2)) => val new_low = low1 max low2 val new_high = high1 min high2 - if (new_low > new_high) - return IntervalBottom + if (new_low > new_high) + return IntervalBottom return Interval (new_low, new_high) } @@ -171,7 +171,7 @@ class BoxDomainCore extends CompleteLatticeOperator[Box] return Option(-1) if (low2 >= low1 && high1 >= high2) return Option(1) - + return Option.empty } } From d36485d198a2eed609e23672455e6b43e78ffb79 Mon Sep 17 00:00:00 2001 From: Mou95 Date: Thu, 22 Mar 2018 17:07:19 +0100 Subject: [PATCH 63/99] Added linearInequality --- core/examples/Java/TestBox.class | Bin 349 -> 356 bytes core/examples/Java/TestBox.java | 3 +- .../it/unipd/jandom/domains/InfInt.scala | 16 ++++-- .../domains/numerical/box/BoxDomain.scala | 48 ++++++++++++------ .../domains/numerical/box/BoxDomainCore.scala | 6 +-- 5 files changed, 50 insertions(+), 23 deletions(-) diff --git a/core/examples/Java/TestBox.class b/core/examples/Java/TestBox.class index ff5e7c9dc42d72afd5487aaf2f58f7b58a82b44b..468b5c4857cb30d959b840fb5d937e93471fb4bb 100644 GIT binary patch delta 101 zcmcc1^n_``Q$Jq@Mg}GZ1_ogPE^7`Osd)@MEsTsU4F8w^|F#h*%*4PBB&8VGfFv^z qvM{g$At#W}1C$X0vN(Y<91Ki<8CV$^c_!;Hs&VrIjpPRF 0) { y++; + x--; } } public static void BoxUnion() { - + } } diff --git a/core/src/main/scala/it/unipd/jandom/domains/InfInt.scala b/core/src/main/scala/it/unipd/jandom/domains/InfInt.scala index a7d07d18..807da011 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/InfInt.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/InfInt.scala @@ -18,6 +18,9 @@ package it.unipd.jandom.domains trait InfInt { + + def isInfinity : Boolean + def +(x: InfInt): InfInt def /(x: InfInt): InfInt def *(x: InfInt): InfInt @@ -56,8 +59,9 @@ trait InfInt { case class IntNumber(n: Int) extends InfInt { + def isInfinity = false + def +(x: InfInt): InfInt = { - print("IntNumber+",n," + ",x) x match { case NegativeInfinity() => NegativeInfinity() case PositiveInfinity() => PositiveInfinity() @@ -164,8 +168,10 @@ case class IntNumber(n: Int) extends InfInt { } case class NegativeInfinity() extends InfInt { + + def isInfinity = true + def +(x: InfInt): InfInt = { - print("NegativeInf+",x) x match { case PositiveInfinity() => Undetermined() case Undetermined() => Undetermined() @@ -242,8 +248,9 @@ case class NegativeInfinity() extends InfInt { case class PositiveInfinity() extends InfInt { + def isInfinity = true + def +(x: InfInt): InfInt = { - print("NegativeInf+",x) x match { case NegativeInfinity() => Undetermined() case Undetermined() => Undetermined() @@ -315,6 +322,9 @@ case class PositiveInfinity() extends InfInt { // case infinity - infinity case class Undetermined() extends InfInt { + + def isInfinity = false + def +(x: InfInt): InfInt = { return Undetermined() } diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala index aae6c603..b60951e0 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala @@ -82,21 +82,32 @@ class BoxDomain extends BaseNumericalDomain[Box, BoxDomainCore](BoxDomainCore()) override def linearInequality(lf: LinearForm): Property = { if (isEmpty) return this - val homcoeffs = lf.homcoeffs.toArray - val known = lf.known - val lowresult = projectLow(linearEvaluation(lf)) + val homcoeffs = lf.homcoeffs.map(_.toInt).toArray + val known = IntNumber(lf.known.toInt) + val lfMin = projectLow(linearEvaluation(lf)) val lfArgmin = linearArgmin(lf); - print(lowresult) - if (lowresult > IntNumber(0)) + //print(lowresult) + if (lfMin > IntNumber(0)) return bottom else { var newboxes = boxes.clone - for (i <- homcoeffs.indices) { - if (homcoeffs(i) < 0) newboxes(i) = Interval(projectLow(boxes(i)) max (lfArgmin(i) - (lowresult / IntNumber(homcoeffs(i).toInt))), projectHigh(newboxes(i))) - if (homcoeffs(i) > 0) newboxes(i) = Interval(projectLow(newboxes(i)), projectHigh(boxes(i)) min (lfArgmin(i) - (lowresult / IntNumber(homcoeffs(i).toInt)))) + val infinities = (homcoeffs.indices) filter { i => lfArgmin(i).isInfinity && homcoeffs(i) != 0 } + + infinities.size match { + case 0 => + for (i <- homcoeffs.indices) { + if (homcoeffs(i) < 0) newboxes(i) = Interval(projectLow(boxes(i)) max (lfArgmin(i) - (lfMin / IntNumber(homcoeffs(i)))), projectHigh(newboxes(i))) + if (homcoeffs(i) > 0) newboxes(i) = Interval(projectLow(newboxes(i)), projectHigh(boxes(i)) min (lfArgmin(i) - (lfMin / IntNumber(homcoeffs(i))))) + } + case 1 => { + val posinf = infinities.head + if (homcoeffs(posinf) < 0) + newboxes(posinf) = Interval(projectLow(boxes(posinf)) max ((dotprod(homcoeffs, lfArgmin, posinf) - known).inverse() / IntNumber(homcoeffs(posinf))), projectHigh(newboxes(posinf))) + else + newboxes(posinf) = Interval(projectLow(boxes(posinf)), projectHigh(boxes(posinf)) min ((dotprod(homcoeffs, lfArgmin, posinf) - known).inverse() / IntNumber(homcoeffs(posinf)))) + } + case _ => } - for (i <- newboxes.indices) - print("boxes:",newboxes(i)) new Property(newboxes,false) } } @@ -107,6 +118,13 @@ class BoxDomain extends BaseNumericalDomain[Box, BoxDomainCore](BoxDomainCore()) } } + private def dotprod(x: Seq[Int], y: Seq[InfInt], remove: Int): InfInt = { + var sum: InfInt = IntNumber(0) + for (i <- x.indices; if i != remove && x(i) != 0) + sum = sum + (IntNumber(x(i)) * y(i)) + sum + } + override def widening(that : Property) : Property = { createProperty((this.elements, that.elements).zipped.map((x, y) => { (x,y) match { @@ -119,14 +137,14 @@ class BoxDomain extends BaseNumericalDomain[Box, BoxDomainCore](BoxDomainCore()) var newhigh = high1 var newlow = low1 - if (low2 >= low1) + if (low2 >= low1) newlow = low1 - else + else newlow = NegativeInfinity() - - if (high1 >= high2) + + if (high1 >= high2) newhigh = high1 - else + else newhigh = PositiveInfinity() Interval(newlow,newhigh) diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala index 51e06d0b..663971af 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala @@ -35,7 +35,6 @@ class BoxDomainCore extends CompleteLatticeOperator[Box] * @inheritdoc */ def alpha(num : Int) : Box = { - print("Astraggo ",num) return Interval(IntNumber(num),IntNumber(num)) } @@ -43,7 +42,6 @@ class BoxDomainCore extends CompleteLatticeOperator[Box] * @inheritdoc */ def sum(x : Box, y : Box) : Box = { - print("sum",x,y) (x,y) match { case (IntervalBottom, _) => IntervalBottom case (_, IntervalBottom) => IntervalBottom @@ -57,7 +55,6 @@ class BoxDomainCore extends CompleteLatticeOperator[Box] * @inheritdoc */ def inverse(x : Box) : Box = { - print("INVERSE") x match { case IntervalBottom => IntervalBottom case IntervalTop => IntervalTop @@ -115,7 +112,7 @@ class BoxDomainCore extends CompleteLatticeOperator[Box] //TODO def remainder(x : Box, y : Box) : Box = { - sum(x,inverse(mult(division(x,y),y))) // (10%4) = 10 - (10/4)*4 + sum(x,inverse(mult(division(x,y),y))) // (10%4) = 10 - (10/4)*4 } /** @@ -138,6 +135,7 @@ class BoxDomainCore extends CompleteLatticeOperator[Box] * @inheritdoc */ def glb(x : Box, y : Box) : Box = { + print("GLB",x,y) (x, y) match { case (IntervalTop, _) => return y case (_, IntervalTop) => return x From 749a146b13f7106d152c1acdf167e4f15646a633 Mon Sep 17 00:00:00 2001 From: BottCode Date: Sat, 24 Mar 2018 14:17:34 +0100 Subject: [PATCH 64/99] Add doc and comment to InfInt.scala --- .../it/unipd/jandom/domains/InfInt.scala | 64 ++++++++++++++++++- .../jandom/domains/numerical/box/Box.scala | 4 +- 2 files changed, 65 insertions(+), 3 deletions(-) diff --git a/core/src/main/scala/it/unipd/jandom/domains/InfInt.scala b/core/src/main/scala/it/unipd/jandom/domains/InfInt.scala index 807da011..b464b51a 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/InfInt.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/InfInt.scala @@ -17,19 +17,53 @@ */ package it.unipd.jandom.domains +/** + * This class manage integer operation avoid overflow. + * It defines also a way to manage the "infinite" similar to Double.PositiveInfinity and Double.NegativeInfinity + * + * @author Mattia Bottaro + * @author Mauro Carlin + */ + trait InfInt { def isInfinity : Boolean + /** + * The following method are abstract. + * The real implementation can be found in each sub-case class extending this trait + */ + + /** + * Perform the mathematical sum between the object that invoke this method and the param + * @param x is the adding + * @return the mathematical sum between the object that invoke this method and x. + */ def +(x: InfInt): InfInt + + /** + * Perform the mathematical division between the object that invoke this method and the param + * @param x is the divider + * @return the mathematical division between the object that invoke this method and x. + */ def /(x: InfInt): InfInt + def *(x: InfInt): InfInt def >(x: InfInt): Boolean - def >=(x: InfInt): Boolean + def >=(x: InfInt): + + /** + * @param x is the second argument of max operator + * @return the max element between the object that invoke this method and x. + */ def max(x: InfInt): InfInt + def min(x: InfInt): InfInt def ==(x: InfInt): Boolean + /** + * @return the inverse of the object that invoke this method. + */ def inverse(): InfInt = { this match { case PositiveInfinity() => NegativeInfinity() @@ -39,18 +73,35 @@ trait InfInt { } } + + /** + * Perform the mathematical difference between the object that invoke this method and the param + * @param x is the substracting + * @return the mathematical difference between the object that invoke this method and x. + */ def -(x: InfInt): InfInt = { this + x.inverse() } + /** + * Checks if two InfInt are not equal + * @param x is the second argument of != operator + * @return true if and only if the object that invoke this method is not equal to x. + */ def !=(x: InfInt): Boolean = { !(this == x) } + /** + * Checks if the object that invoke this method is less than the argument + * @param x is the second argument of < operator + * @return true if and only if the object that invoke this method is less than x. + */ def <(x: InfInt): Boolean = { !(this >= x) } + // similar to < def <=(x: InfInt): Boolean = { !(this > x) } @@ -131,7 +182,13 @@ case class IntNumber(n: Int) extends InfInt { } } + /** + * Perform a "safe add", that is a sum that will never do an overflow. + * @param x is the adding + * @return the safe add between the object that invoke this method and x. If an overflow is detected, an Infinity is returned. + */ def safeAdd(left: Int, right: Int): InfInt = { + // if right + left > Int.MaxValue => Overflow if (right > 0 && left > Int.MaxValue - right) return PositiveInfinity() @@ -141,6 +198,11 @@ case class IntNumber(n: Int) extends InfInt { return IntNumber(left + right) } + /** + * Perform a "safe multiplication", that is a product that will never do an overflow. + * @param x is the adding + * @return the safe prduct between the object that invoke this method and x. If an overflow is detected, an Infinity is returned. + */ def safeMul(left: Int, right: Int): InfInt = { // TODO if (right > 0) { if (left > Int.MaxValue / right) diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/Box.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/Box.scala index 5e2a32bf..3cd86131 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/Box.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/Box.scala @@ -20,8 +20,8 @@ import it.unipd.jandom.domains.InfInt /** * The elements of the constant domain. - * It is a flat domain composed of constant elements, top and bottom. - * This domain is useful for the constant propagation analysis. + * It is a flat domain composed of Interval, top and bottom. + * This domain is useful for the Interval propagation analysis. * * @author Mattia Bottaro * @author Mauro Carlin From 8bcc0eb48d9eba0f16995843ac52814f133743b5 Mon Sep 17 00:00:00 2001 From: BottCode Date: Sat, 24 Mar 2018 14:30:40 +0100 Subject: [PATCH 65/99] Add doc and comment to BoxDomain --- .../domains/numerical/box/BoxDomain.scala | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala index b60951e0..78063c86 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala @@ -44,6 +44,10 @@ class BoxDomain extends BaseNumericalDomain[Box, BoxDomainCore](BoxDomainCore()) */ class Property (boxes : Array[Box], unreachable: Boolean) extends BaseProperty(boxes, unreachable) { + /** + * @param x is an Interval + * @return the lower bound. + */ def projectLow (box : Box) : InfInt = { box match { case IntervalBottom => PositiveInfinity() @@ -52,6 +56,10 @@ class BoxDomain extends BaseNumericalDomain[Box, BoxDomainCore](BoxDomainCore()) } } + /** + * @param x is an Interval + * @return the upper bound. + */ def projectHigh (box : Box) : InfInt = { box match { case IntervalBottom => NegativeInfinity() @@ -125,6 +133,13 @@ class BoxDomain extends BaseNumericalDomain[Box, BoxDomainCore](BoxDomainCore()) sum } + /** + * Implementing the widening strategy described in + * https://hal.archives-ouvertes.fr/hal-01657536 (Tutorial on Static Inference of Numeric Invariants by Abstract Interpretation), page 221 + * + * @param that the abstract object to be widened with `this`. `that` IS assumed to be smaller than `this`. + * @return the widening of the two abstract properties. + */ override def widening(that : Property) : Property = { createProperty((this.elements, that.elements).zipped.map((x, y) => { (x,y) match { @@ -152,6 +167,12 @@ class BoxDomain extends BaseNumericalDomain[Box, BoxDomainCore](BoxDomainCore()) }), this.isEmpty && that.isEmpty) } + /** + * Implementing the narrowing strategy + * + * @param that the abstract object to be narrowed with `this`. `that` IS assumed to be smaller than `this`. + * @return the narrowing of the two abstract properties. + */ override def narrowing(that : Property) : Property = { createProperty((this.elements, that.elements).zipped.map((x, y) => { (x,y) match { From 150cb6bdc1c0f3d01f6163d0b378a3bb39458bdc Mon Sep 17 00:00:00 2001 From: Mou95 Date: Mon, 26 Mar 2018 12:42:44 +0200 Subject: [PATCH 66/99] Managed undetermined value --- core/examples/Java/TestBox.class | Bin 356 -> 607 bytes core/examples/Java/TestBox.java | 27 ++++++++++++++++-- .../jandom/targets/NumericExpression.scala | 4 ++- .../it/unipd/jandom/domains/InfInt.scala | 2 +- .../domains/numerical/box/BoxDomain.scala | 13 +++++++-- .../domains/numerical/box/BoxDomainCore.scala | 14 +++++++-- 6 files changed, 50 insertions(+), 10 deletions(-) diff --git a/core/examples/Java/TestBox.class b/core/examples/Java/TestBox.class index 468b5c4857cb30d959b840fb5d937e93471fb4bb..9ba7b2d8df8644a6430ce7208adb536f0fbb2fa4 100644 GIT binary patch literal 607 zcmZ`#O)mpc6g{_N+8Q%D{XooUg&SB9TywHf&96XsK3c#SiH3uwY?hVxU?@A+H4>B zg2Yav<(InWRsXW$RhvZO8||BedP5!Axh=5D9j|t_>s^Em1{=1I!xlYA1TpTVZnG&c z%I)rD&EEN4RHfqYy7Tw=jDmJ@g;?AI>B3NO02$dNqnE5uLZA zFj+~#-~#y~UmR9URz?P6T!iB-Xa(CSI_{yJxQ9h@SFaZz`tRDB;~v?$JH#BfzNY5< zRa+nnFv=`JE*ln-j44bYgGr3h_BiI5DPGE48Ti;4_$P{*O7aGmBqnG3CKiMwCgr3uGH^KM zSA^ze=I2eU^<-q8c-%mRm4T6g4XD=_NHYOxVF4~{4jZX?3_LB2j4cfRm;e8^ak31f yvI8drCs3M$f$1*;D 0) { y++; x--; + + } + return x; + } + + public static void BoxIfWhile() { + int x = 0; + int y = 10; + while (x + y <= 15) { + x--; + y = y *2; } + int w = 0; + if (x - y < 30) + w = x * y; } - public static void BoxUnion() { + public static void BoxIf() { + int x = 0; + int y = 10; + int w = 0; + if (x - y < 30) + w = x * y; + } + public static void BoxNull() { + int x = 0; + } } diff --git a/core/src/main/scala/it/unich/jandom/targets/NumericExpression.scala b/core/src/main/scala/it/unich/jandom/targets/NumericExpression.scala index 64a01116..eed18adf 100644 --- a/core/src/main/scala/it/unich/jandom/targets/NumericExpression.scala +++ b/core/src/main/scala/it/unich/jandom/targets/NumericExpression.scala @@ -147,8 +147,10 @@ object NumericExpression { def assignTo[Property <: NumericalProperty[Property]](v: Int)(input: Property): Property = input.linearAssignment(v, lf) - override def lteZero[Property <: NumericalProperty[Property]](input: Property): Property = + override def lteZero[Property <: NumericalProperty[Property]](input: Property): Property = { + print("LinearIneq ",input.linearInequality(lf)) input.linearInequality(lf) + } override def ltZero[Property <: NumericalProperty[Property]](input: Property): Property = input.linearInequality(lf) diff --git a/core/src/main/scala/it/unipd/jandom/domains/InfInt.scala b/core/src/main/scala/it/unipd/jandom/domains/InfInt.scala index 807da011..cb3d154e 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/InfInt.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/InfInt.scala @@ -198,7 +198,7 @@ case class NegativeInfinity() extends InfInt { x match { case NegativeInfinity() => false case Undetermined() => false - case _ => true + case _ => false } } diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala index b60951e0..40ab81c1 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala @@ -44,7 +44,7 @@ class BoxDomain extends BaseNumericalDomain[Box, BoxDomainCore](BoxDomainCore()) */ class Property (boxes : Array[Box], unreachable: Boolean) extends BaseProperty(boxes, unreachable) { - def projectLow (box : Box) : InfInt = { + private def projectLow (box : Box) : InfInt = { box match { case IntervalBottom => PositiveInfinity() case IntervalTop => NegativeInfinity() @@ -52,7 +52,7 @@ class BoxDomain extends BaseNumericalDomain[Box, BoxDomainCore](BoxDomainCore()) } } - def projectHigh (box : Box) : InfInt = { + private def projectHigh (box : Box) : InfInt = { box match { case IntervalBottom => NegativeInfinity() case IntervalTop => PositiveInfinity() @@ -85,21 +85,27 @@ class BoxDomain extends BaseNumericalDomain[Box, BoxDomainCore](BoxDomainCore()) val homcoeffs = lf.homcoeffs.map(_.toInt).toArray val known = IntNumber(lf.known.toInt) val lfMin = projectLow(linearEvaluation(lf)) + print("LfMin", lfMin) val lfArgmin = linearArgmin(lf); + print("ArgMin", lfArgmin) //print(lowresult) if (lfMin > IntNumber(0)) return bottom else { var newboxes = boxes.clone val infinities = (homcoeffs.indices) filter { i => lfArgmin(i).isInfinity && homcoeffs(i) != 0 } + print("Infiniti", infinities) infinities.size match { - case 0 => + case 0 => { + print("Case Zero") for (i <- homcoeffs.indices) { if (homcoeffs(i) < 0) newboxes(i) = Interval(projectLow(boxes(i)) max (lfArgmin(i) - (lfMin / IntNumber(homcoeffs(i)))), projectHigh(newboxes(i))) if (homcoeffs(i) > 0) newboxes(i) = Interval(projectLow(newboxes(i)), projectHigh(boxes(i)) min (lfArgmin(i) - (lfMin / IntNumber(homcoeffs(i))))) } + } case 1 => { + print("Case Uno") val posinf = infinities.head if (homcoeffs(posinf) < 0) newboxes(posinf) = Interval(projectLow(boxes(posinf)) max ((dotprod(homcoeffs, lfArgmin, posinf) - known).inverse() / IntNumber(homcoeffs(posinf))), projectHigh(newboxes(posinf))) @@ -108,6 +114,7 @@ class BoxDomain extends BaseNumericalDomain[Box, BoxDomainCore](BoxDomainCore()) } case _ => } + print("Return ") new Property(newboxes,false) } } diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala index 663971af..409b061b 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala @@ -19,7 +19,7 @@ package it.unipd.jandom.domains.numerical.box import it.unipd.jandom.domains.numerical.utils.{MathLibrary => M} -import it.unipd.jandom.domains.{Abstraction, CompleteLatticeOperator, IntOperator, InfInt, IntNumber, PositiveInfinity, NegativeInfinity} +import it.unipd.jandom.domains.{Abstraction, CompleteLatticeOperator, IntOperator, InfInt, IntNumber, PositiveInfinity, NegativeInfinity, Undetermined} import Box._ /** @@ -47,7 +47,7 @@ class BoxDomainCore extends CompleteLatticeOperator[Box] case (_, IntervalBottom) => IntervalBottom case (IntervalTop, _) => IntervalTop case (_, IntervalTop) => IntervalTop - case (Interval(low1,high1),Interval(low2,high2)) => Interval(low1 + low2, high1 + high2) + case (Interval(low1,high1),Interval(low2,high2)) => check(Interval(low1 + low2, high1 + high2)) } } @@ -76,7 +76,15 @@ class BoxDomainCore extends CompleteLatticeOperator[Box] val comb = Array(low1 * low2, high1 * high2, low1 * high2, high1 * low2) val new_low = comb.reduceLeft(_ min _) val new_high = comb.reduceLeft(_ max _) - return Interval(new_low,new_high) + return check(Interval(new_low,new_high)) + } + } + + def check(x : Interval) : Box = { + x match { + case Interval(Undetermined(), _) => IntervalTop + case Interval(_, Undetermined()) => IntervalTop + case _ => x } } From ef65902f752b7956b66c47e7980015705952a6d4 Mon Sep 17 00:00:00 2001 From: Mou95 Date: Wed, 28 Mar 2018 11:01:41 +0200 Subject: [PATCH 67/99] Creted file for testing --- .../it/unipd/jandom/domains/InfInt.scala | 30 +++++++++---------- .../numerical/box/BoxDomainCoreSuite.scala | 3 ++ 2 files changed, 18 insertions(+), 15 deletions(-) create mode 100644 core/src/test/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCoreSuite.scala diff --git a/core/src/main/scala/it/unipd/jandom/domains/InfInt.scala b/core/src/main/scala/it/unipd/jandom/domains/InfInt.scala index c3e3972d..b4e9671d 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/InfInt.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/InfInt.scala @@ -18,7 +18,7 @@ package it.unipd.jandom.domains /** - * This class manage integer operation avoid overflow. + * This class manage integer operation avoid overflow. * It defines also a way to manage the "infinite" similar to Double.PositiveInfinity and Double.NegativeInfinity * * @author Mattia Bottaro @@ -30,18 +30,18 @@ trait InfInt { def isInfinity : Boolean /** - * The following method are abstract. + * The following method are abstract. * The real implementation can be found in each sub-case class extending this trait */ - /** + /** * Perform the mathematical sum between the object that invoke this method and the param * @param x is the adding * @return the mathematical sum between the object that invoke this method and x. */ def +(x: InfInt): InfInt - /** + /** * Perform the mathematical division between the object that invoke this method and the param * @param x is the divider * @return the mathematical division between the object that invoke this method and x. @@ -50,9 +50,9 @@ trait InfInt { def *(x: InfInt): InfInt def >(x: InfInt): Boolean - def >=(x: InfInt): - - /** + def >=(x: InfInt): Boolean + + /** * @param x is the second argument of max operator * @return the max element between the object that invoke this method and x. */ @@ -73,8 +73,8 @@ trait InfInt { } } - - /** + + /** * Perform the mathematical difference between the object that invoke this method and the param * @param x is the substracting * @return the mathematical difference between the object that invoke this method and x. @@ -83,7 +83,7 @@ trait InfInt { this + x.inverse() } - /** + /** * Checks if two InfInt are not equal * @param x is the second argument of != operator * @return true if and only if the object that invoke this method is not equal to x. @@ -92,7 +92,7 @@ trait InfInt { !(this == x) } - /** + /** * Checks if the object that invoke this method is less than the argument * @param x is the second argument of < operator * @return true if and only if the object that invoke this method is less than x. @@ -182,8 +182,8 @@ case class IntNumber(n: Int) extends InfInt { } } - /** - * Perform a "safe add", that is a sum that will never do an overflow. + /** + * Perform a "safe add", that is a sum that will never do an overflow. * @param x is the adding * @return the safe add between the object that invoke this method and x. If an overflow is detected, an Infinity is returned. */ @@ -198,8 +198,8 @@ case class IntNumber(n: Int) extends InfInt { return IntNumber(left + right) } - /** - * Perform a "safe multiplication", that is a product that will never do an overflow. + /** + * Perform a "safe multiplication", that is a product that will never do an overflow. * @param x is the adding * @return the safe prduct between the object that invoke this method and x. If an overflow is detected, an Infinity is returned. */ diff --git a/core/src/test/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCoreSuite.scala b/core/src/test/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCoreSuite.scala new file mode 100644 index 00000000..4f8fde91 --- /dev/null +++ b/core/src/test/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCoreSuite.scala @@ -0,0 +1,3 @@ +package it.unipd.jandom.domains.numerical.box + +import org.scalatest.FlatSpec From e198237f19131e63237a7d0666672c0f369751d4 Mon Sep 17 00:00:00 2001 From: Mou95 Date: Wed, 28 Mar 2018 14:50:24 +0200 Subject: [PATCH 68/99] Test for interval --- .travis.yml | 1 + .../domains/numerical/box/BoxDomainCore.scala | 3 +- .../it/unich/jandom/JandomFasterBench.scala | 8 +- .../jandom/JandomParallelotopeBench.scala | 8 +- .../it/unich/jandom/JandomSumBench.scala | 7 +- .../numerical/box/BoxDomainCoreSuite.scala | 216 ++++++++++++++++++ 6 files changed, 231 insertions(+), 12 deletions(-) diff --git a/.travis.yml b/.travis.yml index f4f9bf72..0921ae1d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,3 +4,4 @@ scala: script: - sbt compile + - sbt test diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala index 409b061b..4fdb7e4b 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala @@ -65,11 +65,12 @@ class BoxDomainCore extends CompleteLatticeOperator[Box] /** * @inheritdoc */ - def mult(x : Box, y : Box) : Box = { (x,y) match { case (IntervalBottom, _) => IntervalBottom case (_, IntervalBottom) => IntervalBottom + case (_, Interval(IntNumber(0),IntNumber(0))) => Interval(IntNumber(0),IntNumber(0)) + case (Interval(IntNumber(0),IntNumber(0)), _) => Interval(IntNumber(0),IntNumber(0)) case (IntervalTop, _) => IntervalTop case (_, IntervalTop) => IntervalTop case (Interval(low1,high1),Interval(low2,high2)) => diff --git a/core/src/test/scala/it/unich/jandom/JandomFasterBench.scala b/core/src/test/scala/it/unich/jandom/JandomFasterBench.scala index 7d70d5dc..a419bbdb 100644 --- a/core/src/test/scala/it/unich/jandom/JandomFasterBench.scala +++ b/core/src/test/scala/it/unich/jandom/JandomFasterBench.scala @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with JANDOM. If not, see . */ - +/* package it.unich.jandom import it.unich.jandom.benchmark.FASTLoader @@ -26,14 +26,14 @@ import it.unich.jandom.targets.parameters.IterationStrategy import it.unich.jandom.targets.parameters.NarrowingSpecs._ import it.unich.jandom.targets.parameters.WideningSpecs._ import parma_polyhedra_library.C_Polyhedron - +*/ /** * Example program using ''Jandom'' to analyze the Alice benchmarks and * compare the results with different parameters. In this moment, it compares * the result of the analyisis with standard Kleene iteration and worklist * based ones. */ -object JandomFasterBench extends App with FASTLoader { +/*object JandomFasterBench extends App with FASTLoader { def fastModelAnalyze(program: LTS) { println(s"------> ${program.name}") @@ -74,4 +74,4 @@ object JandomFasterBench extends App with FASTLoader { } for (lts <- ltss) fastModelAnalyze(lts) -} +}*/ diff --git a/core/src/test/scala/it/unich/jandom/JandomParallelotopeBench.scala b/core/src/test/scala/it/unich/jandom/JandomParallelotopeBench.scala index e60c25d3..eb2e1e2f 100644 --- a/core/src/test/scala/it/unich/jandom/JandomParallelotopeBench.scala +++ b/core/src/test/scala/it/unich/jandom/JandomParallelotopeBench.scala @@ -16,7 +16,7 @@ * along with JANDOM. If not, see . */ -package it.unich.jandom +/*package it.unich.jandom import it.unich.jandom.benchmark.FASTLoader import it.unich.jandom.domains.DimensionFiberedProperty @@ -25,7 +25,7 @@ import it.unich.jandom.domains.numerical.ppl.PPLDomain import it.unich.jandom.targets.lts.LTS import it.unich.jandom.targets.parameters.NarrowingSpecs._ import it.unich.jandom.targets.parameters.WideningSpecs._ -import parma_polyhedra_library.C_Polyhedron +import parma_polyhedra_library.C_Polyhedron*/ /** * Example program using ''Jandom'' to analyze the Alice benchmarks and @@ -33,7 +33,7 @@ import parma_polyhedra_library.C_Polyhedron * the result of separately computing using box and parallelotope with respect * to using their product. */ -object JandomParallelotopeBench extends App with FASTLoader { +/*object JandomParallelotopeBench extends App with FASTLoader { var totalEquals = 0 var totalBestReduced = 0 @@ -149,4 +149,4 @@ object JandomParallelotopeBench extends App with FASTLoader { println(s"Total best reduced product: $totalBestReduced") println(s"Total best separate analysis: $totalBestSeparate") println(s"Total uncomparables: $totalUncomparable") -} +}*/ diff --git a/core/src/test/scala/it/unich/jandom/JandomSumBench.scala b/core/src/test/scala/it/unich/jandom/JandomSumBench.scala index dbd7996f..d60c5c55 100644 --- a/core/src/test/scala/it/unich/jandom/JandomSumBench.scala +++ b/core/src/test/scala/it/unich/jandom/JandomSumBench.scala @@ -16,7 +16,7 @@ * along with JANDOM. If not, see . */ -package it.unich.jandom +/*package it.unich.jandom import it.unich.jandom.benchmark.FASTLoader import it.unich.jandom.domains.DimensionFiberedProperty @@ -24,7 +24,7 @@ import it.unich.jandom.domains.numerical._ import it.unich.jandom.domains.numerical.ppl.PPLDomain import it.unich.jandom.targets.lts.LTS import it.unich.jandom.targets.parameters.WideningSpecs._ -import parma_polyhedra_library.C_Polyhedron +import parma_polyhedra_library.C_Polyhedron*/ /** * Example program using ''Jandom'' to analyze the Alice benchmarks and @@ -32,7 +32,7 @@ import parma_polyhedra_library.C_Polyhedron * the result of the analyisis with standard Kleene iteration and worklist * based ones. */ -object JandomSumBench extends App with FASTLoader { +/*object JandomSumBench extends App with FASTLoader { var totalEquals = 0 var totalBestSum = 0 @@ -155,3 +155,4 @@ object JandomSumBench extends App with FASTLoader { println(s"Total best other: $totalBestOther") println(s"Total uncomparables: $totalUncomparable") } +*/ diff --git a/core/src/test/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCoreSuite.scala b/core/src/test/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCoreSuite.scala index 4f8fde91..05b7b802 100644 --- a/core/src/test/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCoreSuite.scala +++ b/core/src/test/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCoreSuite.scala @@ -1,3 +1,219 @@ package it.unipd.jandom.domains.numerical.box +import it.unipd.jandom.domains.{InfInt, IntNumber, PositiveInfinity, NegativeInfinity, Undetermined} +import it.unipd.jandom.domains.numerical.box.Box._ +import it.unipd.jandom.domains.numerical.box.BoxDomainCore._ import org.scalatest.FlatSpec +/** + * Unit Test - Box Domain Core + * + * @author Mauro Carlin <> + * @author Mattia Bottaro <> + */ + +class BoxDomainCoreSuite extends FlatSpec { + val bc = BoxDomainCore() + + val Zero = Box.Interval(IntNumber(0), IntNumber(0)) + val One = Box.Interval(IntNumber(1), IntNumber(1)) + val Mone = Box.Interval(IntNumber(-1), IntNumber(-1)) + val zeroTen = Box.Interval(IntNumber(0), IntNumber(10)) + val MtenZero = Box.Interval(IntNumber(-10), IntNumber(0)) + val MtenTen = Box.Interval(IntNumber(-10), IntNumber(10)) + val oneInf = Box.Interval(IntNumber(1), PositiveInfinity()) + val MinfMone = Box.Interval(NegativeInfinity(), IntNumber(-1)) + val MinfZero = Box.Interval(NegativeInfinity(), IntNumber(0)) + + "BoxDomainCore.alpha" should + " - return the corresponding abstract value" in { + assert(bc.alpha(1) === One) + assert(bc.alpha(0) === Zero) + assert(bc.alpha(15) !== One) + } + + "BoxDomainCore.sum" should + " - return the sum of the two Boxs given as input" in { + // IntervalBottom + assert(bc.sum(IntervalBottom, zeroTen) === IntervalBottom) + assert(bc.sum(IntervalBottom, IntervalTop) === IntervalBottom) + assert(bc.sum(oneInf, IntervalBottom) === IntervalBottom) + assert(bc.sum(IntervalTop, IntervalBottom) === IntervalBottom) + assert(bc.sum(IntervalBottom, IntervalBottom) === IntervalBottom) + // IntervalTop + assert(bc.sum(IntervalTop, MtenZero) === IntervalTop) + assert(bc.sum(Zero, IntervalTop) === IntervalTop) + assert(bc.sum(IntervalTop, IntervalTop) === IntervalTop) + // Interval + assert(bc.sum(One, Zero) === One) + assert(bc.sum(zeroTen, MtenZero) === MtenTen) + assert(bc.sum(One, MinfMone) === MinfZero) + assert(bc.sum(MinfMone, One) === MinfZero) + assert(bc.sum(Zero, oneInf) === oneInf) + assert(bc.sum(oneInf, Zero) === oneInf) + assert(bc.sum(oneInf, MinfMone) === IntervalTop) + assert(bc.sum(MinfMone, oneInf) === IntervalTop) + } + + "BoxDomainCore.inverse" should + " - return the inverse of the Box given as input" in { + // IntervalBottom + assert(bc.inverse(IntervalBottom) === IntervalBottom) + // IntervalTop + assert(bc.inverse(IntervalTop) === IntervalTop) + // Interval + assert(bc.inverse(One) === Mone) + assert(bc.inverse(Mone) === One) + assert(bc.inverse(zeroTen) === MtenZero) + assert(bc.inverse(MtenZero) === zeroTen) + assert(bc.inverse(MtenTen) === MtenTen) + assert(bc.inverse(MinfMone) === oneInf) + assert(bc.inverse(oneInf) === MinfMone) + } + + + "BoxDomainCore.mult" should + " - return the mult of the two Boxs given as input" in { + val MhundredZero = Box.Interval(IntNumber(-100), IntNumber(0)) + val MhudredHundred = Box.Interval(IntNumber(-100), IntNumber(100)) + // IntervalBottom + assert(bc.sum(IntervalBottom, One) === IntervalBottom) + assert(bc.sum(IntervalBottom, IntervalTop) === IntervalBottom) + assert(bc.sum(MtenTen, IntervalBottom) === IntervalBottom) + assert(bc.sum(IntervalTop, IntervalBottom) === IntervalBottom) + assert(bc.sum(IntervalBottom, IntervalBottom) === IntervalBottom) + // IntervalTop + assert(bc.sum(IntervalTop, Mone) === IntervalTop) + assert(bc.sum(Mone, IntervalTop) === IntervalTop) + assert(bc.sum(IntervalTop, IntervalTop) === IntervalTop) + // Interval 0 + assert(bc.mult(IntervalTop, Zero) === Zero) + assert(bc.mult(Zero, IntervalTop) === Zero) + assert(bc.mult(IntervalBottom, Zero) === IntervalBottom) + assert(bc.mult(Zero, IntervalBottom) === IntervalBottom) + assert(bc.sum(Zero, oneInf) === Zero) + assert(bc.sum(oneInf, Zero) === Zero) + assert(bc.sum(One, Zero) === Zero) + assert(bc.sum(Zero, One) === Zero) + // Interval + assert(bc.sum(zeroTen, MtenZero) === MhundredZero) + assert(bc.sum(MtenZero, zeroTen) === MhundredZero) + assert(bc.sum(MinfMone, One) === MinfMone) + assert(bc.sum(One, MinfMone) === MinfMone) + assert(bc.mult(MtenTen, MtenTen) === MhudredHundred) + assert(bc.sum(oneInf, MinfMone) === MinfZero) + assert(bc.sum(MinfMone, oneInf) === MinfZero) + assert(bc.sum(oneInf, Mone) === MinfMone) + assert(bc.sum(Mone, oneInf) === MinfMone) + } + + "BoxDomainCore.division" should + " - return the division of the two Boxs given as input" in { + val twoThree = Box.Interval(IntNumber(2), IntNumber(3)) + val twoThirteen = Box.Interval(IntNumber(2), IntNumber(13)) + val zeroFour = Box.Interval(IntNumber(0), IntNumber(4)) + // IntervalBottom + assert(bc.division(IntervalBottom, MtenTen) === IntervalBottom) + assert(bc.division(IntervalBottom, IntervalTop) === IntervalBottom) + assert(bc.division(MtenTen, IntervalBottom) === IntervalBottom) + assert(bc.division(IntervalTop, IntervalBottom) === IntervalBottom) + assert(bc.division(IntervalBottom, IntervalBottom) === IntervalBottom) + // IntervalTop + assert(bc.division(IntervalTop, One) === IntervalTop) + assert(bc.division(One, IntervalTop) === IntervalTop) + assert(bc.division(IntervalTop, IntervalTop) === IntervalTop) + // Interval [0,0]) + assert(bc.division(IntervalTop, Zero) === IntervalBottom) + assert(bc.division(Zero, IntervalTop) === Zero) + assert(bc.division(Zero, MtenTen) === Zero) + assert(bc.division(MtenTen, Zero) === IntervalBottom) + + // Interval + assert(bc.division(MtenTen, MtenTen) === MtenTen) + assert(bc.division(twoThirteen, twoThree) === zeroFour) + } + + "BoxDomainCore.remainder" should + " - return the remainder of the two Boxs given as input" in { + // IntervalBottom + /*assert(bc.remainder(IntervalBottom, One) === IntervalBottom) + assert(bc.remainder(IntervalBottom, IntervalTop) === IntervalBottom) + assert(bc.remainder(One, IntervalBottom) === IntervalBottom) + assert(bc.remainder(IntervalTop, IntervalBottom) === IntervalBottom) + // IntervalTop + assert(bc.remainder(IntervalTop, MtenTen) === IntervalTop) + assert(bc.remainder(MtenTen, IntervalTop) === IntervalTop) + assert(bc.remainder(IntervalTop, IntervalTop) === IntervalTop) + // Interval(0) + assert(bc.remainder(IntervalTop, Zero) === IntervalBottom) + assert(bc.remainder(Zero, IntervalTop) === Zero) + assert(bc.remainder(Zero, MtenTen) === Zero) + assert(bc.remainder(MtenTen, Zero) === IntervalBottom) + assert(bc.remainder(Zero, Zero) === IntervalBottom) + // Interval + assert(bc.remainder(MtenTen, MtenTen) === zero)*/ + } + + "BoxDomainCore.lub" should + " - return the least upper bound of the two Boxs given as input" in { + val MinfTen = Box.Interval(NegativeInfinity(), IntNumber(10)) + val zeroOne = Box.Interval(IntNumber(0), IntNumber(1)) + // IntervalBottom + assert(bc.lub(IntervalBottom, MtenTen) === MtenTen) + assert(bc.lub(MtenTen, IntervalBottom) === MtenTen) + assert(bc.lub(IntervalBottom, IntervalBottom) === IntervalBottom) + // IntervalTop + assert(bc.lub(IntervalTop, One) === IntervalTop) + assert(bc.lub(One, IntervalTop) === IntervalTop) + assert(bc.lub(IntervalTop, IntervalBottom) === IntervalTop) + assert(bc.lub(IntervalBottom, IntervalTop) === IntervalTop) + assert(bc.lub(IntervalTop, IntervalTop) === IntervalTop) + // Interval + assert(bc.lub(oneInf, MinfMone) === IntervalTop) + assert(bc.lub(MinfMone, oneInf) === IntervalTop) + assert(bc.lub(MinfMone, MtenTen) === MinfTen) + assert(bc.lub(MtenTen, MinfMone) === MinfTen) + assert(bc.lub(Zero, One) === zeroOne) + assert(bc.lub(One, Zero) === zeroOne) + } + + "BoxDomainCore.glb" should + " - return the greatest lower bound between the two Boxs given as input" in { + val MtenMone = Box.Interval(IntNumber(-10), IntNumber(-1)) + val zeroOne = Box.Interval(IntNumber(0), IntNumber(1)) + // IntervalBottom + assert(bc.lub(IntervalBottom, MtenTen) === IntervalBottom) + assert(bc.lub(MtenTen, IntervalBottom) === IntervalBottom) + assert(bc.lub(IntervalBottom, IntervalBottom) === IntervalBottom) + // IntervalTop + assert(bc.lub(IntervalTop, One) === One) + assert(bc.lub(One, IntervalTop) === One) + assert(bc.lub(IntervalTop, IntervalBottom) === IntervalBottom) + assert(bc.lub(IntervalBottom, IntervalTop) === IntervalBottom) + assert(bc.lub(IntervalTop, IntervalTop) === IntervalTop) + // Interval + assert(bc.lub(oneInf, MinfMone) === IntervalBottom) + assert(bc.lub(MinfMone, oneInf) === IntervalBottom) + assert(bc.lub(MinfMone, MtenTen) === MtenMone) + assert(bc.lub(MtenTen, MinfMone) === MtenMone) + assert(bc.lub(Zero, One) === IntervalBottom) + assert(bc.lub(One, Zero) === IntervalBottom) + } + + "BoxDomainCore.compare" should + " - return the comparison between the two Boxs given as input" in { + // IntervalTop + assert(bc.compare(IntervalTop, IntervalTop) === Option(0)) + assert(bc.compare(IntervalTop, MtenTen) === Option(1)) + assert(bc.compare(IntervalTop, IntervalBottom) === Option(1)) + assert(bc.compare(MtenTen, IntervalTop) === Option(-1)) + assert(bc.compare(IntervalBottom, IntervalTop) === Option(-1)) + // IntervalBottom + assert(bc.compare(IntervalBottom, IntervalBottom) === Option(0)) + assert(bc.compare(IntervalBottom, MinfMone) === Option(-1)) + assert(bc.compare(MinfMone, IntervalBottom) === Option(1)) + // Interval + assert(bc.compare(One, Zero) === Option.empty) + assert(bc.compare(MinfMone, oneInf) === Option.empty) + assert(bc.compare(MtenTen, MtenTen) === Option(0)) + } +} // end of BoxDomainCoreSuite From 66bdde3c56342ff5cad39c6375f1939547aafd14 Mon Sep 17 00:00:00 2001 From: Mou95 Date: Wed, 28 Mar 2018 15:12:16 +0200 Subject: [PATCH 69/99] Fixed test --- .../domains/numerical/box/BoxDomainCore.scala | 2 + .../numerical/box/BoxDomainCoreSuite.scala | 69 +++++++++---------- 2 files changed, 36 insertions(+), 35 deletions(-) diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala index 4fdb7e4b..5c277d1e 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala @@ -85,6 +85,7 @@ class BoxDomainCore extends CompleteLatticeOperator[Box] x match { case Interval(Undetermined(), _) => IntervalTop case Interval(_, Undetermined()) => IntervalTop + case Interval(NegativeInfinity(), PositiveInfinity()) => IntervalTop case _ => x } } @@ -96,6 +97,7 @@ class BoxDomainCore extends CompleteLatticeOperator[Box] (x,y) match { case (IntervalBottom, _) => IntervalBottom case (_, IntervalBottom) => IntervalBottom + case (_, Interval(IntNumber(0),IntNumber(0))) => IntervalBottom case (IntervalTop, _) => IntervalTop case (_, IntervalTop) => IntervalTop case (Interval (low1, high1), Interval (low2,high2)) => diff --git a/core/src/test/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCoreSuite.scala b/core/src/test/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCoreSuite.scala index 05b7b802..a22509de 100644 --- a/core/src/test/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCoreSuite.scala +++ b/core/src/test/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCoreSuite.scala @@ -76,34 +76,34 @@ class BoxDomainCoreSuite extends FlatSpec { val MhundredZero = Box.Interval(IntNumber(-100), IntNumber(0)) val MhudredHundred = Box.Interval(IntNumber(-100), IntNumber(100)) // IntervalBottom - assert(bc.sum(IntervalBottom, One) === IntervalBottom) - assert(bc.sum(IntervalBottom, IntervalTop) === IntervalBottom) - assert(bc.sum(MtenTen, IntervalBottom) === IntervalBottom) - assert(bc.sum(IntervalTop, IntervalBottom) === IntervalBottom) - assert(bc.sum(IntervalBottom, IntervalBottom) === IntervalBottom) + assert(bc.mult(IntervalBottom, One) === IntervalBottom) + assert(bc.mult(IntervalBottom, IntervalTop) === IntervalBottom) + assert(bc.mult(MtenTen, IntervalBottom) === IntervalBottom) + assert(bc.mult(IntervalTop, IntervalBottom) === IntervalBottom) + assert(bc.mult(IntervalBottom, IntervalBottom) === IntervalBottom) // IntervalTop - assert(bc.sum(IntervalTop, Mone) === IntervalTop) - assert(bc.sum(Mone, IntervalTop) === IntervalTop) - assert(bc.sum(IntervalTop, IntervalTop) === IntervalTop) + assert(bc.mult(IntervalTop, Mone) === IntervalTop) + assert(bc.mult(Mone, IntervalTop) === IntervalTop) + assert(bc.mult(IntervalTop, IntervalTop) === IntervalTop) // Interval 0 assert(bc.mult(IntervalTop, Zero) === Zero) assert(bc.mult(Zero, IntervalTop) === Zero) assert(bc.mult(IntervalBottom, Zero) === IntervalBottom) assert(bc.mult(Zero, IntervalBottom) === IntervalBottom) - assert(bc.sum(Zero, oneInf) === Zero) - assert(bc.sum(oneInf, Zero) === Zero) - assert(bc.sum(One, Zero) === Zero) - assert(bc.sum(Zero, One) === Zero) + assert(bc.mult(Zero, oneInf) === Zero) + assert(bc.mult(oneInf, Zero) === Zero) + assert(bc.mult(One, Zero) === Zero) + assert(bc.mult(Zero, One) === Zero) // Interval - assert(bc.sum(zeroTen, MtenZero) === MhundredZero) - assert(bc.sum(MtenZero, zeroTen) === MhundredZero) - assert(bc.sum(MinfMone, One) === MinfMone) - assert(bc.sum(One, MinfMone) === MinfMone) + assert(bc.mult(zeroTen, MtenZero) === MhundredZero) + assert(bc.mult(MtenZero, zeroTen) === MhundredZero) + assert(bc.mult(MinfMone, One) === MinfMone) + assert(bc.mult(One, MinfMone) === MinfMone) assert(bc.mult(MtenTen, MtenTen) === MhudredHundred) - assert(bc.sum(oneInf, MinfMone) === MinfZero) - assert(bc.sum(MinfMone, oneInf) === MinfZero) - assert(bc.sum(oneInf, Mone) === MinfMone) - assert(bc.sum(Mone, oneInf) === MinfMone) + assert(bc.mult(oneInf, MinfMone) === MinfZero) + assert(bc.mult(MinfMone, oneInf) === MinfZero) + assert(bc.mult(oneInf, Mone) === MinfMone) + assert(bc.mult(Mone, oneInf) === MinfMone) } "BoxDomainCore.division" should @@ -179,24 +179,23 @@ class BoxDomainCoreSuite extends FlatSpec { "BoxDomainCore.glb" should " - return the greatest lower bound between the two Boxs given as input" in { val MtenMone = Box.Interval(IntNumber(-10), IntNumber(-1)) - val zeroOne = Box.Interval(IntNumber(0), IntNumber(1)) // IntervalBottom - assert(bc.lub(IntervalBottom, MtenTen) === IntervalBottom) - assert(bc.lub(MtenTen, IntervalBottom) === IntervalBottom) - assert(bc.lub(IntervalBottom, IntervalBottom) === IntervalBottom) + assert(bc.glb(IntervalBottom, MtenTen) === IntervalBottom) + assert(bc.glb(MtenTen, IntervalBottom) === IntervalBottom) + assert(bc.glb(IntervalBottom, IntervalBottom) === IntervalBottom) // IntervalTop - assert(bc.lub(IntervalTop, One) === One) - assert(bc.lub(One, IntervalTop) === One) - assert(bc.lub(IntervalTop, IntervalBottom) === IntervalBottom) - assert(bc.lub(IntervalBottom, IntervalTop) === IntervalBottom) - assert(bc.lub(IntervalTop, IntervalTop) === IntervalTop) + assert(bc.glb(IntervalTop, One) === One) + assert(bc.glb(One, IntervalTop) === One) + assert(bc.glb(IntervalTop, IntervalBottom) === IntervalBottom) + assert(bc.glb(IntervalBottom, IntervalTop) === IntervalBottom) + assert(bc.glb(IntervalTop, IntervalTop) === IntervalTop) // Interval - assert(bc.lub(oneInf, MinfMone) === IntervalBottom) - assert(bc.lub(MinfMone, oneInf) === IntervalBottom) - assert(bc.lub(MinfMone, MtenTen) === MtenMone) - assert(bc.lub(MtenTen, MinfMone) === MtenMone) - assert(bc.lub(Zero, One) === IntervalBottom) - assert(bc.lub(One, Zero) === IntervalBottom) + assert(bc.glb(oneInf, MinfMone) === IntervalBottom) + assert(bc.glb(MinfMone, oneInf) === IntervalBottom) + assert(bc.glb(MinfMone, MtenTen) === MtenMone) + assert(bc.glb(MtenTen, MinfMone) === MtenMone) + assert(bc.glb(Zero, One) === IntervalBottom) + assert(bc.glb(One, Zero) === IntervalBottom) } "BoxDomainCore.compare" should From 66f6c7f4e118d6f4cc929c94efe284f6be723523 Mon Sep 17 00:00:00 2001 From: Mou95 Date: Wed, 28 Mar 2018 15:27:57 +0200 Subject: [PATCH 70/99] Fixed test --- .../it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala | 3 ++- .../jandom/domains/numerical/box/BoxDomainCoreSuite.scala | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala index 5c277d1e..88b44b4d 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala @@ -98,6 +98,7 @@ class BoxDomainCore extends CompleteLatticeOperator[Box] case (IntervalBottom, _) => IntervalBottom case (_, IntervalBottom) => IntervalBottom case (_, Interval(IntNumber(0),IntNumber(0))) => IntervalBottom + case (Interval(IntNumber(0),IntNumber(0)), _) => Interval(IntNumber(0),IntNumber(0)) case (IntervalTop, _) => IntervalTop case (_, IntervalTop) => IntervalTop case (Interval (low1, high1), Interval (low2,high2)) => @@ -138,7 +139,7 @@ class BoxDomainCore extends CompleteLatticeOperator[Box] case (Interval (low1, high1), Interval (low2, high2)) => val new_low = low1 min low2 val new_high = high1 max high2 - return Interval (new_low, new_high) + return check(Interval (new_low, new_high)) } } diff --git a/core/src/test/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCoreSuite.scala b/core/src/test/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCoreSuite.scala index a22509de..e18aac9a 100644 --- a/core/src/test/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCoreSuite.scala +++ b/core/src/test/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCoreSuite.scala @@ -100,7 +100,7 @@ class BoxDomainCoreSuite extends FlatSpec { assert(bc.mult(MinfMone, One) === MinfMone) assert(bc.mult(One, MinfMone) === MinfMone) assert(bc.mult(MtenTen, MtenTen) === MhudredHundred) - assert(bc.mult(oneInf, MinfMone) === MinfZero) + assert(bc.mult(oneInf, MinfMone) === MinfMone) assert(bc.mult(MinfMone, oneInf) === MinfZero) assert(bc.mult(oneInf, Mone) === MinfMone) assert(bc.mult(Mone, oneInf) === MinfMone) From 15d11705df273567e6b8390f88cf2f0e274b06ec Mon Sep 17 00:00:00 2001 From: Mou95 Date: Wed, 28 Mar 2018 15:42:21 +0200 Subject: [PATCH 71/99] Fixed test --- .travis.yml | 1 - .../scala/it/unich/jandom/targets/NumericExpression.scala | 4 +--- .../it/unipd/jandom/domains/numerical/box/BoxDomain.scala | 6 ------ .../unipd/jandom/domains/numerical/box/BoxDomainCore.scala | 1 - .../jandom/domains/numerical/box/BoxDomainCoreSuite.scala | 6 +++--- 5 files changed, 4 insertions(+), 14 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0921ae1d..b5358b53 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,5 +3,4 @@ scala: - 2.12.4 script: - - sbt compile - sbt test diff --git a/core/src/main/scala/it/unich/jandom/targets/NumericExpression.scala b/core/src/main/scala/it/unich/jandom/targets/NumericExpression.scala index eed18adf..64a01116 100644 --- a/core/src/main/scala/it/unich/jandom/targets/NumericExpression.scala +++ b/core/src/main/scala/it/unich/jandom/targets/NumericExpression.scala @@ -147,10 +147,8 @@ object NumericExpression { def assignTo[Property <: NumericalProperty[Property]](v: Int)(input: Property): Property = input.linearAssignment(v, lf) - override def lteZero[Property <: NumericalProperty[Property]](input: Property): Property = { - print("LinearIneq ",input.linearInequality(lf)) + override def lteZero[Property <: NumericalProperty[Property]](input: Property): Property = input.linearInequality(lf) - } override def ltZero[Property <: NumericalProperty[Property]](input: Property): Property = input.linearInequality(lf) diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala index 8aa19873..54b9b18d 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala @@ -96,27 +96,22 @@ class BoxDomain extends BaseNumericalDomain[Box, BoxDomainCore](BoxDomainCore()) val homcoeffs = lf.homcoeffs.map(_.toInt).toArray val known = IntNumber(lf.known.toInt) val lfMin = projectLow(linearEvaluation(lf)) - print("LfMin", lfMin) val lfArgmin = linearArgmin(lf); - print("ArgMin", lfArgmin) //print(lowresult) if (lfMin > IntNumber(0)) return bottom else { var newboxes = boxes.clone val infinities = (homcoeffs.indices) filter { i => lfArgmin(i).isInfinity && homcoeffs(i) != 0 } - print("Infiniti", infinities) infinities.size match { case 0 => { - print("Case Zero") for (i <- homcoeffs.indices) { if (homcoeffs(i) < 0) newboxes(i) = Interval(projectLow(boxes(i)) max (lfArgmin(i) - (lfMin / IntNumber(homcoeffs(i)))), projectHigh(newboxes(i))) if (homcoeffs(i) > 0) newboxes(i) = Interval(projectLow(newboxes(i)), projectHigh(boxes(i)) min (lfArgmin(i) - (lfMin / IntNumber(homcoeffs(i))))) } } case 1 => { - print("Case Uno") val posinf = infinities.head if (homcoeffs(posinf) < 0) newboxes(posinf) = Interval(projectLow(boxes(posinf)) max ((dotprod(homcoeffs, lfArgmin, posinf) - known).inverse() / IntNumber(homcoeffs(posinf))), projectHigh(newboxes(posinf))) @@ -125,7 +120,6 @@ class BoxDomain extends BaseNumericalDomain[Box, BoxDomainCore](BoxDomainCore()) } case _ => } - print("Return ") new Property(newboxes,false) } } diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala index 88b44b4d..53449cb1 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala @@ -147,7 +147,6 @@ class BoxDomainCore extends CompleteLatticeOperator[Box] * @inheritdoc */ def glb(x : Box, y : Box) : Box = { - print("GLB",x,y) (x, y) match { case (IntervalTop, _) => return y case (_, IntervalTop) => return x diff --git a/core/src/test/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCoreSuite.scala b/core/src/test/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCoreSuite.scala index e18aac9a..71f57307 100644 --- a/core/src/test/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCoreSuite.scala +++ b/core/src/test/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCoreSuite.scala @@ -101,7 +101,7 @@ class BoxDomainCoreSuite extends FlatSpec { assert(bc.mult(One, MinfMone) === MinfMone) assert(bc.mult(MtenTen, MtenTen) === MhudredHundred) assert(bc.mult(oneInf, MinfMone) === MinfMone) - assert(bc.mult(MinfMone, oneInf) === MinfZero) + assert(bc.mult(MinfMone, oneInf) === MinfMone) assert(bc.mult(oneInf, Mone) === MinfMone) assert(bc.mult(Mone, oneInf) === MinfMone) } @@ -110,7 +110,7 @@ class BoxDomainCoreSuite extends FlatSpec { " - return the division of the two Boxs given as input" in { val twoThree = Box.Interval(IntNumber(2), IntNumber(3)) val twoThirteen = Box.Interval(IntNumber(2), IntNumber(13)) - val zeroFour = Box.Interval(IntNumber(0), IntNumber(4)) + val zeroSix = Box.Interval(IntNumber(0), IntNumber(6)) // IntervalBottom assert(bc.division(IntervalBottom, MtenTen) === IntervalBottom) assert(bc.division(IntervalBottom, IntervalTop) === IntervalBottom) @@ -129,7 +129,7 @@ class BoxDomainCoreSuite extends FlatSpec { // Interval assert(bc.division(MtenTen, MtenTen) === MtenTen) - assert(bc.division(twoThirteen, twoThree) === zeroFour) + assert(bc.division(twoThirteen, twoThree) === zeroSix) } "BoxDomainCore.remainder" should From c78c7f9c3cd0f24e40b63eb23b812e030008f3de Mon Sep 17 00:00:00 2001 From: Mou95 Date: Wed, 28 Mar 2018 15:51:13 +0200 Subject: [PATCH 72/99] Fixed test --- .../test/scala/it/unich/jandom/JandomFasterBench.scala | 8 ++++---- .../scala/it/unich/jandom/JandomParallelotopeBench.scala | 8 ++++---- core/src/test/scala/it/unich/jandom/JandomSumBench.scala | 7 +++---- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/core/src/test/scala/it/unich/jandom/JandomFasterBench.scala b/core/src/test/scala/it/unich/jandom/JandomFasterBench.scala index a419bbdb..7d70d5dc 100644 --- a/core/src/test/scala/it/unich/jandom/JandomFasterBench.scala +++ b/core/src/test/scala/it/unich/jandom/JandomFasterBench.scala @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with JANDOM. If not, see . */ -/* + package it.unich.jandom import it.unich.jandom.benchmark.FASTLoader @@ -26,14 +26,14 @@ import it.unich.jandom.targets.parameters.IterationStrategy import it.unich.jandom.targets.parameters.NarrowingSpecs._ import it.unich.jandom.targets.parameters.WideningSpecs._ import parma_polyhedra_library.C_Polyhedron -*/ + /** * Example program using ''Jandom'' to analyze the Alice benchmarks and * compare the results with different parameters. In this moment, it compares * the result of the analyisis with standard Kleene iteration and worklist * based ones. */ -/*object JandomFasterBench extends App with FASTLoader { +object JandomFasterBench extends App with FASTLoader { def fastModelAnalyze(program: LTS) { println(s"------> ${program.name}") @@ -74,4 +74,4 @@ import parma_polyhedra_library.C_Polyhedron } for (lts <- ltss) fastModelAnalyze(lts) -}*/ +} diff --git a/core/src/test/scala/it/unich/jandom/JandomParallelotopeBench.scala b/core/src/test/scala/it/unich/jandom/JandomParallelotopeBench.scala index eb2e1e2f..e60c25d3 100644 --- a/core/src/test/scala/it/unich/jandom/JandomParallelotopeBench.scala +++ b/core/src/test/scala/it/unich/jandom/JandomParallelotopeBench.scala @@ -16,7 +16,7 @@ * along with JANDOM. If not, see . */ -/*package it.unich.jandom +package it.unich.jandom import it.unich.jandom.benchmark.FASTLoader import it.unich.jandom.domains.DimensionFiberedProperty @@ -25,7 +25,7 @@ import it.unich.jandom.domains.numerical.ppl.PPLDomain import it.unich.jandom.targets.lts.LTS import it.unich.jandom.targets.parameters.NarrowingSpecs._ import it.unich.jandom.targets.parameters.WideningSpecs._ -import parma_polyhedra_library.C_Polyhedron*/ +import parma_polyhedra_library.C_Polyhedron /** * Example program using ''Jandom'' to analyze the Alice benchmarks and @@ -33,7 +33,7 @@ import parma_polyhedra_library.C_Polyhedron*/ * the result of separately computing using box and parallelotope with respect * to using their product. */ -/*object JandomParallelotopeBench extends App with FASTLoader { +object JandomParallelotopeBench extends App with FASTLoader { var totalEquals = 0 var totalBestReduced = 0 @@ -149,4 +149,4 @@ import parma_polyhedra_library.C_Polyhedron*/ println(s"Total best reduced product: $totalBestReduced") println(s"Total best separate analysis: $totalBestSeparate") println(s"Total uncomparables: $totalUncomparable") -}*/ +} diff --git a/core/src/test/scala/it/unich/jandom/JandomSumBench.scala b/core/src/test/scala/it/unich/jandom/JandomSumBench.scala index d60c5c55..dbd7996f 100644 --- a/core/src/test/scala/it/unich/jandom/JandomSumBench.scala +++ b/core/src/test/scala/it/unich/jandom/JandomSumBench.scala @@ -16,7 +16,7 @@ * along with JANDOM. If not, see . */ -/*package it.unich.jandom +package it.unich.jandom import it.unich.jandom.benchmark.FASTLoader import it.unich.jandom.domains.DimensionFiberedProperty @@ -24,7 +24,7 @@ import it.unich.jandom.domains.numerical._ import it.unich.jandom.domains.numerical.ppl.PPLDomain import it.unich.jandom.targets.lts.LTS import it.unich.jandom.targets.parameters.WideningSpecs._ -import parma_polyhedra_library.C_Polyhedron*/ +import parma_polyhedra_library.C_Polyhedron /** * Example program using ''Jandom'' to analyze the Alice benchmarks and @@ -32,7 +32,7 @@ import parma_polyhedra_library.C_Polyhedron*/ * the result of the analyisis with standard Kleene iteration and worklist * based ones. */ -/*object JandomSumBench extends App with FASTLoader { +object JandomSumBench extends App with FASTLoader { var totalEquals = 0 var totalBestSum = 0 @@ -155,4 +155,3 @@ import parma_polyhedra_library.C_Polyhedron*/ println(s"Total best other: $totalBestOther") println(s"Total uncomparables: $totalUncomparable") } -*/ From b0edd30cf20819a18fa1d5bf1f7942aa7a7693be Mon Sep 17 00:00:00 2001 From: BottCode Date: Thu, 29 Mar 2018 10:15:13 +0200 Subject: [PATCH 73/99] canghed behaviour on infinities --- .../it/unipd/jandom/domains/InfInt.scala | 39 ++++++++++--------- .../domains/numerical/box/BoxDomainCore.scala | 8 ++-- .../it/unich/jandom/JandomFasterBench.scala | 7 ++-- .../jandom/JandomParallelotopeBench.scala | 7 ++-- .../it/unich/jandom/JandomSumBench.scala | 7 ++-- .../numerical/box/BoxDomainCoreSuite.scala | 2 +- 6 files changed, 39 insertions(+), 31 deletions(-) diff --git a/core/src/main/scala/it/unipd/jandom/domains/InfInt.scala b/core/src/main/scala/it/unipd/jandom/domains/InfInt.scala index b4e9671d..61c118bb 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/InfInt.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/InfInt.scala @@ -69,7 +69,7 @@ trait InfInt { case PositiveInfinity() => NegativeInfinity() case NegativeInfinity() => PositiveInfinity() case IntNumber(x) => IntNumber(-x) - case _ => Undetermined() + //case _ => Undetermined() } } @@ -116,7 +116,7 @@ case class IntNumber(n: Int) extends InfInt { x match { case NegativeInfinity() => NegativeInfinity() case PositiveInfinity() => PositiveInfinity() - case Undetermined() => Undetermined() + // // case Undetermined() => Undetermined() case IntNumber(m) => safeAdd(n,m) } } @@ -125,7 +125,7 @@ case class IntNumber(n: Int) extends InfInt { if(n == 0) return IntNumber(0) x match { case IntNumber(m) => safeMul(n,m) - case Undetermined() => Undetermined() + // // case Undetermined() => Undetermined() case _ => if(n > 0) return x return x.inverse() @@ -152,7 +152,7 @@ case class IntNumber(n: Int) extends InfInt { def /(x: InfInt): InfInt = { x match { case IntNumber(m) => IntNumber(n / m) - case Undetermined() => Undetermined() + // // case Undetermined() => Undetermined() case _ => IntNumber(0) } } @@ -169,7 +169,7 @@ case class IntNumber(n: Int) extends InfInt { case IntNumber(m) => IntNumber(n max m) case PositiveInfinity() => PositiveInfinity() case NegativeInfinity() => IntNumber(n) - case _ => Undetermined() + //case _ => Undetermined() } } @@ -178,7 +178,7 @@ case class IntNumber(n: Int) extends InfInt { case IntNumber(m) => IntNumber(n min m) case PositiveInfinity() => IntNumber(n) case NegativeInfinity() => NegativeInfinity() - case _ => Undetermined() + //case _ => Undetermined() } } @@ -235,9 +235,10 @@ case class NegativeInfinity() extends InfInt { def +(x: InfInt): InfInt = { x match { - case PositiveInfinity() => Undetermined() - case Undetermined() => Undetermined() case _ => NegativeInfinity() + /*case PositiveInfinity() => Undetermined() + // // case Undetermined() => Undetermined() + case _ => NegativeInfinity()*/ } } @@ -249,7 +250,7 @@ case class NegativeInfinity() extends InfInt { if (m < 0) return PositiveInfinity() return IntNumber(0) - case Undetermined() => Undetermined() + // // case Undetermined() => Undetermined() case PositiveInfinity() => NegativeInfinity() case NegativeInfinity() => PositiveInfinity() } @@ -259,7 +260,7 @@ case class NegativeInfinity() extends InfInt { def >(x: InfInt): Boolean = { x match { case NegativeInfinity() => false - case Undetermined() => false + // // case Undetermined() => false case _ => false } } @@ -278,7 +279,7 @@ case class NegativeInfinity() extends InfInt { return PositiveInfinity() return NegativeInfinity() - case Undetermined() => Undetermined() + // // case Undetermined() => Undetermined() case _ => IntNumber(0) // Inf / Inf = Inf * (1 / Inf) = Inf * 0 } } @@ -299,7 +300,7 @@ case class NegativeInfinity() extends InfInt { def min(x: InfInt): InfInt = { x match { - case Undetermined() => Undetermined() + // // case Undetermined() => Undetermined() case _ => NegativeInfinity() } } @@ -314,8 +315,8 @@ case class PositiveInfinity() extends InfInt { def +(x: InfInt): InfInt = { x match { - case NegativeInfinity() => Undetermined() - case Undetermined() => Undetermined() + /*case NegativeInfinity() => Undetermined() + // // case Undetermined() => Undetermined()*/ case _ => PositiveInfinity() } } @@ -335,7 +336,7 @@ case class PositiveInfinity() extends InfInt { def >(x: InfInt): Boolean = { x match { case NegativeInfinity() => true - case Undetermined() => true // todo think + // // case Undetermined() => true // todo think case _ => false } } @@ -359,21 +360,21 @@ case class PositiveInfinity() extends InfInt { if(m < 0) return NegativeInfinity() return PositiveInfinity() // TODO EXCEPTION /0 - case Undetermined() => Undetermined() + // // case Undetermined() => Undetermined() case _ => IntNumber(0) // Inf / Inf = Inf * (1 / Inf) = Inf * 0 } } def max(x: InfInt): InfInt = { x match { - case Undetermined() => Undetermined() + // // case Undetermined() => Undetermined() case _ => PositiveInfinity() } } def min(x: InfInt): InfInt = { x match { - case Undetermined() => Undetermined() + // // case Undetermined() => Undetermined() case _ => x } } @@ -383,6 +384,7 @@ case class PositiveInfinity() extends InfInt { } // case infinity - infinity +/* case class Undetermined() extends InfInt { def isInfinity = false @@ -420,3 +422,4 @@ case class Undetermined() extends InfInt { } } +*/ diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala index 53449cb1..0cac8bdf 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala @@ -19,7 +19,7 @@ package it.unipd.jandom.domains.numerical.box import it.unipd.jandom.domains.numerical.utils.{MathLibrary => M} -import it.unipd.jandom.domains.{Abstraction, CompleteLatticeOperator, IntOperator, InfInt, IntNumber, PositiveInfinity, NegativeInfinity, Undetermined} +import it.unipd.jandom.domains.{Abstraction, CompleteLatticeOperator, IntOperator, InfInt, IntNumber, PositiveInfinity, NegativeInfinity} import Box._ /** @@ -83,8 +83,10 @@ class BoxDomainCore extends CompleteLatticeOperator[Box] def check(x : Interval) : Box = { x match { - case Interval(Undetermined(), _) => IntervalTop - case Interval(_, Undetermined()) => IntervalTop + /*case Interval(Undetermined(), _) => IntervalTop + case Interval(_, Undetermined()) => IntervalTop*/ + case Interval(NegativeInfinity(), NegativeInfinity()) => Interval(NegativeInfinity(),IntNumber(Int.MinValue)) + case Interval(PositiveInfinity(), PositiveInfinity()) => Interval(IntNumber(Int.MaxValue), PositiveInfinity()) case Interval(NegativeInfinity(), PositiveInfinity()) => IntervalTop case _ => x } diff --git a/core/src/test/scala/it/unich/jandom/JandomFasterBench.scala b/core/src/test/scala/it/unich/jandom/JandomFasterBench.scala index 7d70d5dc..38c201b3 100644 --- a/core/src/test/scala/it/unich/jandom/JandomFasterBench.scala +++ b/core/src/test/scala/it/unich/jandom/JandomFasterBench.scala @@ -14,7 +14,7 @@ * * You should have received a copy of the GNU General Public License * along with JANDOM. If not, see . - */ + package it.unich.jandom @@ -27,12 +27,12 @@ import it.unich.jandom.targets.parameters.NarrowingSpecs._ import it.unich.jandom.targets.parameters.WideningSpecs._ import parma_polyhedra_library.C_Polyhedron -/** + * Example program using ''Jandom'' to analyze the Alice benchmarks and * compare the results with different parameters. In this moment, it compares * the result of the analyisis with standard Kleene iteration and worklist * based ones. - */ + object JandomFasterBench extends App with FASTLoader { def fastModelAnalyze(program: LTS) { @@ -75,3 +75,4 @@ object JandomFasterBench extends App with FASTLoader { for (lts <- ltss) fastModelAnalyze(lts) } +*/ \ No newline at end of file diff --git a/core/src/test/scala/it/unich/jandom/JandomParallelotopeBench.scala b/core/src/test/scala/it/unich/jandom/JandomParallelotopeBench.scala index e60c25d3..adb1562d 100644 --- a/core/src/test/scala/it/unich/jandom/JandomParallelotopeBench.scala +++ b/core/src/test/scala/it/unich/jandom/JandomParallelotopeBench.scala @@ -14,7 +14,7 @@ * * You should have received a copy of the GNU General Public License * along with JANDOM. If not, see . - */ + package it.unich.jandom @@ -27,12 +27,12 @@ import it.unich.jandom.targets.parameters.NarrowingSpecs._ import it.unich.jandom.targets.parameters.WideningSpecs._ import parma_polyhedra_library.C_Polyhedron -/** + * Example program using ''Jandom'' to analyze the Alice benchmarks and * compare the results with different parameters. At the moment, it compares * the result of separately computing using box and parallelotope with respect * to using their product. - */ + object JandomParallelotopeBench extends App with FASTLoader { var totalEquals = 0 @@ -150,3 +150,4 @@ object JandomParallelotopeBench extends App with FASTLoader { println(s"Total best separate analysis: $totalBestSeparate") println(s"Total uncomparables: $totalUncomparable") } +*/ \ No newline at end of file diff --git a/core/src/test/scala/it/unich/jandom/JandomSumBench.scala b/core/src/test/scala/it/unich/jandom/JandomSumBench.scala index dbd7996f..3bdf539f 100644 --- a/core/src/test/scala/it/unich/jandom/JandomSumBench.scala +++ b/core/src/test/scala/it/unich/jandom/JandomSumBench.scala @@ -14,7 +14,7 @@ * * You should have received a copy of the GNU General Public License * along with JANDOM. If not, see . - */ + package it.unich.jandom @@ -26,12 +26,12 @@ import it.unich.jandom.targets.lts.LTS import it.unich.jandom.targets.parameters.WideningSpecs._ import parma_polyhedra_library.C_Polyhedron -/** + * Example program using ''Jandom'' to analyze the Alice benchmarks and * compare the results with different parameters. In this moment, it compares * the result of the analyisis with standard Kleene iteration and worklist * based ones. - */ + object JandomSumBench extends App with FASTLoader { var totalEquals = 0 @@ -155,3 +155,4 @@ object JandomSumBench extends App with FASTLoader { println(s"Total best other: $totalBestOther") println(s"Total uncomparables: $totalUncomparable") } +*/ diff --git a/core/src/test/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCoreSuite.scala b/core/src/test/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCoreSuite.scala index 71f57307..3683f6d2 100644 --- a/core/src/test/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCoreSuite.scala +++ b/core/src/test/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCoreSuite.scala @@ -1,6 +1,6 @@ package it.unipd.jandom.domains.numerical.box -import it.unipd.jandom.domains.{InfInt, IntNumber, PositiveInfinity, NegativeInfinity, Undetermined} +import it.unipd.jandom.domains.{InfInt, IntNumber, PositiveInfinity, NegativeInfinity} import it.unipd.jandom.domains.numerical.box.Box._ import it.unipd.jandom.domains.numerical.box.BoxDomainCore._ import org.scalatest.FlatSpec From 6682b1323f7a2ed1e926202c90e986ce24173d62 Mon Sep 17 00:00:00 2001 From: BottCode Date: Thu, 29 Mar 2018 12:20:04 +0200 Subject: [PATCH 74/99] Remove Undetermined and BoundedBoxDomainCore done --- .../numerical/box/BoundedBoxDomain.scala | 0 .../numerical/box/BoundedBoxDomainCore.scala | 114 ++++++++++++++++++ .../domains/numerical/box/BoxDomainCore.scala | 2 - 3 files changed, 114 insertions(+), 2 deletions(-) create mode 100644 core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomain.scala create mode 100644 core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCore.scala diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomain.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomain.scala new file mode 100644 index 00000000..e69de29b diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCore.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCore.scala new file mode 100644 index 00000000..ba8e50fc --- /dev/null +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCore.scala @@ -0,0 +1,114 @@ +/** + * Copyright 2018 Mattia Bottaro, Mauro Carlin + * + * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains + * JANDOM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * JANDOM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of a + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You shosuld have received a copy of the GNU General Public License + * along with JANDOM. If not, see . + */ + +package it.unipd.jandom.domains.numerical.box + +import it.unipd.jandom.domains.numerical.utils.{MathLibrary => M} +import it.unipd.jandom.domains.{InfInt, IntNumber, PositiveInfinity, NegativeInfinity} +import Box._ + +/* + * The bounded Box domain + * @author Mattia Bottaro , + * @author Mauro Carlin +*/ + +class BoundedBoxDomainCore(m,n) extends BoxDomainCore{ + + override def alpha(num : Int) : Box = { + val result = super.alpha(num) + normalizeBound(result) + } + + override def sum(x : Box, y : Box) : Box = { + val result = super.sum(x,y) + normalizeBound(result) + } + + /** + * @inheritdoc + */ + override def inverse(x : Box) : Box = { + val result = super.inverse(x) + normalizeBound(result) + } + + override def mult(x : Box, y : Box) : Box = { + val result = super.mult(x,y) + normalizeBound(result) + } + + /** + * @inheritdoc + */ + override def division(x : Box, y : Box) : Box = { + val result = super.division(x,y) + normalizeBound(result) + } + + override def remainder(x : Box, y : Box) : Box = { + val result = super.remainder(x,y) + normalizeBound(result) + } + + /** + * @inheritdoc + */ + override def lub(x : Box, y : Box) : Box = { + val result = super.lub(x,y) + normalizeBound(result) + } + + /** + * @inheritdoc + */ + override def glb(x : Box, y : Box) : Box = { + val result = super.glb(x,y) + normalizeBound(result) + } + + def normalizeBound(x : Box) : Box = { + x match { + case Interval(low,high) => + if (high < m) + return Interval(NegativeInfinity(),m) + if (low > n) + return Interval(n,PositiveInfinity()) + + val new_low = low + val new_high = high + if (high > n) + new_high = PositiveInfinity() + if (low < m) + new_low = NegativeInfinity() + + return Interval(new_low,new_high) + + case _ => x + + } + } + +} // end of BoundedBoxDomainCore class + +object BoundedBoxDomainCore { + /** + * Factory method of BoundedBoxDomainCore + */ + def apply() = new BoundedBoxDomainCore +} // end of BoundedBoxDomainCore companion object \ No newline at end of file diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala index 0cac8bdf..73d2d839 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala @@ -26,8 +26,6 @@ import Box._ * The Box domain */ - // TODO: define reminder function - class BoxDomainCore extends CompleteLatticeOperator[Box] with IntOperator[Box] with Abstraction[Int,Box]{ From 640a33704435aa2dcbfa3fa8e847d1ef78ef2129 Mon Sep 17 00:00:00 2001 From: BottCode Date: Thu, 29 Mar 2018 14:55:37 +0200 Subject: [PATCH 75/99] First uncomplete version of bounded box domain done --- .../it/unich/jandom/ui/NumericalDomains.scala | 3 + .../numerical/box/BoundedBoxDomain.scala | 152 ++++++++++++++++++ .../numerical/box/BoundedBoxDomainCore.scala | 39 ++--- 3 files changed, 176 insertions(+), 18 deletions(-) diff --git a/core/src/main/scala/it/unich/jandom/ui/NumericalDomains.scala b/core/src/main/scala/it/unich/jandom/ui/NumericalDomains.scala index 2f72688c..61df4495 100644 --- a/core/src/main/scala/it/unich/jandom/ui/NumericalDomains.scala +++ b/core/src/main/scala/it/unich/jandom/ui/NumericalDomains.scala @@ -27,6 +27,8 @@ import it.unipd.jandom.domains.numerical.constant.ConstantDomain import it.unipd.jandom.domains.numerical.mod.ModKDomain import it.unipd.jandom.domains.numerical.sign.{ESeqDomain, ExtendedSigns01Domain, SignDomain} import it.unipd.jandom.domains.numerical.box.BoxDomain +import it.unipd.jandom.domains.numerical.box.BoundedBoxDomain +import it.unipd.jandom.domains.IntNumber /** * The ParameterEnumeration for numerical domains. @@ -36,6 +38,7 @@ object NumericalDomains extends ParameterEnumeration[NumericalDomain] { val description = "The numerical domain to use for the analysis." val values: Buffer[ParameterValue[NumericalDomain]] = Buffer( + ParameterValue(BoundedBoxDomain(IntNumber(-10),IntNumber(10)), "Bounded Box", "This is a native Scala implementation of the Bounded Box (that is Interval) integer domain. You must provide lower and upper bound which bound the interval analysis."), ParameterValue(BoxDomain(), "Box (Interval) Domain", "This is a native Scala implementation of the Box (that is Interval) integer domain"), ParameterValue(SignDomain(), "Sign Domain", "This is a native Scala implementation of the simple sign domain " + "(<0, =0, >0)"), diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomain.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomain.scala index e69de29b..9054814e 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomain.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomain.scala @@ -0,0 +1,152 @@ +/** + * Copyright 2018 Mattia Bottaro, Mauro Carlin + * + * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains + * JANDOM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * JANDOM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of a + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You shosuld have received a copy of the GNU General Public License + * along with JANDOM. If not, see . + */ +package it.unipd.jandom.domains.numerical.box + +import it.unich.jandom.domains.numerical.LinearForm +import it.unipd.jandom.domains.numerical.BaseNumericalDomain +import it.unipd.jandom.domains.numerical.box.Box._ +import it.unipd.jandom.domains.numerical.box.BoundedBoxDomainCore._ +import it.unipd.jandom.domains.{InfInt, PositiveInfinity, NegativeInfinity, IntNumber} + +/** + * + * + * @author Mattia Bottaro + * @author Mauro Carlin + */ +class BoundedBoxDomain(m : InfInt, n : InfInt) extends BaseNumericalDomain[Box, BoundedBoxDomainCore](BoundedBoxDomainCore(m,n)){ + + + /** + * @inheritdoc + */ + override def createProperty(boxes: Array[Box], unreachable: Boolean): Property = { + boxes.map(BoundedBoxDomainCore.normalizeBound) + new Property(boxes, unreachable) + } + + /** + * Numerical property that tells whether the variables in a certain point of the CFG are constant or not. + * @param boxes array of the variables' boxes status + * @param unreachable tells if a given program point is unreachable + */ + class Property (boxes : Array[Box], unreachable: Boolean) extends BaseProperty(boxes, unreachable) { + + /** + * @param x is an Interval + * @return the lower bound. + */ + private def projectLow (box : Box) : InfInt = { + + box match { + case IntervalBottom => PositiveInfinity() + case IntervalTop => NegativeInfinity() + case Interval(low,high) => low + } + } + + + /** + * @param x is an Interval + * @return the upper bound. + */ + private def projectHigh (box : Box) : InfInt = { + + box match { + case IntervalBottom => NegativeInfinity() + case IntervalTop => PositiveInfinity() + case Interval(low,high) => high + } + } + + def apply(boxes: Array[Box], unreachable: Boolean) : Property = new Property(boxes, unreachable) + // x != 0 + /** + * @inheritdoc + */ + override def linearDisequality(lf: LinearForm): Property = { + if (isEmpty) + return this + val result : Box = linearEvaluation(lf); + result match { + case IntervalBottom => bottom + case Interval(low,high) => if (low == high && low == IntNumber(0)) bottom else this + case _ => this + } + } + + /** + * @inheritdoc + */ + override def linearInequality(lf: LinearForm): Property = { + if (isEmpty) + return this + val homcoeffs = lf.homcoeffs.map(_.toInt).toArray + val known = IntNumber(lf.known.toInt) + val lfMin = projectLow(linearEvaluation(lf)) + val lfArgmin = linearArgmin(lf); + //print(lowresult) + if (lfMin > IntNumber(0)) + return bottom + else { + var newboxes = boxes.clone + val infinities = (homcoeffs.indices) filter { i => lfArgmin(i).isInfinity && homcoeffs(i) != 0 } + + infinities.size match { + case 0 => { + for (i <- homcoeffs.indices) { + if (homcoeffs(i) < 0) newboxes(i) = Interval(projectLow(boxes(i)) max (lfArgmin(i) - (lfMin / IntNumber(homcoeffs(i)))), projectHigh(newboxes(i))) + if (homcoeffs(i) > 0) newboxes(i) = Interval(projectLow(newboxes(i)), projectHigh(boxes(i)) min (lfArgmin(i) - (lfMin / IntNumber(homcoeffs(i))))) + } + } + case 1 => { + val posinf = infinities.head + if (homcoeffs(posinf) < 0) + newboxes(posinf) = Interval(projectLow(boxes(posinf)) max ((dotprod(homcoeffs, lfArgmin, posinf) - known).inverse() / IntNumber(homcoeffs(posinf))), projectHigh(newboxes(posinf))) + else + newboxes(posinf) = Interval(projectLow(boxes(posinf)), projectHigh(boxes(posinf)) min ((dotprod(homcoeffs, lfArgmin, posinf) - known).inverse() / IntNumber(homcoeffs(posinf)))) + } + case _ => + } + new Property(newboxes,false) + } + } + + private def linearArgmin(lf: LinearForm): Seq[InfInt] = { + (lf.homcoeffs.zipWithIndex) map { + case (c, i) => if (c > 0) projectLow(boxes(i)) else projectHigh(boxes(i)) + } + } + + private def dotprod(x: Seq[Int], y: Seq[InfInt], remove: Int): InfInt = { + var sum: InfInt = IntNumber(0) + for (i <- x.indices; if i != remove && x(i) != 0) + sum = sum + (IntNumber(x(i)) * y(i)) + sum + } + + } // End of property + +} // End of BoundedBoxDomain + +object BoundedBoxDomain { + /** + * Factory method of BoxDomain + */ + def apply(m : InfInt, n : InfInt) = new BoundedBoxDomain(m,n) +} diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCore.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCore.scala index ba8e50fc..d7fbd440 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCore.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCore.scala @@ -28,16 +28,16 @@ import Box._ * @author Mauro Carlin */ -class BoundedBoxDomainCore(m,n) extends BoxDomainCore{ +class BoundedBoxDomainCore(m : InfInt, n : InfInt) extends BoxDomainCore{ override def alpha(num : Int) : Box = { val result = super.alpha(num) - normalizeBound(result) + BoundedBoxDomainCore.normalizeBound(result) } override def sum(x : Box, y : Box) : Box = { val result = super.sum(x,y) - normalizeBound(result) + BoundedBoxDomainCore.normalizeBound(result) } /** @@ -45,12 +45,12 @@ class BoundedBoxDomainCore(m,n) extends BoxDomainCore{ */ override def inverse(x : Box) : Box = { val result = super.inverse(x) - normalizeBound(result) + BoundedBoxDomainCore.normalizeBound(result) } override def mult(x : Box, y : Box) : Box = { val result = super.mult(x,y) - normalizeBound(result) + BoundedBoxDomainCore.normalizeBound(result) } /** @@ -58,12 +58,12 @@ class BoundedBoxDomainCore(m,n) extends BoxDomainCore{ */ override def division(x : Box, y : Box) : Box = { val result = super.division(x,y) - normalizeBound(result) + BoundedBoxDomainCore.normalizeBound(result) } override def remainder(x : Box, y : Box) : Box = { val result = super.remainder(x,y) - normalizeBound(result) + BoundedBoxDomainCore.normalizeBound(result) } /** @@ -71,7 +71,7 @@ class BoundedBoxDomainCore(m,n) extends BoxDomainCore{ */ override def lub(x : Box, y : Box) : Box = { val result = super.lub(x,y) - normalizeBound(result) + BoundedBoxDomainCore.normalizeBound(result) } /** @@ -79,10 +79,20 @@ class BoundedBoxDomainCore(m,n) extends BoxDomainCore{ */ override def glb(x : Box, y : Box) : Box = { val result = super.glb(x,y) - normalizeBound(result) + BoundedBoxDomainCore.normalizeBound(result) } +} // end of BoundedBoxDomainCore class + +object BoundedBoxDomainCore { + /** + * Factory method of BoundedBoxDomainCore + */ + def apply(m : InfInt, n : InfInt) = new BoundedBoxDomainCore(m,n) + def normalizeBound(x : Box) : Box = { + val m = IntNumber(-10) + val n = IntNumber(10) x match { case Interval(low,high) => if (high < m) @@ -90,8 +100,8 @@ class BoundedBoxDomainCore(m,n) extends BoxDomainCore{ if (low > n) return Interval(n,PositiveInfinity()) - val new_low = low - val new_high = high + var new_low = low + var new_high = high if (high > n) new_high = PositiveInfinity() if (low < m) @@ -104,11 +114,4 @@ class BoundedBoxDomainCore(m,n) extends BoxDomainCore{ } } -} // end of BoundedBoxDomainCore class - -object BoundedBoxDomainCore { - /** - * Factory method of BoundedBoxDomainCore - */ - def apply() = new BoundedBoxDomainCore } // end of BoundedBoxDomainCore companion object \ No newline at end of file From cdd50a46d07e18136cfa5602cb36098e506725d6 Mon Sep 17 00:00:00 2001 From: Mou95 Date: Thu, 29 Mar 2018 18:03:31 +0200 Subject: [PATCH 76/99] Implemented test BoundedBox --- .../numerical/box/BoundedBoxDomain.scala | 8 +- .../numerical/box/BoundedBoxDomainCore.scala | 19 +- .../box/BoundedBoxDomainCoreSuite.scala | 230 ++++++++++++++++++ 3 files changed, 242 insertions(+), 15 deletions(-) create mode 100644 core/src/test/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCoreSuite.scala diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomain.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomain.scala index 9054814e..0a806bbd 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomain.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomain.scala @@ -24,14 +24,14 @@ import it.unipd.jandom.domains.numerical.box.BoundedBoxDomainCore._ import it.unipd.jandom.domains.{InfInt, PositiveInfinity, NegativeInfinity, IntNumber} /** - * + * * * @author Mattia Bottaro * @author Mauro Carlin */ class BoundedBoxDomain(m : InfInt, n : InfInt) extends BaseNumericalDomain[Box, BoundedBoxDomainCore](BoundedBoxDomainCore(m,n)){ - + /** * @inheritdoc */ @@ -139,8 +139,8 @@ class BoundedBoxDomain(m : InfInt, n : InfInt) extends BaseNumericalDomain[Box, sum = sum + (IntNumber(x(i)) * y(i)) sum } - - } // End of property + + } // End of property } // End of BoundedBoxDomain diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCore.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCore.scala index d7fbd440..d4ef063a 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCore.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCore.scala @@ -30,11 +30,6 @@ import Box._ class BoundedBoxDomainCore(m : InfInt, n : InfInt) extends BoxDomainCore{ - override def alpha(num : Int) : Box = { - val result = super.alpha(num) - BoundedBoxDomainCore.normalizeBound(result) - } - override def sum(x : Box, y : Box) : Box = { val result = super.sum(x,y) BoundedBoxDomainCore.normalizeBound(result) @@ -92,17 +87,19 @@ object BoundedBoxDomainCore { def normalizeBound(x : Box) : Box = { val m = IntNumber(-10) - val n = IntNumber(10) + val n = IntNumber(10) x match { - case Interval(low,high) => - if (high < m) + case Interval(low,high) => + if (low == high) + return Interval(low,high) + if (high < m) return Interval(NegativeInfinity(),m) if (low > n) return Interval(n,PositiveInfinity()) - + var new_low = low var new_high = high - if (high > n) + if (high > n) new_high = PositiveInfinity() if (low < m) new_low = NegativeInfinity() @@ -114,4 +111,4 @@ object BoundedBoxDomainCore { } } -} // end of BoundedBoxDomainCore companion object \ No newline at end of file +} // end of BoundedBoxDomainCore companion object diff --git a/core/src/test/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCoreSuite.scala b/core/src/test/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCoreSuite.scala new file mode 100644 index 00000000..bfb052a0 --- /dev/null +++ b/core/src/test/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCoreSuite.scala @@ -0,0 +1,230 @@ +package it.unipd.jandom.domains.numerical.box + +import it.unipd.jandom.domains.{InfInt, IntNumber, PositiveInfinity, NegativeInfinity} +import it.unipd.jandom.domains.numerical.box.Box._ +import it.unipd.jandom.domains.numerical.box.BoundedBoxDomainCore._ +import org.scalatest.FlatSpec +/** + * Unit Test - Bounded Box Domain Core + * + * @author Mauro Carlin <> + * @author Mattia Bottaro <> + */ + +class BoundedBoxDomainCoreSuite extends FlatSpec { + val m = IntNumber(-10) + val n = IntNumber(10) + val bc = BoundedBoxDomainCore(m,n) + + val Zero = Box.Interval(IntNumber(0), IntNumber(0)) + val One = Box.Interval(IntNumber(1), IntNumber(1)) + val Seven = Box.Interval(IntNumber(7), IntNumber(7)) + val fourTeen = Box.Interval(IntNumber(14), IntNumber(14)) + val Mone = Box.Interval(IntNumber(-1), IntNumber(-1)) + val zeroTen = Box.Interval(IntNumber(0), IntNumber(10)) + val MtenZero = Box.Interval(IntNumber(-10), IntNumber(0)) + val MtenTen = Box.Interval(IntNumber(-10), IntNumber(10)) + val oneInf = Box.Interval(IntNumber(1), PositiveInfinity()) + val MinfMone = Box.Interval(NegativeInfinity(), IntNumber(-1)) + val MinfZero = Box.Interval(NegativeInfinity(), IntNumber(0)) + val nInf = Box.Interval(n, PositiveInfinity()) + val MinfM = Box.Interval(NegativeInfinity(), m) + + "BoundedBoxDomainCore.alpha" should + " - return the corresponding abstract value" in { + assert(bc.alpha(1) === One) + assert(bc.alpha(0) === Zero) + assert(bc.alpha(15) !== One) + } + + "BoundedBoxDomainCore.sum" should + " - return the sum of the two Boxs given as input" in { + val sevenInf = Box.Interval(IntNumber(7), PositiveInfinity()) + // IntervalBottom + assert(bc.sum(IntervalBottom, zeroTen) === IntervalBottom) + assert(bc.sum(IntervalBottom, IntervalTop) === IntervalBottom) + assert(bc.sum(oneInf, IntervalBottom) === IntervalBottom) + assert(bc.sum(IntervalTop, IntervalBottom) === IntervalBottom) + assert(bc.sum(IntervalBottom, IntervalBottom) === IntervalBottom) + // IntervalTop + assert(bc.sum(IntervalTop, MtenZero) === IntervalTop) + assert(bc.sum(Zero, IntervalTop) === IntervalTop) + assert(bc.sum(IntervalTop, IntervalTop) === IntervalTop) + // Interval + assert(bc.sum(One, Zero) === One) + assert(bc.sum(zeroTen, Seven) === sevenInf) + assert(bc.sum(Seven, zeroTen) === sevenInf) + assert(bc.sum(Seven, Seven) === fourTeen) + assert(bc.sum(fourTeen, fourTeen) === nInf) + assert(bc.sum(MinfMone, One) === MinfZero) + assert(bc.sum(Zero, oneInf) === oneInf) + assert(bc.sum(oneInf, Zero) === oneInf) + assert(bc.sum(oneInf, MinfMone) === IntervalTop) + assert(bc.sum(MinfMone, oneInf) === IntervalTop) + + } + + "BoundedBoxDomainCore.inverse" should + " - return the inverse of the Box given as input" in { + // IntervalBottom + assert(bc.inverse(IntervalBottom) === IntervalBottom) + // IntervalTop + assert(bc.inverse(IntervalTop) === IntervalTop) + // Interval + assert(bc.inverse(One) === Mone) + assert(bc.inverse(Mone) === One) + assert(bc.inverse(zeroTen) === MtenZero) + assert(bc.inverse(MtenZero) === zeroTen) + assert(bc.inverse(MtenTen) === MtenTen) + assert(bc.inverse(MinfMone) === oneInf) + assert(bc.inverse(oneInf) === MinfMone) + assert(bc.inverse(fourTeen) === MinfM) + } + + + "BoundedBoxDomainCore.mult" should + " - return the mult of the two Boxs given as input" in { + val MinfZero = Box.Interval(NegativeInfinity(), IntNumber(0)) + val MhudredHundred = Box.Interval(IntNumber(-100), IntNumber(100)) + // IntervalBottom + assert(bc.mult(IntervalBottom, One) === IntervalBottom) + assert(bc.mult(IntervalBottom, IntervalTop) === IntervalBottom) + assert(bc.mult(MtenTen, IntervalBottom) === IntervalBottom) + assert(bc.mult(IntervalTop, IntervalBottom) === IntervalBottom) + assert(bc.mult(IntervalBottom, IntervalBottom) === IntervalBottom) + // IntervalTop + assert(bc.mult(IntervalTop, Mone) === IntervalTop) + assert(bc.mult(Mone, IntervalTop) === IntervalTop) + assert(bc.mult(IntervalTop, IntervalTop) === IntervalTop) + // Interval 0 + assert(bc.mult(IntervalTop, Zero) === Zero) + assert(bc.mult(Zero, IntervalTop) === Zero) + assert(bc.mult(IntervalBottom, Zero) === IntervalBottom) + assert(bc.mult(Zero, IntervalBottom) === IntervalBottom) + assert(bc.mult(Zero, nInf) === Zero) + assert(bc.mult(nInf, Zero) === Zero) + assert(bc.mult(One, Zero) === Zero) + assert(bc.mult(Zero, One) === Zero) + // Interval + assert(bc.mult(zeroTen, MtenZero) === MinfZero) + assert(bc.mult(MtenZero, zeroTen) === MinfZero) + assert(bc.mult(MinfMone, One) === MinfMone) + assert(bc.mult(One, MinfMone) === MinfMone) + assert(bc.mult(MtenTen, MtenTen) === IntervalTop) + assert(bc.mult(oneInf, MinfMone) === MinfMone) + assert(bc.mult(MinfMone, oneInf) === MinfMone) + assert(bc.mult(oneInf, Mone) === MinfMone) + assert(bc.mult(Mone, oneInf) === MinfMone) + } + + "BoundedBoxDomainCore.division" should + " - return the division of the two Boxs given as input" in { + val twoThree = Box.Interval(IntNumber(2), IntNumber(3)) + val twoThirteen = Box.Interval(IntNumber(2), IntNumber(13)) + val zeroSix = Box.Interval(IntNumber(0), IntNumber(6)) + // IntervalBottom + assert(bc.division(IntervalBottom, MtenTen) === IntervalBottom) + assert(bc.division(IntervalBottom, IntervalTop) === IntervalBottom) + assert(bc.division(MtenTen, IntervalBottom) === IntervalBottom) + assert(bc.division(IntervalTop, IntervalBottom) === IntervalBottom) + assert(bc.division(IntervalBottom, IntervalBottom) === IntervalBottom) + // IntervalTop + assert(bc.division(IntervalTop, One) === IntervalTop) + assert(bc.division(One, IntervalTop) === IntervalTop) + assert(bc.division(IntervalTop, IntervalTop) === IntervalTop) + // Interval [0,0]) + assert(bc.division(IntervalTop, Zero) === IntervalBottom) + assert(bc.division(Zero, IntervalTop) === Zero) + assert(bc.division(Zero, MtenTen) === Zero) + assert(bc.division(MtenTen, Zero) === IntervalBottom) + + // Interval + assert(bc.division(fourTeen, One) === fourTeen) + assert(bc.division(twoThirteen, twoThree) === zeroSix) + } + + "BoundedBoxDomainCore.remainder" should + " - return the remainder of the two Boxs given as input" in { + // IntervalBottom + /*assert(bc.remainder(IntervalBottom, One) === IntervalBottom) + assert(bc.remainder(IntervalBottom, IntervalTop) === IntervalBottom) + assert(bc.remainder(One, IntervalBottom) === IntervalBottom) + assert(bc.remainder(IntervalTop, IntervalBottom) === IntervalBottom) + // IntervalTop + assert(bc.remainder(IntervalTop, MtenTen) === IntervalTop) + assert(bc.remainder(MtenTen, IntervalTop) === IntervalTop) + assert(bc.remainder(IntervalTop, IntervalTop) === IntervalTop) + // Interval(0) + assert(bc.remainder(IntervalTop, Zero) === IntervalBottom) + assert(bc.remainder(Zero, IntervalTop) === Zero) + assert(bc.remainder(Zero, MtenTen) === Zero) + assert(bc.remainder(MtenTen, Zero) === IntervalBottom) + assert(bc.remainder(Zero, Zero) === IntervalBottom) + // Interval + assert(bc.remainder(MtenTen, MtenTen) === zero)*/ + } + + "BoundedBoxDomainCore.lub" should + " - return the least upper bound of the two Boxs given as input" in { + val MinfTen = Box.Interval(NegativeInfinity(), IntNumber(10)) + val zeroOne = Box.Interval(IntNumber(0), IntNumber(1)) + // IntervalBottom + assert(bc.lub(IntervalBottom, MtenTen) === MtenTen) + assert(bc.lub(MtenTen, IntervalBottom) === MtenTen) + assert(bc.lub(IntervalBottom, IntervalBottom) === IntervalBottom) + // IntervalTop + assert(bc.lub(IntervalTop, One) === IntervalTop) + assert(bc.lub(One, IntervalTop) === IntervalTop) + assert(bc.lub(IntervalTop, IntervalBottom) === IntervalTop) + assert(bc.lub(IntervalBottom, IntervalTop) === IntervalTop) + assert(bc.lub(IntervalTop, IntervalTop) === IntervalTop) + // Interval + assert(bc.lub(oneInf, MinfMone) === IntervalTop) + assert(bc.lub(MinfMone, oneInf) === IntervalTop) + assert(bc.lub(MinfMone, MtenTen) === MinfTen) + assert(bc.lub(MtenTen, MinfMone) === MinfTen) + assert(bc.lub(Zero, One) === zeroOne) + assert(bc.lub(One, Zero) === zeroOne) + } + + "BoundedBoxDomainCore.glb" should + " - return the greatest lower bound between the two Boxs given as input" in { + val MtenMone = Box.Interval(IntNumber(-10), IntNumber(-1)) + // IntervalBottom + assert(bc.glb(IntervalBottom, MtenTen) === IntervalBottom) + assert(bc.glb(MtenTen, IntervalBottom) === IntervalBottom) + assert(bc.glb(IntervalBottom, IntervalBottom) === IntervalBottom) + // IntervalTop + assert(bc.glb(IntervalTop, One) === One) + assert(bc.glb(One, IntervalTop) === One) + assert(bc.glb(IntervalTop, IntervalBottom) === IntervalBottom) + assert(bc.glb(IntervalBottom, IntervalTop) === IntervalBottom) + assert(bc.glb(IntervalTop, IntervalTop) === IntervalTop) + // Interval + assert(bc.glb(oneInf, MinfMone) === IntervalBottom) + assert(bc.glb(MinfMone, oneInf) === IntervalBottom) + assert(bc.glb(MinfMone, MtenTen) === MtenMone) + assert(bc.glb(MtenTen, MinfMone) === MtenMone) + assert(bc.glb(Zero, One) === IntervalBottom) + assert(bc.glb(One, Zero) === IntervalBottom) + } + + "BoundedBoxDomainCore.compare" should + " - return the comparison between the two Boxs given as input" in { + // IntervalTop + assert(bc.compare(IntervalTop, IntervalTop) === Option(0)) + assert(bc.compare(IntervalTop, MtenTen) === Option(1)) + assert(bc.compare(IntervalTop, IntervalBottom) === Option(1)) + assert(bc.compare(MtenTen, IntervalTop) === Option(-1)) + assert(bc.compare(IntervalBottom, IntervalTop) === Option(-1)) + // IntervalBottom + assert(bc.compare(IntervalBottom, IntervalBottom) === Option(0)) + assert(bc.compare(IntervalBottom, MinfMone) === Option(-1)) + assert(bc.compare(MinfMone, IntervalBottom) === Option(1)) + // Interval + assert(bc.compare(One, Zero) === Option.empty) + assert(bc.compare(MinfMone, oneInf) === Option.empty) + assert(bc.compare(MtenTen, MtenTen) === Option(0)) + assert(bc.compare(nInf,nInf) === Option(0)) + } +} // end of BoundedBoxDomainCoreSuite From b8cc19f52fe37ca4af47208893594256c001f244 Mon Sep 17 00:00:00 2001 From: Mou95 Date: Thu, 29 Mar 2018 18:11:11 +0200 Subject: [PATCH 77/99] Fixed test Bounded --- .../domains/numerical/box/BoundedBoxDomainCoreSuite.scala | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/core/src/test/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCoreSuite.scala b/core/src/test/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCoreSuite.scala index bfb052a0..d1c3c25e 100644 --- a/core/src/test/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCoreSuite.scala +++ b/core/src/test/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCoreSuite.scala @@ -55,7 +55,7 @@ class BoundedBoxDomainCoreSuite extends FlatSpec { assert(bc.sum(zeroTen, Seven) === sevenInf) assert(bc.sum(Seven, zeroTen) === sevenInf) assert(bc.sum(Seven, Seven) === fourTeen) - assert(bc.sum(fourTeen, fourTeen) === nInf) + assert(bc.sum(fourTeen, zeroTen) === nInf) assert(bc.sum(MinfMone, One) === MinfZero) assert(bc.sum(Zero, oneInf) === oneInf) assert(bc.sum(oneInf, Zero) === oneInf) @@ -66,6 +66,7 @@ class BoundedBoxDomainCoreSuite extends FlatSpec { "BoundedBoxDomainCore.inverse" should " - return the inverse of the Box given as input" in { + val elevenTwelve = Box.Interval(IntNumber(11), IntNumber(12)) // IntervalBottom assert(bc.inverse(IntervalBottom) === IntervalBottom) // IntervalTop @@ -78,7 +79,7 @@ class BoundedBoxDomainCoreSuite extends FlatSpec { assert(bc.inverse(MtenTen) === MtenTen) assert(bc.inverse(MinfMone) === oneInf) assert(bc.inverse(oneInf) === MinfMone) - assert(bc.inverse(fourTeen) === MinfM) + assert(bc.inverse(elevenTwelve) === MinfM) } From d4f1ac3371f4920e66f7391b54e0b201cab40b0a Mon Sep 17 00:00:00 2001 From: Mou95 Date: Sat, 31 Mar 2018 16:58:05 +0200 Subject: [PATCH 78/99] Fixed BoundedCore --- .../numerical/box/BoundedBoxDomain.scala | 2 +- .../numerical/box/BoundedBoxDomainCore.scala | 39 ++++++++++++------- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomain.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomain.scala index 0a806bbd..be0169e1 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomain.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomain.scala @@ -36,7 +36,7 @@ class BoundedBoxDomain(m : InfInt, n : InfInt) extends BaseNumericalDomain[Box, * @inheritdoc */ override def createProperty(boxes: Array[Box], unreachable: Boolean): Property = { - boxes.map(BoundedBoxDomainCore.normalizeBound) + //boxes.map(normalizeBound) new Property(boxes, unreachable) } diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCore.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCore.scala index d4ef063a..a93cb506 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCore.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCore.scala @@ -32,7 +32,7 @@ class BoundedBoxDomainCore(m : InfInt, n : InfInt) extends BoxDomainCore{ override def sum(x : Box, y : Box) : Box = { val result = super.sum(x,y) - BoundedBoxDomainCore.normalizeBound(result) + normalizeBound(result) } /** @@ -40,12 +40,12 @@ class BoundedBoxDomainCore(m : InfInt, n : InfInt) extends BoxDomainCore{ */ override def inverse(x : Box) : Box = { val result = super.inverse(x) - BoundedBoxDomainCore.normalizeBound(result) + normalizeBound(result) } override def mult(x : Box, y : Box) : Box = { val result = super.mult(x,y) - BoundedBoxDomainCore.normalizeBound(result) + normalizeBound(result) } /** @@ -53,12 +53,12 @@ class BoundedBoxDomainCore(m : InfInt, n : InfInt) extends BoxDomainCore{ */ override def division(x : Box, y : Box) : Box = { val result = super.division(x,y) - BoundedBoxDomainCore.normalizeBound(result) + normalizeBound(result) } override def remainder(x : Box, y : Box) : Box = { val result = super.remainder(x,y) - BoundedBoxDomainCore.normalizeBound(result) + normalizeBound(result) } /** @@ -66,7 +66,7 @@ class BoundedBoxDomainCore(m : InfInt, n : InfInt) extends BoxDomainCore{ */ override def lub(x : Box, y : Box) : Box = { val result = super.lub(x,y) - BoundedBoxDomainCore.normalizeBound(result) + normalizeBound(result) } /** @@ -74,16 +74,17 @@ class BoundedBoxDomainCore(m : InfInt, n : InfInt) extends BoxDomainCore{ */ override def glb(x : Box, y : Box) : Box = { val result = super.glb(x,y) - BoundedBoxDomainCore.normalizeBound(result) + normalizeBound(result) } -} // end of BoundedBoxDomainCore class - -object BoundedBoxDomainCore { - /** - * Factory method of BoundedBoxDomainCore - */ - def apply(m : InfInt, n : InfInt) = new BoundedBoxDomainCore(m,n) + /*def check(x : Interval) : Box = { + x match { + case Interval(NegativeInfinity(), NegativeInfinity()) => Interval(NegativeInfinity(),m) + case Interval(PositiveInfinity(), PositiveInfinity()) => Interval(n, PositiveInfinity()) + case Interval(NegativeInfinity(), PositiveInfinity()) => IntervalTop + case _ => x + } + }*/ def normalizeBound(x : Box) : Box = { val m = IntNumber(-10) @@ -104,11 +105,19 @@ object BoundedBoxDomainCore { if (low < m) new_low = NegativeInfinity() - return Interval(new_low,new_high) + return check(Interval(new_low,new_high)) case _ => x } } +} // end of BoundedBoxDomainCore class + +object BoundedBoxDomainCore { + /** + * Factory method of BoundedBoxDomainCore + */ + def apply(m : InfInt, n : InfInt) = new BoundedBoxDomainCore(m,n) + } // end of BoundedBoxDomainCore companion object From f4b55180edb440f277bfef1411dc38beef95a73f Mon Sep 17 00:00:00 2001 From: Mou95 Date: Wed, 4 Apr 2018 16:47:52 +0200 Subject: [PATCH 79/99] Updated test --- core/examples/Java/TestBox.class | Bin 607 -> 722 bytes core/examples/Java/TestBox.java | 12 +++++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/core/examples/Java/TestBox.class b/core/examples/Java/TestBox.class index 9ba7b2d8df8644a6430ce7208adb536f0fbb2fa4..8235515acb96156c7ec780a4f7b26714a043d2f1 100644 GIT binary patch delta 162 zcmcc5a*0*+)W2Q(7#J8#7(}=jm>C4w8HCswgeQt-ad8%<<|bz5rKA>3to3AM+jzX6 zv4E3-kAanek%0}UBa(p$sDXh&T7b)%*+xn_L4bb|15XPBV+$kW^8cTtqzh~}0;QQ4 z*ny-Rm{bR9&;S~s$-v8?#UQ|-%^=30%OJ&|$G`C4v83frGgeHn+P3(4OWZihVpOKT1fe)yFiGd#g DIw%TT diff --git a/core/examples/Java/TestBox.java b/core/examples/Java/TestBox.java index 2a3132c1..a97fadfb 100644 --- a/core/examples/Java/TestBox.java +++ b/core/examples/Java/TestBox.java @@ -32,7 +32,17 @@ public static void BoxIf() { public static void BoxNull() { int x = 0; - + + } + + public static void remainder() { + int x = 10; + int y = 0; + while (x + y < 15) { + x++; + y++; + } + int w = x % y; } } From f17f6d8912044cf37ed4954265df37168e557694 Mon Sep 17 00:00:00 2001 From: BottCode Date: Tue, 10 Apr 2018 12:08:09 +0200 Subject: [PATCH 80/99] add m,n panel --- .../it/unich/jandom/ui/NumericalDomains.scala | 8 ++++- .../unich/jandom/ui/gui/ParametersPane.scala | 33 +++++++++++++++---- 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/core/src/main/scala/it/unich/jandom/ui/NumericalDomains.scala b/core/src/main/scala/it/unich/jandom/ui/NumericalDomains.scala index 61df4495..f2bfc7c5 100644 --- a/core/src/main/scala/it/unich/jandom/ui/NumericalDomains.scala +++ b/core/src/main/scala/it/unich/jandom/ui/NumericalDomains.scala @@ -33,12 +33,14 @@ import it.unipd.jandom.domains.IntNumber /** * The ParameterEnumeration for numerical domains. */ + + object NumericalDomains extends ParameterEnumeration[NumericalDomain] { val name = "Domain" val description = "The numerical domain to use for the analysis." val values: Buffer[ParameterValue[NumericalDomain]] = Buffer( - ParameterValue(BoundedBoxDomain(IntNumber(-10),IntNumber(10)), "Bounded Box", "This is a native Scala implementation of the Bounded Box (that is Interval) integer domain. You must provide lower and upper bound which bound the interval analysis."), + ParameterValue(BoundedBoxDomain(IntNumber(Double.NegativeInfinity.toInt),IntNumber(Double.PositiveInfinity.toInt)), "Bounded Box", "This is a native Scala implementation of the Bounded Box (that is Interval) integer domain. You must provide lower and upper bound which bound the interval analysis."), ParameterValue(BoxDomain(), "Box (Interval) Domain", "This is a native Scala implementation of the Box (that is Interval) integer domain"), ParameterValue(SignDomain(), "Sign Domain", "This is a native Scala implementation of the simple sign domain " + "(<0, =0, >0)"), @@ -68,6 +70,10 @@ object NumericalDomains extends ParameterEnumeration[NumericalDomain] { ) val default = values.last + def setBound(m: Int,n: Int) = { + values.update(0,ParameterValue(BoundedBoxDomain(IntNumber(m),IntNumber(n)), "Bounded Box", "This is a native Scala implementation of the Bounded Box (that is Interval) integer domain. You must provide lower and upper bound which bound the interval analysis.")) + } + // Load objects PPLUIInitializer and PPLMacroUIInitializer if available Try ( Class.forName ("it.unich.jandom.ui.PPLUIInitializer$") ) Try ( Class.forName ("it.unich.jandom.ui.PPLMacroUIInitializer$") ) diff --git a/core/src/main/scala/it/unich/jandom/ui/gui/ParametersPane.scala b/core/src/main/scala/it/unich/jandom/ui/gui/ParametersPane.scala index d146cd23..c3dfffdb 100644 --- a/core/src/main/scala/it/unich/jandom/ui/gui/ParametersPane.scala +++ b/core/src/main/scala/it/unich/jandom/ui/gui/ParametersPane.scala @@ -38,6 +38,10 @@ class ParametersPane extends GridBagPanel { val wideningComboBox = addParameterEnumeration(2, WideningScopes) val narrowingComboBox = addParameterEnumeration(3, NarrowingStrategies) val delayModel = new SpinnerNumberModel(0, 0, Double.PositiveInfinity, 1) + val parameter_m_model = new SpinnerNumberModel(0, Double.NegativeInfinity, Double.PositiveInfinity, 1) + val parameter_n_model = new SpinnerNumberModel(0, Double.NegativeInfinity, Double.PositiveInfinity, 1) + val parameter_m = Component.wrap(new JSpinner(parameter_m_model)) + val parameter_n = Component.wrap(new JSpinner(parameter_n_model)) val delay = Component.wrap(new JSpinner(delayModel)) val debug = new CheckBox("Debug") @@ -45,9 +49,20 @@ class ParametersPane extends GridBagPanel { GridBagConstraints.NONE, new Insets(0, 0, 5, 5), 0, 0) layout(delay) = new Constraints(1, 4, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 5, 0), 0, 0) - layout(debug) = new Constraints(0, 5, 2, 1, 0.0, 0.0, GridBagConstraints.BASELINE, + + layout(new Label("Lower bound M:")) = new Constraints(0, 5, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, + GridBagConstraints.NONE, new Insets(0, 0, 5, 5), 0, 0) + layout(parameter_m) = new Constraints(1, 5, 2, 1, 0.0, 0.0, GridBagConstraints.WEST, + GridBagConstraints.HORIZONTAL, new Insets(0, 0, 5, 0), 0, 0) + + layout(new Label("Upper bound N:")) = new Constraints(0, 6, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, + GridBagConstraints.NONE, new Insets(0, 0, 5, 5), 0, 0) + layout(parameter_n) = new Constraints(1, 6, 3, 1, 0.0, 0.0, GridBagConstraints.WEST, + GridBagConstraints.HORIZONTAL, new Insets(0, 0, 5, 0), 0, 0) + + layout(debug) = new Constraints(0, 7, 2, 1, 0.0, 0.0, GridBagConstraints.BASELINE, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0) - layout(Swing.VGlue) = new Constraints(0, 6, 2, 1, 0.0, 1.0, GridBagConstraints.BASELINE, + layout(Swing.VGlue) = new Constraints(0, 7, 4, 1, 0.0, 1.0, GridBagConstraints.BASELINE, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0) object ParameterRenderer extends Renderer[ParameterValue[_]] { @@ -77,17 +92,23 @@ class ParametersPane extends GridBagPanel { comboBox } - def selectedNumericalDomain = NumericalDomains.values(numericalDomainComboBox.selection.index).value - - def selectedObjectDomain = ObjectDomains.values(objectDomainComboBox.selection.index).value - def setParameters[T <: Target[T]](params: Parameters[T]) { params.wideningScope = WideningScopes.values(wideningComboBox.selection.index).value params.narrowingStrategy = NarrowingStrategies.values(narrowingComboBox.selection.index).value val delay = delayModel.getValue().asInstanceOf[Double].toInt + val bound_m = parameter_m_model.getValue().asInstanceOf[Double].toInt + val bound_n = parameter_n_model.getValue.asInstanceOf[Double].toInt + print("Bound",bound_m,bound_n) + NumericalDomains.setBound(bound_m, bound_n) params.widening = DelayedWidening(DefaultWidening, delay) params.narrowing = DelayedNarrowing(TrivialNarrowing, 2) if (debug.selected) params.debugWriter = new java.io.StringWriter } + def selectedNumericalDomain = NumericalDomains.values(numericalDomainComboBox.selection.index).value + + def selectedObjectDomain = ObjectDomains.values(objectDomainComboBox.selection.index).value + + + } From 19e8132c7cafb7e26dc969e0b3392d7b836bc8af Mon Sep 17 00:00:00 2001 From: BottCode Date: Tue, 10 Apr 2018 12:28:52 +0200 Subject: [PATCH 81/99] print utili --- core/src/main/scala/it/unich/jandom/ui/NumericalDomains.scala | 2 +- .../jandom/domains/numerical/box/BoundedBoxDomainCore.scala | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/core/src/main/scala/it/unich/jandom/ui/NumericalDomains.scala b/core/src/main/scala/it/unich/jandom/ui/NumericalDomains.scala index f2bfc7c5..758f9e87 100644 --- a/core/src/main/scala/it/unich/jandom/ui/NumericalDomains.scala +++ b/core/src/main/scala/it/unich/jandom/ui/NumericalDomains.scala @@ -71,7 +71,7 @@ object NumericalDomains extends ParameterEnumeration[NumericalDomain] { val default = values.last def setBound(m: Int,n: Int) = { - values.update(0,ParameterValue(BoundedBoxDomain(IntNumber(m),IntNumber(n)), "Bounded Box", "This is a native Scala implementation of the Bounded Box (that is Interval) integer domain. You must provide lower and upper bound which bound the interval analysis.")) + values.update(0,ParameterValue(BoundedBoxDomain(IntNumber(m),IntNumber(n)), "BOUNDED CON "+ m + " e " + n, "This is a native Scala implementation of the Bounded Box (that is Interval) integer domain. You must provide lower and upper bound which bound the interval analysis.")) } // Load objects PPLUIInitializer and PPLMacroUIInitializer if available diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCore.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCore.scala index a93cb506..e18bdaac 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCore.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCore.scala @@ -31,6 +31,7 @@ import Box._ class BoundedBoxDomainCore(m : InfInt, n : InfInt) extends BoxDomainCore{ override def sum(x : Box, y : Box) : Box = { + print("method sum. Bounds are: " + m + " and " + n) val result = super.sum(x,y) normalizeBound(result) } From ad43d79ac4832ebf98817916fd1906423d539801 Mon Sep 17 00:00:00 2001 From: Mou95 Date: Tue, 10 Apr 2018 17:21:01 +0200 Subject: [PATCH 82/99] Updated values of domains --- .../scala/it/unich/jandom/ui/NumericalDomains.scala | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/core/src/main/scala/it/unich/jandom/ui/NumericalDomains.scala b/core/src/main/scala/it/unich/jandom/ui/NumericalDomains.scala index 758f9e87..ff7a802b 100644 --- a/core/src/main/scala/it/unich/jandom/ui/NumericalDomains.scala +++ b/core/src/main/scala/it/unich/jandom/ui/NumericalDomains.scala @@ -40,7 +40,7 @@ object NumericalDomains extends ParameterEnumeration[NumericalDomain] { val description = "The numerical domain to use for the analysis." val values: Buffer[ParameterValue[NumericalDomain]] = Buffer( - ParameterValue(BoundedBoxDomain(IntNumber(Double.NegativeInfinity.toInt),IntNumber(Double.PositiveInfinity.toInt)), "Bounded Box", "This is a native Scala implementation of the Bounded Box (that is Interval) integer domain. You must provide lower and upper bound which bound the interval analysis."), + ParameterValue(BoundedBoxDomain(IntNumber(0),IntNumber(0)), "Bounded Box", "This is a native Scala implementation of the Bounded Box (that is Interval) integer domain. You must provide lower and upper bound which bound the interval analysis."), ParameterValue(BoxDomain(), "Box (Interval) Domain", "This is a native Scala implementation of the Box (that is Interval) integer domain"), ParameterValue(SignDomain(), "Sign Domain", "This is a native Scala implementation of the simple sign domain " + "(<0, =0, >0)"), @@ -71,7 +71,16 @@ object NumericalDomains extends ParameterEnumeration[NumericalDomain] { val default = values.last def setBound(m: Int,n: Int) = { - values.update(0,ParameterValue(BoundedBoxDomain(IntNumber(m),IntNumber(n)), "BOUNDED CON "+ m + " e " + n, "This is a native Scala implementation of the Bounded Box (that is Interval) integer domain. You must provide lower and upper bound which bound the interval analysis.")) + var i = 0 + for (d <- values) { + if (d.value.isInstanceOf[BoundedBoxDomain]) { + print("dkfbskjfbksdfkasdfbaksefbaskdfbaskdfbasdk") + values.update(i, + (new ParameterValue(BoundedBoxDomain(IntNumber(m),IntNumber(n)), + "Bounded Box "+ m + " " + n, "This is a native Scala implementation of the Bounded Box (that is Interval) integer domain. You must provide lower and upper bound which bound the interval analysis."))) + } + i = i + 1 + } } // Load objects PPLUIInitializer and PPLMacroUIInitializer if available From 955e3b67cd154598951bc7bafdb5376f8f465688 Mon Sep 17 00:00:00 2001 From: BottCode Date: Wed, 11 Apr 2018 00:42:47 +0200 Subject: [PATCH 83/99] m and n updatding seems working --- .../domains/numerical/BoxDoubleDomain.scala | 1 + .../domains/numerical/NumericalDomain.scala | 2 + .../ParallelotopeRationalDomain.scala | 1 - .../domains/numerical/ProductDomain.scala | 1 - .../domains/numerical/SumGenericDomain.scala | 1 - .../numerical/SumIntParallelotopeDomain.scala | 1 - .../it/unich/jandom/ui/NumericalDomains.scala | 8 +- .../unich/jandom/ui/gui/ParametersPane.scala | 2 +- .../numerical/BaseNumericalDomain.scala | 2 + ...ucedProductCongruenceBoxDoubleDomain.scala | 2 +- .../numerical/box/BoundedBoxDomain.scala | 5 + .../numerical/box/BoundedBoxDomainCore.scala | 21 +- hs_err_pid16436.log | 376 ++++++++++++++++++ hs_err_pid16514.log | 376 ++++++++++++++++++ hs_err_pid17258.log | 376 ++++++++++++++++++ 15 files changed, 1158 insertions(+), 17 deletions(-) create mode 100644 hs_err_pid16436.log create mode 100644 hs_err_pid16514.log create mode 100644 hs_err_pid17258.log diff --git a/core/src/main/scala/it/unich/jandom/domains/numerical/BoxDoubleDomain.scala b/core/src/main/scala/it/unich/jandom/domains/numerical/BoxDoubleDomain.scala index 1dbea6ad..c14bc010 100644 --- a/core/src/main/scala/it/unich/jandom/domains/numerical/BoxDoubleDomain.scala +++ b/core/src/main/scala/it/unich/jandom/domains/numerical/BoxDoubleDomain.scala @@ -52,6 +52,7 @@ class BoxDoubleDomain(val overReals: Boolean) extends NumericalDomain { final class Property(val low: Array[Double], val high: Array[Double], val isEmpty: Boolean) extends NumericalProperty[Property] { require(normalized, s"The parameters low: ${low.mkString(",")}, high: ${high.mkString(",")} and isEmpty: ${isEmpty} are not normalized") + type Domain = BoxDoubleDomain def domain = BoxDoubleDomain.this diff --git a/core/src/main/scala/it/unich/jandom/domains/numerical/NumericalDomain.scala b/core/src/main/scala/it/unich/jandom/domains/numerical/NumericalDomain.scala index 94e5024e..e0cac367 100644 --- a/core/src/main/scala/it/unich/jandom/domains/numerical/NumericalDomain.scala +++ b/core/src/main/scala/it/unich/jandom/domains/numerical/NumericalDomain.scala @@ -31,5 +31,7 @@ abstract class NumericalDomain extends DimensionFiberedDomain { * @inheritdoc * For numerical domains, properties needs to be instances of [[it.unich.jandom.domains.NumericalProperty]]. */ + //type T <: Any // @TODO: Make this method more type-generic + def updateData(x: Double, y: Double): Unit = x * 1 type Property <: NumericalProperty[Property] } diff --git a/core/src/main/scala/it/unich/jandom/domains/numerical/ParallelotopeRationalDomain.scala b/core/src/main/scala/it/unich/jandom/domains/numerical/ParallelotopeRationalDomain.scala index d0981af7..a39b5f78 100644 --- a/core/src/main/scala/it/unich/jandom/domains/numerical/ParallelotopeRationalDomain.scala +++ b/core/src/main/scala/it/unich/jandom/domains/numerical/ParallelotopeRationalDomain.scala @@ -39,7 +39,6 @@ import scala.util.Try class ParallelotopeRationalDomain private(favorAxis: Int) extends NumericalDomain { val widenings = Seq(WideningDescription.default[Property]) - /** * Build a non-empty parallelotope. If the parallelotope is not empty, the result is undetermined. * diff --git a/core/src/main/scala/it/unich/jandom/domains/numerical/ProductDomain.scala b/core/src/main/scala/it/unich/jandom/domains/numerical/ProductDomain.scala index 53887729..1abb0300 100644 --- a/core/src/main/scala/it/unich/jandom/domains/numerical/ProductDomain.scala +++ b/core/src/main/scala/it/unich/jandom/domains/numerical/ProductDomain.scala @@ -37,7 +37,6 @@ import it.unich.scalafix.Box */ class ProductDomain[D1 <: NumericalDomain, D2 <: NumericalDomain](val dom1: D1, val dom2: D2)( implicit val dom1Todom2: DomainTransformation[D1, D2], val dom2Todom1: DomainTransformation[D2, D1]) extends NumericalDomain { - val widenings = { for (w1 <- dom1.widenings; w2 <- dom2.widenings) yield WideningDescription(s"${w1.name} X ${w2.name}", s"Component-wise combination of the two widenings.", diff --git a/core/src/main/scala/it/unich/jandom/domains/numerical/SumGenericDomain.scala b/core/src/main/scala/it/unich/jandom/domains/numerical/SumGenericDomain.scala index b369f479..ec51bb17 100644 --- a/core/src/main/scala/it/unich/jandom/domains/numerical/SumGenericDomain.scala +++ b/core/src/main/scala/it/unich/jandom/domains/numerical/SumGenericDomain.scala @@ -28,7 +28,6 @@ package it.unich.jandom.domains.numerical class SumGenericDomain[D1 <: NumericalDomain, D2 <: NumericalDomain](val dom1: D1, val dom2: D2) extends SumDomain[D1,D2] { type Property = SumGeneric - class SumGeneric(val p1: dom1.Property, val p2: dom2.Property) extends Sum def apply(p1: dom1.Property, p2: dom2.Property) = new SumGeneric(p1, p2) diff --git a/core/src/main/scala/it/unich/jandom/domains/numerical/SumIntParallelotopeDomain.scala b/core/src/main/scala/it/unich/jandom/domains/numerical/SumIntParallelotopeDomain.scala index a5ff7ea4..8db728da 100644 --- a/core/src/main/scala/it/unich/jandom/domains/numerical/SumIntParallelotopeDomain.scala +++ b/core/src/main/scala/it/unich/jandom/domains/numerical/SumIntParallelotopeDomain.scala @@ -27,7 +27,6 @@ package it.unich.jandom.domains.numerical class SumBoxDoubleParallelotopeRationDomain(val dom1: BoxDoubleDomain, val dom2: ParallelotopeRationalDomain) extends SumDomain[BoxDoubleDomain, ParallelotopeRationalDomain] { type Property = SumBoxDoubleParallelotopeRational - class SumBoxDoubleParallelotopeRational(val p1: dom1.Property, val p2: dom2.Property) extends Sum { override def linearAssignment(n: Int, lf: LinearForm): Property = { if ((n >= lf.homcoeffs.size) || (lf.homcoeffs(n) == 0)) { diff --git a/core/src/main/scala/it/unich/jandom/ui/NumericalDomains.scala b/core/src/main/scala/it/unich/jandom/ui/NumericalDomains.scala index ff7a802b..ab0f7c1e 100644 --- a/core/src/main/scala/it/unich/jandom/ui/NumericalDomains.scala +++ b/core/src/main/scala/it/unich/jandom/ui/NumericalDomains.scala @@ -71,15 +71,11 @@ object NumericalDomains extends ParameterEnumeration[NumericalDomain] { val default = values.last def setBound(m: Int,n: Int) = { - var i = 0 for (d <- values) { if (d.value.isInstanceOf[BoundedBoxDomain]) { - print("dkfbskjfbksdfkasdfbaksefbaskdfbaskdfbasdk") - values.update(i, - (new ParameterValue(BoundedBoxDomain(IntNumber(m),IntNumber(n)), - "Bounded Box "+ m + " " + n, "This is a native Scala implementation of the Bounded Box (that is Interval) integer domain. You must provide lower and upper bound which bound the interval analysis."))) + println("te chiamo qui" + m + " - " + n) + d.value.updateData(m,n) } - i = i + 1 } } diff --git a/core/src/main/scala/it/unich/jandom/ui/gui/ParametersPane.scala b/core/src/main/scala/it/unich/jandom/ui/gui/ParametersPane.scala index c3dfffdb..ee3ff734 100644 --- a/core/src/main/scala/it/unich/jandom/ui/gui/ParametersPane.scala +++ b/core/src/main/scala/it/unich/jandom/ui/gui/ParametersPane.scala @@ -98,7 +98,7 @@ class ParametersPane extends GridBagPanel { val delay = delayModel.getValue().asInstanceOf[Double].toInt val bound_m = parameter_m_model.getValue().asInstanceOf[Double].toInt val bound_n = parameter_n_model.getValue.asInstanceOf[Double].toInt - print("Bound",bound_m,bound_n) + print("Bound from graphics ",bound_m,bound_n) NumericalDomains.setBound(bound_m, bound_n) params.widening = DelayedWidening(DefaultWidening, delay) params.narrowing = DelayedNarrowing(TrivialNarrowing, 2) diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/BaseNumericalDomain.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/BaseNumericalDomain.scala index b78a620a..abab50db 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/BaseNumericalDomain.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/BaseNumericalDomain.scala @@ -44,12 +44,14 @@ abstract class BaseNumericalDomain * @param unreachable tells whether the program point is reachable or not * @return a new property for the given array */ + def createProperty(elements: Array[T], unreachable: Boolean) : Property def createProperty(p : BaseProperty): Property = createProperty(p.elements, p.isEmpty || p.elements.contains(core.bottom)) + //def updateData(x: Double, y: Double) = core.updateData(x,y) /** * Factory method for creating a Property. diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/FullyReducedProductCongruenceBoxDoubleDomain.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/FullyReducedProductCongruenceBoxDoubleDomain.scala index c2e6271c..7c5ba5c7 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/FullyReducedProductCongruenceBoxDoubleDomain.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/FullyReducedProductCongruenceBoxDoubleDomain.scala @@ -36,7 +36,7 @@ import it.unipd.jandom.domains.numerical.utils.MathLibrary class FullyReducedProductCongruenceBoxDoubleDomain(override val dom1 : CongruenceDomain, override val dom2 : BoxDoubleDomain) extends ProductDomain[CongruenceDomain, BoxDoubleDomain](dom1, dom2) { override val dom1Todom2 = DomainTransformation.CongruenceToBoxDouble override val dom2Todom1 = DomainTransformation.BoxDoubleToCongruence - + override def top(n: Int) = new FullyReducedProductCongruenceBoxDouble(dom1.top(n), dom2.top(n)) diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomain.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomain.scala index be0169e1..a0004504 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomain.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomain.scala @@ -31,6 +31,11 @@ import it.unipd.jandom.domains.{InfInt, PositiveInfinity, NegativeInfinity, IntN */ class BoundedBoxDomain(m : InfInt, n : InfInt) extends BaseNumericalDomain[Box, BoundedBoxDomainCore](BoundedBoxDomainCore(m,n)){ + override def updateData(x: Double, y: Double): Unit = { + val new_m = IntNumber(x.toInt) + val new_n = IntNumber(y.toInt) + BoundedBoxDomainCore.updateData(new_m,new_n) + } /** * @inheritdoc diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCore.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCore.scala index e18bdaac..a301ce8e 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCore.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCore.scala @@ -28,11 +28,14 @@ import Box._ * @author Mauro Carlin */ -class BoundedBoxDomainCore(m : InfInt, n : InfInt) extends BoxDomainCore{ +class BoundedBoxDomainCore(bound_m : InfInt, bound_n : InfInt) extends BoxDomainCore{ + + var m: InfInt = bound_m + var n: InfInt = bound_n override def sum(x : Box, y : Box) : Box = { - print("method sum. Bounds are: " + m + " and " + n) val result = super.sum(x,y) + println("sum i bound sono"+ m + " " +n) normalizeBound(result) } @@ -88,8 +91,6 @@ class BoundedBoxDomainCore(m : InfInt, n : InfInt) extends BoxDomainCore{ }*/ def normalizeBound(x : Box) : Box = { - val m = IntNumber(-10) - val n = IntNumber(10) x match { case Interval(low,high) => if (low == high) @@ -119,6 +120,16 @@ object BoundedBoxDomainCore { /** * Factory method of BoundedBoxDomainCore */ - def apply(m : InfInt, n : InfInt) = new BoundedBoxDomainCore(m,n) + var D: BoundedBoxDomainCore = apply(IntNumber(0),IntNumber(0)) + def apply(m : InfInt, n : InfInt): BoundedBoxDomainCore = { + D = new BoundedBoxDomainCore(m,n) + return D + } + + def updateData(x: InfInt, y: InfInt) = { + D.m = x + D.n = y + println("DATA ARE UPDATED " + D.m + " and " + D.n) + } } // end of BoundedBoxDomainCore companion object diff --git a/hs_err_pid16436.log b/hs_err_pid16436.log new file mode 100644 index 00000000..7d9aaa9a --- /dev/null +++ b/hs_err_pid16436.log @@ -0,0 +1,376 @@ +# +# There is insufficient memory for the Java Runtime Environment to continue. +# Native memory allocation (mmap) failed to map 357564416 bytes for committing reserved memory. +# Possible reasons: +# The system is out of physical RAM or swap space +# In 32 bit mode, the process size limit was hit +# Possible solutions: +# Reduce memory load on the system +# Increase physical memory or swap space +# Check if swap backing store is full +# Use 64 bit Java on a 64 bit OS +# Decrease Java heap size (-Xmx/-Xms) +# Decrease number of Java threads +# Decrease Java thread stack sizes (-Xss) +# Set larger code cache with -XX:ReservedCodeCacheSize= +# This output file may be truncated or incomplete. +# +# Out of Memory Error (os_linux.cpp:2640), pid=16436, tid=0x00007fd306a90700 +# +# JRE version: (8.0_162-b12) (build ) +# Java VM: OpenJDK 64-Bit Server VM (25.162-b12 mixed mode linux-amd64 compressed oops) +# Core dump written. Default location: /home/mattia/Jandom/core or core.16436 +# + +--------------- T H R E A D --------------- + +Current thread (0x00007fd30000b000): JavaThread "Unknown thread" [_thread_in_vm, id=16437, stack(0x00007fd306991000,0x00007fd306a91000)] + +Stack: [0x00007fd306991000,0x00007fd306a91000], sp=0x00007fd306a8f5b0, free space=1017k +Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code) +V [libjvm.so+0xaa80b2] +V [libjvm.so+0x4d92c7] +V [libjvm.so+0x8e3eb0] +V [libjvm.so+0x8de45e] +V [libjvm.so+0x95ea76] +V [libjvm.so+0x960ac6] +V [libjvm.so+0x2b48d4] +V [libjvm.so+0x90bab1] +V [libjvm.so+0xa6a68a] +V [libjvm.so+0xa6a975] +V [libjvm.so+0x6252af] +V [libjvm.so+0xa4e0cb] +V [libjvm.so+0x6a4b40] JNI_CreateJavaVM+0x60 +C [libjli.so+0x2bf3] +C [libpthread.so.0+0x708c] start_thread+0xdc + + +--------------- P R O C E S S --------------- + +Java Threads: ( => current thread ) + +Other Threads: + +=>0x00007fd30000b000 (exited) JavaThread "Unknown thread" [_thread_in_vm, id=16437, stack(0x00007fd306991000,0x00007fd306a91000)] + +VM state:not at safepoint (not fully initialized) + +VM Mutex/Monitor currently owned by a thread: None + +GC Heap History (0 events): +No events + +Deoptimization events (0 events): +No events + +Classes redefined (0 events): +No events + +Internal exceptions (0 events): +No events + +Events (0 events): +No events + + +Dynamic libraries: +c0000000-eab00000 ---p 00000000 00:00 0 +558ba4aba000-558ba4abb000 r-xp 00000000 08:03 3285459 /usr/lib/jvm/java-8-openjdk/jre/bin/java +558ba4cba000-558ba4cbb000 r--p 00000000 08:03 3285459 /usr/lib/jvm/java-8-openjdk/jre/bin/java +558ba4cbb000-558ba4cbc000 rw-p 00001000 08:03 3285459 /usr/lib/jvm/java-8-openjdk/jre/bin/java +558ba51d3000-558ba51f4000 rw-p 00000000 00:00 0 [heap] +7fd2f73c0000-7fd2f75c0000 ---p 00000000 00:00 0 +7fd2f75c0000-7fd2f75cb000 rw-p 00000000 00:00 0 +7fd2f75cb000-7fd2f77c1000 ---p 00000000 00:00 0 +7fd2f77c1000-7fd2f7a31000 rwxp 00000000 00:00 0 +7fd2f7a31000-7fd2ff7c1000 ---p 00000000 00:00 0 +7fd2ff7c1000-7fd2ff7c9000 r-xp 00000000 08:03 3285516 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libzip.so +7fd2ff7c9000-7fd2ff9c8000 ---p 00008000 08:03 3285516 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libzip.so +7fd2ff9c8000-7fd2ff9c9000 r--p 00007000 08:03 3285516 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libzip.so +7fd2ff9c9000-7fd2ff9ca000 rw-p 00008000 08:03 3285516 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libzip.so +7fd2ff9ca000-7fd2ff9d5000 r-xp 00000000 08:03 2496384 /usr/lib/libnss_files-2.26.so +7fd2ff9d5000-7fd2ffbd4000 ---p 0000b000 08:03 2496384 /usr/lib/libnss_files-2.26.so +7fd2ffbd4000-7fd2ffbd5000 r--p 0000a000 08:03 2496384 /usr/lib/libnss_files-2.26.so +7fd2ffbd5000-7fd2ffbd6000 rw-p 0000b000 08:03 2496384 /usr/lib/libnss_files-2.26.so +7fd2ffbd6000-7fd2ffbdc000 rw-p 00000000 00:00 0 +7fd2ffbdc000-7fd2ffbe7000 r-xp 00000000 08:03 2496388 /usr/lib/libnss_nis-2.26.so +7fd2ffbe7000-7fd2ffde6000 ---p 0000b000 08:03 2496388 /usr/lib/libnss_nis-2.26.so +7fd2ffde6000-7fd2ffde7000 r--p 0000a000 08:03 2496388 /usr/lib/libnss_nis-2.26.so +7fd2ffde7000-7fd2ffde8000 rw-p 0000b000 08:03 2496388 /usr/lib/libnss_nis-2.26.so +7fd2ffde8000-7fd2ffdfc000 r-xp 00000000 08:03 2496377 /usr/lib/libnsl-2.26.so +7fd2ffdfc000-7fd2ffffc000 ---p 00014000 08:03 2496377 /usr/lib/libnsl-2.26.so +7fd2ffffc000-7fd2ffffd000 r--p 00014000 08:03 2496377 /usr/lib/libnsl-2.26.so +7fd2ffffd000-7fd2ffffe000 rw-p 00015000 08:03 2496377 /usr/lib/libnsl-2.26.so +7fd2ffffe000-7fd300000000 rw-p 00000000 00:00 0 +7fd300000000-7fd300033000 rw-p 00000000 00:00 0 +7fd300033000-7fd304000000 ---p 00000000 00:00 0 +7fd30417a000-7fd304181000 r-xp 00000000 08:03 2496381 /usr/lib/libnss_compat-2.26.so +7fd304181000-7fd304380000 ---p 00007000 08:03 2496381 /usr/lib/libnss_compat-2.26.so +7fd304380000-7fd304381000 r--p 00006000 08:03 2496381 /usr/lib/libnss_compat-2.26.so +7fd304381000-7fd304382000 rw-p 00007000 08:03 2496381 /usr/lib/libnss_compat-2.26.so +7fd304382000-7fd3043b0000 r-xp 00000000 08:03 3285495 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libjava.so +7fd3043b0000-7fd3045af000 ---p 0002e000 08:03 3285495 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libjava.so +7fd3045af000-7fd3045b0000 r--p 0002d000 08:03 3285495 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libjava.so +7fd3045b0000-7fd3045b2000 rw-p 0002e000 08:03 3285495 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libjava.so +7fd3045b2000-7fd3045bf000 r-xp 00000000 08:03 3285515 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libverify.so +7fd3045bf000-7fd3047be000 ---p 0000d000 08:03 3285515 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libverify.so +7fd3047be000-7fd3047c0000 r--p 0000c000 08:03 3285515 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libverify.so +7fd3047c0000-7fd3047c1000 rw-p 0000e000 08:03 3285515 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libverify.so +7fd3047c1000-7fd3047c8000 r-xp 00000000 08:03 2496441 /usr/lib/librt-2.26.so +7fd3047c8000-7fd3049c7000 ---p 00007000 08:03 2496441 /usr/lib/librt-2.26.so +7fd3049c7000-7fd3049c8000 r--p 00006000 08:03 2496441 /usr/lib/librt-2.26.so +7fd3049c8000-7fd3049c9000 rw-p 00007000 08:03 2496441 /usr/lib/librt-2.26.so +7fd3049c9000-7fd304b14000 r-xp 00000000 08:03 2496340 /usr/lib/libm-2.26.so +7fd304b14000-7fd304d13000 ---p 0014b000 08:03 2496340 /usr/lib/libm-2.26.so +7fd304d13000-7fd304d14000 r--p 0014a000 08:03 2496340 /usr/lib/libm-2.26.so +7fd304d14000-7fd304d15000 rw-p 0014b000 08:03 2496340 /usr/lib/libm-2.26.so +7fd304d15000-7fd3059b7000 r-xp 00000000 08:03 3408093 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/server/libjvm.so +7fd3059b7000-7fd305bb7000 ---p 00ca2000 08:03 3408093 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/server/libjvm.so +7fd305bb7000-7fd305c4b000 r--p 00ca2000 08:03 3408093 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/server/libjvm.so +7fd305c4b000-7fd305c73000 rw-p 00d36000 08:03 3408093 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/server/libjvm.so +7fd305c73000-7fd305ca4000 rw-p 00000000 00:00 0 +7fd305ca4000-7fd305e52000 r-xp 00000000 08:03 2496207 /usr/lib/libc-2.26.so +7fd305e52000-7fd306051000 ---p 001ae000 08:03 2496207 /usr/lib/libc-2.26.so +7fd306051000-7fd306055000 r--p 001ad000 08:03 2496207 /usr/lib/libc-2.26.so +7fd306055000-7fd306057000 rw-p 001b1000 08:03 2496207 /usr/lib/libc-2.26.so +7fd306057000-7fd30605b000 rw-p 00000000 00:00 0 +7fd30605b000-7fd30605e000 r-xp 00000000 08:03 2496234 /usr/lib/libdl-2.26.so +7fd30605e000-7fd30625d000 ---p 00003000 08:03 2496234 /usr/lib/libdl-2.26.so +7fd30625d000-7fd30625e000 r--p 00002000 08:03 2496234 /usr/lib/libdl-2.26.so +7fd30625e000-7fd30625f000 rw-p 00003000 08:03 2496234 /usr/lib/libdl-2.26.so +7fd30625f000-7fd30626d000 r-xp 00000000 08:03 3408091 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/jli/libjli.so +7fd30626d000-7fd30646c000 ---p 0000e000 08:03 3408091 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/jli/libjli.so +7fd30646c000-7fd30646d000 r--p 0000d000 08:03 3408091 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/jli/libjli.so +7fd30646d000-7fd30646e000 rw-p 0000e000 08:03 3408091 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/jli/libjli.so +7fd30646e000-7fd306484000 r-xp 00000000 08:03 2496516 /usr/lib/libz.so.1.2.11 +7fd306484000-7fd306683000 ---p 00016000 08:03 2496516 /usr/lib/libz.so.1.2.11 +7fd306683000-7fd306684000 r--p 00015000 08:03 2496516 /usr/lib/libz.so.1.2.11 +7fd306684000-7fd306685000 rw-p 00016000 08:03 2496516 /usr/lib/libz.so.1.2.11 +7fd306685000-7fd30669e000 r-xp 00000000 08:03 2496427 /usr/lib/libpthread-2.26.so +7fd30669e000-7fd30689d000 ---p 00019000 08:03 2496427 /usr/lib/libpthread-2.26.so +7fd30689d000-7fd30689e000 r--p 00018000 08:03 2496427 /usr/lib/libpthread-2.26.so +7fd30689e000-7fd30689f000 rw-p 00019000 08:03 2496427 /usr/lib/libpthread-2.26.so +7fd30689f000-7fd3068a3000 rw-p 00000000 00:00 0 +7fd3068a3000-7fd3068c8000 r-xp 00000000 08:03 2496165 /usr/lib/ld-2.26.so +7fd306990000-7fd306991000 ---p 00000000 00:00 0 +7fd306991000-7fd306994000 ---p 00000000 00:00 0 +7fd306994000-7fd306a95000 rw-p 00000000 00:00 0 +7fd306abd000-7fd306ac5000 rw-s 00000000 00:29 324 /tmp/hsperfdata_mattia/16436 +7fd306ac5000-7fd306ac6000 rw-p 00000000 00:00 0 +7fd306ac6000-7fd306ac7000 r--p 00000000 00:00 0 +7fd306ac7000-7fd306ac8000 r--p 00024000 08:03 2496165 /usr/lib/ld-2.26.so +7fd306ac8000-7fd306ac9000 rw-p 00025000 08:03 2496165 /usr/lib/ld-2.26.so +7fd306ac9000-7fd306aca000 rw-p 00000000 00:00 0 +7ffd65953000-7ffd65974000 rw-p 00000000 00:00 0 [stack] +7ffd659f0000-7ffd659f3000 r--p 00000000 00:00 0 [vvar] +7ffd659f3000-7ffd659f5000 r-xp 00000000 00:00 0 [vdso] +ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall] + +VM Arguments: +jvm_args: -Xms1024m -Xmx1024m -XX:ReservedCodeCacheSize=128m -XX:MaxMetaspaceSize=256m +java_command: /usr/share/sbt/bin/sbt-launch.jar run +java_class_path (initial): /usr/share/sbt/bin/sbt-launch.jar +Launcher Type: SUN_STANDARD + +Environment Variables: +PATH=/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl +USERNAME=mattia +SHELL=/bin/bash +DISPLAY=:1 + +Signal Handlers: +SIGSEGV: [libjvm.so+0xaa8a00], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO +SIGBUS: [libjvm.so+0xaa8a00], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO +SIGFPE: [libjvm.so+0x8df590], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO +SIGPIPE: [libjvm.so+0x8df590], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO +SIGXFSZ: [libjvm.so+0x8df590], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO +SIGILL: [libjvm.so+0x8df590], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO +SIGUSR1: SIG_DFL, sa_mask[0]=00000000000000000000000000000000, sa_flags=none +SIGUSR2: [libjvm.so+0x8df440], sa_mask[0]=00000000000000000000000000000000, sa_flags=SA_RESTART|SA_SIGINFO +SIGHUP: SIG_DFL, sa_mask[0]=00000000000000000000000000000000, sa_flags=none +SIGINT: SIG_DFL, sa_mask[0]=00000000000000000000000000000000, sa_flags=none +SIGTERM: SIG_DFL, sa_mask[0]=00000000000000000000000000000000, sa_flags=none +SIGQUIT: SIG_DFL, sa_mask[0]=00000000000000000000000000000000, sa_flags=none + + +--------------- S Y S T E M --------------- + +OS:DISTRIB_ID=ManjaroLinux +DISTRIB_RELEASE=17.1.7 +DISTRIB_CODENAME=Hakoila +DISTRIB_DESCRIPTION="Manjaro Linux" + +uname:Linux 4.14.31-1-MANJARO #1 SMP PREEMPT Wed Mar 28 21:42:49 UTC 2018 x86_64 +libc:glibc 2.26 NPTL 2.26 +rlimit: STACK 8192k, CORE infinity, NPROC 31554, NOFILE 4096, AS infinity +load average:0.50 0.87 0.97 + +/proc/meminfo: +MemTotal: 8091324 kB +MemFree: 132740 kB +MemAvailable: 326416 kB +Buffers: 13880 kB +Cached: 1023072 kB +SwapCached: 0 kB +Active: 6691980 kB +Inactive: 922628 kB +Active(anon): 6496544 kB +Inactive(anon): 730464 kB +Active(file): 195436 kB +Inactive(file): 192164 kB +Unevictable: 84 kB +Mlocked: 84 kB +SwapTotal: 0 kB +SwapFree: 0 kB +Dirty: 6584 kB +Writeback: 0 kB +AnonPages: 6449520 kB +Mapped: 826284 kB +Shmem: 746216 kB +Slab: 115808 kB +SReclaimable: 53664 kB +SUnreclaim: 62144 kB +KernelStack: 17868 kB +PageTables: 75224 kB +NFS_Unstable: 0 kB +Bounce: 0 kB +WritebackTmp: 0 kB +CommitLimit: 4045660 kB +Committed_AS: 17952508 kB +VmallocTotal: 34359738367 kB +VmallocUsed: 0 kB +VmallocChunk: 0 kB +HardwareCorrupted: 0 kB +AnonHugePages: 2172928 kB +ShmemHugePages: 0 kB +ShmemPmdMapped: 0 kB +HugePages_Total: 0 +HugePages_Free: 0 +HugePages_Rsvd: 0 +HugePages_Surp: 0 +Hugepagesize: 2048 kB +DirectMap4k: 398372 kB +DirectMap2M: 7909376 kB +DirectMap1G: 0 kB + + +CPU:total 4 (initial active 4) (2 cores per cpu, 2 threads per core) family 6 model 158 stepping 9, cmov, cx8, fxsr, mmx, sse, sse2, sse3, ssse3, sse4.1, sse4.2, popcnt, avx, avx2, aes, clmul, erms, 3dnowpref, lzcnt, ht, tsc, tscinvbit, bmi1, bmi2, adx + +/proc/cpuinfo: +processor : 0 +vendor_id : GenuineIntel +cpu family : 6 +model : 158 +model name : Intel(R) Core(TM) i3-7100 CPU @ 3.90GHz +stepping : 9 +microcode : 0x84 +cpu MHz : 3900.050 +cache size : 3072 KB +physical id : 0 +siblings : 4 +core id : 0 +cpu cores : 2 +apicid : 0 +initial apicid : 0 +fpu : yes +fpu_exception : yes +cpuid level : 22 +wp : yes +flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single pti tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves ibpb ibrs stibp dtherm arat pln pts hwp hwp_notify hwp_act_window hwp_epp +bugs : cpu_meltdown spectre_v1 spectre_v2 +bogomips : 7827.00 +clflush size : 64 +cache_alignment : 64 +address sizes : 39 bits physical, 48 bits virtual +power management: + +processor : 1 +vendor_id : GenuineIntel +cpu family : 6 +model : 158 +model name : Intel(R) Core(TM) i3-7100 CPU @ 3.90GHz +stepping : 9 +microcode : 0x84 +cpu MHz : 3900.051 +cache size : 3072 KB +physical id : 0 +siblings : 4 +core id : 1 +cpu cores : 2 +apicid : 2 +initial apicid : 2 +fpu : yes +fpu_exception : yes +cpuid level : 22 +wp : yes +flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single pti tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves ibpb ibrs stibp dtherm arat pln pts hwp hwp_notify hwp_act_window hwp_epp +bugs : cpu_meltdown spectre_v1 spectre_v2 +bogomips : 7827.00 +clflush size : 64 +cache_alignment : 64 +address sizes : 39 bits physical, 48 bits virtual +power management: + +processor : 2 +vendor_id : GenuineIntel +cpu family : 6 +model : 158 +model name : Intel(R) Core(TM) i3-7100 CPU @ 3.90GHz +stepping : 9 +microcode : 0x84 +cpu MHz : 3900.008 +cache size : 3072 KB +physical id : 0 +siblings : 4 +core id : 0 +cpu cores : 2 +apicid : 1 +initial apicid : 1 +fpu : yes +fpu_exception : yes +cpuid level : 22 +wp : yes +flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single pti tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves ibpb ibrs stibp dtherm arat pln pts hwp hwp_notify hwp_act_window hwp_epp +bugs : cpu_meltdown spectre_v1 spectre_v2 +bogomips : 7827.00 +clflush size : 64 +cache_alignment : 64 +address sizes : 39 bits physical, 48 bits virtual +power management: + +processor : 3 +vendor_id : GenuineIntel +cpu family : 6 +model : 158 +model name : Intel(R) Core(TM) i3-7100 CPU @ 3.90GHz +stepping : 9 +microcode : 0x84 +cpu MHz : 3899.996 +cache size : 3072 KB +physical id : 0 +siblings : 4 +core id : 1 +cpu cores : 2 +apicid : 3 +initial apicid : 3 +fpu : yes +fpu_exception : yes +cpuid level : 22 +wp : yes +flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single pti tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves ibpb ibrs stibp dtherm arat pln pts hwp hwp_notify hwp_act_window hwp_epp +bugs : cpu_meltdown spectre_v1 spectre_v2 +bogomips : 7827.00 +clflush size : 64 +cache_alignment : 64 +address sizes : 39 bits physical, 48 bits virtual +power management: + + + +Memory: 4k page, physical 8091324k(132972k free), swap 0k(0k free) + +vm_info: OpenJDK 64-Bit Server VM (25.162-b12) for linux-amd64 JRE (1.8.0_162-b12), built on Mar 1 2018 16:46:58 by "builduser" with gcc 7.3.0 + +time: Tue Apr 10 14:00:13 2018 +elapsed time: 0 seconds (0d 0h 0m 0s) + diff --git a/hs_err_pid16514.log b/hs_err_pid16514.log new file mode 100644 index 00000000..2bed7e86 --- /dev/null +++ b/hs_err_pid16514.log @@ -0,0 +1,376 @@ +# +# There is insufficient memory for the Java Runtime Environment to continue. +# Native memory allocation (mmap) failed to map 357564416 bytes for committing reserved memory. +# Possible reasons: +# The system is out of physical RAM or swap space +# In 32 bit mode, the process size limit was hit +# Possible solutions: +# Reduce memory load on the system +# Increase physical memory or swap space +# Check if swap backing store is full +# Use 64 bit Java on a 64 bit OS +# Decrease Java heap size (-Xmx/-Xms) +# Decrease number of Java threads +# Decrease Java thread stack sizes (-Xss) +# Set larger code cache with -XX:ReservedCodeCacheSize= +# This output file may be truncated or incomplete. +# +# Out of Memory Error (os_linux.cpp:2640), pid=16514, tid=0x00007fe65d4ab700 +# +# JRE version: (8.0_162-b12) (build ) +# Java VM: OpenJDK 64-Bit Server VM (25.162-b12 mixed mode linux-amd64 compressed oops) +# Core dump written. Default location: /home/mattia/Jandom/core or core.16514 +# + +--------------- T H R E A D --------------- + +Current thread (0x00007fe65400b000): JavaThread "Unknown thread" [_thread_in_vm, id=16515, stack(0x00007fe65d3ac000,0x00007fe65d4ac000)] + +Stack: [0x00007fe65d3ac000,0x00007fe65d4ac000], sp=0x00007fe65d4aa5b0, free space=1017k +Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code) +V [libjvm.so+0xaa80b2] +V [libjvm.so+0x4d92c7] +V [libjvm.so+0x8e3eb0] +V [libjvm.so+0x8de45e] +V [libjvm.so+0x95ea76] +V [libjvm.so+0x960ac6] +V [libjvm.so+0x2b48d4] +V [libjvm.so+0x90bab1] +V [libjvm.so+0xa6a68a] +V [libjvm.so+0xa6a975] +V [libjvm.so+0x6252af] +V [libjvm.so+0xa4e0cb] +V [libjvm.so+0x6a4b40] JNI_CreateJavaVM+0x60 +C [libjli.so+0x2bf3] +C [libpthread.so.0+0x708c] start_thread+0xdc + + +--------------- P R O C E S S --------------- + +Java Threads: ( => current thread ) + +Other Threads: + +=>0x00007fe65400b000 (exited) JavaThread "Unknown thread" [_thread_in_vm, id=16515, stack(0x00007fe65d3ac000,0x00007fe65d4ac000)] + +VM state:not at safepoint (not fully initialized) + +VM Mutex/Monitor currently owned by a thread: None + +GC Heap History (0 events): +No events + +Deoptimization events (0 events): +No events + +Classes redefined (0 events): +No events + +Internal exceptions (0 events): +No events + +Events (0 events): +No events + + +Dynamic libraries: +c0000000-eab00000 ---p 00000000 00:00 0 +55560cc58000-55560cc59000 r-xp 00000000 08:03 3285459 /usr/lib/jvm/java-8-openjdk/jre/bin/java +55560ce58000-55560ce59000 r--p 00000000 08:03 3285459 /usr/lib/jvm/java-8-openjdk/jre/bin/java +55560ce59000-55560ce5a000 rw-p 00001000 08:03 3285459 /usr/lib/jvm/java-8-openjdk/jre/bin/java +55560d8a5000-55560d8c6000 rw-p 00000000 00:00 0 [heap] +7fe64c000000-7fe64c270000 rwxp 00000000 00:00 0 +7fe64c270000-7fe654000000 ---p 00000000 00:00 0 +7fe654000000-7fe654033000 rw-p 00000000 00:00 0 +7fe654033000-7fe658000000 ---p 00000000 00:00 0 +7fe659f55000-7fe65a155000 ---p 00000000 00:00 0 +7fe65a155000-7fe65a160000 rw-p 00000000 00:00 0 +7fe65a160000-7fe65a356000 ---p 00000000 00:00 0 +7fe65a356000-7fe65a35e000 r-xp 00000000 08:03 3285516 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libzip.so +7fe65a35e000-7fe65a55d000 ---p 00008000 08:03 3285516 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libzip.so +7fe65a55d000-7fe65a55e000 r--p 00007000 08:03 3285516 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libzip.so +7fe65a55e000-7fe65a55f000 rw-p 00008000 08:03 3285516 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libzip.so +7fe65a55f000-7fe65a56a000 r-xp 00000000 08:03 2496384 /usr/lib/libnss_files-2.26.so +7fe65a56a000-7fe65a769000 ---p 0000b000 08:03 2496384 /usr/lib/libnss_files-2.26.so +7fe65a769000-7fe65a76a000 r--p 0000a000 08:03 2496384 /usr/lib/libnss_files-2.26.so +7fe65a76a000-7fe65a76b000 rw-p 0000b000 08:03 2496384 /usr/lib/libnss_files-2.26.so +7fe65a76b000-7fe65a771000 rw-p 00000000 00:00 0 +7fe65a771000-7fe65a77c000 r-xp 00000000 08:03 2496388 /usr/lib/libnss_nis-2.26.so +7fe65a77c000-7fe65a97b000 ---p 0000b000 08:03 2496388 /usr/lib/libnss_nis-2.26.so +7fe65a97b000-7fe65a97c000 r--p 0000a000 08:03 2496388 /usr/lib/libnss_nis-2.26.so +7fe65a97c000-7fe65a97d000 rw-p 0000b000 08:03 2496388 /usr/lib/libnss_nis-2.26.so +7fe65a97d000-7fe65a991000 r-xp 00000000 08:03 2496377 /usr/lib/libnsl-2.26.so +7fe65a991000-7fe65ab91000 ---p 00014000 08:03 2496377 /usr/lib/libnsl-2.26.so +7fe65ab91000-7fe65ab92000 r--p 00014000 08:03 2496377 /usr/lib/libnsl-2.26.so +7fe65ab92000-7fe65ab93000 rw-p 00015000 08:03 2496377 /usr/lib/libnsl-2.26.so +7fe65ab93000-7fe65ab95000 rw-p 00000000 00:00 0 +7fe65ab95000-7fe65ab9c000 r-xp 00000000 08:03 2496381 /usr/lib/libnss_compat-2.26.so +7fe65ab9c000-7fe65ad9b000 ---p 00007000 08:03 2496381 /usr/lib/libnss_compat-2.26.so +7fe65ad9b000-7fe65ad9c000 r--p 00006000 08:03 2496381 /usr/lib/libnss_compat-2.26.so +7fe65ad9c000-7fe65ad9d000 rw-p 00007000 08:03 2496381 /usr/lib/libnss_compat-2.26.so +7fe65ad9d000-7fe65adcb000 r-xp 00000000 08:03 3285495 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libjava.so +7fe65adcb000-7fe65afca000 ---p 0002e000 08:03 3285495 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libjava.so +7fe65afca000-7fe65afcb000 r--p 0002d000 08:03 3285495 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libjava.so +7fe65afcb000-7fe65afcd000 rw-p 0002e000 08:03 3285495 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libjava.so +7fe65afcd000-7fe65afda000 r-xp 00000000 08:03 3285515 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libverify.so +7fe65afda000-7fe65b1d9000 ---p 0000d000 08:03 3285515 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libverify.so +7fe65b1d9000-7fe65b1db000 r--p 0000c000 08:03 3285515 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libverify.so +7fe65b1db000-7fe65b1dc000 rw-p 0000e000 08:03 3285515 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libverify.so +7fe65b1dc000-7fe65b1e3000 r-xp 00000000 08:03 2496441 /usr/lib/librt-2.26.so +7fe65b1e3000-7fe65b3e2000 ---p 00007000 08:03 2496441 /usr/lib/librt-2.26.so +7fe65b3e2000-7fe65b3e3000 r--p 00006000 08:03 2496441 /usr/lib/librt-2.26.so +7fe65b3e3000-7fe65b3e4000 rw-p 00007000 08:03 2496441 /usr/lib/librt-2.26.so +7fe65b3e4000-7fe65b52f000 r-xp 00000000 08:03 2496340 /usr/lib/libm-2.26.so +7fe65b52f000-7fe65b72e000 ---p 0014b000 08:03 2496340 /usr/lib/libm-2.26.so +7fe65b72e000-7fe65b72f000 r--p 0014a000 08:03 2496340 /usr/lib/libm-2.26.so +7fe65b72f000-7fe65b730000 rw-p 0014b000 08:03 2496340 /usr/lib/libm-2.26.so +7fe65b730000-7fe65c3d2000 r-xp 00000000 08:03 3408093 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/server/libjvm.so +7fe65c3d2000-7fe65c5d2000 ---p 00ca2000 08:03 3408093 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/server/libjvm.so +7fe65c5d2000-7fe65c666000 r--p 00ca2000 08:03 3408093 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/server/libjvm.so +7fe65c666000-7fe65c68e000 rw-p 00d36000 08:03 3408093 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/server/libjvm.so +7fe65c68e000-7fe65c6bf000 rw-p 00000000 00:00 0 +7fe65c6bf000-7fe65c86d000 r-xp 00000000 08:03 2496207 /usr/lib/libc-2.26.so +7fe65c86d000-7fe65ca6c000 ---p 001ae000 08:03 2496207 /usr/lib/libc-2.26.so +7fe65ca6c000-7fe65ca70000 r--p 001ad000 08:03 2496207 /usr/lib/libc-2.26.so +7fe65ca70000-7fe65ca72000 rw-p 001b1000 08:03 2496207 /usr/lib/libc-2.26.so +7fe65ca72000-7fe65ca76000 rw-p 00000000 00:00 0 +7fe65ca76000-7fe65ca79000 r-xp 00000000 08:03 2496234 /usr/lib/libdl-2.26.so +7fe65ca79000-7fe65cc78000 ---p 00003000 08:03 2496234 /usr/lib/libdl-2.26.so +7fe65cc78000-7fe65cc79000 r--p 00002000 08:03 2496234 /usr/lib/libdl-2.26.so +7fe65cc79000-7fe65cc7a000 rw-p 00003000 08:03 2496234 /usr/lib/libdl-2.26.so +7fe65cc7a000-7fe65cc88000 r-xp 00000000 08:03 3408091 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/jli/libjli.so +7fe65cc88000-7fe65ce87000 ---p 0000e000 08:03 3408091 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/jli/libjli.so +7fe65ce87000-7fe65ce88000 r--p 0000d000 08:03 3408091 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/jli/libjli.so +7fe65ce88000-7fe65ce89000 rw-p 0000e000 08:03 3408091 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/jli/libjli.so +7fe65ce89000-7fe65ce9f000 r-xp 00000000 08:03 2496516 /usr/lib/libz.so.1.2.11 +7fe65ce9f000-7fe65d09e000 ---p 00016000 08:03 2496516 /usr/lib/libz.so.1.2.11 +7fe65d09e000-7fe65d09f000 r--p 00015000 08:03 2496516 /usr/lib/libz.so.1.2.11 +7fe65d09f000-7fe65d0a0000 rw-p 00016000 08:03 2496516 /usr/lib/libz.so.1.2.11 +7fe65d0a0000-7fe65d0b9000 r-xp 00000000 08:03 2496427 /usr/lib/libpthread-2.26.so +7fe65d0b9000-7fe65d2b8000 ---p 00019000 08:03 2496427 /usr/lib/libpthread-2.26.so +7fe65d2b8000-7fe65d2b9000 r--p 00018000 08:03 2496427 /usr/lib/libpthread-2.26.so +7fe65d2b9000-7fe65d2ba000 rw-p 00019000 08:03 2496427 /usr/lib/libpthread-2.26.so +7fe65d2ba000-7fe65d2be000 rw-p 00000000 00:00 0 +7fe65d2be000-7fe65d2e3000 r-xp 00000000 08:03 2496165 /usr/lib/ld-2.26.so +7fe65d3ab000-7fe65d3ac000 ---p 00000000 00:00 0 +7fe65d3ac000-7fe65d3af000 ---p 00000000 00:00 0 +7fe65d3af000-7fe65d4b0000 rw-p 00000000 00:00 0 +7fe65d4d8000-7fe65d4e0000 rw-s 00000000 00:29 324 /tmp/hsperfdata_mattia/16514 +7fe65d4e0000-7fe65d4e1000 rw-p 00000000 00:00 0 +7fe65d4e1000-7fe65d4e2000 r--p 00000000 00:00 0 +7fe65d4e2000-7fe65d4e3000 r--p 00024000 08:03 2496165 /usr/lib/ld-2.26.so +7fe65d4e3000-7fe65d4e4000 rw-p 00025000 08:03 2496165 /usr/lib/ld-2.26.so +7fe65d4e4000-7fe65d4e5000 rw-p 00000000 00:00 0 +7ffd55c60000-7ffd55c81000 rw-p 00000000 00:00 0 [stack] +7ffd55df2000-7ffd55df5000 r--p 00000000 00:00 0 [vvar] +7ffd55df5000-7ffd55df7000 r-xp 00000000 00:00 0 [vdso] +ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall] + +VM Arguments: +jvm_args: -Xms1024m -Xmx1024m -XX:ReservedCodeCacheSize=128m -XX:MaxMetaspaceSize=256m +java_command: /usr/share/sbt/bin/sbt-launch.jar run +java_class_path (initial): /usr/share/sbt/bin/sbt-launch.jar +Launcher Type: SUN_STANDARD + +Environment Variables: +PATH=/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl +USERNAME=mattia +SHELL=/bin/bash +DISPLAY=:1 + +Signal Handlers: +SIGSEGV: [libjvm.so+0xaa8a00], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO +SIGBUS: [libjvm.so+0xaa8a00], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO +SIGFPE: [libjvm.so+0x8df590], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO +SIGPIPE: [libjvm.so+0x8df590], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO +SIGXFSZ: [libjvm.so+0x8df590], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO +SIGILL: [libjvm.so+0x8df590], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO +SIGUSR1: SIG_DFL, sa_mask[0]=00000000000000000000000000000000, sa_flags=none +SIGUSR2: [libjvm.so+0x8df440], sa_mask[0]=00000000000000000000000000000000, sa_flags=SA_RESTART|SA_SIGINFO +SIGHUP: SIG_DFL, sa_mask[0]=00000000000000000000000000000000, sa_flags=none +SIGINT: SIG_DFL, sa_mask[0]=00000000000000000000000000000000, sa_flags=none +SIGTERM: SIG_DFL, sa_mask[0]=00000000000000000000000000000000, sa_flags=none +SIGQUIT: SIG_DFL, sa_mask[0]=00000000000000000000000000000000, sa_flags=none + + +--------------- S Y S T E M --------------- + +OS:DISTRIB_ID=ManjaroLinux +DISTRIB_RELEASE=17.1.7 +DISTRIB_CODENAME=Hakoila +DISTRIB_DESCRIPTION="Manjaro Linux" + +uname:Linux 4.14.31-1-MANJARO #1 SMP PREEMPT Wed Mar 28 21:42:49 UTC 2018 x86_64 +libc:glibc 2.26 NPTL 2.26 +rlimit: STACK 8192k, CORE infinity, NPROC 31554, NOFILE 4096, AS infinity +load average:0.54 0.87 0.97 + +/proc/meminfo: +MemTotal: 8091324 kB +MemFree: 134732 kB +MemAvailable: 329176 kB +Buffers: 14072 kB +Cached: 1018068 kB +SwapCached: 0 kB +Active: 6697868 kB +Inactive: 915432 kB +Active(anon): 6500104 kB +Inactive(anon): 724748 kB +Active(file): 197764 kB +Inactive(file): 190684 kB +Unevictable: 84 kB +Mlocked: 84 kB +SwapTotal: 0 kB +SwapFree: 0 kB +Dirty: 6940 kB +Writeback: 0 kB +AnonPages: 6453256 kB +Mapped: 820980 kB +Shmem: 740500 kB +Slab: 115652 kB +SReclaimable: 53500 kB +SUnreclaim: 62152 kB +KernelStack: 17692 kB +PageTables: 74984 kB +NFS_Unstable: 0 kB +Bounce: 0 kB +WritebackTmp: 0 kB +CommitLimit: 4045660 kB +Committed_AS: 17932412 kB +VmallocTotal: 34359738367 kB +VmallocUsed: 0 kB +VmallocChunk: 0 kB +HardwareCorrupted: 0 kB +AnonHugePages: 2172928 kB +ShmemHugePages: 0 kB +ShmemPmdMapped: 0 kB +HugePages_Total: 0 +HugePages_Free: 0 +HugePages_Rsvd: 0 +HugePages_Surp: 0 +Hugepagesize: 2048 kB +DirectMap4k: 398372 kB +DirectMap2M: 7909376 kB +DirectMap1G: 0 kB + + +CPU:total 4 (initial active 4) (2 cores per cpu, 2 threads per core) family 6 model 158 stepping 9, cmov, cx8, fxsr, mmx, sse, sse2, sse3, ssse3, sse4.1, sse4.2, popcnt, avx, avx2, aes, clmul, erms, 3dnowpref, lzcnt, ht, tsc, tscinvbit, bmi1, bmi2, adx + +/proc/cpuinfo: +processor : 0 +vendor_id : GenuineIntel +cpu family : 6 +model : 158 +model name : Intel(R) Core(TM) i3-7100 CPU @ 3.90GHz +stepping : 9 +microcode : 0x84 +cpu MHz : 3900.046 +cache size : 3072 KB +physical id : 0 +siblings : 4 +core id : 0 +cpu cores : 2 +apicid : 0 +initial apicid : 0 +fpu : yes +fpu_exception : yes +cpuid level : 22 +wp : yes +flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single pti tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves ibpb ibrs stibp dtherm arat pln pts hwp hwp_notify hwp_act_window hwp_epp +bugs : cpu_meltdown spectre_v1 spectre_v2 +bogomips : 7827.00 +clflush size : 64 +cache_alignment : 64 +address sizes : 39 bits physical, 48 bits virtual +power management: + +processor : 1 +vendor_id : GenuineIntel +cpu family : 6 +model : 158 +model name : Intel(R) Core(TM) i3-7100 CPU @ 3.90GHz +stepping : 9 +microcode : 0x84 +cpu MHz : 3900.085 +cache size : 3072 KB +physical id : 0 +siblings : 4 +core id : 1 +cpu cores : 2 +apicid : 2 +initial apicid : 2 +fpu : yes +fpu_exception : yes +cpuid level : 22 +wp : yes +flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single pti tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves ibpb ibrs stibp dtherm arat pln pts hwp hwp_notify hwp_act_window hwp_epp +bugs : cpu_meltdown spectre_v1 spectre_v2 +bogomips : 7827.00 +clflush size : 64 +cache_alignment : 64 +address sizes : 39 bits physical, 48 bits virtual +power management: + +processor : 2 +vendor_id : GenuineIntel +cpu family : 6 +model : 158 +model name : Intel(R) Core(TM) i3-7100 CPU @ 3.90GHz +stepping : 9 +microcode : 0x84 +cpu MHz : 3900.011 +cache size : 3072 KB +physical id : 0 +siblings : 4 +core id : 0 +cpu cores : 2 +apicid : 1 +initial apicid : 1 +fpu : yes +fpu_exception : yes +cpuid level : 22 +wp : yes +flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single pti tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves ibpb ibrs stibp dtherm arat pln pts hwp hwp_notify hwp_act_window hwp_epp +bugs : cpu_meltdown spectre_v1 spectre_v2 +bogomips : 7827.00 +clflush size : 64 +cache_alignment : 64 +address sizes : 39 bits physical, 48 bits virtual +power management: + +processor : 3 +vendor_id : GenuineIntel +cpu family : 6 +model : 158 +model name : Intel(R) Core(TM) i3-7100 CPU @ 3.90GHz +stepping : 9 +microcode : 0x84 +cpu MHz : 3900.004 +cache size : 3072 KB +physical id : 0 +siblings : 4 +core id : 1 +cpu cores : 2 +apicid : 3 +initial apicid : 3 +fpu : yes +fpu_exception : yes +cpuid level : 22 +wp : yes +flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single pti tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves ibpb ibrs stibp dtherm arat pln pts hwp hwp_notify hwp_act_window hwp_epp +bugs : cpu_meltdown spectre_v1 spectre_v2 +bogomips : 7827.00 +clflush size : 64 +cache_alignment : 64 +address sizes : 39 bits physical, 48 bits virtual +power management: + + + +Memory: 4k page, physical 8091324k(133992k free), swap 0k(0k free) + +vm_info: OpenJDK 64-Bit Server VM (25.162-b12) for linux-amd64 JRE (1.8.0_162-b12), built on Mar 1 2018 16:46:58 by "builduser" with gcc 7.3.0 + +time: Tue Apr 10 14:00:20 2018 +elapsed time: 0 seconds (0d 0h 0m 0s) + diff --git a/hs_err_pid17258.log b/hs_err_pid17258.log new file mode 100644 index 00000000..91fc0763 --- /dev/null +++ b/hs_err_pid17258.log @@ -0,0 +1,376 @@ +# +# There is insufficient memory for the Java Runtime Environment to continue. +# Native memory allocation (mmap) failed to map 716177408 bytes for committing reserved memory. +# Possible reasons: +# The system is out of physical RAM or swap space +# In 32 bit mode, the process size limit was hit +# Possible solutions: +# Reduce memory load on the system +# Increase physical memory or swap space +# Check if swap backing store is full +# Use 64 bit Java on a 64 bit OS +# Decrease Java heap size (-Xmx/-Xms) +# Decrease number of Java threads +# Decrease Java thread stack sizes (-Xss) +# Set larger code cache with -XX:ReservedCodeCacheSize= +# This output file may be truncated or incomplete. +# +# Out of Memory Error (os_linux.cpp:2640), pid=17258, tid=0x00007f0b0c473700 +# +# JRE version: (8.0_162-b12) (build ) +# Java VM: OpenJDK 64-Bit Server VM (25.162-b12 mixed mode linux-amd64 compressed oops) +# Core dump written. Default location: /home/mattia/Jandom/core or core.17258 +# + +--------------- T H R E A D --------------- + +Current thread (0x00007f0b0400b000): JavaThread "Unknown thread" [_thread_in_vm, id=17259, stack(0x00007f0b0c374000,0x00007f0b0c474000)] + +Stack: [0x00007f0b0c374000,0x00007f0b0c474000], sp=0x00007f0b0c4725a0, free space=1017k +Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code) +V [libjvm.so+0xaa80b2] +V [libjvm.so+0x4d92c7] +V [libjvm.so+0x8e3eb0] +V [libjvm.so+0x8de45e] +V [libjvm.so+0x95ea76] +V [libjvm.so+0x94edac] +V [libjvm.so+0x2b490e] +V [libjvm.so+0x90bab1] +V [libjvm.so+0xa6a68a] +V [libjvm.so+0xa6a975] +V [libjvm.so+0x6252af] +V [libjvm.so+0xa4e0cb] +V [libjvm.so+0x6a4b40] JNI_CreateJavaVM+0x60 +C [libjli.so+0x2bf3] +C [libpthread.so.0+0x708c] start_thread+0xdc + + +--------------- P R O C E S S --------------- + +Java Threads: ( => current thread ) + +Other Threads: + +=>0x00007f0b0400b000 (exited) JavaThread "Unknown thread" [_thread_in_vm, id=17259, stack(0x00007f0b0c374000,0x00007f0b0c474000)] + +VM state:not at safepoint (not fully initialized) + +VM Mutex/Monitor currently owned by a thread: None + +GC Heap History (0 events): +No events + +Deoptimization events (0 events): +No events + +Classes redefined (0 events): +No events + +Internal exceptions (0 events): +No events + +Events (0 events): +No events + + +Dynamic libraries: +eab00000-100000000 rw-p 00000000 00:00 0 +55efe910d000-55efe910e000 r-xp 00000000 08:03 3285459 /usr/lib/jvm/java-8-openjdk/jre/bin/java +55efe930d000-55efe930e000 r--p 00000000 08:03 3285459 /usr/lib/jvm/java-8-openjdk/jre/bin/java +55efe930e000-55efe930f000 rw-p 00001000 08:03 3285459 /usr/lib/jvm/java-8-openjdk/jre/bin/java +55efeb137000-55efeb158000 rw-p 00000000 00:00 0 [heap] +7f0afc000000-7f0afc270000 rwxp 00000000 00:00 0 +7f0afc270000-7f0b04000000 ---p 00000000 00:00 0 +7f0b04000000-7f0b04034000 rw-p 00000000 00:00 0 +7f0b04034000-7f0b08000000 ---p 00000000 00:00 0 +7f0b08f1d000-7f0b09072000 ---p 00000000 00:00 0 +7f0b09072000-7f0b09128000 rw-p 00000000 00:00 0 +7f0b09128000-7f0b0931e000 ---p 00000000 00:00 0 +7f0b0931e000-7f0b09326000 r-xp 00000000 08:03 3285516 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libzip.so +7f0b09326000-7f0b09525000 ---p 00008000 08:03 3285516 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libzip.so +7f0b09525000-7f0b09526000 r--p 00007000 08:03 3285516 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libzip.so +7f0b09526000-7f0b09527000 rw-p 00008000 08:03 3285516 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libzip.so +7f0b09527000-7f0b09532000 r-xp 00000000 08:03 2496384 /usr/lib/libnss_files-2.26.so +7f0b09532000-7f0b09731000 ---p 0000b000 08:03 2496384 /usr/lib/libnss_files-2.26.so +7f0b09731000-7f0b09732000 r--p 0000a000 08:03 2496384 /usr/lib/libnss_files-2.26.so +7f0b09732000-7f0b09733000 rw-p 0000b000 08:03 2496384 /usr/lib/libnss_files-2.26.so +7f0b09733000-7f0b09739000 rw-p 00000000 00:00 0 +7f0b09739000-7f0b09744000 r-xp 00000000 08:03 2496388 /usr/lib/libnss_nis-2.26.so +7f0b09744000-7f0b09943000 ---p 0000b000 08:03 2496388 /usr/lib/libnss_nis-2.26.so +7f0b09943000-7f0b09944000 r--p 0000a000 08:03 2496388 /usr/lib/libnss_nis-2.26.so +7f0b09944000-7f0b09945000 rw-p 0000b000 08:03 2496388 /usr/lib/libnss_nis-2.26.so +7f0b09945000-7f0b09959000 r-xp 00000000 08:03 2496377 /usr/lib/libnsl-2.26.so +7f0b09959000-7f0b09b59000 ---p 00014000 08:03 2496377 /usr/lib/libnsl-2.26.so +7f0b09b59000-7f0b09b5a000 r--p 00014000 08:03 2496377 /usr/lib/libnsl-2.26.so +7f0b09b5a000-7f0b09b5b000 rw-p 00015000 08:03 2496377 /usr/lib/libnsl-2.26.so +7f0b09b5b000-7f0b09b5d000 rw-p 00000000 00:00 0 +7f0b09b5d000-7f0b09b64000 r-xp 00000000 08:03 2496381 /usr/lib/libnss_compat-2.26.so +7f0b09b64000-7f0b09d63000 ---p 00007000 08:03 2496381 /usr/lib/libnss_compat-2.26.so +7f0b09d63000-7f0b09d64000 r--p 00006000 08:03 2496381 /usr/lib/libnss_compat-2.26.so +7f0b09d64000-7f0b09d65000 rw-p 00007000 08:03 2496381 /usr/lib/libnss_compat-2.26.so +7f0b09d65000-7f0b09d93000 r-xp 00000000 08:03 3285495 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libjava.so +7f0b09d93000-7f0b09f92000 ---p 0002e000 08:03 3285495 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libjava.so +7f0b09f92000-7f0b09f93000 r--p 0002d000 08:03 3285495 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libjava.so +7f0b09f93000-7f0b09f95000 rw-p 0002e000 08:03 3285495 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libjava.so +7f0b09f95000-7f0b09fa2000 r-xp 00000000 08:03 3285515 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libverify.so +7f0b09fa2000-7f0b0a1a1000 ---p 0000d000 08:03 3285515 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libverify.so +7f0b0a1a1000-7f0b0a1a3000 r--p 0000c000 08:03 3285515 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libverify.so +7f0b0a1a3000-7f0b0a1a4000 rw-p 0000e000 08:03 3285515 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libverify.so +7f0b0a1a4000-7f0b0a1ab000 r-xp 00000000 08:03 2496441 /usr/lib/librt-2.26.so +7f0b0a1ab000-7f0b0a3aa000 ---p 00007000 08:03 2496441 /usr/lib/librt-2.26.so +7f0b0a3aa000-7f0b0a3ab000 r--p 00006000 08:03 2496441 /usr/lib/librt-2.26.so +7f0b0a3ab000-7f0b0a3ac000 rw-p 00007000 08:03 2496441 /usr/lib/librt-2.26.so +7f0b0a3ac000-7f0b0a4f7000 r-xp 00000000 08:03 2496340 /usr/lib/libm-2.26.so +7f0b0a4f7000-7f0b0a6f6000 ---p 0014b000 08:03 2496340 /usr/lib/libm-2.26.so +7f0b0a6f6000-7f0b0a6f7000 r--p 0014a000 08:03 2496340 /usr/lib/libm-2.26.so +7f0b0a6f7000-7f0b0a6f8000 rw-p 0014b000 08:03 2496340 /usr/lib/libm-2.26.so +7f0b0a6f8000-7f0b0b39a000 r-xp 00000000 08:03 3408093 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/server/libjvm.so +7f0b0b39a000-7f0b0b59a000 ---p 00ca2000 08:03 3408093 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/server/libjvm.so +7f0b0b59a000-7f0b0b62e000 r--p 00ca2000 08:03 3408093 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/server/libjvm.so +7f0b0b62e000-7f0b0b656000 rw-p 00d36000 08:03 3408093 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/server/libjvm.so +7f0b0b656000-7f0b0b687000 rw-p 00000000 00:00 0 +7f0b0b687000-7f0b0b835000 r-xp 00000000 08:03 2496207 /usr/lib/libc-2.26.so +7f0b0b835000-7f0b0ba34000 ---p 001ae000 08:03 2496207 /usr/lib/libc-2.26.so +7f0b0ba34000-7f0b0ba38000 r--p 001ad000 08:03 2496207 /usr/lib/libc-2.26.so +7f0b0ba38000-7f0b0ba3a000 rw-p 001b1000 08:03 2496207 /usr/lib/libc-2.26.so +7f0b0ba3a000-7f0b0ba3e000 rw-p 00000000 00:00 0 +7f0b0ba3e000-7f0b0ba41000 r-xp 00000000 08:03 2496234 /usr/lib/libdl-2.26.so +7f0b0ba41000-7f0b0bc40000 ---p 00003000 08:03 2496234 /usr/lib/libdl-2.26.so +7f0b0bc40000-7f0b0bc41000 r--p 00002000 08:03 2496234 /usr/lib/libdl-2.26.so +7f0b0bc41000-7f0b0bc42000 rw-p 00003000 08:03 2496234 /usr/lib/libdl-2.26.so +7f0b0bc42000-7f0b0bc50000 r-xp 00000000 08:03 3408091 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/jli/libjli.so +7f0b0bc50000-7f0b0be4f000 ---p 0000e000 08:03 3408091 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/jli/libjli.so +7f0b0be4f000-7f0b0be50000 r--p 0000d000 08:03 3408091 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/jli/libjli.so +7f0b0be50000-7f0b0be51000 rw-p 0000e000 08:03 3408091 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/jli/libjli.so +7f0b0be51000-7f0b0be67000 r-xp 00000000 08:03 2496516 /usr/lib/libz.so.1.2.11 +7f0b0be67000-7f0b0c066000 ---p 00016000 08:03 2496516 /usr/lib/libz.so.1.2.11 +7f0b0c066000-7f0b0c067000 r--p 00015000 08:03 2496516 /usr/lib/libz.so.1.2.11 +7f0b0c067000-7f0b0c068000 rw-p 00016000 08:03 2496516 /usr/lib/libz.so.1.2.11 +7f0b0c068000-7f0b0c081000 r-xp 00000000 08:03 2496427 /usr/lib/libpthread-2.26.so +7f0b0c081000-7f0b0c280000 ---p 00019000 08:03 2496427 /usr/lib/libpthread-2.26.so +7f0b0c280000-7f0b0c281000 r--p 00018000 08:03 2496427 /usr/lib/libpthread-2.26.so +7f0b0c281000-7f0b0c282000 rw-p 00019000 08:03 2496427 /usr/lib/libpthread-2.26.so +7f0b0c282000-7f0b0c286000 rw-p 00000000 00:00 0 +7f0b0c286000-7f0b0c2ab000 r-xp 00000000 08:03 2496165 /usr/lib/ld-2.26.so +7f0b0c373000-7f0b0c374000 ---p 00000000 00:00 0 +7f0b0c374000-7f0b0c377000 ---p 00000000 00:00 0 +7f0b0c377000-7f0b0c478000 rw-p 00000000 00:00 0 +7f0b0c4a0000-7f0b0c4a8000 rw-s 00000000 00:29 230 /tmp/hsperfdata_mattia/17258 +7f0b0c4a8000-7f0b0c4a9000 rw-p 00000000 00:00 0 +7f0b0c4a9000-7f0b0c4aa000 r--p 00000000 00:00 0 +7f0b0c4aa000-7f0b0c4ab000 r--p 00024000 08:03 2496165 /usr/lib/ld-2.26.so +7f0b0c4ab000-7f0b0c4ac000 rw-p 00025000 08:03 2496165 /usr/lib/ld-2.26.so +7f0b0c4ac000-7f0b0c4ad000 rw-p 00000000 00:00 0 +7ffe6892a000-7ffe6894b000 rw-p 00000000 00:00 0 [stack] +7ffe689d3000-7ffe689d6000 r--p 00000000 00:00 0 [vvar] +7ffe689d6000-7ffe689d8000 r-xp 00000000 00:00 0 [vdso] +ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall] + +VM Arguments: +jvm_args: -Xms1024m -Xmx1024m -XX:ReservedCodeCacheSize=128m -XX:MaxMetaspaceSize=256m +java_command: /usr/share/sbt/bin/sbt-launch.jar run +java_class_path (initial): /usr/share/sbt/bin/sbt-launch.jar +Launcher Type: SUN_STANDARD + +Environment Variables: +PATH=/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl +USERNAME=mattia +SHELL=/bin/bash +DISPLAY=:1 + +Signal Handlers: +SIGSEGV: [libjvm.so+0xaa8a00], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO +SIGBUS: [libjvm.so+0xaa8a00], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO +SIGFPE: [libjvm.so+0x8df590], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO +SIGPIPE: [libjvm.so+0x8df590], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO +SIGXFSZ: [libjvm.so+0x8df590], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO +SIGILL: [libjvm.so+0x8df590], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO +SIGUSR1: SIG_DFL, sa_mask[0]=00000000000000000000000000000000, sa_flags=none +SIGUSR2: [libjvm.so+0x8df440], sa_mask[0]=00000000000000000000000000000000, sa_flags=SA_RESTART|SA_SIGINFO +SIGHUP: SIG_DFL, sa_mask[0]=00000000000000000000000000000000, sa_flags=none +SIGINT: SIG_DFL, sa_mask[0]=00000000000000000000000000000000, sa_flags=none +SIGTERM: SIG_DFL, sa_mask[0]=00000000000000000000000000000000, sa_flags=none +SIGQUIT: SIG_DFL, sa_mask[0]=00000000000000000000000000000000, sa_flags=none + + +--------------- S Y S T E M --------------- + +OS:DISTRIB_ID=ManjaroLinux +DISTRIB_RELEASE=17.1.7 +DISTRIB_CODENAME=Hakoila +DISTRIB_DESCRIPTION="Manjaro Linux" + +uname:Linux 4.14.31-1-MANJARO #1 SMP PREEMPT Wed Mar 28 21:42:49 UTC 2018 x86_64 +libc:glibc 2.26 NPTL 2.26 +rlimit: STACK 8192k, CORE infinity, NPROC 31554, NOFILE 4096, AS infinity +load average:1.22 1.28 1.06 + +/proc/meminfo: +MemTotal: 8091320 kB +MemFree: 212016 kB +MemAvailable: 532432 kB +Buffers: 27100 kB +Cached: 826664 kB +SwapCached: 0 kB +Active: 6927820 kB +Inactive: 645032 kB +Active(anon): 6626352 kB +Inactive(anon): 432396 kB +Active(file): 301468 kB +Inactive(file): 212636 kB +Unevictable: 104 kB +Mlocked: 104 kB +SwapTotal: 0 kB +SwapFree: 0 kB +Dirty: 136 kB +Writeback: 0 kB +AnonPages: 6571468 kB +Mapped: 595016 kB +Shmem: 445064 kB +Slab: 113180 kB +SReclaimable: 54336 kB +SUnreclaim: 58844 kB +KernelStack: 16664 kB +PageTables: 71472 kB +NFS_Unstable: 0 kB +Bounce: 0 kB +WritebackTmp: 0 kB +CommitLimit: 4045660 kB +Committed_AS: 18703336 kB +VmallocTotal: 34359738367 kB +VmallocUsed: 0 kB +VmallocChunk: 0 kB +HardwareCorrupted: 0 kB +AnonHugePages: 2297856 kB +ShmemHugePages: 0 kB +ShmemPmdMapped: 0 kB +HugePages_Total: 0 +HugePages_Free: 0 +HugePages_Rsvd: 0 +HugePages_Surp: 0 +Hugepagesize: 2048 kB +DirectMap4k: 410660 kB +DirectMap2M: 7897088 kB +DirectMap1G: 0 kB + + +CPU:total 4 (initial active 4) (2 cores per cpu, 2 threads per core) family 6 model 158 stepping 9, cmov, cx8, fxsr, mmx, sse, sse2, sse3, ssse3, sse4.1, sse4.2, popcnt, avx, avx2, aes, clmul, erms, 3dnowpref, lzcnt, ht, tsc, tscinvbit, bmi1, bmi2, adx + +/proc/cpuinfo: +processor : 0 +vendor_id : GenuineIntel +cpu family : 6 +model : 158 +model name : Intel(R) Core(TM) i3-7100 CPU @ 3.90GHz +stepping : 9 +microcode : 0x84 +cpu MHz : 3899.963 +cache size : 3072 KB +physical id : 0 +siblings : 4 +core id : 0 +cpu cores : 2 +apicid : 0 +initial apicid : 0 +fpu : yes +fpu_exception : yes +cpuid level : 22 +wp : yes +flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single pti tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves ibpb ibrs stibp dtherm arat pln pts hwp hwp_notify hwp_act_window hwp_epp +bugs : cpu_meltdown spectre_v1 spectre_v2 +bogomips : 7827.00 +clflush size : 64 +cache_alignment : 64 +address sizes : 39 bits physical, 48 bits virtual +power management: + +processor : 1 +vendor_id : GenuineIntel +cpu family : 6 +model : 158 +model name : Intel(R) Core(TM) i3-7100 CPU @ 3.90GHz +stepping : 9 +microcode : 0x84 +cpu MHz : 3900.001 +cache size : 3072 KB +physical id : 0 +siblings : 4 +core id : 1 +cpu cores : 2 +apicid : 2 +initial apicid : 2 +fpu : yes +fpu_exception : yes +cpuid level : 22 +wp : yes +flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single pti tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves ibpb ibrs stibp dtherm arat pln pts hwp hwp_notify hwp_act_window hwp_epp +bugs : cpu_meltdown spectre_v1 spectre_v2 +bogomips : 7827.00 +clflush size : 64 +cache_alignment : 64 +address sizes : 39 bits physical, 48 bits virtual +power management: + +processor : 2 +vendor_id : GenuineIntel +cpu family : 6 +model : 158 +model name : Intel(R) Core(TM) i3-7100 CPU @ 3.90GHz +stepping : 9 +microcode : 0x84 +cpu MHz : 3900.003 +cache size : 3072 KB +physical id : 0 +siblings : 4 +core id : 0 +cpu cores : 2 +apicid : 1 +initial apicid : 1 +fpu : yes +fpu_exception : yes +cpuid level : 22 +wp : yes +flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single pti tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves ibpb ibrs stibp dtherm arat pln pts hwp hwp_notify hwp_act_window hwp_epp +bugs : cpu_meltdown spectre_v1 spectre_v2 +bogomips : 7827.00 +clflush size : 64 +cache_alignment : 64 +address sizes : 39 bits physical, 48 bits virtual +power management: + +processor : 3 +vendor_id : GenuineIntel +cpu family : 6 +model : 158 +model name : Intel(R) Core(TM) i3-7100 CPU @ 3.90GHz +stepping : 9 +microcode : 0x84 +cpu MHz : 3899.999 +cache size : 3072 KB +physical id : 0 +siblings : 4 +core id : 1 +cpu cores : 2 +apicid : 3 +initial apicid : 3 +fpu : yes +fpu_exception : yes +cpuid level : 22 +wp : yes +flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single pti tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves ibpb ibrs stibp dtherm arat pln pts hwp hwp_notify hwp_act_window hwp_epp +bugs : cpu_meltdown spectre_v1 spectre_v2 +bogomips : 7827.00 +clflush size : 64 +cache_alignment : 64 +address sizes : 39 bits physical, 48 bits virtual +power management: + + + +Memory: 4k page, physical 8091320k(210868k free), swap 0k(0k free) + +vm_info: OpenJDK 64-Bit Server VM (25.162-b12) for linux-amd64 JRE (1.8.0_162-b12), built on Mar 1 2018 16:46:58 by "builduser" with gcc 7.3.0 + +time: Wed Apr 11 00:21:43 2018 +elapsed time: 0 seconds (0d 0h 0m 0s) + From ad33284695204a56d7f91918a9c3af6bf0f9c8cb Mon Sep 17 00:00:00 2001 From: Mattia Bottaro Date: Wed, 11 Apr 2018 00:52:15 +0200 Subject: [PATCH 84/99] Delete hs_err_pid16436.log --- hs_err_pid16436.log | 376 -------------------------------------------- 1 file changed, 376 deletions(-) delete mode 100644 hs_err_pid16436.log diff --git a/hs_err_pid16436.log b/hs_err_pid16436.log deleted file mode 100644 index 7d9aaa9a..00000000 --- a/hs_err_pid16436.log +++ /dev/null @@ -1,376 +0,0 @@ -# -# There is insufficient memory for the Java Runtime Environment to continue. -# Native memory allocation (mmap) failed to map 357564416 bytes for committing reserved memory. -# Possible reasons: -# The system is out of physical RAM or swap space -# In 32 bit mode, the process size limit was hit -# Possible solutions: -# Reduce memory load on the system -# Increase physical memory or swap space -# Check if swap backing store is full -# Use 64 bit Java on a 64 bit OS -# Decrease Java heap size (-Xmx/-Xms) -# Decrease number of Java threads -# Decrease Java thread stack sizes (-Xss) -# Set larger code cache with -XX:ReservedCodeCacheSize= -# This output file may be truncated or incomplete. -# -# Out of Memory Error (os_linux.cpp:2640), pid=16436, tid=0x00007fd306a90700 -# -# JRE version: (8.0_162-b12) (build ) -# Java VM: OpenJDK 64-Bit Server VM (25.162-b12 mixed mode linux-amd64 compressed oops) -# Core dump written. Default location: /home/mattia/Jandom/core or core.16436 -# - ---------------- T H R E A D --------------- - -Current thread (0x00007fd30000b000): JavaThread "Unknown thread" [_thread_in_vm, id=16437, stack(0x00007fd306991000,0x00007fd306a91000)] - -Stack: [0x00007fd306991000,0x00007fd306a91000], sp=0x00007fd306a8f5b0, free space=1017k -Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code) -V [libjvm.so+0xaa80b2] -V [libjvm.so+0x4d92c7] -V [libjvm.so+0x8e3eb0] -V [libjvm.so+0x8de45e] -V [libjvm.so+0x95ea76] -V [libjvm.so+0x960ac6] -V [libjvm.so+0x2b48d4] -V [libjvm.so+0x90bab1] -V [libjvm.so+0xa6a68a] -V [libjvm.so+0xa6a975] -V [libjvm.so+0x6252af] -V [libjvm.so+0xa4e0cb] -V [libjvm.so+0x6a4b40] JNI_CreateJavaVM+0x60 -C [libjli.so+0x2bf3] -C [libpthread.so.0+0x708c] start_thread+0xdc - - ---------------- P R O C E S S --------------- - -Java Threads: ( => current thread ) - -Other Threads: - -=>0x00007fd30000b000 (exited) JavaThread "Unknown thread" [_thread_in_vm, id=16437, stack(0x00007fd306991000,0x00007fd306a91000)] - -VM state:not at safepoint (not fully initialized) - -VM Mutex/Monitor currently owned by a thread: None - -GC Heap History (0 events): -No events - -Deoptimization events (0 events): -No events - -Classes redefined (0 events): -No events - -Internal exceptions (0 events): -No events - -Events (0 events): -No events - - -Dynamic libraries: -c0000000-eab00000 ---p 00000000 00:00 0 -558ba4aba000-558ba4abb000 r-xp 00000000 08:03 3285459 /usr/lib/jvm/java-8-openjdk/jre/bin/java -558ba4cba000-558ba4cbb000 r--p 00000000 08:03 3285459 /usr/lib/jvm/java-8-openjdk/jre/bin/java -558ba4cbb000-558ba4cbc000 rw-p 00001000 08:03 3285459 /usr/lib/jvm/java-8-openjdk/jre/bin/java -558ba51d3000-558ba51f4000 rw-p 00000000 00:00 0 [heap] -7fd2f73c0000-7fd2f75c0000 ---p 00000000 00:00 0 -7fd2f75c0000-7fd2f75cb000 rw-p 00000000 00:00 0 -7fd2f75cb000-7fd2f77c1000 ---p 00000000 00:00 0 -7fd2f77c1000-7fd2f7a31000 rwxp 00000000 00:00 0 -7fd2f7a31000-7fd2ff7c1000 ---p 00000000 00:00 0 -7fd2ff7c1000-7fd2ff7c9000 r-xp 00000000 08:03 3285516 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libzip.so -7fd2ff7c9000-7fd2ff9c8000 ---p 00008000 08:03 3285516 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libzip.so -7fd2ff9c8000-7fd2ff9c9000 r--p 00007000 08:03 3285516 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libzip.so -7fd2ff9c9000-7fd2ff9ca000 rw-p 00008000 08:03 3285516 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libzip.so -7fd2ff9ca000-7fd2ff9d5000 r-xp 00000000 08:03 2496384 /usr/lib/libnss_files-2.26.so -7fd2ff9d5000-7fd2ffbd4000 ---p 0000b000 08:03 2496384 /usr/lib/libnss_files-2.26.so -7fd2ffbd4000-7fd2ffbd5000 r--p 0000a000 08:03 2496384 /usr/lib/libnss_files-2.26.so -7fd2ffbd5000-7fd2ffbd6000 rw-p 0000b000 08:03 2496384 /usr/lib/libnss_files-2.26.so -7fd2ffbd6000-7fd2ffbdc000 rw-p 00000000 00:00 0 -7fd2ffbdc000-7fd2ffbe7000 r-xp 00000000 08:03 2496388 /usr/lib/libnss_nis-2.26.so -7fd2ffbe7000-7fd2ffde6000 ---p 0000b000 08:03 2496388 /usr/lib/libnss_nis-2.26.so -7fd2ffde6000-7fd2ffde7000 r--p 0000a000 08:03 2496388 /usr/lib/libnss_nis-2.26.so -7fd2ffde7000-7fd2ffde8000 rw-p 0000b000 08:03 2496388 /usr/lib/libnss_nis-2.26.so -7fd2ffde8000-7fd2ffdfc000 r-xp 00000000 08:03 2496377 /usr/lib/libnsl-2.26.so -7fd2ffdfc000-7fd2ffffc000 ---p 00014000 08:03 2496377 /usr/lib/libnsl-2.26.so -7fd2ffffc000-7fd2ffffd000 r--p 00014000 08:03 2496377 /usr/lib/libnsl-2.26.so -7fd2ffffd000-7fd2ffffe000 rw-p 00015000 08:03 2496377 /usr/lib/libnsl-2.26.so -7fd2ffffe000-7fd300000000 rw-p 00000000 00:00 0 -7fd300000000-7fd300033000 rw-p 00000000 00:00 0 -7fd300033000-7fd304000000 ---p 00000000 00:00 0 -7fd30417a000-7fd304181000 r-xp 00000000 08:03 2496381 /usr/lib/libnss_compat-2.26.so -7fd304181000-7fd304380000 ---p 00007000 08:03 2496381 /usr/lib/libnss_compat-2.26.so -7fd304380000-7fd304381000 r--p 00006000 08:03 2496381 /usr/lib/libnss_compat-2.26.so -7fd304381000-7fd304382000 rw-p 00007000 08:03 2496381 /usr/lib/libnss_compat-2.26.so -7fd304382000-7fd3043b0000 r-xp 00000000 08:03 3285495 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libjava.so -7fd3043b0000-7fd3045af000 ---p 0002e000 08:03 3285495 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libjava.so -7fd3045af000-7fd3045b0000 r--p 0002d000 08:03 3285495 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libjava.so -7fd3045b0000-7fd3045b2000 rw-p 0002e000 08:03 3285495 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libjava.so -7fd3045b2000-7fd3045bf000 r-xp 00000000 08:03 3285515 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libverify.so -7fd3045bf000-7fd3047be000 ---p 0000d000 08:03 3285515 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libverify.so -7fd3047be000-7fd3047c0000 r--p 0000c000 08:03 3285515 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libverify.so -7fd3047c0000-7fd3047c1000 rw-p 0000e000 08:03 3285515 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libverify.so -7fd3047c1000-7fd3047c8000 r-xp 00000000 08:03 2496441 /usr/lib/librt-2.26.so -7fd3047c8000-7fd3049c7000 ---p 00007000 08:03 2496441 /usr/lib/librt-2.26.so -7fd3049c7000-7fd3049c8000 r--p 00006000 08:03 2496441 /usr/lib/librt-2.26.so -7fd3049c8000-7fd3049c9000 rw-p 00007000 08:03 2496441 /usr/lib/librt-2.26.so -7fd3049c9000-7fd304b14000 r-xp 00000000 08:03 2496340 /usr/lib/libm-2.26.so -7fd304b14000-7fd304d13000 ---p 0014b000 08:03 2496340 /usr/lib/libm-2.26.so -7fd304d13000-7fd304d14000 r--p 0014a000 08:03 2496340 /usr/lib/libm-2.26.so -7fd304d14000-7fd304d15000 rw-p 0014b000 08:03 2496340 /usr/lib/libm-2.26.so -7fd304d15000-7fd3059b7000 r-xp 00000000 08:03 3408093 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/server/libjvm.so -7fd3059b7000-7fd305bb7000 ---p 00ca2000 08:03 3408093 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/server/libjvm.so -7fd305bb7000-7fd305c4b000 r--p 00ca2000 08:03 3408093 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/server/libjvm.so -7fd305c4b000-7fd305c73000 rw-p 00d36000 08:03 3408093 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/server/libjvm.so -7fd305c73000-7fd305ca4000 rw-p 00000000 00:00 0 -7fd305ca4000-7fd305e52000 r-xp 00000000 08:03 2496207 /usr/lib/libc-2.26.so -7fd305e52000-7fd306051000 ---p 001ae000 08:03 2496207 /usr/lib/libc-2.26.so -7fd306051000-7fd306055000 r--p 001ad000 08:03 2496207 /usr/lib/libc-2.26.so -7fd306055000-7fd306057000 rw-p 001b1000 08:03 2496207 /usr/lib/libc-2.26.so -7fd306057000-7fd30605b000 rw-p 00000000 00:00 0 -7fd30605b000-7fd30605e000 r-xp 00000000 08:03 2496234 /usr/lib/libdl-2.26.so -7fd30605e000-7fd30625d000 ---p 00003000 08:03 2496234 /usr/lib/libdl-2.26.so -7fd30625d000-7fd30625e000 r--p 00002000 08:03 2496234 /usr/lib/libdl-2.26.so -7fd30625e000-7fd30625f000 rw-p 00003000 08:03 2496234 /usr/lib/libdl-2.26.so -7fd30625f000-7fd30626d000 r-xp 00000000 08:03 3408091 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/jli/libjli.so -7fd30626d000-7fd30646c000 ---p 0000e000 08:03 3408091 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/jli/libjli.so -7fd30646c000-7fd30646d000 r--p 0000d000 08:03 3408091 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/jli/libjli.so -7fd30646d000-7fd30646e000 rw-p 0000e000 08:03 3408091 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/jli/libjli.so -7fd30646e000-7fd306484000 r-xp 00000000 08:03 2496516 /usr/lib/libz.so.1.2.11 -7fd306484000-7fd306683000 ---p 00016000 08:03 2496516 /usr/lib/libz.so.1.2.11 -7fd306683000-7fd306684000 r--p 00015000 08:03 2496516 /usr/lib/libz.so.1.2.11 -7fd306684000-7fd306685000 rw-p 00016000 08:03 2496516 /usr/lib/libz.so.1.2.11 -7fd306685000-7fd30669e000 r-xp 00000000 08:03 2496427 /usr/lib/libpthread-2.26.so -7fd30669e000-7fd30689d000 ---p 00019000 08:03 2496427 /usr/lib/libpthread-2.26.so -7fd30689d000-7fd30689e000 r--p 00018000 08:03 2496427 /usr/lib/libpthread-2.26.so -7fd30689e000-7fd30689f000 rw-p 00019000 08:03 2496427 /usr/lib/libpthread-2.26.so -7fd30689f000-7fd3068a3000 rw-p 00000000 00:00 0 -7fd3068a3000-7fd3068c8000 r-xp 00000000 08:03 2496165 /usr/lib/ld-2.26.so -7fd306990000-7fd306991000 ---p 00000000 00:00 0 -7fd306991000-7fd306994000 ---p 00000000 00:00 0 -7fd306994000-7fd306a95000 rw-p 00000000 00:00 0 -7fd306abd000-7fd306ac5000 rw-s 00000000 00:29 324 /tmp/hsperfdata_mattia/16436 -7fd306ac5000-7fd306ac6000 rw-p 00000000 00:00 0 -7fd306ac6000-7fd306ac7000 r--p 00000000 00:00 0 -7fd306ac7000-7fd306ac8000 r--p 00024000 08:03 2496165 /usr/lib/ld-2.26.so -7fd306ac8000-7fd306ac9000 rw-p 00025000 08:03 2496165 /usr/lib/ld-2.26.so -7fd306ac9000-7fd306aca000 rw-p 00000000 00:00 0 -7ffd65953000-7ffd65974000 rw-p 00000000 00:00 0 [stack] -7ffd659f0000-7ffd659f3000 r--p 00000000 00:00 0 [vvar] -7ffd659f3000-7ffd659f5000 r-xp 00000000 00:00 0 [vdso] -ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall] - -VM Arguments: -jvm_args: -Xms1024m -Xmx1024m -XX:ReservedCodeCacheSize=128m -XX:MaxMetaspaceSize=256m -java_command: /usr/share/sbt/bin/sbt-launch.jar run -java_class_path (initial): /usr/share/sbt/bin/sbt-launch.jar -Launcher Type: SUN_STANDARD - -Environment Variables: -PATH=/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl -USERNAME=mattia -SHELL=/bin/bash -DISPLAY=:1 - -Signal Handlers: -SIGSEGV: [libjvm.so+0xaa8a00], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO -SIGBUS: [libjvm.so+0xaa8a00], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO -SIGFPE: [libjvm.so+0x8df590], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO -SIGPIPE: [libjvm.so+0x8df590], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO -SIGXFSZ: [libjvm.so+0x8df590], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO -SIGILL: [libjvm.so+0x8df590], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO -SIGUSR1: SIG_DFL, sa_mask[0]=00000000000000000000000000000000, sa_flags=none -SIGUSR2: [libjvm.so+0x8df440], sa_mask[0]=00000000000000000000000000000000, sa_flags=SA_RESTART|SA_SIGINFO -SIGHUP: SIG_DFL, sa_mask[0]=00000000000000000000000000000000, sa_flags=none -SIGINT: SIG_DFL, sa_mask[0]=00000000000000000000000000000000, sa_flags=none -SIGTERM: SIG_DFL, sa_mask[0]=00000000000000000000000000000000, sa_flags=none -SIGQUIT: SIG_DFL, sa_mask[0]=00000000000000000000000000000000, sa_flags=none - - ---------------- S Y S T E M --------------- - -OS:DISTRIB_ID=ManjaroLinux -DISTRIB_RELEASE=17.1.7 -DISTRIB_CODENAME=Hakoila -DISTRIB_DESCRIPTION="Manjaro Linux" - -uname:Linux 4.14.31-1-MANJARO #1 SMP PREEMPT Wed Mar 28 21:42:49 UTC 2018 x86_64 -libc:glibc 2.26 NPTL 2.26 -rlimit: STACK 8192k, CORE infinity, NPROC 31554, NOFILE 4096, AS infinity -load average:0.50 0.87 0.97 - -/proc/meminfo: -MemTotal: 8091324 kB -MemFree: 132740 kB -MemAvailable: 326416 kB -Buffers: 13880 kB -Cached: 1023072 kB -SwapCached: 0 kB -Active: 6691980 kB -Inactive: 922628 kB -Active(anon): 6496544 kB -Inactive(anon): 730464 kB -Active(file): 195436 kB -Inactive(file): 192164 kB -Unevictable: 84 kB -Mlocked: 84 kB -SwapTotal: 0 kB -SwapFree: 0 kB -Dirty: 6584 kB -Writeback: 0 kB -AnonPages: 6449520 kB -Mapped: 826284 kB -Shmem: 746216 kB -Slab: 115808 kB -SReclaimable: 53664 kB -SUnreclaim: 62144 kB -KernelStack: 17868 kB -PageTables: 75224 kB -NFS_Unstable: 0 kB -Bounce: 0 kB -WritebackTmp: 0 kB -CommitLimit: 4045660 kB -Committed_AS: 17952508 kB -VmallocTotal: 34359738367 kB -VmallocUsed: 0 kB -VmallocChunk: 0 kB -HardwareCorrupted: 0 kB -AnonHugePages: 2172928 kB -ShmemHugePages: 0 kB -ShmemPmdMapped: 0 kB -HugePages_Total: 0 -HugePages_Free: 0 -HugePages_Rsvd: 0 -HugePages_Surp: 0 -Hugepagesize: 2048 kB -DirectMap4k: 398372 kB -DirectMap2M: 7909376 kB -DirectMap1G: 0 kB - - -CPU:total 4 (initial active 4) (2 cores per cpu, 2 threads per core) family 6 model 158 stepping 9, cmov, cx8, fxsr, mmx, sse, sse2, sse3, ssse3, sse4.1, sse4.2, popcnt, avx, avx2, aes, clmul, erms, 3dnowpref, lzcnt, ht, tsc, tscinvbit, bmi1, bmi2, adx - -/proc/cpuinfo: -processor : 0 -vendor_id : GenuineIntel -cpu family : 6 -model : 158 -model name : Intel(R) Core(TM) i3-7100 CPU @ 3.90GHz -stepping : 9 -microcode : 0x84 -cpu MHz : 3900.050 -cache size : 3072 KB -physical id : 0 -siblings : 4 -core id : 0 -cpu cores : 2 -apicid : 0 -initial apicid : 0 -fpu : yes -fpu_exception : yes -cpuid level : 22 -wp : yes -flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single pti tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves ibpb ibrs stibp dtherm arat pln pts hwp hwp_notify hwp_act_window hwp_epp -bugs : cpu_meltdown spectre_v1 spectre_v2 -bogomips : 7827.00 -clflush size : 64 -cache_alignment : 64 -address sizes : 39 bits physical, 48 bits virtual -power management: - -processor : 1 -vendor_id : GenuineIntel -cpu family : 6 -model : 158 -model name : Intel(R) Core(TM) i3-7100 CPU @ 3.90GHz -stepping : 9 -microcode : 0x84 -cpu MHz : 3900.051 -cache size : 3072 KB -physical id : 0 -siblings : 4 -core id : 1 -cpu cores : 2 -apicid : 2 -initial apicid : 2 -fpu : yes -fpu_exception : yes -cpuid level : 22 -wp : yes -flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single pti tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves ibpb ibrs stibp dtherm arat pln pts hwp hwp_notify hwp_act_window hwp_epp -bugs : cpu_meltdown spectre_v1 spectre_v2 -bogomips : 7827.00 -clflush size : 64 -cache_alignment : 64 -address sizes : 39 bits physical, 48 bits virtual -power management: - -processor : 2 -vendor_id : GenuineIntel -cpu family : 6 -model : 158 -model name : Intel(R) Core(TM) i3-7100 CPU @ 3.90GHz -stepping : 9 -microcode : 0x84 -cpu MHz : 3900.008 -cache size : 3072 KB -physical id : 0 -siblings : 4 -core id : 0 -cpu cores : 2 -apicid : 1 -initial apicid : 1 -fpu : yes -fpu_exception : yes -cpuid level : 22 -wp : yes -flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single pti tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves ibpb ibrs stibp dtherm arat pln pts hwp hwp_notify hwp_act_window hwp_epp -bugs : cpu_meltdown spectre_v1 spectre_v2 -bogomips : 7827.00 -clflush size : 64 -cache_alignment : 64 -address sizes : 39 bits physical, 48 bits virtual -power management: - -processor : 3 -vendor_id : GenuineIntel -cpu family : 6 -model : 158 -model name : Intel(R) Core(TM) i3-7100 CPU @ 3.90GHz -stepping : 9 -microcode : 0x84 -cpu MHz : 3899.996 -cache size : 3072 KB -physical id : 0 -siblings : 4 -core id : 1 -cpu cores : 2 -apicid : 3 -initial apicid : 3 -fpu : yes -fpu_exception : yes -cpuid level : 22 -wp : yes -flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single pti tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves ibpb ibrs stibp dtherm arat pln pts hwp hwp_notify hwp_act_window hwp_epp -bugs : cpu_meltdown spectre_v1 spectre_v2 -bogomips : 7827.00 -clflush size : 64 -cache_alignment : 64 -address sizes : 39 bits physical, 48 bits virtual -power management: - - - -Memory: 4k page, physical 8091324k(132972k free), swap 0k(0k free) - -vm_info: OpenJDK 64-Bit Server VM (25.162-b12) for linux-amd64 JRE (1.8.0_162-b12), built on Mar 1 2018 16:46:58 by "builduser" with gcc 7.3.0 - -time: Tue Apr 10 14:00:13 2018 -elapsed time: 0 seconds (0d 0h 0m 0s) - From 8621a2fd2fb87f6c949058bb9750475dfc74e78f Mon Sep 17 00:00:00 2001 From: Mattia Bottaro Date: Wed, 11 Apr 2018 00:52:34 +0200 Subject: [PATCH 85/99] Delete hs_err_pid16514.log --- hs_err_pid16514.log | 376 -------------------------------------------- 1 file changed, 376 deletions(-) delete mode 100644 hs_err_pid16514.log diff --git a/hs_err_pid16514.log b/hs_err_pid16514.log deleted file mode 100644 index 2bed7e86..00000000 --- a/hs_err_pid16514.log +++ /dev/null @@ -1,376 +0,0 @@ -# -# There is insufficient memory for the Java Runtime Environment to continue. -# Native memory allocation (mmap) failed to map 357564416 bytes for committing reserved memory. -# Possible reasons: -# The system is out of physical RAM or swap space -# In 32 bit mode, the process size limit was hit -# Possible solutions: -# Reduce memory load on the system -# Increase physical memory or swap space -# Check if swap backing store is full -# Use 64 bit Java on a 64 bit OS -# Decrease Java heap size (-Xmx/-Xms) -# Decrease number of Java threads -# Decrease Java thread stack sizes (-Xss) -# Set larger code cache with -XX:ReservedCodeCacheSize= -# This output file may be truncated or incomplete. -# -# Out of Memory Error (os_linux.cpp:2640), pid=16514, tid=0x00007fe65d4ab700 -# -# JRE version: (8.0_162-b12) (build ) -# Java VM: OpenJDK 64-Bit Server VM (25.162-b12 mixed mode linux-amd64 compressed oops) -# Core dump written. Default location: /home/mattia/Jandom/core or core.16514 -# - ---------------- T H R E A D --------------- - -Current thread (0x00007fe65400b000): JavaThread "Unknown thread" [_thread_in_vm, id=16515, stack(0x00007fe65d3ac000,0x00007fe65d4ac000)] - -Stack: [0x00007fe65d3ac000,0x00007fe65d4ac000], sp=0x00007fe65d4aa5b0, free space=1017k -Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code) -V [libjvm.so+0xaa80b2] -V [libjvm.so+0x4d92c7] -V [libjvm.so+0x8e3eb0] -V [libjvm.so+0x8de45e] -V [libjvm.so+0x95ea76] -V [libjvm.so+0x960ac6] -V [libjvm.so+0x2b48d4] -V [libjvm.so+0x90bab1] -V [libjvm.so+0xa6a68a] -V [libjvm.so+0xa6a975] -V [libjvm.so+0x6252af] -V [libjvm.so+0xa4e0cb] -V [libjvm.so+0x6a4b40] JNI_CreateJavaVM+0x60 -C [libjli.so+0x2bf3] -C [libpthread.so.0+0x708c] start_thread+0xdc - - ---------------- P R O C E S S --------------- - -Java Threads: ( => current thread ) - -Other Threads: - -=>0x00007fe65400b000 (exited) JavaThread "Unknown thread" [_thread_in_vm, id=16515, stack(0x00007fe65d3ac000,0x00007fe65d4ac000)] - -VM state:not at safepoint (not fully initialized) - -VM Mutex/Monitor currently owned by a thread: None - -GC Heap History (0 events): -No events - -Deoptimization events (0 events): -No events - -Classes redefined (0 events): -No events - -Internal exceptions (0 events): -No events - -Events (0 events): -No events - - -Dynamic libraries: -c0000000-eab00000 ---p 00000000 00:00 0 -55560cc58000-55560cc59000 r-xp 00000000 08:03 3285459 /usr/lib/jvm/java-8-openjdk/jre/bin/java -55560ce58000-55560ce59000 r--p 00000000 08:03 3285459 /usr/lib/jvm/java-8-openjdk/jre/bin/java -55560ce59000-55560ce5a000 rw-p 00001000 08:03 3285459 /usr/lib/jvm/java-8-openjdk/jre/bin/java -55560d8a5000-55560d8c6000 rw-p 00000000 00:00 0 [heap] -7fe64c000000-7fe64c270000 rwxp 00000000 00:00 0 -7fe64c270000-7fe654000000 ---p 00000000 00:00 0 -7fe654000000-7fe654033000 rw-p 00000000 00:00 0 -7fe654033000-7fe658000000 ---p 00000000 00:00 0 -7fe659f55000-7fe65a155000 ---p 00000000 00:00 0 -7fe65a155000-7fe65a160000 rw-p 00000000 00:00 0 -7fe65a160000-7fe65a356000 ---p 00000000 00:00 0 -7fe65a356000-7fe65a35e000 r-xp 00000000 08:03 3285516 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libzip.so -7fe65a35e000-7fe65a55d000 ---p 00008000 08:03 3285516 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libzip.so -7fe65a55d000-7fe65a55e000 r--p 00007000 08:03 3285516 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libzip.so -7fe65a55e000-7fe65a55f000 rw-p 00008000 08:03 3285516 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libzip.so -7fe65a55f000-7fe65a56a000 r-xp 00000000 08:03 2496384 /usr/lib/libnss_files-2.26.so -7fe65a56a000-7fe65a769000 ---p 0000b000 08:03 2496384 /usr/lib/libnss_files-2.26.so -7fe65a769000-7fe65a76a000 r--p 0000a000 08:03 2496384 /usr/lib/libnss_files-2.26.so -7fe65a76a000-7fe65a76b000 rw-p 0000b000 08:03 2496384 /usr/lib/libnss_files-2.26.so -7fe65a76b000-7fe65a771000 rw-p 00000000 00:00 0 -7fe65a771000-7fe65a77c000 r-xp 00000000 08:03 2496388 /usr/lib/libnss_nis-2.26.so -7fe65a77c000-7fe65a97b000 ---p 0000b000 08:03 2496388 /usr/lib/libnss_nis-2.26.so -7fe65a97b000-7fe65a97c000 r--p 0000a000 08:03 2496388 /usr/lib/libnss_nis-2.26.so -7fe65a97c000-7fe65a97d000 rw-p 0000b000 08:03 2496388 /usr/lib/libnss_nis-2.26.so -7fe65a97d000-7fe65a991000 r-xp 00000000 08:03 2496377 /usr/lib/libnsl-2.26.so -7fe65a991000-7fe65ab91000 ---p 00014000 08:03 2496377 /usr/lib/libnsl-2.26.so -7fe65ab91000-7fe65ab92000 r--p 00014000 08:03 2496377 /usr/lib/libnsl-2.26.so -7fe65ab92000-7fe65ab93000 rw-p 00015000 08:03 2496377 /usr/lib/libnsl-2.26.so -7fe65ab93000-7fe65ab95000 rw-p 00000000 00:00 0 -7fe65ab95000-7fe65ab9c000 r-xp 00000000 08:03 2496381 /usr/lib/libnss_compat-2.26.so -7fe65ab9c000-7fe65ad9b000 ---p 00007000 08:03 2496381 /usr/lib/libnss_compat-2.26.so -7fe65ad9b000-7fe65ad9c000 r--p 00006000 08:03 2496381 /usr/lib/libnss_compat-2.26.so -7fe65ad9c000-7fe65ad9d000 rw-p 00007000 08:03 2496381 /usr/lib/libnss_compat-2.26.so -7fe65ad9d000-7fe65adcb000 r-xp 00000000 08:03 3285495 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libjava.so -7fe65adcb000-7fe65afca000 ---p 0002e000 08:03 3285495 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libjava.so -7fe65afca000-7fe65afcb000 r--p 0002d000 08:03 3285495 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libjava.so -7fe65afcb000-7fe65afcd000 rw-p 0002e000 08:03 3285495 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libjava.so -7fe65afcd000-7fe65afda000 r-xp 00000000 08:03 3285515 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libverify.so -7fe65afda000-7fe65b1d9000 ---p 0000d000 08:03 3285515 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libverify.so -7fe65b1d9000-7fe65b1db000 r--p 0000c000 08:03 3285515 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libverify.so -7fe65b1db000-7fe65b1dc000 rw-p 0000e000 08:03 3285515 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libverify.so -7fe65b1dc000-7fe65b1e3000 r-xp 00000000 08:03 2496441 /usr/lib/librt-2.26.so -7fe65b1e3000-7fe65b3e2000 ---p 00007000 08:03 2496441 /usr/lib/librt-2.26.so -7fe65b3e2000-7fe65b3e3000 r--p 00006000 08:03 2496441 /usr/lib/librt-2.26.so -7fe65b3e3000-7fe65b3e4000 rw-p 00007000 08:03 2496441 /usr/lib/librt-2.26.so -7fe65b3e4000-7fe65b52f000 r-xp 00000000 08:03 2496340 /usr/lib/libm-2.26.so -7fe65b52f000-7fe65b72e000 ---p 0014b000 08:03 2496340 /usr/lib/libm-2.26.so -7fe65b72e000-7fe65b72f000 r--p 0014a000 08:03 2496340 /usr/lib/libm-2.26.so -7fe65b72f000-7fe65b730000 rw-p 0014b000 08:03 2496340 /usr/lib/libm-2.26.so -7fe65b730000-7fe65c3d2000 r-xp 00000000 08:03 3408093 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/server/libjvm.so -7fe65c3d2000-7fe65c5d2000 ---p 00ca2000 08:03 3408093 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/server/libjvm.so -7fe65c5d2000-7fe65c666000 r--p 00ca2000 08:03 3408093 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/server/libjvm.so -7fe65c666000-7fe65c68e000 rw-p 00d36000 08:03 3408093 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/server/libjvm.so -7fe65c68e000-7fe65c6bf000 rw-p 00000000 00:00 0 -7fe65c6bf000-7fe65c86d000 r-xp 00000000 08:03 2496207 /usr/lib/libc-2.26.so -7fe65c86d000-7fe65ca6c000 ---p 001ae000 08:03 2496207 /usr/lib/libc-2.26.so -7fe65ca6c000-7fe65ca70000 r--p 001ad000 08:03 2496207 /usr/lib/libc-2.26.so -7fe65ca70000-7fe65ca72000 rw-p 001b1000 08:03 2496207 /usr/lib/libc-2.26.so -7fe65ca72000-7fe65ca76000 rw-p 00000000 00:00 0 -7fe65ca76000-7fe65ca79000 r-xp 00000000 08:03 2496234 /usr/lib/libdl-2.26.so -7fe65ca79000-7fe65cc78000 ---p 00003000 08:03 2496234 /usr/lib/libdl-2.26.so -7fe65cc78000-7fe65cc79000 r--p 00002000 08:03 2496234 /usr/lib/libdl-2.26.so -7fe65cc79000-7fe65cc7a000 rw-p 00003000 08:03 2496234 /usr/lib/libdl-2.26.so -7fe65cc7a000-7fe65cc88000 r-xp 00000000 08:03 3408091 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/jli/libjli.so -7fe65cc88000-7fe65ce87000 ---p 0000e000 08:03 3408091 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/jli/libjli.so -7fe65ce87000-7fe65ce88000 r--p 0000d000 08:03 3408091 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/jli/libjli.so -7fe65ce88000-7fe65ce89000 rw-p 0000e000 08:03 3408091 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/jli/libjli.so -7fe65ce89000-7fe65ce9f000 r-xp 00000000 08:03 2496516 /usr/lib/libz.so.1.2.11 -7fe65ce9f000-7fe65d09e000 ---p 00016000 08:03 2496516 /usr/lib/libz.so.1.2.11 -7fe65d09e000-7fe65d09f000 r--p 00015000 08:03 2496516 /usr/lib/libz.so.1.2.11 -7fe65d09f000-7fe65d0a0000 rw-p 00016000 08:03 2496516 /usr/lib/libz.so.1.2.11 -7fe65d0a0000-7fe65d0b9000 r-xp 00000000 08:03 2496427 /usr/lib/libpthread-2.26.so -7fe65d0b9000-7fe65d2b8000 ---p 00019000 08:03 2496427 /usr/lib/libpthread-2.26.so -7fe65d2b8000-7fe65d2b9000 r--p 00018000 08:03 2496427 /usr/lib/libpthread-2.26.so -7fe65d2b9000-7fe65d2ba000 rw-p 00019000 08:03 2496427 /usr/lib/libpthread-2.26.so -7fe65d2ba000-7fe65d2be000 rw-p 00000000 00:00 0 -7fe65d2be000-7fe65d2e3000 r-xp 00000000 08:03 2496165 /usr/lib/ld-2.26.so -7fe65d3ab000-7fe65d3ac000 ---p 00000000 00:00 0 -7fe65d3ac000-7fe65d3af000 ---p 00000000 00:00 0 -7fe65d3af000-7fe65d4b0000 rw-p 00000000 00:00 0 -7fe65d4d8000-7fe65d4e0000 rw-s 00000000 00:29 324 /tmp/hsperfdata_mattia/16514 -7fe65d4e0000-7fe65d4e1000 rw-p 00000000 00:00 0 -7fe65d4e1000-7fe65d4e2000 r--p 00000000 00:00 0 -7fe65d4e2000-7fe65d4e3000 r--p 00024000 08:03 2496165 /usr/lib/ld-2.26.so -7fe65d4e3000-7fe65d4e4000 rw-p 00025000 08:03 2496165 /usr/lib/ld-2.26.so -7fe65d4e4000-7fe65d4e5000 rw-p 00000000 00:00 0 -7ffd55c60000-7ffd55c81000 rw-p 00000000 00:00 0 [stack] -7ffd55df2000-7ffd55df5000 r--p 00000000 00:00 0 [vvar] -7ffd55df5000-7ffd55df7000 r-xp 00000000 00:00 0 [vdso] -ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall] - -VM Arguments: -jvm_args: -Xms1024m -Xmx1024m -XX:ReservedCodeCacheSize=128m -XX:MaxMetaspaceSize=256m -java_command: /usr/share/sbt/bin/sbt-launch.jar run -java_class_path (initial): /usr/share/sbt/bin/sbt-launch.jar -Launcher Type: SUN_STANDARD - -Environment Variables: -PATH=/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl -USERNAME=mattia -SHELL=/bin/bash -DISPLAY=:1 - -Signal Handlers: -SIGSEGV: [libjvm.so+0xaa8a00], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO -SIGBUS: [libjvm.so+0xaa8a00], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO -SIGFPE: [libjvm.so+0x8df590], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO -SIGPIPE: [libjvm.so+0x8df590], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO -SIGXFSZ: [libjvm.so+0x8df590], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO -SIGILL: [libjvm.so+0x8df590], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO -SIGUSR1: SIG_DFL, sa_mask[0]=00000000000000000000000000000000, sa_flags=none -SIGUSR2: [libjvm.so+0x8df440], sa_mask[0]=00000000000000000000000000000000, sa_flags=SA_RESTART|SA_SIGINFO -SIGHUP: SIG_DFL, sa_mask[0]=00000000000000000000000000000000, sa_flags=none -SIGINT: SIG_DFL, sa_mask[0]=00000000000000000000000000000000, sa_flags=none -SIGTERM: SIG_DFL, sa_mask[0]=00000000000000000000000000000000, sa_flags=none -SIGQUIT: SIG_DFL, sa_mask[0]=00000000000000000000000000000000, sa_flags=none - - ---------------- S Y S T E M --------------- - -OS:DISTRIB_ID=ManjaroLinux -DISTRIB_RELEASE=17.1.7 -DISTRIB_CODENAME=Hakoila -DISTRIB_DESCRIPTION="Manjaro Linux" - -uname:Linux 4.14.31-1-MANJARO #1 SMP PREEMPT Wed Mar 28 21:42:49 UTC 2018 x86_64 -libc:glibc 2.26 NPTL 2.26 -rlimit: STACK 8192k, CORE infinity, NPROC 31554, NOFILE 4096, AS infinity -load average:0.54 0.87 0.97 - -/proc/meminfo: -MemTotal: 8091324 kB -MemFree: 134732 kB -MemAvailable: 329176 kB -Buffers: 14072 kB -Cached: 1018068 kB -SwapCached: 0 kB -Active: 6697868 kB -Inactive: 915432 kB -Active(anon): 6500104 kB -Inactive(anon): 724748 kB -Active(file): 197764 kB -Inactive(file): 190684 kB -Unevictable: 84 kB -Mlocked: 84 kB -SwapTotal: 0 kB -SwapFree: 0 kB -Dirty: 6940 kB -Writeback: 0 kB -AnonPages: 6453256 kB -Mapped: 820980 kB -Shmem: 740500 kB -Slab: 115652 kB -SReclaimable: 53500 kB -SUnreclaim: 62152 kB -KernelStack: 17692 kB -PageTables: 74984 kB -NFS_Unstable: 0 kB -Bounce: 0 kB -WritebackTmp: 0 kB -CommitLimit: 4045660 kB -Committed_AS: 17932412 kB -VmallocTotal: 34359738367 kB -VmallocUsed: 0 kB -VmallocChunk: 0 kB -HardwareCorrupted: 0 kB -AnonHugePages: 2172928 kB -ShmemHugePages: 0 kB -ShmemPmdMapped: 0 kB -HugePages_Total: 0 -HugePages_Free: 0 -HugePages_Rsvd: 0 -HugePages_Surp: 0 -Hugepagesize: 2048 kB -DirectMap4k: 398372 kB -DirectMap2M: 7909376 kB -DirectMap1G: 0 kB - - -CPU:total 4 (initial active 4) (2 cores per cpu, 2 threads per core) family 6 model 158 stepping 9, cmov, cx8, fxsr, mmx, sse, sse2, sse3, ssse3, sse4.1, sse4.2, popcnt, avx, avx2, aes, clmul, erms, 3dnowpref, lzcnt, ht, tsc, tscinvbit, bmi1, bmi2, adx - -/proc/cpuinfo: -processor : 0 -vendor_id : GenuineIntel -cpu family : 6 -model : 158 -model name : Intel(R) Core(TM) i3-7100 CPU @ 3.90GHz -stepping : 9 -microcode : 0x84 -cpu MHz : 3900.046 -cache size : 3072 KB -physical id : 0 -siblings : 4 -core id : 0 -cpu cores : 2 -apicid : 0 -initial apicid : 0 -fpu : yes -fpu_exception : yes -cpuid level : 22 -wp : yes -flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single pti tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves ibpb ibrs stibp dtherm arat pln pts hwp hwp_notify hwp_act_window hwp_epp -bugs : cpu_meltdown spectre_v1 spectre_v2 -bogomips : 7827.00 -clflush size : 64 -cache_alignment : 64 -address sizes : 39 bits physical, 48 bits virtual -power management: - -processor : 1 -vendor_id : GenuineIntel -cpu family : 6 -model : 158 -model name : Intel(R) Core(TM) i3-7100 CPU @ 3.90GHz -stepping : 9 -microcode : 0x84 -cpu MHz : 3900.085 -cache size : 3072 KB -physical id : 0 -siblings : 4 -core id : 1 -cpu cores : 2 -apicid : 2 -initial apicid : 2 -fpu : yes -fpu_exception : yes -cpuid level : 22 -wp : yes -flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single pti tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves ibpb ibrs stibp dtherm arat pln pts hwp hwp_notify hwp_act_window hwp_epp -bugs : cpu_meltdown spectre_v1 spectre_v2 -bogomips : 7827.00 -clflush size : 64 -cache_alignment : 64 -address sizes : 39 bits physical, 48 bits virtual -power management: - -processor : 2 -vendor_id : GenuineIntel -cpu family : 6 -model : 158 -model name : Intel(R) Core(TM) i3-7100 CPU @ 3.90GHz -stepping : 9 -microcode : 0x84 -cpu MHz : 3900.011 -cache size : 3072 KB -physical id : 0 -siblings : 4 -core id : 0 -cpu cores : 2 -apicid : 1 -initial apicid : 1 -fpu : yes -fpu_exception : yes -cpuid level : 22 -wp : yes -flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single pti tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves ibpb ibrs stibp dtherm arat pln pts hwp hwp_notify hwp_act_window hwp_epp -bugs : cpu_meltdown spectre_v1 spectre_v2 -bogomips : 7827.00 -clflush size : 64 -cache_alignment : 64 -address sizes : 39 bits physical, 48 bits virtual -power management: - -processor : 3 -vendor_id : GenuineIntel -cpu family : 6 -model : 158 -model name : Intel(R) Core(TM) i3-7100 CPU @ 3.90GHz -stepping : 9 -microcode : 0x84 -cpu MHz : 3900.004 -cache size : 3072 KB -physical id : 0 -siblings : 4 -core id : 1 -cpu cores : 2 -apicid : 3 -initial apicid : 3 -fpu : yes -fpu_exception : yes -cpuid level : 22 -wp : yes -flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single pti tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves ibpb ibrs stibp dtherm arat pln pts hwp hwp_notify hwp_act_window hwp_epp -bugs : cpu_meltdown spectre_v1 spectre_v2 -bogomips : 7827.00 -clflush size : 64 -cache_alignment : 64 -address sizes : 39 bits physical, 48 bits virtual -power management: - - - -Memory: 4k page, physical 8091324k(133992k free), swap 0k(0k free) - -vm_info: OpenJDK 64-Bit Server VM (25.162-b12) for linux-amd64 JRE (1.8.0_162-b12), built on Mar 1 2018 16:46:58 by "builduser" with gcc 7.3.0 - -time: Tue Apr 10 14:00:20 2018 -elapsed time: 0 seconds (0d 0h 0m 0s) - From eea823fd241e6216348c0a57cf8b5b6ed470e3c5 Mon Sep 17 00:00:00 2001 From: Mattia Bottaro Date: Wed, 11 Apr 2018 00:52:45 +0200 Subject: [PATCH 86/99] Delete hs_err_pid17258.log --- hs_err_pid17258.log | 376 -------------------------------------------- 1 file changed, 376 deletions(-) delete mode 100644 hs_err_pid17258.log diff --git a/hs_err_pid17258.log b/hs_err_pid17258.log deleted file mode 100644 index 91fc0763..00000000 --- a/hs_err_pid17258.log +++ /dev/null @@ -1,376 +0,0 @@ -# -# There is insufficient memory for the Java Runtime Environment to continue. -# Native memory allocation (mmap) failed to map 716177408 bytes for committing reserved memory. -# Possible reasons: -# The system is out of physical RAM or swap space -# In 32 bit mode, the process size limit was hit -# Possible solutions: -# Reduce memory load on the system -# Increase physical memory or swap space -# Check if swap backing store is full -# Use 64 bit Java on a 64 bit OS -# Decrease Java heap size (-Xmx/-Xms) -# Decrease number of Java threads -# Decrease Java thread stack sizes (-Xss) -# Set larger code cache with -XX:ReservedCodeCacheSize= -# This output file may be truncated or incomplete. -# -# Out of Memory Error (os_linux.cpp:2640), pid=17258, tid=0x00007f0b0c473700 -# -# JRE version: (8.0_162-b12) (build ) -# Java VM: OpenJDK 64-Bit Server VM (25.162-b12 mixed mode linux-amd64 compressed oops) -# Core dump written. Default location: /home/mattia/Jandom/core or core.17258 -# - ---------------- T H R E A D --------------- - -Current thread (0x00007f0b0400b000): JavaThread "Unknown thread" [_thread_in_vm, id=17259, stack(0x00007f0b0c374000,0x00007f0b0c474000)] - -Stack: [0x00007f0b0c374000,0x00007f0b0c474000], sp=0x00007f0b0c4725a0, free space=1017k -Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code) -V [libjvm.so+0xaa80b2] -V [libjvm.so+0x4d92c7] -V [libjvm.so+0x8e3eb0] -V [libjvm.so+0x8de45e] -V [libjvm.so+0x95ea76] -V [libjvm.so+0x94edac] -V [libjvm.so+0x2b490e] -V [libjvm.so+0x90bab1] -V [libjvm.so+0xa6a68a] -V [libjvm.so+0xa6a975] -V [libjvm.so+0x6252af] -V [libjvm.so+0xa4e0cb] -V [libjvm.so+0x6a4b40] JNI_CreateJavaVM+0x60 -C [libjli.so+0x2bf3] -C [libpthread.so.0+0x708c] start_thread+0xdc - - ---------------- P R O C E S S --------------- - -Java Threads: ( => current thread ) - -Other Threads: - -=>0x00007f0b0400b000 (exited) JavaThread "Unknown thread" [_thread_in_vm, id=17259, stack(0x00007f0b0c374000,0x00007f0b0c474000)] - -VM state:not at safepoint (not fully initialized) - -VM Mutex/Monitor currently owned by a thread: None - -GC Heap History (0 events): -No events - -Deoptimization events (0 events): -No events - -Classes redefined (0 events): -No events - -Internal exceptions (0 events): -No events - -Events (0 events): -No events - - -Dynamic libraries: -eab00000-100000000 rw-p 00000000 00:00 0 -55efe910d000-55efe910e000 r-xp 00000000 08:03 3285459 /usr/lib/jvm/java-8-openjdk/jre/bin/java -55efe930d000-55efe930e000 r--p 00000000 08:03 3285459 /usr/lib/jvm/java-8-openjdk/jre/bin/java -55efe930e000-55efe930f000 rw-p 00001000 08:03 3285459 /usr/lib/jvm/java-8-openjdk/jre/bin/java -55efeb137000-55efeb158000 rw-p 00000000 00:00 0 [heap] -7f0afc000000-7f0afc270000 rwxp 00000000 00:00 0 -7f0afc270000-7f0b04000000 ---p 00000000 00:00 0 -7f0b04000000-7f0b04034000 rw-p 00000000 00:00 0 -7f0b04034000-7f0b08000000 ---p 00000000 00:00 0 -7f0b08f1d000-7f0b09072000 ---p 00000000 00:00 0 -7f0b09072000-7f0b09128000 rw-p 00000000 00:00 0 -7f0b09128000-7f0b0931e000 ---p 00000000 00:00 0 -7f0b0931e000-7f0b09326000 r-xp 00000000 08:03 3285516 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libzip.so -7f0b09326000-7f0b09525000 ---p 00008000 08:03 3285516 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libzip.so -7f0b09525000-7f0b09526000 r--p 00007000 08:03 3285516 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libzip.so -7f0b09526000-7f0b09527000 rw-p 00008000 08:03 3285516 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libzip.so -7f0b09527000-7f0b09532000 r-xp 00000000 08:03 2496384 /usr/lib/libnss_files-2.26.so -7f0b09532000-7f0b09731000 ---p 0000b000 08:03 2496384 /usr/lib/libnss_files-2.26.so -7f0b09731000-7f0b09732000 r--p 0000a000 08:03 2496384 /usr/lib/libnss_files-2.26.so -7f0b09732000-7f0b09733000 rw-p 0000b000 08:03 2496384 /usr/lib/libnss_files-2.26.so -7f0b09733000-7f0b09739000 rw-p 00000000 00:00 0 -7f0b09739000-7f0b09744000 r-xp 00000000 08:03 2496388 /usr/lib/libnss_nis-2.26.so -7f0b09744000-7f0b09943000 ---p 0000b000 08:03 2496388 /usr/lib/libnss_nis-2.26.so -7f0b09943000-7f0b09944000 r--p 0000a000 08:03 2496388 /usr/lib/libnss_nis-2.26.so -7f0b09944000-7f0b09945000 rw-p 0000b000 08:03 2496388 /usr/lib/libnss_nis-2.26.so -7f0b09945000-7f0b09959000 r-xp 00000000 08:03 2496377 /usr/lib/libnsl-2.26.so -7f0b09959000-7f0b09b59000 ---p 00014000 08:03 2496377 /usr/lib/libnsl-2.26.so -7f0b09b59000-7f0b09b5a000 r--p 00014000 08:03 2496377 /usr/lib/libnsl-2.26.so -7f0b09b5a000-7f0b09b5b000 rw-p 00015000 08:03 2496377 /usr/lib/libnsl-2.26.so -7f0b09b5b000-7f0b09b5d000 rw-p 00000000 00:00 0 -7f0b09b5d000-7f0b09b64000 r-xp 00000000 08:03 2496381 /usr/lib/libnss_compat-2.26.so -7f0b09b64000-7f0b09d63000 ---p 00007000 08:03 2496381 /usr/lib/libnss_compat-2.26.so -7f0b09d63000-7f0b09d64000 r--p 00006000 08:03 2496381 /usr/lib/libnss_compat-2.26.so -7f0b09d64000-7f0b09d65000 rw-p 00007000 08:03 2496381 /usr/lib/libnss_compat-2.26.so -7f0b09d65000-7f0b09d93000 r-xp 00000000 08:03 3285495 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libjava.so -7f0b09d93000-7f0b09f92000 ---p 0002e000 08:03 3285495 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libjava.so -7f0b09f92000-7f0b09f93000 r--p 0002d000 08:03 3285495 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libjava.so -7f0b09f93000-7f0b09f95000 rw-p 0002e000 08:03 3285495 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libjava.so -7f0b09f95000-7f0b09fa2000 r-xp 00000000 08:03 3285515 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libverify.so -7f0b09fa2000-7f0b0a1a1000 ---p 0000d000 08:03 3285515 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libverify.so -7f0b0a1a1000-7f0b0a1a3000 r--p 0000c000 08:03 3285515 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libverify.so -7f0b0a1a3000-7f0b0a1a4000 rw-p 0000e000 08:03 3285515 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/libverify.so -7f0b0a1a4000-7f0b0a1ab000 r-xp 00000000 08:03 2496441 /usr/lib/librt-2.26.so -7f0b0a1ab000-7f0b0a3aa000 ---p 00007000 08:03 2496441 /usr/lib/librt-2.26.so -7f0b0a3aa000-7f0b0a3ab000 r--p 00006000 08:03 2496441 /usr/lib/librt-2.26.so -7f0b0a3ab000-7f0b0a3ac000 rw-p 00007000 08:03 2496441 /usr/lib/librt-2.26.so -7f0b0a3ac000-7f0b0a4f7000 r-xp 00000000 08:03 2496340 /usr/lib/libm-2.26.so -7f0b0a4f7000-7f0b0a6f6000 ---p 0014b000 08:03 2496340 /usr/lib/libm-2.26.so -7f0b0a6f6000-7f0b0a6f7000 r--p 0014a000 08:03 2496340 /usr/lib/libm-2.26.so -7f0b0a6f7000-7f0b0a6f8000 rw-p 0014b000 08:03 2496340 /usr/lib/libm-2.26.so -7f0b0a6f8000-7f0b0b39a000 r-xp 00000000 08:03 3408093 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/server/libjvm.so -7f0b0b39a000-7f0b0b59a000 ---p 00ca2000 08:03 3408093 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/server/libjvm.so -7f0b0b59a000-7f0b0b62e000 r--p 00ca2000 08:03 3408093 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/server/libjvm.so -7f0b0b62e000-7f0b0b656000 rw-p 00d36000 08:03 3408093 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/server/libjvm.so -7f0b0b656000-7f0b0b687000 rw-p 00000000 00:00 0 -7f0b0b687000-7f0b0b835000 r-xp 00000000 08:03 2496207 /usr/lib/libc-2.26.so -7f0b0b835000-7f0b0ba34000 ---p 001ae000 08:03 2496207 /usr/lib/libc-2.26.so -7f0b0ba34000-7f0b0ba38000 r--p 001ad000 08:03 2496207 /usr/lib/libc-2.26.so -7f0b0ba38000-7f0b0ba3a000 rw-p 001b1000 08:03 2496207 /usr/lib/libc-2.26.so -7f0b0ba3a000-7f0b0ba3e000 rw-p 00000000 00:00 0 -7f0b0ba3e000-7f0b0ba41000 r-xp 00000000 08:03 2496234 /usr/lib/libdl-2.26.so -7f0b0ba41000-7f0b0bc40000 ---p 00003000 08:03 2496234 /usr/lib/libdl-2.26.so -7f0b0bc40000-7f0b0bc41000 r--p 00002000 08:03 2496234 /usr/lib/libdl-2.26.so -7f0b0bc41000-7f0b0bc42000 rw-p 00003000 08:03 2496234 /usr/lib/libdl-2.26.so -7f0b0bc42000-7f0b0bc50000 r-xp 00000000 08:03 3408091 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/jli/libjli.so -7f0b0bc50000-7f0b0be4f000 ---p 0000e000 08:03 3408091 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/jli/libjli.so -7f0b0be4f000-7f0b0be50000 r--p 0000d000 08:03 3408091 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/jli/libjli.so -7f0b0be50000-7f0b0be51000 rw-p 0000e000 08:03 3408091 /usr/lib/jvm/java-8-openjdk/jre/lib/amd64/jli/libjli.so -7f0b0be51000-7f0b0be67000 r-xp 00000000 08:03 2496516 /usr/lib/libz.so.1.2.11 -7f0b0be67000-7f0b0c066000 ---p 00016000 08:03 2496516 /usr/lib/libz.so.1.2.11 -7f0b0c066000-7f0b0c067000 r--p 00015000 08:03 2496516 /usr/lib/libz.so.1.2.11 -7f0b0c067000-7f0b0c068000 rw-p 00016000 08:03 2496516 /usr/lib/libz.so.1.2.11 -7f0b0c068000-7f0b0c081000 r-xp 00000000 08:03 2496427 /usr/lib/libpthread-2.26.so -7f0b0c081000-7f0b0c280000 ---p 00019000 08:03 2496427 /usr/lib/libpthread-2.26.so -7f0b0c280000-7f0b0c281000 r--p 00018000 08:03 2496427 /usr/lib/libpthread-2.26.so -7f0b0c281000-7f0b0c282000 rw-p 00019000 08:03 2496427 /usr/lib/libpthread-2.26.so -7f0b0c282000-7f0b0c286000 rw-p 00000000 00:00 0 -7f0b0c286000-7f0b0c2ab000 r-xp 00000000 08:03 2496165 /usr/lib/ld-2.26.so -7f0b0c373000-7f0b0c374000 ---p 00000000 00:00 0 -7f0b0c374000-7f0b0c377000 ---p 00000000 00:00 0 -7f0b0c377000-7f0b0c478000 rw-p 00000000 00:00 0 -7f0b0c4a0000-7f0b0c4a8000 rw-s 00000000 00:29 230 /tmp/hsperfdata_mattia/17258 -7f0b0c4a8000-7f0b0c4a9000 rw-p 00000000 00:00 0 -7f0b0c4a9000-7f0b0c4aa000 r--p 00000000 00:00 0 -7f0b0c4aa000-7f0b0c4ab000 r--p 00024000 08:03 2496165 /usr/lib/ld-2.26.so -7f0b0c4ab000-7f0b0c4ac000 rw-p 00025000 08:03 2496165 /usr/lib/ld-2.26.so -7f0b0c4ac000-7f0b0c4ad000 rw-p 00000000 00:00 0 -7ffe6892a000-7ffe6894b000 rw-p 00000000 00:00 0 [stack] -7ffe689d3000-7ffe689d6000 r--p 00000000 00:00 0 [vvar] -7ffe689d6000-7ffe689d8000 r-xp 00000000 00:00 0 [vdso] -ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall] - -VM Arguments: -jvm_args: -Xms1024m -Xmx1024m -XX:ReservedCodeCacheSize=128m -XX:MaxMetaspaceSize=256m -java_command: /usr/share/sbt/bin/sbt-launch.jar run -java_class_path (initial): /usr/share/sbt/bin/sbt-launch.jar -Launcher Type: SUN_STANDARD - -Environment Variables: -PATH=/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl -USERNAME=mattia -SHELL=/bin/bash -DISPLAY=:1 - -Signal Handlers: -SIGSEGV: [libjvm.so+0xaa8a00], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO -SIGBUS: [libjvm.so+0xaa8a00], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO -SIGFPE: [libjvm.so+0x8df590], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO -SIGPIPE: [libjvm.so+0x8df590], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO -SIGXFSZ: [libjvm.so+0x8df590], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO -SIGILL: [libjvm.so+0x8df590], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO -SIGUSR1: SIG_DFL, sa_mask[0]=00000000000000000000000000000000, sa_flags=none -SIGUSR2: [libjvm.so+0x8df440], sa_mask[0]=00000000000000000000000000000000, sa_flags=SA_RESTART|SA_SIGINFO -SIGHUP: SIG_DFL, sa_mask[0]=00000000000000000000000000000000, sa_flags=none -SIGINT: SIG_DFL, sa_mask[0]=00000000000000000000000000000000, sa_flags=none -SIGTERM: SIG_DFL, sa_mask[0]=00000000000000000000000000000000, sa_flags=none -SIGQUIT: SIG_DFL, sa_mask[0]=00000000000000000000000000000000, sa_flags=none - - ---------------- S Y S T E M --------------- - -OS:DISTRIB_ID=ManjaroLinux -DISTRIB_RELEASE=17.1.7 -DISTRIB_CODENAME=Hakoila -DISTRIB_DESCRIPTION="Manjaro Linux" - -uname:Linux 4.14.31-1-MANJARO #1 SMP PREEMPT Wed Mar 28 21:42:49 UTC 2018 x86_64 -libc:glibc 2.26 NPTL 2.26 -rlimit: STACK 8192k, CORE infinity, NPROC 31554, NOFILE 4096, AS infinity -load average:1.22 1.28 1.06 - -/proc/meminfo: -MemTotal: 8091320 kB -MemFree: 212016 kB -MemAvailable: 532432 kB -Buffers: 27100 kB -Cached: 826664 kB -SwapCached: 0 kB -Active: 6927820 kB -Inactive: 645032 kB -Active(anon): 6626352 kB -Inactive(anon): 432396 kB -Active(file): 301468 kB -Inactive(file): 212636 kB -Unevictable: 104 kB -Mlocked: 104 kB -SwapTotal: 0 kB -SwapFree: 0 kB -Dirty: 136 kB -Writeback: 0 kB -AnonPages: 6571468 kB -Mapped: 595016 kB -Shmem: 445064 kB -Slab: 113180 kB -SReclaimable: 54336 kB -SUnreclaim: 58844 kB -KernelStack: 16664 kB -PageTables: 71472 kB -NFS_Unstable: 0 kB -Bounce: 0 kB -WritebackTmp: 0 kB -CommitLimit: 4045660 kB -Committed_AS: 18703336 kB -VmallocTotal: 34359738367 kB -VmallocUsed: 0 kB -VmallocChunk: 0 kB -HardwareCorrupted: 0 kB -AnonHugePages: 2297856 kB -ShmemHugePages: 0 kB -ShmemPmdMapped: 0 kB -HugePages_Total: 0 -HugePages_Free: 0 -HugePages_Rsvd: 0 -HugePages_Surp: 0 -Hugepagesize: 2048 kB -DirectMap4k: 410660 kB -DirectMap2M: 7897088 kB -DirectMap1G: 0 kB - - -CPU:total 4 (initial active 4) (2 cores per cpu, 2 threads per core) family 6 model 158 stepping 9, cmov, cx8, fxsr, mmx, sse, sse2, sse3, ssse3, sse4.1, sse4.2, popcnt, avx, avx2, aes, clmul, erms, 3dnowpref, lzcnt, ht, tsc, tscinvbit, bmi1, bmi2, adx - -/proc/cpuinfo: -processor : 0 -vendor_id : GenuineIntel -cpu family : 6 -model : 158 -model name : Intel(R) Core(TM) i3-7100 CPU @ 3.90GHz -stepping : 9 -microcode : 0x84 -cpu MHz : 3899.963 -cache size : 3072 KB -physical id : 0 -siblings : 4 -core id : 0 -cpu cores : 2 -apicid : 0 -initial apicid : 0 -fpu : yes -fpu_exception : yes -cpuid level : 22 -wp : yes -flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single pti tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves ibpb ibrs stibp dtherm arat pln pts hwp hwp_notify hwp_act_window hwp_epp -bugs : cpu_meltdown spectre_v1 spectre_v2 -bogomips : 7827.00 -clflush size : 64 -cache_alignment : 64 -address sizes : 39 bits physical, 48 bits virtual -power management: - -processor : 1 -vendor_id : GenuineIntel -cpu family : 6 -model : 158 -model name : Intel(R) Core(TM) i3-7100 CPU @ 3.90GHz -stepping : 9 -microcode : 0x84 -cpu MHz : 3900.001 -cache size : 3072 KB -physical id : 0 -siblings : 4 -core id : 1 -cpu cores : 2 -apicid : 2 -initial apicid : 2 -fpu : yes -fpu_exception : yes -cpuid level : 22 -wp : yes -flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single pti tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves ibpb ibrs stibp dtherm arat pln pts hwp hwp_notify hwp_act_window hwp_epp -bugs : cpu_meltdown spectre_v1 spectre_v2 -bogomips : 7827.00 -clflush size : 64 -cache_alignment : 64 -address sizes : 39 bits physical, 48 bits virtual -power management: - -processor : 2 -vendor_id : GenuineIntel -cpu family : 6 -model : 158 -model name : Intel(R) Core(TM) i3-7100 CPU @ 3.90GHz -stepping : 9 -microcode : 0x84 -cpu MHz : 3900.003 -cache size : 3072 KB -physical id : 0 -siblings : 4 -core id : 0 -cpu cores : 2 -apicid : 1 -initial apicid : 1 -fpu : yes -fpu_exception : yes -cpuid level : 22 -wp : yes -flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single pti tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves ibpb ibrs stibp dtherm arat pln pts hwp hwp_notify hwp_act_window hwp_epp -bugs : cpu_meltdown spectre_v1 spectre_v2 -bogomips : 7827.00 -clflush size : 64 -cache_alignment : 64 -address sizes : 39 bits physical, 48 bits virtual -power management: - -processor : 3 -vendor_id : GenuineIntel -cpu family : 6 -model : 158 -model name : Intel(R) Core(TM) i3-7100 CPU @ 3.90GHz -stepping : 9 -microcode : 0x84 -cpu MHz : 3899.999 -cache size : 3072 KB -physical id : 0 -siblings : 4 -core id : 1 -cpu cores : 2 -apicid : 3 -initial apicid : 3 -fpu : yes -fpu_exception : yes -cpuid level : 22 -wp : yes -flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single pti tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves ibpb ibrs stibp dtherm arat pln pts hwp hwp_notify hwp_act_window hwp_epp -bugs : cpu_meltdown spectre_v1 spectre_v2 -bogomips : 7827.00 -clflush size : 64 -cache_alignment : 64 -address sizes : 39 bits physical, 48 bits virtual -power management: - - - -Memory: 4k page, physical 8091320k(210868k free), swap 0k(0k free) - -vm_info: OpenJDK 64-Bit Server VM (25.162-b12) for linux-amd64 JRE (1.8.0_162-b12), built on Mar 1 2018 16:46:58 by "builduser" with gcc 7.3.0 - -time: Wed Apr 11 00:21:43 2018 -elapsed time: 0 seconds (0d 0h 0m 0s) - From 6dd3e5bff326078092dfe6bcb4b4091bcf60db9f Mon Sep 17 00:00:00 2001 From: Mattia Bottaro Date: Wed, 11 Apr 2018 00:53:05 +0200 Subject: [PATCH 87/99] Update .gitignore --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index ef7b210f..d700149c 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,6 @@ target.eclipse/ .cache-main .cache-tests *.sc - +*.log # intellij idea .idea/ From b3af707ff2a4bbcb2b047693fabfe79f82f6cf3b Mon Sep 17 00:00:00 2001 From: Mou95 Date: Wed, 11 Apr 2018 11:15:29 +0200 Subject: [PATCH 88/99] Added remainder operator and test for it --- core/examples/Java/TestBox.class | Bin 722 -> 720 bytes core/examples/Java/TestBox.java | 2 +- .../domains/numerical/box/BoxDomainCore.scala | 19 +++++++- .../box/BoundedBoxDomainCoreSuite.scala | 15 ++++-- .../numerical/box/BoxDomainCoreSuite.scala | 43 +++++++++++------- 5 files changed, 56 insertions(+), 23 deletions(-) diff --git a/core/examples/Java/TestBox.class b/core/examples/Java/TestBox.class index 8235515acb96156c7ec780a4f7b26714a043d2f1..bcc4358bbe7d5028684a4648a7b1fc11b0810227 100644 GIT binary patch delta 81 zcmcb_dVzIA9+PZ10}}%?0|SGk0GBnhjg$cYA_kro2F4af#^wLNOzvfpQ|D&TV&G%Y jW)NY}WsqRdW8ea+=3rp@%fQOW$j89Qzz^gzF$e$vb({<% delta 83 zcmcb>dWm&I9+P||0}}%?0|SG!0GBnhjg)kP0RJKeo)!ki7DmS9|36LcW|C9qWzb>} lV9;g|W6))gV$fsY0;=a=VEW6z%E&0dz{tQ4 IntervalBottom + case (_, IntervalBottom) => IntervalBottom + case (_, Interval(IntNumber(0),IntNumber(0))) => IntervalBottom + case (Interval(IntNumber(0),IntNumber(0)), _) => Interval(IntNumber(0),IntNumber(0)) + case (IntervalTop, _) => IntervalTop + case (_, IntervalTop) => IntervalTop + case (Interval (low1, high1), Interval (low2,high2)) => + if (low2 >= IntNumber(0)) + return Interval(IntNumber(0),high2 - IntNumber(1)) + if (high2 <= IntNumber(0)) + return Interval(low2 + IntNumber(1), IntNumber(0)) + return Interval(low2 + IntNumber(1), high2 - IntNumber(1)) + } } /** diff --git a/core/src/test/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCoreSuite.scala b/core/src/test/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCoreSuite.scala index d1c3c25e..915b0061 100644 --- a/core/src/test/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCoreSuite.scala +++ b/core/src/test/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCoreSuite.scala @@ -146,8 +146,14 @@ class BoundedBoxDomainCoreSuite extends FlatSpec { "BoundedBoxDomainCore.remainder" should " - return the remainder of the two Boxs given as input" in { - // IntervalBottom - /*assert(bc.remainder(IntervalBottom, One) === IntervalBottom) + val twoThree = Box.Interval(IntNumber(2), IntNumber(3)) + val MnineNine = Box.Interval(IntNumber(-9), IntNumber(9)) + val zeroTwo = Box.Interval(IntNumber(0), IntNumber(2)) + val MnineMseven = Box.Interval(IntNumber(-9), IntNumber(-7)) + val MeightZero = Box.Interval(IntNumber(-8), IntNumber(0)) + val MtwelveMseven = Box.Interval(IntNumber(-12), IntNumber(-7)) + //IntervalBottom + assert(bc.remainder(IntervalBottom, One) === IntervalBottom) assert(bc.remainder(IntervalBottom, IntervalTop) === IntervalBottom) assert(bc.remainder(One, IntervalBottom) === IntervalBottom) assert(bc.remainder(IntervalTop, IntervalBottom) === IntervalBottom) @@ -162,7 +168,10 @@ class BoundedBoxDomainCoreSuite extends FlatSpec { assert(bc.remainder(MtenTen, Zero) === IntervalBottom) assert(bc.remainder(Zero, Zero) === IntervalBottom) // Interval - assert(bc.remainder(MtenTen, MtenTen) === zero)*/ + assert(bc.remainder(MtenTen, MtenTen) === MnineNine) + assert(bc.remainder(MtenTen, twoThree) === zeroTwo) + assert(bc.remainder(MtenTen, MnineMseven) === MeightZero) + assert(bc.remainder(MtenTen, MtwelveMseven) === MinfZero) } "BoundedBoxDomainCore.lub" should diff --git a/core/src/test/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCoreSuite.scala b/core/src/test/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCoreSuite.scala index 3683f6d2..be52210f 100644 --- a/core/src/test/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCoreSuite.scala +++ b/core/src/test/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCoreSuite.scala @@ -134,23 +134,32 @@ class BoxDomainCoreSuite extends FlatSpec { "BoxDomainCore.remainder" should " - return the remainder of the two Boxs given as input" in { - // IntervalBottom - /*assert(bc.remainder(IntervalBottom, One) === IntervalBottom) - assert(bc.remainder(IntervalBottom, IntervalTop) === IntervalBottom) - assert(bc.remainder(One, IntervalBottom) === IntervalBottom) - assert(bc.remainder(IntervalTop, IntervalBottom) === IntervalBottom) - // IntervalTop - assert(bc.remainder(IntervalTop, MtenTen) === IntervalTop) - assert(bc.remainder(MtenTen, IntervalTop) === IntervalTop) - assert(bc.remainder(IntervalTop, IntervalTop) === IntervalTop) - // Interval(0) - assert(bc.remainder(IntervalTop, Zero) === IntervalBottom) - assert(bc.remainder(Zero, IntervalTop) === Zero) - assert(bc.remainder(Zero, MtenTen) === Zero) - assert(bc.remainder(MtenTen, Zero) === IntervalBottom) - assert(bc.remainder(Zero, Zero) === IntervalBottom) - // Interval - assert(bc.remainder(MtenTen, MtenTen) === zero)*/ + val twoThree = Box.Interval(IntNumber(2), IntNumber(3)) + val MnineNine = Box.Interval(IntNumber(-9), IntNumber(9)) + val zeroTwo = Box.Interval(IntNumber(0), IntNumber(2)) + val MnineMseven = Box.Interval(IntNumber(-9), IntNumber(-7)) + val MeightZero = Box.Interval(IntNumber(-8), IntNumber(0)) + val zeroInf = Box.Interval(IntNumber(0), PositiveInfinity()) + //IntervalBottom + assert(bc.remainder(IntervalBottom, One) === IntervalBottom) + assert(bc.remainder(IntervalBottom, IntervalTop) === IntervalBottom) + assert(bc.remainder(One, IntervalBottom) === IntervalBottom) + assert(bc.remainder(IntervalTop, IntervalBottom) === IntervalBottom) + // IntervalTop + assert(bc.remainder(IntervalTop, MtenTen) === IntervalTop) + assert(bc.remainder(MtenTen, IntervalTop) === IntervalTop) + assert(bc.remainder(IntervalTop, IntervalTop) === IntervalTop) + // Interval(0) + assert(bc.remainder(IntervalTop, Zero) === IntervalBottom) + assert(bc.remainder(Zero, IntervalTop) === Zero) + assert(bc.remainder(Zero, MtenTen) === Zero) + assert(bc.remainder(MtenTen, Zero) === IntervalBottom) + assert(bc.remainder(Zero, Zero) === IntervalBottom) + // Interval + assert(bc.remainder(MtenTen, MtenTen) === MnineNine) + assert(bc.remainder(MtenTen, twoThree) === zeroTwo) + assert(bc.remainder(MtenTen, MnineMseven) === MeightZero) + assert(bc.remainder(MtenTen, oneInf) === zeroInf) } "BoxDomainCore.lub" should From ca3bf3a857d5c2b612e590be44513f5dc7f8ea14 Mon Sep 17 00:00:00 2001 From: Mou95 Date: Wed, 11 Apr 2018 16:16:26 +0200 Subject: [PATCH 89/99] Solved error in linearInequality --- .../domains/numerical/BoxDoubleDomain.scala | 8 ++- .../unich/jandom/targets/slil/WhileStmt.scala | 3 +- .../numerical/box/BoundedBoxDomain.scala | 6 +-- .../numerical/box/BoundedBoxDomainCore.scala | 12 +++-- .../domains/numerical/box/BoxDomain.scala | 16 ++++-- .../domains/numerical/box/BoxDomainCore.scala | 2 +- .../numerical/box/BoxDomainCoreSuite.scala | 52 +++++++++---------- 7 files changed, 57 insertions(+), 42 deletions(-) diff --git a/core/src/main/scala/it/unich/jandom/domains/numerical/BoxDoubleDomain.scala b/core/src/main/scala/it/unich/jandom/domains/numerical/BoxDoubleDomain.scala index c14bc010..8951cc24 100644 --- a/core/src/main/scala/it/unich/jandom/domains/numerical/BoxDoubleDomain.scala +++ b/core/src/main/scala/it/unich/jandom/domains/numerical/BoxDoubleDomain.scala @@ -323,9 +323,13 @@ class BoxDoubleDomain(val overReals: Boolean) extends NumericalDomain { } case 1 => { val posinf = infinities.head - if (homcoeffs(posinf) < 0) + if (homcoeffs(posinf) < 0) { + print("MINORE") + print("LOW = " + low(posinf)) + print("ALTRO = " + ((-dotprod_lo(homcoeffs, lfArgmin, posinf) - known) / homcoeffs(posinf))) + print("LFARGMIN = "+lfArgmin) newlow(posinf) = low(posinf) max ((-dotprod_lo(homcoeffs, lfArgmin, posinf) - known) / homcoeffs(posinf)) - else + } else newhigh(posinf) = high(posinf) min ((-dotprod_hi(homcoeffs, lfArgmin, posinf) - known) / homcoeffs(posinf)) } case _ => diff --git a/core/src/main/scala/it/unich/jandom/targets/slil/WhileStmt.scala b/core/src/main/scala/it/unich/jandom/targets/slil/WhileStmt.scala index cf1e500c..2fc42e8a 100644 --- a/core/src/main/scala/it/unich/jandom/targets/slil/WhileStmt.scala +++ b/core/src/main/scala/it/unich/jandom/targets/slil/WhileStmt.scala @@ -43,7 +43,6 @@ case class WhileStmt(condition: NumericCondition, body: SLILStmt) extends SLILSt var lastBodyResult: NumericalProperty[_] = null override def analyzeStmt(params: Parameters)(input: params.Property, phase: AnalysisPhase, ann: Annotation[ProgramPoint, params.Property]): params.Property = { - import WideningScope._ import NarrowingStrategy._ @@ -116,6 +115,7 @@ case class WhileStmt(condition: NumericCondition, body: SLILStmt) extends SLILSt currentPhase = Descending } + if (currentPhase == Descending) { // Debug params.log("Beginning Descending Chain\n") @@ -144,7 +144,6 @@ case class WhileStmt(condition: NumericCondition, body: SLILStmt) extends SLILSt params.log(s"Final descending invariant: $newinvariant\n") } - // Save current values for later iterations of the loop lastInvariant = invariant lastBodyResult = bodyResult diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomain.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomain.scala index a0004504..1e1cdf5f 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomain.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomain.scala @@ -122,13 +122,13 @@ class BoundedBoxDomain(m : InfInt, n : InfInt) extends BaseNumericalDomain[Box, case 1 => { val posinf = infinities.head if (homcoeffs(posinf) < 0) - newboxes(posinf) = Interval(projectLow(boxes(posinf)) max ((dotprod(homcoeffs, lfArgmin, posinf) - known).inverse() / IntNumber(homcoeffs(posinf))), projectHigh(newboxes(posinf))) + newboxes(posinf) = Interval(projectLow(boxes(posinf)) max ((dotprod(homcoeffs, lfArgmin, posinf).inverse() - known) / IntNumber(homcoeffs(posinf))), projectHigh(newboxes(posinf))) else - newboxes(posinf) = Interval(projectLow(boxes(posinf)), projectHigh(boxes(posinf)) min ((dotprod(homcoeffs, lfArgmin, posinf) - known).inverse() / IntNumber(homcoeffs(posinf)))) + newboxes(posinf) = Interval(projectLow(boxes(posinf)), projectHigh(boxes(posinf)) min ((dotprod(homcoeffs, lfArgmin, posinf).inverse() - known) / IntNumber(homcoeffs(posinf)))) } case _ => } - new Property(newboxes,false) + new Property(newboxes.map(BoundedBoxDomainCore.norm),false) } } diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCore.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCore.scala index a301ce8e..99109685 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCore.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCore.scala @@ -35,7 +35,7 @@ class BoundedBoxDomainCore(bound_m : InfInt, bound_n : InfInt) extends BoxDomain override def sum(x : Box, y : Box) : Box = { val result = super.sum(x,y) - println("sum i bound sono"+ m + " " +n) + //println("sum i bound sono"+ m + " " +n) normalizeBound(result) } @@ -92,7 +92,7 @@ class BoundedBoxDomainCore(bound_m : InfInt, bound_n : InfInt) extends BoxDomain def normalizeBound(x : Box) : Box = { x match { - case Interval(low,high) => + case Interval(low,high) => { if (low == high) return Interval(low,high) if (high < m) @@ -108,8 +108,8 @@ class BoundedBoxDomainCore(bound_m : InfInt, bound_n : InfInt) extends BoxDomain new_low = NegativeInfinity() return check(Interval(new_low,new_high)) - - case _ => x + } + case _ => x } } @@ -132,4 +132,8 @@ object BoundedBoxDomainCore { println("DATA ARE UPDATED " + D.m + " and " + D.n) } + def norm(x : Box) : Box = { + D.normalizeBound(x) + } + } // end of BoundedBoxDomainCore companion object diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala index 54b9b18d..47928e52 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala @@ -106,17 +106,25 @@ class BoxDomain extends BaseNumericalDomain[Box, BoxDomainCore](BoxDomainCore()) infinities.size match { case 0 => { + print("CASE 0") for (i <- homcoeffs.indices) { if (homcoeffs(i) < 0) newboxes(i) = Interval(projectLow(boxes(i)) max (lfArgmin(i) - (lfMin / IntNumber(homcoeffs(i)))), projectHigh(newboxes(i))) if (homcoeffs(i) > 0) newboxes(i) = Interval(projectLow(newboxes(i)), projectHigh(boxes(i)) min (lfArgmin(i) - (lfMin / IntNumber(homcoeffs(i))))) } } case 1 => { + print("CASE 1") val posinf = infinities.head - if (homcoeffs(posinf) < 0) - newboxes(posinf) = Interval(projectLow(boxes(posinf)) max ((dotprod(homcoeffs, lfArgmin, posinf) - known).inverse() / IntNumber(homcoeffs(posinf))), projectHigh(newboxes(posinf))) - else - newboxes(posinf) = Interval(projectLow(boxes(posinf)), projectHigh(boxes(posinf)) min ((dotprod(homcoeffs, lfArgmin, posinf) - known).inverse() / IntNumber(homcoeffs(posinf)))) + if (homcoeffs(posinf) < 0) { + print("MINORE") + print("LOW = " + projectLow(boxes(posinf))) + print("ALTRO = " + ((dotprod(homcoeffs, lfArgmin, posinf).inverse() - known) / IntNumber(homcoeffs(posinf)))) + print("LFARGMIN = "+lfArgmin) + newboxes(posinf) = Interval(projectLow(boxes(posinf)) max ((dotprod(homcoeffs, lfArgmin, posinf).inverse() - known) / IntNumber(homcoeffs(posinf))), projectHigh(newboxes(posinf))) + } else { + print("MAGGIORE") + newboxes(posinf) = Interval(projectLow(boxes(posinf)), projectHigh(boxes(posinf)) min ((dotprod(homcoeffs, lfArgmin, posinf).inverse() - known) / IntNumber(homcoeffs(posinf)))) + } } case _ => } diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala index 4838ad7d..f7e97a07 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala @@ -135,7 +135,7 @@ class BoxDomainCore extends CompleteLatticeOperator[Box] case (_, IntervalTop) => IntervalTop case (Interval (low1, high1), Interval (low2,high2)) => if (low2 >= IntNumber(0)) - return Interval(IntNumber(0),high2 - IntNumber(1)) + return Interval(IntNumber(0), high2 - IntNumber(1)) if (high2 <= IntNumber(0)) return Interval(low2 + IntNumber(1), IntNumber(0)) return Interval(low2 + IntNumber(1), high2 - IntNumber(1)) diff --git a/core/src/test/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCoreSuite.scala b/core/src/test/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCoreSuite.scala index be52210f..b1e61298 100644 --- a/core/src/test/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCoreSuite.scala +++ b/core/src/test/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCoreSuite.scala @@ -134,32 +134,32 @@ class BoxDomainCoreSuite extends FlatSpec { "BoxDomainCore.remainder" should " - return the remainder of the two Boxs given as input" in { - val twoThree = Box.Interval(IntNumber(2), IntNumber(3)) - val MnineNine = Box.Interval(IntNumber(-9), IntNumber(9)) - val zeroTwo = Box.Interval(IntNumber(0), IntNumber(2)) - val MnineMseven = Box.Interval(IntNumber(-9), IntNumber(-7)) - val MeightZero = Box.Interval(IntNumber(-8), IntNumber(0)) - val zeroInf = Box.Interval(IntNumber(0), PositiveInfinity()) - //IntervalBottom - assert(bc.remainder(IntervalBottom, One) === IntervalBottom) - assert(bc.remainder(IntervalBottom, IntervalTop) === IntervalBottom) - assert(bc.remainder(One, IntervalBottom) === IntervalBottom) - assert(bc.remainder(IntervalTop, IntervalBottom) === IntervalBottom) - // IntervalTop - assert(bc.remainder(IntervalTop, MtenTen) === IntervalTop) - assert(bc.remainder(MtenTen, IntervalTop) === IntervalTop) - assert(bc.remainder(IntervalTop, IntervalTop) === IntervalTop) - // Interval(0) - assert(bc.remainder(IntervalTop, Zero) === IntervalBottom) - assert(bc.remainder(Zero, IntervalTop) === Zero) - assert(bc.remainder(Zero, MtenTen) === Zero) - assert(bc.remainder(MtenTen, Zero) === IntervalBottom) - assert(bc.remainder(Zero, Zero) === IntervalBottom) - // Interval - assert(bc.remainder(MtenTen, MtenTen) === MnineNine) - assert(bc.remainder(MtenTen, twoThree) === zeroTwo) - assert(bc.remainder(MtenTen, MnineMseven) === MeightZero) - assert(bc.remainder(MtenTen, oneInf) === zeroInf) + val twoThree = Box.Interval(IntNumber(2), IntNumber(3)) + val MnineNine = Box.Interval(IntNumber(-9), IntNumber(9)) + val zeroTwo = Box.Interval(IntNumber(0), IntNumber(2)) + val MnineMseven = Box.Interval(IntNumber(-9), IntNumber(-7)) + val MeightZero = Box.Interval(IntNumber(-8), IntNumber(0)) + val zeroInf = Box.Interval(IntNumber(0), PositiveInfinity()) + //IntervalBottom + assert(bc.remainder(IntervalBottom, One) === IntervalBottom) + assert(bc.remainder(IntervalBottom, IntervalTop) === IntervalBottom) + assert(bc.remainder(One, IntervalBottom) === IntervalBottom) + assert(bc.remainder(IntervalTop, IntervalBottom) === IntervalBottom) + // IntervalTop + assert(bc.remainder(IntervalTop, MtenTen) === IntervalTop) + assert(bc.remainder(MtenTen, IntervalTop) === IntervalTop) + assert(bc.remainder(IntervalTop, IntervalTop) === IntervalTop) + // Interval(0) + assert(bc.remainder(IntervalTop, Zero) === IntervalBottom) + assert(bc.remainder(Zero, IntervalTop) === Zero) + assert(bc.remainder(Zero, MtenTen) === Zero) + assert(bc.remainder(MtenTen, Zero) === IntervalBottom) + assert(bc.remainder(Zero, Zero) === IntervalBottom) + // Interval + assert(bc.remainder(MtenTen, MtenTen) === MnineNine) + assert(bc.remainder(MtenTen, twoThree) === zeroTwo) + assert(bc.remainder(MtenTen, MnineMseven) === MeightZero) + assert(bc.remainder(MtenTen, oneInf) === zeroInf) } "BoxDomainCore.lub" should From 857581bd1764dcf5f372751c504c3213e7212a46 Mon Sep 17 00:00:00 2001 From: Mou95 Date: Thu, 12 Apr 2018 17:35:00 +0200 Subject: [PATCH 90/99] Fixed m > n in bounded box --- .../numerical/box/BoundedBoxDomainCore.scala | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCore.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCore.scala index 99109685..c47aa2f4 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCore.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCore.scala @@ -95,19 +95,22 @@ class BoundedBoxDomainCore(bound_m : InfInt, bound_n : InfInt) extends BoxDomain case Interval(low,high) => { if (low == high) return Interval(low,high) - if (high < m) - return Interval(NegativeInfinity(),m) - if (low > n) - return Interval(n,PositiveInfinity()) - - var new_low = low - var new_high = high - if (high > n) - new_high = PositiveInfinity() - if (low < m) - new_low = NegativeInfinity() - - return check(Interval(new_low,new_high)) + if (n > m) { + if (high < m) + return Interval(NegativeInfinity(),m) + if (low > n) + return Interval(n,PositiveInfinity()) + + var new_low = low + var new_high = high + if (high > n) + new_high = PositiveInfinity() + if (low < m) + new_low = NegativeInfinity() + + return check(Interval(new_low,new_high)) + } + return IntervalTop } case _ => x From be077d24279faa01532d558ce6ceff442c427fa0 Mon Sep 17 00:00:00 2001 From: BottCode Date: Sat, 14 Apr 2018 11:16:17 +0200 Subject: [PATCH 91/99] delete useless method --- .../numerical/box/BoundedBoxDomainCore.scala | 26 +++++++------------ 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCore.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCore.scala index 99109685..b320662a 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCore.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCore.scala @@ -81,33 +81,27 @@ class BoundedBoxDomainCore(bound_m : InfInt, bound_n : InfInt) extends BoxDomain normalizeBound(result) } - /*def check(x : Interval) : Box = { - x match { - case Interval(NegativeInfinity(), NegativeInfinity()) => Interval(NegativeInfinity(),m) - case Interval(PositiveInfinity(), PositiveInfinity()) => Interval(n, PositiveInfinity()) - case Interval(NegativeInfinity(), PositiveInfinity()) => IntervalTop - case _ => x - } - }*/ - def normalizeBound(x : Box) : Box = { x match { case Interval(low,high) => { if (low == high) return Interval(low,high) + if(n > m){ if (high < m) return Interval(NegativeInfinity(),m) if (low > n) return Interval(n,PositiveInfinity()) - var new_low = low - var new_high = high - if (high > n) - new_high = PositiveInfinity() - if (low < m) - new_low = NegativeInfinity() + var new_low = low + var new_high = high + if (high > n) + new_high = PositiveInfinity() + if (low < m) + new_low = NegativeInfinity() - return check(Interval(new_low,new_high)) + return check(Interval(new_low,new_high)) + } + return IntervalTop } case _ => x From dd1814223b1ad86b10114368eb244e503e1357f0 Mon Sep 17 00:00:00 2001 From: BottCode Date: Sat, 14 Apr 2018 11:36:53 +0200 Subject: [PATCH 92/99] removed some useless print --- .../domains/numerical/BoxDoubleDomain.scala | 8 ++++---- .../it/unich/jandom/ui/NumericalDomains.scala | 2 +- .../it/unich/jandom/ui/gui/ParametersPane.scala | 2 +- .../numerical/box/BoundedBoxDomainCore.scala | 6 +++--- .../jandom/domains/numerical/box/BoxDomain.scala | 16 ++++++++-------- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/core/src/main/scala/it/unich/jandom/domains/numerical/BoxDoubleDomain.scala b/core/src/main/scala/it/unich/jandom/domains/numerical/BoxDoubleDomain.scala index 8951cc24..e3896b14 100644 --- a/core/src/main/scala/it/unich/jandom/domains/numerical/BoxDoubleDomain.scala +++ b/core/src/main/scala/it/unich/jandom/domains/numerical/BoxDoubleDomain.scala @@ -324,10 +324,10 @@ class BoxDoubleDomain(val overReals: Boolean) extends NumericalDomain { case 1 => { val posinf = infinities.head if (homcoeffs(posinf) < 0) { - print("MINORE") - print("LOW = " + low(posinf)) - print("ALTRO = " + ((-dotprod_lo(homcoeffs, lfArgmin, posinf) - known) / homcoeffs(posinf))) - print("LFARGMIN = "+lfArgmin) + // print("MINORE") + // print("LOW = " + low(posinf)) + // print("ALTRO = " + ((-dotprod_lo(homcoeffs, lfArgmin, posinf) - known) / homcoeffs(posinf))) + // print("LFARGMIN = "+lfArgmin) newlow(posinf) = low(posinf) max ((-dotprod_lo(homcoeffs, lfArgmin, posinf) - known) / homcoeffs(posinf)) } else newhigh(posinf) = high(posinf) min ((-dotprod_hi(homcoeffs, lfArgmin, posinf) - known) / homcoeffs(posinf)) diff --git a/core/src/main/scala/it/unich/jandom/ui/NumericalDomains.scala b/core/src/main/scala/it/unich/jandom/ui/NumericalDomains.scala index ab0f7c1e..c9e1b79c 100644 --- a/core/src/main/scala/it/unich/jandom/ui/NumericalDomains.scala +++ b/core/src/main/scala/it/unich/jandom/ui/NumericalDomains.scala @@ -73,7 +73,7 @@ object NumericalDomains extends ParameterEnumeration[NumericalDomain] { def setBound(m: Int,n: Int) = { for (d <- values) { if (d.value.isInstanceOf[BoundedBoxDomain]) { - println("te chiamo qui" + m + " - " + n) + // println("te chiamo qui" + m + " - " + n) d.value.updateData(m,n) } } diff --git a/core/src/main/scala/it/unich/jandom/ui/gui/ParametersPane.scala b/core/src/main/scala/it/unich/jandom/ui/gui/ParametersPane.scala index ee3ff734..c63d5308 100644 --- a/core/src/main/scala/it/unich/jandom/ui/gui/ParametersPane.scala +++ b/core/src/main/scala/it/unich/jandom/ui/gui/ParametersPane.scala @@ -98,7 +98,7 @@ class ParametersPane extends GridBagPanel { val delay = delayModel.getValue().asInstanceOf[Double].toInt val bound_m = parameter_m_model.getValue().asInstanceOf[Double].toInt val bound_n = parameter_n_model.getValue.asInstanceOf[Double].toInt - print("Bound from graphics ",bound_m,bound_n) + // print("Bound from graphics ",bound_m,bound_n) NumericalDomains.setBound(bound_m, bound_n) params.widening = DelayedWidening(DefaultWidening, delay) params.narrowing = DelayedNarrowing(TrivialNarrowing, 2) diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCore.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCore.scala index 4f3caf07..b44cc6f2 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCore.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCore.scala @@ -35,7 +35,7 @@ class BoundedBoxDomainCore(bound_m : InfInt, bound_n : InfInt) extends BoxDomain override def sum(x : Box, y : Box) : Box = { val result = super.sum(x,y) - //println("sum i bound sono"+ m + " " +n) + //// println("sum i bound sono"+ m + " " +n) normalizeBound(result) } @@ -92,7 +92,7 @@ class BoundedBoxDomainCore(bound_m : InfInt, bound_n : InfInt) extends BoxDomain return Interval(NegativeInfinity(),m) if (low > n) return Interval(n,PositiveInfinity()) - + var new_low = low var new_high = high if (high > n) @@ -124,7 +124,7 @@ object BoundedBoxDomainCore { def updateData(x: InfInt, y: InfInt) = { D.m = x D.n = y - println("DATA ARE UPDATED " + D.m + " and " + D.n) + // println("DATA ARE UPDATED " + D.m + " and " + D.n) } def norm(x : Box) : Box = { diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala index 47928e52..17ae40fd 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala @@ -97,7 +97,7 @@ class BoxDomain extends BaseNumericalDomain[Box, BoxDomainCore](BoxDomainCore()) val known = IntNumber(lf.known.toInt) val lfMin = projectLow(linearEvaluation(lf)) val lfArgmin = linearArgmin(lf); - //print(lowresult) + //// print(lowresult) if (lfMin > IntNumber(0)) return bottom else { @@ -106,23 +106,23 @@ class BoxDomain extends BaseNumericalDomain[Box, BoxDomainCore](BoxDomainCore()) infinities.size match { case 0 => { - print("CASE 0") + // print("CASE 0") for (i <- homcoeffs.indices) { if (homcoeffs(i) < 0) newboxes(i) = Interval(projectLow(boxes(i)) max (lfArgmin(i) - (lfMin / IntNumber(homcoeffs(i)))), projectHigh(newboxes(i))) if (homcoeffs(i) > 0) newboxes(i) = Interval(projectLow(newboxes(i)), projectHigh(boxes(i)) min (lfArgmin(i) - (lfMin / IntNumber(homcoeffs(i))))) } } case 1 => { - print("CASE 1") + // print("CASE 1") val posinf = infinities.head if (homcoeffs(posinf) < 0) { - print("MINORE") - print("LOW = " + projectLow(boxes(posinf))) - print("ALTRO = " + ((dotprod(homcoeffs, lfArgmin, posinf).inverse() - known) / IntNumber(homcoeffs(posinf)))) - print("LFARGMIN = "+lfArgmin) + // print("MINORE") + // print("LOW = " + projectLow(boxes(posinf))) + // print("ALTRO = " + ((dotprod(homcoeffs, lfArgmin, posinf).inverse() - known) / IntNumber(homcoeffs(posinf)))) + // print("LFARGMIN = "+lfArgmin) newboxes(posinf) = Interval(projectLow(boxes(posinf)) max ((dotprod(homcoeffs, lfArgmin, posinf).inverse() - known) / IntNumber(homcoeffs(posinf))), projectHigh(newboxes(posinf))) } else { - print("MAGGIORE") + // print("MAGGIORE") newboxes(posinf) = Interval(projectLow(boxes(posinf)), projectHigh(boxes(posinf)) min ((dotprod(homcoeffs, lfArgmin, posinf).inverse() - known) / IntNumber(homcoeffs(posinf)))) } } From 65dca723e813e4d6324b1746b8c3354312b9ba8d Mon Sep 17 00:00:00 2001 From: BottCode Date: Sat, 14 Apr 2018 16:41:34 +0200 Subject: [PATCH 93/99] add a bit of doc --- .../unich/jandom/domains/numerical/BoxDoubleDomain.scala | 4 ---- .../jandom/domains/numerical/box/BoundedBoxDomain.scala | 5 ++--- .../it/unipd/jandom/domains/numerical/box/BoxDomain.scala | 7 +++++-- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/core/src/main/scala/it/unich/jandom/domains/numerical/BoxDoubleDomain.scala b/core/src/main/scala/it/unich/jandom/domains/numerical/BoxDoubleDomain.scala index e3896b14..2df54b16 100644 --- a/core/src/main/scala/it/unich/jandom/domains/numerical/BoxDoubleDomain.scala +++ b/core/src/main/scala/it/unich/jandom/domains/numerical/BoxDoubleDomain.scala @@ -324,10 +324,6 @@ class BoxDoubleDomain(val overReals: Boolean) extends NumericalDomain { case 1 => { val posinf = infinities.head if (homcoeffs(posinf) < 0) { - // print("MINORE") - // print("LOW = " + low(posinf)) - // print("ALTRO = " + ((-dotprod_lo(homcoeffs, lfArgmin, posinf) - known) / homcoeffs(posinf))) - // print("LFARGMIN = "+lfArgmin) newlow(posinf) = low(posinf) max ((-dotprod_lo(homcoeffs, lfArgmin, posinf) - known) / homcoeffs(posinf)) } else newhigh(posinf) = high(posinf) min ((-dotprod_hi(homcoeffs, lfArgmin, posinf) - known) / homcoeffs(posinf)) diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomain.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomain.scala index 1e1cdf5f..77a66ae9 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomain.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomain.scala @@ -1,7 +1,7 @@ /** * Copyright 2018 Mattia Bottaro, Mauro Carlin * - * This file is part of JANDOM: JVM-based Analyzer for Numerical DOMains + * This file is part of JANDOM: JVM-based Analyzer for Numerical Domains * JANDOM is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or @@ -23,8 +23,7 @@ import it.unipd.jandom.domains.numerical.box.Box._ import it.unipd.jandom.domains.numerical.box.BoundedBoxDomainCore._ import it.unipd.jandom.domains.{InfInt, PositiveInfinity, NegativeInfinity, IntNumber} -/** - * +/** TODO * * @author Mattia Bottaro * @author Mauro Carlin diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala index 17ae40fd..e5047184 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala @@ -24,11 +24,14 @@ import it.unipd.jandom.domains.numerical.box.BoxDomainCore._ import it.unipd.jandom.domains.{InfInt, PositiveInfinity, NegativeInfinity, IntNumber} /** - * Box Domain ... @TODO a better explanation is required + * This is the domain of Integer boxes, also known as the interval domain. Bounds are represented by two numbers which type is :InfInt. + * InfInt is a particular ad-hoc type that manages normal Int operation better than :Int type. For Example there's no overflow error, but it's + * replaced by an "infinity" entity just like happens in :Double type. * * @author Mattia Bottaro * @author Mauro Carlin */ + class BoxDomain extends BaseNumericalDomain[Box, BoxDomainCore](BoxDomainCore()) { /** @@ -38,7 +41,7 @@ class BoxDomain extends BaseNumericalDomain[Box, BoxDomainCore](BoxDomainCore()) new Property(boxes, unreachable) /** - * Numerical property that tells whether the variables in a certain point of the CFG are constant or not. + * Numerical property that tells whether the variables in a certain point of the CFG are an integer interval or not. * @param boxes array of the variables' boxes status * @param unreachable tells if a given program point is unreachable */ From d0c5c5938ad778761a79d82af6d4773c79efac88 Mon Sep 17 00:00:00 2001 From: Mou95 Date: Sun, 22 Apr 2018 11:46:16 +0200 Subject: [PATCH 94/99] Added test for BoundedBox --- core/examples/Java/TestBox.class | Bin 720 -> 1261 bytes core/examples/Java/TestBox.java | 64 +++++++++++++++++++++++++++---- 2 files changed, 57 insertions(+), 7 deletions(-) diff --git a/core/examples/Java/TestBox.class b/core/examples/Java/TestBox.class index bcc4358bbe7d5028684a4648a7b1fc11b0810227..0699b743d6e4e6ca285909503b699510864316bc 100644 GIT binary patch delta 592 zcmY+BO)mpc6o%hB)9G}ks<&vhcgjZMW9K`Vsfe#se1!->Ll>1;R)}pkHkN*Yh(*`k zTKEB05`Tl8AVGOMnl?7~+?;dI^WO8GN8`ncKUDAT0gNJLLr20yr-|fM{JhUNJ32iZ z7VzU}J&xDogg~%X9~!*6ToU2R)2k?1h{6C1#LYtE4Twq8Rr2iywlWHC`RA>|qz02` z8v;CsC^`%aBaj$_&5Q}{3%Y1wQZ{%wHt8&O>8^bCl#|b-RY87U!*8Zoh#JZ{=HK6&_yk`A zb9^_?+X8WmD8-QVxgluZFoXyb+t$FI)UgBd^N)Lr2)W(`MEU1c$>0sbO4>9DA;!Gh zRO=-OSf&9hGKDzk)4L9smFU delta 48 zcmaFMd4W~*)W2Q(7#J8#7(}=jm>C4w8HCswgeQuYP2A$n$hPs%7e-D-27aIdCI$fj DNSO;Z diff --git a/core/examples/Java/TestBox.java b/core/examples/Java/TestBox.java index 8cae59ca..4dd40c86 100644 --- a/core/examples/Java/TestBox.java +++ b/core/examples/Java/TestBox.java @@ -36,13 +36,63 @@ public static void BoxNull() { } public static void remainder() { - int x = 10; - int y = 0; - while (x < 15) { - x++; - y++; - } - int w = x % y; + int x = 10; + int y = 0; + while (x < 15) { + x++; + y++; + } + int w = x % y; + } + + public static void test2() { + int x = 7; + while (x >= -10) { + x = x - 2; + } + } + + public static void test4() { + int x = 0; + int y = -20; + int w = x + y; + if (w - x != -5) { + y = y * w; + } else { + w = x % y; + } + } + + public static void test6() { + int x = 0; + int y = 15; + while (x != 5) { + x = x * y; + } + } + + public static void test8() { + int x = -5; + int y = 15; + while (x <= 5) { + y = x * y; + x++; + } + if (x >= 6) { + x = x - 10; + } else { + x = x + 10; + } + } + + public static void test10() { + int x = 0; + int y = 7; + while (x <= 5) { + x++; + } + int w = y % x; + int z = x % y; } } From 2643b0196269d2102c3f5138e72c4485e005b117 Mon Sep 17 00:00:00 2001 From: BottCode Date: Sun, 22 Apr 2018 11:54:55 +0200 Subject: [PATCH 95/99] add other test for BoundedBox --- core/examples/Java/TestBox.class | Bin 720 -> 1235 bytes core/examples/Java/TestBox.java | 46 ++++++++++++++++++++++++++++++- 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/core/examples/Java/TestBox.class b/core/examples/Java/TestBox.class index bcc4358bbe7d5028684a4648a7b1fc11b0810227..c9b30a96434d7a01422900d5e0f15506f884a9a3 100644 GIT binary patch literal 1235 zcmb7@OHUJF6o%ig!*t5DrPESwGhE^Y1fn8B0;UBCMi3)K1tsnrV5G%Tnp%uIH~b10 zE^yI}8&@VS`~m(Cmo7}aEwID;O(# zbv2k8EP-&gP%2bs1(e~D#{w<4_O={>#Jxhv$?flMIF&VfqsX1e{NAhed_hhbxg-!@ zt=gNQ8R0PyD=S6kgA19cDTu*S~9ZdP- zw1B?4w_n+G7ChOQj3V#qj{VY(Aq-6*Dd%HFyR<#FRH{1LlCJr20!H(6Wn;(Ltl}J6 zXoCDjL0xEkM!4$ZC^)L4A0a+)!i4z@dz*5udlzJAj(Z`FX+zIMvgTXF4um*>TXTPz z@3|lHZkoIcDEv!7m3v{tD3>BB#*+v_f1wHy<4HV7qs-e1PluF@p=V9&sgZbxIN_F> z&(_@U%8Y4k8U2UQOe;Sl^K7UMd75opC8%YPnB+5sE~L?e4wl`CL9V2742q|mJVIPn z))uJeeD$=a{x7XYWhP@SYW4DVA65I&jsd?iQAfKFlAQ?H19VLqtSFhLy*eSlc|I>N z*a(8x{X}|bv63~7#34)X`x=!q*htm)`LP$hOO9ixfpO$QC(4wXh z&1Y)v&$GNK22PWAgY{-k^5W#R|37b*yqo0BkvD&qmkxM~43lOjQwlA$Oj)nA^G`Fs zP8tZ@rj-kvEwWMXka_o%g*ub$2%x(}%61)8GHRCnB5ky2qp6nPKyUQyH_NEY-u>DX uYIN%|FXw3S3crl|6nVgIc}Vywd+HG`;)y4$L#ZRoZt9SqYA3})=sE^rOr|sd delta 343 zcmY+9OKJi^7=-KZPS5CMG`<2MzJfTYBW4wFA!L=U*U3GGIYoA6C5U(cSAr+-1YRJD z_0J3hyXj|re|7b-d~nbE>t+Yw1FZlSbsr5M&7}LCY&-S=E;+w_8VcGx2zbTW_;*r1F?Qlm5tD{PZN# zwh|$1M%4dM(HFvk8kvaH()7P_AGx9_qC_PpSlee7jce`VKWqTQs{!XB;c8*GGVwwK f_p%R-7 Date: Tue, 24 Apr 2018 13:15:15 +0200 Subject: [PATCH 96/99] Eliminated useless code --- .../jandom/targets/NumericExpression.scala | 5 +- .../unich/jandom/targets/slil/WhileStmt.scala | 1 + .../it/unipd/jandom/domains/InfInt.scala | 628 ++++++++---------- .../numerical/box/BoundedBoxDomain.scala | 26 +- .../numerical/box/BoundedBoxDomainCore.scala | 8 +- .../jandom/domains/numerical/box/Box.scala | 2 +- .../domains/numerical/box/BoxDomain.scala | 18 +- .../domains/numerical/box/BoxDomainCore.scala | 4 +- 8 files changed, 310 insertions(+), 382 deletions(-) diff --git a/core/src/main/scala/it/unich/jandom/targets/NumericExpression.scala b/core/src/main/scala/it/unich/jandom/targets/NumericExpression.scala index 64a01116..774a17af 100644 --- a/core/src/main/scala/it/unich/jandom/targets/NumericExpression.scala +++ b/core/src/main/scala/it/unich/jandom/targets/NumericExpression.scala @@ -150,9 +150,10 @@ object NumericExpression { override def lteZero[Property <: NumericalProperty[Property]](input: Property): Property = input.linearInequality(lf) - override def ltZero[Property <: NumericalProperty[Property]](input: Property): Property = + override def ltZero[Property <: NumericalProperty[Property]](input: Property): Property = { + println("INPUT"+input) input.linearInequality(lf) - + } override def neqZero[Property <: NumericalProperty[Property]](input: Property): Property = input.linearDisequality(lf) diff --git a/core/src/main/scala/it/unich/jandom/targets/slil/WhileStmt.scala b/core/src/main/scala/it/unich/jandom/targets/slil/WhileStmt.scala index 2fc42e8a..e62a7ce8 100644 --- a/core/src/main/scala/it/unich/jandom/targets/slil/WhileStmt.scala +++ b/core/src/main/scala/it/unich/jandom/targets/slil/WhileStmt.scala @@ -88,6 +88,7 @@ case class WhileStmt(condition: NumericCondition, body: SLILStmt) extends SLILSt invariant = newinvariant params.wideningScope match { case Random => + print("CONDITION ANALYZE" + condition.analyze(invariant)) bodyResult = body.analyzeStmt(params)(condition.analyze(invariant), currentPhase, ann) newinvariant = widening(invariant, bodyResult) case BackEdges => diff --git a/core/src/main/scala/it/unipd/jandom/domains/InfInt.scala b/core/src/main/scala/it/unipd/jandom/domains/InfInt.scala index 61c118bb..b25669f9 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/InfInt.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/InfInt.scala @@ -27,399 +27,335 @@ package it.unipd.jandom.domains trait InfInt { - def isInfinity : Boolean - - /** - * The following method are abstract. - * The real implementation can be found in each sub-case class extending this trait - */ - - /** - * Perform the mathematical sum between the object that invoke this method and the param - * @param x is the adding - * @return the mathematical sum between the object that invoke this method and x. - */ - def +(x: InfInt): InfInt - - /** - * Perform the mathematical division between the object that invoke this method and the param - * @param x is the divider - * @return the mathematical division between the object that invoke this method and x. - */ - def /(x: InfInt): InfInt - - def *(x: InfInt): InfInt - def >(x: InfInt): Boolean - def >=(x: InfInt): Boolean - - /** - * @param x is the second argument of max operator - * @return the max element between the object that invoke this method and x. - */ - def max(x: InfInt): InfInt - - def min(x: InfInt): InfInt - def ==(x: InfInt): Boolean - - /** - * @return the inverse of the object that invoke this method. - */ - def inverse(): InfInt = { - this match { - case PositiveInfinity() => NegativeInfinity() - case NegativeInfinity() => PositiveInfinity() - case IntNumber(x) => IntNumber(-x) - //case _ => Undetermined() - } - } - - - /** - * Perform the mathematical difference between the object that invoke this method and the param - * @param x is the substracting - * @return the mathematical difference between the object that invoke this method and x. - */ - def -(x: InfInt): InfInt = { - this + x.inverse() - } - - /** - * Checks if two InfInt are not equal - * @param x is the second argument of != operator - * @return true if and only if the object that invoke this method is not equal to x. - */ - def !=(x: InfInt): Boolean = { - !(this == x) - } - - /** - * Checks if the object that invoke this method is less than the argument - * @param x is the second argument of < operator - * @return true if and only if the object that invoke this method is less than x. - */ - def <(x: InfInt): Boolean = { - !(this >= x) - } - - // similar to < - def <=(x: InfInt): Boolean = { - !(this > x) - } + def isInfinity : Boolean + + /** + * The following method are abstract. + * The real implementation can be found in each sub-case class extending this trait + */ + + /** + * Perform the mathematical sum between the object that invoke this method and the param + * @param x is the adding + * @return the mathematical sum between the object that invoke this method and x. + */ + def +(x: InfInt): InfInt + + /** + * Perform the mathematical division between the object that invoke this method and the param + * @param x is the divider + * @return the mathematical division between the object that invoke this method and x. + */ + def /(x: InfInt): InfInt + + def *(x: InfInt): InfInt + def >(x: InfInt): Boolean + def >=(x: InfInt): Boolean + + /** + * @param x is the second argument of max operator + * @return the max element between the object that invoke this method and x. + */ + def max(x: InfInt): InfInt + + def min(x: InfInt): InfInt + def ==(x: InfInt): Boolean + + /** + * @return the inverse of the object that invoke this method. + */ + def inverse(): InfInt = { + this match { + case PositiveInfinity() => NegativeInfinity() + case NegativeInfinity() => PositiveInfinity() + case IntNumber(x) => IntNumber(-x) + } + } + + + /** + * Perform the mathematical difference between the object that invoke this method and the param + * @param x is the substracting + * @return the mathematical difference between the object that invoke this method and x. + */ + def -(x: InfInt): InfInt = { + this + x.inverse() + } + + /** + * Checks if two InfInt are not equal + * @param x is the second argument of != operator + * @return true if and only if the object that invoke this method is not equal to x. + */ + def !=(x: InfInt): Boolean = { + !(this == x) + } + + /** + * Checks if the object that invoke this method is less than the argument + * @param x is the second argument of < operator + * @return true if and only if the object that invoke this method is less than x. + */ + def <(x: InfInt): Boolean = { + !(this >= x) + } + + // similar to < + def <=(x: InfInt): Boolean = { + !(this > x) + } } case class IntNumber(n: Int) extends InfInt { - def isInfinity = false - - def +(x: InfInt): InfInt = { - x match { - case NegativeInfinity() => NegativeInfinity() - case PositiveInfinity() => PositiveInfinity() - // // case Undetermined() => Undetermined() - case IntNumber(m) => safeAdd(n,m) - } - } - - def *(x: InfInt): InfInt = { - if(n == 0) return IntNumber(0) - x match { - case IntNumber(m) => safeMul(n,m) - // // case Undetermined() => Undetermined() - case _ => - if(n > 0) return x - return x.inverse() - } - } - - def >(x: InfInt): Boolean = { - x match { - case PositiveInfinity() => false - case IntNumber(m) => n > m - case _ => true // TODO - - } - } - - def >=(x: InfInt): Boolean = { - x match { - case IntNumber(m) => n >= m - case PositiveInfinity() => false - case _ => true - } - } - - def /(x: InfInt): InfInt = { - x match { - case IntNumber(m) => IntNumber(n / m) - // // case Undetermined() => Undetermined() - case _ => IntNumber(0) - } - } - - def ==(x: InfInt): Boolean = { - x match { - case IntNumber(x) => x == n - case _ => false - } - } - - def max(x: InfInt): InfInt = { - x match { - case IntNumber(m) => IntNumber(n max m) - case PositiveInfinity() => PositiveInfinity() - case NegativeInfinity() => IntNumber(n) - //case _ => Undetermined() - } - } - - def min(x: InfInt): InfInt = { - x match { - case IntNumber(m) => IntNumber(n min m) - case PositiveInfinity() => IntNumber(n) - case NegativeInfinity() => NegativeInfinity() - //case _ => Undetermined() - } - } - - /** - * Perform a "safe add", that is a sum that will never do an overflow. - * @param x is the adding - * @return the safe add between the object that invoke this method and x. If an overflow is detected, an Infinity is returned. - */ - def safeAdd(left: Int, right: Int): InfInt = { - // if right + left > Int.MaxValue => Overflow - if (right > 0 && left > Int.MaxValue - right) - return PositiveInfinity() - - if (right < 0 && left < Int.MinValue - right) - return NegativeInfinity() - - return IntNumber(left + right) - } - - /** - * Perform a "safe multiplication", that is a product that will never do an overflow. - * @param x is the adding - * @return the safe prduct between the object that invoke this method and x. If an overflow is detected, an Infinity is returned. - */ - def safeMul(left: Int, right: Int): InfInt = { // TODO - if (right > 0) { - if (left > Int.MaxValue / right) - return PositiveInfinity() - if (left < Int.MinValue / right) - return NegativeInfinity() - } - if (right < -1) { - if (left > Int.MinValue / right) - return NegativeInfinity() - if (left < Int.MaxValue / right) - return PositiveInfinity() - } - if (right == -1) { - if (left == Int.MinValue) - return PositiveInfinity() - if (left == Int.MaxValue) - return NegativeInfinity() - } - - return IntNumber(left * right) - } - - override def toString : String = n.toString + def isInfinity = false + + def +(x: InfInt): InfInt = { + x match { + case NegativeInfinity() => NegativeInfinity() + case PositiveInfinity() => PositiveInfinity() + case IntNumber(m) => safeAdd(n,m) + } + } + + def *(x: InfInt): InfInt = { + if (n == 0) return IntNumber(0) + x match { + case IntNumber(m) => safeMul(n,m) + case _ => + if (n > 0) + return x + return x.inverse() + } + } + + def >(x: InfInt): Boolean = { + x match { + case PositiveInfinity() => false + case IntNumber(m) => n > m + case _ => true + } + } + + def >=(x: InfInt): Boolean = { + x match { + case IntNumber(m) => n >= m + case PositiveInfinity() => false + case _ => true + } + } + + def /(x: InfInt): InfInt = { + x match { + case IntNumber(m) => IntNumber(n / m) + case _ => IntNumber(0) + } + } + + def ==(x: InfInt): Boolean = { + x match { + case IntNumber(x) => x == n + case _ => false + } + } + + def max(x: InfInt): InfInt = { + x match { + case IntNumber(m) => IntNumber(n max m) + case PositiveInfinity() => PositiveInfinity() + case NegativeInfinity() => IntNumber(n) + } + } + + def min(x: InfInt): InfInt = { + x match { + case IntNumber(m) => IntNumber(n min m) + case PositiveInfinity() => IntNumber(n) + case NegativeInfinity() => NegativeInfinity() + } + } + + /** + * Perform a "safe add", that is a sum that will never do an overflow. + * @param x is the adding + * @return the safe add between the object that invoke this method and x. If an overflow is detected, an Infinity is returned. + */ + def safeAdd(left: Int, right: Int): InfInt = { + if (right > 0 && left > Int.MaxValue - right) + return PositiveInfinity() + + if (right < 0 && left < Int.MinValue - right) + return NegativeInfinity() + + return IntNumber(left + right) + } + + /** + * Perform a "safe multiplication", that is a product that will never do an overflow. + * @param x is the adding + * @return the safe prduct between the object that invoke this method and x. If an overflow is detected, an Infinity is returned. + */ + def safeMul(left: Int, right: Int): InfInt = { // TODO + if (right > 0) { + if (left > Int.MaxValue / right) + return PositiveInfinity() + if (left < Int.MinValue / right) + return NegativeInfinity() + } + if (right < -1) { + if (left > Int.MinValue / right) + return NegativeInfinity() + if (left < Int.MaxValue / right) + return PositiveInfinity() + } + if (right == -1) { + if (left == Int.MinValue) + return PositiveInfinity() + if (left == Int.MaxValue) + return NegativeInfinity() + } + return IntNumber(left * right) + } + + override def toString : String = n.toString } case class NegativeInfinity() extends InfInt { - def isInfinity = true + def isInfinity = true - def +(x: InfInt): InfInt = { - x match { - case _ => NegativeInfinity() - /*case PositiveInfinity() => Undetermined() - // // case Undetermined() => Undetermined() - case _ => NegativeInfinity()*/ - } + def +(x: InfInt): InfInt = { + x match { + case _ => NegativeInfinity() } + } - def *(x: InfInt): InfInt = { - x match { - case IntNumber(m) => - if (m > 0) - return NegativeInfinity() - if (m < 0) - return PositiveInfinity() - return IntNumber(0) - // // case Undetermined() => Undetermined() - case PositiveInfinity() => NegativeInfinity() - case NegativeInfinity() => PositiveInfinity() - } - + def *(x: InfInt): InfInt = { + x match { + case IntNumber(m) => + if (m > 0) + return NegativeInfinity() + if (m < 0) + return PositiveInfinity() + return IntNumber(0) + case PositiveInfinity() => NegativeInfinity() + case NegativeInfinity() => PositiveInfinity() } + } - def >(x: InfInt): Boolean = { - x match { - case NegativeInfinity() => false - // // case Undetermined() => false - case _ => false - } + def >(x: InfInt): Boolean = { + x match { + case NegativeInfinity() => false + case _ => false } + } - def >=(x: InfInt): Boolean = { - x match { - case NegativeInfinity() => true - case _ => false - } + def >=(x: InfInt): Boolean = { + x match { + case NegativeInfinity() => true + case _ => false } + } - def /(x: InfInt): InfInt = { - x match { - case IntNumber(x) => - if(x < 0) // TODO THORW /0 - - return PositiveInfinity() - return NegativeInfinity() - // // case Undetermined() => Undetermined() - case _ => IntNumber(0) // Inf / Inf = Inf * (1 / Inf) = Inf * 0 - } + def /(x: InfInt): InfInt = { + x match { + case IntNumber(x) => + if(x < 0) + return PositiveInfinity() + return NegativeInfinity() + case _ => IntNumber(0) // Inf / Inf = Inf * (1 / Inf) = Inf * 0 } + } - def ==(x: InfInt): Boolean = { - x match { - case NegativeInfinity() => true - case _ => false - } + def ==(x: InfInt): Boolean = { + x match { + case NegativeInfinity() => true + case _ => false } + } - def max(x: InfInt): InfInt = { - x match { - case IntNumber(m) => IntNumber(m) - case _ => x - } + def max(x: InfInt): InfInt = { + x match { + case IntNumber(m) => IntNumber(m) + case _ => x } + } - def min(x: InfInt): InfInt = { - x match { - // // case Undetermined() => Undetermined() - case _ => NegativeInfinity() - } + def min(x: InfInt): InfInt = { + x match { + case _ => NegativeInfinity() } + } - override def toString : String = "-\u221E" + override def toString : String = "-\u221E" } case class PositiveInfinity() extends InfInt { - def isInfinity = true - - def +(x: InfInt): InfInt = { - x match { - /*case NegativeInfinity() => Undetermined() - // // case Undetermined() => Undetermined()*/ - case _ => PositiveInfinity() - } - } - - def *(x: InfInt): InfInt = { - x match { - case IntNumber(x) => - if (x > 0) - return PositiveInfinity() - if (x < 0) - return NegativeInfinity() - return IntNumber(0) - case _ => x - } - } - - def >(x: InfInt): Boolean = { - x match { - case NegativeInfinity() => true - // // case Undetermined() => true // todo think - case _ => false - } - } - - def >=(x: InfInt): Boolean = { - x match { - case _ => true - } - } - - def ==(x: InfInt): Boolean = { - x match { - case PositiveInfinity() => true - case _ => false - } - } - - def /(x: InfInt): InfInt = { - x match { - case IntNumber(m) => - if(m < 0) - return NegativeInfinity() - return PositiveInfinity() // TODO EXCEPTION /0 - // // case Undetermined() => Undetermined() - case _ => IntNumber(0) // Inf / Inf = Inf * (1 / Inf) = Inf * 0 - } - } - - def max(x: InfInt): InfInt = { - x match { - // // case Undetermined() => Undetermined() - case _ => PositiveInfinity() - } - } + def isInfinity = true - def min(x: InfInt): InfInt = { - x match { - // // case Undetermined() => Undetermined() - case _ => x - } + def +(x: InfInt): InfInt = { + x match { + case _ => PositiveInfinity() } + } - override def toString : String = "+\u221E" - -} - -// case infinity - infinity -/* -case class Undetermined() extends InfInt { - - def isInfinity = false - - def +(x: InfInt): InfInt = { - return Undetermined() + def *(x: InfInt): InfInt = { + x match { + case IntNumber(x) => + if (x > 0) + return PositiveInfinity() + if (x < 0) + return NegativeInfinity() + return IntNumber(0) + case _ => x } + } - def *(x: InfInt): InfInt = { - return Undetermined() + def >(x: InfInt): Boolean = { + x match { + case NegativeInfinity() => true + case _ => false } + } - def >(x:InfInt): Boolean = { - return false + def >=(x: InfInt): Boolean = { + x match { + case _ => true } + } - def >=(x: InfInt): Boolean = { - return false + def ==(x: InfInt): Boolean = { + x match { + case PositiveInfinity() => true + case _ => false } + } - def ==(x: InfInt): Boolean = { - return false + def /(x: InfInt): InfInt = { + x match { + case IntNumber(m) => + if(m < 0) + return NegativeInfinity() + return PositiveInfinity() + case _ => IntNumber(0) // Inf / Inf = Inf * (1 / Inf) = Inf * 0 } + } - def /(x: InfInt): InfInt = { - return Undetermined() + def max(x: InfInt): InfInt = { + x match { + case _ => PositiveInfinity() } + } - def max(x: InfInt): InfInt = { - return Undetermined(); + def min(x: InfInt): InfInt = { + x match { + case _ => x } + } - def min(x: InfInt): InfInt = { - return Undetermined() - } + override def toString : String = "+\u221E" } -*/ diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomain.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomain.scala index 77a66ae9..14b40c37 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomain.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomain.scala @@ -23,7 +23,7 @@ import it.unipd.jandom.domains.numerical.box.Box._ import it.unipd.jandom.domains.numerical.box.BoundedBoxDomainCore._ import it.unipd.jandom.domains.{InfInt, PositiveInfinity, NegativeInfinity, IntNumber} -/** TODO +/** * * @author Mattia Bottaro * @author Mauro Carlin @@ -40,20 +40,19 @@ class BoundedBoxDomain(m : InfInt, n : InfInt) extends BaseNumericalDomain[Box, * @inheritdoc */ override def createProperty(boxes: Array[Box], unreachable: Boolean): Property = { - //boxes.map(normalizeBound) new Property(boxes, unreachable) } /** - * Numerical property that tells whether the variables in a certain point of the CFG are constant or not. + * * @param boxes array of the variables' boxes status * @param unreachable tells if a given program point is unreachable */ class Property (boxes : Array[Box], unreachable: Boolean) extends BaseProperty(boxes, unreachable) { /** - * @param x is an Interval - * @return the lower bound. + * @param box is an Interval + * @return the lower bound of the interval. */ private def projectLow (box : Box) : InfInt = { @@ -66,7 +65,7 @@ class BoundedBoxDomain(m : InfInt, n : InfInt) extends BaseNumericalDomain[Box, /** - * @param x is an Interval + * @param box is an Interval * @return the upper bound. */ private def projectHigh (box : Box) : InfInt = { @@ -79,7 +78,7 @@ class BoundedBoxDomain(m : InfInt, n : InfInt) extends BaseNumericalDomain[Box, } def apply(boxes: Array[Box], unreachable: Boolean) : Property = new Property(boxes, unreachable) - // x != 0 + /** * @inheritdoc */ @@ -104,7 +103,6 @@ class BoundedBoxDomain(m : InfInt, n : InfInt) extends BaseNumericalDomain[Box, val known = IntNumber(lf.known.toInt) val lfMin = projectLow(linearEvaluation(lf)) val lfArgmin = linearArgmin(lf); - //print(lowresult) if (lfMin > IntNumber(0)) return bottom else { @@ -112,6 +110,7 @@ class BoundedBoxDomain(m : InfInt, n : InfInt) extends BaseNumericalDomain[Box, val infinities = (homcoeffs.indices) filter { i => lfArgmin(i).isInfinity && homcoeffs(i) != 0 } infinities.size match { + case 0 => { for (i <- homcoeffs.indices) { if (homcoeffs(i) < 0) newboxes(i) = Interval(projectLow(boxes(i)) max (lfArgmin(i) - (lfMin / IntNumber(homcoeffs(i)))), projectHigh(newboxes(i))) @@ -120,14 +119,15 @@ class BoundedBoxDomain(m : InfInt, n : InfInt) extends BaseNumericalDomain[Box, } case 1 => { val posinf = infinities.head - if (homcoeffs(posinf) < 0) - newboxes(posinf) = Interval(projectLow(boxes(posinf)) max ((dotprod(homcoeffs, lfArgmin, posinf).inverse() - known) / IntNumber(homcoeffs(posinf))), projectHigh(newboxes(posinf))) - else - newboxes(posinf) = Interval(projectLow(boxes(posinf)), projectHigh(boxes(posinf)) min ((dotprod(homcoeffs, lfArgmin, posinf).inverse() - known) / IntNumber(homcoeffs(posinf)))) + if (homcoeffs(posinf) < 0) { + newboxes(posinf) = Interval(projectLow(boxes(posinf)) max ((dotprod(homcoeffs, lfArgmin, posinf).inverse() - known) / IntNumber(homcoeffs(posinf))), projectHigh(newboxes(posinf))) + } else { + newboxes(posinf) = Interval(projectLow(boxes(posinf)), projectHigh(boxes(posinf)) min ((dotprod(homcoeffs, lfArgmin, posinf).inverse() - known) / IntNumber(homcoeffs(posinf)))) + } } case _ => } - new Property(newboxes.map(BoundedBoxDomainCore.norm),false) + new Property(newboxes,false) } } diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCore.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCore.scala index b44cc6f2..b334f446 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCore.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCore.scala @@ -35,7 +35,6 @@ class BoundedBoxDomainCore(bound_m : InfInt, bound_n : InfInt) extends BoxDomain override def sum(x : Box, y : Box) : Box = { val result = super.sum(x,y) - //// println("sum i bound sono"+ m + " " +n) normalizeBound(result) } @@ -47,6 +46,9 @@ class BoundedBoxDomainCore(bound_m : InfInt, bound_n : InfInt) extends BoxDomain normalizeBound(result) } + /** + * @inheritdoc + */ override def mult(x : Box, y : Box) : Box = { val result = super.mult(x,y) normalizeBound(result) @@ -60,6 +62,9 @@ class BoundedBoxDomainCore(bound_m : InfInt, bound_n : InfInt) extends BoxDomain normalizeBound(result) } + /** + * @inheritdoc + */ override def remainder(x : Box, y : Box) : Box = { val result = super.remainder(x,y) normalizeBound(result) @@ -124,7 +129,6 @@ object BoundedBoxDomainCore { def updateData(x: InfInt, y: InfInt) = { D.m = x D.n = y - // println("DATA ARE UPDATED " + D.m + " and " + D.n) } def norm(x : Box) : Box = { diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/Box.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/Box.scala index 3cd86131..b77f10a3 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/Box.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/Box.scala @@ -19,7 +19,7 @@ package it.unipd.jandom.domains.numerical.box import it.unipd.jandom.domains.InfInt /** - * The elements of the constant domain. + * The elements of the Interval domain. * It is a flat domain composed of Interval, top and bottom. * This domain is useful for the Interval propagation analysis. * diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala index e5047184..5d80295e 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala @@ -48,11 +48,10 @@ class BoxDomain extends BaseNumericalDomain[Box, BoxDomainCore](BoxDomainCore()) class Property (boxes : Array[Box], unreachable: Boolean) extends BaseProperty(boxes, unreachable) { /** - * @param x is an Interval + * @param box is an Interval * @return the lower bound. */ private def projectLow (box : Box) : InfInt = { - box match { case IntervalBottom => PositiveInfinity() case IntervalTop => NegativeInfinity() @@ -62,11 +61,10 @@ class BoxDomain extends BaseNumericalDomain[Box, BoxDomainCore](BoxDomainCore()) /** - * @param x is an Interval + * @param box is an Interval * @return the upper bound. */ private def projectHigh (box : Box) : InfInt = { - box match { case IntervalBottom => NegativeInfinity() case IntervalTop => PositiveInfinity() @@ -75,7 +73,7 @@ class BoxDomain extends BaseNumericalDomain[Box, BoxDomainCore](BoxDomainCore()) } def apply(boxes: Array[Box], unreachable: Boolean) : Property = new Property(boxes, unreachable) - // x != 0 + /** * @inheritdoc */ @@ -100,7 +98,6 @@ class BoxDomain extends BaseNumericalDomain[Box, BoxDomainCore](BoxDomainCore()) val known = IntNumber(lf.known.toInt) val lfMin = projectLow(linearEvaluation(lf)) val lfArgmin = linearArgmin(lf); - //// print(lowresult) if (lfMin > IntNumber(0)) return bottom else { @@ -109,23 +106,16 @@ class BoxDomain extends BaseNumericalDomain[Box, BoxDomainCore](BoxDomainCore()) infinities.size match { case 0 => { - // print("CASE 0") for (i <- homcoeffs.indices) { if (homcoeffs(i) < 0) newboxes(i) = Interval(projectLow(boxes(i)) max (lfArgmin(i) - (lfMin / IntNumber(homcoeffs(i)))), projectHigh(newboxes(i))) if (homcoeffs(i) > 0) newboxes(i) = Interval(projectLow(newboxes(i)), projectHigh(boxes(i)) min (lfArgmin(i) - (lfMin / IntNumber(homcoeffs(i))))) } } case 1 => { - // print("CASE 1") val posinf = infinities.head if (homcoeffs(posinf) < 0) { - // print("MINORE") - // print("LOW = " + projectLow(boxes(posinf))) - // print("ALTRO = " + ((dotprod(homcoeffs, lfArgmin, posinf).inverse() - known) / IntNumber(homcoeffs(posinf)))) - // print("LFARGMIN = "+lfArgmin) newboxes(posinf) = Interval(projectLow(boxes(posinf)) max ((dotprod(homcoeffs, lfArgmin, posinf).inverse() - known) / IntNumber(homcoeffs(posinf))), projectHigh(newboxes(posinf))) } else { - // print("MAGGIORE") newboxes(posinf) = Interval(projectLow(boxes(posinf)), projectHigh(boxes(posinf)) min ((dotprod(homcoeffs, lfArgmin, posinf).inverse() - known) / IntNumber(homcoeffs(posinf)))) } } @@ -163,7 +153,6 @@ class BoxDomain extends BaseNumericalDomain[Box, BoxDomainCore](BoxDomainCore()) case (IntervalTop, _) => IntervalTop case (_ , IntervalTop) => IntervalTop case (Interval(low1, high1), Interval(low2,high2)) => - // TODO var newhigh = high1 var newlow = low1 @@ -196,7 +185,6 @@ class BoxDomain extends BaseNumericalDomain[Box, BoxDomainCore](BoxDomainCore()) case (IntervalTop, _) => y case (_ , IntervalTop) => x case (Interval(low1, high1), Interval(low2,high2)) => - // TODO var newlow = low1 var newhigh = high1 if (low1 == NegativeInfinity()) newlow = low2 diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala index f7e97a07..1b22da68 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala @@ -56,7 +56,7 @@ class BoxDomainCore extends CompleteLatticeOperator[Box] x match { case IntervalBottom => IntervalBottom case IntervalTop => IntervalTop - case Interval(low,high) => Interval(high.inverse(),low.inverse()) // TODO, bruttino + case Interval(low,high) => Interval(high.inverse(),low.inverse()) } } @@ -81,8 +81,6 @@ class BoxDomainCore extends CompleteLatticeOperator[Box] def check(x : Interval) : Box = { x match { - /*case Interval(Undetermined(), _) => IntervalTop - case Interval(_, Undetermined()) => IntervalTop*/ case Interval(NegativeInfinity(), NegativeInfinity()) => Interval(NegativeInfinity(),IntNumber(Int.MinValue)) case Interval(PositiveInfinity(), PositiveInfinity()) => Interval(IntNumber(Int.MaxValue), PositiveInfinity()) case Interval(NegativeInfinity(), PositiveInfinity()) => IntervalTop From 94142a4d6e38e5ac5922766f2dc3552948e448b8 Mon Sep 17 00:00:00 2001 From: Mou95 Date: Wed, 25 Apr 2018 18:25:25 +0200 Subject: [PATCH 97/99] Added documentation of methods --- .../it/unipd/jandom/domains/InfInt.scala | 29 ++++++++- .../numerical/box/BoundedBoxDomainCore.scala | 35 +++++++---- .../jandom/domains/numerical/box/Box.scala | 1 - .../domains/numerical/box/BoxDomain.scala | 18 +++++- .../domains/numerical/box/BoxDomainCore.scala | 59 +++++++++++-------- 5 files changed, 100 insertions(+), 42 deletions(-) diff --git a/core/src/main/scala/it/unipd/jandom/domains/InfInt.scala b/core/src/main/scala/it/unipd/jandom/domains/InfInt.scala index b25669f9..8f13dc48 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/InfInt.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/InfInt.scala @@ -48,8 +48,23 @@ trait InfInt { */ def /(x: InfInt): InfInt + /** + * Perform the mathematical multiplication between the object that invoke this method and the param + * @param x is the factor + * @return the mathematical multiplication between the object that invoke this method and x. + */ def *(x: InfInt): InfInt + + /** + * @param x is the element to compare + * @return true if the object that invoke this method is greater then x, false otherwise. + */ def >(x: InfInt): Boolean + + /** + * @param x is the element to compare + * @return true if the object that invoke this method is greater or equal then x, false otherwise. + */ def >=(x: InfInt): Boolean /** @@ -58,7 +73,16 @@ trait InfInt { */ def max(x: InfInt): InfInt + /** + * @param x is the second argument of min operator + * @return the min element between the object that invoke this method and x. + */ def min(x: InfInt): InfInt + + /** + * @param x is the element to compare + * @return true if the object that invoke this method is equal to x, false otherwise. + */ def ==(x: InfInt): Boolean /** @@ -100,7 +124,10 @@ trait InfInt { !(this >= x) } - // similar to < + /** + * @param x is the element to compare + * @return true if the object that invoke this method is smaller or equal then x, false otherwise. + */ def <=(x: InfInt): Boolean = { !(this > x) } diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCore.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCore.scala index b334f446..70f8b79b 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCore.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomainCore.scala @@ -33,59 +33,70 @@ class BoundedBoxDomainCore(bound_m : InfInt, bound_n : InfInt) extends BoxDomain var m: InfInt = bound_m var n: InfInt = bound_n + /** + * @inheritdoc + */ override def sum(x : Box, y : Box) : Box = { val result = super.sum(x,y) normalizeBound(result) } /** - * @inheritdoc - */ + * @inheritdoc + */ override def inverse(x : Box) : Box = { val result = super.inverse(x) normalizeBound(result) } /** - * @inheritdoc - */ + * @inheritdoc + */ override def mult(x : Box, y : Box) : Box = { val result = super.mult(x,y) normalizeBound(result) } /** - * @inheritdoc - */ + * @inheritdoc + */ override def division(x : Box, y : Box) : Box = { val result = super.division(x,y) normalizeBound(result) } /** - * @inheritdoc - */ + * @inheritdoc + */ override def remainder(x : Box, y : Box) : Box = { val result = super.remainder(x,y) normalizeBound(result) } /** - * @inheritdoc - */ + * @inheritdoc + */ override def lub(x : Box, y : Box) : Box = { val result = super.lub(x,y) normalizeBound(result) } /** - * @inheritdoc - */ + * @inheritdoc + */ override def glb(x : Box, y : Box) : Box = { val result = super.glb(x,y) normalizeBound(result) } + /** + * Normalize an interval in order to respect the bound m and n. + * If m >= n the domain become the Constant domain. + * If m is -Inf and n +Inf it become the Interval domain. + * + * @param x an Interval + * @return the interval bounded with m and n + */ def normalizeBound(x : Box) : Box = { x match { case Interval(low,high) => { diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/Box.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/Box.scala index b77f10a3..294d47d6 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/Box.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/Box.scala @@ -20,7 +20,6 @@ import it.unipd.jandom.domains.InfInt /** * The elements of the Interval domain. - * It is a flat domain composed of Interval, top and bottom. * This domain is useful for the Interval propagation analysis. * * @author Mattia Bottaro diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala index 5d80295e..c6c2277a 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomain.scala @@ -48,6 +48,7 @@ class BoxDomain extends BaseNumericalDomain[Box, BoxDomainCore](BoxDomainCore()) class Property (boxes : Array[Box], unreachable: Boolean) extends BaseProperty(boxes, unreachable) { /** + * Returning the lower bound of an interval. * @param box is an Interval * @return the lower bound. */ @@ -61,6 +62,7 @@ class BoxDomain extends BaseNumericalDomain[Box, BoxDomainCore](BoxDomainCore()) /** + * Returning the upper bound of an interval. * @param box is an Interval * @return the upper bound. */ @@ -125,12 +127,23 @@ class BoxDomain extends BaseNumericalDomain[Box, BoxDomainCore](BoxDomainCore()) } } + /** + * Compute the corner of the box which minimizes a linear form. + * @param coeff the homogeneous coefficients. + * @return the coordinates of the point which minimizes the linear form. + */ private def linearArgmin(lf: LinearForm): Seq[InfInt] = { (lf.homcoeffs.zipWithIndex) map { case (c, i) => if (c > 0) projectLow(boxes(i)) else projectHigh(boxes(i)) } } + /** + * Return the dot product of `x` and `y`. + * If element `x(i)` is zero, then `x(i)*y(i)` is `0` independently from the value of `y(i)`. + * If `remove` is a valid index in `x` and `y`, the factor `x(remove) * y(remove)` is + * removed from the dot product. + */ private def dotprod(x: Seq[Int], y: Seq[InfInt], remove: Int): InfInt = { var sum: InfInt = IntNumber(0) for (i <- x.indices; if i != remove && x(i) != 0) @@ -140,7 +153,7 @@ class BoxDomain extends BaseNumericalDomain[Box, BoxDomainCore](BoxDomainCore()) /** * Implementing the widening strategy described in - * https://hal.archives-ouvertes.fr/hal-01657536 (Tutorial on Static Inference of Numeric Invariants by Abstract Interpretation), page 221 + * [[https://hal.archives-ouvertes.fr/hal-01657536]] (Tutorial on Static Inference of Numeric Invariants by Abstract Interpretation), page 221 * * @param that the abstract object to be widened with `this`. `that` IS assumed to be smaller than `this`. * @return the widening of the two abstract properties. @@ -172,7 +185,8 @@ class BoxDomain extends BaseNumericalDomain[Box, BoxDomainCore](BoxDomainCore()) } /** - * Implementing the narrowing strategy + * Implementing the narrowing strategy described in + * [[https://hal.archives-ouvertes.fr/hal-01657536]] (Tutorial on Static Inference of Numeric Invariants by Abstract Interpretation), page 230 * * @param that the abstract object to be narrowed with `this`. `that` IS assumed to be smaller than `this`. * @return the narrowing of the two abstract properties. diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala index 1b22da68..5054b6f9 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala @@ -30,15 +30,15 @@ class BoxDomainCore extends CompleteLatticeOperator[Box] with IntOperator[Box] with Abstraction[Int,Box]{ /** - * @inheritdoc - */ + * @inheritdoc + */ def alpha(num : Int) : Box = { return Interval(IntNumber(num),IntNumber(num)) } /** - * @inheritdoc - */ + * @inheritdoc + */ def sum(x : Box, y : Box) : Box = { (x,y) match { case (IntervalBottom, _) => IntervalBottom @@ -49,9 +49,9 @@ class BoxDomainCore extends CompleteLatticeOperator[Box] } } - /** - * @inheritdoc - */ + /** + * @inheritdoc + */ def inverse(x : Box) : Box = { x match { case IntervalBottom => IntervalBottom @@ -60,9 +60,9 @@ class BoxDomainCore extends CompleteLatticeOperator[Box] } } - /** - * @inheritdoc - */ + /** + * @inheritdoc + */ def mult(x : Box, y : Box) : Box = { (x,y) match { case (IntervalBottom, _) => IntervalBottom @@ -79,6 +79,13 @@ class BoxDomainCore extends CompleteLatticeOperator[Box] } } + /** + * Check if an interval is in the form [-Inf, -Inf], [+Inf, +Inf] or [-Inf, +Inf] to return a sound approsimation in order to avoid + * a sum with +Inf and -Inf. + * + * @param x an interval. + * @return a sound approsimation of the interval. + */ def check(x : Interval) : Box = { x match { case Interval(NegativeInfinity(), NegativeInfinity()) => Interval(NegativeInfinity(),IntNumber(Int.MinValue)) @@ -89,8 +96,8 @@ class BoxDomainCore extends CompleteLatticeOperator[Box] } /** - * @inheritdoc - */ + * @inheritdoc + */ def division(x : Box, y : Box) : Box = { (x,y) match { case (IntervalBottom, _) => IntervalBottom @@ -121,8 +128,8 @@ class BoxDomainCore extends CompleteLatticeOperator[Box] } /** - * @inheritdoc - */ + * @inheritdoc + */ def remainder(x : Box, y : Box) : Box = { (x,y) match { case (IntervalBottom, _) => IntervalBottom @@ -141,8 +148,8 @@ class BoxDomainCore extends CompleteLatticeOperator[Box] } /** - * @inheritdoc - */ + * @inheritdoc + */ def lub(x : Box, y : Box) : Box = { (x, y) match { case (IntervalTop, _) => return IntervalTop @@ -157,8 +164,8 @@ class BoxDomainCore extends CompleteLatticeOperator[Box] } /** - * @inheritdoc - */ + * @inheritdoc + */ def glb(x : Box, y : Box) : Box = { (x, y) match { case (IntervalTop, _) => return y @@ -176,8 +183,8 @@ class BoxDomainCore extends CompleteLatticeOperator[Box] } /** - * @inheritdoc - */ + * @inheritdoc + */ def compare(x : Box, y : Box) : Option[Int] = { (x, y) match { case (IntervalBottom, IntervalBottom) => return Option(0) @@ -199,20 +206,20 @@ class BoxDomainCore extends CompleteLatticeOperator[Box] } /** - * @inheritdoc - */ + * @inheritdoc + */ override def top: Box = IntervalTop /** - * @inheritdoc - */ + * @inheritdoc + */ override def bottom: Box = IntervalBottom } object BoxDomainCore { /** - * Factory method of BoxDomainCore - */ + * @inheritdoc + */ def apply() = new BoxDomainCore } // end of BoxDomainCore companion object From b8199fe427c9adfbe68685c879164b711190bb02 Mon Sep 17 00:00:00 2001 From: Mou95 Date: Sat, 28 Apr 2018 15:56:53 +0200 Subject: [PATCH 98/99] Fixed code --- core/examples/Java/TestBox.class | Bin 1686 -> 1679 bytes core/examples/Java/TestBox.java | 3 +-- .../jandom/targets/NumericExpression.scala | 1 - .../unich/jandom/targets/slil/WhileStmt.scala | 1 - .../numerical/box/BoundedBoxDomain.scala | 2 +- .../domains/numerical/box/BoxDomainCore.scala | 16 ++++++++-------- 6 files changed, 10 insertions(+), 13 deletions(-) diff --git a/core/examples/Java/TestBox.class b/core/examples/Java/TestBox.class index 27f064ada09cea48269abeca1452bf81649481c1..0c65582a054bbe38be8c08378162b7d4868f4602 100644 GIT binary patch delta 194 zcmWNJ&u#%>6h}`x-!~|enjofZ%4}xk1*S{3;%_V@XqupDQZz&)Ex`j=e2ImHXXw*- z7Ym7-ySnFha*ocy`9COU$fF$iR;b_1Sp}scQTb~^>nIvL(Zr!eiZ(eq6zP%>BZhTD znX3xjp2&SP1Cifx`7jk-c86GugpP%NlH|*rbodZ47yVlJmTiK~lsGe<`60ucJPUl5 c1guQfuD<+A_fHCIDQu*$CCv_xy;40@?Y-B=L!uiDL>&|za4HRVI&v&|iUxufK?e*=NhIh%HFvO}Q5WHz zcrVTiKb*cF|HHq?{A8AkAp3xa4;=ZiJ@squH>jK(lT= 6) { + if (x >= 7) { x = x - 10; } else { x = x + 10; diff --git a/core/src/main/scala/it/unich/jandom/targets/NumericExpression.scala b/core/src/main/scala/it/unich/jandom/targets/NumericExpression.scala index 774a17af..82b36155 100644 --- a/core/src/main/scala/it/unich/jandom/targets/NumericExpression.scala +++ b/core/src/main/scala/it/unich/jandom/targets/NumericExpression.scala @@ -151,7 +151,6 @@ object NumericExpression { input.linearInequality(lf) override def ltZero[Property <: NumericalProperty[Property]](input: Property): Property = { - println("INPUT"+input) input.linearInequality(lf) } override def neqZero[Property <: NumericalProperty[Property]](input: Property): Property = diff --git a/core/src/main/scala/it/unich/jandom/targets/slil/WhileStmt.scala b/core/src/main/scala/it/unich/jandom/targets/slil/WhileStmt.scala index e62a7ce8..2fc42e8a 100644 --- a/core/src/main/scala/it/unich/jandom/targets/slil/WhileStmt.scala +++ b/core/src/main/scala/it/unich/jandom/targets/slil/WhileStmt.scala @@ -88,7 +88,6 @@ case class WhileStmt(condition: NumericCondition, body: SLILStmt) extends SLILSt invariant = newinvariant params.wideningScope match { case Random => - print("CONDITION ANALYZE" + condition.analyze(invariant)) bodyResult = body.analyzeStmt(params)(condition.analyze(invariant), currentPhase, ann) newinvariant = widening(invariant, bodyResult) case BackEdges => diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomain.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomain.scala index 14b40c37..6bb094c5 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomain.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoundedBoxDomain.scala @@ -127,7 +127,7 @@ class BoundedBoxDomain(m : InfInt, n : InfInt) extends BaseNumericalDomain[Box, } case _ => } - new Property(newboxes,false) + new Property(newboxes.map(BoundedBoxDomainCore.norm),false) } } diff --git a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala index 5054b6f9..21b8ff64 100644 --- a/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala +++ b/core/src/main/scala/it/unipd/jandom/domains/numerical/box/BoxDomainCore.scala @@ -152,10 +152,10 @@ class BoxDomainCore extends CompleteLatticeOperator[Box] */ def lub(x : Box, y : Box) : Box = { (x, y) match { - case (IntervalTop, _) => return IntervalTop - case (_, IntervalTop) => return IntervalTop - case (IntervalBottom, _) => return y - case (_, IntervalBottom) => return x + case (IntervalTop, _) => IntervalTop + case (_, IntervalTop) => IntervalTop + case (IntervalBottom, _) => y + case (_, IntervalBottom) => x case (Interval (low1, high1), Interval (low2, high2)) => val new_low = low1 min low2 val new_high = high1 max high2 @@ -168,10 +168,10 @@ class BoxDomainCore extends CompleteLatticeOperator[Box] */ def glb(x : Box, y : Box) : Box = { (x, y) match { - case (IntervalTop, _) => return y - case (_, IntervalTop) => return x - case (IntervalBottom, _) => return IntervalBottom - case (_, IntervalBottom) => return IntervalBottom + case (IntervalTop, _) => y + case (_, IntervalTop) => x + case (IntervalBottom, _) => IntervalBottom + case (_, IntervalBottom) => IntervalBottom case (Interval (low1, high1), Interval (low2, high2)) => val new_low = low1 max low2 val new_high = high1 min high2 From 8bcbfa14a7f96d2b72dfc4542e3a47ea1eaacd7e Mon Sep 17 00:00:00 2001 From: Mou95 Date: Wed, 16 May 2018 10:41:56 +0200 Subject: [PATCH 99/99] Fixed test --- core/examples/Java/TestBox.class | Bin 1679 -> 1555 bytes core/examples/Java/TestBox.java | 14 -------------- 2 files changed, 14 deletions(-) diff --git a/core/examples/Java/TestBox.class b/core/examples/Java/TestBox.class index 0c65582a054bbe38be8c08378162b7d4868f4602..a8778355ddd36c8fe83442e63a79b1723ce01283 100644 GIT binary patch delta 239 zcmZ9`%Sr-a9ES1doAH~;@eCa-om`9yX{RWHm(WU$zzo3?iUgKaZo7n#Z|S-#Xy+na zdrvz4X;=H-%kzFFOx)icHa|d>f`=yOlD9v?Fm&-HTq@xC`^8Z)<&V1006L7?EPk8543$ w37Aph>38Q5+2bgcOhjavHASaUp39SGDZEHwA%#~?c_YjFzmnoo9$H)-0lSPM;s5{u delta 349 zcmZ9HOG^S_6o#MAna|PDNuw-tnu=yqtLWmU`~|JLQV?_@FhwYfB7#)9>_cW(yEe6z zb}jk=t@{ft`w2Q7-4zGUh4Z|;=LE?I$NTKOe*g zhYbeUB*&KQcSs5m$7o|Jm9eB93hL&(zbm3WIcr};2lR8;17k$mXr&Uu4F_N5oL|J? zNVt-4WztmsaJF#SU|KKdkA*uSN|gksq&OqPIW8CYTr$N~PiJGci7M6Sn4%mBUiISa bwOmpYhq^d4#NmcPZpm`@&q>Kk-N)Tu?Cv(C diff --git a/core/examples/Java/TestBox.java b/core/examples/Java/TestBox.java index 02a3ed3a..e1edc08d 100644 --- a/core/examples/Java/TestBox.java +++ b/core/examples/Java/TestBox.java @@ -76,20 +76,6 @@ public static void test4() { } } - public static void test5(){ - int i = 0; - int x = 2; - while(i < 10){ - i++; - if(i % 2 == 0){ - x = x * 2; - }else{ - x = x* (-2); - } - } - - } - public static void test6() { int x = 0; int y = 15;