Home > Archive > Prolog > September 2007 > Get a limited amount of solutions from a prolog Goal?
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 |
Get a limited amount of solutions from a prolog Goal?
|
|
| sberna@gmail.com 2007-09-25, 7:14 pm |
| Hello,
First I would like to say that I'm a complete newbie in prolog so
maybe there is a better way to do what I'm trying to accomplish and a
bit of enlightment would be very welcomed.
Lets imagine that I have a possibly infinite predicate that represents
the integer numbers set.
positive_integer(X)
In this way positive_integer(X) would render 1,2,3,4,5,6.. each time a
new solution to the goal is demanded, but a findall would hang the
interpreter.
Is there any simple way to either have a new predicate built upon the
previous one that fails when a certain number of solutions have been
found as could be:
is_limited(Count),integer(X)
Which would only allow to REDO Count times before failing.
Or either build a findlimited(Term,Goal,N,LIST), which would only
return the first N Terms that satisfy the goal?
Up to now the only ways I have thought of, are either using a
combination of bag_create, bag_dissolve which I dont like, or using
assert and retract which I like even less.
Any ideas?
Thanks for your time
| |
| Chip Eastham 2007-09-26, 7:08 pm |
| On Sep 25, 7:35 pm, sbe...@gmail.com wrote:
> Hello,
>
> First I would like to say that I'm a complete newbie in prolog so
> maybe there is a better way to do what I'm trying to accomplish and a
> bit of enlightment would be very welcomed.
>
> Lets imagine that I have a possibly infinite predicate that represents
> the integer numbers set.
>
> positive_integer(X)
>
> In this way positive_integer(X) would render 1,2,3,4,5,6.. each time a
> new solution to the goal is demanded, but a findall would hang the
> interpreter.
>
> Is there any simple way to either have a new predicate built upon the
> previous one that fails when a certain number of solutions have been
> found as could be:
>
> is_limited(Count),integer(X)
>
> Which would only allow to REDO Count times before failing.
>
> Or either build a findlimited(Term,Goal,N,LIST), which would only
> return the first N Terms that satisfy the goal?
>
> Up to now the only ways I have thought of, are either using a
> combination of bag_create, bag_dissolve which I dont like, or using
> assert and retract which I like even less.
>
> Any ideas?
>
> Thanks for your time
While it is possible to wrap the "generator"
predicate positive_integer(X) of your specific
illustration in an "outer" predicate,
is_limited(Limit,X):
is_limited(Limit,X) :- positive_integer(X),
( (X > Limit, !, fail) ; X <= Limit ).
so that the wrapper fails once X exceeds
Count, I don't think the general effect you
are looking for can be obtained without
side-effects, eg. assert/retract or
some other type of persistent accumulator.
regards, chip
| |
| sberna@gmail.com 2007-09-26, 7:08 pm |
| On 26 sep, 13:16, Chip Eastham <hardm...@gmail.com> wrote:
> On Sep 25, 7:35 pm, sbe...@gmail.com wrote:
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
> While it is possible to wrap the "generator"
> predicate positive_integer(X) of your specific
> illustration in an "outer" predicate,
> is_limited(Limit,X):
>
> is_limited(Limit,X) :- positive_integer(X),
> ( (X > Limit, !, fail) ; X <= Limit ).
>
> so that the wrapper fails once X exceeds
> Count, I don't think the general effect you
> are looking for can be obtained without
> side-effects, eg. assert/retract or
> some other type of persistent accumulator.
>
> regards, chip
Thanks for the tips chip. Your solution would be perfect if not
because I can't know beforehand without exploring which is the
explicit limit for the interval im exploring. Maybe a better expample
wold have been the following:
is_limited(Count),integer(X), check_condition(X).
Here only integers that satisfay a certain condition would be
returned. The problem is that the constraint i need to impose is not
over the explored domain, but over the number of Terms allowed to
satisfy the predicate.
Thanks, Sergio.
| |
| Joachim Schimpf 2007-09-26, 7:08 pm |
| sberna@gmail.com wrote:
> Hello,
>
> First I would like to say that I'm a complete newbie in prolog so
> maybe there is a better way to do what I'm trying to accomplish and a
> bit of enlightment would be very welcomed.
>
> Lets imagine that I have a possibly infinite predicate that represents
> the integer numbers set.
>
> positive_integer(X)
>
> In this way positive_integer(X) would render 1,2,3,4,5,6.. each time a
> new solution to the goal is demanded, but a findall would hang the
> interpreter.
>
> Is there any simple way to either have a new predicate built upon the
> previous one that fails when a certain number of solutions have been
> found as could be:
>
> is_limited(Count),integer(X)
>
> Which would only allow to REDO Count times before failing.
>
> Or either build a findlimited(Term,Goal,N,LIST), which would only
> return the first N Terms that satisfy the goal?
>
> Up to now the only ways I have thought of, are either using a
> combination of bag_create, bag_dissolve which I dont like, or using
> assert and retract which I like even less.
As Chip, said, you need some persistent counter. Since you seem to be
using ECLiPSe, the simplest is to use a "shelf":
shelf_create(count(Limit), Count),
<your goal>,
( shelf_dec(Count, 1) -> true ; !, fail ).
-- Joachim
| |
| sberna@gmail.com 2007-09-26, 7:08 pm |
| On 26 sep, 13:54, Joachim Schimpf <jschi...@cisco.com> wrote:
> sbe...@gmail.com wrote:
>
>
>
>
>
>
>
>
>
>
> As Chip, said, you need some persistent counter. Since you seem to be
> using ECLiPSe, the simplest is to use a "shelf":
>
> shelf_create(count(Limit), Count),
> <your goal>,
> ( shelf_dec(Count, 1) -> true ; !, fail ).
>
> -- Joachim
Joachim,
My infinite gratitude to chip and you for both tips, it works like a
charm right now using the shelf_create solution.
Regards.
Sergio.
|
|
|
|
|