Ovid has asked for the wisdom of the Perl Monks concerning the following question:
I'm trying to create a replacement for AI::Prolog (one that uses Perl data structures and doesn't require knowledge of Prolog) and I've hit a stumbling block and my solution seems really nasty.
Imagine an arbitrarily complex data structure:
[ $var1, undef, [ undef, undef, { 'foo' => $var2 } ], { 'bar' => $var3 } ];
Let's say I have an arbitrary number of other data structures with identical structures, but different values. For every variable in the structure above (it's an instance of something called a "logic" variable), how can I efficiently assign it the corresponding value in the each of the other structures? As a simple example, let's say that structure looks like this:
my $unknown = [ undef, undef, $var ];
If I have three other structures like this:
my @structures = ( [ qw/ 1 2 3 / ], [ qw/ this that other / ], [ qw/ un deux trois / ], );
Then I'd like something like this:
foreach my $structure (@structures) { bind($unknown, $structure); print $var->value; }
That would print "3", "other", and "trois", in sequence.
As mentioned, the data structures might be arbitrarily complex and currently the only data types allowed are scalars, array refs, hashrefs, and regexes and due to how the system is built, the structure are guaranteed to be identical in shape, including size of arrays and hashes.
I am assuming that I need an easy way to spider the $unknown structure and cache the positions of all of those logic variables. The only way I've thought of it so far is to build up a string representation of the data structure and use nasty string eval tricks to get at them (sort of like XPath for Perl data structures). For example, the following will assign "3" to the logic variable:
my $struct = [ 'whaa!', undef, [undef, undef, { foo => 3}], { bar => 'baz'}, ]; my $path = "[2][2]{foo}"; $var->bind( eval "\$struct->$path" );
This seems really nasty and any advice would be welcome.
Note that things like Data::Diver and Class::XPath seem great, but they don't solve the general algorithm problem of:
foreach my $path (find_logic_var($unknown_struct)) { push @paths => $path; }
In other words, the paths are unknown up front and that's the major problem I want to solve efficiently. Maybe I should recursively walk the data structure while pushing path elements on a localized stack?
Cheers,
Ovid
New address of my CGI Course.
|
---|
Replies are listed 'Best First'. | |
---|---|
Re: Efficient partial deep cloning
by jbert (Priest) on Jan 08, 2008 at 12:06 UTC | |
by Ovid (Cardinal) on Jan 08, 2008 at 12:09 UTC | |
by exussum0 (Vicar) on Jan 08, 2008 at 15:32 UTC | |
by Ovid (Cardinal) on Jan 09, 2008 at 10:29 UTC | |
Re: Efficient partial deep cloning
by Ovid (Cardinal) on Jan 08, 2008 at 12:04 UTC | |
Re: Efficient partial deep cloning
by runrig (Abbot) on Jan 09, 2008 at 01:10 UTC | |
Re: Efficient partial deep cloning
by sfink (Deacon) on Jan 09, 2008 at 07:14 UTC | |
by Ovid (Cardinal) on Jan 09, 2008 at 10:22 UTC | |
Re: Efficient partial deep cloning
by toma (Vicar) on Jan 11, 2008 at 05:13 UTC |