<< Back to previous view

[LOGIC-46] Unification on Struct Maps Causes Error Created: 02/Aug/12  Updated: 28/Jul/13  Resolved: 04/Oct/12

Status: Closed
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Daniel Gregoire Assignee: David Nolen
Resolution: Completed Votes: 0
Labels: None


 Description   

Unless two struct maps satisfy identical?, attempting to unify on them results in an error. Consider the following:

(defstruct element :tag :attrs :content)
(def an-element (struct element :div [] "bar"))

(run* [q]
  (membero an-element (all-elements))

Results in:

java.lang.RuntimeException: Can't remove struct key
 at clojure.lang.Util.runtimeException (Util.java:156)
    clojure.lang.PersistentStructMap.without (PersistentStructMap.java:178)
    clojure.lang.RT.dissoc (RT.java:736)
    clojure.core$dissoc.invoke (core.clj:1404)
    clojure.core.logic$eval4245$fn__4246.invoke (logic.clj:1430)
    clojure.core.logic$eval2230$fn__2231$G__2221__2240.invoke (logic.clj:36)
    clojure.core.logic$eval4139$fn__4140.invoke (logic.clj:1280)
    clojure.core.logic$eval2050$fn__2051$G__2041__2060.invoke (logic.clj:18)

During unification for IPersistentMap, the two map-like arguments have the just-compared entry removed with dissoc on recursion. For struct maps, this obviously throws the above error, whereas for Clojure records it "downgrades" them to regular maps (also sub-optimal).

(Aside: I've encountered the above using Christophe Grand's Enlive library, which still uses struct maps for modeling parsed HTML/XML documents.)



 Comments   
Comment by David Nolen [ 07/Aug/12 8:48 PM ]

There is no support for unifying struct maps. Patch welcome.

Comment by David Nolen [ 27/Sep/12 9:44 PM ]

I'm considering adding a IEmptyableCollection protocol to core.logic. If you implement then we can call it when unifying maps to preserve the original type. Does this sound satisfactory?

Comment by Daniel Gregoire [ 27/Sep/12 10:16 PM ]

Per our conversation at StrangeLoop, this sounds like a nice approach, and should solve current issues both with structmaps and records.

Comment by David Nolen [ 04/Oct/12 7:20 PM ]

Fixed, http://github.com/clojure/core.logic/commit/a62e7f11f02ade156043d309dc94166c9ec581b8. The record issue will be resolved in a separate ticket.

Comment by David Nolen [ 04/Oct/12 7:30 PM ]

I refined the ticket LOGIC-58 about issues around defrecord which is really an issue around reconstructing it during reification not unification specifically.

Generated at Fri Oct 24 19:42:59 CDT 2014 using JIRA 4.4#649-r158309.