Skip to content

Nominal unification inspired by alphaKanren#12

Closed
namin wants to merge 64 commits into
clojure:masterfrom
namin:nominal-base
Closed

Nominal unification inspired by alphaKanren#12
namin wants to merge 64 commits into
clojure:masterfrom
namin:nominal-base

Conversation

@namin

@namin namin commented Dec 16, 2012

Copy link
Copy Markdown
Member

Review by @swannodette.

@swannodette

Copy link
Copy Markdown
Member

This is truly, truly fantastic. However official Clojure projects can't just merge pull requests. I need a ticket+patch in JIRA - http://dev.clojure.org/jira/browse/LOGIC. If it's not too much bother could you please submit a Clojure Contributor Agreement (CA) - http://clojure.org/contributing. If you're willing to become a contributor, I'm more than happy to go ahead and apply the patch ASAP while the CA slowly finds its way to North Carolina via snail mail :)

Again, thank you very much for this addition.

@namin

namin commented Dec 16, 2012

Copy link
Copy Markdown
Member Author

Sure. I'll do the ticket / patch on JIRA as well as sign the agreement tomorrow.

Also please let me know if you have suggestions.

Thanks. :-)

Comment thread src/main/clojure/clojure/core/logic.clj Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm curious about this, why do we need to check for nil?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In reifyc for the nom-hash constraint, I just reify the constraint if it's relevant to the end result. This is consistent with alphaKanren.

For example,

(run* [q]
  (nom-fresh [c d]
     (typo [] ['lam (nom-tie c ['lam (nom-tie d ['var c])])] q)))

would otherwise return

(([-> _0 [-> _1 _0]] :- lvar:x5037#lvar:xc5049 nom:b5036#lvar:gc5025 nom:b5036#_0 nom:b5036#[nom:b5026 lvar:trand5024]))

instead of just

((-> _0 (-> _1 _0)))

Because the constraints are on vars and noms that are not in the final result, they're just noisy and not interesting to the end user.

Simpler examples. Contrast:

(is (= (run* [q] (nom-fresh [a b] (nom-hash a q) (nom-hash b q))) '(_0)))
(is (= (run* [q] (fresh [x]  (nom-fresh [a b] (nom-hash a x) (nom-hash b x) (== [x a b] q))))
      '(([_0 a_1 a_2] :- a_2#_0 a_1#_0))))

For the first case, we don't want:

((_0 :- <nom:b5130>#_0 <nom:a5129>#_0))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, makes sense.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just making sure that you actually want to test that q unifies with a list that contains 2 numbers and 1 symbol. Clojure doesn't have pairs like Scheme. lcons and the supporting protocol fns lfirst lnext exist so that you can construct sequence like things with an improper tail as you can in Scheme via cons - but in the case of core.logic only logic vars are truly allowed. Though we don't do any explicit validation around lcons now - we may do so in the future. A closer translation of this test would be:

(= (run* [q] 
     (nom/fresh [a b] 
       (== q (lcons 1 1))
       (nom/hash a q)))
   (lcons 1 1))

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. Done.

@namin

namin commented Dec 26, 2012

Copy link
Copy Markdown
Member Author

I am just not sure how to deeply apply swaps without having suspensions. Let's take it on chat sometimes.

@swannodette

Copy link
Copy Markdown
Member

Yes would also need to add a constraint to each var that gets a swap. This constraint would apply the swap list when the var becomes ground. Related I think we can eliminate the Suspension type altogether. We can just leverage the constraint solving infrastructure to do that work.

@swannodette

Copy link
Copy Markdown
Member

Starting to look more closely at the nominal implementation, I believe removing Suspension and leveraging the constraint solving framework is the key.

Conflicts:
	src/main/clojure/clojure/core/logic.clj
Conflicts:
	src/main/clojure/clojure/core/logic.clj
@swannodette

Copy link
Copy Markdown
Member

Check out master, we have deep constraints now in the form of treec :)

@namin

namin commented Dec 27, 2012

Copy link
Copy Markdown
Member Author

Cool, @swannodette. I could use treec for nom/hash. I added some hacks for special handling and reifyc (but just saw that you anticipated that as well).

@namin

namin commented Dec 31, 2012

Copy link
Copy Markdown
Member Author

@swannodette : I've been working on an implementation of core.logic.nominal which doesn't use suspensions. I am almost there, but the quine example gets generated with extra nils at the end of lists. Debugging that.

In addition, with the latest core.logic master, I'm having trouble printing to the repl for debugging. Have you been experiencing that?

@namin

namin commented Dec 31, 2012

Copy link
Copy Markdown
Member Author

FYI, the no-susp branch is here: https://github.com/namin/core.logic/compare/nominal-no-susp

All tests pass, but there's still a problem with quines related to extra nils.

@swannodette

Copy link
Copy Markdown
Member

Wow, cool! Now that run expressions are lazy you need to wrap them in a doall when debugging. I'm happy to add a debug atom that we can set to make this less tedious. Let me know.

@swannodette

Copy link
Copy Markdown
Member

Code is looking pretty! :) :) :)

@swannodette

Copy link
Copy Markdown
Member

Please feel free to attach a patch in JIRA. As soon as your CA is in more than happy to give you commit rights to core.logic :)

@namin

namin commented Dec 31, 2012

Copy link
Copy Markdown
Member Author

Neat, thanks :)

The quines now run with the no-susp branch. I'll attach a patch on JIRA soon. Just want to iron out a few more quirks.

@namin

namin commented Dec 31, 2012

Copy link
Copy Markdown
Member Author

Patch attached to http://dev.clojure.org/jira/browse/LOGIC-78

Closing this pull request.

@namin namin closed this Dec 31, 2012
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

Successfully merging this pull request may close these issues.

2 participants