尝试在Prolog中运行(显然)简单谓词时遇到麻烦

时间:2011-11-30 16:57:48

标签: prolog

我在prolog中实现了以下谓词:

roulette_wheel(EvaluatedPopulation, Result) :-
    get_total_fitness(EvaluatedPopulation, Total_fitness),
    random(0, Total_fitness, Target),
    roulette_wheel_iteration(EvaluatedPopulation, 0, Target, Result).

roulette_wheel_iteration([[Fitness,Individual]|Tail], Counter, Target, Result) :-
    CounterX is Counter + Fitness,
    (CounterX >= Target) -> (Result = Individual); roulette_wheel_iteration(Tail, CounterX, Target, Result).

当试图运行它们时,它很可能失败了

| ?- roulette_wheel([[10,[1,1,1]], [20, [2,2,2]], [50, [5,5,5]]], R).
! Instantiation error in argument 2 of is/2
! goal:  _114 is _117+20

以下是跟踪日志:

| ?- roulette_wheel([[10,[1,1,1]], [20, [2,2,2]], [50, [5,5,5]]], R).
        1      1 Call: roulette_wheel([[10,[1,1,1]],[20,[2,2,2]],[50,[5,5,5]]],_597) ? 
        2      2 Call: get_total_fitness([[10,[1,1,1]],[20,[2,2,2]],[50,[5,5,5]]],_1183) ? 
        3      3 Call: get_total_fitness([[20,[2,2,2]],[50,[5,5,5]]],_1691) ? 
        4      4 Call: get_total_fitness([[50,[5,5,5]]],_2191) ? 
        5      5 Call: get_total_fitness([],_2691) ? 
        5      5 Exit: get_total_fitness([],0) ? 
        6      5 Call: _2191 is 50+0 ? 
        6      5 Exit: 50 is 50+0 ? 
        4      4 Exit: get_total_fitness([[50,[5,5,5]]],50) ? 
        7      4 Call: _1691 is 20+50 ? 
        7      4 Exit: 70 is 20+50 ? 
        3      3 Exit: get_total_fitness([[20,[2,2,2]],[50,[5,5,5]]],70) ? 
        8      3 Call: _1183 is 10+70 ? 
        8      3 Exit: 80 is 10+70 ? 
        2      2 Exit: get_total_fitness([[10,[1,1,1]],[20,[2,2,2]],[50,[5,5,5]]],80) ? 
        9      2 Call: random(0,80,_1190) ? 
        9      2 Exit: random(0,80,12) ? 
       10      2 Call: roulette_wheel_iteration([[10,[1,1,1]],[20,[2,2,2]],[50,[5,5,5]]],0,12,_597) ? 
       11      3 Call: _9340 is 0+10 ? 
       11      3 Call: _9340 is 0+10 ? 
       11      3 Exit: 10 is 0+10 ? 
       12      3 Call: 10>=12 ? 
       12      3 Fail: 10>=12 ? 
       13      3 Call: roulette_wheel_iteration([[20,[2,2,2]],[50,[5,5,5]]],_9340,12,_597) ? 
       14      4 Call: _9897 is _9340+20 ? 
! Instantiation error in argument 2 of is/2
! goal:  _9979 is _9982+20
       14      4 Exception: _9897 is _9340+20 ? 
! Instantiation error in argument 2 of is/2
! goal:  _9418 is _9421+20
       13      3 Exception: roulette_wheel_iteration([[20,[2,2,2]],[50,[5,5,5]]],_9340,12,_597) ? 
! Instantiation error in argument 2 of is/2
! goal:  _8894 is _8897+20
       10      2 Exception: roulette_wheel_iteration([[10,[1,1,1]],[20,[2,2,2]],[50,[5,5,5]]],0,12,_597) ? 
! Instantiation error in argument 2 of is/2
! goal:  _911 is _914+20
        1      1 Exception: roulette_wheel([[10,[1,1,1]],[20,[2,2,2]],[50,[5,5,5]]],_597) ? 
! Instantiation error in argument 2 of is/2
! goal:  _114 is _117+20

有谁能告诉我为什么会失败?

1 个答案:

答案 0 :(得分:1)

失败是因为is运算符不允许在右操作数中使用未实例化的变量。

在您的示例中,Counter未被实例化。我猜这个问题就说明了你使用;/2的方式。

考虑对您的代码进行此修改:

roulette_wheel_iteration([[Fitness,Individual]|Tail], Counter, Target, Result) :-
    CounterX is Counter + Fitness,
    (CounterX >= Target -> (Result = Individual); roulette_wheel_iteration(Tail, CounterX, Target, Result)).