home *** CD-ROM | disk | FTP | other *** search
-
- PFL Language
- by Tim Finin
- from:
- November & December 1986 AI EXPERT article
- "Understanding Frame Languages"
-
-
- fdcl.lisp
-
- ;;; -*- Mode: LISP; Syntax: Zetalisp; Base: 10 -*-
-
- ;;; copyright (c) 1985 Tim Finin (tim@cis.upenn.edu)
-
- ;;; this file defines/loads the PFL system.
-
- #+ symbolics
- (defpackage pfl
- (:export fput frame fslots ffacets fget fvalues fremove ferase
- framep fsubsumes fdefineq fdefine ako instance subsumes-if
- subsumed-if))
-
- #+ symbolics
- (defsystem pfl
- (:name "Pedagogic Frame Representation Language")
- (:package "pfl")
- (:pathname-default "upenn:usr:[tim.frames]")è (:module pflvariables ("pflvariables"))
- (:module pflmacros ("pflmacros"))
- (:module pflbase ("pflbase"))
- (:module pfldisplay ("pfldisplay"))
- (:module pflthing ("thing"))
-
- (:compile-load pflvariables)
- (:compile-load pflmacros)
- (:compile-load pflbase (:fasload pflmacros))
- (:compile-load pfldisplay (:fasload pflmacros))
- (:load pflthing))
-
- #+vax
- (progn
- ;; VAXLISP system file for PFL.
- (require 'pflvariables "pflvariables.lisp")
- (require 'pflmacros "pflmacros.lisp")
- (require 'pflbase "pflbase.lisp")
- (require 'pfldisplay "pfldisplay.lisp")
- (require 'pflthing "pflthing.lisp")
- (export '(fput frame fslots ffacets fget fvalues fremove ferase
- framep fsubsumes fdefineq fdefine
- ako instance subsumes-if subsumed-if))
- (provide 'pfl))
-
-
-
-
- fvariables.lisp
-
- ;;; -*- Mode: LISP; Syntax: Common-lisp; Package: USER; Base: 10 -*-
-
- ;;; copyright (c) 1985 Tim Finin (tim@cis.upenn.edu)
-
- ;;; This file binds and initializes the global variables used in PFL.
-
- (defvar *frames* nil) ; a list of all frames in existence.
- (defvar *fdemons* t) ; should demons be triggered by default?
- (defvar *finherit* t) ; should inheritance be done by default?
- (defvar *fdefault* t) ; should default-values be used by default?
- (defvar *ftype* t) ; should type checking be done by default?
- (defvar *fnumber* t) ; should :min and :max checking be done by default?
-
- (provide 'pflvariables)
-
-
-
-
- fmacros.lisp
-
- ;;; -*- Mode: LISP; Syntax: Common-lisp; Package: USER; Base: 10 -*-
-
- ;;; copyright (c) 1985 Tim Finin (tim@cis.upenn.edu)
-
- ;;; local macros and utilities used in PFL.è
- ;; syntactic sugar for a mapcar, some and every.
- (defmacro foreach (V in L &rest body) `(mapcar #'(lambda (,V) ,@body) ,L))
-
- (defmacro forsome (V in L &rest body) `(some #'(lambda (,V) ,@body) ,L))
-
- (defmacro forall (V in L &rest body) `(every #'(lambda (,V) ,@body) ,L))
-
- (defmacro fwarn (msg &rest fillers) `(progn (format t ,msg ,@fillers) nil))
-
- ;; applies a function to a list of things, then unions the results.
- (defun collect (function sequence)(reduce #'onion (mapcar function sequence)))
-
- ;; like union, but works with 0 and 1 argument.
- (defun onion (&optional arg1 arg2) (union arg1 arg2))
-
- (provide 'pflmacros)
-
-
-
-
- fbase.lisp
-
- ;; -*- Mode: LISP; Syntax: Common-lisp; Base: 10; Package: USER -*-
-
- ;;; copyright (c) 1985 Tim Finin (tim@cis.upenn.edu)
-
- ;;; this file provides the basic PFL functions.
-
- ;;; SETTING FUNCTIONS ...
-
- (defun fput (frame slot facet datum
- &key (demons *fdemons*) (type *ftype*)
- (inherit *finherit*) (number *fnumber*))
- ;; adds a datum to a slot if its not their already.
- (cond ((member datum (fget-local frame slot facet)) datum)
- ((equal facet :value)
- (fput-value frame slot datum demons type inherit number))
- (t (fput-add frame slot facet datum) datum)))
-
- (defun fput-value (frame slot datum demons? type? inherit? number?)
- ;; adds a value to a slot if the types are ok and the
- ;; slot isn't full, then runs demons.
- (unless (and type? (not (fcheck-types frame slot datum)))
- (unless (and number? (not (fcheck-max frame slot)))
- (fput-add frame slot :value datum)
- (if demons?
- (foreach demon in
- (fget frame slot :if-added :inherit inherit?)
- (funcall demon frame slot datum)))
- datum)))
-
- (defun fcheck-types (frame slot value)
- ;; true iff value is subsumed by all of the slot's types.
- (forall type in (fget frame slot :type)è (or (fsubsumes type value)
- (fwarn "~%;; ~S can't fit into ~S of ~S because it's
- not subsumed by ~S" value slot frame type))))
-
- (defun fcheck-max (frame slot)
- ;; true if there's room for another value.
- (or (<= (length (fget-local frame slot :value))
- (fget-slot-max frame slot))
- (fwarn ";; Can't add another value to ~S of ~S" slot frame)))
-
- (defun fcheck-min (frame slot)
- ;; true if it's ok to remove a value
- (or (> (length (fget-local frame slot :value))
- (fget-slot-min frame slot))
- (fwarn ";; Can't remove a value from ~S of ~S " slot frame)))
-
- (defun fget-slot-max (f s)
- ; returns the max-cardinality for slot S of frame F.
- (let ((max (fget f s :max)))
- (if max (car max) most-positive-fixnum)))
-
- (defun fget-slot-min (f s)
- ; returns the min-cardinality for slot S of frame F.
- (let ((min (fget f s :min)))
- (if min (car min) 0)))
-
- (defun fput-add (frame slot facet datum)
- ;; adds datum to specified (frame,slot,facet)
- (rplacd (last (ffacet frame slot facet)) (list datum)))
-
- (defun ffacet (frame slot facet)
- ;; returns the expression representing the given facet of
- ;; a particular frame and slot, creating it if neccessary.
- (extend facet (extend slot (frame frame))))
-
- (defun extend (key alist)
- ;; like assoc, but adds key KEY if its not in the alist alIST.
- (or (assoc key (cdr alist)) (cadr (rplacd (last alist)(list (list key))))))
-
- ;;; ACCESSING FUNCTIONS ...
-
- ;; returns the structure which represents the frame named F.
- (defun frame (f) (or (get f 'frame) (fcreate f)))
-
- ;; returns a list of all local and inherited slots.
- (defun fslots (f &key (inherit *finherit*))
- (if inherit
- (collect 'fslots-local (flineage f))
- (fslots-local f)))
-
- (defun fslots-local (f)
- "returns just the local slots of frame f"
- (mapcar #'car (cdr (frame f))))
-
- (defun ffacets (f s &key (inherit *finherit*))è "returns a list of local and inherited facets for slot of frame"
- (if inherit
- (collect #'(lambda (x) (ffacets-local x s)) (flineage f))
- (ffacets-local f s)))
-
- (defun ffacets-local (f s) (mapcar 'car (cdr (assoc s (cdr (frame f))))))
-
- (defun fget (frame slot facet &key (inherit *finherit*)
- (demons *fdemons*) (default *fdefault*))
- (if (equal facet :value)
- (fvalues frame slot :inherit inherit :demons demons :default default)
- (fget1 frame slot facet inherit)))
-
- (defun fget1 (frame slot facet inherit?)
- ;; returns list of data for the given frame, slot and facet
- (or (fget-local frame slot facet)
- (if inherit?
- (forsome parent in (fparents frame)
- (fget1 parent slot facet t)))))
-
- (defun fget-local (frame slot facet)
- ;; returns the data in a facet w/o inheritance or demons.
- (cdr (assoc facet (cdr (assoc slot (cdr (frame frame)))))))
-
- (defun fvalues (f s &key (inherit *finherit*) (demons *fdemons*)
- (default *fdefault*) (finitial f))
- ;; returns values from frame F slot S, local or inherited.
- (or (fget-local f s :value)
- (and default (fget-local f s :default))
- (and demons (forsome demon in (fget-local f s :if-needed)
- (listify (funcall demon finitial s))))
- (and inherit
- (forsome parent in (fparents f)
- (fvalues parent s :inherit t
- :demons demons
- :default default
- :finitial finitial)))))
-
- (defun listify (l) (if (and l (atom l)) (list l) l))
-
- (defun fvalue (frame slot &key (inherit *finherit*) (demons *fdemons*)
- (default *fdefault*))
- "returns the 1st value in the specified slot"
- (car (fvalues frame slot :inherit inherit :demons demons :default default)))
-
- ;; returns the immediate parents of frame f.
- (defun fparents (f) (fget-local f 'ako :value))
-
- ;; returns a list of F and all of F's ancestor frames.
- (defun flineage (f) (cons f (collect #'flineage (fparents f))))
-
- ;;; FUNCTIONS TO REMOVE FRAMES, ETC. ...
-
- (defun fremove (frame slot facet datum
- &key (demons *fdemons*)è (inherit *finherit*)
- (number *fnumber*))
- ;; removes datum from frame's slot's facet and runs if-removed demons.
- (when (and (member datum (fget-local frame slot facet))
- (or (not (eq facet :value)) (fcheck-min frame slot)))
- (delete datum (ffacet frame slot facet))
- (if (and (eq facet :value) demons)
- (foreach demon in (fget frame slot :if-removed :inherit inherit)
- (funcall demon frame slot datum)))))
-
- (defun ferase (f &key (demons *fdemons*) (inherit *finherit*))
- "erases a frame, piece by piece (so that demons can fire)"
- (foreach slot in (append (delete 'ako (fslots-local f)) '(ako))
- (foreach facet in (ffacets-local f slot)
- (foreach datum in (fget-local f slot facet)
- (fremove f s facet datum :demons demons :inherit inherit))))
- (setq *frames* (delete f *frames*))
- (setf (get f 'frame) nil))
-
- ;;; PREDICATES
-
- (defun framep (f)
- "returns T iff its argument is a frame"
- (and (symbolp f) (get f 'frame) (member f *frames*)))
-
- (defun fsubsumes (super sub)
- "Does SUPER subsume SUB? One of {sub,super} must be a frame."
- (or (ako-chain sub super)
- (ako-subsumes-if sub super)
- (ako-subsumed-if sub super)))
-
- (defun ako-chain (sub super)
- "is there a chain of AKO likes from frame SUB to frame SUPER?"
- (and (framep sub) (framep super) (ako-chain1 sub super)))
-
- (defun ako-chain1 (sub super)
- (or (equal sub super)
- (forsome parent in (fparents sub) (ako-chain parent super))))
-
- (defun ako-subsumes-if (sub super)
- "is there a method on SUPER that says SUB is below it?"
- (and (framep super)
- (forsome pred in (fvalues super 'subsumes-if) (funcall pred sub))))
-
- (defun ako-subsumed-if (sub super)
- "is there a method on SUB that says SUPER is above it?"
- (and (framep sub)
- (forsome pred in (fvalues sub 'subsumed-if) (funcall pred sub))))
-
- ;;; FUNCTIONS TO CREATE and DEFINE FRAMES
-
- (defmacro fdefineq (frame parents &rest slots)
- ;; defines a frame named FRAME with parents PARENTS and slots SLOTS
- `(fdefine ',frame ',parents ',slots))
- è(defun fdefine (name parents slots)
- ;; (re)defines a frame, arguments are evaluated.
- (fcreate name)
- (foreach p in (if (listp parents) parents (list parents))
- (fput name 'ako :value p))
- (foreach slot in slots
- (foreach facet in (cdr slot)
- (foreach datum in (cdr facet)
- (fput name (car slot) (car facet) datum))))
- name)
-
- (defun fcreate (f)
- "creates a frame with name F"
- (setq *frames* (adjoin f *frames*))
- (setf (get f 'frame) (list f)))
-
- (provide 'pflbase)
-
-
-
-
- fdisplay.lisp
-
- ;;; -*- Mode: LISP; Syntax: Common-lisp; Package: USER; Base: 10 -*-
-
- ;;; copyright (c) 1985 Tim Finin (tim@cis.upenn.edu)
-
- ;;; This file defines functions to display frames, including:
- ;;; fshow - show all data in all facets of all slots of a frame.
- ;;; fshow-values - show just values of all slots of a frame.
-
- (defun fshow (frame &key (inherit *finherit*))
- ;; displays a frame
- (format t "~%frame ~S" frame)
- (foreach slot in (fslots frame :inherit inherit)
- (format t "~% slot ~S:" slot)
- (foreach facet in (ffacets frame slot :inherit inherit)
- (format t "~% ~S = " facet)
- (foreach datum in (fget frame slot facet :inherit inherit)
- (format t "~S " datum))))
- frame)
-
- (defun fshow-values (frame
- &key (inherit *finherit*)
- (demons *fdemons*)
- (default *fdefault*))
- ;; displays values in a frame
- (format t "~%frame ~S" frame)
- (foreach slot in (fslots frame :inherit inherit)
- (let ((values (fvalues frame slot
- :inherit inherit :demons demons :default default)))
- (WHEN values
- (format t "~% ~S = " slot)
- (foreach v in
- (if (atom values) (list values) values)è (format t "~S " v)))))
- frame)
-
- (provide 'pfldisplay)
-
-
-
-
- pflthing.lisp
-
- ;;; -*- Mode: LISP; Syntax: Common-lisp; Package: USER; Base: 10 -*-
-
- ;;; copyright (c) 1985 Tim Finin (tim@cis.upenn.edu)
-
- ;;; this is the default initialization file for the frame hierarchy.
- ;;; It sets up the hierarchy:
- ;;;
- ;;; thing
- ;;; frame - subsumes all PFL frames.
- ;;; slot - subsumes all PFL slots.
- ;;; ako - the PFL AKO slot.
- ;;; instance - The PFL instance slot.
- ;;; expression
- ;;; list
- ;;; number
-
- (fdefineq thing nil ; in the beginning was THING ...
- (ako (:type frame)
- (:if-added add-inverse)
- (:if-removed remove-inverse))
- (instance (:type frame)
- (:if-added add-inverse)
- (:if-removed remove-inverse)))
-
- (defun add-inverse (frame slot value)
- ;; add an inverse relation.
- (fput value (fvalue slot 'inverse) ':value frame))
-
- (defun remove-inverse (frame slot value)
- ;; remove an inverse relation
- (fremove value (fvalue slot 'inverse) ':value frame))
-
- (defun add-symmetric (frame slot value) (fput value slot :value frame))
- (defun remove-symmetric (frame slot value) (fremove value slot :value frame))
-
- ;; these are PFL related concepts....
-
- (fdefineq frame thing (subsumes-if (:value framep)))
-
- (fdefineq slot thing
- (inverse (if-added (lambda (f s d) (fput d 'inverse f)))
- (if-removed (lambda (f s d) (fremove d 'inverse f)))))
-
- (fdefineq ako slot (inverse (:value instance)))
- è(fdefineq instance slot (inverse (:value ako)))
-
- (fdefineq ILLEGAL nil
- ;; this is a frame that subsumes nothing.
- (subsumes-if (lambda (x) nil)))
-
- ;; These are commonly useful concepts.
-
- (fdefineq expression thing (subsumes-if (:value (lambda(x) t))))
-
- (fdefineq list expression (subsumes-if (:value listp)))
-
- (fdefineq number expression (subsumes-if (:value numberp)))
-
- (provide 'pfl-thing)
- ))))
-
- ;;; FUNCTIONS TO CREATE and DEFINE FRAMES
-
- (