For Programmers: Free Programming Magazines  


Home > Archive > Prolog > January 2006 > Generic term search in a list









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Generic term search in a list
Steffen Schwigon

2006-01-10, 7:57 am

Hi!

My sub-average prolog skills need a lesson. I use swi-prolog.

I have an application in which I want to give kind of
option arguments into my predicates, e.g this way:

get_d(Options, depends_on(B,C), D) :-
options:get_range(Options, range(Min,Max)),
calendar:fruehestens_danach(Options, C,D),
calendar:fruehestens_x_tage_danach(Optio
ns, B,10,D),
calendar:ist_guter_tag(D),
between(Min,Max,D).

When "get_d" is called, "Options" is a term containing a list of
option terms, e.g.:

options([range(100,300), foo(12), bar(1,2,3)])

I specify the "Options" at toplevel and hand it over to each predicate
that might also use them. Each predicate then extracts the options it
needs; some might need "range(Min,Max)", another one needs "foo(X)" or
"bar(X,Y,Z)". If an option is not contained, default values are
returned.

What I want is a clever way to extract a specific option.

My current option handling looks too explicit and non-gerneric. I have
a recursive search for each option, because of different arities of
the option terms and the different default values for each option.

%% Option: range(Min,Max) - default: range(0, inf).
get_range(options([]), Range) :- Range = range(0,inf), !.
get_range(options([range(Min, Max)|_]), range(Min, Max)).
get_range(options([Head|Tail]), Range) :-
Head \= range(_,_),
get_range(options(Tail), Range).

%% Option: foo(F) - default: foo(1).
get_foo(options([]), Foo) :- Foo = foo(1), !.
get_foo(options([foo(Min)|_]), foo(Min)).
get_foo(options([Head|Tail]), Foo) :-
Head \= foo(_),
get_foo(options(Tail), Foo).


It would be better to have a generic recursive search for a matching
term name and a way to specify which term to search and which default
value it should have. Something that could easily be extend for more
options.

E.g., a general option searcher:

get_option(Options, Termname, Default, Result) :- ... ???.

and specifications of different options, arities and default values:

get_range(Options, R) :- get_option(Options, 'range', range(0, inf), R).
get_foo(Options, F) :- get_option(Options, 'foo', foo(1), F).

The option terms are unambiguous in name and arity, e.g. there is only
one "range" option with its specific arity, and not another one with
different arity.

==> I don't really know how to do it. Different experiments
stumbled. I had most problems in mapping strings to terms,
respectively understanding the right usage of things like
atom_to_term/3. I don't even know whether that's the right
direction.

Could someone please give me some help?

Thanks in advance.

Steffen
--
Steffen Schwigon <schwigon@webit.de>
Dresden Perl Mongers <http://dresden-pm.org/>
Jan Wielemaker

2006-01-10, 7:57 am

On 2006-01-10, Steffen Schwigon <schwigon@webit.de> wrote:
> Hi!
>
> My sub-average prolog skills need a lesson. I use swi-prolog.
>
> I have an application in which I want to give kind of
> option arguments into my predicates, e.g this way:
>
> get_d(Options, depends_on(B,C), D) :-
> options:get_range(Options, range(Min,Max)),
> calendar:fruehestens_danach(Options, C,D),
> calendar:fruehestens_x_tage_danach(Optio
ns, B,10,D),
> calendar:ist_guter_tag(D),
> between(Min,Max,D).
>
> When "get_d" is called, "Options" is a term containing a list of
> option terms, e.g.:
>
> options([range(100,300), foo(12), bar(1,2,3)])
>
> I specify the "Options" at toplevel and hand it over to each predicate
> that might also use them. Each predicate then extracts the options it
> needs; some might need "range(Min,Max)", another one needs "foo(X)" or
> "bar(X,Y,Z)". If an option is not contained, default values are
> returned.
>
> What I want is a clever way to extract a specific option.
>
> My current option handling looks too explicit and non-gerneric. I have
> a recursive search for each option, because of different arities of
> the option terms and the different default values for each option.
>
> %% Option: range(Min,Max) - default: range(0, inf).
> get_range(options([]), Range) :- Range = range(0,inf), !.
> get_range(options([range(Min, Max)|_]), range(Min, Max)).
> get_range(options([Head|Tail]), Range) :-
> Head \= range(_,_),
> get_range(options(Tail), Range).


