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
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.
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.