Fork me on GitHub
#core-logic
<
2023-02-16
>
wontheone112:02:08

Hi I wonder if there is someone who could help me with this. I have a function that is accumulating something (load) until it doesn't exceed its limit (capacity). Please help me if you can! It almost works as intended but I get non-unique results. I have tried but failed in writing code that doesn't produce non-unique results. My function and function call looks like:

(defn assign-classes-to-teacher [classes teacher load-sum ?assigned-classes]
  (fresh [?c ?class ?l ?next-load-sum ?rest-classes ?run-assigned-classes]
         (conde
          [(rembero ?class classes ?rest-classes)
           (featurec teacher {:capacity ?c})
           (featurec ?class {:load ?l})
           (fd/+ ?l load-sum ?next-load-sum)
           (fd/>= ?c ?next-load-sum)
           (conso ?class ?run-assigned-classes ?assigned-classes)
           (assign-classes-to-teacher
            ?rest-classes teacher ?next-load-sum ?run-assigned-classes)]
          [(emptyo classes) (== '() ?assigned-classes)]
          [(rembero ?class classes ?rest-classes)
           (assign-classes-to-teacher
            ?rest-classes teacher load-sum ?assigned-classes)])))

(let [classes [{:id 0 :subject "da" :load 50 :block 1}
               {:id 1 :subject "da" :load 42 :block 1}
               {:id 2 :subject "ma" :load 40}
               {:id 3 :subject "en" :load 30}]
      teacher {:id 0 :subjects ["da" "en"] :capacity 100}]
  (run 5 [?assigned-classes]
       (assign-classes-to-teacher classes teacher 0 ?assigned-classes)))
And it returns the following (the first 2 answers are not unique)
(({:id 0, :subject "da", :load 50, :block 1} {:id 1, :subject "da", :load 42, :block 1})
 ({:id 0, :subject "da", :load 50, :block 1} {:id 1, :subject "da", :load 42, :block 1})
 ({:id 2, :subject "ma", :load 40} {:id 3, :subject "en", :load 30})
 ({:id 1, :subject "da", :load 42, :block 1} {:id 3, :subject "en", :load 30})
 ({:id 0, :subject "da", :load 50, :block 1} {:id 3, :subject "en", :load 30}))