make_lts.scm 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;; ;;;
  3. ;;; Language Technologies Institute ;;;
  4. ;;; Carnegie Mellon University ;;;
  5. ;;; Copyright (c) 1999 ;;;
  6. ;;; All Rights Reserved. ;;;
  7. ;;; ;;;
  8. ;;; Permission is hereby granted, free of charge, to use and distribute ;;;
  9. ;;; this software and its documentation without restriction, including ;;;
  10. ;;; without limitation the rights to use, copy, modify, merge, publish, ;;;
  11. ;;; distribute, sublicense, and/or sell copies of this work, and to ;;;
  12. ;;; permit persons to whom this work is furnished to do so, subject to ;;;
  13. ;;; the following conditions: ;;;
  14. ;;; 1. The code must retain the above copyright notice, this list of ;;;
  15. ;;; conditions and the following disclaimer. ;;;
  16. ;;; 2. Any modifications must be clearly marked as such. ;;;
  17. ;;; 3. Original authors' names are not deleted. ;;;
  18. ;;; 4. The authors' names are not used to endorse or promote products ;;;
  19. ;;; derived from this software without specific prior written ;;;
  20. ;;; permission. ;;;
  21. ;;; ;;;
  22. ;;; CARNEGIE MELLON UNIVERSITY AND THE CONTRIBUTORS TO THIS WORK ;;;
  23. ;;; DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ;;;
  24. ;;; ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT ;;;
  25. ;;; SHALL CARNEGIE MELLON UNIVERSITY NOR THE CONTRIBUTORS BE LIABLE ;;;
  26. ;;; FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ;;;
  27. ;;; WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN ;;;
  28. ;;; AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ;;;
  29. ;;; ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF ;;;
  30. ;;; THIS SOFTWARE. ;;;
  31. ;;; ;;;
  32. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  33. ;;; Author: Alan W Black (awb@cs.cmu.edu) ;;;
  34. ;;; Date: December 1999 ;;;
  35. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  36. ;;; ;;;
  37. ;;; Generate a C compilable lts rules. ;;;
  38. ;;; ;;;
  39. ;;; Two modes, from decision graphs as wfsts or from CART trees ;;;
  40. ;;; ;;;
  41. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  42. ;;; These are preordained by the LTS building process
  43. (set! lts_context_window_size 4)
  44. (set! lts_context_extra_feats 1)
  45. (define (ltsregextoC name trees idir odir)
  46. "(ltsregextoC name idir odir)
  47. Converts its wfsts to a C compilation structure for flite. Assumes
  48. $idir/[a-z].tree.wfst to compile from."
  49. (let
  50. ((ofde (fopen (path-append odir (string-append name "_lts_rules.c")) "w"))
  51. (ofdm (fopen (path-append odir (string-append name "_lts_model.c")) "w"))
  52. (ofdh (fopen (path-append odir (string-append name "_lts_model.h")) "w"))
  53. (ifd)
  54. (rule_index nil))
  55. (set! lts_pos 0)
  56. (set! phone_table (list "epsilon"))
  57. (set! letter_table (list "nothing" "#" "0"))
  58. (set! letter_table (append letter_table (mapcar car trees)))
  59. (format ofde "/*******************************************************/\n")
  60. (format ofde "/** Autogenerated lts rules (regex) for %s */\n" name)
  61. (format ofde "/** from %s */\n" idir)
  62. (format ofde "/*******************************************************/\n")
  63. (format ofde "\n")
  64. (format ofde "#include \"cst_string.h\"\n")
  65. (format ofde "#include \"cst_lts.h\"\n")
  66. (format ofde "#include \"cst_lexicon.h\"\n")
  67. (format ofdm "/*******************************************************/\n")
  68. (format ofdm "/** Autogenerated lts rules (regex) for %s */\n" name)
  69. (format ofdm "/** from %s */\n" idir)
  70. (format ofdm "/*******************************************************/\n")
  71. (format ofdm "\n")
  72. (format ofdm "#include \"cst_string.h\"\n")
  73. (format ofdm "#include \"cst_lts.h\"\n")
  74. (format ofdm "#include \"cst_lexicon.h\"\n")
  75. (format ofdm "#include \"%s_lts_model.h\"\n\n" name)
  76. (format ofdm "const cst_lts_model %s_lts_model[] = \n" name)
  77. (format ofdm "{\n")
  78. (set! ln 0)
  79. (mapcar
  80. (lambda (l)
  81. (let ((ifd (fopen (path-append idir
  82. (string-append l ".tree.wfst")) "r")))
  83. (format t "doing: %s\n" l)
  84. (format ofdm " /** letter \"%s\" **/\n" l)
  85. (format ofdh " /** letter \"%s\" **/\n" l)
  86. (set! rule_index (cons (list l lts_pos ln) rule_index))
  87. (set! lts_pos (dump_lts_wfst ln ifd ofdm ofdh lts_pos))
  88. (fclose ifd)
  89. (set! ln (+ 1 ln))
  90. ))
  91. (cdr (cddr letter_table))
  92. )
  93. (format ofdm " 0, 0, 0,0, 0,0\n")
  94. (format ofdm "};\n")
  95. ;; Make the letter table be the same order as the rule inde (+2)
  96. ;; The phone table (bytes to phone names)
  97. (format ofde "\n")
  98. (format ofde "const char * const %s_lts_phone_table[%d] = \n"
  99. name (+ 1 (length phone_table)))
  100. (format ofde "{\n")
  101. (mapcar (lambda (p) (format ofde " \"%s\",\n" p)) phone_table)
  102. (format ofde " NULL\n")
  103. (format ofde "};\n")
  104. ;; The letter_table (bytes to letter names)
  105. (format ofde "\n")
  106. (format ofde "const char * const %s_lts_letter_table[%d] = \n"
  107. name (+ 1 (length letter_table)))
  108. (format ofde "{\n")
  109. (mapcar (lambda (p) (format ofde " \"%s\",\n" p)) letter_table)
  110. (format ofde " NULL\n")
  111. (format ofde "};\n")
  112. ;; Which rule starts where
  113. (format ofde "\n")
  114. (format ofde "const cst_lts_addr %s_lts_letter_index[%d] = \n"
  115. name (+ 1 (length rule_index)) )
  116. (format ofde "{\n")
  117. (mapcar
  118. (lambda (p) (format ofde " %d, /* %s */\n" (car (cdr p)) (car p)))
  119. (reverse rule_index))
  120. (format ofde " 0\n")
  121. (format ofde "};\n")
  122. (format ofde "\n")
  123. ; (format ofde "const cst_lts_rules %s_lts_rules = {\n" name)
  124. ; (format ofde " \"%s\",\n" name)
  125. ; (format ofde " %s_lts_letter_index,\n" name)
  126. ; (format ofde " %s_lts_model,\n" name)
  127. ; (format ofde " %s_lts_phone_table,\n" name)
  128. ; (format ofde " 4, /* context_window_size */\n")
  129. ; (format ofde " 1, /* context_extra_feats */\n")
  130. ; (format ofde " %s_lts_letter_table\n" name)
  131. ; (format ofde "};\n")
  132. ; (format ofde "\n")
  133. (fclose ofde)
  134. (fclose ofdh)
  135. (fclose ofdm)
  136. ))
  137. (define (dump_lts_wfst ln ifd ofde ofdh lts_pos)
  138. "(dump_lts_wfst ifd ofde ofdh lts_pos)
  139. Dump the WFST as a byte table to ifd. Jumps are dumped as
  140. #define's to ofdh so forward references work. lts_pos is the
  141. rule position. Each state is saves as
  142. feature value true_addr false_addr
  143. Feature and value are single bytes, which addrs are double bytes."
  144. (let ((state))
  145. ;; Skip WFST header
  146. (while (not (string-equal (set! state (readfp ifd)) "EST_Header_End"))
  147. (if (equal? state (eof-val))
  148. (error "eof in lts regex file")))
  149. (while (not (equal? (set! state (readfp ifd)) (eof-val)))
  150. (format ofdh "#define LTS_STATE_%d_%d %s\n"
  151. ln (car (car state))
  152. (lts_bytify lts_pos))
  153. (cond
  154. ((string-equal "final" (car (cdr (car state))))
  155. (set! lts_pos (- lts_pos 1))
  156. t) ;; do nothing
  157. ((string-matches (car (car (cdr state))) ".*_.*")
  158. (format ofde " %s, %d, %s , %s , \n"
  159. (lts_feat (car (car (cdr state))))
  160. ; (lts_val (car (car (cdr state))))
  161. (lts_let_num (lts_letter (car (car (cdr state)))) 0 letter_table)
  162. (format nil "LTS_STATE_%d_%d" ln
  163. (car (cdr (cdr (car (cdr (cdr state)))))))
  164. (format nil "LTS_STATE_%d_%d" ln
  165. (car (cdr (cdr (car (cdr state))))))))
  166. (t ;; its a letter output state
  167. (format ofde " 255, %s, 0,0 , 0,0 , \n"
  168. (lts_phone (car (car (cdr state))) 0 phone_table))))
  169. (set! lts_pos (+ 1 lts_pos)))
  170. lts_pos))
  171. (define (lts_feat trans)
  172. "(lts_feat trans)
  173. Returns the feature number represented in this transition name."
  174. (let ((fname (substring trans 5 (- (length trans) 11))))
  175. (if (string-matches fname ".*_i?")
  176. (set! fname (string-before fname "_")))
  177. (cond
  178. ((string-equal fname "p.p.p.p.name") 0)
  179. ((string-equal fname "p.p.p.name") 1)
  180. ((string-equal fname "p.p.name") 2)
  181. ((string-equal fname "p.name") 3)
  182. ((string-equal fname "n.name") 4)
  183. ((string-equal fname "n.n.name") 5)
  184. ((string-equal fname "n.n.n.name") 6)
  185. ((string-equal fname "n.n.n.n.name") 7)
  186. (t (error (format nil "ltsregex2C: unknown feat %s %s\n" fname trans ))))))
  187. (define (lts_letter trans)
  188. "(lts_val trans)
  189. The letter being tested."
  190. (string-before (string-after trans "is_") "_"))
  191. (define (lts_val trans)
  192. "(lts_val trans)
  193. The letter being tested."
  194. (substring trans (- (length trans) 2) 1))
  195. (define (lts_phone p n table)
  196. (cond
  197. ((string-equal p (car table))
  198. n)
  199. ((not (cdr table)) ;; new p
  200. (set-cdr! table (list p))
  201. (+ 1 n))
  202. (t
  203. (lts_phone p (+ 1 n) (cdr table)))))
  204. (define (lts_let_num p n table)
  205. (cond
  206. ((null table)
  207. (format t "no entry %s %d\n" p n)
  208. (errrr))
  209. ((string-equal p (car table))
  210. n)
  211. (t
  212. (lts_let_num p (+ 1 n) (cdr table)))))
  213. (define (lts_bytify n)
  214. "(lts_bytify n)
  215. Return this short as a two byte comma separated string."
  216. (let ((xx (format nil "%04x" n)))
  217. ;; This is unfortunately byte order specific
  218. (format nil "0x%s,0x%s"
  219. (substring xx 2 2)
  220. (substring xx 0 2))))
  221. (provide 'make_lts)