From d5f032965252dfa4ddc3f5e363577a7cf0195979 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 11 Nov 2026 10:19:32 +0000 Subject: [PATCH 1/2] Run the automata chapter's Racket examples at render time pairs-table, step, run, accepts? and the numeral checker were plain fences, and the runs and #t and #f results were typed in the prose (#131). They are now {racket} chunks, the typed results are chunk output, and the solution to exr-racket-step runs the lookup one step at a time, as its reasoning does. Part of #131. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01FWgYrEUFVHj2qKjKncHg77 --- .../automata/_racket-numeral_exm.qmd | 12 ++++++----- .../_subfiles/automata/_racket-run_exm.qmd | 20 +++++++++++++------ .../_subfiles/automata/_racket-step_exr.qmd | 3 ++- .../_subfiles/automata/_racket-step_sol.qmd | 9 +++++++++ chapters/automata.qmd | 2 ++ 5 files changed, 34 insertions(+), 12 deletions(-) diff --git a/chapters/_subfiles/automata/_racket-numeral_exm.qmd b/chapters/_subfiles/automata/_racket-numeral_exm.qmd index 2c6c84818..3d88a1d14 100644 --- a/chapters/_subfiles/automata/_racket-numeral_exm.qmd +++ b/chapters/_subfiles/automata/_racket-numeral_exm.qmd @@ -4,7 +4,8 @@ In the form of @exr-racket-step, the DFA of @sol-decimal-numeral is the table below, with the symbol `'digit` for the input $\mathtt{d}$ and the symbol `'point` for the input $\mathtt{.}$: -```racket +```{racket} +#| code-fold: false (define numeral-table '((n0 (digit n1) (point n4)) (n1 (digit n1) (point n2)) @@ -16,7 +17,8 @@ with the symbol `'digit` for the input $\mathtt{d}$ and the symbol `'point` for To check real text, `classify` turns each character into an input, and `numeral?` runs the DFA with `accepts?` from @exm-racket-run: -```racket +```{racket} +#| code-fold: false (define (classify c) (cond [(char<=? #\0 c #\9) 'digit] [(char=? c #\.) 'point] @@ -35,13 +37,13 @@ and `numeral?` runs the DFA with `accepts?` from @exm-racket-run: A character that is neither a digit nor a point is classified `'other`, which is not an input of the DFA, so `numeral?` returns `#f` for any text that contains one, without running the DFA. -Then +Applied to eight strings, `numeral?` returns: -```racket +```{racket} +#| code-fold: false (map numeral? '("3.14" "2026" "7." ".5" "1.2.3" "d.d" "-3" "\u00BD")) ``` -returns `'(#t #t #f #f #f #f #f #f)`: `"3.14"` and `"2026"` are numerals, and the others are not. The letter d in `"d.d"` is classified `'other`, not `'digit`, and so is the one character of `"\u00BD"`, the fraction one half, diff --git a/chapters/_subfiles/automata/_racket-run_exm.qmd b/chapters/_subfiles/automata/_racket-run_exm.qmd index bae1f6776..cc3597038 100644 --- a/chapters/_subfiles/automata/_racket-run_exm.qmd +++ b/chapters/_subfiles/automata/_racket-run_exm.qmd @@ -5,7 +5,8 @@ With `step` as in @exr-racket-step, `run` returns the run (@def-run) from a state `s` on a list `xs` of inputs, and `accepts?` says whether a DFA accepts (@def-accept) the string whose inputs are the list `xs`: -```racket +```{racket} +#| code-fold: false (define (run table s xs) (if (empty? xs) (list s) @@ -21,11 +22,18 @@ and `accepts?` says whether a DFA accepts (@def-accept) the string whose inputs - `(member x L)` is `#f` if `x` is not in the list `L`, and a list that is not `#f` if it is. - `(string->list w)` is the list of the characters of the string `w`. -`(run pairs-table 'q0 (string->list "abab"))` returns `'(q0 q1 q0 q1 q0)`, -and `(run pairs-table 'q0 (string->list "aab"))` returns `'(q0 q1 q2 q2)`, the runs of @exm-pairs-accept. -`(accepts? pairs-table 'q0 '(q0) (string->list "abab"))` returns `#t`, -`(accepts? pairs-table 'q0 '(q0) (string->list "ba"))` returns `#f`, -and `(accepts? pairs-table 'q0 '(q0) (string->list ""))` returns `#t`, since $A$ accepts $\lambda$. +`run` returns the runs of @exm-pairs-accept on `"abab"` and `"aab"`. +$A$ accepts `"abab"` and the empty string $\lambda$, but not `"ba"`: + +```{racket} +#| code-fold: false +(run pairs-table 'q0 (string->list "abab")) +(run pairs-table 'q0 (string->list "aab")) +(accepts? pairs-table 'q0 '(q0) (string->list "abab")) +(accepts? pairs-table 'q0 '(q0) (string->list "ba")) +(accepts? pairs-table 'q0 '(q0) (string->list "")) +``` + Let $w$ be the string whose symbols are the elements of `xs`, in order. `run` reads the first symbol of $w$ first, as @def-run does, so by @thm-run-last the last state of `(run table s xs)` is $\delta^*(s, w)$. diff --git a/chapters/_subfiles/automata/_racket-step_exr.qmd b/chapters/_subfiles/automata/_racket-step_exr.qmd index d2270640a..e89bc962c 100644 --- a/chapters/_subfiles/automata/_racket-step_exr.qmd +++ b/chapters/_subfiles/automata/_racket-step_exr.qmd @@ -4,7 +4,8 @@ In Racket, the table of the DFA $A$ (@exm-pairs-table) can be stored as a list with one list for each state, which starts with the state and goes on with a list `(x t)` for each input `x`, where `t` is the state that `x` leads to: -```racket +```{racket} +#| code-fold: false (define pairs-table '((q0 (#\a q1) (#\b q0)) (q1 (#\a q2) (#\b q0)) diff --git a/chapters/_subfiles/automata/_racket-step_sol.qmd b/chapters/_subfiles/automata/_racket-step_sol.qmd index aba3e467f..67106cfa0 100644 --- a/chapters/_subfiles/automata/_racket-step_sol.qmd +++ b/chapters/_subfiles/automata/_racket-step_sol.qmd @@ -5,4 +5,13 @@ and its rest is `'((#\a q2) (#\b q0))`. `(assoc #\b ...)` finds `'(#\b q0)` in that list, and its second element is `'q0`. So `(step pairs-table 'q1 #\b)` returns `'q0`, which is $\delta(q_1, \mathtt{b})$ (@exm-pairs-dfa). +Racket returns the same values: + +```{racket} +#| code-fold: false +(assoc 'q1 pairs-table) +(rest (assoc 'q1 pairs-table)) +(step pairs-table 'q1 #\b) +``` + ::: diff --git a/chapters/automata.qmd b/chapters/automata.qmd index e1cca0313..49c2a3efd 100644 --- a/chapters/automata.qmd +++ b/chapters/automata.qmd @@ -13,6 +13,8 @@ format: {{< include ../latex-macros/macros.qmd >}} +{{< include _subfiles/_racket-setup.qmd >}} + ::: {.callout-note appearance='simple' collapse=true} ## Source From 9411a494c17a49c72d7746db34204f3867dd937e Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 12 Nov 2026 09:17:58 +0000 Subject: [PATCH 2/2] Give the run example's two claims a chunk each, in the prose's order One chunk held the two runs and the three acceptance tests, introduced by the sentence about acceptance alone, and it tested "ba" before the empty string while the sentence named them the other way round. Split it so each sentence introduces its own calls, and test the strings in the order the sentence names them. Raised by the cross-harness read of #146. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01FWgYrEUFVHj2qKjKncHg77 --- chapters/_subfiles/automata/_racket-run_exm.qmd | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/chapters/_subfiles/automata/_racket-run_exm.qmd b/chapters/_subfiles/automata/_racket-run_exm.qmd index cc3597038..5a8ac48e6 100644 --- a/chapters/_subfiles/automata/_racket-run_exm.qmd +++ b/chapters/_subfiles/automata/_racket-run_exm.qmd @@ -22,16 +22,21 @@ and `accepts?` says whether a DFA accepts (@def-accept) the string whose inputs - `(member x L)` is `#f` if `x` is not in the list `L`, and a list that is not `#f` if it is. - `(string->list w)` is the list of the characters of the string `w`. -`run` returns the runs of @exm-pairs-accept on `"abab"` and `"aab"`. -$A$ accepts `"abab"` and the empty string $\lambda$, but not `"ba"`: +`run` returns the runs of @exm-pairs-accept on `"abab"` and `"aab"`: ```{racket} #| code-fold: false (run pairs-table 'q0 (string->list "abab")) (run pairs-table 'q0 (string->list "aab")) +``` + +$A$ accepts `"abab"` and the empty string $\lambda$, but not `"ba"`: + +```{racket} +#| code-fold: false (accepts? pairs-table 'q0 '(q0) (string->list "abab")) -(accepts? pairs-table 'q0 '(q0) (string->list "ba")) (accepts? pairs-table 'q0 '(q0) (string->list "")) +(accepts? pairs-table 'q0 '(q0) (string->list "ba")) ``` Let $w$ be the string whose symbols are the elements of `xs`, in order.