-
Notifications
You must be signed in to change notification settings - Fork 30
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RECURSION statement clarification #475
Comments
I have to add that expression after STEP doesn't look intuitive to me at all. Instead |
We have documentation in English. The process of thanslation is not finished yet, but you might find it useful. |
Thank's @danchanka. I have managed on my own. If someone needs it, I have collected these materials till now: |
First of all, You can use https://en-documentation.lsfusion.org to get english version for now. Now only article captions and comments in examples are not translated, but it will be done soon (and then documentation.lsfusion.org will be in english by default). Regarding your main question, the thing is that, basically RECURSION is more like breadth-first search than depth-first search. So $X is the reference to a parameter rather than the reference to a function value (previous function value is used implicitly - multiplied with the step value and added to the final result). That's why it is not that evident, when RECURSION operator is used for working with recursive functions (and even trees) and might be a quite confusing. To understand how this operator works it's better to read how recursive CTEs work in SQL, and this operator works the same way (and sometimes uses them) except that it uses functions instead of tables (actually that's one of the main features of lsFusion, in a way, it's a sort of "functional SQL"). In case of fibonacci numbers, it works like, we start with values (actually all the same keys are grouped on each iteration and sumed up, that's by the way why SQL RECURSIVE CTEs usually cannot be used - they don't support grouping, so generated table functions + temporary tables are used instead) final result ..... So it's not easy to understand / to prove that the result of such calculation is "fibonacci numbers", but it is. RECURSION operator is implemented / defined this way not only because this implementation / definition is compliant with SQL (and thus has a lot more efficient calculation), but because this implementation / definition has a very efficient incremental update mechanism (not worse than GROUP SUM). But nevertheless RECURSION is one of the most complicated operators in lsFusion, and usually is used for pretty basic cases described in samples (i.e. calculating tree depth / reachability, number of pathes in graph and so on). |
Ok. There is bug with fibonacci in my earlier writing. fibR(i) = RECURSION 1l IF (i == 1) STEP 1l IF (i = $i + 1 OR i = $i + 2) AND i > 0 AND i < 30 CYCLES IMPOSSIBLE; fib(i) = IF i == 0 THEN 0 ELSE fibR(i); action to show fib(0) - fib(10): showMessage() { LOCAL i = INTEGER(); i() <- 0; WHILE i() < 11 DO { MESSAGE 'fib(' + i() + ')=' + (fib(i())); i() <- i() + 1; } } This is something I would like to see in the documentation :). Something what I can easily run. |
CTEs - recursive common table expressions https://www.postgresqltutorial.com/postgresql-recursive-query/ |
Excerpt from lsfusion documentation: Currently, only two types of aggregate functions are supported for the recursion operator - SUM and OR . The latter is used when the initial value and step are of the class BOOLEAN. SUM is used in all other cases.
I would be useful to explain CYCLES option with three characteristic examples. |
Regarding the example, there is an another way to fix first values in fibonacci function. Plus there is a more appropriate way to output results. You can put this code in https://lsfusion.org/try (RDBMS mode) to see results:
Or you can try this in any demo, in Administration -> Interpreter. Button Run script.
|
Alex, thank you for the tips! Running examples like this this is really extremely useful and powerful :). This works like it should: fibR(i, to) = RECURSION 1 IF (i == 1) AND to IS INTEGER STEP 1 IF (i = $i + 1 OR i = $i + 2) AND i > 0 AND i <= to CYCLES IMPOSSIBLE; fib(i, to) = IF (i == 0) THEN 0 ELSE fibR(i, to); funCall(i) = 'fib(' + i + ')'; FORM showFib OBJECTS to = INTEGER PANEL, i=INTEGER PROPERTIES i 'call' = funCall(i) AS STRING[10], fib 'Result' = fib(i, to) FILTERS iterate(i, 0, to) ; run() { SHOW showFib OBJECTS to=20; } |
I am struggling with lsfusion documentation (I have using auto translation from russian to english, as I don't understand russian).
First, fibonacci given example don't work. When I put this in my playground project:
platform generates exceptions because of integer limits. I have fixed it putting limit on
i < 60
, and using LONG (bigint):Again, fibanocci function is not calculated like we want. We had to add
i>1
to makefib(1)=1
. Without that condition the result isfib(1)=2
.Anyway, the most problematic part for me was understanding how this works at all!?
At the end, This is my understanding:
In next evaluation step the result is previous value
i = $i + 1
plusOR
second previous valuei = $i + 2
.The result is multiplied by 1.
So, If we put this:
we are going to get result as fib3(i) = 3 * ( fib3(i-1) + fib3(i-2) + fib3(i-3)):
I am aware that this example has no practical usage. It is written this for the sake of understanding how the RECURSION statement makes the calculation.
The text was updated successfully, but these errors were encountered: