M
M
Mercury132018-06-15 22:27:54
Algorithms
Mercury13, 2018-06-15 22:27:54

How to formulate an algorithm for visual query editing?

There is a homemade visual query editor. The query is a linear list of conditions and logical operations (three options: AND , OR and () AND () ). The first line has no operation. () AND () is an AND whose priority is even lower than OR.
Quite a real request, invented "in the field".

группа = 'A'
AND хитрый параметр < 70%
OR группа = 'B'
AND хитрый параметр < 40%
OR группа = 'C'
AND хитрый параметр < 20%
() AND () поставщик = 'первый'
OR поставщик = 'второй'

The equivalent condition would be:
((г='A' & хп < 70%) | (г='B' & хп < 40%) | (г='C' & хп < 20%)) & (п = 'первый' | п = 'второй')

Three tasks.
1. Here we have this request in the visual editor. Arrange indents automatically so that the logic is clear. Something like this.
    группа = 'A'
    AND хитрый параметр < 70%
  OR группа = 'B'
    AND хитрый параметр < 40%
  OR группа = 'C'
    AND хитрый параметр < 20%
() AND () поставщик = 'первый'
  OR поставщик = 'второй'

While the algorithm is pecking: the priority AND has an indent of 0, OR 1, AND 2, the first item without an operation is the same as the second. It remains only to reduce the indentation if there is no priority AND.
2. Turn this linear list into a query execution plan. Something like that.
1. группа = 'A': +2, −3   // при срабатывании GOTO 2, при неудаче — GOTO 3.
2. хитрый параметр < 70%: +7, −3
3. группа = 'B': +4, −5
4. хитрый параметр < 40%: +7, −5
5. группа = 'C': +6, −FALSE      // при срабатывании GOTO 6, при несрабатывании — неудача
6. хитрый параметр < 40%: +7, −FALSE
7. поставщик = 'первый': +TRUE, −8
8. поставщик = 'второй': +TRUE, −FALSE

3. And now, imagine, we have introduced this.
группа = 'A'
AND хитрый_параметр < 70%
OR группа = 'B'
AND хитрый параметр < 40%
OR группа = 'C'
AND хитрый параметр < 20%
() AND ()           (дырка)
AND поставщик = 'первый'
OR поставщик = 'второй'

We assume that the hole is the identical TRUE.
How to convert a query to an equivalent one, but without holes? Instead of AND, put the least priority of () AND () and AND?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
M
Mercury13, 2018-06-17
@Mercury13

With question 3 everything turned out to be simple and difficult at the same time. A hole is NOT identical to TRUE, it is something neutral to operations before or after (which is more important). If OR is an external operation, AND is priority, TRUE/FALSE is resp. neutral element, then ...
A OR (B AND TRUE) OR C = A OR B OR C, that is, AND leaves
(A AND B) OR (TRUE AND C) = (A AND B) OR C, that is, OR takes place AND.
So it really turns out the least precedence of () AND () and AND.
With question 1, so far it is.
With question 2, the problem turned out to be similar to the sorting yard algorithm. On the one hand, we don't have parentheses, prefix/postfix functions, or right associative operations.
On the other hand, for each element of the stack, we keep op, firstIndex and lastIndex (indexes of the beginning / end of the operand).
For the first element we throw (⌀, 1, 1). Or (⌀, 0, 0) if the indices are zero.
For the second (AND, 2, 2).
When the third one (OR, 3, 3) is encountered, the condition is triggered, and we do the "reset AND" operation, which consists of three things:
1. For the first lastIndex, if TRUE, we jump to the second firstIndex.
2. We write somewhere: the first lastIndex transition in case of FALSE will be the same as the second lastIndex.
3. Combine these two elements by assigning a second lastIndex to the first element.
Well, we add our (OR, 3, 3) to the stack - this is always done, regardless of how many times the reset condition has worked.
How to reset OR - I think it's understandable.
So now our stack will be: (⌀, 1, 2) (OR, 3, 3).
Our plan: (+2 −?) (+? −?) …
Our list of analogues: (1, 2, FALSE) The
fourth element will go on the stack, the fifth will cause two resets at once.
Stack (⌀, 1, 4) (OR, 5, 5).
Plan: (+2 −?) (+? −3) (+4 −?) (+? −?)…
Our list of analogues: (1, 2, FALSE), (3, 4, FALSE), (2, 4, TRUE)
When the list ends, perform a reset operation until there is (⌀, 1, 8) left on the stack, and then fill the list of analogues from the end.
If the question mark still remains, it will be +TRUE or -FALSE.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question