1

Im having a problem with Prolog since cut is not doing what (i believe) its supposed to do:

% line-column handlers
checkVallEle(_, _, 6, _):- write('FAIL'), !, fail.
checkVallEle(TABULEIRO, VALUE, LINE, COLUMN):- COLUMN>5, NL is LINE+1, checkVallEle(TABULEIRO, VALUE, NL, 0).

% if this fails, it goes to the next
checkVallEle(TABULEIRO, VALUE, LINE, COLUMN):-
       (checkHorizontal(TABULEIRO, VALUE, LINE, COLUMN, 0), write('HORIZONTAL ');
        checkVertical(TABULEIRO, VALUE, LINE, COLUMN, 0), write('VERTICAL');
        checkDiagonalRight(TABULEIRO, VALUE, LINE, COLUMN, 0), write('DIAGONALRIGHT');
        checkDiagonalLeft(TABULEIRO, VALUE, LINE, COLUMN, 0), write('DIAGONALLEFT')),
        write('WIN').

% goes to the next if above fails
checkVallEle(TABULEIRO, VALUE, LINE, COLUMN):-
        NC is COLUMN+1,
        checkVallEle(TABULEIRO, VALUE, LINE, NC).

What I wish to do is that if the code ever reaches the first statement, that is, if the line is ever 6, it fails (since it went out of range), without checking for more possibilities. But what happens is, when it reaches the first statement, it keeps going to the below statements and ignores the cut symbol, and I dont see why. I just want the statement to fail when it reaches the first line.

I also made an experience...

run(6):-write('done'), !, fail.
run(X):-X1 is X+1, run(X1).

And this is what i get from tracing:

| ?- run(0).
        1      1 Call: run(0) ? 
        2      2 Call: _1079 is 0+1 ? 
        2      2 Exit: 1 is 0+1 ? 
        3      2 Call: run(1) ? 
        4      3 Call: _3009 is 1+1 ? 
        4      3 Exit: 2 is 1+1 ? 
        5      3 Call: run(2) ? 
        6      4 Call: _4939 is 2+1 ? 
        6      4 Exit: 3 is 2+1 ? 
        7      4 Call: run(3) ? 
        8      5 Call: _6869 is 3+1 ? 
        8      5 Exit: 4 is 3+1 ? 
        9      5 Call: run(4) ? 
       10      6 Call: _8799 is 4+1 ? 
       10      6 Exit: 5 is 4+1 ? 
       11      6 Call: run(5) ? 
       12      7 Call: _10729 is 5+1 ? 
       12      7 Exit: 6 is 5+1 ? 
       13      7 Call: run(6) ? 
       14      8 Call: write(done) ? 
done
       14      8 Exit: write(done) ? 
       13      7 Fail: run(6) ? 
       11      6 Fail: run(5) ? 
        9      5 Fail: run(4) ? 
        7      4 Fail: run(3) ? 
        5      3 Fail: run(2) ? 
        3      2 Fail: run(1) ? 
        1      1 Fail: run(0) ? 
no

What are all those Fails after the write? is it still backtracing to previous answers? Is this behaviour the reason why cut is failing in my first code? Please enlighten me.

4

1 回答 1

0

考虑最后一步,您正在评估run(5):-run(6).. run(6)失败,这意味着run(5)失败,这当然意味着run(4)失败,等等。

至于你原来的问题,它并没有忽略削减。剪切不会完全停止回溯,它只会停止回溯以获取解决方案checkVallEle(_,_,6,_)- 一旦失败,它将开始回溯以获取更多解决方案LINE=5

真正的问题是你的其余规则受到了限制。一旦它尝试了第二种情况COLUMN=6,它就会尝试第三种情况COLUMN=6- 没有什么可以阻止它。您可以通过对其进行更多削减来解决此问题,但这不是一个很好的方法。

更好的方法是明确所有约束。checkVallEle(_,_,6,_)只要您LINE<6在其他所有规则的开头都说,就没有必要插话。而且,如果您COLUMN<6在每条规则中都说(当然第二条除外),它应该可以通过意外回溯来解决您的问题。

于 2013-11-07T05:20:29.547 回答