clojure-losangeles

seancorfield 2021-09-09T03:38:53.012400Z

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!).

nate 2021-09-09T03:42:03.012500Z

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

nate 2021-09-09T03:42:17.012700Z

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

👍🏻 1
dorab 2021-09-09T15:42:39.016800Z

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

seancorfield 2021-09-09T17:48:39.018600Z

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/

dorab 2021-09-09T20:45:32.018900Z

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.

seancorfield 2021-09-09T20:54:01.019100Z

@dorab 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! 🙂

dorab 2021-09-09T21:07:16.019300Z

Thanks!

esp1 2021-09-09T03:43:45.013900Z

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.

nate 2021-09-09T03:45:30.014100Z

I agree

nate 2021-09-09T03:45:48.014300Z

where p1 = p1 is where it ends up, maybe

esp1 2021-09-09T03:45:58.014500Z

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")

nate 2021-09-09T03:46:24.014800Z

huh

esp1 2021-09-09T03:47:50.015Z

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

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

esp1 2021-09-09T03:54:02.015200Z

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")

🤔 1
refset 2021-09-09T09:30:24.015600Z

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!

refset 2021-09-09T14:41:38.016100Z

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 @saf), 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!

dorab 2021-09-09T15:50:17.017Z

@taylor.jeremydavid 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]]]})

✔️ 1
🙏 1
😅 1
nate 2021-09-09T15:56:04.017200Z

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).

refset 2021-09-09T16:11:22.017700Z

Ah, yep, you're right of course 🤦‍♂️ 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 @saf

😮 1
refset 2021-09-09T16:11:53.017900Z

> 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