Numbers in a list smaller than a given number

Hernan
xMenores(_,[],[]).
xMenores(X,[H|T],[R|Z]) :-
   xMenores(X,T,Z),
   X > H,
   R is H.

xMenores takes three parameters:

  • The first one is a number.
  • The second is a list of numbers.
  • The third is a list and is the variable that will contain the result.

The objective of the rule xMenores is obtain a list with the numbers of the list (Second parameter) that are smaller than the value on the first parameter. For example:

?- xMenores(3,[1,2,3],X).
X = [1,2].                        % expected result

The problem is that xMenores returns false when X > H is false and my programming skills are almost null at prolog. So:

?- xMenores(4,[1,2,3],X).
X = [1,2,3].                      % Perfect.

?- xMenores(2,[1,2,3],X).
false.                            % Wrong! "X = [1]" would be perfect.

I consider X > H, R is H. because I need that whenever X is bigger than H, R takes the value of H. But I don't know a control structure like an if or something in Prolog to handle this.

Please, any solution? Thanks.

user1812457

Using ( if -> then ; else )

The control structure you might be looking for is ( if -> then ; else ).

Warning: you should probably swap the order of the first two arguments:

lessthan_if([], _, []).
lessthan_if([X|Xs], Y, Zs) :-
    (   X < Y
    ->  Zs = [X|Zs1]
    ;   Zs = Zs1
    ),
    lessthan_if(Xs, Y, Zs1).

However, if you are writing real code, you should almost certainly go with one of the predicates in library(apply), for example include/3, as suggested by @CapelliC:

?- include(>(3), [1,2,3], R).
R = [1, 2].

?- include(>(4), [1,2,3], R).
R = [1, 2, 3].

?- include(<(2), [1,2,3], R).
R = [3].

See the implementation of include/3 if you want to know how this kind of problems are solved. You will notice that lessthan/3 above is nothing but a specialization of the more general include/3 in library(apply): include/3 will reorder the arguments and use the ( if -> then ; else ).

"Declarative" solution

Alternatively, a less "procedural" and more "declarative" predicate:

lessthan_decl([], _, []).
lessthan_decl([X|Xs], Y, [X|Zs]) :- X < Y,
    lessthan_decl(Xs, Y, Zs).
lessthan_decl([X|Xs], Y, Zs) :- X >= Y,
    lessthan_decl(Xs, Y, Zs).

(lessthan_if/3 and lessthan_decl/3 are nearly identical to the solutions by Nicholas Carey, except for the order of arguments.)

On the downside, lessthan_decl/3 leaves behind choice points. However, it is a good starting point for a general, readable solution. We need two code transformations:

  1. Replace the arithmetic comparisons < and >= with CLP(FD) constraints: #< and #>=;
  2. Use a DCG rule to get rid of arguments in the definition.

You will arrive at the solution by lurker.

A different approach

The most general comparison predicate in Prolog is compare/3. A common pattern using it is to explicitly enumerate the three possible values for Order:

lessthan_compare([], _, []).
lessthan_compare([H|T], X, R) :-
    compare(Order, H, X),
    lessthan_compare_1(Order, H, T, X, R).

lessthan_compare_1(<, H, T, X, [H|R]) :-
    lessthan_compare(T, X, R).
lessthan_compare_1(=, _, T, X, R) :-
    lessthan_compare(T, X, R).
lessthan_compare_1(>, _, T, X, R) :-
    lessthan_compare(T, X, R).

(Compared to any of the other solutions, this one would work with any terms, not just integers or arithmetic expressions.)

Replacing compare/3 with zcompare/3:

:- use_module(library(clpfd)).

lessthan_clpfd([], _, []).
lessthan_clpfd([H|T], X, R) :-
    zcompare(ZOrder, H, X),
    lessthan_clpfd_1(ZOrder, H, T, X, R).

lessthan_clpfd_1(<, H, T, X, [H|R]) :-
    lessthan_clpfd(T, X, R).
lessthan_clpfd_1(=, _, T, X, R) :-
    lessthan_clpfd(T, X, R).
lessthan_clpfd_1(>, _, T, X, R) :-
    lessthan_clpfd(T, X, R).

This is definitely more code than any of the other solutions, but it does not leave behind unnecessary choice points:

?- lessthan_clpfd(3, [1,3,2], Xs).
Xs = [1, 2]. % no dangling choice points!

In the other cases, it behaves just as the DCG solution by lurker:

?- lessthan_clpfd(X, [1,3,2], Xs).
Xs = [1, 3, 2],
X in 4..sup ;
X = 3,
Xs = [1, 2] ;
X = 2,
Xs = [1] ;
X = 1,
Xs = [] .

