Wissenschaft
Copyright © 2024 Jiri Kriz, www.nosco.ch

8    Prolog Potpouri (oder: Spass mit Prolog)

Lösung der Aufgaben

Prolog Uebungen 8: Prolog Potpouri

8.1    Kryptoarithmetische Rätsel, allgemeine Lösung

/* call:  ?- puzzle( [0,S,E,N,D], [0,M,O,R,E], [M,O,N,E,Y]), M=1 */
/* solution: puzzle( [0,9,5,6,7], [0,1,0,8,5], [1,0,6,5,2])      */

puzzle( X, Y, Z) :-
    puzzle( X, Y, Z, 0, 0, 
    [0,1,2,3,4,5,6,7,8,9], _).
puzzle( [ X1| Xs], [ Y1| Ys], 
[ Z1| Zs], C_in, C_out, 
Digs_in, Digs_out) 
:-
    puzzle( Xs, Ys, Zs, C_in, C_out1, 
    Digs_in, Digs_out1),
    choose( X1, Digs_out1, DigsX),
    choose( Y1, DigsX, DigsY),
    choose( Z1,DigsY, Digs_out),
    add1( X1, Y1, Z1, C_out1, C_out).
     
puzzle( [], [], [], 0, 0, Digs, Digs). 
 
choose( X, Y, Y) :- 
    nonvar( X), !.
choose( X, Y, Z) :-
    delete( X, Y, Z).
    
delete( X, [ X| Xs], Xs).
delete( X, [ X1| Xs], [ X1| Zs]) :- 
    delete( X, Xs, Zs).
 
add1( X, Y, Z, Cin, Cout) :- 
    S is X + Y + Cin,
    Z is S mod 10, Cout is S div 10.

Back to example 8.1

8.2    Drei Freunde

/* p( Name, Beruf, Stadt, Rang) 
Loesung: 
Daniel, Sportlehrer, Basel, 1
Michael, Arzt, Zuerich, 2
Beat, Beamte, Bern, 3
*/
            
freunde( S)  :- 
    S = [p( _, _, _, 1), 
    p( _, _, _, 2), 
    p( _, _, _, 3)],     
    member( p( beat, _, _, _), S),
    member( p( _, _, zurich, _), S),
    member( p( michael, arzt, _, RM), S),
    member( p( _, _, bern, RB), S), 
    M < RB,
    member( p( daniel, _, basel, RD), S),
    member( p( _, beamte, _, RBe), S), 
    RD < RBe,
    member( p( _, sportlehrer, _, 1), S).

Back to example 8.2

8.3    Ein Intelligenztest

iq( Seq, X) :- 
    hypothese( R, Seq), 
    test_apply( R, Seq, X).

hypothese( lin_diff( A, B), [X1, X2, X3| _]) :-
    A is X3 - 2*X2 + X1,
    B is X2 - X1 - A.
    
test_apply( lin_diff( A, B), Seq, X) :-
    test_apply(lin_diff( A, B), Seq, 1, X).
    
test_apply( lin_diff( A, B), [XN, XN1| Xs], N, X) :-
    XN1 is XN + A * N + B, 
    N1 is N + 1,
    test_apply( lin_diff( A, B), [ XN1| Xs], N1, X).

test_apply( lin_diff( A, B), [ XN], N, X) :-
     X is XN + A * N + B.
 
hypothese( fibo, [1, 1, 2| _]).

test_apply( fibo, [ X1, X2, X3| Xs], X) :-
    X3 is X1 + X2,
    test_apply( fibo, [X2, X3| Xs], X).
test_apply( fibo, [ XN, XN1], X) :-
    X is XN + XN1.

Back to example 8.3

8.4    Sprachübersetzung

translate( [ G1| Gs], EE) :-      
    sequence( [ G1| G], E), 
    append( [ G1| G], Grest, [ G1| Gs]), 
    translate( Grest, Erest), 
    append( E, Erest, EE).
    
translate( [ G1| Gs], [ E1| Es]) :- 
    word( G1, E1), 
    translate( Gs, Es).

translate( [ G1| Gs], [ ?| Es]) :- 
    not word( G1, _), 
    translate(Gs, Es).

translate( [], []).

learn( G, E) :- 
    is_list( G), !, 
    assert( sequence( G, E)), ok.

learn( G, E) :- 
    assert( word( G, E)), ok.

ok :- write( 'OK, teacher!'), nl.

save( File) :- 
    tell( File),
    save_words( File), 
    save_sequences( File),
    told( File), !.
     
save_words( File) :-
    word( D, E),
    write( word( D, E)), 
    write( .), nl,
    fail.      

save_words(_).

save_sequences( File) :-
    sequence( D, E),
    write( sequence( D, E)), 
    write( .), nl,
     fail. 

save_sequences( _).

is_list( []).
is_list( [ _| _]).

member( X, [ X| _]).
member( X, [ _| Y]) :- 
    member( X, Y).

append( [], Y, Y).
append( [ X1| Xs], Ys, [ X1| Zs]) :- 
    append( Xs, Ys, Zs).

Back to example 8.4