3 ms·
Don't understand why the article uses SWI's constraint libs when the problem is easily solved using pure ISO Prolog with code readily linked from the article ev
by tannhaeuser 2y ago
Don't understand why the article uses SWI's constraint libs when the problem is easily solved using pure ISO Prolog with code readily linked from the article even ie Pablo's solution at [2].
Just paste that code into [1] and append the line (or place it at the start, doesn't matter)
:- initialization(colin_score(X)).
to tell Prolog which top-level goal to solve and hit Execute to see the solution in your browser.
[1]: https://quantumprolog.sgml.net/browser-demo/browser-demo.html https://quantumprolog.sgml.net/browser-demo/browser-demo.htm...
[2]: https://morepablo.com/2010/09/some-professor-layton-prolog.html https://morepablo.com/2010/09/some-professor-layton-prolog.h...
- Avshalom 2y agoIt's hardly SWI's lib, clpFD is available almost identically in Sicstus, Ciao, GNU, B† and others. As to why? I dunno I guess for a lot of us constraint programming just comes to hand very naturally. It often feels more Prolog-y to us than non-constraint approaches. †B-Prolog of course morphed into Picat which is also mentioned and Picat also leans heavy on clp so if the author is more familiar with Picat it would be even more natural to use clpFD.
- jodrellblank 2y agoIt can be more briefly solved without constraints than the linked code, brute-forcing through the possible correct-answer permutations: member_of(List, X) :- % helper swaps args for use with maplist. member(X, List). score(Given, Correct, Adder, NewScore) :- (Given = Correct % Prolog if/else -> NewScore is Adder + 10 ; NewScore = Adder). puzzle(ColinScore) :- length(CorrectAnswers, 10), % ten unknown correct answers, maplist(member_of([a,b]), CorrectAnswers), % each 'a' or 'b' % compare player answers to correct answers, add their scores. foldl(score, [b,b,a,b,a,b,b,a,b,b], CorrectAnswers, 0, 70), % Mary foldl(score, [b,a,a,a,b,a,b,a,a,a], CorrectAnswers, 0, 50), % Dan foldl(score, [b,a,a,a,b,b,b,a,b,a], CorrectAnswers, 0, 30), % Lisa foldl(score, [b,b,a,a,a,b,b,a,a,a], CorrectAnswers, 0, ColinScore). Then: ?- puzzle(ColinScore). ColinScore = 60 It's fine for a toy puzzle and it uses fewer resources than invoking the constraint solver, but it's a poor way to approach a puzzle or real world task with a larger search space.
- hwayne 2y agoThe `(if -> then; else)` syntax introduces a cut, which I found hides possible solutions.
- jodrellblank 2y agoI believe that is not a concern in my code; if "a=a" then commiting to that cannot hide any possible solutions where either side of the equals could be different because we've already tested and found them equal (they unify). One can avoid that worry by swapping in this version instead: score(X, X, Adder, NewScore) :- NewScore is Adder + 10. score(X, Y, Adder, Adder) :- dif(X, Y). Leaving choicepoints where I don't want them is an annoying part of Prolog when I know the answer is deterministic - that's where I used zcompare/3 in my other answer in this thread, but it's far too much effort to write that pattern for every test situation. For people who object to `is` then make it `succ(Adder, NewScore)` and adjust the player scores down by a factor of ten as per the blog post. For people who comment that succ/2 doesn't always work, note that the Adder is always initialised to 0 in the foldl goal so succ/2 always has one instantiated value. [It just wouldn't be a Prolog solution if it wasn't hard to write, hard to read, hard to verify that it's working properly, full of single letter variable names OrLongWordVariableNames and immediately making people talk about cut and constraint handlers and ISO compatibility and Prolog internals rather than the problem. On that note, PabloLife's code has "flip(correct, incorrect)" which is imperatively named but doesn't do anything imperative, uses nested lists instead of Number-Answer pairs which is more visually cluttered and uses more memory...].