-1

Write predicate evenNumbers(L1, L2) which is true if the list L1 containing random integers and the list L2 contains even integers from L1.

For example:

?-evenNumbers ([2,1,-3,6,8,9], L2). 

»Your program returns L2 = [2,6,8].

My code is:

    evenNumbers([],[]).
    evenNumbers([H|T],L):-
        integer(H),
        0 is H mod 2,
        append([H],L,L);
        evenNumbers(T,L).
coder
  • 12,832
  • 5
  • 39
  • 53
  • I presume there is something wrong with it, but you haven't explained what. – Scott Hunter Nov 12 '16 at 19:16
  • the problem is this line: append([H],L,L); but i dont know how to resolve it without append. – Manos Mardkodimitrakis Nov 12 '16 at 19:34
  • See the closely related questions [Prolog Constraint Programing finding even and odd numbers](http://stackoverflow.com/questions/21584521/prolog-constraint-programing-finding-even-and-odd-numbers) and [Sum of even, product of odd numbers in Prolog](http://stackoverflow.com/questions/32543847/sum-of-even-product-of-odd-numbers-in-prolog) and the very nice declarative [**first answer**](http://stackoverflow.com/a/21607900/1613573) and [**second answer**](http://stackoverflow.com/a/32570620/1613573). – mat Nov 12 '16 at 19:52
  • I saw those answers before, but i just started learn prolog. So it was not so easy to figure out! – Manos Mardkodimitrakis Nov 12 '16 at 20:05
  • With the solution you accepted, please simply try out the most general query: "*Which solutions are there at all?*" We can ask: `?- evenNumbers(Ls, Es).`, and then we obtain, as the **only** solution: `Ls = Es, Es = []`. Surely that cannot be correct, no? Please think about the properties you actually expect from a Prolog program. For example, in the most general case, it would be terrific if the program answered with a succession of all possible solutions instead of only giving one of them. Let's hope better answers will be posted too. Consider waiting a bit and studying different approaches. – mat Nov 12 '16 at 20:08
  • @mat note that the second answer (using findall) in these cases returns Instantiation error as it should but first one is lacking many properties... – coder Nov 12 '16 at 20:35
  • @coder, throwing an instantiation error is definitely a good improvement over silent failure (silent failure would indicate that there are no further solutions, which would be wrong in this case). However, let us aim higher than this: I think a truly relational solution would be best in this case, which we can use in all directions, also for example if *only* the second, not the first argument is instantiated, and also if *none* of the arguments is instantiated. I think such a solution would most clearly exhibit the logical properties we expect from a declarative program. – mat Nov 12 '16 at 23:33

1 Answers1

2

Your code has multiple issues append([H],L,L); will stop recursion and give you a wrong list also your if-then-else statement isn't right .So you could write:

 evenNumbers([],[]).
 evenNumbers([H|T],L1):-
        integer(H),
        (H mod 2 =:=0 -> L1=[H|T1],evenNumbers(T,T1);
        evenNumbers(T,L1) ).

Example:

?- evenNumbers([2,1,-3,6,8,9], L2).
L2 = [2, 6, 8].

Another way writing it would be:

evenNumbers(L1,L2):-findall(X,(member(X,L1), X mod 2=:=0),L2).
coder
  • 12,832
  • 5
  • 39
  • 53