; SILex - Scheme Implementation of Lex
; Copyright (C) 2001 Danny Dube'
;
; This program is free software; you can redistribute it and/or
; modify it under the terms of the GNU General Public License
; as published by the Free Software Foundation; either version 2
; of the License, or (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program; if not, write to the Free Software
; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
; Recoupement de deux arcs
(define n2d-2arcs
(lambda (arc1 arc2)
(let* ((class1 (car arc1))
(ss1 (cdr arc1))
(class2 (car arc2))
(ss2 (cdr arc2))
(result (class-sep class1 class2))
(classl (vector-ref result 0))
(classc (vector-ref result 1))
(classr (vector-ref result 2))
(ssl ss1)
(ssc (ss-union ss1 ss2))
(ssr ss2))
(vector (if (or (null? classl) (null? ssl)) #f (cons classl ssl))
(if (or (null? classc) (null? ssc)) #f (cons classc ssc))
(if (or (null? classr) (null? ssr)) #f (cons classr ssr))))))
; Insertion d'un arc dans une liste d'arcs a classes distinctes
(define n2d-insert-arc
(lambda (new-arc arcs)
(if (null? arcs)
(list new-arc)
(let* ((arc (car arcs))
(others (cdr arcs))
(result (n2d-2arcs new-arc arc))
(arcl (vector-ref result 0))
(arcc (vector-ref result 1))
(arcr (vector-ref result 2))
(list-arcc (if arcc (list arcc) '()))
(list-arcr (if arcr (list arcr) '())))
(if arcl
(append list-arcc list-arcr (n2d-insert-arc arcl others))
(append list-arcc list-arcr others))))))
; Regroupement des arcs qui aboutissent au meme sous-ensemble d'etats
(define n2d-factorize-arcs
(lambda (arcs)
(if (null? arcs)
'()
(let* ((arc (car arcs))
(arc-ss (cdr arc))
(others-no-fact (cdr arcs))
(others (n2d-factorize-arcs others-no-fact)))
(let loop ((o others))
(if (null? o)
(list arc)
(let* ((o1 (car o))
(o1-ss (cdr o1)))
(if (equal? o1-ss arc-ss)
(let* ((arc-class (car arc))
(o1-class (car o1))
(new-class (class-union arc-class o1-class))
(new-arc (cons new-class arc-ss)))
(cons new-arc (cdr o)))
(cons o1 (loop (cdr o)))))))))))
; Transformer une liste d'arcs quelconques en des arcs a classes distinctes
(define n2d-distinguish-arcs
(lambda (arcs)
(let loop ((arcs arcs) (n-arcs '()))
(if (null? arcs)
n-arcs
(loop (cdr arcs) (n2d-insert-arc (car arcs) n-arcs))))))
; Transformer une liste d'arcs quelconques en des arcs a classes et a
; destinations distinctes
(define n2d-normalize-arcs
(lambda (arcs)
(n2d-factorize-arcs (n2d-distinguish-arcs arcs))))
; Factoriser des arcs a destination unique (~deterministes)
(define n2d-factorize-darcs
(lambda (arcs)
(if (null? arcs)
'()
(let* ((arc (car arcs))
(arc-end (cdr arc))
(other-arcs (cdr arcs))
(farcs (n2d-factorize-darcs other-arcs)))
(let loop ((farcs farcs))
(if (null? farcs)
(list arc)
(let* ((farc (car farcs))
(farc-end (cdr farc)))
(if (= farc-end arc-end)
(let* ((arc-class (car arc))
(farc-class (car farc))
(new-class (class-union farc-class arc-class))
(new-arc (cons new-class arc-end)))
(cons new-arc (cdr farcs)))
(cons farc (loop (cdr farcs)))))))))))
; Normaliser un vecteur de listes d'arcs
(define n2d-normalize-arcs-v
(lambda (arcs-v)
(let* ((nbnodes (vector-length arcs-v))
(new-v (make-vector nbnodes)))
(let loop ((n 0))
(if (= n nbnodes)
new-v
(begin
(vector-set! new-v n (n2d-normalize-arcs (vector-ref arcs-v n)))
(loop (+ n 1))))))))
; Inserer un arc dans une liste d'arcs a classes distinctes en separant
; les arcs contenant une partie de la classe du nouvel arc des autres arcs
; Retourne: (oui . non)
(define n2d-ins-sep-arc
(lambda (new-arc arcs)
(if (null? arcs)
(cons (list new-arc) '())
(let* ((arc (car arcs))
(others (cdr arcs))
(result (n2d-2arcs new-arc arc))
(arcl (vector-ref result 0))
(arcc (vector-ref result 1))
(arcr (vector-ref result 2))
(l-arcc (if arcc (list arcc) '()))
(l-arcr (if arcr (list arcr) '()))
(result (if arcl
(n2d-ins-sep-arc arcl others)
(cons '() others)))
(oui-arcs (car result))
(non-arcs (cdr result)))
(cons (append l-arcc oui-arcs) (append l-arcr non-arcs))))))
; Combiner deux listes d'arcs a classes distinctes
; Ne tente pas de combiner les arcs qui ont nec. des classes disjointes
; Conjecture: les arcs crees ont leurs classes disjointes
; Note: envisager de rajouter un "n2d-factorize-arcs" !!!!!!!!!!!!
(define n2d-combine-arcs
(lambda (arcs1 arcs2)
(let loop ((arcs1 arcs1) (arcs2 arcs2) (dist-arcs2 '()))
(if (null? arcs1)
(append arcs2 dist-arcs2)
(let* ((arc (car arcs1))
(result (n2d-ins-sep-arc arc arcs2))
(oui-arcs (car result))
(non-arcs (cdr result)))
(loop (cdr arcs1) non-arcs (append oui-arcs dist-arcs2)))))))
; ;
; ; Section temporaire: vieille facon de generer le dfa
; ; Dictionnaire d'etat det. Recherche lineaire. Creation naive
; ; des arcs d'un ensemble d'etats.
; ;
;
; ; Quelques variables globales
; (define n2d-state-dict '#(#f))
; (define n2d-state-len 1)
; (define n2d-state-count 0)
;
; ; Fonctions de gestion des entrees du dictionnaire
; (define make-dentry (lambda (ss) (vector ss #f #f)))
;
; (define get-dentry-ss (lambda (dentry) (vector-ref dentry 0)))
; (define get-dentry-darcs (lambda (dentry) (vector-ref dentry 1)))
; (define get-dentry-acc (lambda (dentry) (vector-ref dentry 2)))
;
; (define set-dentry-darcs (lambda (dentry arcs) (vector-set! dentry 1 arcs)))
; (define set-dentry-acc (lambda (dentry acc) (vector-set! dentry 2 acc)))
;
; ; Initialisation des variables globales
; (define n2d-init-glob-vars
; (lambda ()
; (set! n2d-state-dict (vector #f))
; (set! n2d-state-len 1)
; (set! n2d-state-count 0)))
;
; ; Extension du dictionnaire
; (define n2d-extend-dict
; (lambda ()
; (let* ((new-len (* 2 n2d-state-len))
; (v (make-vector new-len #f)))
; (let loop ((n 0))
; (if (= n n2d-state-count)
; (begin
; (set! n2d-state-dict v)
; (set! n2d-state-len new-len))
; (begin
; (vector-set! v n (vector-ref n2d-state-dict n))
; (loop (+ n 1))))))))
;
; ; Ajout d'un etat
; (define n2d-add-state
; (lambda (ss)
; (let* ((s n2d-state-count)
; (dentry (make-dentry ss)))
; (if (= n2d-state-count n2d-state-len)
; (n2d-extend-dict))
; (vector-set! n2d-state-dict s dentry)
; (set! n2d-state-count (+ n2d-state-count 1))
; s)))
;
; ; Recherche d'un etat
; (define n2d-search-state
; (lambda (ss)
; (let loop ((n 0))
; (if (= n n2d-state-count)
; (n2d-add-state ss)
; (let* ((dentry (vector-ref n2d-state-dict n))
; (dentry-ss (get-dentry-ss dentry)))
; (if (equal? dentry-ss ss)
; n
; (loop (+ n 1))))))))
;
; ; Transformer un arc non-det. en un arc det.
; (define n2d-translate-arc
; (lambda (arc)
; (let* ((class (car arc))
; (ss (cdr arc))
; (s (n2d-search-state ss)))
; (cons class s))))
;
; ; Transformer une liste d'arcs non-det. en ...
; (define n2d-translate-arcs
; (lambda (arcs)
; (map n2d-translate-arc arcs)))
;
; ; Trouver le minimum de deux acceptants
; (define n2d-acc-min2
; (let ((acc-min (lambda (rule1 rule2)
; (cond ((not rule1)
; rule2)
; ((not rule2)
; rule1)
; (else
; (min rule1 rule2))))))
; (lambda (acc1 acc2)
; (cons (acc-min (car acc1) (car acc2))
; (acc-min (cdr acc1) (cdr acc2))))))
;
; ; Trouver le minimum de plusieurs acceptants
; (define n2d-acc-mins
; (lambda (accs)
; (if (null? accs)
; (cons #f #f)
; (n2d-acc-min2 (car accs) (n2d-acc-mins (cdr accs))))))
;
; ; Fabriquer les vecteurs d'arcs et d'acceptance
; (define n2d-extract-vs
; (lambda ()
; (let* ((arcs-v (make-vector n2d-state-count))
; (acc-v (make-vector n2d-state-count)))
; (let loop ((n 0))
; (if (= n n2d-state-count)
; (cons arcs-v acc-v)
; (begin
; (vector-set! arcs-v n (get-dentry-darcs
; (vector-ref n2d-state-dict n)))
; (vector-set! acc-v n (get-dentry-acc
; (vector-ref n2d-state-dict n)))
; (loop (+ n 1))))))))
;
; ; Effectuer la transformation de l'automate de non-det. a det.
; (define nfa2dfa
; (lambda (nl-start no-nl-start arcs-v acc-v)
; (n2d-init-glob-vars)
; (let* ((nl-d (n2d-search-state nl-start))
; (no-nl-d (n2d-search-state no-nl-start)))
; (let loop ((n 0))
; (if (< n n2d-state-count)
; (let* ((dentry (vector-ref n2d-state-dict n))
; (ss (get-dentry-ss dentry))
; (arcss (map (lambda (s) (vector-ref arcs-v s)) ss))
; (arcs (apply append arcss))
; (dist-arcs (n2d-distinguish-arcs arcs))
; (darcs (n2d-translate-arcs dist-arcs))
; (fact-darcs (n2d-factorize-darcs darcs))
; (accs (map (lambda (s) (vector-ref acc-v s)) ss))
; (acc (n2d-acc-mins accs)))
; (set-dentry-darcs dentry fact-darcs)
; (set-dentry-acc dentry acc)
; (loop (+ n 1)))))
; (let* ((result (n2d-extract-vs))
; (new-arcs-v (car result))
; (new-acc-v (cdr result)))
; (n2d-init-glob-vars)
; (list nl-d no-nl-d new-arcs-v new-acc-v)))))
; ;
; ; Section temporaire: vieille facon de generer le dfa
; ; Dictionnaire d'etat det. Recherche lineaire. Creation des
; ; arcs d'un ensemble d'etats en combinant des ensembles d'arcs a
; ; classes distinctes.
; ;
;
; ; Quelques variables globales
; (define n2d-state-dict '#(#f))
; (define n2d-state-len 1)
; (define n2d-state-count 0)
;
; ; Fonctions de gestion des entrees du dictionnaire
; (define make-dentry (lambda (ss) (vector ss #f #f)))
;
; (define get-dentry-ss (lambda (dentry) (vector-ref dentry 0)))
; (define get-dentry-darcs (lambda (dentry) (vector-ref dentry 1)))
; (define get-dentry-acc (lambda (dentry) (vector-ref dentry 2)))
;
; (define set-dentry-darcs (lambda (dentry arcs) (vector-set! dentry 1 arcs)))
; (define set-dentry-acc (lambda (dentry acc) (vector-set! dentry 2 acc)))
;
; ; Initialisation des variables globales
; (define n2d-init-glob-vars
; (lambda ()
; (set! n2d-state-dict (vector #f))
; (set! n2d-state-len 1)
; (set! n2d-state-count 0)))
;
; ; Extension du dictionnaire
; (define n2d-extend-dict
; (lambda ()
; (let* ((new-len (* 2 n2d-state-len))
; (v (make-vector new-len #f)))
; (let loop ((n 0))
; (if (= n n2d-state-count)
; (begin
; (set! n2d-state-dict v)
; (set! n2d-state-len new-len))
; (begin
; (vector-set! v n (vector-ref n2d-state-dict n))
; (loop (+ n 1))))))))
;
; ; Ajout d'un etat
; (define n2d-add-state
; (lambda (ss)
; (let* ((s n2d-state-count)
; (dentry (make-dentry ss)))
; (if (= n2d-state-count n2d-state-len)
; (n2d-extend-dict))
; (vector-set! n2d-state-dict s dentry)
; (set! n2d-state-count (+ n2d-state-count 1))
; s)))
;
; ; Recherche d'un etat
; (define n2d-search-state
; (lambda (ss)
; (let loop ((n 0))
; (if (= n n2d-state-count)
; (n2d-add-state ss)
; (let* ((dentry (vector-ref n2d-state-dict n))
; (dentry-ss (get-dentry-ss dentry)))
; (if (equal? dentry-ss ss)
; n
; (loop (+ n 1))))))))
;
; ; Combiner des listes d'arcs a classes dictinctes
; (define n2d-combine-arcs-l
; (lambda (arcs-l)
; (if (null? arcs-l)
; '()
; (let* ((arcs (car arcs-l))
; (other-arcs-l (cdr arcs-l))
; (other-arcs (n2d-combine-arcs-l other-arcs-l)))
; (n2d-combine-arcs arcs other-arcs)))))
;
; ; Transformer un arc non-det. en un arc det.
; (define n2d-translate-arc
; (lambda (arc)
; (let* ((class (car arc))
; (ss (cdr arc))
; (s (n2d-search-state ss)))
; (cons class s))))
;
; ; Transformer une liste d'arcs non-det. en ...
; (define n2d-translate-arcs
; (lambda (arcs)
; (map n2d-translate-arc arcs)))
;
; ; Trouver le minimum de deux acceptants
; (define n2d-acc-min2
; (let ((acc-min (lambda (rule1 rule2)
; (cond ((not rule1)
; rule2)
; ((not rule2)
; rule1)
; (else
; (min rule1 rule2))))))
; (lambda (acc1 acc2)
; (cons (acc-min (car acc1) (car acc2))
; (acc-min (cdr acc1) (cdr acc2))))))
;
; ; Trouver le minimum de plusieurs acceptants
; (define n2d-acc-mins
; (lambda (accs)
; (if (null? accs)
; (cons #f #f)
; (n2d-acc-min2 (car accs) (n2d-acc-mins (cdr accs))))))
;
; ; Fabriquer les vecteurs d'arcs et d'acceptance
; (define n2d-extract-vs
; (lambda ()
; (let* ((arcs-v (make-vector n2d-state-count))
; (acc-v (make-vector n2d-state-count)))
; (let loop ((n 0))
; (if (= n n2d-state-count)
; (cons arcs-v acc-v)
; (begin
; (vector-set! arcs-v n (get-dentry-darcs
; (vector-ref n2d-state-dict n)))
; (vector-set! acc-v n (get-dentry-acc
; (vector-ref n2d-state-dict n)))
; (loop (+ n 1))))))))
;
; ; Effectuer la transformation de l'automate de non-det. a det.
; (define nfa2dfa
; (lambda (nl-start no-nl-start arcs-v acc-v)
; (n2d-init-glob-vars)
; (let* ((nl-d (n2d-search-state nl-start))
; (no-nl-d (n2d-search-state no-nl-start))
; (norm-arcs-v (n2d-normalize-arcs-v arcs-v)))
; (let loop ((n 0))
; (if (< n n2d-state-count)
; (let* ((dentry (vector-ref n2d-state-dict n))
; (ss (get-dentry-ss dentry))
; (arcs-l (map (lambda (s) (vector-ref norm-arcs-v s)) ss))
; (arcs (n2d-combine-arcs-l arcs-l))
; (darcs (n2d-translate-arcs arcs))
; (fact-darcs (n2d-factorize-darcs darcs))
; (accs (map (lambda (s) (vector-ref acc-v s)) ss))
; (acc (n2d-acc-mins accs)))
; (set-dentry-darcs dentry fact-darcs)
; (set-dentry-acc dentry acc)
; (loop (+ n 1)))))
; (let* ((result (n2d-extract-vs))
; (new-arcs-v (car result))
; (new-acc-v (cdr result)))
; (n2d-init-glob-vars)
; (list nl-d no-nl-d new-arcs-v new-acc-v)))))
; ;
; ; Section temporaire: vieille facon de generer le dfa
; ; Dictionnaire d'etat det. Arbre de recherche. Creation des
; ; arcs d'un ensemble d'etats en combinant des ensembles d'arcs a
; ; classes distinctes.
; ;
;
; ; Quelques variables globales
; (define n2d-state-dict '#(#f))
; (define n2d-state-len 1)
; (define n2d-state-count 0)
; (define n2d-state-tree '#(#f ()))
;
; ; Fonctions de gestion des entrees du dictionnaire
; (define make-dentry (lambda (ss) (vector ss #f #f)))
;
; (define get-dentry-ss (lambda (dentry) (vector-ref dentry 0)))
; (define get-dentry-darcs (lambda (dentry) (vector-ref dentry 1)))
; (define get-dentry-acc (lambda (dentry) (vector-ref dentry 2)))
;
; (define set-dentry-darcs (lambda (dentry arcs) (vector-set! dentry 1 arcs)))
; (define set-dentry-acc (lambda (dentry acc) (vector-set! dentry 2 acc)))
;
; ; Fonctions de gestion de l'arbre de recherche
; (define make-snode (lambda () (vector #f '())))
;
; (define get-snode-dstate (lambda (snode) (vector-ref snode 0)))
; (define get-snode-children (lambda (snode) (vector-ref snode 1)))
;
; (define set-snode-dstate
; (lambda (snode dstate) (vector-set! snode 0 dstate)))
; (define set-snode-children
; (lambda (snode children) (vector-set! snode 1 children)))
;
; ; Initialisation des variables globales
; (define n2d-init-glob-vars
; (lambda ()
; (set! n2d-state-dict (vector #f))
; (set! n2d-state-len 1)
; (set! n2d-state-count 0)
; (set! n2d-state-tree (make-snode))))
;
; ; Extension du dictionnaire
; (define n2d-extend-dict
; (lambda ()
; (let* ((new-len (* 2 n2d-state-len))
; (v (make-vector new-len #f)))
; (let loop ((n 0))
; (if (= n n2d-state-count)
; (begin
; (set! n2d-state-dict v)
; (set! n2d-state-len new-len))
; (begin
; (vector-set! v n (vector-ref n2d-state-dict n))
; (loop (+ n 1))))))))
;
; ; Ajout d'un etat
; (define n2d-add-state
; (lambda (ss)
; (let* ((s n2d-state-count)
; (dentry (make-dentry ss)))
; (if (= n2d-state-count n2d-state-len)
; (n2d-extend-dict))
; (vector-set! n2d-state-dict s dentry)
; (set! n2d-state-count (+ n2d-state-count 1))
; s)))
;
; ; Recherche d'un etat
; (define n2d-search-state
; (lambda (ss)
; (let loop ((s-l ss) (snode n2d-state-tree))
; (if (null? s-l)
; (or (get-snode-dstate snode)
; (let ((s (n2d-add-state ss)))
; (set-snode-dstate snode s)
; s))
; (let* ((next-s (car s-l))
; (alist (get-snode-children snode))
; (ass (or (assv next-s alist)
; (let ((ass (cons next-s (make-snode))))
; (set-snode-children snode (cons ass alist))
; ass))))
; (loop (cdr s-l) (cdr ass)))))))
;
; ; Combiner des listes d'arcs a classes dictinctes
; (define n2d-combine-arcs-l
; (lambda (arcs-l)
; (if (null? arcs-l)
; '()
; (let* ((arcs (car arcs-l))
; (other-arcs-l (cdr arcs-l))
; (other-arcs (n2d-combine-arcs-l other-arcs-l)))
; (n2d-combine-arcs arcs other-arcs)))))
;
; ; Transformer un arc non-det. en un arc det.
; (define n2d-translate-arc
; (lambda (arc)
; (let* ((class (car arc))
; (ss (cdr arc))
; (s (n2d-search-state ss)))
; (cons class s))))
;
; ; Transformer une liste d'arcs non-det. en ...
; (define n2d-translate-arcs
; (lambda (arcs)
; (map n2d-translate-arc arcs)))
;
; ; Trouver le minimum de deux acceptants
; (define n2d-acc-min2
; (let ((acc-min (lambda (rule1 rule2)
; (cond ((not rule1)
; rule2)
; ((not rule2)
; rule1)
; (else
; (min rule1 rule2))))))
; (lambda (acc1 acc2)
; (cons (acc-min (car acc1) (car acc2))
; (acc-min (cdr acc1) (cdr acc2))))))
;
; ; Trouver le minimum de plusieurs acceptants
; (define n2d-acc-mins
; (lambda (accs)
; (if (null? accs)
; (cons #f #f)
; (n2d-acc-min2 (car accs) (n2d-acc-mins (cdr accs))))))
;
; ; Fabriquer les vecteurs d'arcs et d'acceptance
; (define n2d-extract-vs
; (lambda ()
; (let* ((arcs-v (make-vector n2d-state-count))
; (acc-v (make-vector n2d-state-count)))
; (let loop ((n 0))
; (if (= n n2d-state-count)
; (cons arcs-v acc-v)
; (begin
; (vector-set! arcs-v n (get-dentry-darcs
; (vector-ref n2d-state-dict n)))
; (vector-set! acc-v n (get-dentry-acc
; (vector-ref n2d-state-dict n)))
; (loop (+ n 1))))))))
;
; ; Effectuer la transformation de l'automate de non-det. a det.
; (define nfa2dfa
; (lambda (nl-start no-nl-start arcs-v acc-v)
; (n2d-init-glob-vars)
; (let* ((nl-d (n2d-search-state nl-start))
; (no-nl-d (n2d-search-state no-nl-start))
; (norm-arcs-v (n2d-normalize-arcs-v arcs-v)))
; (let loop ((n 0))
; (if (< n n2d-state-count)
; (let* ((dentry (vector-ref n2d-state-dict n))
; (ss (get-dentry-ss dentry))
; (arcs-l (map (lambda (s) (vector-ref norm-arcs-v s)) ss))
; (arcs (n2d-combine-arcs-l arcs-l))
; (darcs (n2d-translate-arcs arcs))
; (fact-darcs (n2d-factorize-darcs darcs))
; (accs (map (lambda (s) (vector-ref acc-v s)) ss))
; (acc (n2d-acc-mins accs)))
; (set-dentry-darcs dentry fact-darcs)
; (set-dentry-acc dentry acc)
; (loop (+ n 1)))))
; (let* ((result (n2d-extract-vs))
; (new-arcs-v (car result))
; (new-acc-v (cdr result)))
; (n2d-init-glob-vars)
; (list nl-d no-nl-d new-arcs-v new-acc-v)))))
;
; Section temporaire: vieille facon de generer le dfa
; Dictionnaire d'etat det. Table de hashage. Creation des
; arcs d'un ensemble d'etats en combinant des ensembles d'arcs a
; classes distinctes.
;
; Quelques variables globales
(define n2d-state-dict '#(#f))
(define n2d-state-len 1)
(define n2d-state-count 0)
(define n2d-state-hash '#())
; Fonctions de gestion des entrees du dictionnaire
(define make-dentry (lambda (ss) (vector ss #f #f)))
(define get-dentry-ss (lambda (dentry) (vector-ref dentry 0)))
(define get-dentry-darcs (lambda (dentry) (vector-ref dentry 1)))
(define get-dentry-acc (lambda (dentry) (vector-ref dentry 2)))
(define set-dentry-darcs (lambda (dentry arcs) (vector-set! dentry 1 arcs)))
(define set-dentry-acc (lambda (dentry acc) (vector-set! dentry 2 acc)))
; Initialisation des variables globales
(define n2d-init-glob-vars
(lambda (hash-len)
(set! n2d-state-dict (vector #f))
(set! n2d-state-len 1)
(set! n2d-state-count 0)
(set! n2d-state-hash (make-vector hash-len '()))))
; Extension du dictionnaire
(define n2d-extend-dict
(lambda ()
(let* ((new-len (* 2 n2d-state-len))
(v (make-vector new-len #f)))
(let loop ((n 0))
(if (= n n2d-state-count)
(begin
(set! n2d-state-dict v)
(set! n2d-state-len new-len))
(begin
(vector-set! v n (vector-ref n2d-state-dict n))
(loop (+ n 1))))))))
; Ajout d'un etat
(define n2d-add-state
(lambda (ss)
(let* ((s n2d-state-count)
(dentry (make-dentry ss)))
(if (= n2d-state-count n2d-state-len)
(n2d-extend-dict))
(vector-set! n2d-state-dict s dentry)
(set! n2d-state-count (+ n2d-state-count 1))
s)))
; Recherche d'un etat
(define n2d-search-state
(lambda (ss)
(let* ((hash-no (if (null? ss) 0 (car ss)))
(alist (vector-ref n2d-state-hash hash-no))
(ass (assoc ss alist)))
(if ass
(cdr ass)
(let* ((s (n2d-add-state ss))
(new-ass (cons ss s)))
(vector-set! n2d-state-hash hash-no (cons new-ass alist))
s)))))
; Combiner des listes d'arcs a classes dictinctes
(define n2d-combine-arcs-l
(lambda (arcs-l)
(if (null? arcs-l)
'()
(let* ((arcs (car arcs-l))
(other-arcs-l (cdr arcs-l))
(other-arcs (n2d-combine-arcs-l other-arcs-l)))
(n2d-combine-arcs arcs other-arcs)))))
; Transformer un arc non-det. en un arc det.
(define n2d-translate-arc
(lambda (arc)
(let* ((class (car arc))
(ss (cdr arc))
(s (n2d-search-state ss)))
(cons class s))))
; Transformer une liste d'arcs non-det. en ...
(define n2d-translate-arcs
(lambda (arcs)
(map n2d-translate-arc arcs)))
; Trouver le minimum de deux acceptants
(define n2d-acc-min2
(let ((acc-min (lambda (rule1 rule2)
(cond ((not rule1)
rule2)
((not rule2)
rule1)
(else
(min rule1 rule2))))))
(lambda (acc1 acc2)
(cons (acc-min (car acc1) (car acc2))
(acc-min (cdr acc1) (cdr acc2))))))
; Trouver le minimum de plusieurs acceptants
(define n2d-acc-mins
(lambda (accs)
(if (null? accs)
(cons #f #f)
(n2d-acc-min2 (car accs) (n2d-acc-mins (cdr accs))))))
; Fabriquer les vecteurs d'arcs et d'acceptance
(define n2d-extract-vs
(lambda ()
(let* ((arcs-v (make-vector n2d-state-count))
(acc-v (make-vector n2d-state-count)))
(let loop ((n 0))
(if (= n n2d-state-count)
(cons arcs-v acc-v)
(begin
(vector-set! arcs-v n (get-dentry-darcs
(vector-ref n2d-state-dict n)))
(vector-set! acc-v n (get-dentry-acc
(vector-ref n2d-state-dict n)))
(loop (+ n 1))))))))
; Effectuer la transformation de l'automate de non-det. a det.
(define nfa2dfa
(lambda (nl-start no-nl-start arcs-v acc-v)
(n2d-init-glob-vars (vector-length arcs-v))
(let* ((nl-d (n2d-search-state nl-start))
(no-nl-d (n2d-search-state no-nl-start))
(norm-arcs-v (n2d-normalize-arcs-v arcs-v)))
(let loop ((n 0))
(if (< n n2d-state-count)
(let* ((dentry (vector-ref n2d-state-dict n))
(ss (get-dentry-ss dentry))
(arcs-l (map (lambda (s) (vector-ref norm-arcs-v s)) ss))
(arcs (n2d-combine-arcs-l arcs-l))
(darcs (n2d-translate-arcs arcs))
(fact-darcs (n2d-factorize-darcs darcs))
(accs (map (lambda (s) (vector-ref acc-v s)) ss))
(acc (n2d-acc-mins accs)))
(set-dentry-darcs dentry fact-darcs)
(set-dentry-acc dentry acc)
(loop (+ n 1)))))
(let* ((result (n2d-extract-vs))
(new-arcs-v (car result))
(new-acc-v (cdr result)))
(n2d-init-glob-vars 0)
(list nl-d no-nl-d new-arcs-v new-acc-v)))))