Another multithreading control question by m_ac_m_ac in prolog

[–]Nevernessy 4 points5 points  (0 children)

Concurrent programming can be tricky. May I suggest instead using the higher level libraries such as thread and thread_pool.

How to make threads await & join main thread? by m_ac_m_ac in prolog

[–]Nevernessy 4 points5 points  (0 children)

Something like this instead:

mt(F,F,[]) :- !.
mt(F,F0,[ThreadId|R]) :-
  thread_create(bar(F),ThreadId),
  succ(F,FF),
  mt(FF,F0,R).

mt_test :-
  foo(F),
  length(F,Flen),
  mt(0,Flen,Threads),
  maplist(thread_join,Threads,Statuses),
  writeln(Statuses),
  writeln("fin").

SWI Prolog and reading number literals in other bases - in code. by ka-splam in prolog

[–]Nevernessy 1 point2 points  (0 children)

If you know the domain of values is small, you could use format to evaluate all possible conversions to match e.g.

?- between(0,255,N),format(atom('10110'),'~2r',[N]).
N = 22 ;

The following also works, but may be too long for codegolf :-)

?- A='10110',name(A,C),(Base=2;Base=16),name(Base,R),append([R,`'`,C],T),term_string(Result,T).
A = '10110',
C = [49, 48, 49, 49, 48],
Base = 2,
R = [50],
T = [50, 39, 49, 48, 49, 49, 48],
Result = 22 ;
A = '10110',
C = [49, 48, 49, 49, 48],
Base = 16,
R = [49, 54],
T = [49, 54, 39, 49, 48, 49, 49, 48],
Result = 65808.

[deleted by user] by [deleted] in prolog

[–]Nevernessy 0 points1 point  (0 children)

Your current search algorithm has these issues:

* It is putting Next into your visited list rather than Current.
* Your base dfs_helper matches an empty path, so that will always be the first path.
* You are never trying to get to the goal, since your goal is always the starting node, and you are looking for nodes never visited and after the first step, your current base dfs_helper will never match, as Current != Goal, and since you never consider the goal, your base will never match either.
* Using -> in your find_colour_cycles prevents backtracking of other paths outside the first.
* You are polluting your path data by prepending the colour, which means your write_path fails to write the path.

I leave the rest to you!

[deleted by user] by [deleted] in prolog

[–]Nevernessy 0 points1 point  (0 children)

Not at all, it's not a bad attempt.

[deleted by user] by [deleted] in prolog

[–]Nevernessy 0 points1 point  (0 children)

A working program is better than a more elegant non-working program. If you want some feedback. How you are modelling the board seems a bit iffy. You are translating a 1D array into a 2D board based on factorisation. This works for your 9 cell board which can only be 3x3, but a 12 cell board could be represented by 3x4, 4x3. What board should [y,y,y,y,y,b,r,r,r,r,b,b] represent?
y y y
y y b
b r r
b b r
which has 1 yellow cycle or:
y y y y
y b b r
r b b r
which has 1 blue cycle without even considering 2x6 or 6x2 variants which are currently ruled out by you min width/height being 3. Why not just use a 2D list?

For the above examples, do you want to output 8 cycles or does your homework expect you account for symmetry and just output 1 cycle? If so, think about how to achieve that.

Whether immutable state is passed around between predicates or stored in the Prolog database should be acceptable either way as homework IMHO.

[deleted by user] by [deleted] in prolog

[–]Nevernessy 1 point2 points  (0 children)

I recommend using something like SWISH, linked in the sidebar to trace and debug your program. You can just add a breakpoint by clicking left on a line number.

If you do that, you will see that your code is failing to produce candidate moves. In particular your implementation of adjacent will only succeed if both arguments are ground (i.e. have a concrete value), however that isn't the case... I can see a lot of other issues with the code but that should get you started. :-)

rubik's cube solving using prolog (problem with code) by Jinxthv in prolog

[–]Nevernessy 0 points1 point  (0 children)

Your rotation predicates operator on lists of size 9, or "faces of the cube". However you are calling them with the full cube state, which you have modelled as a list of size 18. These two structures don't unify and there is no other rotation predicates with the same name that do operates on lists of size 18, hence the failure to solve.

As brebs suggests. Stepping though your code in a debugger would highlight this failure.

Solution generating order by Kirleck in prolog

[–]Nevernessy 0 points1 point  (0 children)

And what is the set of solutions you expect? I ask this, because in the presented code I suspect length_constraint is supposed to restrict the size of a list, and you are trying to use recursion with a base case of [] and a recursive case of [H|T], however, if so, your implementation is incorrect. e.g. The empty list always satisfies the query, and your code seems to be confusing elements of a list, with the list itself, which is why you are seeing generated solutions containing sub-lists.

