Problem with CLIPS defrule firing multiple times

23 views
Skip to first unread message

Jose Antonio Escribano Ayllon

unread,
Apr 18, 2024, 4:26:45 AMApr 18
to CLIPSESG
Hi everyone.

I am working on system where I use defrules to push actions to a "requested actions queue" into my C++ code.
But I have a strange problem I don't understand.

To give more info, this is the rule:
; Default agent wander by default
(defrule MAIN::barbarian_agent_wander_around
    (not (exists (has_order)))                                                ; There is not any higher priority order
    (faction (type ?faction_type))
    (npc_agent (id ?agent_id) (faction_type ?faction_type))
    (not (exists (current_action ?any_action_id ?agent_id ?any_status)))
    =>
    (bind ?action_id (udf_generate_unique_id))                                ; UDF to generate unique action ID
    (udf_request_action ?action_id WANDER ?agent_id)                        ; UDF to push an action request to the request queue
)



So, the idea behind this, is that the first tick, the system will call udf_request_action function, because the fact (current_action ?any_action_id ?agent_id ?any_status) won't be there.

Once I have an action in the queue, after the update of the rule based system, I create and execute the action, so during the execution, I assert the fact (current_action ?any_action_id ?agent_id ?any_status).

My expected behavior would be that, once I have already that fact in the database, the defrule wouldn't fire anymore, because of the (not (exist ...)) that is checking if there is a current action.

For some reason this is not happening, any idea of what I am doing wrong?

Cheers,
Jose

CLIPS Support

unread,
Apr 18, 2024, 1:59:18 PMApr 18
to CLIPSESG
Using (not (exists ...)) is redundant; use (not ...) instead. Otherwise, without knowing the specific facts that are causing the activation of the rule, it's difficult to say what's causing the extraneous activation. If you have multiple agents, then the rule will be activated for any agent that doesn't have a current action. Here you can see with one agent that the rule is deactivated once it has a current action:


         CLIPS (6.4.1 4/8/23)
CLIPS>
(deftemplate faction
   (slot type))
CLIPS>    
(deftemplate npc_agent
   (slot id)
   (slot faction_type))
CLIPS>
(defrule barbarian_agent_wander_around
    (not (has_order))                                              
    (faction (type ?faction_type))
    (npc_agent (id ?agent_id) (faction_type ?faction_type))
    (not (current_action ?any_action_id ?agent_id ?any_status))
    =>)
CLIPS>    
(assert (faction (type ft)))
<Fact-1>
CLIPS> (assert (npc_agent (id a1) (faction_type ft)))
<Fact-2>
CLIPS> (agenda)
0      barbarian_agent_wander_around: *,f-1,f-2,*
For a total of 1 activation.
CLIPS> (assert (current_action aid a1 done))
<Fact-3>
CLIPS> (agenda)
CLIPS> 

Jose Antonio

unread,
Apr 22, 2024, 11:56:19 AMApr 22
to CLIPSESG
Hi

I found the problem as, indeed, it was my code and not really related to CLIPS,
Thanks!

Reply all
Reply to author
Forward
0 new messages