Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rule cross-reference doesn’t work #312

Closed
tonsky opened this issue Aug 8, 2019 · 7 comments
Closed

Rule cross-reference doesn’t work #312

tonsky opened this issue Aug 8, 2019 · 7 comments

Comments

@tonsky
Copy link
Owner

tonsky commented Aug 8, 2019

I've been playing around with this a bit more, and I've discovered a similar-looking bug. Let me know if I should make another issue for it.

The following situation is the same as the previous one, except instead involving rules not being found by other rules. The following code snippets should be identical.

(d/q '[:find ?kid
       :in $ %
       :where (wants-and-needs? ?kid :foo)]
     '[["george" :wants :foo]
       ["george" :needs :foo]
       ["sally" :wants :bar]]
     '[[(wants-and-needs? ?kid ?obj) [?kid :wants ?obj] [?kid :needs ?obj]]]))
;; => #{["george"]}

(d/q '[:find ?kid
       :in $ %
       :where (wants-and-needs? ?kid :foo)]
     '[["george" :wants :foo]
       ["george" :needs :foo]
       ["sally" :wants :bar]]
     '[[(wants? ?kid ?obj) [?kid :wants ?obj]]
       [(needs? ?kid ?obj) [?kid :needs ?obj]]
       [(wants-and-needs? ?kid ?obj) [(wants? ?kid ?obj)] [(needs? ?kid ?obj)]]]))
;; => Execution error (ExceptionInfo) at datascript.query/filter-by-pred (query.cljc:530).
;;    Unknown predicate 'wants? in [(wants? ?kid :foo)]

_Originally posted by @MyriaCore in https://github.com/tonsky/datascript/issues/311#issuecomment-519237592_
@MyriaCore
Copy link

MyriaCore commented Aug 8, 2019

Yep, I probably should've made a new issue to begin with, sorry!

@tonsky
Copy link
Owner Author

tonsky commented Aug 9, 2019

No worries, it’s literally a single button click in github. Thanks for reporting!

@MyriaCore
Copy link

MyriaCore commented Aug 10, 2019

Hey, so I'm trying to design a rule application system to get around this issue, and I encountered the same issue, even though the rule only ever recursively calls itself, and never tries to cross-reference.

(d/q '[:find ?kid
       :in $ %
       :where (apply :wants-and-needs? ?kid :foo)]
     '[["george" :wants :foo]
       ["george" :needs :foo]
       ["sally" :wants :bar]]
     '[[(apply :wants? ?kid ?obj) [?kid :wants ?obj]]
       [(apply :needs? ?kid ?obj) [?kid :needs ?obj]]
       [(apply :wants-and-needs? ?kid ?obj)
        [(apply :wants? ?kid ?obj)]
        [(apply :needs? ?kid ?obj)]]]
;; => Execution error (ExceptionInfo) at datascript.query/filter-by-pred (query.cljc:530).
;;    Unknown predicate 'apply in [(apply :wants? ?kid :foo)]

Maybe the issue is that filter-by-pred is using a one-way check to dispatch based on rule heads, instead of something like unification?

