I'm currently working on a problem that asks to look for certain vendors that can fulfill an order. The vendors are represented as maps, as is the order. A vendor can fulfill an order if it can serve the order's zipcode, the order's service level, the order's requested vehicle, and has the appropriate extra accommodations. I've been trying to use core.logic for this problem, so I have the vendors stored in a logic database using core.logic.pldb as fleets. Following my research on how to use core.logic with Clojure maps, I've been trying to use a combination of featurec, membero and PMap to solve the problem. The code shown below is the current state of my efforts.
(pldb/db-rel fleet fl)
(def f1 {:id 1
:zipcodes #{"02138" "33135" "33157" "02139"}
:services #{"standard" "through_door" "to_curb" "to_door"}
:vehicles #{"any" "sedan" "suv" "wav"}
:extra {:covid-19 true}
:cost 20
:weight 100})
(def f2 {:id 2
:zipcodes #{"33157" "02139"}
:services #{"standard" "through_door"}
:vehicles #{"sedan" "suv"}
:extra {:covid-19 true}
:cost 40
:weight 80})
(def f3 {:id 3
:zipcodes #{"02138" "33135"}
:services #{"to_curb" "to_door"}
:vehicles #{"any" "sedan"}
:extra {:covid-19 true}
:cost 60
:weight 120})
(def ex_m {:ride {:zipcodes "02138"
:appointment-time "0630"
:services "to_curb"
:vehicles "sedan"}
:accessibility {:extra {:covid-19 true}}})
(def fleets
(pldb/db
[fleet (map->PMap f1)]
[fleet (map->PMap f2)]
[fleet (map->PMap f3)]))
(defn find-fleets [m]
(run-db* fleets [fl]
(fresh [fl_zipcodes fl_services fl_vehicles fl_covid
ride_info ride_zip ride_service ride_vehicle ride_covid]
(membero ride_zip fl_zipcodes)
(membero ride_service fl_services)
(membero ride_vehicle fl_vehicles)
(== fl_covid ride_covid)
(featurec fl {:zipcodes fl_zipcodes
:services fl_services
:vehicles fl_vehicles
:extra {:covid-19 fl_covid}})
(featurec m {:ride ride_info
:accessibility {:extra {:covid-19 ride_covid}}})
(featurec ride_info {:zipcodes ride_zip
:services ride_service
:vehicles ride_vehicle}))))
However, when I try to run the find-fleets function above, like so,
(find-fleets (map->PMap ex_m))
I get the following error and trace:
; Error printing return value (StackOverflowError) at clojure.lang.KeywordLookupSite$1/get (KeywordLookupSite.java:45).
; null
Is there something I'm missing here about core.logic and how to use it with Clojure maps? Am I just missing some stupid error?
Thank you in advance!
If you reformulate your problem a bit, you can solve this using the
submatch?
function from the Tupelo library. From the docs:An example
Define the repair job to match the structure of the shops (a map with values that are sets or maps).
A unit test shows the
submatch?
function in action.