如何生成一些带有数字的列表?

时间:2017-03-19 18:11:02

标签: prolog

我想生成一个包含所有数字x=0 while index('$',x+1) do x = index('$',x+1) #function that does translating end 的列表,其中abca = c

我知道如何生成数字,但我不知道如何将它们添加到列表中,因为我无法执行b >= a + c之类的操作。

我不知道如何定义L = [Number|L]谓词......或者我应该以另一种方式来做? 我已经尝试将其定义为add,但我不知道在那之后该怎么做。

add(Nr, L, [Nr|L]).

输出应为:
c(0). c(1). c(2). c(3). c(4). c(5). c(6). c(7). c(8). c(9). bts(L, Lr) :- c(A), A =\= 0, c(C), A =:= C, c(B), C =\=9, B >= A + C, Nr is A * 100 + B * 10 + C, add(......). solve(L) :- bts([], L).

3 个答案:

答案 0 :(得分:1)

你走在正确的轨道上。这里有两个小技巧:

  1. 首先,最重要的是,关注单一解决方案的外观。您始终可以使用findall/3setof/3等元谓词将所有解决方案收集到解决方案的列表中。
  2. 其次,在您的案例中有更智能的方法来描述解决方案。目前,您正在使用生成和测试,这对于更大的问题是不可行的策略。相反,使用Prolog系统的约束求解器以声明方式描述所有要求。这使引擎可以应用修剪以避免生成所有组合。
  3. 总的来说,我建议的做法与以下内容类似:

    abc(Ls) :-
            Ls = [A,B,C],
            A #= C,
            A #\= 0,
            C #\= 9,
            B #>= A + C,
            Ls ins 0..9.
    

    我们现在可以尝试最常见的查询来查看一般的解决方案:

    ?- abc(Ls).
    Ls = [_940, _946, _940],
    _940 in 1..4,
    2*_940#=<_946,
    _946 in 2..9.
    

    这当然不是很有用,但它至少告诉我们我们的关系终止并且确定性

    这意味着所谓的标记,即具体解决方案的搜索也将终止。这是一个非常好的属性,因为它意味着搜索将始终终止,即使它可能需要很长时间。

    在这种情况下,搜索当然是微不足道的,我们可以使用例如label/1来枚举解决方案:

    ?- abc(Ls), label(Ls).
    Ls = [1, 2, 1] ;
    Ls = [1, 3, 1] ;
    Ls = [1, 4, 1] ;
    Ls = [1, 5, 1] ;
    etc.
    

    现在,为了获得您想要的结果,我们将使用findall/3所有解决方案收集到列表中:

    ?- abc(Ls),
       findall(N, (label(Ls),
                   atomic_list_concat(Ls,A),atom_number(A,N)), Ns).
    Ls = [_774, _780, _774],
    Ns = [121, 131, 141, 151, 161, 171, 181, 191, 242|...],
    _774 in 1..4,
    2*_774#=<_780,
    _780 in 2..9.
    

    我还冒昧地对每个解决方案应用一个小变换,以便您立即得到所需的结果。

    我在这里应用的形式主义称为 CLP(FD),调用此机制的确切细节在可用的Prolog系统之间略有不同。有关详细信息,请查看系统手册,另请参阅

答案 1 :(得分:1)

findall / 3和/ 3之间的简单应用

abc(Ns) :- findall(N, (between(1,9,A),between(1,9,B),C=A,B>=A+C,N is A * 100 + B * 10 + C), Ns).

答案 2 :(得分:1)

这是我找到的解决方案:

bts(1000, []) :- !.
bts(Nr, L) :-
         N is Nr + 1, 
         bts(N, X),
         once(((number_chars(Nr, [H1, H2, H3]), number_chars(A, [H1]), number_chars(C, [H3]),
                A =:= C, number_chars(B, [H2]), B >= A + C,
                L = [Nr|X]);
               L = X)).

solve(L) :- bts(100, L).