Here's my stack-trace
{:clojure.main/message
 "Execution error (ExceptionInfo) at datascript.query/filter-by-pred (query.cljc:530).\nUnknown predicate 'apply in [(apply :wants? ?kid :foo)]\n",
 :clojure.main/triage
 {:clojure.error/class clojure.lang.ExceptionInfo,
  :clojure.error/line 530,
  :clojure.error/cause
  "Unknown predicate 'apply in [(apply :wants? ?kid :foo)]",
  :clojure.error/symbol datascript.query/filter-by-pred,
  :clojure.error/source "query.cljc",
  :clojure.error/phase :execution},
 :clojure.main/trace
 {:via
  [{:type clojure.lang.ExceptionInfo,
    :message "Unknown predicate 'apply in [(apply :wants? ?kid :foo)]",
    :data
    {:error :query/where,
     :form [(apply :wants? ?kid :foo)],
     :var apply},
    :at
    [datascript.query$filter_by_pred invokeStatic "query.cljc" 530]}],
  :trace
  [[datascript.query$filter_by_pred invokeStatic "query.cljc" 530]
   [datascript.query$filter_by_pred invoke "query.cljc" 524]
   [datascript.query$_resolve_clause invokeStatic "query.cljc" 716]
   [datascript.query$_resolve_clause invoke "query.cljc" 710]
   [datascript.query$_resolve_clause invokeStatic "query.cljc" 712]
   [datascript.query$_resolve_clause invoke "query.cljc" 710]
   [clojure.core.protocols$fn__8159 invokeStatic "protocols.clj" 168]
   [clojure.core.protocols$fn__8159 invoke "protocols.clj" 124]
   [clojure.core.protocols$fn__8114$G__8109__8123
    invoke
    "protocols.clj"
    19]
   [clojure.core.protocols$seq_reduce invokeStatic "protocols.clj" 31]
   [clojure.core.protocols$fn__8146 invokeStatic "protocols.clj" 75]
   [clojure.core.protocols$fn__8146 invoke "protocols.clj" 75]
   [clojure.core.protocols$fn__8088$G__8083__8101
    invoke
    "protocols.clj"
    13]
   [clojure.core$reduce invokeStatic "core.clj" 6828]
   [clojure.core$reduce invoke "core.clj" 6810]
   [datascript.query$solve_rule$solve__27567 invoke "query.cljc" 620]
   [datascript.query$solve_rule invokeStatic "query.cljc" 634]
   [datascript.query$solve_rule invoke "query.cljc" 615]
   [datascript.query$resolve_clause invokeStatic "query.cljc" 792]
   [datascript.query$resolve_clause invoke "query.cljc" 787]
   [clojure.lang.PersistentVector reduce "PersistentVector.java" 343]
   [clojure.core$reduce invokeStatic "core.clj" 6827]
   [clojure.core$reduce invoke "core.clj" 6810]
   [datascript.query$_q invokeStatic "query.cljc" 797]
   [datascript.query$_q invoke "query.cljc" 795]
   [datascript.query$q invokeStatic "query.cljc" 921]
   [datascript.query$q doInvoke "query.cljc" 906]
   [clojure.lang.RestFn invoke "RestFn.java" 439]
   [ducktools.api.birdseye$_main invokeStatic "birdseye.clj" 362]
   [ducktools.api.birdseye$_main doInvoke "birdseye.clj" 341]
   [clojure.lang.RestFn invoke "RestFn.java" 397]
   [clojure.lang.AFn applyToHelper "AFn.java" 152]
   [clojure.lang.RestFn applyTo "RestFn.java" 132]
   [clojure.lang.Var applyTo "Var.java" 705]
   [clojure.core$apply invokeStatic "core.clj" 665]
   [clojure.main$main_opt invokeStatic "main.clj" 514]
   [clojure.main$main_opt invoke "main.clj" 510]
   [clojure.main$main invokeStatic "main.clj" 664]
   [clojure.main$main doInvoke "main.clj" 616]
   [clojure.lang.RestFn applyTo "RestFn.java" 137]
   [clojure.lang.Var applyTo "Var.java" 705]
   [clojure.main main "main.java" 40]],
  :cause "Unknown predicate 'apply in [(apply :wants? ?kid :foo)]",
  :data
  {:error :query/where, :form [(apply :wants? ?kid :foo)], :var apply}}}

@tonsky
Copy link
Owner Author

tonsky commented Aug 11, 2019

I’m pretty sure recursive rules have worked before. Interesting!

@refset
Copy link
Contributor

refset commented Mar 20, 2023

Hey @MyriaCore you had a typo where your rule expressions inside wants-and-needs? were wrapped in an unwanted set of square brackets, i.e.
[(wants-and-needs? ?kid ?obj) [(wants? ?kid ?obj)] [(needs? ?kid ?obj)]]
should be
[(wants-and-needs? ?kid ?obj) (wants? ?kid ?obj) (needs? ?kid ?obj)]

(similarly in your later example)

Fixing that makes it work :)

@tonsky
Copy link
Owner Author

tonsky commented Mar 21, 2023

Thanks @refset!

@tonsky tonsky closed this as completed Mar 21, 2023
@tonsky
Copy link
Owner Author

tonsky commented Mar 21, 2023

Not every day I get to close issues without doing anything :) Feels good :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants