Jump to content
Claris Engage 2025 - March 25-26 Austin Texas ×

This topic is 3993 days old. Please don't post here. Open a new topic instead.

Recommended Posts

Posted

I have an if() that contains a list of conditions separated by logical AND.

 

Can I revise that list of if() conditions on the fly? When another part of my program detects something I'd like to add another condition to my if() so that it's there when the program loops back through.  I just can't think of a way to do that.

Posted

I believe the only way would be to have your script branch off upon detection of this other condition. I don't have enough info, but perhaps this new condition could be stored in a variable and passed to your script. As far as the text of a script changing on the fly, this isn't possible.

Posted

As Rick said, you cannot change the script "code" dynamically; but depending on your purpose, there may be other ways. A concrete example would be helpful.

Posted

I think the answer might be on page 9-23 of FTS 12 - multi-line keys. A portal will match a record that contains a line delimited list in the match field.

 

My loop has 2 functions in it, a filter and a find. When find sees something it wants filter to know about, it can write it in a multi-line key field, a single global field in a related table. That field will contain a constantly changing list of things to filter while the loop is running. Then when the filter runs it tests that global field for the if() condition and should return true if anything in the list matches.

 

There's no way to revise the contents of the if() on the fly, can't even do it with the script paused, but we can revise the contents of fields on the fly. It turns out that the portal has the proper function needed for this, the ability to match any item in a line delimited list. The end result is a dynamic filter using if().

 

I'll code it tomorrow and let you know. I'll aslo see whether if() can match a line delimited variable without using a portal and related table. It's a pretty cool problem, something that most folks would never have a need for.

 

I'm constructing a ternary tree database. The algorithm that creates the records spawns duplicates. Each duplicate then spawns 3 duplicate children, and so forth. One of the problems I am running requires a tree with 3,628,798 nodes. But there's only 40,320 unique nodes, all the rest are duplicates. This means it is essential to if() those suckers outta there before they enter the main processing part of the loop and start spawning vast numbers of duplicate children. My first 2 filter conditions cut the nodes in half. But the higher order duplicates are far beyond my math ability to predict. So I catch a duplicate with find and then terminate it's family tree in filter. Each new level of the tree spawns all new duplicates.

 

The next problem I'll run has 479 million nodes and 3.6 million uniques meaning there are going to be about 476 million duplicates to weed out. And believe me, I am not going to do 479 million scripted finds on 479 million records. No way. I'd rather filter 'em out before they start breeding.

 

This sort of filtering can be effective.  A smaller problem had a 3.6 million node tree. I found the 70 unique members after processing only 18,000 nodes. It was partially filtered which killed off 5,280 parent nodes before they could spawn duplicate children. It will get faster with full dynamic filtering.

Posted

 

 

There's no way to revise the contents of the if() on the fly, can't even do it with the script paused,

 

 

You can make the IF dynamic by building the calc on the fly and say store it in a variable $myIFcalc.  The IF itself in the script would just be:

 

IF[ Evaluate( $myIFcalc ) ]

  • Like 2
Posted

Thanks, Wim. You get my upvote. I now have a dynamic if() using evaluate().

 

I started with an if() with 2 boolean tests

 

if[

$$parentLastMove  ≠  "AL"
 and 
$$recentAncestors_AR ≠ $$ancestorLimit_AR]
 
I replaced the if() to read
 
if[evaluate($$filter_AR)
 
where $$filter_AR contains the same thing the original if() had
 
$$parentLastMove  ≠  "AL" and 
$$recentAncestors_AR ≠ $$ancestorLimit_AR
 
I made a copy of the enumerator and ran both versions on a short problem. They both reported the exact same results. Had evaluate() not been correctly evaluating both of the boolean tests, I would have seen more nodes and more duplicates in the results. Deleting the second condition and testing proves this.
 
So I now add the dynamic part and run a larger problem that had already been run. The results were again identical except now $$filter_AR contained
 
$$parentLastMove  ≠  "AL" and 
$$recentAncestors_AR ≠ $$ancestorLimit_AR and
$$Ancestors_5 ≠ "BR AR BL AL BR" and
$$Ancestors_6 ≠ "AL BL AR BR AL BL" and
$$Ancestors_6 ≠ "BR AR AR BR BR AR" and
$$Ancestors_6 ≠ "BL AL AL BL BL AR" and
$$Ancestors_6 ≠ "BL BL AR AR BR BR" and
$$Ancestors_6 ≠ "BL BL AR BR AL BL"
 
All of the extra terms were added dynamically on the fly and functioned properly.
 
I logged the processing time and evaluate() has very little overhead. It eliminates countless millions of scripted finds for me which have very large overhead. The net gain is quite significant and the cost to implement it only took a few minutes. This technique avoids disk I/O and takes up very little memory.
Posted

I could not get it to work in a production environment.

 

You cannot use that if() wth a variable that contains evaluate() anywhere else except right where you're going to use it. It gives very wrong results otherwise. You cannot even wrap that variable in an if() without it breaking. Also, you cannot use the variable in another script and cannot write to it from another script. It only works in very limited circumstances. One might guess that evaluate() is working in the context of where it was created, not in the context of where you want to instantiate it. The thing simply won't work where I need it to. I can get it to work properly but then I can't write to it. Or I can write to it but it won't work. Just no way to do both.

 

I don't know if case() will behave any differently. Probably have the same trouble with any function loaded into a variable.

 

Any other ways of doing a branching logic test?

Posted

I have an update on this. While Wim's evaluate() method would work beautifully in some circumstances, and I recommend it be the first thing you try, it would not work in my special case. I now have workaround.

 

Instead of writing an expanding list of conditions into a variable for the if() to test using evaluate(), I wrote them to a table and linked it through a multivariate relationship. When my filter function runs it now loops through those portal records and tests them 1x1, exiting the loop on the first test that fails.

 

This certainly works better than scripted finds and yielded a nice improvement in speed for this elaborate calculation. It is still not optimal because of all the disk I/O. What I need to think about now is a way to build that list in a variable that I can loop through and eliminate the disk I/O.

This topic is 3993 days old. Please don't post here. Open a new topic instead.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.