What about

get_range(options(Options), Range) :-
Range = range(_, ),
( memberchk(Range, Options)
-> true
; Range = range(0,inf)
).

I see little purpose in the options/1 representation and would use
a plain list. The code above also gives a good idea how to make
it generic.

>==> I don't really know how to do it. Different experiments
> stumbled. I had most problems in mapping strings to terms,
> respectively understanding the right usage of things like
> atom_to_term/3. I don't even know whether that's the right
> direction.


Unless you have to deal exchange Prolog terms with systems that
are unaware of them, atom_to_term/3 is rarely a good idea.

Hope this helps

--- Jan
Steffen Schwigon

2006-01-10, 7:57 am

Jan Wielemaker <jan@nospam.ct.xs4all.nl> writes:
> What about
>
> get_range(options(Options), Range) :-
> Range = range(_, ),
> ( memberchk(Range, Options)
> -> true
> ; Range = range(0,inf)
> ).


Aha, memberchk. Looks good. Thanks.


> I see little purpose in the options/1 representation and would use a
> plain list.


I do such things often for readability. Less for the definition
of the predicates but mostly when they are called. I prefer

get_d(options([range(1,2), foo(12), bar(65)]), depends(B,C), D)

over

get_d([range(1,2), foo(12), bar(65)], depends(B,C), D)


I'm still learning typical patterns and are experimenting to find my
personal style. Would you consider the above as unusual style in
Prolog?

Thanks.

Steffen
--
Steffen Schwigon <schwigon@webit.de>
Dresden Perl Mongers <http://dresden-pm.org/>
Jan Wielemaker

2006-01-10, 9:58 pm

On 2006-01-10, Steffen Schwigon <schwigon@webit.de> wrote:
> Jan Wielemaker <jan@nospam.ct.xs4all.nl> writes:
>
> Aha, memberchk. Looks good. Thanks.
>
>
>
> I do such things often for readability. Less for the definition
> of the predicates but mostly when they are called. I prefer
>
> get_d(options([range(1,2), foo(12), bar(65)]), depends(B,C), D)
>
> over
>
> get_d([range(1,2), foo(12), bar(65)], depends(B,C), D)
>
>
> I'm still learning typical patterns and are experimenting to find my
> personal style. Would you consider the above as unusual style in
> Prolog?


If you look at most of the ISO predicates that use option lists, they
carry them as last argument without option() around them. Carrying
them as last argument makes sense, as you normally want the first
argument for things you switch on to exploit clause-indexing. You do
not switch on the option list in a way that is exploitable by
clause-indexing. By carrying option lists always at the end there is
not that much need for an extra option(). I'm not saying it is bad
style to use option(). There is some point in trying to addopt to
current practice and only develop your own style for things you `can't
live with' though. There is a good document on style issues by
Michael A. Covington at http://www.ai.uga.edu/mc/plcoding.pdf. I also
keep recommending reading Richard O'Keefe's "The Craft of Prolog" for
anyone who plans to take Prolog programming seriously (considering
your questions you appear to be in this group).

Enjoy --- Jan
Steffen Schwigon

2006-01-10, 9:58 pm

Jan Wielemaker <jan@nospam.ct.xs4all.nl> writes:
> There is a good document on style issues by Michael A. Covington at
> http://www.ai.uga.edu/mc/plcoding.pdf.


This guide is great. It will become my new bible. Thanks.

Steffen
--
Steffen Schwigon <schwigon@webit.de>
Dresden Perl Mongers <http://dresden-pm.org/>
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com