clojure-numerics / expresso

Clojure library for symbolic computation
312 stars 20 forks source link

How to differentiate between "no solution" and "not solved"? #20

Closed Vaguery closed 7 years ago

Vaguery commented 8 years ago

I've been trying to get expresso to handle some simple 2-d geometric intersection problems, and while I believe I have entered the equations correctly, the results are consistently #{{}}, which I assume is "no result found".

If you have a look at the last two tests, which are the intersection of a line and a circle, and the intersections of two circles (respectively), there should be nice, simple, integer results in both cases.

I'd be happy to hear about additional simplification rules I can add. But the reason for the Issue is that the empty result #{{}} seems to be returned in many cases:

mschuene commented 8 years ago

Thanks for the report, there seems to be something very odd, I'll look into it.

mschuene commented 8 years ago

Ok I managed to take a look at this:

{{}} means no solution, and it was a bug that it was returned for the 2-nd and 4. to 6. of your examples.

I pushed a bugfix as a new 0.2.2-SNAPSHOT release to clojars just now, can you give it a try?

Your last example still fails, there is another bug that doesn't recognize two equations that are the same. (solve 'x '(= x x) '(= x x)) also returns #{{}}, I open a new issue on it. Maybe I get some time during the weekend to fix this, If you want to help on this - all contributions are welcome :)

I also open a new issue to simplify the #{{x (* (- _0) -3/4), y _0}} output.

Vaguery commented 8 years ago

Thank you. Will re-run tests shortly.

Vaguery commented 8 years ago

Does not compile with [org.clojure/clojure "1.8.0"]

Actually I notice as it loads this happens:

Retrieving org/clojure/clojure/1.6.0-RC1/clojure-1.6.0-RC1.pom from central

which is troubling since I specified 1.8.0 in the project.clj

Vaguery commented 8 years ago

After running lein clean and lein midje here's the error trace.

