【发布时间】:2014-07-31 02:00:35
【问题描述】:
我是 Prolog 的初学者。
我有一个函数遍历列表并在满足条件时返回true。
例如,check_version 会检查包版本是否满足条件(例如,版本是否满足条件,例如大于或小于特定版本),而 check_all 会根据版本列表和条件进行一一检查。
package('python', '2.6.5').
package('python', '2.5.4').
package('python', '1.5.2').
package('python', '3.1.0').
check_version(Pac, Ver, Cmp, V):-
package(Pac, V),
cmp_version(V, Ver, Cmp).
check_all( Pac, [], [], V):-
package(Pac, V).
check_all(Pac, [Ver], [Cmp], V):-
check_version(Pac, Ver, Cmp, V).
check_all(Pac, [Ver|VerS], [Cmp|CmpS], V):-
check_version(Pac, Ver, Cmp, V),
check_all(Pac, VerS, CmpS, V).
我遇到的问题是当我尝试寻找其他解决方案时,它给了我重复的解决方案。
我明白了:
check_all('python', ['3.0','2.4'], [lt,ge], V).
V = '2.6.5' ;
V = '2.6.5' ;
V = '2.5.4' ;
V = '2.5.4' .
预期:
check_all('python', ['3.0','2.4'], [lt,ge], V).
V = '2.6.5' ;
V = '2.5.4' .
我使用跟踪来跟踪它,以及我发现的问题,当它试图找到另一个解决方案时,它会回溯并返回失败,直到找到正确的解决方案。与上面的示例一样,显然,它首先会为 V='2.6.5' 返回 true,然后将其返回并运行函数,我们希望它返回 false,然后当它到达开头时运行 package(' python', V) 和 V 将采用另一个值。
...
Exit: (7) check_all(python, ['3.0', '2.4'], [lt, ge], '2.6.5') ? creep
V = '2.6.5'
...
Fail: (9) check_version(python, '2.4', ge, '2.6.5') ? creep
Redo: (8) check_all(python, ['2.4'], [ge], '2.6.5') ? creep
Call: (9) check_version(python, '2.4', ge, '2.6.5') ? creep
Call: (10) package(python, '2.6.5') ? creep
Exit: (10) package(python, '2.6.5') ? creep
当回溯时,在 check_all 中,它在 check_all 处失败,正如我们预期的那样,但是当它回溯 check_version 并运行 package(python, '2.6.5') 作为 V=2.6.5 一个新值时它返回 true。所以当 V=2.6.5 时它再次返回 true。有没有办法解决这个问题?
【问题讨论】:
标签: recursion prolog backtracking