|
The following is a list of changes in SNePS version 2.7. Only
changes that are visible to the SNePS user are listed.
SNePS 2.7 also includes some additional improvements.
Note: If the installer chooses to make either the Java-SNePS API or the
JUNG /JIMI
version of show
available, the installation must have Franz's Allegro
CL or else one of the prepackaged SNePS executables must be used.
- SNePS
-
- The speed of computing the union of node sets has been improved.
- The
intext command runs the load function
documented below.
- Previously, one could not have a node named with a string the Lisp
reader could not handle, such as "#", and
node-to-lisp-object did not handle nodes with names like
"5 pounds". Both these problems are now fixed. A node's name can now
be any Lisp number, string, or symbol, and
node-to-lisp-object is able to handle it.
- Previously,
*infertrace* and *plantrace*
defaulted to t , so that tracing was done unless turned
off. Now, the default values are nil , so that tracing is
not done unless turned on.
- SNePSLOG
-
- The SNePSLOG parser has been completely rewritten, improved, and
made more robust.
Error messages should be more understandable.
The SNePSLOG syntax is now:
Note: _(_ and _)_ are the object language characters between the _ marks.
input ::= wffNameCommand | snepslogCommand | wffCommand
wffNameCommand ::= wffName terminalPunctuation
wffCommand ::= wff terminalPunctuation ; wff must not be a single symbol
wff ::= infixedTerm | entailment | prefixedTerm
infixedTerm ::= prefixedTerm [( and | or | <=> ) prefixedTerm]+
entailment ::= termSet (=> | v=> | &=> | <Lisp integer> =>) termSet
pTermSet ::= termSet ; but taken to denote all terms that match
termSet ::= prefixedTerm | { termSequence }
termSequence ::= prefixedTerm [, prefixedTerm]*
prefixedTerm ::= negatedTerm | andorTerm | allTerm | nexistsTerm |
threshTerm | atomicTerm
negatedTerm ::= ~ atomicTerm
andorTerm ::= andor (i, j) termSet ; i, j integers, 0 <= i <= j
threshTerm ::= thresh (i [, j]) termSet ; i, j integers, 0 <= i <= j
allTerm ::= all _(_ symbolSequence _)_ _(_ wff _)_ ; but wff cannot be an atomic symbol
nexistsTerm ::= nexists nexistsParameters
_(_ symbolSequence _)_
_(_ termSet : termSet _)_
nexistsParameters ::= _(_ i, j, k _)_ | _(_ _, j, _ _)_ | _(_ i, _, k _)_
atomicTerm ::= wffName | qvar | SNePSLOGsymbol |
withsome/allTerm | ; in mode 3 only
(qvar | SNePSLOGsymbol) _(_ termSetSequence _)_ |
_(_ wff _)_
withsome/allTerm ::= (withsome | withall) _(_ symbolSequence, termSet, termSet [, termSet] _)_
termSetSequence ::= termSet [, termSet]*
symbolSequence ::= SNePSLOGsymbol [, SNePSLOGsymbol]*
wffName ::= wff <Lisp integer, i> ; Assuming that mi is a SNePS node
qvar ::= ? SNePSLOGsymbol
SNePSLOGsymbol ::= (wff <Lisp integer>) | <Lisp atom>
terminalPunctuation ::= . | ! | ? | ??
snepslogCommand ::= %-command |
^-command |
a-command |
c-command |
d-command |
e-command |
l-command |
n-command |
p-command |
r-command |
s-command |
t-command |
u-command
%-command ::= % <SNePSUL command>
^-command ::= ^^ | ^ <Lisp form>
a-command ::= activate wff [.] |
activate! wff [terminalPunctuation] |
add-to-context SNePSLOGsymbol termSet [.]|
ask wff [terminalPunctuation] |
askifnot wff [terminalPunctuation] |
askwh wff [terminalPunctuation] |
askwhnot wff [terminalPunctuation]
c-command ::= clear-infer [.] |
clearkb [.]
d-command ::= define-frame SNePSLOGsymbol <Lisp list> [<Lisp string>] [.] |
define-path SNePSRelation SNePSPath [.] |
describe-terms [pTermSet] [.] |
describe-context [SNePSLOGsymbol] [.] |
demo [<file path> | ? | i] [t | b | bv | a | av | n] [.]
e-command ::= expert [.]
l-command ::= lisp [.] |
list-contexts [.] |
list-terms [pTermSet] [.] |
list-wffs [.] |
list-asserted-wffs [SNePSLOGsymbol] [.] |
load <file path>
n-command ::= normal [.]
p-command ::= perform atomicTerm
r-command ::= remove-from-context SNePSLOGsymbol pTermSet
s-command ::= set-context SNePSLOGsymbol [pTermSet]
::= set-default-context SNePSLOGsymbol
::= set-mode-1
::= set-mode-2
::= set-mode-3 [t | nil]
::= show [pTermSet] [.]
t-command ::= trace [SNePSLOGsymbol]* [.]
Specially recognized symbols: inference, acting, translation, parsing
u-command ::= undefine-path SNePSRelation [.]
::= unlabeled [.]
::= untrace [SNePSLOGsymbol]* [.]
Specially recognized symbols: inference, acting, translation, parsing
- The SNePSLOG
load
command runs the load function discussed below. -
Normal output from SNePSLOG now shows the wff number
(
wffi ) before each top-level wff listed. The old,
unlabeled, output is obtained by giving SNePSLOG the
unlabeled command. Output produced after the
expert command shows both the wff number and the support,
as previously.
- Previously, inference tracing and acting tracing was on
unless turned off. Now, inference tracing and acting tracing is off
unless turned on.
- Previously,
snepslog:tell took a sequence of zero or
more strings, passed each to the SNePSLOG interpreter, printed what
SNePSLOG would print, and returned nil . Now
snepslog:tell takes a single string, passes it to the
SNePSLOG interpreter, prints nothing, and returns whatever would be
returned by the string as a SNePSLOG command. For example,
cl-user(10): (snepslog:tell "Isa(Fido,dog).")
(m1!)
cl-user(11): (snepslog:tell "Isa(Fluffy,cat).")
(m2!)
- Previously
snepslog:askwh and
snepslog:askwhnot would return a simple list of terms,
even if the query had more than one free variable. Now,
snepslog:askwh and snepslog:askwhnot return
a list of substitutions (assoc lists), even if the query has only one
free variable. For example,
cl-user(12): (snepslog:askwh "Isa(?x,?y)")
(((snepslog::y . cat) (snepslog::x . Fluffy))
((snepslog::y . dog) (snepslog::x . Fido)))
- A Java-SNePS
API has been added to give Java programs access to SNePS via the
tell-ask interface. Use of the API requires Franz's Allegro
CL or one of the prepackaged SNePS executables. To use SNePS from
a Javaprogram: include the locations of the files
JavaSnepsAPI.jar and jlinker.jar in the Java
classpath; and import into the Java program
edu.buffalo.JavaSnepsAPI ,
edu.buffalo.Substitution , and
java.util.ArrayList . The Java program must create an
object of the JavaSnepsAPI class, which can use the Java
versions of the tell and ask functions. There are two constructors of
the JavaSnepsAPI instance. One requires a port to connect to and the
String filepath specifying the location of the
java_sneps_config.config file (default location is in the
JavaSnepsAPI subdirectory, but ask the individual who installed SNePS
for specifics). This method doesn't require you to manually start
SNePS, and will do so for you automatically provided a correct
configuration file. The second method only requires that you specify
the port to run the JavaSnepsAPI over, but requires that you manually
start the sneps system and invoke the java-sneps connection funtion as
follows: (snepslog:init-java-sneps-connection <port>
<java-classpath>) . Note:
<port> should be the same port as passed to the
JavaSnepsAPI constructor, and
<java-classpath> the string representing the
classpath needed to run the JavaSnepsAPI program.
- Previously, in
add-to-context context termSet ,
only the wffs in termSet that had already been
introduced to the KB as hypotheses were added as hypotheses of
context . Now, all the wffs in
termSet are asserted into the
context .
- Previously inference and acting tracing were on by default. Now,
they are off by default.
- An optional <Lisp string> has been added to
define-frame . This string should give the intended
semantics of the function whose frame is being defined, and it must
contain a substring of the form [relation] , for
every non-null relation in the frame. The string
will be used by describe-terms to construct a gloss of
the term.
- SNIP
-
- Due to the use of active connection graphs, SNePS could always
handle rules of the form
all(x,y,z)({ancestor(x,y), ancestor(y,z)} &=> ancestor(x,z))
without getting into
infinite recursive loops. However, infinite recursive loops would
still occur if backchaining through rules of the form
all(x)(Duck(motherOf(x)) => Duck(x))
or when
forward-chaining through rules of the form
all(x)(number(x) => number(s(x))) .
Now those two kinds of infinite recursive loops are also avoided by
use of the depth bounds *depthcutoffback* and
*depthcutoffforward* , respectively. They work by
limiting the nesting depth of functional terms when backchaining or
forward-chaining. The default value of each of them is
10 , but they can be reset by the user. If either is set
to nil it means "no limit" in that direction.
A procecural attachment facility has been added. Normally, if
the system backchains into a proposition-valued function node, it will
use inference to determine what instances of the (negation of the)
node may be asserted. If, however, the node has an arc labelled
attachedfunction to a node that has been attached to a
function, the system will determine what instances of the (negation of
the) node may be asserted by evaluating the attached function. For
instance, backchaining into the node
(p1 (attachedfunction Sum) (add1 3) (add2 4) (sum v1))
could result in a computation to determine that the node
(m1 (attachedfunction Sum) (add1 3) (add2 4) (sum 7))
should be asserted.
To use the procedural attachment facility, the user must do three things:
- if using SNePSLOG, define the frames for the predicates to which
functions will be attached,
if using SNePSUL, define the relations to be used as function arguments;
- define the attached function;
- attach the function to a SNePS predicate node.
These steps are more fully explained below.
- For an example of (1) using the above example, the SNePSLOG user
would do:
define-frame Sum(attachedfunction add1 add2 sum)
and the SNePSUL user would do:
(define add1 add2 sum)
The relation, attachedfunction is defined by the SNePS system.
- Attached functions must be defined by
(define-attachedfunction fun ( <lambda variables> ) &body)
where:
-
fun will be the name of the attached function.
- each lambda variable must either be a relation used for the
arguments of the predicate node, or such a relation enclosed in a
pair of parentheses. If the lambda variable is an atomic relation
name, it will be bound to the (modified) set of nodes that that
relation points to. If it is a relation enclosed in parentheses,
the relation symbol will be bound to one element of the (modified)
set of nodes that that relation points to (presumably, there will
only be one). The way that the nodes will be modified is
- if the node is a variable, it will be left alone;
- if the node's name looks like a Lisp number,
the number will be provided;
- otherwise, a Lisp symbol whose name is the same string as the
node's name will be provided.
In the body of the attached function, the three Lisp predicates
numberp , symbolp , and
sneps:isvar.n may be used to
distinguish the
three types of argument.
- the attached function must return a list,
each of whose members is a list of two members:
- Either:
'snip:pos to indicate that the instance of the proposition is
to be asserted;
or 'snip:neg to indicate that the negation of the instance of the
proposition is to be asserted;
- A substitution of the form
( ... (var term) ...)
to indicate the appropriate instance of the proposition,
where each var is a variable-node argument,
and term is a Lisp object to be converted into a node
giving the instance.
If the attached function returns nil ,
that indicates that neither any instance of the proposition
nor any instance of its negation is to be asserted.
A simple attached-function definition for the above example is:
(define-attachedfunction sumfn ((add1) (add2) (sum))
(cond
;; If all three are numbers, check that it is correct.
((and (numberp add1) (numberp add2) (numberp sum))
(if (cl:= (cl:+ add1 add2) sum)
`((snip:pos nil))
`((snip:neg nil))))
;; If add1 and add2 are numbers, and sum is a variable, compute the sum.
((and (numberp add1) (numberp add2) (sneps:isvar.n sum))
`((snip:pos ( (,sum . ,(cl:+ add1 add2))) )))
;; Else, don't give an answer
(t nil)))
- The user must attach functions to SNePS predicates using
(attach-function node fun node fun ...)
For example
(attach-function Sum sumfn)
After which, the SNePSLOG user can ask questions such as
| Sum(3,4,7)? |
and | Sum(4,6,?x)? |
and the SNePSUL user can ask questions such as
| (deduce attachedfunction Sum add1 3 add2 4 sum 7) |
and | (deduce attachedfunction Sum add1 3 add2 4 sum $x) |
- SNeBR
-
- SNeRE
-
- Previously
clear-infer deactivated act nodes. That
is no longer done.
- The message printed when the proposition of an achieve act has
already been achieved has been placed under the
control of plantrace.
- The message printed when there is no plan found for an act has
been improved and placed under the control of
plantrace.
- The guarded acts in
snif and sniterate
can now take sets of conditions and sets of
acts. snif and each loop of
sniterate still performs one act one of
whose guards holds.
- A warning is issued if SNeRE is asked to perform an act which is
not represented as a node with an action arc
emanating from it.
- The mental acts
adopt and unadopt are now
available for adopting and unadopting policies, and
should be used for those purposes instead of
believe and disbelieve .
- Any of the variables in the lambda list of define-primaction may
be enclosed in parentheses, in which case the
variable will be bound to a member of the
appropriate nodeset. This avoids many uses of
sneps:choose.ns to pick a member from the nodeset.
Also the primitive-action function is now compiled
for faster behavior.
- Program Interface
-
- The function
(load file :format
format) is available. It reads and executes all the
SNePSUL (if format is :sneps or
:snepsul ) or SNePSLOG commands (if
format is :snepslog (default)) on
file without printing anything. Any asserting
specified by the file is postponed until the file is completely
loaded, then the asserted terms are checked for consistency by SNeBR.
The load function may be called from Lisp programs
outside the SNePS or SNePSLOG loop. The symbol load is
external in the sneps package, and accessible in the
snepslog package. The SNePSUL version of this function
is now used by the SNePSUL command intext .
- XGinseng and
show
- XGinseng has been eliminated because it was implemented in Garnet,
which has not been maintained, and was difficult to use. SNePS
networks may now be displayed by
show using either: dot ; or a graphical
representation implemented in Java that requires JUNG and JIMI .
Whichever method the installer chooses to use, the
sneps_config.lisp file (in the SNePS home directory)
should be configured appropriately. See the config file for details.
If the installer installs both versions of show , the user
can dynamically pick the version to be used by setting the global variable
cl-user:*use-gui-show* to t for the
JUNG/JIMI version, or to nil for the dot
version.
|