-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathframework.lisp
3098 lines (2861 loc) · 131 KB
/
framework.lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
;;; Thu Mar 18 23:32:43 1993 by Mark Kantrowitz <[email protected]>
;;; framework.lisp -- 131661 bytes
;;; ****************************************************************
;;; FrameWork: A Frame Knowledge Representation Language ***********
;;; ****************************************************************
;;;
;;; FrameWork is a common-lisp portable frame-based knowledge
;;; representation language. It combines some of the better features
;;; of a variety of other frame languages. It includes a variety of
;;; tools for building, examining, and using knowledge-based systems.
;;; It is intended primarily to be a solid example of how such a system
;;; could be built. FrameWork is easily extended.
;;;
;;; Features:
;;; Generic demons (active values) & procedural attachment.
;;; Object-Oriented Programming with attribute and behavior inheritance
;;; in an associative network (methods and message passing)
;;; Cached values, Default values, Listener,
;;; Object database maintenance utilities.
;;;
;;; See associated file frame-systems.text for a listing of a variety
;;; of other frame systems.
;;;
;;; The FRL Manual and the FrameKit (v2.0) User's Guide were read to
;;; ensure that this system did not overlook any of the basic
;;; functionality of frame systems. The MacPIKS (v1.0) User's Guide
;;; (a frame system implemented by the author for the Planning Research
;;; Corporation in 1985) was also read to verify that FrameWork
;;; did *not* accidentally include any innovative ideas developed for
;;; MacPIKS.
;;;
;;; Written by Mark Kantrowitz, December 1990.
;;; Address: School of Computer Science
;;; Carnegie Mellon University
;;; Pittsburgh, PA 15213
;;;
;;; Copyright (c) 1990-1993. All rights reserved.
;;;
;;; See general license below.
;;;
;;; ****************************************************************
;;; General License Agreement and Lack of Warranty *****************
;;; ****************************************************************
;;;
;;; This software is distributed in the hope that it will be useful (both
;;; in and of itself and as an example of lisp programming), but WITHOUT
;;; ANY WARRANTY. The author(s) do not accept responsibility to anyone for
;;; the consequences of using it or for whether it serves any particular
;;; purpose or works at all. No warranty is made about the software or its
;;; performance.
;;;
;;; Use and copying of this software and the preparation of derivative
;;; works based on this software are permitted, so long as the following
;;; conditions are met:
;;; o The copyright notice and this entire notice are included intact
;;; and prominently carried on all copies and supporting documentation.
;;; o No fees or compensation are charged for use, copies, or
;;; access to this software. You may charge a nominal
;;; distribution fee for the physical act of transferring a
;;; copy, but you may not charge for the program itself.
;;; o If you modify this software, you must cause the modified
;;; file(s) to carry prominent notices (a Change Log)
;;; describing the changes, who made the changes, and the date
;;; of those changes.
;;; o Any work distributed or published that in whole or in part
;;; contains or is a derivative of this software or any part
;;; thereof is subject to the terms of this agreement. The
;;; aggregation of another unrelated program with this software
;;; or its derivative on a volume of storage or distribution
;;; medium does not bring the other program under the scope
;;; of these terms.
;;; o Permission is granted to manufacturers and distributors of
;;; lisp compilers and interpreters to include this software
;;; with their distribution.
;;;
;;; This software is made available AS IS, and is distributed without
;;; warranty of any kind, either expressed or implied.
;;;
;;; In no event will the author(s) or their institutions be liable to you
;;; for damages, including lost profits, lost monies, or other special,
;;; incidental or consequential damages arising out of or in connection
;;; with the use or inability to use (including but not limited to loss of
;;; data or data being rendered inaccurate or losses sustained by third
;;; parties or a failure of the program to operate as documented) the
;;; program, even if you have been advised of the possibility of such
;;; damanges, or for any claim by any other party, whether in an action of
;;; contract, negligence, or other tortious action.
;;;
;;; The current version of this software may be obtained by anonymous
;;; ftp from
;;; ftp.cs.cmu.edu:/user/ai/areas/kr/frames/framewrk/ [128.2.206.173]
;;;
;;; Please send bug reports, comments, questions and suggestions to
;;; [email protected]. We would also appreciate receiving any changes
;;; or improvements you may make.
;;;
;;; If you wish to be added to the [email protected] mailing list,
;;; send email to [email protected] with your name, email
;;; address, and affiliation. This mailing list is primarily for
;;; notification about major updates, bug fixes, and additions to the lisp
;;; utilities collection. The mailing list is intended to have low traffic.
;;;
;;; ********************************
;;; Change Log *********************
;;; ********************************
;;;
;;; mk = Mark Kantrowitz <[email protected]>
;;; nick = Nick Afshartous <[email protected]> or <[email protected]>
;;;
;;; 18-NOV-90 mk File created.
;;; 12-DEC-90 mk First released version.
;;; 7-DEC-92 nick Changed some of the framework symbols to keywords
;;; so the stuff in this file could be placed in its own
;;; package. Verified demons and methods.
;;; Changed DEFCLASS to take slots as an &rest arg.
;;; Made instances inherit demons.
;;; 26-FEB-93 mk Verified and extended some of Nick's changes.
;;; Changed several symbols to keywords that Nick missed.
;;; Fixed package definition to be CLtL2 compliant.
;;; 15-MAR-93 mk Fixed problem with frameget-z caused by :value being both a
;;; facet and a demon.
;;; 18-MAR-93 mk Modified the $ and $! reader macros to rebind the readtable
;;; instead of modifying and restoring the Common Lisp
;;; readtable. For some reason, AKCL barfs on this.
;;; ********************************
;;; To Do **************************
;;; ********************************
;;;
;;; Verify & Test:
;;; demons, methods, defclass, make-instance, frameget-Z, heritage.
;;; set of test frames, test demons and methods.
;;;
;;; Attach comments to data (frame) saying who and when modified.
;;;
;;; Frame Tracing Facility:
;;; ftrace, funtrace.
;;; Traces before and after a given facet is executed. Can specify
;;; when something should be printed, when it should call break
;;; to go into the debugger, and what it should print.
;;; print traces (*fw-trace*), print warnings (*fw-verbose*)
;;;
;;; Add RESTICTIONS (require facet of FRL):
;;; serves as constraints on the values that may fill the
;;; value facet. These are predicates on the VALUE which may
;;; fill the :value facet. When frameput tries to add a
;;; value, if a restriction demon returns nil, it fails and
;;; prints an error message (if *fw-verbose* is t). The
;;; predicates take VALUE and VALUES as args.
;;;
;;; Follow framekit idea of abstract data types for frames?
;;; i.e., have all lowlevel functions which deal with the structure
;;; of the representation actually be macros and isolate them from
;;; the rest of the code.
;;;
;;; Random to do comments are sprinkled throughout the code.
;;;
;;; ****************************************************************
;;; Documentation **************************************************
;;; ****************************************************************
;;;
;;; FrameWork, like all other frame based systems, is ultimately based
;;; on Minsky's frame theory of the representation of knowledge [Minsky 1975].
;;; A frame is an object with an associated list of attributes. Objects
;;; (ala object-oriented programming) are data structures with associated
;;; procedures. The attributes of a frame include VALUES and BEHAVIORS.
;;; Some behaviors, called DEMONS, are functions attached to attributes
;;; to monitor their access and modification, and initiate actions
;;; if invoked or otherwise activated.
;;;
;;; Using frames we can create a network of objects representing facts,
;;; things, and other concepts, connected through a variety of links.
;;; Objects and their links are represented as frames with names, slots,
;;; facets, and values. (Other frame systems may have more levels of
;;; representation. The primitives given in FrameWork, however, are easily
;;; extended to arbitrary numbers of levels because of the uniformity of
;;; representation.) Each object has a name (frame) and a set of slots;
;;; each slot has a set of facets; and each facet has a set of values.
;;; Values may be arbitrary lisp objects, including functions
;;; and the name of other frames. In some sense a frame is a generalized
;;; property list: it contains more than just values, and can inherit
;;; information from related frames.
;;;
;;; Frames are implemented as nested association lists (key-value pairs) and
;;; are stored in a hash table under the frame name for efficient access:
;;; (<frame name>
;;; (<slot1> (<facet1> . (<value1> <value2> ...))
;;; (<facet2> . (<value1> ...))
;;; ...)
;;; (<slot2> (<facet1> . (<value1> ...)) ...)
;;; ...)
;;;
;;; Slots may be used to name relations by making the name of one frame
;;; the value of the slot in another frame. For example, the :AKO slot
;;; (an abbreviation for "A Kind Of") and its inverse, :KINDSOF, link
;;; objects in the class hierarchy. Many other types of links exist,
;;; including user-defined links. These relations may be used to
;;; connect the frames into a network. (Note that the relationship defined
;;; by :AKO links is a network and need not be a hierarchy, since it is
;;; permissible for an object to have more than one :AKO value, and for
;;; many objects to be linked to the same parent by :AKO slot. For many
;;; functions even :AKO cycles are permitted, since these functions
;;; specifically check for cycles.)
;;;
;;; The primary facet is :VALUE, which is used to store the value of an
;;; attribute. Other system defined facets include :DEFAULT, :MODE,
;;; :METHOD, :If-Needed, :If-Fetched, :If-Removed. The :MODE facet is used
;;; to associate properties with objects. The :METHOD facet is used to
;;; name procedures that are invoked in response to messages to an object.
;;; The :If-Needed, :If-Fetched, :If-Removed, and :DEFAULT facets are demons
;;; which are used to monitor the :VALUE facet.
;;;
;;; In addition, there are demons which monitor the :VALUE facet and maintain
;;; inverse-slot relationships for any values stored there. For example,
;;; whenever a value x is stored into the :AKO slot of the object y, this
;;; demon automatically stores y into the :KINDSOF slot of the object x.
;;;
;;; ********************************
;;; User Guide *********************
;;; ********************************
;;;
;;; *VERSION* ("2.1 MON 15-MAR-93 12:00:47") [PARAMETER]
;;; Current version number/date for FrameWork.
;;;
;;; *DEFAULT-INHERITANCE-LINK* (:ako) [VARIABLE]
;;; Default link used for inheritance in FrameWork.
;;;
;;; *DEFAULT-INHERITANCE-FACET* (:value) [VARIABLE]
;;; Default facet used for inheritance in FrameWork.
;;;
;;; FRAMEWORK-COPYRIGHT (&optional (stream *standard-output*)) [FUNCTION]
;;; Prints a FrameWork copyright notice and header upon startup.
;;;
;;; CURRENT-TIME-STRING (&optional (mode 'hyphen)) [FUNCTION]
;;; Returns a string for the current time and date in a variety of modes.
;;;
;;; DATE-STRING (month date year &optional (mode 'hyphen)) [FUNCTION]
;;; Given a date, returns a string for the date in a variety of modes.
;;;
;;; YEAR-STRING (year &optional (mode 'long)) [FUNCTION]
;;; Formats a year number in various ways.
;;;
;;; TIME-STRING (hour min secs &optional (mode 'full)) [FUNCTION]
;;; Formats the current time in a variety of ways.
;;;
;;; DOW-STRING (dow &optional (mode 'short)) [FUNCTION]
;;; Formats the day of week in a variety of modes.
;;;
;;; MONTH-STRING (month &optional (mode 'short)) [FUNCTION]
;;; Formats the month in a variety of ways.
;;;
;;; FRAMEWORK-HERALD (&optional (stream *standard-output*)) [FUNCTION]
;;; Prints a FrameWork Herald. Does basic copyright statement,
;;; as well as the time and date.
;;;
;;; EQMEMB (item list &key (test #'equal)) [FUNCTION]
;;; Checks whether ITEM is either equal to or a member of LIST.
;;;
;;; NEQ (x y) [FUNCTION]
;;; not eq
;;;
;;; CAR-EQ (x y) [FUNCTION]
;;; Checks whether Y is eq to the car of X.
;;;
;;; DREMOVE (item list) [FUNCTION]
;;; Destructive remove which replaces the original list with the list
;;; that results when ITEM is deleted from LIST.
;;;
;;; DISPLACE (list val) [FUNCTION]
;;; Replaces LIST with VAL by destructively modifying the car and cdr of
;;; LIST. Warning: VAL must not share list structure with LIST or you'll
;;; be sorry.
;;;
;;; TAILPUSH (item list) [FUNCTION]
;;; Pushes ITEM onto the tail of LIST. Does not work if the list is null.
;;;
;;; DO-QUEUE (((&optional (node 'node) (queue 'queue) [MACRO]
;;; (children 'children) visited) initial-queue children-form
;;; &optional (dequeue-form '(pop queue)) (merge-form '
;;; (setq queue (append queue progeny))) result-form)
;;; &body body)
;;; Implements generic search using a queue representation.
;;; If the VISITED iteration variable is specified, checks to see if a
;;; node has already been visited before proceeding, to prevent
;;; infinite loops in the search when cycles are encountered. It also
;;; prevents multiple occurrences of a node when several inheritance
;;; paths lead to the same node. If VISITED is specified, it is the name
;;; of the variable where the search history is maintained.
;;;
;;; *FRAME-TABLE* ((make-hash-table :test #'equal)) [VARIABLE]
;;; Hash table where all the frame definitions are stored.
;;; Since we are using a hash table instead of a property list, the
;;; frame name need not be an atom. This allows us to attach
;;; information to any lisp object.
;;;
;;; *FRAMES* (nil) [VARIABLE]
;;; Global list of the names of all user defined frames.
;;;
;;; *SYSTEM-FRAMES* (nil) [VARIABLE]
;;; Global list of all system defined frame names. These frames define
;;; the default relations (slots) and their inverses. Frames included
;;; on this list are normally invisible to user deleting and saving
;;; operations.
;;;
;;; DEFINE-FRAME (name frame) [FUNCTION]
;;; Internal function for creating a new frame. Pushes the name of the
;;; frame onto the list of user defined frames.
;;;
;;; CREATE-FRAME (name) [FUNCTION]
;;; Creates a new blank frame named NAME.
;;;
;;; DEF-FRAME (name frame) [MACRO]
;;; External function for creating a new frame. The name and
;;; frame do not need to be quoted.
;;;
;;; FRAME (name) [FUNCTION]
;;; Returns the frame "property" (frame structure) of NAME if there is
;;; one; otherwise returns nil.
;;;
;;; FRAME+ (framename) [FUNCTION]
;;; Gets the frame associate with framename. If a frame structure does
;;; not already exist, creates a new one and returns it.
;;;
;;; FRAMEP (name) [FUNCTION]
;;; Predicate which returns T if NAME names a defined frame, nil
;;; otherwise.
;;;
;;; DELETE-FRAME (frame) [FUNCTION]
;;; Deletes a frame definition without removing any references
;;; to the frame in other frames.
;;;
;;; DELETE-FRAMES (&optional (frame-list *frames*)) [FUNCTION]
;;; Deletes a specified list of frames, which defaults to all user
;;; defined frames. Evaluating (delete-frames) is a quick way to
;;; undo your work without eliminating the system defined frames.
;;;
;;; FLISTP (flist) [FUNCTION]
;;; Returns T if the FLIST is a flist.
;;;
;;; FLIST-KEY (flist) [FUNCTION]
;;; Returns the key of a flist.
;;;
;;; FLIST-BUCKET (flist) [FUNCTION]
;;; Returns the bucket of a flist.
;;;
;;; FLIST-KEYS (flist) [FUNCTION]
;;; Returns a list of the keys of the items in the bucket of flist.
;;;
;;; FRAMEASSOC (key flist &key (test #'eq)) [FUNCTION]
;;; Finds the item with key KEY in the FLIST if present.
;;;
;;; FRAMEASSOC+ (key flist &key (test #'eq)) [FUNCTION]
;;; Finds item with key KEY in the FLIST if present, otherwise inserts
;;; it. Returns the entry.
;;;
;;; FLIST-GET (flist &rest path) [FUNCTION]
;;; Follows the key path down to the value. For retrieving items from
;;; an flist.
;;;
;;; FLIST-PUT (flist item &rest path) [FUNCTION]
;;; Stores ITEM in the bucket pointed to by the path of keys.
;;; Returns the modified FLIST.
;;;
;;; FLIST-DELETE (flist &rest path) [FUNCTION]
;;; Deletes the entire item accessed. Returns the modified FLIST.
;;;
;;; FLIST-CLEAR (flist &rest path) [FUNCTION]
;;; Deletes the bucket of the indicated item, but leaves the key.
;;; Returns the modified FLIST.
;;;
;;; FLIST-REPLACE (flist item &rest path) [FUNCTION]
;;; Replaces all existing items with the item. Returns the modified
;;; FLIST. Equivalent to Flist-Clear followed by Flist-Put.
;;;
;;; FRAMEGET (frame slot &optional (facet :value) (no-demons t)) [FUNCTION]
;;; Fetches information from a frame given an access path consisting of
;;; a frame, a slot, and a facet. FACET defaults to the :VALUE facet.
;;; Returns the list of values stored on the FACET facet of the SLOT
;;; slot of the object FRAME. The actual list within the frame is
;;; returned, so surgery performed on the list of values returned by
;;; FrameGet will change the frame. If no-demons is nil, will run
;;; [<FACET> :get :after] demons.
;;;
;;; FRAMEGET-INTERNAL (frame slot &optional (facet :value)) [FUNCTION]
;;; Internal version of frameget that does not execute demons.
;;;
;;; FRAMEGET! (frame slot &optional (facet :value) (no-demons t)) [FUNCTION]
;;; Assumes that there is only one value in the FACET facet of the SLOT
;;; slot of the object FRAME and returns it. (If there is more than one
;;; value, the first one is returned.)
;;;
;;; INV-SLOT (slot) [FUNCTION]
;;; Returns the inverse slot of SLOT, if it has one, otherwise nil.
;;;
;;; FRAMEGET-V-D (frame slot) [FUNCTION]
;;; First checks the :VALUE facet and returns the values if there are
;;; any. If there are no values in the :VALUE facet, returns any values
;;; present in the :DEFAULT facet of the frame's slot.
;;;
;;; HAS-SLOT (frame slot) [FUNCTION]
;;; Returns the tail of FRAME's slot list beginning with SLOT if
;;; FRAME has a slot named SLOT; otherwise nil.
;;;
;;; SLOTS (frame) [FUNCTION]
;;; Returns a list of the slots of the object FRAME.
;;;
;;; FACETS (frame slot) [FUNCTION]
;;; Returns a list of the facets of the SLOT slot of the object FRAME.
;;;
;;; SLOTNAMES (frame) [FUNCTION]
;;; Returns a list of the names of the slots of the object FRAME.
;;;
;;; FACETNAMES (frame slot) [FUNCTION]
;;; Returns a list of the names of the facets of the SLOT slot
;;; of the object FRAME.
;;;
;;; FRAMEPUT (frame slot facet value &optional no-demons) [FUNCTION]
;;; Used for placing information into a frame.
;;; Stores VALUE as one of the values of the FACET facet of the SLOT
;;; slot of the object FRAME. If no-demons is nil, runs any [<FACET> :put
;;; :after] demons. For example, the (:VALUE :PUT :AFTER) demon handles
;;; inverse slot maintenance: If FACET is eq to :VALUE and SLOT has an
;;; inverse, then FramePut also puts the object FRAME in the :VALUE facet
;;; of the (Inv-Slot SLOT) slot of VALUE. If VALUE is already present,
;;; does not run demons. Returns Value if it was stored, NIL otherwise.
;;;
;;; FRAMEPUT-INTERNAL (frame slot facet value) [FUNCTION]
;;; Internal version of FramePut which does not execute demons.
;;;
;;; FRAMEPUT! (frame slot facet value &optional no-demons) [FUNCTION]
;;; Stores VALUE as the *unique* value of the FACET facet of the SLOT
;;; slot of the object FRAME. It accomplishes this by first removing any
;;; existing value(s) from the frame.
;;;
;;; ADD-VALUE (frame slot value &optional no-demons) [FUNCTION]
;;; Adds a value to the :value facet of the frame's slot.
;;;
;;; MAKE-FRAME (name &rest slots) [MACRO]
;;; Defines a new frame named NAME with the specified SLOTS like
;;; Def-Frame, but with side-effects. Works by calling frameput.
;;;
;;; FRPLFACET (frame slot facet values) [FUNCTION]
;;; Stores VALUES as the values of the FACET facet of the SLOT slot
;;; of FRAME, replacing any previous values. Does not run any demons,
;;; and so does not maintain inverse slot relationships.
;;; This is a fast way to store multiple values. Reports an error if
;;; VALUES is not a list.
;;;
;;; FRAMEREMOVE (frame slot facet value &optional no-demons) [FUNCTION]
;;; Deletes VALUE from the FACET facet of the SLOT slot of the object
;;; FRAME. In no-demons is nil, runs any [<FACET> :remove :after]
;;; demons. The demons include inverse-slot maintenance: If FACET is
;;; :VALUE and SLOT has an inverse, then FrameRemove also removes FRAME
;;; from the (Inv-Slot SLOT) :value of VALUE. Returns VALUE if it was
;;; deleted, nil otherwise.
;;;
;;; FRAMEREMOVE-INTERNAL (framename slotname facetname value) [FUNCTION]
;;; Internal version of FrameRemove which does not execute demons.
;;;
;;; KILL-FACET (frame slot facet &optional no-demons) [FUNCTION]
;;; Deletes the entire FACET facet from the SLOT slot of the object
;;; FRAME. Returns FACET if it was deleted, nil otherwise. If no-demons
;;; is nil, runs any associated demons, such as inverse-slot maintenance.
;;;
;;; KILL-SLOT (frame slot &optional no-demons) [FUNCTION]
;;; Deletes the entire SLOT slot of the object FRAME.
;;; Returns SLOT if it was deleted, nil otherwise. If no-demons is
;;; nil, runs any associated demons, such as inverse-slot maintenance.
;;;
;;; KILL-FRAME (frame &optional no-demons) [FUNCTION]
;;; Deletes the object FRAME.
;;; Returns FRAME if it was deleted, nil otherwise. If no-demons is
;;; nil, runs any associated demons, such as inverse-slot maintenance.
;;;
;;; (SETF FRAMEGET) (value) [SETF MAPPING]
;;;
;;; (SETF FRAMEGET!) (value) [SETF MAPPING]
;;;
;;; MERGE-FRAME (mainframe mergee) [FUNCTION]
;;; Merges mergee into mainframe. If a slot was present in both MainFrame
;;; and Mergee, all of its facets are seen as they were in MainFrame.
;;; Surgery performed on Mergee will change MainFrame. Does not run any
;;; demons, and so does not maintain inverse slot relationships.
;;;
;;; SHARE-SLOT (frame1 slot frame2) [FUNCTION]
;;; Makes FRAME2 share FRAME1's SLOT by destructive modification if
;;; FRAME2 does not already have a slot named SLOT. Later surgery
;;; performed on the contents of SLOT in either frame affects both
;;; frames. For example, any value installed in FRAME1 or FRAME2 using
;;; FramePut will be shared by both frames. Does not run any demons,
;;; and so does not maintain inverse slot relationships.
;;;
;;; COPY-SLOTS (frame1 slots frame2 &optional facet-restrictions) [FUNCTION]
;;; Copies all slots in the list SLOTS from FRAME1 to FRAME2.
;;; Maintains inverse slot relationships. Facet-restrictions is a list
;;; of facets to copy. If nil, all facets of the slots are copied.
;;; Returns nil.
;;;
;;; @ (&optional frame slot facet value) [FUNCTION]
;;; Indirection pointer to the data in another frame.
;;; Behaves like FramePut if the first four arguments are non-NIL,
;;; and like FrameGet if only the first three are non-NIL. If only
;;; FRAME and SLOT are given, returns the list of SLOT's facets.
;;; If only FRAME is given, returns the list of FRAME's slots.
;;;
;;; IMMEDIATE-PROGENY (frame paths) [FUNCTION]
;;; Returns the children of FRAME along the specified PATHS. PATHS
;;; can be either a list of possible paths, or a single path.
;;;
;;; FRAMEGETCLASSES (frame &optional (path :ako)) [FUNCTION]
;;; Returns a list of the classes of a frame.
;;;
;;; TRANSITIVE-CLOSURE (frame &optional (slot :ako) (facet :value)) [FUNCTION]
;;; Finds the transitive closure of FRAME by following paths specified
;;; by SLOT/FACET by traversing the paths in a breadth-first manner.
;;; Returns the set of all frames found without duplicates. Checks to
;;; see if a frame has already been visited before proceeding, to
;;; prevent infinite loops when cycles are encountered.
;;;
;;; LEAVES (frame &optional (slot :kindsof) (facet :value)) [FUNCTION]
;;; Finds the leaf nodes (buds) of the tree rooted at FRAME by descending
;;; SLOT/FACET paths by traversing the paths in a breadth-first
;;; manner. Returns the set of all frames found without duplicates.
;;; Checks to see if a frame has already been visited before
;;; proceeding, to prevent infinite loops when cycles are encountered.
;;;
;;; PROGENY (frame &optional (slot :kindsof) (facet :value)) [FUNCTION]
;;; Finds the progeny of FRAME by following SLOT/FACET paths by
;;; traversing the paths in a breadth-first manner. Returns the
;;; set of all frames found without duplicates. Checks to see if
;;; a frame has already been visited before proceeding,
;;; to prevent infinite loops when cycles are encountered.
;;;
;;; KILL-PATH (frame &optional (slot :kindsof) (facet :value)) [FUNCTION]
;;; Kills FRAME and all of its progeny by following SLOT/FACET paths
;;; by traversing the paths in a breadth-first manner. As each object
;;; is destroyed, inverse slot relationships are maintained by
;;; calling appropriate removal demons. This function is intended for
;;; the destruction of temporary objects. Frame kernel objects are
;;; protected against Kill-Path.
;;; Returns the set of all frames found without duplicates.
;;; Checks to see if a frame has already been visited before
;;; proceeding, to prevent infinite loops when cycles are encountered.
;;;
;;; %FRAME (nil) [VARIABLE]
;;; Global variable containing frame environment's frame arg
;;; for use by demons.
;;;
;;; %SLOT (nil) [VARIABLE]
;;; Global variable containing frame environment's slot arg
;;; for use by demons.
;;;
;;; %FACET (nil) [VARIABLE]
;;; Global variable containing frame environment's facet arg
;;; for use by demons.
;;;
;;; %VALUE (nil) [VARIABLE]
;;; Global variable containing frame environment's value arg
;;; for use by demons.
;;;
;;; %OTHER-ARGS (nil) [VARIABLE]
;;; Global variable containing frame environment's other args
;;; for use by demons.
;;;
;;; *VALUES-MODES* ('((:first \. some) (:no-values \. mapc) [VARIABLE]
;;; (:append \. mapcan) (:collect \. mapcar)))
;;; Global variable containing all methods frame-eval may use
;;; to collect values from demon invocation.
;;;
;;; FRAME-EVAL (demons values-mode frame slot facet [FUNCTION]
;;; &optional value other-args)
;;; Binds %frame, %slot, %facet, %value and %other-args in the
;;; Frame Environment to the supplied values, and then runs
;;; the demons, returning the result as specified by the values mode.
;;; Possible values-modes include :FIRST, :NO-VALUES, :APPEND, and
;;; :COLLECT. Demons is a list of demons, which are forms to be evaluated
;;; in the frame environment.
;;;
;;; DEMON-P (demon) [FUNCTION]
;;; Returns T if the frame is a demon.
;;;
;;; DEFINE-DEMON ((demon-frame &optional (demon-slot :demon) [MACRO]
;;; (demon-facet :value)) &body body)
;;; Macro for defining a new demon. The first argument is the name of the
;;; demon (i.e., where it is stored) followed by the body of the
;;; definition. The name is of the form (demon-frame demon-slot
;;; demon-facet), where demon-frame is the main name of the demon and the
;;; slot and facet further characterize the demon's actions. Demons have
;;; access to the frame environment, which consists of the global
;;; variables %frame %slot %facet %value of the calling frame and
;;; %other-args.
;;;
;;; RUN-DEMON (demon-frame &optional (demon-slot :demon) [FUNCTION]
;;; (demon-facet :value) (values-mode :append) frame slot
;;; facet value other-args)
;;; Retrieves the demon definition and evaluates it in the frame
;;; environment using frame-eval. Values-mode specifies how values
;;; are returned: no-values, append, collect, or just the first value.
;;;
;;; *CACHE-VALUES* (nil) [VARIABLE]
;;; If T, the result of FrameGet-Z demon invocation is cached in the
;;; VALUE slot of the calling frame.
;;;
;;; FRAMEGET-Z (frame slot facet &key legal-demons (path :ako) [FUNCTION]
;;; (path-facet :value) path-focus ancestors-focus args
;;; (cache-values *cache-values*) (values-mode :append))
;;; Returns the same list as FrameGet, unless the frame object has
;;; no slot-facet values, in which case a breadth-first search
;;; is performed along the path relation from the frame until
;;; such values are found. This enables slot values to be inherited
;;; through network links. Information which is common to many objects
;;; may be stored in a common ancestor (instead of redundantly storing
;;; it in each object) and inherited by its progeny. Also
;;; value-returns the unexplored queue.
;;; LEGAL-DEMONS is a list of demons to try if the facet has no value.
;;; For example, if we want to definitely check :DEFAULT and
;;; :IF-NEEDED demons, instead of relying on frameget's demon invocation,
;;; specify LEGAL-DEMONS as '(:DEFAULT :IF-NEEDED).
;;; Path-focus is an extra path tried for the first frame. This is
;;; useful for methods, where the first frame could be an instance of a
;;; class instead of a class. Ancestors-focus is a list of ancestors to
;;; be focused upon instead of starting the search at the frame -- this
;;; is useful in method invocation where we sometimes want to consider
;;; only a specific set of ancestors of the frame.
;;; If cache-values is T, values from FrameGet-Z invocation are cached
;;; in the :VALUE facet of the slot.
;;;
;;; Values-mode specifies how the values of demon invocation should be
;;; returned.
;;;
;;; FRAMEGET-Z-LOCAL (frame slot facet dfacets [FUNCTION]
;;; &optional args (cache-values *cache-values*)
;;; (values-mode :append))
;;; Returns the value of the first facet or demon-facet that has a value.
;;;
;;; IS (node supernode &optional (path :ako) (blockcats nil) [FUNCTION]
;;; visited)
;;; Returns non-NIL if, following path links, node is a descendent of
;;; supernode if supernode is an atom, or if node is a member of
;;; supernode if supernode is a list. The search along path will ignore
;;; blockcats.
;;;
;;; CLASS-P (node) [FUNCTION]
;;; Tests to see if its argument is a class.
;;;
;;; SUPERCLASSES (node) [FUNCTION]
;;; Returns the superclasses of a node.
;;;
;;; (SETF SUPERCLASSES) (value) [SETF MAPPING]
;;;
;;; SUBCLASSES (node) [FUNCTION]
;;; Returns the subclasses of a node.
;;;
;;; (SETF SUBCLASSES) (value) [SETF MAPPING]
;;;
;;; DEFCLASS (name superclasses &rest slots) [MACRO]
;;; Defines a new class with the specified name, superclasses and slots.
;;; Superclasses defaults to (THING) if not given by the user, so that
;;; the class hierarchy is rooted at THING.
;;;
;;; SUBCLASS-P (node &optional (superclass :thing)) [FUNCTION]
;;; Tests to see if its argument is a subclass of superclass, which
;;; defaults to the root class.
;;;
;;; SUPERCLASS-P (node &optional subclass) [FUNCTION]
;;; Tests to see if its argument is a superclass of subclass, which
;;; defaults to nil.
;;;
;;; INSTANCE-OF (node) [FUNCTION]
;;; Returns the CLASS of a node.
;;;
;;; (SETF INSTANCE-OF) (class) [SETF MAPPING]
;;;
;;; INSTANCE-P (node) [FUNCTION]
;;; Tests to see if its argument is an instance, but doesn't care of what
;;; frame it is an instance.
;;;
;;; INSTANCES (node) [FUNCTION]
;;; Returns the instances of a node.
;;;
;;; IS-A-P (node supernode) [FUNCTION]
;;; Tests to see if NODE is a SUPERNODE by searching the class hierarchy.
;;; Will traverse one CLASS link at the start of the search to
;;; correctly process leaf instances, and then continues with :AKO links.
;;; Returns the type of link (:CLASS or :AKO) or NIL.
;;;
;;; INSTANCE-NAME (type) [MACRO]
;;; Generates a new symbol, given the basic name of the frame.
;;; This is used to guarrantee a unique frame name by adding a
;;; numerical suffix to the name.
;;;
;;; MERGE-HERITAGE (frame class &key (path :ako) [FUNCTION]
;;; (path-facets '(:value)) slots-to-ignore)
;;; Merges the structure pointed to by the FRAME with all the
;;; corresponding structures of the frames accessible along the :AKO
;;; link. SLOTS-TO-IGNORE is a list of the slots which shouldn't be
;;; merged. Values are appended.
;;;
;;; MAKE-INSTANCE (class &rest slot-values-list) [FUNCTION]
;;; Generates a new instance of the class: Creates a name for the
;;; instance, a frame for the name, and links that frame to the class via
;;; a CLASS link. Copies the default slot values inherited from the class
;;; hierarchy into the instance and then initializes the supplied slot
;;; values. Class, slotnames, and slot values must all be quoted. For
;;; example, (make-instance 'elephant 'name "Clyde".
;;; Returns the name of the instance.
;;;
;;; INITIALIZE-SLOTS (frame slot-values-list) [FUNCTION]
;;; Initializes the values of the specified slots in frame, installing
;;; them in the :value facet. Slot-values-list is a list of
;;; alternating slot names and values.
;;;
;;; EXTRACT-DECLARATIONS (body &optional environment) [FUNCTION]
;;; Extracts the documentation string and declarations from a function
;;; body.
;;;
;;; DEFMETHOD ((message-name frame &optional (mode :method)) arglist [MACRO]
;;; &body body)
;;; Defines a method for message MESSAGE-NAME for the FRAME object.
;;; Mode is either :METHOD, :BEFORE or :AFTER, for regular methods,
;;; before and after methods.
;;;
;;; *ANCESTORS-QUEUE* (nil) [VARIABLE]
;;; Global variable accessible to methods that contains a list that
;;; represents the state of the queue in FrameGet-Z when this method
;;; was found.
;;;
;;; *CALLING-FRAME* (nil) [VARIABLE]
;;; Global variable accessible to methods that contains the name of
;;; the frame to which the message was sent.
;;;
;;; *MESSAGE-NAME* (nil) [VARIABLE]
;;; The name of the current message being processed.
;;;
;;; *MESSAGE-ARGUMENTS* (nil) [VARIABLE]
;;; The list of arguments of the current message being processed.
;;;
;;; *METHOD-TYPE* (:method) [VARIABLE]
;;; The type of method currently being applied (:method, :before,
;;; or :after).
;;;
;;; CALL-NEXT-METHOD "()" [MACRO]
;;; Calls the next method up in the calling hierarchy for this frame.
;;;
;;; SEND (frame message &rest args) [FUNCTION]
;;; Sends a message to the frame, and receives method(s) from the frame
;;; for dealing with the message. Executes the methods in the frame
;;; environment of the calling frame, along with any supplied
;;; arguments.
;;;
;;; RUN-METHODS (frame message args &optional (type :method) [FUNCTION]
;;; ancestors)
;;; Sends MESSAGE to FRAME, retrieving any methods of the proper TYPE
;;; (:METHOD, :AFTER, or :BEFORE). Calls the methods on the ARGS. If
;;; ANCESTORS is supplied, it is used as the focus for where to begin
;;; searching for methods.
;;;
;;; SAVE-FRAMES (&optional (filename "output.fwk") [FUNCTION]
;;; (frames *frames*))
;;; Pretty prints the frames created by FrameWork into a file. The frames
;;; are both human readable and lisp readable (so that loading the
;;; file restores the frames into lisp).
;;;
;;; SAVE-FRAME (frame &key (stream *standard-output*)) [FUNCTION]
;;;
;;; *DEFAULT-PPFRAME-INDENT* (3) [VARIABLE]
;;; Indentation factor: amount the indent is increased
;;; at each additional level.
;;;
;;; PPF (frame &optional (stream *standard-output*) [FUNCTION]
;;; &key (readable t) (indent 0))
;;; A synonym for pprint-frame.
;;;
;;; PPRINT-FRAME (frame &optional (stream *standard-output*) [FUNCTION]
;;; &key (readable t) (indent 0))
;;; If readable is NIL, parentheses are omitted.
;;;
;;; *MAX-LEVELS* (3) [VARIABLE]
;;; Maximum number of levels in a Frame.
;;;
;;; PPRINT-FRAME-INTERNAL (frame stream &optional (readable t) [FUNCTION]
;;; (indent 0) (level 0))
;;;
;;; *FRAMEWORK-PROMPT* ("~%fw> ") [VARIABLE]
;;; Prompt used in the FrameWork Listener.
;;;
;;; *PRINT-FRAME-BODIES* (t) [VARIABLE]
;;; If the result of a command execution is the name of a frame, the
;;; frame body will be printed and the name returned.
;;;
;;; *FRAMEWORK-COMMANDS* (nil) [VARIABLE]
;;; List of defined commands for the listener.
;;;
;;; FRAMEWORK-COMMAND (name short-doc long-doc function) [STRUCTURE]
;;;
;;; DEFINE-FW-LISTENER-COMMAND (name arg-list short-doc long-doc [MACRO]
;;; &body body)
;;; Defines a new command for the FrameWork listener. Name is either the
;;; name of the command, or a list of synonyms. Short-doc is for the
;;; summary help display. Long-doc is what should be displayed when
;;; asking for detailed help on the command. If the last form in the
;;; body is :noprint, the result of evaluating the command is not
;;; printed. When called from the listener, the rest of the line is
;;; received as arguments.
;;;
;;; DELETE-COMMAND (name) [FUNCTION]
;;; Deletes a FrameWork listener command.
;;;
;;; FIND-COMMAND (name) [FUNCTION]
;;; Finds the FrameWork listener command with that name or nickname.
;;;
;;; LISTIFY-STRING (string) [FUNCTION]
;;; Turns a string into a list of symbols.
;;;
;;; *SCHEDULE* (nil) [VARIABLE]
;;; A list of actions which are executed once every tick of the clock.
;;; They must have bounded execution time.
;;;
;;; GET-INPUT (&optional (stream *standard-input*)) [FUNCTION]
;;; Gets input from the user. If the user isn't typing anything, runs
;;; any functions found on the *schedule*.
;;;
;;; LISTENER "()" [FUNCTION]
;;; A READ-EVAL-PRINT loop for convenient interaction with FrameWork and
;;; demoing the system. Interprets framework commands in abbreviated
;;; form, without parentheses and quotes. Typing the name of a frame will
;;; display it pretty printed. Frames created using the listener are
;;; accessible to the save-frame utility.
;;;
;;; FRAMEWORK-EVAL (line) [FUNCTION]
;;; Evaluates commands typed to the framework listener by the user.
;;; If the line begins with a symbol, and that symbol represents a
;;; framework listener command, the apropriate command is called
;;; with the rest of the line as input. If the symbol is the name
;;; of a frame, it is pretty printed. Otherwise the line is treated
;;; like a regular lisp form.
;;;
;;; EXPLODE (symbol) [FUNCTION]
;;;
;;; IMPLODE (list) [FUNCTION]
;;;
;;; CRUSH (a b) [FUNCTION]
;;;
;;; *PROPERTIES-ARE-SYMBOLS* (nil) [VARIABLE]
;;; If T, properties are represented as P and ~P.
;;; If NIL, properties are represented as P and (NOT P).
;;;
;;; NEGATE (property) [FUNCTION]
;;; Forms the negation of property.
;;;
;;; HAS-PROPERTY (frame property &optional (path :ako) [FUNCTION]
;;; (path-facet :value) (property-slot :ako)
;;; (property-facet :mode))
;;; Checks whether FRAME has the given PROPERTY. Property values are
;;; stored on the MODE facet of the :AKO slot, and may be inherited
;;; in a breadth-first manner from ancestors along the :AKO path. The
;;; inheritance of a given property P may be blocked by the property
;;; ~P (NOT P) occurring somewhere along the path from FRAME to the
;;; ancestor with the property P. This provides for inheritance with
;;; exceptions.
;;;
;;; TREE-PATH (frame paths &optional (restrict nil) [FUNCTION]
;;; (show-frame nil) (visited nil))
;;; Constructs a tree from FRAME's inheritance along PATHS, suitable
;;; for displaying using a graphing function. The resulting tree is
;;; of the form (root subtree1 subtree2 ...) where each subtree is
;;; of the same form. If SHOW-FRAME is T, includes the actual frame
;;; structure of the leaves. RESTRICT is either a maximum depth,
;;; a property, or a function of the form (FUNCALL <function> .
;;; <args>). If RESTRICT is a property, only nodes with that property are
;;; shown, with intermediate nodes visible, of course.
;;;
;;; FRAME-REP (frame restrict &optional show-if-fails show-frame) [FUNCTION]
;;; Creates a representation for the frame as a node in the graph.
;;;
;;; *SHOW-PARENTHESES* (t) [VARIABLE]
;;; If T, shows the parentheses around the values.
;;;
;;; TREE-COPY (tree &optional (keyp t) [FUNCTION]
;;; (show-parens *show-parentheses*))
;;; Returns a copy of TREE (a frame). If show-parens is T, puts
;;; parentheses around the values. This is useful for display them as
;;; individual nodes of the frame, instead of just a big list.
;;;
;;; *PATH-SPECIAL-SYMBOLS* ('(demon ako kindsof value default [VARIABLE]
;;; if-needed if-added if-removed if-fetched
;;; mode put get remove after before method
;;; class instances thing type types parent
;;; child part-of parts is-component-of
;;; components))
;;; Symbols which should be treated as if they were in the keyword
;;; package for path reading.
;;;
;;; PATH-READER (stream char) [FUNCTION]
;;; Reader macro which reads in a special path syntax. For example,
;;; $!cat.ako --> MAMMAL
;;; $cat.ako --> (MAMMAL SIAMESE).
;;;
;;; PATH-GET! (frame &rest path) [FUNCTION]
;;; Extracts the value at the end of the path beginning at frame
;;; using frameget!. E.g., (path-get! me 'office 'room-number).
;;; Here a path is a series of slots.
;;;
;;; PATH-GET (frame &rest path) [FUNCTION]
;;; Extracts the values at the end of the path beginning at frame
;;; using frameget. E.g., (path-get me 'office 'room-number).
;;; Here a path is a series of slots.
;;;
;;; DEFINE-INVERSE-SLOTS (slot1 slot2) [FUNCTION]
;;; Defines two slots as slots and inverses of each other.
;;;
;;; ****************************************************************
;;; FrameWork Kernel ***********************************************
;;; ****************************************************************
;;; Let's be smart about CLtL2 compatible Lisps:
(eval-when (compile load eval)
#+(or (and :excl (or :allegro-v4.0 :allegro-v4.1))
:mcl
(and :lucid :lcl4.0)
(and :cmu :new-compiler)
:clisp
)
(pushnew :cltl2 *features*))
#-:cltl2
(in-package "FRAMEWORK" :nicknames '("FW"))
#-:cltl2
(shadow '(defclass make-instance defmethod call-next-method) "FW")
#+:cltl2
(defpackage "FRAMEWORK" (:nicknames "FW")
(:shadow defclass make-instance defmethod call-next-method)
(:use #-:lucid "COMMON-LISP"
#+:lucid "LISP" #+:lucid "LUCID-COMMON-LISP"))
#+:cltl2
(unless (find-package "FRAMEWORK")
(make-package "FRAMEWORK" :nicknames '("FW"))
(shadow '(defclass make-instance defmethod call-next-method) "FW")
(use-package '("COMMON-LISP") "FW"))
#+:cltl2
(in-package "FRAMEWORK")
(pushnew :framework *features*)
(export '(*version* *frames* *system-frames*
Frame Frame+ FrameP
Def-Frame Create-Frame
Delete-Frame Delete-Frames
FrameAssoc FrameAssoc+
FrameGet FrameGet! FrameGet-V-D
FramePut FramePut! Add-Value
FrameRemove Kill-Frame Kill-Slot Kill-Facet
FrplFacet
Inv-Slot
Slots SlotNames Facets FacetNames Has-Slot GetTail
Merge-Frame Share-Slot Copy-Slots @
Immediate-Progeny
FrameGetClasses Transitive-Closure Leaves Progeny Kill-Path
Demon-P Define-Demon Frame-Eval Run-Demon
FrameGet-Z *cache-values*
Class-P Superclasses Subclasses DefClass Subclass-P Superclass-P
Instance-Of Instance-P Instances
Defmethod Make-Frame Make-Instance Send Call-Next-Method
Is-A-P Is
Save-Frames Save-Frame
PPF PPrint-Frame *default-ppframe-indent*
Listener *print-frame-bodies* Define-Fw-Listener-Command
Has-Property Negate Tree-Path Tree-Copy *Show-Parentheses*
Path-Get Path-Get!
Define-Inverse-Slots
%frame %slot %facet %value %other-args
))
;;; ********************************
;;; Global Variables ***************
;;; ********************************
(defparameter *version* "2.1 THU 18-MAR-93 23:33:04"
"Current version number/date for FrameWork.")
;;; Should we have globals for default inheritance link and facet?
;;; These globals currently aren't used in the functions.
(defvar *default-inheritance-link* :ako
"Default link used for inheritance in FrameWork.")
(defvar *default-inheritance-facet* :value
"Default facet used for inheritance in FrameWork.")
;;; ********************************
;;; Copyright and Herald ***********
;;; ********************************
(defun framework-copyright (&optional (stream *standard-output*))