Fork me on GitHub
#core-logic
<
2018-10-28
>
folcon19:10:30

Just kicking around core logic with one of the initial tutorials and I have this basic definition set:

(pldb/db-rel parent x y)
(defn grandparent [x y]
  (logic/fresh [z]
      (parent x z)
      (parent z y)))
Now if I do this:
(apply pldb/db
    [[parent :Bob :Mike] [parent :Mike :John]])
#_=> {"logic.test/parent_2"
 #:cljs.core.logic.pldb{:unindexed #{(:Bob :Mike) (:Mike :John)}}}
I get the result I expect, but when I do this:
(apply pldb/db
    [[grandparent :Bob :John] [parent :Mike :John]])
#_=> {nil #:cljs.core.logic.pldb{:unindexed #{(:Bob :John)}},
 "logic.test/parent_2"
 #:cljs.core.logic.pldb{:unindexed #{(:Mike :John)}}}
I get the above which I don’t understand, how do I not have the (:Bob :Mike) relation? Have I misunderstood something? Note: I have tried: (grandparent :Bob :John) => #object[Function] ((grandparent :Bob :John)) => #object[cljs.core.logic.Inc] but feeding them into the apply pldb/db statement just gave exceptions, so I thought I was going down the wrong track…

hiredman21:10:22

you can't really call things in core.logic like that

hiredman21:10:53

the grandparent function is returning a a goal, and the goal has to be inside a call to run or run* to see what the result is

hiredman21:10:51

I haven't really used pldb, but my guess is to create facts you call the name of the relation as a function

hiredman21:10:16

(parent :Bob :Mike) not [parent :Bob :Mike]

hiredman21:10:48

but I might be wrong there

hiredman21:10:39

in your example, grandparent is a core.logic goal, not a pldb fact, so you cannot use it like that

hiredman21:10:01

a core.logic goal is like a query you can run over facts, in this case grandparent is a query you can run over a database of parent relationships to derive grandparent relationships

folcon21:10:59

Ok, but given these are relational operators, is there no way that I can take the statement [grandparent :Bob :John] and derive that that means => [parent :Bob _] [parent _ :John]?

folcon21:10:32

It’s very likely that I’m formulating these incorrectly.

folcon21:10:13

Basically I’m trying to understand how I can create new facts, from statements.

folcon21:10:33

Or is that just not possible?

folcon21:10:39

Do I need to work out how to define grandparent as a db-rel perhaps?

hiredman21:10:23

you are looking to infer new facts based on existing facts and definitions of relationships between facts

hiredman21:10:57

you have sort of half that, the missing half is you have to write something that runs the grandparents (rewritten to return some kind of inferred list of parent facts) and adds the results to the database

hiredman21:10:21

you might want something more like a rules engine, like clara

hiredman21:10:59

clara has a fairly active slack channel if it does look like what you want #clara

hiredman21:10:59

but I dunno, maybe not, because rules engines generally don't have logic variables

hiredman22:10:53

so [parent :Bob ?x] [parent ?x :John] isn't going to be directly something you can assert in to it

hiredman22:10:47

on the other hand, given the definition of grandparent, by construction if grandparent is true then we know [parent :Bob ?x] [parent ?x :John] is already true in the database, so there is no point in asserting it

folcon22:10:28

Thanks for mentioning clara =)…

folcon22:10:08

I’m still going through the Reasoned Schemer at the moment, so I’m going to keep reading that and banging my head against this for at least the next week or so and see if I can get somewhere and if that completely fails I’ll give it a look. Much appreciate your help though :)…

folcon23:10:37

Also just out of curiosity, is there a reason that a lot of the examples I see use symbols? Instead of say keywords?

folcon23:10:15

I just got bitten by this:

(l/run* [q]
  (l/== 
    '((pea)  pod)
    `((pea) ~q)))
=> ()
(l/run* [q]
  (l/== 
    '(pea  pod)
    `(pea ~q)))
=> ()
(l/run* [q]
  (l/== 
    '(:pea  :pod)
    `(:pea ~q)))
=> (:pod)

folcon23:10:15

Finally realised it’s because in clojure the “`” resolves the symbol to the namespace, so the two symbols aren’t equal.

rickmoynihan13:10:22

FYI the clojure syntax to unqualify a symbol during a is to use ~'foo`

rickmoynihan13:10:50

I’m assuming by examples you mean minikanren/TRS examples, that you’re porting to clojure rather than core.logic ones