Künstliche Intelligenz und Prolog
Copyright © 2019 Jiri Kriz, www.nosco.ch

14    Natürliche Sprachen I

Lösung der Aufgaben

14.1    Natürlichsprachliche Abfragen zu Datenbanken

query( Question, Answer) :-
    sublist( [ Property, of, Object], Question),  
    /* predefined */
    object( Object, Relation), 
    property( Relation, Property, NP),  
    relation( Relation, NR),
    functor( Term, Relation, NR), 
    arg( 1, Term, Object), 
    arg( NP, Term, Answer),
    call( Term).

state( switzerland, 6, 41, bern). 
state( germany,  65, 248, berlin). 

object( switzerland, state).
object( germany, state).

relation( state, 4).

property( state, population, 2).
property( state, area, 3).
property( state, capital, 4).

Back to example 14.1

14.2    Tokenizer

tokenize( String, Words):-    
    string_ascii( String, Chars),
    parse_chars( Chars, Words),
    !.
    
parse_chars( [ Char| Chars], [ Word| Words]) :-
    word_char( Char),
    get_word_chars( [ Char| Chars], RestChars, WordChars),
    name( Word, WordChars),
    parse_chars( RestChars, Words).
parse_chars( [ Char| Chars], Words) :-
    fill_char( Char),
    parse_chars( Chars, Words).
parse_chars( [ Char| Chars], []) :-
    end_char(Char).
parse_chars( [], []).
    
get_word_chars( [ Char| Chars], RestChars, [ Char| WordChars]) :-
    word_char( Char), !, 
    get_word_chars( Chars, RestChars, WordChars). 
get_word_chars( Chars, Chars, []). 
        
word_char( Char) :- Char >= 97, Char =< 122. /* a b ... z */ 
word_char( Char) :- Char >= 65, Char =< 90.  /* A B ... Z */ 
word_char( Char) :- Char >= 48, Char =< 57. /* 0 1 ... 9 */ 

end_char( 44). /* ',' */ 
end_char( 46). /* '.' */ 
end_char( 63). /* '?' */ 
end_char( 33). /* '!' */
end_char( 10). /* LF */

fill_char( 32). /* blank */
fill_char( 9). /* tab */

talk :- 
    write( "Welcome! Type 'bye' to quit."), 
    nl,
    repeat,
        nl, write( "> "),
        read_string( String),
        tokenize( String, Words),
        process_words( Words), 
        nl,
    Words = [ bye| _], !.

process_words( Words) :-
    listlength( Words, N),
    write_list( Words), 
    write( '/ '), 
    write( N), nl.

write_list( [X1| Xs]) :- 
    write(X1), 
    write(' '), 
    write_list( Xs).
write_list( []).

Back to example 14.2

14.3    ELIZA

eliza( [bye]) :-
    write( 'Goodby. I hope I have helped you.'), 
    nl,
    !.
eliza( Input) :-
    pattern( Stimulus, Response),
    match( Stimulus, Table, Input), 
    match( Response, Table, Output), 
    write_list( Output),
    !.
    
match( [N| Pattern], Table, Words) :-
    integer( N), 
    lookup( N, Table, Words1),
    append( Words1, Words2, Words),
    match( Pattern, Table, Words2).
match( [Word| Pattern], Table, [Word| Words]) :-
    atom( Word), 
    match( Pattern, Table, Words).
match( [], Table, []).

lookup( Key, [(Key, Value)| Dict], Value).
lookup( Key, [(Key1, Value1)| Dict], Value) :-
    Key \= Key1, lookup( Key, Dict, Value).

pattern( [i, am, 1], ['How long have you been', 1, ?]).
pattern( [1, you, 2, me], ['What makes you think I', 1, 2, you, ?]).
pattern( [i, like, 1], ['Does anyone else in your family like', 1, ?]).
pattern( [i, feel, 1], ['Do you often feel that way?']).
pattern( [1, X, 2], ['Please tell me more about', X, .]) :- 
    important( X).
pattern( [1], ['Please go on.']).

important( father).
important( mother).
important( son).
important( daughter).
important( sister).
important( brother).

/* Use for ELIZA: process_words( Words) :- eliza( Words). */

Back to example 14.3