?- lessthan_clpfd(X, [1,3,2], Xs), X = 3. %
X = 3,
Xs = [1, 2] ; % no error!
false.

?- lessthan_clpfd([1,3,2], X, R), R = [1, 2].
X = 3,
R = [1, 2] ;
false.

Unless you need such a general approach, include(>(X), List, Result) is good enough.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Find number of elements smaller than a given element in BST

From Dev

Write a function that returns a stack, that contains all elements smaller than a given number, and in same order?

From Dev

Efficient way of counting number of elements smaller (larger) than cutoff in a sorted list

From Dev

How to create a list containing numbers from 1 to given number in NetLogo?

From Dev

Generate a random number larger or smaller than the previous random number

From Dev

Highest power of two but smaller than given BigInteger

From Dev

Segment tree: amount of numbers smaller than x

From Dev

MySQL ORDER BY string as number (larger numbers above smaller numbers)

From Dev

First random number is always smaller than rest

From Dev

Max value from list that is smaller than X

From Dev

Number of integers in a list larger than a given integer possibly not in the list in log log time

From Dev

Python function that returns values from list smaller than a number

From Dev

Given a number N how many pairs of numbers have square sum less than or equal to N?

From Dev

does a computer take more time to multiply, divide, subtract, add two big numbers than smaller number

From Dev

Generating a numpy array with all combinations of numbers that sum to less than a given number

From Dev

Number of Fibonacci numbers smaller than number k. Sub O(n)

From Dev

find optimal sum of elements in list of numbers that are > a given number

From Dev

RecyclerView Children count smaller than the number of children

From Dev

Given a number n, list all n-digit numbers such that each number does not have repeating digits

From Dev

How to create a select list containing only numbers smaller than $x

From Dev

How to test for number smaller than other number

From Dev

Given a list of real numbers. What is a good algorithm to group them together so that the max and the min in the group is smaller than, say 5?

From Dev

Check if variable is a number smaller than a given number or equal to the text "QUIT"

From Dev

RecyclerView Children count smaller than the number of children

From Dev

Maximal subset sum smaller than a given value

From Dev

Enter the natural number n and print even smaller numbers n and odd numbers smaller than n

From Dev

Find the largest number that is lesser than a given number in a sorted list

From Dev

addition of numbers, in a list, that are smaller than a given number

From Dev

How to find the list of consecutive elements in a random list where the resultant list should not have greater number than the given number

Related Related

  1. 1

    Find number of elements smaller than a given element in BST

  2. 2

    Write a function that returns a stack, that contains all elements smaller than a given number, and in same order?

  3. 3

    Efficient way of counting number of elements smaller (larger) than cutoff in a sorted list

  4. 4

    How to create a list containing numbers from 1 to given number in NetLogo?

  5. 5

    Generate a random number larger or smaller than the previous random number

  6. 6

    Highest power of two but smaller than given BigInteger

  7. 7

    Segment tree: amount of numbers smaller than x

  8. 8

    MySQL ORDER BY string as number (larger numbers above smaller numbers)

  9. 9

    First random number is always smaller than rest

  10. 10

    Max value from list that is smaller than X

  11. 11

    Number of integers in a list larger than a given integer possibly not in the list in log log time

  12. 12

    Python function that returns values from list smaller than a number

  13. 13

    Given a number N how many pairs of numbers have square sum less than or equal to N?

  14. 14

    does a computer take more time to multiply, divide, subtract, add two big numbers than smaller number

  15. 15

    Generating a numpy array with all combinations of numbers that sum to less than a given number

  16. 16

    Number of Fibonacci numbers smaller than number k. Sub O(n)

  17. 17

    find optimal sum of elements in list of numbers that are > a given number

  18. 18

    RecyclerView Children count smaller than the number of children

  19. 19

    Given a number n, list all n-digit numbers such that each number does not have repeating digits

  20. 20

    How to create a select list containing only numbers smaller than $x

  21. 21

    How to test for number smaller than other number

  22. 22

    Given a list of real numbers. What is a good algorithm to group them together so that the max and the min in the group is smaller than, say 5?

  23. 23

    Check if variable is a number smaller than a given number or equal to the text "QUIT"

  24. 24

    RecyclerView Children count smaller than the number of children

  25. 25

    Maximal subset sum smaller than a given value

  26. 26

    Enter the natural number n and print even smaller numbers n and odd numbers smaller than n

  27. 27

    Find the largest number that is lesser than a given number in a sorted list

  28. 28

    addition of numbers, in a list, that are smaller than a given number

  29. 29

    How to find the list of consecutive elements in a random list where the resultant list should not have greater number than the given number

HotTag

Archive