Skip to content

Commit

Permalink
Merge branch 'main' into jk/oracles2
Browse files Browse the repository at this point in the history
  • Loading branch information
Kukovec authored Sep 22, 2023
2 parents 617fa06 + 281c66d commit 67890e2
Show file tree
Hide file tree
Showing 14 changed files with 179 additions and 23 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/container.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:

steps:
- name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v4

- name: Log in to the Container registry
uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4

- name: Setup mdBook
uses: peaceiris/actions-mdbook@v1
Expand Down
24 changes: 13 additions & 11 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
build-mdbook:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4

- name: Setup mdBook
uses: peaceiris/actions-mdbook@v1
Expand All @@ -30,10 +30,11 @@ jobs:
format-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v1
uses: actions/setup-java@v3
with:
distribution: temurin
java-version: 17
- name: Check formatting
run: make fmt-check
Expand All @@ -43,10 +44,11 @@ jobs:
APALACHE_FATAL_WARNINGS: true
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v1
uses: actions/setup-java@v3
with:
distribution: temurin
java-version: 17
- name: Check scaladoc
run: sbt unidoc
Expand All @@ -56,9 +58,9 @@ jobs:
APALACHE_FATAL_WARNINGS: true
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v2
uses: actions/setup-java@v3
with:
distribution: temurin
java-version: 17
Expand Down Expand Up @@ -87,9 +89,9 @@ jobs:
matrix:
operating-system: [ubuntu-latest, macos-latest]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v2
uses: actions/setup-java@v3
with:
distribution: temurin
java-version: 17
Expand Down Expand Up @@ -129,7 +131,7 @@ jobs:
- operating-system: macos-latest
smt-encoding: arrays
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Cache local m2 repository
uses: actions/cache@v2
with:
Expand Down Expand Up @@ -166,7 +168,7 @@ jobs:
docker-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Cache nix store
# Workaround for cache action not playing well with permissions
# See https://github.com/actions/cache/issues/324
Expand Down
5 changes: 3 additions & 2 deletions .github/workflows/prepare-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,10 @@ jobs:
GITHUB_TOKEN: ${{ secrets.APALACHE_BOT_TOKEN }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-java@v1
- uses: actions/checkout@v4
- uses: actions/setup-java@v3
with:
distribution: temurin
java-version: 17
- name: Configure Git
run: |
Expand Down
5 changes: 3 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,15 @@ jobs:
if: startsWith(github.event.pull_request.title, '[release]') && github.event.pull_request.merged == true
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
with:
# See https://github.com/actions/checkout/issues/124#issuecomment-606277160
ref: ${{ github.event.pull_request.head.ref }}
# We only need the two commits of the release prep branch
fetch-depth: 2
- uses: actions/setup-java@v1
- uses: actions/setup-java@v3
with:
distribution: temurin
java-version: 17
- name: Cut Release
env:
Expand Down
1 change: 0 additions & 1 deletion .unreleased/features/2732.md

This file was deleted.

6 changes: 6 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
<!-- NOTE: This file is generated. Do not write release notes here.
Notes for unreleased changes go in the .unreleased/ directory. -->

## 0.43.0 - 2023-09-18

### Features

- - Revise the ITF format: Use only `{ "#bigint": "num" }`, even for small integers`

## 0.42.0 - 2023-08-21

### Breaking changes
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.42.1-SNAPSHOT
0.43.1-SNAPSHOT
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ ThisBuild / versionFile := (ThisBuild / baseDirectory).value / "VERSION"
ThisBuild / version := scala.io.Source.fromFile(versionFile.value).mkString.trim

ThisBuild / organization := "at.forsyte"
ThisBuild / scalaVersion := "2.13.11"
ThisBuild / scalaVersion := "2.13.12"

// Add resolver for Sonatype OSS Snapshots and Releases Maven repository
ThisBuild / resolvers ++= Resolver.sonatypeOssRepos("snapshots")
Expand Down
4 changes: 2 additions & 2 deletions project/Dependencies.scala
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ object Dependencies {
val slf4j = "org.slf4j" % "slf4j-api" % "2.0.9"
val shapeless = "com.chuusai" %% "shapeless" % "2.3.10"
val tla2tools = "org.lamport" % "tla2tools" % "1.7.0-SNAPSHOT"
val ujson = "com.lihaoyi" %% "ujson" % "3.1.2"
val upickle = "com.lihaoyi" %% "upickle" % "3.1.2"
val ujson = "com.lihaoyi" %% "ujson" % "3.1.3"
val upickle = "com.lihaoyi" %% "upickle" % "3.1.3"
val z3 = "tools.aqua" % "z3-turnkey" % "4.12.2"
val zio = "dev.zio" %% "zio" % zioVersion
// Keep up to sync with version in plugins.sbt
Expand Down
2 changes: 1 addition & 1 deletion project/plugins.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.11.0")
// https://github.com/sbt/sbt-native-packager
addSbtPlugin("com.github.sbt" % "sbt-native-packager" % "1.9.16")
// https://scalacenter.github.io/scalafix/docs/users/installation.html
addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.11.0")
addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.11.1")
// https://scalapb.github.io/zio-grpc/docs/installation
addSbtPlugin("com.thesamet" % "sbt-protoc" % "1.0.6")
// https://github.com/sbt/sbt-unidoc
Expand Down
2 changes: 2 additions & 0 deletions test/tla/cli-integration-tests.md
Original file line number Diff line number Diff line change
Expand Up @@ -3918,6 +3918,7 @@ up and output its welcome message, before killing it:
$ apalache-mc server & pid=$! && sleep 3 && kill $pid
...
The Apalache server is running on port 8822. Press Ctrl-C to stop.
...
```
### server mode: server can be started at different port
Expand All @@ -3926,6 +3927,7 @@ The Apalache server is running on port 8822. Press Ctrl-C to stop.
$ apalache-mc server --port=8888 & pid=$! && sleep 3 && kill $pid
...
The Apalache server is running on port 8888. Press Ctrl-C to stop.
...
```
## quint input
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package at.forsyte.apalache.tla.bmcmt.stratifiedRules.aux.oracles

import at.forsyte.apalache.tla.bmcmt.smt.SolverContext
import at.forsyte.apalache.tla.bmcmt.stratifiedRules.RewriterScope
import at.forsyte.apalache.tla.typecomp.TBuilderInstruction
import at.forsyte.apalache.tla.types.tla

/**
* Given a set `indices` of size `N`, sparse oracle is able to answer {{{chosenValueIsEqualToIndexedValue(_, i),}}} for
* any `i \in indices`, despite having a size, which may be smaller than some (ot all) elements of `indices`.
* {{{chosenValueIsEqualToIndexedValue(_, j),}}} for any `j` not in `indices` does not hold.
*
* Internally, every SparseOracle `s` maintains an oracle `o` of size `N-1`, such that for every scope `X`, and any
* index `i \in indices` the following holds:
* {{{s.chosenValueIsEqualToIndexedValue(X,i) = o.chosenValueIsEqualToIndexedValue(x, idxMap(i),}}} where `idxMap` is
* some bijection from `indices` to `{0,...,N-1}`.
*
* @author
* Jure Kukovec
*
* @param mkOracle
* the method to create the backend oracle, of a given size
* @param values
* the set S of oracle values
*/
class SparseOracle(mkOracle: Int => Oracle, val values: Set[Int]) extends Oracle {
private[oracles] val oracle = mkOracle(values.size)
private[oracles] val sortedValues: Seq[Int] = values.toSeq.sorted
private[oracles] val indexMap: Map[Int, Int] = Map(sortedValues.zipWithIndex: _*)

override def size: Int = values.size

def chosenValueIsEqualToIndexedValue(scope: RewriterScope, index: BigInt): TBuilderInstruction =
indexMap
.get(index.toInt)
.map {
oracle.chosenValueIsEqualToIndexedValue(scope, _)
}
.getOrElse(tla.bool(false))

override def caseAssertions(
scope: RewriterScope,
assertions: Seq[TBuilderInstruction],
elseAssertionsOpt: Option[Seq[TBuilderInstruction]] = None): TBuilderInstruction =
oracle.caseAssertions(scope, assertions, elseAssertionsOpt)

override def getIndexOfChosenValueFromModel(solverContext: SolverContext): BigInt = {
val oracleIdx = oracle.getIndexOfChosenValueFromModel(solverContext).toInt
sortedValues.applyOrElse[Int, Int](oracleIdx, _ => -1)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package at.forsyte.apalache.tla.bmcmt.stratifiedRules.aux.oracles

import at.forsyte.apalache.tla.bmcmt.arena.PureArenaAdapter
import at.forsyte.apalache.tla.bmcmt.smt.{SolverConfig, Z3SolverContext}
import at.forsyte.apalache.tla.bmcmt.stratifiedRules.RewriterScope
import at.forsyte.apalache.tla.bmcmt.types.CellT
import at.forsyte.apalache.tla.bmcmt.{ArenaCell, PureArena}
import at.forsyte.apalache.tla.lir._
import at.forsyte.apalache.tla.typecomp.TBuilderInstruction
import at.forsyte.apalache.tla.types.tla
import org.junit.runner.RunWith
import org.scalacheck.Gen
import org.scalacheck.Prop.forAll
import org.scalatest.BeforeAndAfterEach
import org.scalatest.funsuite.AnyFunSuite
import org.scalatestplus.junit.JUnitRunner
import org.scalatestplus.scalacheck.Checkers

@RunWith(classOf[JUnitRunner])
class TestSparseOracle extends AnyFunSuite with BeforeAndAfterEach with Checkers {

var initScope: RewriterScope = RewriterScope.initial()
var intOracleCell: ArenaCell = PureArena.cellInvalid

def mkIntOracle(n: Int): Oracle = new IntOracle(intOracleCell, n)

override def beforeEach(): Unit = {
val scope0 = RewriterScope.initial()
initScope = scope0.copy(arena = scope0.arena.appendCell(CellT.fromType1(IntT1)))
intOracleCell = initScope.arena.topCell
}

val intGen: Gen[Int] = Gen.choose(-10, 10)
val nonNegIntGen: Gen[Int] = Gen.choose(0, 20)

val setGen: Gen[Set[Int]] = for {
maxSize <- nonNegIntGen
elems <- Gen.listOfN(maxSize, nonNegIntGen)
} yield elems.toSet

val nonemptySetAndIdxGen: Gen[(Set[Int], Int)] = for {
maxSize <- Gen.choose(1, 20)
elems <- Gen.listOfN(maxSize, nonNegIntGen)
idx <- Gen.oneOf(elems)
} yield (elems.toSet, idx)

test("chosenValueIsEqualToIndexedValue returns the correct value for any element of the constructor set") {
val prop =
forAll(Gen.zip(setGen, intGen)) { case (set, index) =>
val oracle = new SparseOracle(mkIntOracle, set)
val cmp: TlaEx = oracle.chosenValueIsEqualToIndexedValue(initScope, index)
if (!set.contains(index))
cmp == tla.bool(false).build
else {
cmp == oracle.oracle.chosenValueIsEqualToIndexedValue(initScope, oracle.indexMap(index)).build
}
}

check(prop, minSuccessful(1000), sizeRange(4))
}

val (assertionsA, assertionsB): (Seq[TBuilderInstruction], Seq[TBuilderInstruction]) = 0
.to(10)
.map { i =>
(tla.name(s"A$i", BoolT1), tla.name(s"B$i", BoolT1))
}
.unzip

// "caseAssertions" tests ignored, since SparseOracle literally just invokes the underlying oracle's method,
// which should have its own tests

// We cannot test getIndexOfChosenValueFromModel without running the solver
test("getIndexOfChosenValueFromModel recovers the index correctly") {
val ctx = new Z3SolverContext(SolverConfig.default)
val paa = PureArenaAdapter.create(ctx) // We use PAA, since it performs the basic context initialization
val paa2 = paa.appendCell(IntT1) // also declares the cell
intOracleCell = paa2.topCell
initScope = initScope.copy(arena = paa2.arena)
val prop =
forAll(nonemptySetAndIdxGen) { case (set, index) =>
val oracle = new SparseOracle(mkIntOracle, set)
val eql = oracle.chosenValueIsEqualToIndexedValue(initScope, index)
ctx.push()
ctx.assertGroundExpr(eql)
ctx.sat()
val ret = oracle.getIndexOfChosenValueFromModel(ctx) == index
ctx.pop()
ret
}

// 1000 is too many, since each run invokes the solver
check(prop, minSuccessful(80), sizeRange(4))
}
}

0 comments on commit 67890e2

Please sign in to comment.