Fork me on GitHub
#clojure-losangeles
<
2021-09-09
>
seancorfield03:09:53

Bummed I missed it tonight. Work got away from me and it was 6:30 pm before I was done and then my wife wanted to go eat out (because we're under a "flex alert" until 9 pm and she wanted a/c -- so we went to the local Asian fusion place which has great a/c!).

nate03:09:03

I missed seeing you tonight as well. It was a fun discussion.

nate03:09:17

Glad you got some good A/C, always a treat

2
dorab15:09:39

Missed you as well. What are your go-to dishes at the Asian fusion place?

seancorfield17:09:39

They have a "Phoenix" roll which I love -- it's basically a deep-fried, spicy hamachi (yellowfin) roll. I like all of their scallop (hotate) dishes too. You can see most of their menu here http://genghixmenu.com/

dorab20:09:32

Thanks. They have quite the variety of rolls. Are you in Castro Valley? I have some friends there (though, have not visited for a few years now). I'll have to mention Genghix to them. One of them really likes sushi.

seancorfield20:09:01

@U0AT6MBUL Yes, Castro Valley. Genghix' nigiri isn't great, IMO, but their rolls are awesome. I Sushi is the place to go in CV for sushi. Katsu used to be absolutely incredible but it has gone downhill over the years. There's Koyomi as well but that's never been as good as I Sushi or Katsu. Yeah, tiny little Castro Valley and four sushi restaurants! 🙂

esp103:09:45

So that last example was bugging me. I think that the query is actually not doing friends of friends, but is actually just returning all people in the database. It's basically the equivalent of adding a rule that matches everything.

nate03:09:48

where p1 = p1 is where it ends up, maybe

esp103:09:58

for instance, this query returns all 50 ppl as well:

(q '{:find [friend]
     :in [name]
     :where [[p1 :person/name name]
             (friends p1 p2)
             [p2 :person/name friend]]
     :rules [[(friends ?p1 ?p2)
              (friends ?p2 ?p1)]]}
  "Mel Gibson")

esp103:09:50

same thing if you change the definition of friends to be an identity instead of an inversion relationship:

[(friends ?p1 ?p2)
 (friends ?p1 ?p2)]

esp103:09:02

this query however works - this is probably the way it should have been written, without the self-recursion:

(q '{:find [friend]
     :in [name]
     :where [[p1 :person/name name]
             (myfriends p1 p2)
             [p2 :person/name friend]]
     :rules [[(friends ?p1 ?p2)
              [?m :movie/cast ?p1]
              [?m :movie/cast ?p2]
              [(not= ?p1 ?p2)]]
             [(friends ?p1 ?p2)
              [?m :movie/cast ?p1]
              [?m :movie/director ?p2]
              [(not= ?p1 ?p2)]]
             [(myfriends ?p1 ?p2)
              (friends ?p1 ?p2)]
             [(myfriends ?p1 ?p2)
              (friends ?p2 ?p1)]]}
  "Mel Gibson")

2
refset09:09:24

Thanks for flagging this, I've opened an issue https://github.com/crux-labs/learn-crux-datalog-today/issues/14 (which is technically the old repo, issue transfer is pending) to fix this. It's my fault for blindly copying the original solution from http://www.learndatalogtoday.org/chapter/8 but failing to spot that the answers are different 😅 On first glance, I think the original solution only works because the semantics of that Datalog implementation are order-sensitive (unlike XT's more declarative style), which means ?p2 is already constrained by the time it gets to evaluating [?p2 :person/name ?friend] ...but that may be wrong, I'll give it some thought soon!

refset14:09:38

Update So there is a known https://github.com/xtdb/xtdb/issues/1569 which this solution seems to be hitting. If you add a couple of unification clauses a workaround though, as suggested, then it works as expected:

[p1 :person/name name]
(myfriends p1 p2)
[p2 :person/name friend]

;; becomes

[p1 :person/name name]
(myfriends p1* p2*) ;; intermediate variables
[p2 :person/name friend]
[(== p1 p1*)] ;; added this
[(== p2 p2*)]] ;; added this
However, there is a simpler/better answer available by simply removing the "inverse" rule anyway (all credit to @U02E9RYRHNV), which doesn't require those workaround clauses:
[(friends ?p1 ?p2)
 [?m :movie/cast ?p1]
 [?m :movie/cast ?p2]
 [(not= ?p1 ?p2)]]
[(friends ?p1 ?p2)
 [?m :movie/cast ?p1]
 [?m :movie/director ?p2]]
[(friends ?p1 ?p2)
 (friends ?p2 ?p1)]

;; becomes

[(friends ?p1 ?p2)
 [?m :movie/cast ?p1]
 [?m :movie/cast ?p2]
 [(not= ?p1 ?p2)]]
[(friends ?p1 ?p2)
 [?m :movie/cast ?p1]
 [?m :movie/director ?p2]
 [(not= ?p1 ?p2)]] ;; also added this as per 
I've now https://github.com/xtdb/learn-xtdb-datalog-today/pull/2/files as the official solution. Sorry again though that the original solution results weren't thoroughly vetted in the first instance - we will be more diligent in future!

dorab15:09:17

@U899JBRPF we also came across another small bug in the tutorial last night. In the Rules section,

(q '{:find [name]
     :where [(actor-movie name "The Terminator")]
     :rules [[(actor-movie name title)
              [p :person/name name]
              [m :movie/cast p]
              [m :movie/title "The Terminator"]]]})
should be
(q '{:find [name]
     :where [(actor-movie name "The Terminator")]
     :rules [[(actor-movie name title)
              [p :person/name name]
              [m :movie/cast p]
              [m :movie/title title]]]})

😅 2
🙏 2
✔️ 2
nate15:09:04

I think that

[(friends ?p1 ?p2)
 [?m :movie/cast ?p1]
 [?m :movie/cast ?p2]
 [(not= ?p1 ?p2)]]
[(friends ?p1 ?p2)
 [?m :movie/cast ?p1]
 [?m :movie/director ?p2]
 [(not= ?p1 ?p2)]]
isn't quite sufficient, it doesn't cover the p1 as director being friends with p2 in the cast, so we need an extra clause, like this:
[(friends ?p1 ?p2)
 [?m :movie/cast ?p1]
 [?m :movie/cast ?p2]
 [(not= ?p1 ?p2)]]
[(friends ?p1 ?p2)
 [?m :movie/cast ?p1]
 [?m :movie/director ?p2]
 [(not= ?p1 ?p2)]]
[(friends ?p1 ?p2)
 [?m :movie/director ?p1]
 [?m :movie/cast ?p2]
 [(not= ?p1 ?p2)]]
Unfortunately, it's hard to find a person in this dataset where this problem pops out, the only person who crosses over from acting to directing did it in a movie in which he was also an actor (Mel Gibson).

refset16:09:22

Ah, yep, you're right of course :man-facepalming: That's why the original solution had the third self-recursion rule to "invert" that second rule (but which also needlessly inverted the first rule, probably giving up some efficiency). /cc @U02E9RYRHNV

😮 2
refset16:09:53

> we also came across another small bug in the tutorial last night. thanks for this, fixed in https://github.com/xtdb/learn-xtdb-datalog-today/commit/8890ffe46d2f0fab062716c21641a0a455e24691