Menu

#20 Bypass allowed-values in RHS of Rule

CLIPS
closed
None
5
2025-11-17
2025-06-09
No

The following code allows writing values to slots that would otherwise be restricted with allowed-values:

CLIPS (6.4.3 5/26/25)
CLIPS> (defrule do (f ?f) => (modify ?f (bar 1)))
CLIPS> (deftemplate foo (slot bar (allowed-values 2 3 4)))
CLIPS> (assert (foo (bar 1))
)

[CSTRNCHK1] A literal slot value found in the 'assert' command does not match the allowed values for slot 'bar'.
CLIPS> (assert (f (assert (foo (bar 2)))))
<Fact-2>
CLIPS> (facts)
f-1     (foo (bar 2))
f-2     (f <Fact-1>)
For a total of 2 facts.
CLIPS> (run)
CLIPS> (facts)
f-1     (foo (bar 1))
f-2     (f <Fact-1>)
For a total of 2 facts.

Updating the defrule in this way resolves the issue by disallowing creation of the defrule:

CLIPS> (defrule do ?f <- (foo) (f ?f) => (modify ?f (bar 1)))

[CSTRNCHK1] A literal slot value found in the 'modify' command does not match the allowed values for slot 'bar'.

ERROR:
(defrule MAIN::do
   ?f <- (foo)
   (f ?f)
   =>
   (modify ?f (bar 1)))

Similarly, (and this may be my misunderstanding of the usage of allowed-values within defclass slots) it appears allowed-values are entirely ignored in defclass slots:

CLIPS> (defclass FOO (is-a USER) (slot bar (allowed-values 2 3 4)))
CLIPS> (make-instance of FOO (bar 2))
[gen1]
CLIPS> (make-instance of FOO (bar 1))
[gen2]
CLIPS> (send [gen1] print)
[gen1] of FOO
(bar 2)
CLIPS> (send [gen2] print)
[gen2] of FOO
(bar 1)

Discussion

  • Gary Riley

    Gary Riley - 2025-11-17

    This is caused by the difference between dynamic and static constraint checking. Dynamic constraint checking is off by default. Static constraint checking occurs when constructs or commands are parsed. Dynamic constraint checking occurs when a program is executing. Because you can override the put- handlers for a class, assigning literal values to instances does not trigger static constraint checking because the init or put- handlers for a class could change the value assigned to an instance during execution. Literal values in object patterns will trigger static constraint checking because these values are fixed.

         CLIPS (6.4.2 1/14/25)
    CLIPS> (defrule do (f ?f) => (modify ?f (bar 1)))
    CLIPS> (deftemplate foo (slot bar (allowed-values 2 3 4)))
    CLIPS> (assert (f (assert (foo (bar 2)))))
    <Fact-2>
    CLIPS> (set-dynamic-constraint-checking TRUE)
    FALSE
    CLIPS> (run)
    
    [CSTRNCHK1] Slot value 1 found in fact f-1 does not match the allowed values for slot 'bar'.
    [PRCCODE4] WARNING: Execution halted during the actions of defrule 'do'.
    CLIPS> (defclass FOO (is-a USER) (slot bar (allowed-values 2 3 4)))
    CLIPS> (make-instance of FOO (bar 2))
    [gen1]
    CLIPS> (make-instance of FOO (bar 1))
    [CSTRNCHK1] The value 1 for slot 'bar' of instance [gen2] found in 'put-bar' primary in class 'FOO' does not match the allowed values.
    [PRCCODE4] Execution halted during the actions of message-handler 'put-bar' primary in class 'FOO'
    FALSE
    CLIPS> (set-dynamic-constraint-checking FALSE)
    TRUE
    CLIPS> (defrule bad (object (is-a FOO) (bar 1)) =>)
    
    [CSTRNCHK1] A literal restriction value found in CE #1 does not match the allowed values for slot 'bar'.
    
    ERROR:
    (defrule MAIN::bad
    (object (is-a FOO)
           (bar 1))
    =>)
    CLIPS> 
    
     

    Last edit: Gary Riley 2025-11-17
  • Gary Riley

    Gary Riley - 2025-11-17
    • status: open --> closed
    • assigned_to: Gary Riley
     

Anonymous
Anonymous

Add attachments
Cancel





MongoDB Logo MongoDB