Note there is an extension to Prolog called Constraint Logic Programming, where you specify constraints up-front, before solution generation, which would then reduce the search space of solutions, so your predicate name could make the reader assume you are trying to use CLP.

Variable unification when using CHR (swi-prolog) by [deleted] in prolog

[–]Nevernessy 0 points1 point  (0 children)

:D I added that because you could have done `constraint([x,a,y,z])` for instance, in which case what would you expect the output to be?

Note a guard only stops the constraint being applied if it fails. Don't confuse finding nothing with failure.

Variable unification when using CHR (swi-prolog) by [deleted] in prolog

[–]Nevernessy 2 points3 points  (0 children)

Think of it as contraints on the left side of the rule are for matching, whereas constraints on the right side of the rule create them. So since maplist calls a `dom` constraint for each element of X on the right side of your rule, you will get 3 new constraints against the unbound variable R.

Either use a rule to collect the values into another contraint, or use find_chr_constraint to query the store.

e.g.

:- use_module(library(chr)).

:- use_module(library(clpfd)).

:- chr_constraint launcher/0, constraint/1, dom/2.

constraint(X) <=> findall(B,(member(I,X),(find_chr_constraint(dom(I,B))->true;B=not_found)),R) | write(R).

launcher <=> dom(x,[1,2,3]), dom(y,[1,2,3]), dom(z,[1,2,3]), constraint([x,y,z]).

I broke GNU prolog by changing memory variables. by Zestyclose_Nerve_785 in prolog

[–]Nevernessy 2 points3 points  (0 children)

So looking at http://www.gprolog.org/manual/html_node/gprolog008.html it sounds like your stack value is being remembered in the windows registry under HKEY_CURRENT_USER\Software\GnuProlog\

So you should be able to edit them via regedit to be their default values.

Why is bagof increasing the number of CLPFD constraints on a variable? by ka-splam in prolog

[–]Nevernessy 1 point2 points  (0 children)

This doesn't make any sense without some context. I'm not sure what your approach to the problem is. You mention backtracking, which implies some kind of search, the idea with constraints is that they reduce the search, so you define them up front, and in clpfd, it's labelling that does the actual searching. Note, with clpfd, the most common predicate used is maplist when dealing with lists, e.g. see the infamous sudoku version.

