#lang typed/syndicate/roles ;; Expected Output: #| balance = 0 balance = 5 balance = 0 JEEPERS know overdraft! balance = -1 balance = -2 no longer in overdraft balance = 8 |# (assertion-struct balance : Balance (v)) (message-struct deposit : Deposit (v)) ;; Internal Events (message-struct new-transaction : NewTransaction (old new)) (assertion-struct overdraft : Overdraft ()) (define-type-alias τc/external (U (Balance Int) (Message (Deposit Int)) (Observe ★/t))) (define-type-alias τc/internal (U (Message (NewTransaction Int Int)) (Overdraft) (Observe ★/t))) (define-type-alias τc (U τc/external τc/internal)) (run-ground-dataspace τc/external (spawn (begin (start-facet bank (field [account Int 0]) (assert (balance (ref account))) (on (message (deposit $v)) (define prev (ref account)) (set! account (+ v prev)) (realize! (new-transaction prev (ref account)))) (on (realize (new-transaction $old:Int $new:Int)) (when (and (negative? new) (not (negative? old))) (start-facet neg ;; (this print is to make sure only one of these facets is created) (printf "JEEPERS\n") (know (overdraft)) (on (realize (new-transaction _ $new:Int)) (when (not (negative? new)) (stop neg)))))) (during (know (overdraft)) (on-start (printf "know overdraft!\n")) (on-stop (printf "no longer in overdraft\n")))))) (spawn (start-facet obs (on (asserted (balance $v)) (printf "balance = ~a\n" v)))) (spawn (start-facet _ (on start (send! (deposit 5)) (spawn (start-facet _ (on start (send! (deposit -5)) (spawn (start-facet _ (on start (send! (deposit -1)) (spawn (start-facet _ (on start (send! (deposit -1)) (spawn (start-facet _ (on start (send! (deposit 10))))))))))))))))) )