We present three implementations, one using recursion, the others using a do loop with the fromto keyword.
/* version 1 */ :-mode filter(+,-). filter([],[]). filter([A|A1],[A|B1]):- q(A), !, filter(A1,B1). filter([_A|A1],B1):- filter(A1,B1). /* version 2 */ :-mode filter(+,-). filter(L,K):- (foreach(X,L), fromto([],In,Out,K) do q(X,In,Out) ). q(X,L,[X|L]):- q(X), !. q(_,L,L).
/* version 3 */ :-mode filter(+,-). filter(L,K):- (foreach(X,L), fromto(K,In,Out,[]) do q(X,In,Out) ). q(X,[X|L],L):- q(X), !. q(_,L,L).
The cuts (!) in the program clauses are very important, as they remove the possibility that a selected element is not included in the filtered list. If we remove the cuts, then the filter predicate has an exponential number of ``solutions''. Only the first solution will be correct, on backtracking we will decide to reject elements which satisfy the test criterion and we will explore all combinations until we reach the empty list as the last ``solution''.
:-mode selected_min_max(+,+). selected_min_max(Type,Interfaces):- Interfaces = interfaces with list:List, (foreach(Interface,List), fromto([],In,Out,Customers) do selected_customer(Interface,In,Out) ), sort(0,=<,Customers,Sorted), customers_by_node(Sorted,Grouped), selected_together(Type,Grouped,Interfaces). selected_customer(interface with [type:Type, index:I, node_index:Node], In, [customer with [node:Node, index:I, type:Type]|In]):- memberchk(Type,[customer,selected,remaining]), !. % all other types: backbone,backbone_net,interconnection,local selected_customer(_,In,In).