Imports and exports #949
Replies: 9 comments 16 replies
-
Use case 1. module A {
var x: int
action aInit = x' = 0
action aStep = x' = x + 1
}
module B {
import A.*
action bInit = aInit
// x is visible in bStep
action bStep = all { x >= 0, aStep }
}
// C can be the internal module constructed by REPL
module C {
import B.*
action cInit = bInit
action cStep = bStep
// aInit, aStep, and x are not visible in C
} The expectation. The module The VSCode is OK ✅ REPL ✅: $ quint repl -r t.qnt::C
Quint REPL 0.11.1
Type ".exit" to exit, or ".help" for more information
>>> cInit
true
>>> cStep
true
>>> The simulator ✅: $ quint run --main=C --init=cInit --step=cStep t.qnt The transpiler ✅: $ quint verify --main=C --init=cInit --step=cStep t.qnt |
Beta Was this translation helpful? Give feedback.
-
Use case 2. module A {
var x: int
action aInit = x' = 0
action aStep = x' = x + 1
}
module B {
import A as A2
export A2.*
action bInit = A2::aInit
// x is visible in bStep
action bStep = all { A2::x >= 0, A2::aStep }
}
// C can be the internal module constructed by REPL
module C {
import B.*
action cInit = bInit
action cStep = bStep
// aInit, aStep, and x are visible in C
action cInit2 = aInit
action cStep2 = all { x >= 0, aStep }
} The expectation. This does not work in VSCode ❌ This does not work in REPL ❌ $ quint repl -r t.qnt::C
Quint REPL 0.11.2
Type ".exit" to exit, or ".help" for more information
syntax error: error: Failed to resolve name aInit in definition for cInit2, in module C
action cInit2 = aInit
^^^^^ This does not work in the simulator ❌ $ quint run --main=C --init=cInit --step=cStep t.qnt
.../quint/t.qnt:24:19 - error: Failed to resolve name aInit in definition for cInit2, in module C
24: action cInit2 = aInit
^^^^^ This does not work in the transpiler ❌ $ quint verify --main=C --init=cInit --step=cStep t.qnt
.../quint/t.qnt:24:19 - error: Failed to resolve name aInit in definition for cInit2, in module C
24: action cInit2 = aInit
^^^^^ |
Beta Was this translation helpful? Give feedback.
-
Use case 3. The third use case using a single instance. module A {
const N: int
var x: int
action aInit = x' = 0
action aStep = x' = x + N
}
module B {
import A(N=2) as A2
export A2.*
action bInit = A2::aInit
// x is visible in bStep
action bStep = all { A2::x >= 0, A2::aStep }
}
// C can be the internal module constructed by REPL
module C {
import B.*
action cInit = bInit
action cStep = bStep
// aInit, aStep, and x are visible in C
action cInit2 = aInit
action cStep2 = all { x >= 0, aStep }
} The expectation. This does work in VSCode ✅ REPL is quite confused here ❌ $ quint repl -r t.qnt::C
Quint REPL 0.11.2
Type ".exit" to exit, or ".help" for more information
>>> cInit
true
[warning] some variables are undefined: x
>>> cStep
true
[warning] some variables are undefined: x
>>> A::x
syntax error: error: Failed to resolve name A::x in definition for q::input, in module __repl__
A::x
^^^^
>>> x
runtime error: error: Variable x is not set
var x: int
^^^^^^^^^^
<undefined value> This works in the simulator, though it uses the variable
The Apalache transpiler is confused ❌ $ quint verify --main=C --init=cInit --step=cStep t.qnt
error: Assignment error: No assignments found for: x |
Beta Was this translation helpful? Give feedback.
-
Use case 4. For some reason it works, though it works somewhat unexpected. module A {
const N: int
var x: int
action aInit = x' = 0
action aStep = x' = x + N
}
module B {
import A(N=2).*
action bInit = aInit
// x is visible in bStep
action bStep = all { x >= 0, aStep }
} The expectation. This works in VSCode ✅ This works in REPL but it may be confusing 🪲 $ quint repl -r t.qnt::B
Quint REPL 0.11.2
Type ".exit" to exit, or ".help" for more information
>>> bInit
true
>>> bStep
true
>>> x
2 Although it works in REPL, I did not expect it. Apparently, when we instantiate a module, it is exported automatically. I think this is where we have got confused: Normal imports do not export names, whereas instances export names. What makes it worse, when I import the module $ quint repl
Quint REPL 0.11.2
Type ".exit" to exit, or ".help" for more information
>>> import B.* from "./t"
syntax error: error: [QNT404] Module B not found
import B.* from "./t"
^^^^^^^^^^^^^^^^^^^^^
>>> It works in the simulator as expected ✅ $ quint run --main=B --init=bInit --step=bStep t.qnt
An example execution:
[State 0] { x: 0 }
... It works in the transpiler as expected ✅ $ quint verify --main=B --init=bInit --step=bStep t.qnt |
Beta Was this translation helpful? Give feedback.
-
Use case 5. module A {
const N: int
var x: int
action aInit = x' = 0
action aStep = x' = x + N
}
module B {
import A(N=2) as A2
import A(N=3) as A3
action bInit = all { A2::aInit, A3::bInit }
action bStep = all { A2::aStep, A3::bStep }
} The expectation. The VSCode is not working ❌ REPL is not working ❌ $ quint repl -r t.qnt::B
Quint REPL 0.11.2
Type ".exit" to exit, or ".help" for more information
syntax error: error: Failed to resolve name A3::bInit in definition for bInit, in module B
action bInit = all { A2::aInit, A3::bInit }
^^^^^^^^^ The simulator is not working ❌ $ quint run --main=B --init=bInit --step=bStep t.qnt
.../quint/t.qnt:13:35 - error: Failed to resolve name A3::bInit in definition for bInit, in module B
13: action bInit = all { A2::aInit, A3::bInit } The transpiler is not working ❌ $ quint verify --main=B --init=bInit --step=bStep t.qnt
.../quint/t.qnt:13:35 - error: Failed to resolve name A3::bInit in definition for bInit, in module B
13: action bInit = all { A2::aInit, A3::bInit } |
Beta Was this translation helpful? Give feedback.
-
Use case 6. Exporting all the names from the namespace. Consider the following example: module A {
const N: int
var x: int
action aInit = x' = 0
action aStep = x' = x + N
}
module B {
import A.*
export *
action bInit = A2::aInit
// x is visible in bStep
action bStep = all { A2::x >= 0, A2::aStep }
}
// C can be the internal module constructed by REPL
module C {
import B(N = 2).*
export *
action cInit = bInit
action cStep = bStep
// aInit, aStep, and x are visible in C
action cInit2 = aInit
action cStep2 = all { x >= 0, aStep }
} Expected behavior. All names of Currently, we do not have syntax for that. However, it should be really easy to introduce |
Beta Was this translation helpful? Give feedback.
-
Use case 7. Importing and exporting names across files. Consider the following three module definitions scattered across three files: File module A {
const N: int
var x: int
action aInit = x' = 0
action aStep = x' = x + N
} File module B {
import A as A2 from "./A"
export A2.*
action bInit = A2::aInit
// x is visible in bStep
action bStep = all { A2::x >= 0, A2::aStep }
} File module C {
import B(N = 2) as B2 from "./B"
export B2.*
action cInit = bInit
action cStep = bStep
// aInit, aStep, and x are visible in C
action cInit2 = aInit
action cStep2 = all { x >= 0, aStep }
} Expected behavior. Module Current behavior. The parser does not accept $ quint parse B.qnt
.../B.qnt:3:3 - error: [QNT405] Module 'A2' not found
3: export A2.*
^^^^^^^^^^^
error: parsing failed $ quint parse C.qnt
.../B.qnt:3:3 - error: [QNT405] Module 'A2' not found
3: export B2.*
^^^^^^^^^^^
.../C.qnt:2:3 - error: [QNT406] Instantiation error: 'N' not found in 'B'
2: import B(N = 2) as B2 from "./B"
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.../C.qnt:2:12 - error: [QNT404] Name 'B2::N' not found
2: import B(N = 2) as B2 from "./B"
^
.../C.qnt:8:19 - error: [QNT404] Name 'aInit' not found
8: action cInit2 = aInit
^^^^^
.../C.qnt:9:25 - error: [QNT404] Name 'x' not found
9: action cStep2 = all { x >= 0, aStep }
^
.../C.qnt:9:33 - error: [QNT404] Name 'aStep' not found
9: action cStep2 = all { x >= 0, aStep }
^^^^^
error: parsing failed |
Beta Was this translation helpful? Give feedback.
-
After meeting about this subject twice this week, here's what we believe we should do:
With this, we should end up with the following semantics: Imports:
|
Beta Was this translation helpful? Give feedback.
-
Given module A {
const X: int
val f = X
}
module B {
import A.f
val g = f
}
module C {
import B
val h = B::g
}
module D {
import C.h
val i = h
}
However, loading the modules in the repl, we find that modules B, C, and D are
However, if we use the
As I understand things, modules that declare constants are parametric. We should
In short: our modules have types. They are either non-parametric modules of type
|
Beta Was this translation helpful? Give feedback.
-
As we have discussed, in the recent implementation of
import
andexport
keywords, we have (somewhat unexpectedly) introduced a large feature space. The purpose of this discussion is to enumerate all possible combinations of usingimport
andexport
and figure out which behaviour is considered valid. This is needed for synchronisation between the VSCode plugin,quint repl
,quint run
,quint test
, andquint verify
.Beta Was this translation helpful? Give feedback.
All reactions