The shortest way to define multiple rules in a prolog

I am trying to solve an exercise in order to get to know the prologue better.

The task is as follows:

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

I decided this exercise, but in a somewhat bulky way. My code is:

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

Can anyone suggest a better method to initialize these rules? For example, in Haskell, I could do something like this:

 let numbers = [1..100] 

Thanks in advance.

+4
source share
3 answers

Some versions of Prolog have between / 3 predicate. Could you say

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

If in between is not available, you can say

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

If you do not want to use the / 2 member, use recursion.

Edit: you can also implement between / 3 as follows:

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

A strong and efficient implementation between / 3 may be more complex, but for your purposes this should be enough.

+5
source

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

Request example:

 ?- flowers(Lilies, Roses, Tulips), label([Lilies,Roses,Tulips]). Lilies = 1, Roses = 39, Tulips = 60 ; false. 
+7
source
 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 . 
+2
source

Source: https://habr.com/ru/post/1334222/


All Articles