#lang racket/base (require slideshow slideshow/play racket/class racket/math (prefix-in 2: 2htdp/image) (prefix-in i: mrlib/image-core) file/convertible racket/gui/base "color.rkt") (define bug-image (2:overlay (2:circle 8 "solid" "black") (2:radial-star 16 16 40 "solid" (2:color (send red red) (send red green) (send red blue))))) (define bug-bmp (read-bitmap (open-input-bytes (convert bug-image 'png-bytes)))) (define bug-w (send bug-bmp get-width)) (define bug-h (send bug-bmp get-width)) (provide lifecycle) (define arc-angles (list (list -0.03 (* pi 105/320)) (list (* pi .7) (* pi 1.07)) (list (* pi 1.3) (* pi 1.67)))) (define dots (list (list (+ (* pi 4/10) -.05) "misrenamed" "non-terminal") (list (* pi 10/10) "forgot" "typing" "rule") (list (+ (* pi 5/10) -.05) "lost a case" "in a helper" "function") (list (* pi -1/10) "added a" "case to" "wrong fn") (list (* pi -3/10) "swappped args") (list (+ (* pi 6/10) -.05) "misused the" "inductive hyp.") (list (* pi 12/10) "didn’t" "recheck a" "lemma") (list (* pi 11/10) "transcribed" "math wrong") (list (* pi -2/10) "forgot" "to recheck" "example"))) (define lifecycle-circle-color "black") (define extra-offset -0.09) (define (put-at main-pict angle new-pict delta-angle) (let ([mw2 (/ (pict-width main-pict) 2)] [mh2 (/ (pict-height main-pict) 2)]) (pin-over (pin-over main-pict (- (+ mw2 (* mw2 (cos angle))) (/ (pict-width new-pict) 2)) (- (+ mh2 (* mh2 (sin angle))) (/ (pict-height new-pict) 2)) new-pict) (+ mw2 (* mw2 (cos (+ angle delta-angle)))) (+ mh2 (* mh2 (sin (+ angle delta-angle)))) (colorize (pip-arrow-line (cos (+ (/ pi 2) (+ angle delta-angle extra-offset))) (sin (+ (/ pi 2) (+ angle delta-angle extra-offset))) 60) lifecycle-circle-color)))) (define (spaced-out a da b db c dc dots) (let ([init-angle (* pi -1/2)]) (cc-superimpose (put-at (put-at (put-at (linewidth 4 (colorize (linewidth 16 (arcs 300)) lifecycle-circle-color)) (+ init-angle (* pi 2/3) (* pi 2/3)) c dc) (+ init-angle (* pi 2/3)) b db) init-angle a da) (colorize (linewidth 16 (red-dots 300 dots)) red)))) (define (arcs diameter) (dc (λ (dc dx dy) (define brush (send dc get-brush)) (send dc set-brush "black" 'transparent) (for ([start-θ (in-list (map car arc-angles))] [end-θ (in-list (map cadr arc-angles))]) (send dc draw-arc dx dy diameter diameter start-θ end-θ)) (send dc set-brush brush)) diameter diameter)) (define (red-dots diameter dots) (dc (λ (dc dx dy) (define brush (send dc get-brush)) (send dc set-brush "black" 'transparent) (for ([θ (in-list (map car dots))]) (define size 16) (i:render-image bug-image dc (+ dx (* diameter 1/2) (* diameter 1/2 (cos θ)) (- (/ bug-w 2))) (+ dy (* diameter 1/2) (* diameter 1/2 (sin θ)) (- (/ bug-h 2))))) (send dc set-brush brush)) diameter diameter)) (define (white-around p) (cc-superimpose (colorize (filled-rectangle (+ 4 (pict-width p)) (+ 25 (pict-height p))) "white") p)) (define (lifecycle) (define (add-title p n) (ct-superimpose p (vl-append (blank 0 20) (cellophane (scale/improve-new-text (t "The Semantics Lifecycle") 2) (sqr (sqr n)))))) (play-n #:steps 20 (λ (n) (slide-pict (cc-superimpose (add-title (blank client-w client-h) n) (colorize lifecycle-placement2 "red") ((if (= n 1) ghost values) (scale items (- 1 (* n .95))))) (scale (nth-lifecycle 0) (+ (* n .8) .2)) lifecycle-placement lifecycle-placement2 n))) (for ([x (in-range 1 (+ (length dots) 1))]) (slide #:layout 'center (add-title (cc-superimpose (nth-lifecycle x) (blank client-w client-h)) 1)))) (define (nth-lifecycle x) (define-values (left-side right-side) (split-at (map (λ (line) (apply vc-append (map t (cdr line)))) dots) (round (/ (length dots) 2)))) (define-values (left-ghosts right-ghosts) (split-at (for/list ([y (in-range 0 (length dots))]) (if (<= x y) ghost values)) (round (/ (length dots) 2)))) (hc-append 20 (apply vc-append 30 (map (λ (f x) (f x)) left-ghosts left-side)) (scale/improve-new-text (inset (panorama (scale (spaced-out (white-around (vc-append (t "Prototype") (t "model"))) -0.4 (white-around (vc-append (t "Robust") (t "model"))) -0.35 (white-around (vc-append (t "Write-up"))) -0.25 (take dots x)) .4)) 0 0 6 6) 3.5) (apply vc-append 30 (map (λ (f x) (f x)) right-ghosts right-side)))) (define lifecycle-placement (scale (launder (ghost (nth-lifecycle 0))) .2)) (define lifecycle-placement2 (launder (ghost (nth-lifecycle 0)))) (define items (vl-append 40 (para "A niche for mechanized metatheory:") (hbl-append (blank 40 0) (item "lightweight: high level of expressiveness (think scripting language)")) (hbl-append (blank 40 0) (item "supports the entire semantics lifecycle:" (let ([p (ghost (t "y"))]) (refocus (lc-superimpose p lifecycle-placement) p))))))