This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-08-01
Channels
- # beginners (41)
- # boot (25)
- # cider (34)
- # cljs-dev (221)
- # cljsrn (1)
- # clojure (191)
- # clojure-dusseldorf (4)
- # clojure-hamburg (1)
- # clojure-italy (8)
- # clojure-poland (1)
- # clojure-russia (22)
- # clojure-spec (27)
- # clojure-uk (91)
- # clojurescript (101)
- # core-async (11)
- # cursive (33)
- # data-science (9)
- # datascript (3)
- # datomic (30)
- # emacs (4)
- # events (4)
- # garden (6)
- # jobs (3)
- # leiningen (8)
- # luminus (39)
- # lumo (2)
- # off-topic (158)
- # om (13)
- # onyx (1)
- # parinfer (22)
- # planck (2)
- # protorepl (5)
- # re-frame (7)
- # reagent (10)
- # remote-jobs (1)
- # ring (1)
- # ring-swagger (20)
- # unrepl (92)
- # vim (11)
is "mutual exclusiveness" and/or "orthogonality" of a set of the predicates is even approachable, let alone provable automatically (e.g. during testing with spec)? Does it imply complete exhaustion of the possible input combinations?
Context is: In Harel's charts (or UML state diagrams), state can have multiple transitions to mutually exclusive states, via the same trigger. What ensures that system ends up in a valid state, is a combination of guards (predicates) on those transitions, which should guarantee mutual exclusiveness of the guard outcome. I want to try to automatically test whether guards on a set of transitions are mutually exclusive. e.g. :
(def FSM
{:A {:B {:trigger :a :guard pos-int?}
:C {:trigger :a :guard neg-int?}}})
Current state is :A
. Some event triggers transition :a
. Machine has to switch to either :B
or :C
, but not both.
I want to make sure guards (`pos-int?`, and neg-int?
in this case) are mutually exclusive. Automatically. At compile time.Is it even possible? Or the best I can do is to just issue a "dude, make sure [:A :B :guard] and [:A :C :guard] are mutually-exclusive" warning?
there's no general solution to that, but you could write a test.check property that asserts it
if you have a meaningful generator for the state
or whatever it is that's getting passed to the guards
@gfredericks the complication with this, is the huge arity of the guards: they need to accept app-db, whole-machine, and event trigger with its args
where for machine
I may supply generator, but app-db
and trigger args
structure, contents, and specs are entirely up to user
sounds tough 🙂 you can validate at compile time of course
and for even as simple as a single string arg, exhausting 2 arbitrary predicates (e.g. with regexps inside) is doubtful, I think(?)
but for a turing-complete language you can't in general check if two predicates are mutually exclusive
regexes might be doable, depending on the details
not worth it though
just a theoretical curiosity
what if the predicate's source code is available? Is there something to, say, reverse-engineer things like (select-keys app-db [:foo :bar])
to reduce relevant input scope? Or at least to deduce, that guards, in fact, are orthogonal (which is useful too, but I forgot why just now)?
definitely for special cases
but the general case impossibility I mentioned earlier applies to source or compiled or whatever else
it'd be useful to cover at least some basic cases, because most of (UI) FSMs would actually use pretty basic guards
(There are at least 2 implementation options: 1) pseudo states, where you define a fork in the transition as a separate state, and just ask to for cond/case
guard there. 2) duplicate transitions with separate boolean
guards, which (implicitly) need to be mutually-exclusive.
I am exploring (2) at the moment, to make literal FSM definition less verbose.)
The solution to my s/cat
in s/cat
question yesterday was, of course, s/spec
:
(s/fdef none? :args (s/cat :ingredient (s/spec ::ingredient)))
if someone finds it useful, just released a version of https://github.com/jpmonettas/inspectable with clojure and clojuresript support, also with an enhanced browser that shows the spec together with a sample