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)
Anonymous
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.
Last edit: Gary Riley 2025-11-17