How to create an agent that selects the intersection of multiple conditions

Here is a query that doesn’t do what I expect because I don’t yet grasp the programming logic:

($StartDate >= Jan 1, 2022 & $StartDate <= Jan31, 2022) & $Hours > 0;

What I expected was that the “&” operator means that both conditions are true (i.e. the intersection of two areas). In the above example that would mean that the the agent would find only notes between Jan 1, 2022 and Jan 31, 2022, and only notes within that range where Hours > 0.

But that’s not happening. The query is finding all notes with Hours greater than 0, regardless of dates. It’s as if the “&” operator between the date range and Hours is being ignored.

In general, how can I set up a query to get only results that intersect multiple conditions?

A few general points:

  • queries don’t use semi-colon terminators (but it doesn’t affect things)
  • the dates strings should be in quotes and use of date() is advised
  • you probably meant “Jan 31, 2022” not “Jan31, 2022”
  • I’m assuming your user attribute $Hours is Number type (that’s what I used in my test)

If I use this, it works for me:

($StartDate >= date("Jan 1, 2022") & $StartDate <= date("Jan 31, 2022")) & $Hours > 0

See more on date()

Thank you Mark for the general points and the syntax reminders. Even though your syntax is written perfectly, it took me three tries until I fixed everything. When I finally got it right, the query works as expected. Syntax errors and I are pals, and your reply saved me much time.

@_Bill , no worries. It takes a while to get the hang of things. I didn’t mention parentheses last night, so as not to complicate this, but now you’ve fixed the basics I will address that aspect.

You are right in the general principle of parentheses. I’d generalise to say they are needed where an OR join, a | in action code syntax, is needed. By contrast they make no difference to an AND (&) join.

Why so? Because a query is read left to right, with each term (essentially a yes/no question) being evaluated and only those notes matching the test being passed into the next query term. Thus a succeeding AND-joined term can never increase the number of matches. At most it will be the same number as passed to it. This is because, for example with A & B & C at the end tests A, B and C will all be matched (as a true result).

As a result of this additive process writing A & B & C is functionally/logically the same as (A & B) & C because the result of A & B is the same as (A & B). Both A and B _must _ be true to match that part of the query. In fact, were you to write A & (B & C) the result would still be the same due to the nature of AND joins. But, it parentheses help your understanding of the problem you can use them without harm

Parentheses come into play with OR joins. A | B & C means A and B must both be fully evaluated before can be tested. Let me add another term to the example to make things more clear: A & B | C & D. More logically to the human eye this might be written as A & (B | C) & D. Indeed, if you feed the former to Tinderbox, my understanding (@eastgate may correct me here) is Tinderbox reads the query, breaks out the terms and joins and processes the query as if in the second form.

What this means is whereas with AND, the matched list of one term is feed straight to the next term, with OR joins all successive OR-joined terms must be tested against the same input list. Thus in our 4-term example above, both B and C test all the matches to A. As B and C may have different result, the two are merged and the larger list of unique items from both lists forms the input to term D.

Using parentheses helps us as the writers of the query code as much as it helps Tinderbox parse it.

Where I’m less clear is on more complex queries (of the like most of us never need) like (A | B) & ( C | ( D | E ) ). Here, A and B sample the whole document and the outcome it used as the scope for testing C , D and E although the extra parentheses mean the results combine in a different way.

Thank you Mark. From a logic perspective , I’ve always considered “and” and “or” operators, or logical conditions, to have equal priority. I wouldn’t have expected programming languages to deviate from that with respect to “and” and “or”, but apparently they do. I saw that python gives higher priority to “or” than to “and,” while C does the opposite. So it’s good to know that Tinderbox gives higher priority to “or” than to “and.”

As far as (A | B) & ( C | ( D | E ) ) goes, I’d interpret it visually as the picture shows, with parentheses having ultimate priority and the query finding the intersected area. (This assumes that computer language developers at least agree with parentheses having highest prioritization.) Given the rule that “or” (union) has priority over “and” (intersection), if the parentheses were taken away, looks to me like the result would be the same.

image

1 Like

Thanks, bill, this is helpful. Also, I believe the query goes from left to right. So, in your above example, it will first grab the notes that meet the conditions of A or B. then, it will look for only those conditions that also meet (i.e., and) the conditions of C or the conditions of D or E). In your above example, I’m not sure if putting parentheses around the (D|E) are doing anything. Did I interpret this right?

1 Like

I think so. In terms of left to right parsing, I think the main need for parentheses is where an OR join occurs to the left of an and. Even then , I believe Tinderbox parese out terms and essentially acts as if those parentheses were there. Frankly, if in doubt, test with without. Should the default not be right, it’s likely a thing to raise with eastgate.

Bottom line. Left to right parsing trumps whatever logic book one’s reading. :slight_smile: I don’t say that with any sense of smugness but rather as a quotidian take on how things actually work.

1 Like