simplest simulation example passes

This commit is contained in:
Sam Caldwell 2019-03-25 21:01:22 -04:00
parent 50448f41a7
commit 324557e8b5
1 changed files with 161 additions and 0 deletions

View File

@ -586,6 +586,167 @@
[_
#f])]))
;; D D -> Bool
;; subtyping lifted over event descriptions
(define (D<:? D1 D2)
(match (list D1 D2)
[(list (Know τ1) (Know τ2))
(<:? τ1 τ2)]
[(list (¬Know τ1) (¬Know τ2))
(<:? τ1 τ2)]
[_
#f]))
;; Role -> (Setof τ)
;; Compute the set of assertions the role contributes (on its own, not
;; considering parent assertions)
(define (role-assertions r)
(for/set ([ep (in-list (Role-eps r))])
(match ep
[(Shares τ)
τ]
[(Reacts evt _)
;; TODO - this doesn't put ⋆ in where an underlying pattern uses a capture
(match evt
[(Know τ)
(Observe τ)]
[(¬Know τ)
(Observe τ)])])))
;; an Equation is (equiv StateName StateName)
;;
;; a Goal is one of
;; - Equation
;; - (one-of (Setof StateMatch))
;;
;; a StateMatch is a (Setof Equation)
(struct equiv (a b) #:transparent)
(struct one-of (opts) #:transparent)
;; (Setof StateName) (Setof StateName) -> (Setof (Setof Equation))
;; Create potential state matchings
;; In each state matching, each element a of the first set (as) is
;; matched with an element b of bs, where each b has at least one state
;; matched with it.
(define (make-combinations as bs)
(define combos (make-combinations* as bs))
(define (all-bs? combo)
(for/and ([b (in-set bs)])
(for/or ([eqn (in-set combo)])
(match-define (equiv _ bb) eqn)
(equal? b bb))))
(for/set ([combo (in-set combos)]
#:when (all-bs? combo))
combo))
;; (Setof StateName) (Setof StateName) -> (Setof (Setof Equation))
;; Like make-combinations, but don't enforce that each b occurs at
;; least once in each combination
(define (make-combinations* as bs)
(cond
[(= (set-count as) 1)
(for*/set ([a (in-value (set-first as))]
[b (in-set bs)])
(set (equiv a b)))]
[else
(for*/fold ([agg (set)])
([a (in-set as)]
[b (in-set bs)])
(define combos (make-combinations* (set-remove as a) bs))
(define combos+
(for/set ([c (in-set combos)])
(set-add c (equiv a b))))
(set-union agg combos+))]))
;; Role Role -> Bool
;; determine if the first role acts suitably like the second role.
;; at all times, it is asserting a superset of the second's assertions
;; role1 ~ actual
;; role2 ~ spec
(define (simulates? role1 role2)
(match-define (role-graph st0-1 st#1) (compile role1))
(match-define (role-graph st0-2 st#2) (compile role2))
(define ft1 (make-facet-tree role1))
(define ft2 (make-facet-tree role2))
(define all-roles1 (enumerate-roles role1))
(define all-roles2 (enumerate-roles role2))
(define assertion#1
(for/hash ([role (in-list all-roles1)])
(values (Role-nm role)
(role-assertions role))))
(define assertion#2
(for/hash ([role (in-list all-roles2)])
(values (Role-nm role)
(role-assertions role))))
(define state-assertions1
(for/hash ([sn (in-hash-keys st#1)])
(values sn
(for/fold ([assertions (set)])
([facet-name (in-set sn)])
(set-union assertions (hash-ref assertion#1 facet-name (set)))))))
(define state-assertions2
(for/hash ([sn (in-hash-keys st#2)])
(values sn
(for/fold ([assertions (set)])
([facet-name (in-set sn)])
(set-union assertions (hash-ref assertion#2 facet-name (set)))))))
;; Goal (Setof Equation) -> Bool
(define (verify goal assumptions)
(let/ec return
(match goal
[(equiv sn1 sn2)
(when (set-member? assumptions goal)
(return #t))
(define assertions1 (hash-ref state-assertions1 sn1))
(define assertions2 (hash-ref state-assertions2 sn2))
(define superset?
(for/and ([assertion2 (in-set assertions2)])
(for/or ([assertion1 (in-set assertions1)])
(<:? assertion1 assertion2))))
(unless superset?
(return #f))
(define transitions1 (state-transitions (hash-ref st#1 sn1)))
(define transitions2 (state-transitions (hash-ref st#2 sn2)))
(define evts1 (hash-keys transitions1))
(define evts2 (hash-keys transitions2))
(define same-on-specified-events?
(for/and ([(D dests2) (in-hash transitions2)])
(define dests1
(for/fold ([agg (set)])
([(D1 dests) (in-hash transitions1)]
#:when (D<:? D D1))
(set-union agg dests)))
(unless dests1
(return #f))
(define combos (make-combinations dests1 dests2))
(for/or ([matching (in-set combos)])
(verify (one-of matching) (set-add assumptions goal)))))
(unless same-on-specified-events?
(return #f))
(define extra-evts
(for/set ([evt1 (in-list evts1)]
#:unless (for/or ([evt2 (in-list evts2)])
(D<:? evt2 evt1)))
evt1))
(define same-on-extra-evts?
(for*/and ([evt (in-set extra-evts)]
[dest (in-set (hash-ref transitions1 evt))])
(verify (equiv dest sn2)
(set-add assumptions goal))))
same-on-extra-evts?]
[(one-of matchings)
(for/or ([matching (in-set matchings)])
(for/and ([goal (in-set matching)])
(define hypotheses (set-remove matching goal))
(verify goal (set-union hypotheses assumptions))))])))
(verify (equiv st0-1 st0-2) (set)))
(module+ test
(test-case
"simplest simul"
(define r (Role 'x (list)))
(check-true (simulates? r r))))
;; ---------------------------------------------------------------------------
;; Visualization