4

我正在尝试解决一个练习,以便更熟悉序言。

任务如下:

% 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.

我已经解决了那个练习,但我猜有点笨重。我的代码是:

% 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.

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

let numbers = [1..100]

提前致谢。

4

3 回答 3

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.

示例查询:

?- flowers(Lilies, Roses, Tulips), label([Lilies,Roses,Tulips]).
Lilies = 1,
Roses = 39,
Tulips = 60 ;
false.
于 2011-01-04T17:25:48.803 回答
6

Prolog 的某些版本具有 between/3 谓词。你可以说

digit(X):-between(1,100,X).

如果 between 不可用,你可以说

digit(X):-member(X,[1,2,3,4,5 and so on]).

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

编辑:您也可以像这样实现 between/3:

my_between(X,Y,Z):-X<Y,(Z=X;X2 is X+1,my_between(X2,Y,Z)).

between/3 的健壮和高效的实现可能会更复杂,但就您的目的而言,这应该足够了。

于 2011-01-04T16:03:16.313 回答
3
quantity(lilies(L),roses(R),tulips(T)) :- 
    between(0,100,L),
    between(0,100,R),
    between(0,100,T),
    L + R + T =:= 100,
    L*50 + R*10 + T =:= 500 .
于 2011-01-05T19:53:41.287 回答