|
14 | 14 | (dfa-universal alphabet) |
15 | 15 | (dfa-complement dfaA) |
16 | 16 | (dfa-complete dfaA) |
| 17 | + (dfa-complete! dfaA) |
17 | 18 | (dfa-intersection dfaA dfaB) |
18 | 19 | (dfa-less dfaA dfaB) |
19 | 20 | (dfa-states dfaA) |
20 | 21 | (dfa-minimize! dfaA) |
| 22 | + ;; Yes this is silly, but sometimes minimize is disabled |
| 23 | + ;; This forces it to be done |
| 24 | + (dfa-really-minimize! dfaA) |
21 | 25 | (dfa-remove-unreachable-states! dfaA) |
| 26 | + (dfa-remove-never-accepting-states! dfaA) |
22 | 27 | (dfa-rename-states dfaA) |
| 28 | + (dfa-for-one-symbol dfaA alphabet) |
| 29 | + (dfa-empty-language alphabet) |
23 | 30 | test-dfa |
24 | 31 | test-dfa1)) |
25 | 32 |
|
|
94 | 101 | ;; in the language. |
95 | 102 | ;; This will add in the necessary extra transitions, which will go |
96 | 103 | ;; to a new sink state |
97 | | -(define (dfa-complete dfaA) |
| 104 | +(define (%complete-transitions dfaA) |
98 | 105 | (define transitions (dfa-transition-list dfaA)) |
99 | 106 | (define sink-state (gensym "sink")) |
100 | 107 | ;; Check if is complete beforehand |
101 | | - (cond ((is-complete? dfaA) dfaA) |
| 108 | + (cond ((is-complete? dfaA) transitions) |
102 | 109 | (else (map (lambda (state) |
103 | 110 | (map (lambda (symbol) |
104 | 111 | (if (equal? (dfa-trans dfaA state symbol) #f) |
|
108 | 115 | transitions)))) |
109 | 116 | (dfa-alphabet dfaA))) |
110 | 117 | (cons sink-state (dfa-states dfaA))) |
111 | | - (dfa-rename-states |
112 | | - (dfa (dfa-start-state dfaA) |
113 | | - transitions |
114 | | - (dfa-final-states dfaA) |
115 | | - (dfa-alphabet dfaA)))))) |
| 118 | + transitions))) |
| 119 | + |
| 120 | +(define (dfa-complete! dfaA) |
| 121 | + (let ((trans (%complete-transitions dfaA))) |
| 122 | + (dfa-transition-list-set! dfaA trans))) |
| 123 | + |
| 124 | + |
| 125 | +(define (dfa-complete dfaA) |
| 126 | + (let ((trans (%complete-transitions dfaA))) |
| 127 | + (dfa-rename-states |
| 128 | + (dfa (dfa-start-state dfaA) |
| 129 | + trans |
| 130 | + (dfa-final-states dfaA) |
| 131 | + (dfa-alphabet dfaA))))) |
116 | 132 |
|
117 | 133 | (define (is-complete? dfaA) |
118 | 134 | (let loop ((states (dfa-states dfaA)) |
|
122 | 138 | ((equal? #f (dfa-trans dfaA (car states) (car alphabet))) #f) |
123 | 139 | (else (loop states (cdr alphabet)))))) |
124 | 140 |
|
125 | | -;; Returns the dfa for the universal language, eg. E* |
126 | | -(define (dfa-universal alphabet) |
127 | | - (let* ((q0 (gensym "q")) |
128 | | - (trans (map |
129 | | - (lambda (sym) |
130 | | - (list q0 sym q0)) |
131 | | - alphabet))) |
132 | | - (dfa |
133 | | - q0 |
134 | | - trans |
135 | | - (list q0) |
136 | | - alphabet))) |
137 | | - |
138 | | - |
| 141 | + |
139 | 142 | (define (dfa-complement dfaA) |
140 | 143 | (let* ((cdfa (dfa-complete dfaA)) |
141 | 144 | (states (dfa-states cdfa)) |
|
225 | 228 | new-transitions)))) |
226 | 229 |
|
227 | 230 | (define (dfa-minimize! dfa1) |
228 | | - (print "Minmize") |
| 231 | + #t |
229 | 232 | ;(dfa-remove-unreachable-states! dfa1) |
230 | 233 | ;(%dfa-minimize! dfa1) |
231 | 234 | ) |
232 | 235 |
|
| 236 | +(define (dfa-really-minimize! dfa1) |
| 237 | + (dfa-remove-unreachable-states! dfa1) |
| 238 | + (%dfa-minimize! dfa1)) |
| 239 | + |
| 240 | + |
233 | 241 | ;; Minimise a dfa |
234 | 242 | ;; Find the states that are equivalent and merge them |
235 | 243 | (define (%dfa-minimize! dfa1) |
236 | | - (print (length (dfa-states dfa1))) |
| 244 | + (print "Minimize") |
| 245 | + ;(print (length (dfa-states dfa1))) |
237 | 246 | (define changed #f) |
238 | 247 | (let loop1 ((states1 (dfa-states dfa1))) |
239 | 248 | (cond ((not (null? states1)) |
240 | 249 | (let loop2 ((states2 (dfa-states dfa1))) |
241 | | - (print " " (length states2)) |
| 250 | + ;(print " " (length states2)) |
242 | 251 | (cond ((not (null? states2)) |
243 | 252 | (let ((state1 (car states1)) |
244 | 253 | (state2 (car states2))) |
|
261 | 270 | ;; next state. They must also both be either final or not |
262 | 271 | ;; final. |
263 | 272 | (define (equivalent-states? dfa1 q1 q2) |
264 | | - (if (not (equal? (member q1 (dfa-final-states dfa1)) |
265 | | - (member q2 (dfa-final-states dfa1)))) |
| 273 | + (if (not (equal? (member? q1 (dfa-final-states dfa1)) |
| 274 | + (member? q2 (dfa-final-states dfa1)))) |
266 | 275 | #f |
| 276 | + |
267 | 277 | (let loop ((symbols (dfa-alphabet dfa1))) |
268 | 278 | (cond ((null? symbols) |
269 | 279 | #t) |
|
362 | 372 | new-trans |
363 | 373 | new-final |
364 | 374 | (dfa-alphabet dfa1))))) |
| 375 | + |
| 376 | +(define (dfa-remove-never-accepting-states! dfa1) |
| 377 | + (let loop ((accepting (dfa-final-states dfa1))) |
| 378 | + ;; remove the accepting states |
| 379 | + ;; new accepting states are the states which can go to the |
| 380 | + ;; accepting states |
| 381 | + (let* ((remaining-states (list-less (dfa-states dfa1) accepting)) |
| 382 | + (can-accept |
| 383 | + (find-if-all |
| 384 | + (lambda (state) |
| 385 | + ;; they accept if there is a transition from them to an |
| 386 | + ;; accepting state |
| 387 | + (find-if (lambda (trans) |
| 388 | + (and (equal? (first trans) state) |
| 389 | + (member (third trans) |
| 390 | + accepting))) |
| 391 | + (dfa-transition-list dfa1))) |
| 392 | + remaining-states))) |
| 393 | + (cond ((not (null? can-accept)) |
| 394 | + (loop (append accepting can-accept))) |
| 395 | + (else |
| 396 | + (let* ((non-accept (list-less (dfa-states dfa1) accepting)) |
| 397 | + (new-trans (list-remove-if |
| 398 | + (lambda (trans) |
| 399 | + (or (member (first trans) non-accept) |
| 400 | + (member (third trans) non-accept))) |
| 401 | + (dfa-transition-list dfa1)))) |
| 402 | + (print "Will never accept " non-accept) |
| 403 | + (dfa-transition-list-set! dfa1 new-trans))))))) |
| 404 | + |
| 405 | + |
| 406 | +;; Returns the dfa for the universal language, eg. E* |
| 407 | +(define (dfa-universal alphabet) |
| 408 | + (let* ((q0 (gensym "q")) |
| 409 | + (trans (map |
| 410 | + (lambda (sym) |
| 411 | + (list q0 sym q0)) |
| 412 | + alphabet))) |
| 413 | + (dfa |
| 414 | + q0 |
| 415 | + trans |
| 416 | + (list q0) |
| 417 | + alphabet))) |
| 418 | + |
| 419 | +(define (dfa-for-one-symbol sym alphabet) |
| 420 | + (let ((start (gensym "q")) |
| 421 | + (final (gensym "q"))) |
| 422 | + (dfa start |
| 423 | + (list (list start sym final)) |
| 424 | + (list final) |
| 425 | + alphabet))) |
| 426 | + |
365 | 427 |
|
| 428 | +(define (dfa-empty-language alphabet) |
| 429 | + (let ((start (gensym "q"))) |
| 430 | + (dfa |
| 431 | + start |
| 432 | + (map (lambda (a) |
| 433 | + (list start a start)) |
| 434 | + alphabet) |
| 435 | + (list) |
| 436 | + alphabet))) |
366 | 437 |
|
367 | 438 | (define test-dfa |
368 | 439 | (dfa |
|
0 commit comments