[EMAIL PROTECTED] wrote:
Consider the following

invocable all
procedure f( ) ; suspend 1 to 24 by 1 ; end
procedure g( ) ; suspend 2 to 24 by 2 ; end
procedure h( ) ; suspend 3 to 24 by 3 ; end
procedure i( ) ; suspend 4 to 24 by 4 ; end
procedure main( )
  local L4, L3, L
  L4 := [ f, g, h, i ]
  every f( ) && g( ) && h( ) && i( )
  L3 := [ f, g, h ]
  every f( ) && g( ) && h( )
  every L := L3 | L4 do {
    # conjunction expression using L required here
  }
end

Given a list of generators of unknown length, is there a compact expression that generates the conjuncation of the evaluations of all of the generators in the list? In other words, can an expression be written in terms of L
such that it produces the results produced by
  every f( ) && g( ) && h( ) && i( )
when L = L4 and produces the results produced by every f( ) && g( ) && h( ) when L = L3 ?

Hi Art,

I'm a little confused, there is no && operator in Icon, do you mean
just &?   Also, note that in the examples you give, as in:

   L4 := [f,g,h,i]

L4 is not a list of of generators, but just a list of functions.
(They only become generators when you invoke them, so any operation
on them is going to have to know they are functions in order to
invoke them.)  This means there isn't a general solution that
can handle a 'list of generators' and also a 'list of functions'.

If you're happy with a general solution when using a 'list of functions,
each of which is a generator', here's one.  (It's also recursive - I
haven't figured out a way around *that*):

=============================================
    procedure main()
        every write(e() & f() & g())
        write()
        every write(eval([e, f, g]))
    end

    procedure eval(L)
        a := L[1] | fail
        if *L = 1 then suspend a()
        else every a() do suspend eval(L[2:0])
    end

    procedure e(); suspend !"xyz"; end
    procedure f(); suspend 1 to 3; end
    procedure g(); suspend !"abc"; end
==============================================

If you want a general solution when using a 'list of generators',
then the following works.

==============================================
procedure main()
    every write(e() & f() & g())
    write()
    every write(evalExp{!"xyz", 1 to 3, !"abc"})
    # or just:  every write(evalExp{e(), f(), g()})
end

procedure evalExp(L)
    a := ^L[1] | fail
    if *L = 1 then suspend (|@a)
    else every (|@a) do suspend evalExp(L[2:0])
end

procedure e(); suspend !"xyz"; end
procedure f(); suspend 1 to 3; end
procedure g(); suspend !"abc"; end
==============================================

Note that the only co-expressions come from the initial
call of evalExp{}.

Of course, that builds the list as part of the invocation
to evalExp{}.  If you want to prebuild the list, you also have
to prebuild the co-expressions, as in:

   L3 := [create e(), create f(), create g()]
   every write(evalExp(L3))

Finally, while more 'concise' than yours, there's a lot of
list building going on internally in both of the above.  I
don't know that they'd be faster than yours!

[As a final note, I think the last expression in your "if_all"
function could be shortened to:

   suspend selector( ( *L > 0 & if_all( L, n ) ) | 1, L0( ) )

Getting rid of both the every and the 'result' variable.  I
haven't tested this, however.]

Hope that's useful!
--
Steve Wampler     [EMAIL PROTECTED]
The gods that smiled upon your birth are laughing now. -- fortune cookie


-------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc. Do you grep through log files
for problems?  Stop!  Download the new AJAX search engine that makes
searching your log files as easy as surfing the  web.  DOWNLOAD SPLUNK!
http://ads.osdn.com/?ad_id=7637&alloc_id=16865&op=click
_______________________________________________
Unicon-group mailing list
Unicon-group@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/unicon-group

Reply via email to