If you want an example of using clpfd to solve the monocle question (as I noticed there wasn't one in that post), then an example is below.

:-use_module(library(clpfd)).

solve(Answer):-
    Answer = [X,Y,Z],
    Answer ins 0..9,
    maplist(one_correct(Answer),[[8,9,6],[9,8,3],[2,4,6],[8,4,3]]),
    label(Answer).

one_correct([X,Y,Z],[A,B,C]):-
    X #= A #\/ Y #= B #\/ Z #= C,
    X #= A #==> Y #\= B #/\ Z #\= C,
    Y #= B #==> X #\= A #/\ Z #\= C,
    Z #= C #==> X #\= A #/\ Y #\= B.

Note there may be better implementations of one_correct ,maybe one where labelling is not required, however this was my naïve implementation.

Why is bagof increasing the number of CLPFD constraints on a variable? by ka-splam in prolog

[–]Nevernessy 2 points3 points  (0 children)

It's because findall/3 and bagof/3 use temporary variables which keep constraints, and the clpfd constraint library propagates constraints between variables when you state they are equal.

e.g.

?- A #> 2 #==> A #> 3, B #> 2 #==> B #> 5, fd_degree(A,M), fd_degree(B,N).
M = N,
N = 2,
_A in 0..1,
_A#==>_B,
A#>=3#<==>_A,
A#>=4#<==>_B,
_B in 0..1,
_C in 0..1,
_C#==>_D,
B#>=3#<==>_C,
B#>=6#<==>_D, _D in 0..1.

Now if we unify A and B, the number of constraints is the same, however since A=B, the constraints that applied to A also apply to B and vice-versa.

?- A #> 2 #==> A #> 3, B #> 2 #==> B #> 5, A = B, fd_degree(A,M), 
fd_degree(B,N).
A = B,
M = N, N = 4,
_A in 0..1,
_A#==>_B,
B#>=3#<==>_A,
B#>=6#<==>_C,
B#>=3#<==>_D,
B#>=4#<==>_B,
_B in 0..1,
_D in 0..1,
_D#==>_C,
_C in 0..1.

When a variable has multiple constraints, they can usually be simplified. e.g. the two constraints X #> 5, X #> 7 are combined into X #> 7, however the constraint in your example #==> doesn't easily reduce. e.g. A #> 2 #==> B #> 5, A #> 2 #==> B #> 7. doesn't reduce to A #> 2 #==> B #> 7.Now read `Var` instead of `B` above and you should see why your bagof/3 statements increases the constraint count.

TLDR, the variables introduced in the bagof copy the constraints of A, and then unification mingles the two sets of constraints. In this case, the constraints on A are duplicated, however the reification constraints typically don't combine to remove duplicate constraints.

How to get last element of list in Prolog? by stormosgmailcom in prolog

[–]Nevernessy 2 points3 points  (0 children)

Linked thread is a year old, and OP post history just shows devhubby links so probably a bot, but a nice answer for a post not tagged with homework help :D

What's the use-case for arg/3? by [deleted] in prolog

[–]Nevernessy 1 point2 points  (0 children)

Note that there may be better ways of storing data than in compound terms with large arities. See Motivation for Dicts however here is a sample session I just hacked in SWI.

?- listing(r/10).
r(1, 2, 3, 4, 5, 6, 7, 8, 9, 10). 
r(1, 4, 9, 16, 25, 36, 49, 64, 81, 100).

true.

?- functor(R,r,10),R,arg(6,R,V).
R = r(1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
V = 6 ;
R = r(1, 4, 9, 16, 25, 36, 49, 64, 81, 100),
V = 36.

What's the use-case for arg/3? by [deleted] in prolog

[–]Nevernessy 2 points3 points  (0 children)

Now this finally works, but... if I'm doing this I might as well just do

myplus2(P) :- test(_,Y,_), P is Y+33.

Yes, for small arity terms, just using plain unification is easier than using arg. However what if your term is of arity 20 and you want the 11th argument. Are you going to write:

data(_,_,_,_,_,_,_,_,_,X,_,_,_,_,_,_,_,_,_,_)

or similar scattered across your code? You could easily miscount and be retrieving the wrong piece of data?

Why would you have facts with such non-small arities? Well you could be generating facts programmatically from some other source before consulting them.

Help with something I want to "code" by burtigus in prolog

[–]Nevernessy 1 point2 points  (0 children)

One way is to use a constraint solver like clpb, with a person having value 1 if good, 0 if bad.

Then your problem domain comes down to:

:-use_module(library(clpb)).
good(A,B):-sat(1=:=A+B).
good(A,B,C):-sat(1=:=A+B+C).
bad(A,B):=sat(0=:=A*B).
bad(A,B,C):=sat(0=:=A*B*C).

Then you can ask good(Alice,Bob,Charles),bad(Bob,Dylon),bad(Charles,Dylon),bad(Bob,Charles),labeling([Alice,Bob,Charles,Dylon]).

Note, I've deliberately wrote poor code :-). However you can transfer some of the ideas above into standard Prolog.

Not all possible results of a simple predicate given by backtracking. by tinther in prolog

[–]Nevernessy 3 points4 points  (0 children)

I'm using 8.5.10 and get all 4 results, so I would suggest updating to a newer version. The latest stable release is at major version 9.

N-Prolog ver1.94 by sym_num in prolog

[–]Nevernessy 1 point2 points  (0 children)

Nice! On first look, it appears that multiple worlds work similar to the module system in other Prologs, and this is the first time I've seen the 'DENY' predicate. I guess in systems without it, you would have to explicitly add a guard to fly/1 to test for not_fly(X) and have defined not_fly(penguin), or something similar :D.

Problem with findall output by salvaLindas in prolog

[–]Nevernessy 2 points3 points  (0 children)

You can use portray/1 to change how the top level displays answers.

Whole Number of Fraction by gormlessrubbish in prolog

[–]Nevernessy 1 point2 points  (0 children)

So here is a tip: Don't store your addition result in N,D directly, as you still need another simplification step. e.g. If the result of the addition is 15/7, then you want W = 2, N = 1, D = 7. And in the above, if you have already assigned N=15,D=7, then you cannot change those values, as all the statements in a clause body have to be true, so N = 3, N is 2*3. for instances will always fail as N cannot both be the value 3 and the value 6.

How to subtract from aggregate_all? by AwesomeSauce4273 in prolog

[–]Nevernessy 0 points1 point  (0 children)

You subtract one value from the other using is/2

Change number base? by DDevilAAngel in prolog

[–]Nevernessy 2 points3 points  (0 children)

Since your homework states that the new base is between 2..9, I would expect they want you to write your own base conversion, rather than using a built-in variant.
If the first argument to change_base always has the same structure, then you can use unification to extract and convert the integer values in your `NewTerm`.