Re: Using foreach/2

Jan Wielemaker <[email protected]>
Newsgroups gmane.comp.ai.prolog.swi
Message-ID <[email protected]>
On 03/21/2014 03:44 AM, Boris Vassilev wrote:
> Hello,
>
> since I still don't exactly understand what the copying of the goal by
> `foreach/2` leads to, here is a "cleaner" way to do it:

Well, I think you know how to find the code?  What is does is termine
the variables shared by the generator and the goal.  Then it performs
a findall using the shared variables as template for the generator and
finally it proves that the conjunction of copies of Goal with each 
binding of the shared variables is true.  It can be quite neat, but
it is slow.

Doing as you do below is surely a lot faster.  I wonder however whether
there is a set of neat higher oder predicates that could be used for
processing compound terms?

	Cheers --- Jan

>
>      update_state(Current_state, Next_state) :-
>          functor(Current_state, state, Arity),
>          functor(Next_state, state, Arity),
>          update_args(1, Arity, Current_state, Next_state).
>
>      update_args(N, Arity, Current_state, Next_state) :-
>          (   N =< Arity
>          -> next_arg_state(Current_state, N, A),
>              arg(N, Next_state, A),
>              succ(N, N1),
>              update_args(N1, Arity, Current_state, Next_state)
>          ;   true
>          ).
>
> Boris
>
>
>
> On Wed, Mar 19, 2014 at 4:18 PM, Boris Vassilev <[email protected]>wrote:
>
>> Hello,
>>
>> I am having trouble understanding the implications of using `foreach/2`
>> from `library(aggregate)`.
>>
>> Given a "state", represented as a term of arbitrary length, I want to find
>> a new state, a term with the same functor, based on some rules. The rules
>> themselves use (arbitrary) elements from the current state.
>>
>> While I don't know the arity of my state functor, it will not change
>> during a program run.
>>
>> The reason why I chose to use a term for representing the state is that I
>> don't want to worry about efficiently finding the arguments that a rule
>> might need: I use `arg/3` instead (I am under the impression that it has
>> efficient and constant time access to term arguments, when its first
>> argument is ground).
>>
>> Now the question: if I would define `update_state/2` like this:
>>
>>      update_state(Current_state, Next_state) :-
>>          functor(Current_state, state, Arity),
>>          functor(Next_state, state, Arity),
>>          foreach(
>>              (   between(1, Arity, N),
>>                  next_arg_state(Current_state, N, A) % defined elsewhere....
>>              ),
>>              arg(N, Next_state, A)
>>          ).
>>
>> Would that be a silly thing to do? How should I do this instead?
>> (I know it does the job, but I admit that I don't fully understand the
>> implications of `foreach/2` repeatedly copying its second argument `Goal`.
>> The obvious other method is to use `=..` and `maplist`.)
>>
>> Thank you for the help,
>> Boris
>>
>>
>>
> -------------- next part --------------
> HTML attachment scrubbed and removed
> _______________________________________________
> SWI-Prolog mailing list
> [email protected]
> https://lists.iai.uni-bonn.de/mailman/listinfo.cgi/swi-prolog
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.