3
votes

I've been playing with Prolog recently and getting my head around how to represent some tasks I want to do with it, which are largely about having a database of facts and doing simple queries on it, joining multiple facts together.

But I want to use this is in a context where I'm writing Clojure. And it seems like core.logic should do what I want.

But I'm naively finding it difficult to see how to put basic Prolog predicates into core.logic.

For example, how should I represent something as simple as this in core.logic :

person(phil).
person(mike).
food(cheese).
food(apple).
likes(phil,apple).
likes(phil,cheese).

And a query like

food(F),person(P),likes(P,F)

Most introductions I can find are heavy on the logic programming but not the data representation.

1
Have you looked at the tests posted with core.logic? more tests If this is acceptable, I can make it an answer so that others can see this question has an accepted answer.Guy Coder
Ok, so using db-rel and db?interstar
There's no equivalent of Prolog’s defining relations and data at the same time?interstar
Oops. Forgot to mention I have never used Clojure. I was writing an answer and the facts looked easy, but the the query has me confused on how to convert to core.logic so I will not be posting an answer.Guy Coder
Also noticed that core.logic is based on minikanren which might be of use.Guy Coder

1 Answers

2
votes

As Guy Coder said, the PLDB package under core.logic solves exactly this kind of problems:

(db-rel person p)
(db-rel food f)
(db-rel likes p f)

(def facts (db
  [person 'phil]
  [person 'mike]
  [food 'cheese]
  [food 'apple]
  [likes 'phil 'apple]
  [likes 'phil 'cheese]))

(with-db facts (run* [p f] (food f) (person p) (likes p f)))

=> ([phil cheese] [phil apple])    p=phil,f=cheese   or   p=phil,f=apple