Category : Science and Education
Archive   : AIMAY89.ZIP
Filename : FRAMES.CDE

 
Output of file : FRAMES.CDE contained in archive : AIMAY89.ZIP

Frame Unification


/* frame_unify(Frame1, Frame2, Unification )
unifies two frames. Slots that are present in one frame and not in
another are added to the unification, as if the slot had appeared in
the frame where it was absent with a variable value.
*/

/* frame_unify */
frame_unify(Frame1, Frame2, Unification ):-
% use frame_merge to implement frame_unify
frame_merge(Frame1, Frame2, Unification, slot_unify).



% slot_unify([Tag : Slot_val1, Slot_list2, Result, Fail_Flag ])
%
% unifies a slot with Tag with a member of a Slot_list2 if possible.

% This first rule applies when Slot_list2 contains a slot with Tag.
% Result is the unification if it exists.
% Fail_Flag is set to fail if unification fails, to signal
% frame_merge to fail.
slot_unify([Tag : Slot_val1, Slot_list2, Result, Fail_Flag ]):-
% get value for Tag
slot_list_val(Tag, Slot_list2, Slot_val2),
% If slot list 2 contains a slot with Tag,
% stay in this rule
!,
% if these slot values unify
( value_unify(Slot_val1, Slot_val2, Result),
% then stay in this alternative
!,
% and tell frame_merge not to fail
Fail_Flag = true
% if the slot values do not unify
% tell frame_merge to fail
; Fail_Flag = false).

% When the slot in arg. 1 does not appear in the
% arg. 2 slot list, the result of unify is the slot
% value in arg. 1
slot_unify([ _ : Slot_val1, _ , Slot_val1 , _]):- !.


/*-------------------- value_unify -----------------------------------------*/

% value_unify unifies slot values
% Arg 3 is the unification
% this rule unifies those things that are not frames
value_unify(Slot_val1, Slot_val2, Slot_val1):-
Slot_val1 = Slot_val2, !.

Š % this rule unifies frames
value_unify(Slot_val1, Slot_val2, Result ):-
frame_merge(Slot_val1, Slot_val2, Result, slot_unify),
!.

% set unify slot values that are sets
value_unify(Slot_val1, Slot_val2, Slot_val1) :-
set_unify( Slot_val1, Slot_val2 ) ,!.


Intersecting Frames


/* frame_intersect creates a new frame from 2 existing frames by
* keeping in slots that appear in both frames with values that unify,
and letting the value of such slots be the unification of the input
slot values
* deleting all other slots, including those where the same tag has
values in the two frames that don't unify.
*/

frame_intersect(Frame1, Frame2, Intersection ):-
% do this with frame_merge
frame_merge(Frame1, Frame2, Intersection, slot_intersect).

slot_intersect([Tag : Slot_val1, Slot_list2, New_slot_val, true ]):-
slot_list_val(Tag, Slot_list2, Slot_val2), !,
% merge slot values
slot_merge0(Slot_val1, Slot_val2, New_slot_val, _ ).

% note that when a slot with Tag is not in Slot_list2,
% slot_intersect fails. This causes frame_merge to
% leave the Tag slot out of the computed Intersection

% unify slots if possible
slot_merge0(Slot_val1, Slot_val2, Slot_val1, _):-
Slot_val1 = Slot_val2, !.

% intersect slot values that are frames
slot_merge0(Slot_val1, Slot_val2, New_slot_val, _):-
frame_merge(Slot_val1, Slot_val2, New_slot_val, slot_intersect),
!.

% set unify slot values that are sets
slot_merge0(Slot_val1, Slot_val2, Slot_val1 , _):-
set_unify( Slot_val1, Slot_val2 ) ,!.


A General Frame Merging Predicate


/* frame_merge(Frame1,
Frame2,
New_frame,
Slot_merge_pred,
Š Slot_append_pred),

merges Frame1 and Frame2 into New_frame, where Slot_merge_pred
is used to create the output slot.


*/


frame_merge(Frame1, Frame2, New_frame, Slot_merge_pred):-
/* 2 frames must have same name: */
frame_info(Frame1, Class_name, Slot_list1),
frame_info(Frame2, Class_name, Slot_list2),
/* Merge the tag/slot lists: */
slot_list_merge(Slot_list1, Slot_list2, New_slot_list, Slot_merge_pred),
/* Construct the new frame: */
New_frame =.. [Class_name, New_slot_list],
!.


/*-------------------- slot_list_merge -------------------------------------*/

/* slot_list_merge( Slot_list1,
Slot_list2,
New_slot_list,
Slot_merge_pred )

merges a pair of slot lists, where Slot_merge_pred is used to
merge the individual slots.



*/

% Terminate the recursion when both input lists are empty
slot_list_merge( [],
[],
[],
_ ) :- !.

% If both frames contain a slot with Tag, then use Slot_merge_pred
% to unify them. Make slot_list_merge fail if Slot_merge_pred
% sets FailFlag to fail. This lets us distinguish between
% two slot values failing to merge but wanting to go on, and
% wanting to quit when merge fails on the slot values.
%
% In particular, Slot_merge_pred's behavior is related to what
% slot_list_merge should do in the following way:
%
% What slot_list_merge does What Slot_merge_pred does
% when slot values fail to when slot values fail to
% merge merge
%
% fail set FailFlag to fail and succeed
%
Š % leave out the slot fail
%

slot_list_merge( [Tag : Slot_val1 | Slot_list1],
Slot_list2,
[Tag : New_slot_val | New_slot_list],
Slot_merge_pred):-
% create a term which will try to merge the
% slot with Tag in the slot list in arg. 1, with
% some frame in the slot list in arg. 2
make_call_term(Slot_merge_pred,
[Tag : Slot_val1, Slot_list2, New_slot_val, FailFlag],
Term),
call(Term), % call that term
!,
% cut, fail if FailFlag == fail
FailFlag \== fail,
% remove the slot that merges from the 2nd. slot list
remove_if_slot(Tag, Slot_list2, New_slot_list2),
% recurse
slot_list_merge(Slot_list1,
New_slot_list2,
New_slot_list,
Slot_merge_pred).

% Skip Tag:Slot_val1 if Slot_merge_pred failed.
slot_list_merge([_ | Slot_list1],
Slot_list2,
New_slot_list,
Slot_merge_pred):-
slot_list_merge(Slot_list1,
Slot_list2,
New_slot_list,
Slot_merge_pred).

% When the first slot list is exhausted, switch the slot list
% arguments, and recurse.
slot_list_merge([],
[Slot | Slot_list],
New_slot_list,
Slot_merge_pred):-
slot_list_merge([Slot | Slot_list],
[],
New_slot_list,
Slot_merge_pred).


Using Frame Unify



f(part(X)):- part(X). /* Include part frames in test */

test_merge:-
New_pin_frame = part([part_number : lm309,
Š class : ic,
/* Append info. to 'type' slot */
/* for pins 3 and 4: */
pin(3): pin([type : set([high_gain])]),
pin(4): pin([type : set([high_gain])]),
/* Add new pin descr. for pin 8: */
pin(8): pin([device_number : 2,
type : set([output]),
milliamps : [0, 100],
volts : [-7, 7]
])
]),
!,
f(Frame),
frame_unify( Frame,
New_pin_frame,
New_frame),
frame_display(New_frame).



  3 Responses to “Category : Science and Education
Archive   : AIMAY89.ZIP
Filename : FRAMES.CDE

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/