tmesis:expresso-2d bill$ lein midje
WARNING: cat already refers to: #'clojure.core/cat in namespace: instaparse.combinators-source, being replaced by: #'instaparse.combinators-source/cat
WARNING: cat already refers to: #'clojure.core/cat in namespace: instaparse.cfg, being replaced by: #'instaparse.combinators-source/cat
WARNING: cat already refers to: #'clojure.core/cat in namespace: instaparse.abnf, being replaced by: #'instaparse.combinators-source/cat
Exception in thread "main" clojure.lang.ArityException: Wrong number of args (2) passed to: StringReader, compiling:(abnf.clj:188:28)
    at clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:3657)
    at clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:3651)
    at clojure.lang.Compiler$DefExpr.eval(Compiler.java:451)
    at clojure.lang.Compiler.eval(Compiler.java:6932)
    at clojure.lang.Compiler.load(Compiler.java:7379)
    at clojure.lang.RT.loadResourceScript(RT.java:372)
    at clojure.lang.RT.loadResourceScript(RT.java:363)
    at clojure.lang.RT.load(RT.java:453)
    at clojure.lang.RT.load(RT.java:419)
    at clojure.core$load$fn__5677.invoke(core.clj:5893)
    at clojure.core$load.invokeStatic(core.clj:5892)
    at clojure.core$load.doInvoke(core.clj:5876)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at clojure.core$load_one.invokeStatic(core.clj:5697)
    at clojure.core$load_one.invoke(core.clj:5692)
    at clojure.core$load_lib$fn__5626.invoke(core.clj:5737)
    at clojure.core$load_lib.invokeStatic(core.clj:5736)
    at clojure.core$load_lib.doInvoke(core.clj:5717)
    at clojure.lang.RestFn.applyTo(RestFn.java:142)
    at clojure.core$apply.invokeStatic(core.clj:648)
    at clojure.core$load_libs.invokeStatic(core.clj:5774)
    at clojure.core$load_libs.doInvoke(core.clj:5758)
    at clojure.lang.RestFn.applyTo(RestFn.java:137)
    at clojure.core$apply.invokeStatic(core.clj:648)
    at clojure.core$require.invokeStatic(core.clj:5796)
    at clojure.core$require.doInvoke(core.clj:5796)
    at clojure.lang.RestFn.invoke(RestFn.java:805)
    at instaparse.core$eval16112$loading__5569__auto____16113.invoke(core.clj:1)
    at instaparse.core$eval16112.invokeStatic(core.clj:1)
    at instaparse.core$eval16112.invoke(core.clj:1)
    at clojure.lang.Compiler.eval(Compiler.java:6927)
    at clojure.lang.Compiler.eval(Compiler.java:6916)
    at clojure.lang.Compiler.load(Compiler.java:7379)
    at clojure.lang.RT.loadResourceScript(RT.java:372)
    at clojure.lang.RT.loadResourceScript(RT.java:363)
    at clojure.lang.RT.load(RT.java:453)
    at clojure.lang.RT.load(RT.java:419)
    at clojure.core$load$fn__5677.invoke(core.clj:5893)
    at clojure.core$load.invokeStatic(core.clj:5892)
    at clojure.core$load.doInvoke(core.clj:5876)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at clojure.core$load_one.invokeStatic(core.clj:5697)
    at clojure.core$load_one.invoke(core.clj:5692)
    at clojure.core$load_lib$fn__5626.invoke(core.clj:5737)
    at clojure.core$load_lib.invokeStatic(core.clj:5736)
    at clojure.core$load_lib.doInvoke(core.clj:5717)
    at clojure.lang.RestFn.applyTo(RestFn.java:142)
    at clojure.core$apply.invokeStatic(core.clj:648)
    at clojure.core$load_libs.invokeStatic(core.clj:5774)
    at clojure.core$load_libs.doInvoke(core.clj:5758)
    at clojure.lang.RestFn.applyTo(RestFn.java:137)
    at clojure.core$apply.invokeStatic(core.clj:648)
    at clojure.core$require.invokeStatic(core.clj:5796)
    at clojure.core$require.doInvoke(core.clj:5796)
    at clojure.lang.RestFn.invoke(RestFn.java:457)
    at numeric.expresso.parse$eval16106$loading__5569__auto____16107.invoke(parse.clj:1)
    at numeric.expresso.parse$eval16106.invokeStatic(parse.clj:1)
    at numeric.expresso.parse$eval16106.invoke(parse.clj:1)
    at clojure.lang.Compiler.eval(Compiler.java:6927)
    at clojure.lang.Compiler.eval(Compiler.java:6916)
    at clojure.lang.Compiler.load(Compiler.java:7379)
    at clojure.lang.RT.loadResourceScript(RT.java:372)
    at clojure.lang.RT.loadResourceScript(RT.java:363)
    at clojure.lang.RT.load(RT.java:453)
    at clojure.lang.RT.load(RT.java:419)
    at clojure.core$load$fn__5677.invoke(core.clj:5893)
    at clojure.core$load.invokeStatic(core.clj:5892)
    at clojure.core$load.doInvoke(core.clj:5876)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at clojure.core$load_one.invokeStatic(core.clj:5697)
    at clojure.core$load_one.invoke(core.clj:5692)
    at clojure.core$load_lib$fn__5626.invoke(core.clj:5737)
    at clojure.core$load_lib.invokeStatic(core.clj:5736)
    at clojure.core$load_lib.doInvoke(core.clj:5717)
    at clojure.lang.RestFn.applyTo(RestFn.java:142)
    at clojure.core$apply.invokeStatic(core.clj:648)
    at clojure.core$load_libs.invokeStatic(core.clj:5774)
    at clojure.core$load_libs.doInvoke(core.clj:5758)
    at clojure.lang.RestFn.applyTo(RestFn.java:137)
    at clojure.core$apply.invokeStatic(core.clj:648)
    at clojure.core$require.invokeStatic(core.clj:5796)
    at clojure.core$require.doInvoke(core.clj:5796)
    at clojure.lang.RestFn.invoke(RestFn.java:1289)
    at numeric.expresso.core$eval9682$loading__5569__auto____9683.invoke(core.clj:1)
    at numeric.expresso.core$eval9682.invokeStatic(core.clj:1)
    at numeric.expresso.core$eval9682.invoke(core.clj:1)
    at clojure.lang.Compiler.eval(Compiler.java:6927)
    at clojure.lang.Compiler.eval(Compiler.java:6916)
    at clojure.lang.Compiler.load(Compiler.java:7379)
    at clojure.lang.RT.loadResourceScript(RT.java:372)
    at clojure.lang.RT.loadResourceScript(RT.java:363)
    at clojure.lang.RT.load(RT.java:453)
    at clojure.lang.RT.load(RT.java:419)
    at clojure.core$load$fn__5677.invoke(core.clj:5893)
    at clojure.core$load.invokeStatic(core.clj:5892)
    at clojure.core$load.doInvoke(core.clj:5876)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at clojure.core$load_one.invokeStatic(core.clj:5697)
    at clojure.core$load_one.invoke(core.clj:5692)
    at clojure.core$load_lib$fn__5626.invoke(core.clj:5737)
    at clojure.core$load_lib.invokeStatic(core.clj:5736)
    at clojure.core$load_lib.doInvoke(core.clj:5717)
    at clojure.lang.RestFn.applyTo(RestFn.java:142)
    at clojure.core$apply.invokeStatic(core.clj:648)
    at clojure.core$load_libs.invokeStatic(core.clj:5774)
    at clojure.core$load_libs.doInvoke(core.clj:5758)
    at clojure.lang.RestFn.applyTo(RestFn.java:137)
    at clojure.core$apply.invokeStatic(core.clj:650)
    at clojure.core$use.invokeStatic(core.clj:5860)
    at clojure.core$use.doInvoke(core.clj:5860)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at expresso_2d.core$eval9676$loading__5569__auto____9677.invoke(core.clj:1)
    at expresso_2d.core$eval9676.invokeStatic(core.clj:1)
    at expresso_2d.core$eval9676.invoke(core.clj:1)
    at clojure.lang.Compiler.eval(Compiler.java:6927)
    at clojure.lang.Compiler.eval(Compiler.java:6916)
    at clojure.lang.Compiler.load(Compiler.java:7379)
    at clojure.lang.RT.loadResourceScript(RT.java:372)
    at clojure.lang.RT.loadResourceScript(RT.java:363)
    at clojure.lang.RT.load(RT.java:453)
    at clojure.lang.RT.load(RT.java:419)
    at clojure.core$load$fn__5677.invoke(core.clj:5893)
    at clojure.core$load.invokeStatic(core.clj:5892)
    at clojure.core$load.doInvoke(core.clj:5876)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at clojure.core$load_one.invokeStatic(core.clj:5697)
    at clojure.core$load_one.invoke(core.clj:5692)
    at clojure.core$load_lib$fn__5626.invoke(core.clj:5737)
    at clojure.core$load_lib.invokeStatic(core.clj:5736)
    at clojure.core$load_lib.doInvoke(core.clj:5717)
    at clojure.lang.RestFn.applyTo(RestFn.java:142)
    at clojure.core$apply.invokeStatic(core.clj:648)
    at clojure.core$load_libs.invokeStatic(core.clj:5774)
    at clojure.core$load_libs.doInvoke(core.clj:5758)
    at clojure.lang.RestFn.applyTo(RestFn.java:137)
    at clojure.core$apply.invokeStatic(core.clj:650)
    at clojure.core$use.invokeStatic(core.clj:5860)
    at clojure.core$use.doInvoke(core.clj:5860)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at expresso_2d.core_test$eval9670$loading__5569__auto____9671.invoke(core_test.clj:1)
    at expresso_2d.core_test$eval9670.invokeStatic(core_test.clj:1)
    at expresso_2d.core_test$eval9670.invoke(core_test.clj:1)
    at clojure.lang.Compiler.eval(Compiler.java:6927)
    at clojure.lang.Compiler.eval(Compiler.java:6916)
    at clojure.lang.Compiler.load(Compiler.java:7379)
    at clojure.lang.RT.loadResourceScript(RT.java:372)
    at clojure.lang.RT.loadResourceScript(RT.java:363)
    at clojure.lang.RT.load(RT.java:453)
    at clojure.lang.RT.load(RT.java:419)
    at clojure.core$load$fn__5677.invoke(core.clj:5893)
    at clojure.core$load.invokeStatic(core.clj:5892)
    at clojure.core$load.doInvoke(core.clj:5876)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at clojure.core$load_one.invokeStatic(core.clj:5697)
    at clojure.core$load_one.invoke(core.clj:5692)
    at clojure.core$load_lib$fn__5626.invoke(core.clj:5737)
    at clojure.core$load_lib.invokeStatic(core.clj:5736)
    at clojure.core$load_lib.doInvoke(core.clj:5717)
    at clojure.lang.RestFn.applyTo(RestFn.java:142)
    at clojure.core$apply.invokeStatic(core.clj:648)
    at clojure.core$load_libs.invokeStatic(core.clj:5774)
    at clojure.core$load_libs.doInvoke(core.clj:5758)
    at clojure.lang.RestFn.applyTo(RestFn.java:137)
    at clojure.core$apply.invokeStatic(core.clj:648)
    at clojure.core$require.invokeStatic(core.clj:5796)
    at clojure.core$require.doInvoke(core.clj:5796)
    at clojure.lang.RestFn.invoke(RestFn.java:421)
    at midje.repl$load_facts$fn__9602.invoke(repl.clj:208)
    at midje.repl$load_facts.invokeStatic(repl.clj:194)
    at midje.repl$load_facts.doInvoke(repl.clj:194)
    at clojure.lang.RestFn.invoke(RestFn.java:397)
    at user$eval9665.invokeStatic(form-init376345494813737166.clj:1)
    at user$eval9665.invoke(form-init376345494813737166.clj:1)
    at clojure.lang.Compiler.eval(Compiler.java:6927)
    at clojure.lang.Compiler.eval(Compiler.java:6917)
    at clojure.lang.Compiler.load(Compiler.java:7379)
    at clojure.lang.Compiler.loadFile(Compiler.java:7317)
    at clojure.main$load_script.invokeStatic(main.clj:275)
    at clojure.main$init_opt.invokeStatic(main.clj:277)
    at clojure.main$init_opt.invoke(main.clj:277)
    at clojure.main$initialize.invokeStatic(main.clj:308)
    at clojure.main$null_opt.invokeStatic(main.clj:342)
    at clojure.main$null_opt.invoke(main.clj:339)
    at clojure.main$main.invokeStatic(main.clj:421)
    at clojure.main$main.doInvoke(main.clj:384)
    at clojure.lang.RestFn.invoke(RestFn.java:421)
    at clojure.lang.Var.invoke(Var.java:383)
    at clojure.lang.AFn.applyToHelper(AFn.java:156)
    at clojure.lang.Var.applyTo(Var.java:700)
    at clojure.main.main(main.java:37)
