2
votes

Right to the chase:

I'm having trouble dealing with Prolog's unification system, and what happens to wildcards when they go through my procedure. My code is as follows:

board(B) :- [R1, R2, R3, R4, R5, R6, R7, R8, R9] = B,
        noDuplicatesRows([R1, R2, R3, R4, R5, R6, R7, R8, R9]),
        horzAllWorthy([R1, R2, R3, R4, R5, R6, R7, R8, R9]),
        vertAllWorthy([R1, R2, R3, R4, R5, R6, R7, R8, R9]).

The board is a sudoku board. I'm basically testing if the rows in the board have duplicate numbers, then testing to see if the rows and columns pass certain constraints. The problem is that the rows have wildcards in them to represent empty spots (laid out like: [ _ ,1,4,3_ .... etc]). From what I've gathered, when I run B through noDuplicatesRows, the wildcard spots are given values before they get run through the other two procedures, which is not what I want. However, due to Prolog's unification system, I can't seem to get around this (and I've already tried duplicating the list!).

Any answers here, or am I going about this in a very non-Prolog way?

edit: helper function code

noDuplicatesRows([]).
noDuplicatesRows([H|T]):- usedNumbersRow(H, X), diff(X), !, noDuplicatesRows(T).

usedNumbersRow([], []).
usedNumbersRow([X|Xs], R) :- var(X), validval(X), !, usedNumbersRow(Xs, R).
usedNumbersRow([X|Xs], [X|R]) :- usedNumbersRow(Xs, R).

diff([H]).
diff([H|T]):- not(member(H,T)), diff(T).
1

1 Answers

2
votes

This is not really an "answer" but too long to fit in a comment:

The word "wildcard" is not very helpful here. You have variables. They can be either free, or they get instantiated to a value. There is nothing saying that a predicate must instantiate all arguments passed to it, and this is what you use the _ for: signifying that you don't want to really do anything with a variable. For example:

nothing(_).

The argument passed to this predicate will not be further instantiated. Or, to put it in another way, whatever the argument you give to nothing/1, it will come out as it went in.

So the real question here is probably: what are the helper predicates in your program doing with the arguments passed to them?

And anyway, if your goal is to solve a sudoku, you would have to eventually instantiate all variables (fields not known on the initial board) such that all constraints are satisfied.

If you have a more specific question it would be easier to help you with the problem you are facing.

EDIT:

The _ does not go over to the predicate you are calling. It only matters in the context of the predicate clause in which it appears. In your case, it is probably the validval(X) that instantiates the variables (again, I don't know what it does!)