#24 Assert With Multi-fact String Behaves Differently

Annoyances (7)

In native clips:

CLIPS> (reset)
CLIPS> (assert (f1 foo) (f2 bar))
CLIPS> (facts)
f-0 (initial-fact)
f-1 (f1 foo)
f-2 (f2 bar)
For a total of 3 facts.

In PyClips:

>>> import clips
>>> clips.Reset()
>>> clips.Assert("(f1 foo) (f2 bar)")
<Fact 'f-1': fact object at 0x0095A200>
>>> clips.PrintFacts()
f-0 (initial-fact)
f-1 (f1 foo)
For a total of 2 facts.


Bob Follek


  • Logged In: YES


    I don't think this can be considered a bug: in fact the
    clips.Assert() function maps the CLIPS low-level AssertString
    () API, which only asserts one fact by design.

    The reason why PyCLIPS does not complain about the
    provided list of facts resides in the way the CLIPS API
    handles command strings: unless otherwise specified, it only
    considers the first part (either a symbol or what is enclosed
    in the outermost pair of brackets). Consider the following:

    >>> clips.Assert("(something) & some rubbish (or garbage)")
    <Fact 'f-0': fact object at 0x00AF0020>
    >>> clips.PrintFacts()
    f-0 (something)
    For a total of 1 fact.

    it is the same as in CLIPS:

    CLIPS (V6.23 01/31/05)
    CLIPS> (assert-string "(something) & some rubbish (or
    CLIPS> (facts)
    f-0 (something)
    For a total of 1 fact.

    whereas the CLIPS shell assert command behaves differently:

    CLIPS> (assert (something-else) & more rubbish)
    [PRNTUTIL2] Syntax Error: Check appropriate syntax for
    RHS patterns.

    Thus only what the PyCLIPS documentation states (that is,
    use clips.Assert(o) to assert one fact) can be considered

    A workaround for this annoyance is the following:

    >>> def AssertFacts(s):
    """assert one or more facts from a string"""
    clips.SendCommand("(assert %s)" % s)

    >>> clips.Reset()
    >>> AssertFacts("(f1 foo)(f2 bar)")
    >>> clips.PrintFacts()
    f-0 (initial-fact)
    f-1 (f1 foo)
    f-2 (f2 bar)
    For a total of 3 facts.
    >>> AssertFacts("(f1 foo) & rubbish")

    Traceback (most recent call last):
    File "<pyshell#16>", line 1, in -toplevel-
    AssertFacts("(f1 foo) & rubbish")
    File "<pyshell#11>", line 3, in AssertFacts
    clips.SendCommand("(assert %s)" % s)
    File ".../_clips_wrap.py", line 2822, in SendCommand
    _c.sendCommand(command, verbose)
    ClipsError: C09: unable to understand argument

    which also saves us from trying to find errors in the supplied
    list of facts before passing it to PyCLIPS. However adding
    this function to the PyCLIPS release would probably be a
    little redundant.

    I will close the bug shortly, but your feedback is really

    I hope this helps, and thank you for being interested...



    • status: open --> closed
  • Logged In: YES

    This is how the CLIPS engine works, thus not a bug. An
    entry to the FAQ has been added and will be uploaded along
    with next release (1.0_10).