Caused by: clojure.lang.ArityException: Wrong number of args (2) passed to: StringReader
    at clojure.lang.AFn.throwArity(AFn.java:429)
    at clojure.lang.AFn.invoke(AFn.java:36)
    at instaparse.cfg$eval16836$safe_read_string__16837.invoke(cfg.clj:157)
    at instaparse.cfg$process_string.invokeStatic(cfg.clj:174)
    at instaparse.cfg$process_string.invoke(cfg.clj:166)
    at instaparse.cfg$build_rule.invokeStatic(cfg.clj:210)
    at instaparse.cfg$build_rule.invoke(cfg.clj:194)
    at clojure.core$map$fn__4785.invoke(core.clj:2644)
    at clojure.lang.LazySeq.sval(LazySeq.java:40)
    at clojure.lang.LazySeq.seq(LazySeq.java:49)
    at clojure.lang.RT.seq(RT.java:521)
    at clojure.core$seq__4357.invokeStatic(core.clj:137)
    at clojure.core$apply.invokeStatic(core.clj:641)
    at clojure.core$apply.invoke(core.clj:641)
    at instaparse.cfg$build_rule.invokeStatic(cfg.clj:209)
    at instaparse.cfg$build_rule.invoke(cfg.clj:194)
    at clojure.core$map$fn__4785.invoke(core.clj:2644)
    at clojure.lang.LazySeq.sval(LazySeq.java:40)
    at clojure.lang.LazySeq.seq(LazySeq.java:49)
    at clojure.lang.RT.seq(RT.java:521)
    at clojure.core$seq__4357.invokeStatic(core.clj:137)
    at clojure.core$apply.invokeStatic(core.clj:641)
    at clojure.core$apply.invoke(core.clj:641)
    at instaparse.cfg$build_rule.invokeStatic(cfg.clj:205)
    at instaparse.cfg$build_rule.invoke(cfg.clj:194)
    at instaparse.cfg$build_rule.invokeStatic(cfg.clj:208)
    at instaparse.cfg$build_rule.invoke(cfg.clj:194)
    at clojure.core$map$fn__4785.invoke(core.clj:2644)
    at clojure.lang.LazySeq.sval(LazySeq.java:40)
    at clojure.lang.LazySeq.seq(LazySeq.java:49)
    at clojure.lang.RT.seq(RT.java:521)
    at clojure.core$seq__4357.invokeStatic(core.clj:137)
    at clojure.core$apply.invokeStatic(core.clj:641)
    at clojure.core$apply.invoke(core.clj:641)
    at instaparse.cfg$build_rule.invokeStatic(cfg.clj:209)
    at instaparse.cfg$build_rule.invoke(cfg.clj:194)
    at clojure.core$map$fn__4785.invoke(core.clj:2644)
    at clojure.lang.LazySeq.sval(LazySeq.java:40)
    at clojure.lang.LazySeq.seq(LazySeq.java:49)
    at clojure.lang.RT.seq(RT.java:521)
    at clojure.core$seq__4357.invokeStatic(core.clj:137)
    at clojure.core$apply.invokeStatic(core.clj:641)
    at clojure.core$apply.invoke(core.clj:641)
    at instaparse.cfg$build_rule.invokeStatic(cfg.clj:205)
    at instaparse.cfg$build_rule.invoke(cfg.clj:194)
    at instaparse.cfg$build_rule.invokeStatic(cfg.clj:201)
    at instaparse.cfg$build_rule.invoke(cfg.clj:194)
    at clojure.core$map$fn__4785.invoke(core.clj:2644)
    at clojure.lang.LazySeq.sval(LazySeq.java:40)
    at clojure.lang.LazySeq.seq(LazySeq.java:49)
    at clojure.lang.RT.seq(RT.java:521)
    at clojure.core$seq__4357.invokeStatic(core.clj:137)
    at clojure.core.protocols$seq_reduce.invokeStatic(protocols.clj:24)
    at clojure.core.protocols$fn__6738.invokeStatic(protocols.clj:75)
    at clojure.core.protocols$fn__6738.invoke(protocols.clj:75)
    at clojure.core.protocols$fn__6684$G__6679__6697.invoke(protocols.clj:13)
    at clojure.core$reduce.invokeStatic(core.clj:6545)
    at clojure.core$into.invokeStatic(core.clj:6610)
    at clojure.core$into.invoke(core.clj:6604)
    at instaparse.cfg$ebnf.invokeStatic(cfg.clj:270)
    at instaparse.cfg$ebnf.invoke(cfg.clj:259)
    at clojure.lang.AFn.applyToHelper(AFn.java:154)
    at clojure.lang.AFn.applyTo(AFn.java:144)
    at clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:3652)
    ... 189 more
Subprocess failed
Vaguery commented 8 years ago

This is running this test suite:

https://github.com/Vaguery/expresso-2dgeometry

JMacLulich commented 8 years ago

@Vaguery I'm getting this error on a totally unrelated project, I'm trying to figure out what combination of dependencies or code paths is triggering this.

Did you get to the bottom of your problem per chance?

Vaguery commented 7 years ago

@JMacLulich Sorry, never did. TBH I was still very early in my exploratory phase with Clojure when I found this, and I'm not even sure what project I was working on when it cropped up.

Well, aside from the test posted, that is.

mschuene commented 7 years ago

Closing this as the current version is now compatible with Clojure 1.8