/* READER.LOGIC */ /* This is the part of the READER in the Richard Head exercise that is to be visible to the student. The main predicate is run/0. This exercise is intended as an "alpha-sting", giving the more advanced student something extra to play with, and showing him some of the extra possibilities of Prolog. Predicates you might suggest he can experiment with: converse and run_1: Show how they omit various parts of the interaction. look_up( APat+ ): Call it with various atom patterns. Think about adding extra clauses for other kinds of help, e.g. look_up( examples ) might give a list of example patterns. listify( APat+, LPat- ): Call this with various atom patterns and see the result. Why do we need two representations? fits( LPat+, List+ ): Try examples like fits( [a,==,b], [a,x,b] ), fits( [==,a,==,b==], [q,a,x,b,d] ). Once he's happy with == and =, introduce ?? and ?. Show how patterns like [??V,==,??V] can be used to match repeated sub-sequences. matches( LPat+, List- ): The difference in backtracking between this and fits will only be evident with ??. Demonstrate it. Predicates calling output: Show how messages can be built up. In _this_ file, I have not used ~, but have called nl instead. This gives the student something familiar to hang on to. Show the difference between output(L) output(seplist(L,Sep)) findall: Show how this can be used to find all solutions, e.g. to questions in the MARS database. Then students can try using read_sentence from READ_SENTENCE.PL to read a sentence and reply to it, modifying the looker-up so that it uses pattern-matching to extract parts from sentences and formulate appropriate replies. */ :- lib( reader ). /* Load the other definitions. */ /* Main loop. ---------- */ /* run: Main predicate: initiate a dialogue. */ run :- give_help, nl, run_1. /* run_1: Loop to be entered after giving initial help message. */ run_1 :- converse, nl, run_1. /* One cycle. ---------- */ /* converse: Ask for a pattern and process it. */ converse :- ask_atom( 'Pattern to search for (or help or stop)?', APat ), look_up( APat ). /* look_up( W+ ): W can be: stop: give farewell message and abort. help: give help. a pattern as described by give_help/0: look it up. */ look_up( stop ) :- !, farewell, abort. look_up( help ) :- !, give_help, nl. look_up( APat ) :- listify( APat, LPat ), seek( APat, LPat ). /* Matching a pattern. ------------------- */ /* seek( APat+, LPat+ ): Look up LPat in the full dictionary. First give the first entry found, then ask the student whether he wants to see the others, and display them all if so. APat is the original pattern as an atom, used in messages. */ seek( APat, LPat ) :- head( English, Cant ), fits( LPat, English ), !, output( 'Found:' ), nl, output( ' English:'...seplist_(English,' ') ), nl, output( ' Cant :'...seplist_(Cant,' ') ), nl, continue( APat, LPat ). seek( APat, LPat ) :- output( 'No matches found.' ), nl. /* continue( APat+, LPat+ ): Ask the student whether he wants to see the others, and display them all if so. */ continue( APat, LPat ) :- ask_yn( 'Do you want to see all the matches for'...APat<>'?', YN ), do_all( YN, LPat ). /* do_all( YN+, LPat+ ): If YN = yes, do all matches. */ do_all( no, LPat ) :- !. do_all( yes, LPat ) :- !, findall( [English,Cant], (head( English, Cant ), fits( LPat, English )), All ), write_all( All ). /* write_all( List+ ): List is a list of [English,Cant] elements. Display each one. */ write_all( [] ) :- !. write_all( [ [English1,Cant1] | Rest ] ) :- output( ' English:'...seplist_(English1,' ') ), nl, output( ' Cant :'...seplist_(Cant1,' ') ), nl, nl, write_all( Rest ).