4.7 GUI
(require redex/gui) | package: redex-gui-lib |
This section describes the GUI tools that Redex provides for exploring reduction sequences.
procedure
(traces reductions expr [ #:multiple? multiple? #:reduce reduce #:pred pred #:pp pp #:colors colors #:racket-colors? racket-colors? #:scheme-colors? scheme-colors? #:filter term-filter #:x-spacing x-spacing #:y-spacing y-spacing #:layout layout #:edge-labels? edge-labels? #:edge-label-font edge-label-font #:graph-pasteboard-mixin graph-pasteboard-mixin]) → void? reductions : (or/c reduction-relation? IO-judgment-form?) expr : (or/c any/c (listof any/c)) multiple? : boolean? = #f
reduce :
(-> reduction-relation? any/c (listof (list/c (union false/c string?) any/c))) = apply-reduction-relation/tag-with-names
pred :
(or/c (-> sexp any) (-> sexp term-node? any)) = (λ (x) #t)
pp :
(or/c (any -> string) (any output-port number (is-a?/c text%) -> void)) = default-pretty-printer
colors :
(listof (cons/c string? (and/c (listof (or/c string? (is-a?/c color%))) (λ (x) (<= 0 (length x) 6))))) = '() racket-colors? : boolean? = #t scheme-colors? : boolean? = racket-colors?
term-filter : (-> any/c (or/c #f string?) any/c) = (λ (x y) #t) x-spacing : real? = 15 y-spacing : real? = 15 layout : (-> (listof term-node?) void?) = void edge-labels? : boolean? = #t edge-label-font : (or/c #f (is-a?/c font%)) = #f
graph-pasteboard-mixin : (make-mixin-contract graph-pasteboard<%>) = values
The reduce function applies the reduction relation to the terms. By default, it is apply-reduction-relation/tag-with-names; it may be changed to only return a subset of the possible reductions, for example, but it must satisfy the same contract as apply-reduction-relation/tag-with-names.
If reductions is an IO-judgment-form?, then the judgment form is treated as a reduction relation. The initial input position is the given expr and the output position becomes the next input.
The pred function indicates if a term has a particular property. If it returns #f, the term is displayed with a pink background. If it returns a string or a color% object, the term is displayed with a background of that color (using the-color-database to map the string to a color). If it returns any other value, the term is displayed normally. If the pred function accepts two arguments, a term-node corresponding to the term is passed to the predicate. This lets the predicate function explore the (names of the) reductions that led to this term, using term-node-children, term-node-parents, and term-node-labels.
The pred function may be called more than once per node. In particular, it is called each time an edge is added to a node. The latest value returned determines the color.
The pp function is used to specially print expressions. It must either accept one or four arguments. If it accepts one argument, it will be passed each term and is expected to return a string to display the term.
If the pp function takes four arguments, it should render its first argument into the port (its second argument) with width at most given by the number (its third argument). The final argument is the text where the port is connected – characters written to the port go to the end of the editor. Use write-special to send snip% objects or 2htdp/image images (or other things that subscribe to file/convertible or pict/convert) directly to the editor.
The colors argument, if provided, specifies a list of reduction-name/color-list pairs. The traces gui will color arrows drawn because of the given reduction name with the given color instead of using the default color.
The cdr of each of the elements of colors is a list of colors, organized in pairs. The first two colors cover the colors of the line and the border around the arrow head, the first when the mouse is over a graph node that is connected to that arrow, and the second for when the mouse is not over that arrow. Similarly, the next colors are for the text drawn on the arrow and the last two are for the color that fills the arrow head. If fewer than six colors are specified, the specified colors are used and then defaults are filled in for the remaining colors.
The racket-colors? argument (along with scheme-colors?, retained for backward compatibility), controls the coloring of each window. When racket-colors? is #t (and scheme-colors? is #t too), traces colors the contents according to DrRacket’s Racket-mode color scheme; otherwise, traces uses a black color scheme.
The term-filter function is called each time a new node is about to be inserted into the graph. If the filter returns false, the node is not inserted into the graph.
The x-spacing and y-spacing arguments control the amount of space put between the snips in the default layout.
The layout argument is called (with all of the terms) when new terms are inserted into the window. In general, it is called after new terms are inserted in response to the user clicking on the reduce button, and after the initial set of terms is inserted. See also term-node-set-position!.
If edge-labels? is #t (the default), then edge labels are drawn; otherwise not.
The edge-label-font argument is used as the font on the edge labels. If #f is supplied, the dc<%> object’s default font is used.
The traces library uses an instance of the mrlib/graph library’s graph-pasteboard<%> interface to layout the graphs. Sometimes, overriding one of its methods can help give finer-grained control over the layout, so the graph-pasteboard-mixin is applied to the class before it is instantiated. Also note that all of the snips inserted into the editor by this library have a get-term-node method which returns the snip’s term-node?.
The Fix Layout button calls out to dot (a program that’s a part of graphviz) and uses its results to lay out the graph. While in the fixed-layout mode, the edges are now drawn. Click the button again to restore the edges.
(define/contract (unpair z) (-> exact-nonnegative-integer? (list/c exact-nonnegative-integer? exact-nonnegative-integer?)) (define i (integer-sqrt z)) (define i2 (* i i)) (cond [(< (- z i2) i) (list (- z i2) i)] [else (list i (- z i2 i))])) (define/contract (pair x y) (-> exact-nonnegative-integer? exact-nonnegative-integer? exact-nonnegative-integer?) (if (= x (max x y)) (+ (* x x) x y) (+ (* y y) x)))
(define-language L (n ::= natural)) (define red (reduction-relation L (--> (n_1 n_2) ,(unpair (+ 1 (pair (term n_1) (term n_2))))))) (traces red (term (0 0)))
(require 2htdp/image) (define/contract (two-stars point-count1 point-count2) (-> (>=/c 2) (>=/c 2) image?) (overlay (radial-star (+ 2 point-count1) 10 60 "solid" (make-color 255 0 255 150)) (radial-star (+ 2 point-count2) 10 60 "solid" "cornflowerblue")))
(traces red (term (0 0)) #:pp (λ (term port w txt) (write-special (two-stars (+ 2 (list-ref term 0)) (+ 2 (list-ref term 1))) port)))
procedure
(traces/ps reductions expr file [ #:multiple? multiple? #:reduce reduce #:pred pred #:pp pp #:colors colors #:filter term-filter #:layout layout #:x-spacing x-spacing #:y-spacing y-spacing #:edge-labels? edge-labels? #:edge-label-font edge-label-font #:graph-pasteboard-mixin graph-pasteboard-mixin] #:post-process post-process) → void? reductions : (or/c reduction-relation? IO-judgment-form?) expr : (or/c any/c (listof any/c)) file : (or/c path-string? path?) multiple? : boolean? = #f
reduce :
(-> reduction-relation? any/c (listof (list/c (union false/c string?) any/c))) = apply-reduction-relation/tag-with-names
pred :
(or/c (-> sexp any) (-> sexp term-node? any)) = (λ (x) #t)
pp :
(or/c (any -> string) (any output-port number (is-a?/c text%) -> void)) = default-pretty-printer
colors :
(listof (cons/c string? (and/c (listof (or/c string? (is-a?/c color%))) (λ (x) (<= 0 (length x) 6))))) = '()
term-filter : (-> any/c (or/c #f string?) any/c) = (λ (x y) #t) layout : (-> (listof term-node?) void?) = void x-spacing : number? = 15 y-spacing : number? = 15 edge-labels? : boolean? = #t edge-label-font : (or/c #f (is-a?/c font%)) = #f
graph-pasteboard-mixin : (make-mixin-contract graph-pasteboard<%>) = values post-process : (-> (is-a?/c graph-pasteboard<%>) any/c)
All of the arguments behave like the arguments to traces, with the exception of the post-process argument. It is called just before the PostScript is created with the graph pasteboard.
procedure
(stepper reductions t [ pp #:show-font-size-control? show-font-size-control?]) → void? reductions : (or/c reduction-relation? IO-judgment-form?) t : any/c
pp :
(or/c (any -> string) (any output-port number (is-a?/c text%) -> void)) = default-pretty-printer show-font-size-control? : any/c = #f
The pp argument is the same as to the traces function but is here for backwards compatibility only and should not be changed for most uses, but instead adjusted with pretty-print-parameters. Specifically, the highlighting shown in the stepper window can be wrong if default-pretty-printer does not print sufficiently similarly to how pretty-print prints (when adjusted by pretty-print-parameters’s behavior, of course).
If show-font-size-control? is a true value, then a slider with a font size choice is shown in the window.
Changed in version 1.1 of package redex-gui-lib: Added the show-font-size-control? argument.
procedure
(stepper/seed reductions seed [ pp #:show-font-size-control? show-font-size-control?]) → void? reductions : (or/c reduction-relation? IO-judgment-form?) seed : (cons/c any/c (listof any/c))
pp :
(or/c (any -> string) (any output-port number (is-a?/c text%) -> void)) = default-pretty-printer show-font-size-control? : any/c = #f
Changed in version 1.1 of package redex-gui-lib: Added the show-font-size-control? argument.
procedure
(show-derivations derivations [ #:pp pp #:racket-colors? racket-colors? #:init-derivation init-derivation]) → any derivations : (cons/c derivation? (listof derivation?))
pp :
(or/c (any -> string) (any output-port number (is-a?/c text%) -> void)) = default-pretty-printer racket-colors? : boolean? = #f init-derivation : exact-nonnegative-integer? = 0
The pp and racket-colors? arguments are like those to traces.
The initial derivation shown in the window is chosen by init-derivation, used as an index into derivations.
procedure
(derivation/ps derivation filename [ #:pp pp #:racket-colors? racket-colors?] #:post-process post-process) → void? derivation : derivation? filename : path-string?
pp :
(or/c (any -> string) (any output-port number (is-a?/c text%) -> void)) = default-pretty-printer racket-colors? : boolean? = #f post-process : (-> (is-a?/c pasteboard%) any)
procedure
(term-node-children tn) → (listof term-node?)
tn : term-node?
Note that this function does not return all terms that this term reduces to – only those that are currently in the graph.
procedure
(term-node-parents tn) → (listof term-node?)
tn : term-node?
procedure
(term-node-labels tn) → (listof (or/c false/c string?))
tn : term-node?
procedure
(term-node-set-color! tn color) → void?
tn : term-node? color : (or/c string? (is-a?/c color%) false/c)
procedure
(term-node-color tn) → (or/c string? (is-a?/c color%) false/c)
tn : term-node?
procedure
(term-node-set-red! tn red?) → void?
tn : term-node? red? : boolean?
procedure
(term-node-expr tn) → any
tn : term-node?
procedure
(term-node-set-position! tn x y) → void?
tn : term-node? x : (and/c real? positive?) y : (and/c real? positive?)
procedure
(term-node-x tn) → real?
tn : term-node?
procedure
(term-node-y tn) → real?
tn : term-node?
procedure
(term-node-width tn) → real?
tn : term-node?
procedure
(term-node-height tn) → real?
tn : term-node?
procedure
(term-node? v) → boolean?
v : any/c
parameter
(reduction-steps-cutoff cutoff) → void? cutoff : natural-number/c
parameter
(initial-font-size size) → void? size : number?
If its value is a number, then the number is used as the width for every term. If its value is a function, then the function is called with each term and the resulting number is used as the width.
parameter
(dark-pen-color) → (or/c string? (is-a?/c color<%>))
(dark-pen-color color) → void? color : (or/c string? (is-a?/c color<%>))
parameter
(dark-brush-color) → (or/c string? (is-a?/c color<%>))
(dark-brush-color color) → void? color : (or/c string? (is-a?/c color<%>))
parameter
(light-pen-color) → (or/c string? (is-a?/c color<%>))
(light-pen-color color) → void? color : (or/c string? (is-a?/c color<%>))
parameter
(light-brush-color) → (or/c string? (is-a?/c color<%>))
(light-brush-color color) → void? color : (or/c string? (is-a?/c color<%>))
parameter
(dark-text-color) → (or/c string? (is-a?/c color<%>))
(dark-text-color color) → void? color : (or/c string? (is-a?/c color<%>))
parameter
(light-text-color) → (or/c string? (is-a?/c color<%>))
(light-text-color color) → void? color : (or/c string? (is-a?/c color<%>))
The dark colors are used when the mouse is over one of the nodes that is connected to this edge. The light colors are used when it isn’t.
The pen colors control the color of the line. The brush colors control the color used to fill the arrowhead and the text colors control the color used to draw the label on the edge.
parameter
(pretty-print-parameters) → (-> (-> any/c) any/c)
(pretty-print-parameters f) → void? f : (-> (-> any/c) any/c)
Specifically, whenever default-pretty-printer prints something it calls f with a thunk that does the actual printing. Thus, f can adjust pretty-print’s parameters to adjust how printing happens.
procedure
(default-pretty-printer v port width text) → void?
v : any/c port : output-port? width : exact-nonnegative-integer? text : (is-a?/c text%)
This function uses the value of pretty-print-parameters to adjust how it prints.
It sets the pretty-print-columns parameter to width, and it sets pretty-print-size-hook and pretty-print-print-hook to print holes and the symbol 'hole to match the way they are input in a term expression.