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

13    Frames

Lösung der Aufgaben

13.1    Frames

frame( Frame, Slot, Facet, Value) :- 
    /* Frame must be instantiated */
    F =.. [ Frame, Slot, Facet, Value], 
    call( F).

frame_up( Frame, Slot, Facet, Value, Frame) :- 
    frame( Frame, Slot, Facet, Value).

frame_up( Frame, Slot, Facet, Value, FoundFrame) :-
    frame( Frame, is_a, value, Parent_Frame),
    frame_up( Parent_Frame, Slot, Facet, Value, FoundFrame).

delete( Frame) :-
    retractall( frame( Frame)),
    functor( Term, Frame, 3), 
    retractall( Term).

get_value1( Frame, Slot, Value) :- 
    frame( Frame, Slot, value, Value), !.
 
get_value( Frame, Slot, Value) :- 
    frame_up( Frame, Slot, Facet, V, _), 
    (Facet = value
    ->  Value = V
    ;   Facet = if_needed,
        Demon =.. [ V, Frame, Slot, Value], 
        call( Demon)
    ), !. 
    /* Facet = if_added ignored */

put_value1( Frame, Slot, Value) :-
    F =.. [Frame, Slot, value,  _], 
    (retract( F) ; true), !,
    F1 =.. [Frame, Slot, value, Value], 
    assertz( F1), !.

put_value( Frame, Slot, Value) :-
    frame_up( Frame, Slot, Facet, V, ParFrame), !, 
    /* first slot in hierarchy */
    put_value_x( Frame, Slot, Facet, Value).

put_value_x( Frame, Slot, if_needed, Value) :- 
    !, fail.
put_value_x( Frame, Slot, _, Value) :- 
    put_value1( Frame, Slot, Value), 
    (frame_up( Frame, Slot, if_added, D, _)
    -> Demon =.. [ D, Frame, Slot, Value], 
       call( Demon)
    ), !.
    
create_instance( Frame, InstanceFrame) :-
    frame( Frame),
    retractall( slot( _)),
    assertz( frame( InstanceFrame)),
    put_value1( InstanceFrame, is_a, Frame), 
    frame_up( Frame, Slot, Facet, Value, _),
        not slot( Slot),
        assert( slot( Slot)), 
        Slot \= is_a, 
        Facet \= if_needed,
        modify_value( InstanceFrame, Slot), 
    fail.
create_instance( Frame, InstanceFrame) :- 
    nl, write( InstanceFrame), 
    write( ': finished').

modify_value( Frame, Slot) :-
    get_value( Frame, Slot, Value),
    nl, write( Frame), write( ': '), 
    write( Slot), write( ': '), write( Value),
    nl, write( 'New value? '),  
    nl, read( NewValue),
    nl, write( 'New value: '),  
    modify_value1( Frame, Slot, Value, NewValue), !.

modify_value1( Frame, Slot, Value, eof) :- !,
    write( Value).
modify_value1( Frame, Slot, Value, NewValue) :- 
    put_value( Frame, Slot, NewValue), 
    write( NewValue), !.
modify_value1( Frame, Slot, Value, NewValue) :- 
    nl, write( 'This value could not be asserted (if_added failed)'),
    modify_value( Frame, Slot).

Back to example 13.1

13.2    Hierarchie graphischer Objekte

frame( graphisches_Objekt).
graphisches_Objekt( name, value, 'graphisches Objekt').
graphisches_Objekt( position, value, (0, 0)).

frame( rechteck).
rechteck( is_a, value, graphisches_Objekt).
rechteck( name, value, 'Rechteck').
rechteck( seite_x, value, X).
rechteck( seite_y, value, Y).
rechteck( flaeche, if_needed, rechteck_flaeche).

rechteck_flaeche( Frame, Slot, Value) :-
    get_value( Frame, seite_x, X),
    get_value( Frame, seite_y, Y),
    Value is X * Y, !.

frame( quadrat).
quadrat( is_a, value, rechteck).
quadrat( name, value, 'Quadrat').
quadrat( seite_x, if_added, quadrat_seite).
quadrat( seite_y, if_added, quadrat_test).

quadrat_seite( Frame, Slot, Value) :-
    put_value( Frame, seite_y, Value), !.
    
quadrat_test( Frame, Slot, Value) :-
    get_value1( Frame, seite_x, Value), !.

frame( ellipse).
ellipse( is_a, value, graphisches_Objekt).
ellipse( name, value, 'Ellipse').
ellipse( halbachse_x, value, X).
ellipse( halbachse_y, value, Y).
ellipse( flaeche, if_needed, ellipse_flaeche).

ellipse_flaeche( Frame, Slot, Value) :-
    get_value( Frame, halbachse_x, X), 
    get_value( Frame, halbachse_y, Y),
    Value is 3.14 * X * Y, !.
    
frame( kreis).
kreis( is_a, value, ellipse).
kreis( name, value, 'Kreis').
kreis( radius, value, X).
kreis( halbachse_x, if_needed, kreis_halbachse).
kreis( halbachse_y, if_needed, kreis_halbachse).
kreis( flaeche, if_needed, kreis_flaeche).

kreis_flaeche( Frame, Slot, Value) :-
    get_value( Frame, radius, R), 
    Value is 3.14 * R * R, !.

kreis_halbachse( Frame, Slot, Value) :-
    get_value1( Frame, radius, Value), !.

Back to example 13.2