[HN Gopher] Quint: A specification language based on the tempora...
       ___________________________________________________________________
        
       Quint: A specification language based on the temporal logic of
       actions (TLA)
        
       I am on the dev team for this project and would be happy to answer
       any questions and/or take note of any critical feedback :)  Here's
       a bit more detail:  Quint is a modern, executable specification
       language that is a particularly good fit for distributed systems,
       such as blockchain protocols, distributed databases, and p2p
       protocols. Quint combines the robust theoretical basis of the
       Temporal Logic of Actions (TLA) with state-of-the-art static
       analysis and development tooling.
        
       Author : abathologist
       Score  : 88 points
       Date   : 2023-12-19 11:19 UTC (1 days ago)
        
 (HTM) web link (github.com)
 (TXT) w3m dump (github.com)
        
       | metaketa wrote:
       | Recommended introduction talk for context:
       | 
       | https://www.youtube.com/watch?v=OZIX8rs-kOA&ab_channel=Gatew...
       | 
       | TLDR: compileable modeling language to model the high-level
       | protocol of your blockchain (or any distributed system). It's a
       | "digitalization" step of plain written English protocol
       | specifications to code.
        
       | just_mc wrote:
       | This looks really nice. It's the first thing I have seen that
       | appears to be approachable from a developer's perspective.
        
         | abathologist wrote:
         | That is our aim! If you give it a shot and find things that
         | aren't so approachable, we'd live to hear how we can improve.
        
       | crabbone wrote:
       | One thing that was a demotivating factor (for me) about TLA+ is
       | the syntax (I later realized that there's a more high-level
       | language that looks more like a programming language and less
       | like markup: PlusCal, but it was too late :). This looks a lot
       | nicer.
        
         | pron wrote:
         | The syntax is needed so that simple mathematical substitutions
         | and deductions could be applied. PlusCal is not "higher level",
         | it's just similar to a programming language. In fact, TLA+
         | makes it easy to write higher level specifications, i.e. those
         | that go into less detail. One of the nice things you can do is
         | write a smaller, high-level spec in TLA+ (e.g. you can specify
         | "a program that sorts integer arrays in O(n^2)") and then a
         | lower level spec, closer to code, in PlusCal, and tie the two
         | together, showing that the latter is an implementation of the
         | former.
         | 
         | The simple mathematical syntax (and semantics [1]) of TLA+ has
         | the advantage of making mathematical reasoning easier and it's
         | more expressive; if it were like a programming language there
         | would be too many things that TLA+ users would want to do but
         | couldn't, certainly not as easily. Programming-language-like
         | syntax and semantics has the advantage of being more familiar
         | to programmers (many of which just want to run a model checker,
         | and aren't interested in a more mathematical analysis of the
         | specification (which actually makes specification easier, but
         | only after gaining some experience). The two kinds of languages
         | make different kinds of things either easier or harder.
         | 
         | Overall, being programming-like helps programmers who just want
         | model checking and then maybe to start dipping their toes into
         | specification.
         | 
         | ----
         | 
         | [1]: What's more challenging for programmers is less the syntax
         | and more the semantics. For example, the following function
         | definition in TLA+ (using ASCII syntax) happens to _look_ a lot
         | like programming in this particular case:                   f[x
         | \in Int] == -f[x]
         | 
         | it _looks_ like a programming subroutine that recursively calls
         | itself ad-infinitum, but obviously, as in mathematics, it
         | simply defines a function of the integers that is zero
         | everywhere as that is the only definition that satisfies the
         | equation and allows simple mathematical substitution.
         | 
         | Another example could be (again, using the ASCII syntax):
         | Inc(x) == x + 1
         | 
         | which seems like an increment operator, but                  3
         | = Inc(x)'
         | 
         | means something close to: "the system assigns 2 to x (or maybe
         | something that's not a number)". In TLA+ things don't work like
         | in programming -- they work like in maths -- and they must not
         | work like in programming if you want to do things like high
         | level specifications, refinements and more. The syntax tries to
         | help and make that clear by trying to resemble maths rather
         | than programming so that you wouldn't confuse the different
         | meaning similar expressions have in these different domains.
         | For those who do want to learn TLA+ (which is a language that's
         | significantly simpler than Python but is not a programming
         | language) is to forget any relationship it may have to
         | programming and remember that even things that _look_ similar
         | to programming work in a very different way. I would say that
         | the relationship between TLA+ and programming is similar to
         | that between the formula h = 0.5gt^2 and someone dropping a
         | golf ball off a cliff in California.
         | 
         | Those who aren't interested may still benefit from languages
         | that are programming-like and offer model-checking. That's
         | great, too!
        
         | Taikonerd wrote:
         | I thought I read one time that Leslie Lamport didn't _want_
         | TLA+ to look like a programming language, because it might
         | confuse developers into thinking it IS a programming language.
         | 
         | I understand his logic, but at the same time, TLA+'s weird
         | surface syntax put off a lot of people who otherwise could have
         | used it. And PlusCal seemed like a halfway measure: more like a
         | programming language, but still kinda... weird.
         | 
         | So, I welcome Quint. And it's great that they seem interested
         | in making the tooling fit with the normal developer ecosystem,
         | such as LSP support.
        
         | abathologist wrote:
         | I can sympathize! We are aiming to maintain _most_ of the
         | expressive power of TLA+ -- ideally everything you need for a
         | concise, high-high level specification, that can be simulated
         | and /or verified -- but with surface syntax that is more
         | approachable coming from a programming background. If you're
         | interested in seeing how it maps to TLA+, you can find much of
         | that in this document:
         | https://github.com/informalsystems/quint/blob/main/doc/lang....
         | 
         | We still have lots of ways to improve, and -- we think -- lots
         | of opportunities to improve our interop and complementary
         | qualities in relation to TLA+ and TLC. But we have found the
         | tools in their current state useful enough to be worth sharing
         | :)
        
       | asimpletune wrote:
       | I'm trying to understand what is the difference between this and
       | using TLA.
       | 
       | For example, what is the difference between "robust theoretical
       | basis of the Temporal Logic of Actions (TLA)" and "state-of-the-
       | art static analysis"?
       | 
       | Sorry, I'm not an expert in TLA, but I thought that static
       | analysis was basically what it was used for.
        
         | jleahy wrote:
         | At very least it looks like it can do what TLA can do whilst
         | being dramatically less painful to learn / work with. That is
         | very much enough to be interesting.
        
         | bugarela wrote:
         | Hey! We just changed the description (yesterday) to avoid this
         | confusion - sorry! By static analysis there we actually mean
         | things like type and effect checking.
         | 
         | With either a TLA+ spec or a Quint spec, you can run a model
         | checker to verify properties or get counterexamples. That's the
         | main similarity. As Quint is based on TLA+, we can atually use
         | the same model checkers (that were originally implemented for
         | TLA+).
         | 
         | The main differences between TLA+ and Quint are the surface
         | syntax and the tooling (beyond the model checker). While TLA+
         | has an indentation-based hard-to-parse mathematical syntax
         | (that looks quite pretty in LaTeX), Quint has a typed
         | programming language styled syntax and a very simple parser,
         | making it easier to develop tools around it.
         | 
         | As for tooling, first of all, Quint has type checking, which
         | TLA+ doesn't. Our IDE support is also more similar to that of
         | modern programming languages - with features like "Go to
         | definition". With this, we hope (and have seen many reports of)
         | programmers/engineers having an easier and better time writing
         | Quint specs then they used to have with TLA+ tooling.
         | 
         | Quint also has support for execution of specs with random
         | simulation, a testing framework and a REPL.
         | 
         | In contrast, TLA+ is a much more permissive language, and you
         | can express more mathematical things that, for instance, could
         | never be executed or are not even supported by TLA+ existing
         | model checkers (TLC and Apalache). TLA+ has a proof system
         | (TLAPS), which Quint does not.
         | 
         | Quint imposes many restrictions with the goal of preventing
         | people to write things they don't really understand - which are
         | possible in TLA+. Those restrictions are useful, just as type
         | and effect systems are useful. But mathematicians that really
         | know what they are doing and need more powerful expressivity
         | will likely prefer TLA+ over Quint. Quint is aimed at
         | programmers and engineers.
         | 
         | They are complementary, not direct competition.
        
           | pron wrote:
           | > As for tooling, first of all, Quint has type checking,
           | which TLA+ doesn't.
           | 
           | I wouldn't put it quite like that. It's not that TLA+ doesn't
           | "do type checking" because TLA+ is just a language for
           | writing mathematical descriptions of things. It doesn't "do"
           | anything (do the formulas of Newtonian mechanics _do_ type-
           | checking?). It 's more precise to say that TLA+ is an untyped
           | language. But the model checker does check something like
           | "typing" in the sense of set membership. I.e. the invariant
           | #(x [?] Int), i.e. "x is always an integer", can be checked
           | with a TLA+ model checker just like many other invariants.
           | 
           | Furthermore, a model checker is "static" in the sense that,
           | just like a type-checker, it doesn't "run" a "program". It's
           | easy to see that a model checker doesn't run anything if you
           | consider that a model checker can prove the following "type"
           | on the right hand side of the implication:
           | x [?] BOOLEAN [?] #[x' = TRUE [?] x' = FALSE]_x = #(x [?]
           | BOOLEAN)
           | 
           | It proves it nearly instantaneously, even though every
           | "execution" of the "program" on the left of the implication
           | is infinite in its duration and there is an uncountably
           | infinite number of such "execution", so clearly nothing is
           | "executed" and the check isn't dynamic. So a TLA+ model
           | checker does do something that's analogous-ish to type-
           | checking.
           | 
           | However, it is true that by type-checking we normally mean an
           | automated _deductive_ process, i.e. one that applies
           | inference rules, rather than an automated exhaustive analysis
           | of the semantic domain, which is how a model-checker works.
           | And yes, there are implications to the different ways  "type
           | checking" is done, especially when it comes to the
           | algorithmic complexity of the checker.
           | 
           | This is just another example where comparisons to programming
           | are unhelpful when describing mathematics that don't "run";
           | it just _is_.
           | 
           | It may be best to say that a language like Quint is inspired
           | by the TLA logic (the TLA part of TLA+) and is similar to a
           | programming language, whereas TLA+ is something else
           | altogether (that requires learning something that is very
           | much _not_ programming) and leave it at that.
           | 
           | I admit that explaining the difference between programming
           | (or something that's programming-like) and specifying a
           | system with mathematics to people who are less familiar with
           | the latter is difficult. It's a little like trying to explain
           | the notion of a physics formula to a catapult builder in
           | ancient Greece. There's clearly a relationship between the
           | two (and some physics formulas may certainly be helpful when
           | designing a catapult and make the catapult builder a better
           | catapult builder), but they're also completely different
           | things operating in two different domains (a formula isn't
           | something that can fire a projectile).
        
             | nextaccountic wrote:
             | > It's more precise to say that TLA+ is an untyped
             | language.
             | 
             | That's the same thing as not having static types. (From the
             | POV of static types, dynamically typed languages are just
             | untyped languages, that is, languages that have exactly one
             | type)
             | 
             | > I.e. the invariant #(x [?] Int), i.e. "x is always an
             | integer", can be checked with a TLA+ model checker just
             | like many other invariants.
             | 
             | That's just checking a dynamic typing property (that is,
             | something tha _could_ in principle vary during the
             | execution of the program, but you just proved that it doesn
             | 't). That is, this is checking that certain dynamic types
             | stay the same.
             | 
             | (which is totally okay, and it's true that if you restrict
             | dynamic types enough you can show there's a statically
             | typed program that is equivalent)
             | 
             | > However, it is true that by type-checking we normally
             | mean an automated deductive process, i.e. one that applies
             | inference rules, rather than an automated exhaustive
             | analysis of the semantic domain, which is how a model-
             | checker works. And yes, there are implications to the
             | different ways "type checking" is done, especially when it
             | comes to the algorithmic complexity of the checker.
             | 
             | Yep! Static types are static _by construction_, you don't
             | need any dynamic information to type check them
        
               | erichocean wrote:
               | > _(From the POV of static types, dynamically typed
               | languages are just untyped languages, that is, languages
               | that have exactly one type)_
               | 
               | I believe the mistake you are making is assuming that
               | TLA+ has some kind of runtime where things are "executed"
               | (static vs. dynamic in the context of programming
               | languages refers to, roughly, compile-time vs. execution-
               | time). Model checking in TLA+ is actually analogous to
               | "running a compiler", not running a REPL or whatever.
               | It's definitely NOT a runtime.
               | 
               | TLA+ has no "dynamic" aspect at all, it's all "static"
               | from the POV of language theory. And since it DOES
               | provide a way (read: syntax) to create and check types
               | (as the GP shows) and those types are checked statically
               | (again, remember: there is no execution happening here),
               | TLA+ is formally (and practically) equivalent to a
               | language that has a different syntactic way to specify
               | types, i.e. one that programmers are more familiar with.
               | 
               | What TLA+ is missing is any notion of executing code.
               | That's what makes it a _specification language_ and not
               | an implementation language. Most programming languages
               | are implementation languages, with a bit of
               | "specification"--usually types--sprinkled on top. TLA+ is
               | specification-only, no implementation stuff is written
               | down.
               | 
               | So to recap, from a language-theoretic POV, TLA+
               | absolutely supports "static typing" in the way that it is
               | usually understood and used by programmers and language
               | theoreticians, but with a syntax that is unfamiliar
               | (because it is a specification language).
               | 
               | For completeness, you can specify modern type inference
               | algorithms like MLstruct/MLsub [0] in TLA+ and the model
               | checker will happily apply them to your TLA+
               | specification (again, statically--at compile-time, which
               | is really "model checking" time).
               | 
               | [0] https://lptk.github.io/files/[v8.0]%20mlstruct.pdf
        
               | abathologist wrote:
               | I think you and Ron are confusing the relevant phase
               | distinction the rest of us have in mind when we talk
               | about type checking in this context.
               | 
               | What we mean is that quint, the language, is expressed on
               | top of a many-sorted logic which allows our tooling to
               | find and diagnose typing errors _prior to *running* any
               | type checker_. The TLA Toolbox doesn 't support this, and
               | TLA+, like TLA itself, is untyped. TLC can (and will)
               | raise errors while in the process of checking your model
               | due to the kinds of problems we usually call "typing
               | errors". Quint and apalache shouldn't do this.
               | 
               | I hope this helps clarify a bit.
               | 
               | We understand that, viewed purely theoretically, TLA+ has
               | no dynamic aspect at all, etc. However, our team is very
               | focused on the fusion of theory and practice, and we
               | think it's important to ground our understanding and our
               | discourse in the way the specification languages are
               | actually used by real people given the existing tools.
               | While it may be true in theory that
               | 
               | > What TLA+ is missing is any notion of executing code.
               | 
               | The file `TLC.tla` in the `StandardModules` includes
               | these lines:                 ```       Print(out, val) ==
               | val       PrintT(out) == TRUE              (* This
               | expression equals TRUE, but evaluating it causes TLC to
               | print   *)        (* the value of out.
               | *)          ```
               | 
               | https://github.com/tlaplus/tlaplus/blob/master/tlatools/o
               | rg....
               | 
               | In any case, our whole team thinks TLA is great, and
               | we're happy people like you and Ron find it so useful and
               | insightful. We also think it is a very insightful tool
               | for guiding understanding :)
        
               | erichocean wrote:
               | > _TLA+ is missing is any notion of executing code_
               | 
               | Which is why you had to talk about TLC, not TLA+. And
               | yeah, while the presence of printf-style debugging for
               | specifications being model checked by TLC is technically
               | executable-ish, I think in this case, it kind of proves
               | the point that TLA+ itself _isn 't_.
               | 
               | Regardless, I like the direction Quint is taking though I
               | would quibble with this language in your reply:
               | 
               | > _our tooling to find and diagnose typing errors [runs]
               | prior to [...] any type checker_
               | 
               | If you are _diagnosing typing errors_ , then
               | definitionally, _you are running a type checker_. It 's
               | great that it's fast and interactive, runs prior to the
               | model checker, is easy for programmers to read/write, et
               | cetera. But...it's still a type checker. :-)
               | 
               | Anyway, keep up the great work! I've been on your
               | newsletter for a long time and love the work you guys are
               | doing.
        
               | bugarela wrote:
               | I think they meant "model checker" instead of "type
               | checker" in that sentence. Otherwise, of course, we need
               | to run the type checker to get the type diagnosis.
        
               | pron wrote:
               | > That's the same thing as not having static types.
               | 
               | I didn't say it had static types. I was referring
               | specifically to the notion of type checking.
               | 
               | > dynamically typed languages are just untyped languages
               | 
               | There are no dynamic types in TLA+ just as there aren't
               | in the formula F = ma. There is nothing here that's
               | running, and all the automated analysis, including of the
               | sets that corresponds to types doesn't run anything.
               | 
               | > That's just checking a dynamic typing property
               | 
               | There is no "dynamism" here. The model checker checks
               | that the "type" (really set membership) holds in any
               | possible execution, each of which potentially infinite in
               | duration, out of a countless infinity of executions. It's
               | also a "static" check, it's just that it isn't syntactic.
               | 
               | > Static types are static _by construction_, you don't
               | need any dynamic information to type check them
               | 
               | And neither do you need any "dynamic" information in
               | TLA+. Dynamic types are a programming notion. TLA+ is not
               | a programming language.
        
         | abathologist wrote:
         | Those are great questions! Let me add a one addendum to
         | bugarela's excellent explanation, to help disambiguate these
         | three formalism:
         | 
         | 1. TLA[0] is a logical calculus invented by Leslie Lamport.
         | 
         | 2. TLA+[1] is a formal specification language, also invented by
         | Leslie Lamport, with semantics based on and reducible to TLA.
         | 
         | 3. quint is also a formal specification language with semantics
         | based on and reducible to TLA.
         | 
         | TLA+ can be understood as TLA extended with syntax sugar to
         | help describe systems. On top of the logical calculus it adds
         | niceties like `LET` bindings, syntax to represent common data
         | structures, `CASE` expressions, a module system, etc. But TLA+
         | also exposes the underlying logic directly, making the language
         | extremely expressive. The flip side is that nonsensical
         | formulas which may not be checkable are pretty easy to write.
         | 
         | quint is a (programmer friendly) syntax that, while also
         | desugaring to TLA, gives up expressivity to add the guardrails
         | that we've found most helpful when specifying the systems we
         | work on.
         | 
         | Please let us know if you have any followup questions :)
         | 
         | ---
         | 
         | [0]: https://en.wikipedia.org/wiki/Temporal_logic_of_actions
         | [1]: https://en.wikipedia.org/wiki/TLA%2B
        
       | Kevin09210 wrote:
       | Clojure to TLA+
       | 
       | https://github.com/Viasat/salt
       | 
       | Successor: https://github.com/Viasat/halite
        
         | bugarela wrote:
         | I didn't take a very deep look yet, but this might be similar
         | to https://github.com/pfeodrippe/recife
        
       | zubairq wrote:
       | Interesting
        
       | Nevermark wrote:
       | > We have covered all the aspects of our "Hello, world!" example.
       | Actually, we could have written a much shorter example, but it
       | would not demonstrate the distinctive features of Quint.
       | 
       | Ouch! When I am trying to wrap my head around a new tool, I want
       | a series of examples starting with _the absolute simplest
       | possible example_.
       | 
       | If I can see only one new concept demonstrated at a time, each in
       | the simplest context possible, I can quickly develop a clear
       | understanding. By quickly, I mean a solid understanding in
       | minutes.
       | 
       | Anything else just generates questions (and am I even thinking
       | the right questions?) at a faster rate than lightbulbs.
        
         | abathologist wrote:
         | This is great feedback, thanks! Probably the first step
         | tutorial should just be on something very straightforward, like
         | an hour clock or a counter. I'll file an issue to introduce
         | something more focused.
         | 
         | Thanks again :)
         | 
         | edit: https://github.com/informalsystems/quint/issues/1319
        
       | nextaccountic wrote:
       | How do you compare this with Alloy?
        
         | bugarela wrote:
         | I haven't really used Alloy before to give you a nice
         | comparison, but some people have talked about differences in
         | similarities between Alloy and TLA+ (i.e. in
         | https://alloytools.discourse.group/t/alloy-6-vs-tla/329/13),
         | and, in general, this should apply to Alloy vs Quint, since
         | Quint is heavily based on TLA+. Evidently, the points regarding
         | tooling and surface syntax won't really apply, as those are
         | things Quint does not take from TLA+.
        
       ___________________________________________________________________
       (page generated 2023-12-20 23:01 UTC)