home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 3 / TheARMClub_PDCD3.iso / hensa / programming / a139_1 / !Hope_Programs_WordList < prev    next >
Encoding:
Text File  |  1990-09-23  |  12.6 KB  |  338 lines

  1. !-----------------------------------------------------------------------------!
  2. !                                                                             !
  3. !   Program:  2nd Language Exercise (Hope: Sorted words with frequency count) !
  4. !   Author:   M. Y. Ben-Gershon                                               !
  5. !   Date:     13th December 1989                                              !
  6. !                                                                             !
  7. !-----------------------------------------------------------------------------!
  8. !                                                                             !
  9. !   Purpose:                                                                  !
  10. !     This program reads a sentence as a list of characters.  It then splits  !
  11. !     the sentence into its component words, sorts them into alphabetical     !
  12. !     order (strictly speaking into ASCII order, upper case befor lower case) !
  13. !     and then produces a list of all the words found, together with a        !
  14. !     frequency count for each word found.                                    !
  15. !                                                                             !
  16. !                                                                             !
  17. !   Calling format:                                                           !
  18. !     The program is used by entering a function call of the form:            !
  19. !                                                                             !
  20. !       'WordCount("This is the sentence I wish to use for the test.");'      !
  21. !                                                                             !
  22. !                                                                             !
  23. !   Output format:                                                            !
  24. !     The program displays its results in the form of a list.  In the above   !
  25. !     example, the results would have been:                                   !
  26. !                                                                             !
  27. !     >> [ ( "I" , 1 ) , ( "This" , 1 ) , ( "for" , 1 ) , ( "is" , 1 ) ,      !
  28. !        ( "sentence" , 1 ) , ( "test" , 1 ) , ( "the" , 2 ) , ( "to" , 1 ) , !
  29. !        ( "use" , 1 ) , ( "wish" , 1 ) ] : list ( ( TV000 # num ) )          !
  30. !                                                                             !
  31. !                                                                             !
  32. !-----------------------------------------------------------------------------!
  33.  
  34.  
  35.  
  36. type word == list(char);
  37.  
  38. type sentence == list(char);
  39.  
  40. type CountItem(alpha) == alpha # num;
  41.  
  42. type CountList(alpha) == list(CountItem(alpha));
  43.  
  44.  
  45.  
  46.  
  47.  
  48.  
  49. data tree(alpha) == niltree ++ 
  50.                       constree(alpha #
  51.                                  tree(alpha) # tree(alpha));
  52.  
  53.  
  54.  
  55.  
  56. infix << : 6;                  ! This is the 'less than' operator !
  57.                                ! for words (lists of char).       !
  58.  
  59.  
  60.  
  61. dec Letter    : char -> truval;
  62. dec AWord     : sentence # word -> word # sentence;
  63. dec WordList  : sentence # list(word) -> list(word) # sentence;
  64. dec <<        : word # word -> truval;
  65. dec InsertInTree        : word # tree(word) -> tree(word);
  66. dec OrderedTreeFromList : list(word) -> tree(word);
  67. dec Flatten   : tree(alpha) -> list(alpha);
  68. dec DeleteAndCount      : alpha # list(alpha) # num # list(alpha) -> num # list(alpha);
  69. dec ListCount : list(alpha) -> CountList(alpha);
  70. dec WordCount : sentence -> CountList(word);
  71.  
  72.  
  73.  
  74.  
  75. !--------------------------------------------------------------!
  76. !                                                              !
  77. !  The following function returns 'true' if the character      !
  78. !  parameter passed to it was a letter, and 'false' otherwise. !
  79. !                                                              !
  80. !--------------------------------------------------------------!
  81.  
  82. ! dec Letter : char -> truval;
  83.  
  84. --- Letter ch <=
  85.       ( (ch >= 'a') and (ch =< 'z') )
  86.          or ( (ch >= 'A') and (ch =< 'Z') );
  87.  
  88.  
  89.  
  90.  
  91.  
  92. !--------------------------------------------------------------!
  93. !                                                              !
  94. !  The following function returns a given sentence, split      !
  95. !  into two parts: the first word, and the rest.  It           !
  96. !  terminates a word on the first non-alphabetic character     !
  97. !  found.  It MUST be called initially using the form:         !
  98. !                                                              !
  99. !   'AWord("List of characters forming a sentence" , nil);'    !
  100. !                                                              !
  101. !  as it uses the first parameter to 'accumulate' the          !
  102. !  characters forming the word to be returned.  This makes the !
  103. !  function a linear one, rather than an O(n^2) one, which     !
  104. !  would be the case had the function been a simple recursive  !
  105. !  one, without such an 'accumulating parameter'.              !
  106. !                                                              !
  107. !--------------------------------------------------------------!
  108.  
  109. ! dec AWord : sentence # word -> word # sentence;
  110.  
  111. --- AWord(nil , TheWordSoFar) <=
  112.       (TheWordSoFar , nil);
  113.  
  114. --- AWord(Head::Tail , TheWordSoFar) <=
  115.       if not Letter(Head) then
  116.         (TheWordSoFar , Tail)
  117.       else
  118.         AWord(Tail , TheWordSoFar <> (Head::nil) );
  119.  
  120.  
  121.  
  122.  
  123.  
  124.  
  125.  
  126. !--------------------------------------------------------------!
  127. !                                                              !
  128. !  The following function returns a given sentence, split up   !
  129. !  into its component words (lists of characters).  It uses    !
  130. !  the function 'AWord' (defined previously) which returns a   !
  131. !  given sentence, split into two parts - the first word, and  !
  132. !  the rest.  The words returned by 'AWord' are accumulated    !
  133. !  in an accumulating parameter, so this function should be    !
  134. !  called using the form:                                      !
  135. !                                                              !
  136. !  'WordList("List of characters forming a sentence" , nil);'  !
  137. !                                                              !
  138. !--------------------------------------------------------------!
  139.  
  140.  
  141. ! dec WordList : sentence #  list(word) -> list(word) # sentence;
  142.  
  143. --- WordList(nil , WordsSoFar) <=
  144.       (WordsSoFar , nil);
  145.  
  146. --- WordList(Sentence , WordsSoFar) <=            !  This removes 'nil'     !
  147.       if NextWord = nil then                      !  words - and prevents   !
  148.         WordList(RestOfSentence , WordsSoFar)     !  them from being added  !
  149.                                                   !  to the list of words.  !
  150.       else
  151.         WordList(RestOfSentence , WordsSoFar <> (NextWord :: nil) )
  152.  
  153.           where (NextWord , RestOfSentence) == AWord(Sentence , nil);
  154.  
  155.  
  156.  
  157.  
  158.  
  159.  
  160. !--------------------------------------------------------------!
  161. !                                                              !
  162. !  The following function returns 'true' if the first list     !
  163. !  is 'less' than the second.  It is polymorphic, and will     !
  164. !  work on any list of characters or numbers.  For a list of   !
  165. !  numbers the order is strictly numerical, for lists of char  !
  166. !  the order is ASCII.  The nil list is 'less than' any other  !
  167. !  list.  In the case of lists of char (words), the function   !
  168. !  will, in effect be testing for the alphabetical order of    !
  169. !  the two words, bearing in mind that upper and lower case    !
  170. !  are regarded aa being distinct, with lower-case being       !
  171. !  'less' than upper-case.  The function defines a new infix   !
  172. !  operator, '<<', with a priority of 6 (as '>', '<' etc).     !
  173. !                                                              !
  174. !--------------------------------------------------------------!
  175.  
  176. ! infix << : 6;
  177. ! dec << : list(alpha) # list(alpha) -> truval;
  178.  
  179. --- _ << nil <=
  180.       false;
  181.  
  182. --- nil << _ <=
  183.       true;
  184.  
  185. --- (h1::t1) << (h2::t2) <=
  186.       if (h1 < h2) then
  187.         true
  188.       else
  189.         if (h1 > h2) then
  190.           false
  191.         else
  192.           (t1 << t2);
  193.  
  194.  
  195.  
  196.  
  197.  
  198.  
  199.  
  200. !--------------------------------------------------------------!
  201. !                                                              !
  202. !  The following function returns a tree, consisting of the    !
  203. !  given word inserted into the given ordered binary tree of   !
  204. !  words.                                                      !
  205. !                                                              !
  206. !--------------------------------------------------------------!
  207.  
  208. ! dec InsertInTree : word # tree(word) -> tree(word);
  209.  
  210. --- InsertInTree(w , niltree) <=
  211.       constree(w , niltree , niltree);
  212.  
  213. --- InsertInTree(w , constree(NodeVal , Left , Right)) <=
  214.       if (w << NodeVal) then
  215.         constree(NodeVal , InsertInTree(w , Left) , Right)
  216.       else
  217.         constree(NodeVal , Left , InsertInTree(w , Right) );
  218.  
  219.  
  220.  
  221.  
  222.  
  223.  
  224.  
  225. !--------------------------------------------------------------!
  226. !                                                              !
  227. !  The following function returns a tree, consisting of an     !
  228. !  unordered list of words, entered into an ordered binary     !
  229. !  tree of words.                                              !
  230. !                                                              !
  231. !--------------------------------------------------------------!
  232.  
  233. ! dec OrderedTreeFromList : list(word) -> tree(word);
  234.  
  235. --- OrderedTreeFromList( nil ) <=
  236.       niltree;
  237.  
  238. --- OrderedTreeFromList( h::t ) <=
  239.       InsertInTree(h , OrderedTreeFromList(t) );
  240.  
  241.  
  242.  
  243.  
  244.  
  245.  
  246. !--------------------------------------------------------------!
  247. !                                                              !
  248. !  The following function 'flattens' a tree into a list.  If   !
  249. !  the tree was an ordered one, 'Flatten' will return a list,  !
  250. !  consisting of the ordered elements of the tree.             !
  251. !                                                              !
  252. !--------------------------------------------------------------!
  253.  
  254. ! dec Flatten : tree(alpha) -> list(alpha);
  255.  
  256. --- Flatten niltree <=
  257.       nil;
  258.  
  259. --- Flatten( constree( NodeVal , Left , Right ) ) <=
  260.       (Flatten Left) <> (NodeVal :: Flatten Right);
  261.  
  262.  
  263.  
  264.  
  265.  
  266.  
  267.  
  268.  
  269. !--------------------------------------------------------------!
  270. !                                                              !
  271. !  The following function searches for an item in a list and   !
  272. !  returns a count of the number of times the item was found   !
  273. !  in the list, together with a new list consisting of the     !
  274. !  original list with all occurrences of the item removed.     !
  275. !                                                              !
  276. !--------------------------------------------------------------!
  277.  
  278.  
  279. ! dec DeleteAndCount : alpha # list(alpha) # num # list(alpha) -> num # list(alpha);
  280.  
  281. --- DeleteAndCount(_ , nil , TimesThisWord , UniqueWordsSoFar) <=
  282.       (TimesThisWord , UniqueWordsSoFar);
  283.  
  284. --- DeleteAndCount(Item , Head::Tail , TimesThisWord , UniqueWordsSoFar) <=
  285.       if (Item = Head) then
  286.         DeleteAndCount(Item , Tail , succ TimesThisWord , UniqueWordsSoFar)
  287.       else
  288.         DeleteAndCount(Item , Tail , TimesThisWord , UniqueWordsSoFar <> (Head::nil));
  289.  
  290.  
  291.  
  292.  
  293.  
  294.  
  295. !--------------------------------------------------------------!
  296. !                                                              !
  297. !  The following function counts the frequency of items in a   !
  298. !  list.  It returns a list of tuples, each containing one of  !
  299. !  the unique words found, together with its frequency.        !
  300. !                                                              !
  301. !--------------------------------------------------------------!
  302.  
  303. ! dec ListCount : list(alpha) -> CountList(alpha);
  304.  
  305. --- ListCount(nil) <=
  306.       nil;
  307.  
  308. --- ListCount(Head::Tail) <=
  309.       (Head , (succ TimesHeadFound) ) :: ListCount(NewTail)
  310.           where (TimesHeadFound , NewTail) ==
  311.             DeleteAndCount(Head , Tail , 0 , nil);
  312.  
  313.  
  314.  
  315.  
  316.  
  317.  
  318. !--------------------------------------------------------------!
  319. !                                                              !
  320. !  The following function is the program 'shell' which enables !
  321. !  the component functions to be put together and produce      !
  322. !  a sorted list of the words in a sentence with their         !
  323. !  frequency count, when the user is only required to enter    !
  324. !  the sentence to be counted as a parameter of this one       !
  325. !  function.                                                   !
  326. !                                                              !
  327. !--------------------------------------------------------------!
  328.  
  329.  
  330. ! dec WordCount : sentence -> CountList(word);
  331.  
  332. --- WordCount ls <=
  333.       ListCount(Flatten(OrderedTreeFromList(TheListOfWords)))
  334.  
  335.         where (TheListOfWords , _) == WordList(ls , nil);
  336.  
  337.  
  338. WordCount (" Write a function ChangeBase of two arguments which converts a number to its representation in some specified base <= 10. ") ;