在prolog中定义多个规则的最短方法

pac*_*an. 4 prolog logic-programming clpfd

我正在尝试解决一个练习,以便更熟悉prolog.

任务如下:

% Sten wants to send Lisa 100 flowers. He can choose from lilies, roses and tulips.
% One lily costs $50, rose $10 and tulip $1. Find how many flowers of each type he 
% must buy, so that he spends exactly $500.
Run Code Online (Sandbox Code Playgroud)

我已经解决了这个练习,但我觉得有点笨重.我的代码是:

% numbers 1..100
digit(1). digit(2). digit(3). digit(4). digit(5). digit(6). digit(7). digit(8).
digit(9). digit(10). digit(11). digit(12). digit(13). digit(14). digit(15). digit(16). 
digit(17). digit(18). digit(19). digit(20). digit(21). digit(22). digit(23). digit(24). 
digit(25). digit(26). digit(27). digit(28). digit(29). digit(30). digit(31). digit(32). 
digit(33). digit(34). digit(35). digit(36). digit(37). digit(38). digit(39). digit(40).
digit(41). digit(42). digit(43). digit(44). digit(45). digit(46). digit(47). digit(48). 
digit(49). digit(50). digit(51). digit(52). digit(53). digit(54). digit(55). digit(56). 
digit(57). digit(58). digit(59). digit(60). digit(61). digit(62). digit(63). digit(64). 
digit(65). digit(66). digit(67). digit(68). digit(69). digit(70). digit(71). digit(72). 
digit(73). digit(74). digit(75). digit(76). digit(77). digit(78). digit(79). digit(80).
digit(81). digit(82). digit(83). digit(84). digit(85). digit(86). digit(87). digit(88). 
digit(89). digit(90). digit(91). digit(92). digit(93). digit(94). digit(95). digit(96). 
digit(97). digit(98). digit(99). digit(100).

quantity(A1,A2,A3):-
    var(A1), var(A2), var(A3),
    digit(A1), digit(A2), digit(A3),
    X is A1+A2+A3, X is 100,
    Y is (A1*50)+(A2*10)+(A3*1), Y is 500.
Run Code Online (Sandbox Code Playgroud)

有人可以建议一种更好的方法来初始化这些规则吗?例如在Haskell中,我可以这样做:

let numbers = [1..100]
Run Code Online (Sandbox Code Playgroud)

提前致谢.

mat*_*mat 7

使用SWI-Prolog:

:- use_module(library(clpfd)).

flowers(L, R, T) :-
        [L,R,T] ins 0..sup,
        L+R+T #= 100,
        L*50 + R*10 + T*1 #= 500.
Run Code Online (Sandbox Code Playgroud)

示例查询:

?- flowers(Lilies, Roses, Tulips), label([Lilies,Roses,Tulips]).
Lilies = 1,
Roses = 39,
Tulips = 60 ;
false.
Run Code Online (Sandbox Code Playgroud)


Pav*_*ant 6

某些版本的Prolog具有介于/ 3之间的谓词.你可以说

digit(X):-between(1,100,X).
Run Code Online (Sandbox Code Playgroud)

如果没有,你可以说

digit(X):-member(X,[1,2,3,4,5 and so on]).
Run Code Online (Sandbox Code Playgroud)

如果您不想使用member/2,请使用递归.

编辑:你也可以在/ 3之间实现这样:

my_between(X,Y,Z):-X<Y,(Z=X;X2 is X+1,my_between(X2,Y,Z)).
Run Code Online (Sandbox Code Playgroud)

在/ 3之间强大而有效的实现可能会更复杂,但对于您的目的,这应该足够了.