prolog - How to check which items on the list meet certain condition? -


how make function called buslinelonger, receives @ least 2 parameters decide if bus line longer or not?

*/this how works*/ * busstops(number_of_the_bus,number_of_stops)*/  /*?- buslinelonger([busstops(1,7),busstops(2,4),busstops(3,6)],5,which). * = [1,3]. 

using comparative things, @> <@ /==@. sorry english

edit... far i've think of this

buslinelonger([busstops(a,b)|r],n,[_|_]):-    n@>b,    buslinelonger(r,n,a). 

here's how using , reified test predicates, , lambda expressions.

:- use_module(library(lambda)). 

first, define reified test predicate (>)/3 this:

>(x,y,truth) :- (x > y -> truth=true ; truth=false). 

next, define three different implementations of buslinelonger/3 (named buslinelonger1/3, buslinelonger2/3, , buslinelonger3/3) in terms of following meta-predicates: maplist/3, tfilter/3, tfiltermap/4, , tchoose/3. of course, in end need one---but shouldn't keep exploring various options have!

#1: based on tfilter/3 , maplist/3

do 2 separate steps: 1. select items of concern. 2. project items data of interest.

buslinelonger1(ls0,n,ids) :-     tfilter(\busstops(_,l)^(l>n), ls0,ls1),     maplist(\busstops(id,_)^id^true, ls1, ids). 

#2: based on tfiltermap/4

here, use same lambda expressions before, pass them both meta-predicate tfiltermap/4. doing can reduce save resources.

buslinelonger2(ls,n,ids) :-     tfiltermap(\busstops(_,l)^(l>n), \busstops(id,_)^id^true, ls,ids). 

here's how tfiltermap/4 can implemented:

:- meta_predicate tfiltermap(2,2,?,?). tfiltermap(filter_2,map_2,xs,ys) :-    list_tfilter_map_list(xs,filter_2,map_2,ys).  :- meta_predicate list_tfilter_map_list(?,2,2,?). list_tfilter_map_list([],_,_,[]). list_tfilter_map_list([x|xs],filter_2,map_2,ys1) :-    if_(call(filter_2,x), (call(map_2,x,y),ys1=[y|ys0]), ys1=ys0),    list_tfilter_map_list(xs,filter_2,map_2,ys0). 

#3: based on tchoose/3

here not use 2 separate lambda expressions, combined one.

buslinelonger3(ls,n,ids) :-     tchoose(\busstops(id,l)^id^(l>n), ls,ids). 

here's how tchoose/3 can implemented:

:- meta_predicate tchoose(3,?,?). tchoose(p_3,xs,ys) :-    list_tchoose_list(xs,p_3,ys).  :- meta_predicate list_tchoose_list(?,3,?). list_tchoose_list([],_,[]). list_tchoose_list([x|xs],p_3,ys1) :-    if_(call(p_3,x,y), ys1=[y|ys0], ys1=ys0),    list_tchoose_list(xs,p_3,ys0). 

let's see them in action!

?- xs = [busstops(1,7),busstops(2,4),busstops(3,6)], buslinelonger1(xs,5,zs). xs = [busstops(1, 7), busstops(2, 4), busstops(3, 6)], zs = [1, 3].  ?- xs = [busstops(1,7),busstops(2,4),busstops(3,6)], buslinelonger2(xs,5,zs). xs = [busstops(1, 7), busstops(2, 4), busstops(3, 6)], zs = [1, 3].  ?- xs = [busstops(1,7),busstops(2,4),busstops(3,6)], buslinelonger3(xs,5,zs). xs = [busstops(1, 7), busstops(2, 4), busstops(3, 6)], zs = [1, 3]. 

done!

so... what's the bottom line?

  • many meta-predicates versatile , can used in lot of sitations similar 1 here.
  • implementing these meta-predicates 1 time effort amortized quickly.
  • many meta-predicates handle "recursive part", enables focus on actual work.
  • often, meta-predicates (as regular ones), "there's more 1 way things".
    • depending on concrete circumstances, using particular meta-predicate may better using one, , vice versa.
    • for question, think, implementation #3 (the 1 using tchoose/3) best.

Comments

Popular posts from this blog

PHP DOM loadHTML() method unusual warning -

python - How to create jsonb index using GIN on SQLAlchemy? -

c# - TransactionScope not rolling back although no complete() is called -