You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在CLIPS中生成多槽整数和为指定值的所有组合

Generating Valid Days Distribution Combinations in CLIPS

Absolutely, you can implement this with CLIPS rules—you just need to add a combinatorial generation layer to your existing logic. The key challenge is generating all integer tuples for days-distribution that sum to your benchmark value, while ensuring each place gets at least 1 day (since you can’t spend 0 days in a destination).

Here’s a complete, step-by-step solution that builds on your existing templates and facts:

Full Implementation Code

First, keep your original templates and facts, then add helper structures and rules to handle combination generation:

; Original templates and facts
(deftemplate trip (multislot place-sequence) (multislot days-distribution))
(deftemplate travel-banchmark (slot name) (slot value))

(deffacts initial-data
  (trip (place-sequence milano roma venezia) (days-distribution 1 1 1))
  (trip (place-sequence roma milano venezia) (days-distribution 1 1 1))
  (travel-banchmark (name travel-duration) (value 5))
)

; Helper templates for tracking generation state
(deffacts counters
  (trip-id-counter 0)
)

(deftemplate trip-with-id
  (slot original-trip)
  (slot id)
  (slot num-places)
)

(deftemplate combination-state
  (slot trip-id)
  (multislot current-combo)
  (slot remaining-days)
  (slot remaining-places)
)

(deftemplate value-generator
  (slot trip-id)
  (slot current-value)
  (slot max-value)
  (slot state-ref)
)

(deftemplate trip-processed
  (slot id)
)

; Rule 1: Assign unique IDs to each trip for tracking
(defrule assign-trip-id
  ?counter <- (trip-id-counter ?id)
  ?trip <- (trip (place-sequence $?places))
  (not (trip-with-id (original-trip ?trip)))
=>
  (assert (trip-with-id (original-trip ?trip) (id ?id) (num-places (length$ ?places))))
  (modify ?counter (trip-id-counter (+ ?id 1)))
)

; Rule 2: Start combination generation for valid trips (duration >= number of places)
(defrule start-combination-generation
  (travel-banchmark (name travel-duration) (value ?duration))
  ?trip-info <- (trip-with-id (id ?tid) (num-places ?n))
  (test (>= ?duration ?n))
  (not (combination-state (trip-id ?tid)))
  (not (trip-processed (id ?tid)))
=>
  (assert (combination-state (trip-id ?tid) 
                             (current-combo) 
                             (remaining-days (- ?duration ?n)) 
                             (remaining-places ?n)))
)

; Rule 3: Initiate value generation for non-final places
(defrule initiate-value-generation
  ?state <- (combination-state (trip-id ?tid) 
                               (current-combo $?current) 
                               (remaining-days ?r) 
                               (remaining-places ?p))
  (test (> ?p 1))
=>
  (assert (value-generator (trip-id ?tid) 
                           (current-value 0) 
                           (max-value ?r) 
                           (state-ref ?state)))
  (retract ?state)
)

; Rule 4: Generate each possible value for the current place and recurse
(defrule generate-next-value
  ?generator <- (value-generator (trip-id ?tid) 
                                 (current-value ?v) 
                                 (max-value ?r) 
                                 (state-ref ?state))
  (test (<= ?v ?r))
=>
  (bind ?current-combo (fact-slot-value ?state current-combo))
  (bind ?remaining-places (- (fact-slot-value ?state remaining-places) 1))
  (bind ?new-remaining-days (- ?r ?v))
  
  (assert (combination-state (trip-id ?tid) 
                             (current-combo ?current-combo ?v) 
                             (remaining-days ?new-remaining-days) 
                             (remaining-places ?remaining-places)))
  
  (if (< ?v ?r) then
    (modify ?generator (current-value (+ ?v 1)))
  else
    (retract ?generator)
  )
)

; Rule 5: Finalize combinations and assert new trip facts
(defrule finalize-combination
  ?state <- (combination-state (trip-id ?tid) 
                               (current-combo $?current) 
                               (remaining-days ?r) 
                               (remaining-places 1))
=>
  (bind ?final-extra-combo (create$ ?current ?r))
  (bind ?actual-days (map$ ?x (+ ?x 1) ?final-extra-combo))
  
  (trip-with-id (id ?tid) (original-trip ?original-trip))
  (bind ?places (fact-slot-value ?original-trip place-sequence))
  
  (assert (trip (place-sequence ?places) (days-distribution ?actual-days)))
  
  (retract ?state)
)

; Rule 6: Mark trips as processed once all combinations are generated
(defrule mark-trip-processed
  ?trip-info <- (trip-with-id (id ?tid))
  (not (trip-processed (id ?tid)))
  (not (combination-state (trip-id ?tid)))
  (not (value-generator (trip-id ?tid)))
=>
  (assert (trip-processed (id ?tid)))
)

How It Works

  1. Trip Tracking: Each original trip gets a unique ID to link generated combinations back to their source.
  2. Validity Check: We only generate combinations if the travel duration is at least the number of places (since each destination needs at least 1 day).
  3. Combination Generation:
    • We calculate "extra days" (total duration minus number of places) to distribute across destinations.
    • Using recursive state facts, we build combinations one place at a time, generating all possible values for each position.
  4. Finalization: Convert the extra days to actual days (add 1 to each element) and assert new trip facts with the valid days-distribution combinations.

Expected Output

For your sample data, this will generate 6 new trip facts per original trip, including combinations like:

  • (trip (place-sequence milano roma venezia) (days-distribution 3 1 1))
  • (trip (place-sequence milano roma venezia) (days-distribution 2 2 1))
  • (trip (place-sequence milano roma venezia) (days-distribution 1 3 1))

All combinations will sum to the travel-duration value of 5.

内容的提问来源于stack exchange,提问作者Marco Caldera

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:58:02