LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Calling Recursive Vi's

Solved!
Go to solution

Wow, that was fun!  I wrote the whole thing with a single Function (I called it Recurse) that was, in fact, Recursive.  It was, in fact, a perfect example of "Tail Recursion", which (as I recall) can also be easily turned into an example of Iteration (a While Loop), thereby eliminating the Recursion altogether!  I think this is an instructive-enough example/challenge that I don't want to "give away my solution" right off the bat, as it would be a good exercise to learn a bit about Recursion, String Functions, etc., but I'll post my solution within 24 hours.

 

Here are some "insights":

  • Consider a function with a String Argument.  Split the String into two pieces, "Head" (the first letter) and "Tail" (everything else).  The Problem called for three functions (A, B, and C), depending on the Head, but I used an "Alternative Structure" (found on the Structure Palette) to put all three "functions" into my single Recurse function.
  • Of course, while writing this, the non-recursive (a.k.a. "iterative" version of this routine popped into my head, so I'll present two solutions, both with a single function, one Recursive (Recurse) and one Iterative (Repeat) (which I still have to write, darn it, but it's almost trivial now ...).

Bob Schor

Message 11 of 27
(2,508 Views)

Oops, I realize I solved a slightly different problem (but the "fix" is almost trivial).  Here's a question for the Original Poster -- your Example has the initial routine called with ABCCBA, which causes calls to A, B, C, C, B, but not A (with an empty argument).  What would you want to do if the initial string were simply "A"?  Do nothing?  

 

When I coded this, I added the final call to A with an empty argument (so, for example, the final B call says "B with Argument A", and the final A call says "A with Argument" (since "blank" doesn't print)).  It's a "trivial exercise" to "quit" one step earlier, another Exercise Left to the Student ...

 

Bob Schor

0 Kudos
Message 12 of 27
(2,501 Views)

"LoopB ends recursion as the queue is empty"

No it doesn't. That's the issue. If the string is empty you shouldn't run "call synchronous" at all.

/Y

G# - Award winning reference based OOP for LV, for free! - Qestit VIPM GitHub

Qestit Systems
Certified-LabVIEW-Developer
0 Kudos
Message 13 of 27
(2,488 Views)

Same answer as the first time you asked this question.

 

Time to look into a composite pattern...

 

EDIT: Thanks for merging, GerdW!

0 Kudos
Message 14 of 27
(2,483 Views)

Can you provide more details?

 

All I am seeing is a tree structure, that doesn't solve the problem.

0 Kudos
Message 15 of 27
(2,463 Views)

I have made a mistake, it is supposed to call A at the end.

 

Here is an updated and fully working project:

 

LoopALoopALoopBLoopBLoopCLoopCMainVIMainVI

 

Now if you run the VI, you get to see the generated queue for the instrument.

 

Try it with "ABC", "CBA", "C", "BA", or any permutation from 3 to 1 var.

 

One thing I don't understand is why sequence "AA" or any repeated sequence causes a crash.

I would love to see a iterative solution for this.

0 Kudos
Message 16 of 27
(2,448 Views)

OK.  Here's a Recursive routine I'll call "Recurse".  Let's start with a String, where the first letter (here A, B, or C) determines what you do next, and the rest of the String serves as an "argument" for the (recursive) routine.  Let's call the first element the "Head", and the remaining string the "Tail" (I expect some will recognizes these thtermths -- oops, pardon my Lisp).  The Head determines whether we do "Code A", "Code B", or "Code C", passing the Tail as the "argument".  Rather than implement three A, B, or C processing routines, I simply used a Case Statement ("Alternative") to do A, B, or C processing of the Argument.  When I'm done, I take the Argument and pass it to 

Recurse (within Recurse -- that's what makes it "Recursive", it calls itself).  Here it is:

RecurseRecurse

This shows the "A" case, which simply prints "Loop A with Argument BCCBA".  In this simple example, the B and C cases are identical to the A Case (since this is just an exercise, but they could be very different).  After doing this one thing, the "Argument" (initially "BCCBA") comes out, and if it isn't empty (meaning "all done"), we pass it back to Recurse (which is just the code being shown).  We need to set the Execution property to "Shared Clone, Reentrant" (otherwise LabVIEW will flag the Recursive Call, i.e. a VI named "Recurse" inside a VI name "Recurse", as an error.

 

Note that the Recursive Call is the last thing in Recurse -- this is called "Tail Recursion", and is trivially changed to simple Iteration.  Check out the routine "Repeat", shown below, which does the same thing:

RepeatRepeat

Note the similarity.

 

Bob Schor

Message 17 of 27
(2,443 Views)
Solution
Accepted by Threshold10

Based on your code you made a consecutive looping. I needed recursive looping.

 

Move the recurse inside the AMove the recurse inside the A

 

You had the right idea with the recursive function just had to move it inside the selector case.

 

Fix for the handlesFix for the handles

All my coded needed was a fix for handles. You can now call any of the functions in any order, any times.

0 Kudos
Message 18 of 27
(2,391 Views)

Is this a finished product? I do not know how it is supposed to work, but it seems to work odd.

 

If I put just an A in the dequeue loop will never stop.

If I put AAA in, the frequency reported starts to go through some weird cycling and skipping of steps.

 

mcduff

0 Kudos
Message 19 of 27
(2,383 Views)

Well if you are sweeping a variable A,

                    and then want on each sweep point to sweep A,

                                       and then on that each sweep point to sweep A,

                                                     then yes.

In my case I have many variables to sweep recursively and in any order, and each can be off or on.

0 Kudos
Message 20 of 27
(2,374 Views)