What is an elegant way to break out of a visit statement in Rascal MPL? - break

I'm using visit in rascal to iterate through a string. I would like to break out once I match a specific case. In other words, I would like to achieve this exact behavior:
str toVisit = "abcdefgh";
while(true) {
visit(toVisit) {
case /^bc/: println("before");
case /^de/: break;
case /^fg/: println("after");
}
break;
}
but without the while loop. There is no mention of this in the manual page of visit. Hence my question: is there an elegant way to break out of a visit statement in Rascal MPL?

visit is general better at recursive traversals then iterating, but return is the typical way people do break out of visits:
void myFunction() {
visit (toVisit) {
case /^bc/: println("before");
case /^de/: return;
case /^fg/: println("after");
}
}
So that favors smaller functions :-)
Otherwise, regular expressions themselves have excellent backtracking behavior for searching linear patterns like that:
for (/<before:.*>bc<middle:.*>de<after:.*>fg/ := "abcdefgh") {
println("match! <before> <middle> <after>");
// fail brings you to the next match (also for visit, if, etc)
fail;
// break jumps out of the loop
break;
// continue brings you to the next match as well
continue;
}

Related

What is the equivalent of 'break' in q#?

How would I break out of a loop when I meet a condition?
For example:
for (i in 0..10){
if (i==3){
// equivalent of break
}
}
There is no break in Q#; however, you can implement this behavior using repeat-until-success loop.
Q# is not a general-purpose language, and is designed to allow a lot of optimizations for when a program will be executed on a quantum device. Loops are one example of such design: if you know beforehand how many iterations your loop will do, use a for loop, if you need to iterate until some condition is met, use repeat-until-success loop.
Your example (which is not really a good example of why you'd need a break) would be written as something like this:
mutable i = 0;
repeat {
set i = i + 1;
} until (i == 10 || i == 3)
fixup {
();
}

Not understood return behavior of recursive function with closure

The foundations of my programming "skills" are shaking.. I don't know if this behavior is caused by the recursion, closure or something else, but this is by far the weirdest thing I've seen so far.
My original intention was to use recursion to count the parents of dom element. The closure is implemented to store my counter and recursion would increase it for every parent that is not equal to div#wrapper. And it works - once. For the first element (having only 1 parent - it returns 1) However the second time it returns undefined. for the sake of testing I came up with this rig:
let parents = countParents();
let pathLength = parents(3);
function countParents() {
let counter = 0;
return function nextParent(node) {
let parent = node - 1;
counter++;
if (parent === 1)
return 'WATAFAK';
else
nextParent(parent);
}
}
console.log(pathLength);
I am actually questioning my eyes (it's late, been programming for a while now), but this function returns undefined. HOW is that possible?
function countParents() {
let counter = 0;
return function nextParent(node) {
let parent = node - 1;
counter++;
if (parent === 1)
return 'WATAFAK';
else
nextParent(parent); // call nextParent(parent) and throw away result
return undefined; // invisible line in every function
}
return undefined; // invisible line in every function (never reached)
}
If you wanted the result of the recursion to be the result you must add return in front of it. How it is now it's only for side effects and it's pretty much dead code.
Since the else branch doesn't return all functions have a invisible return undefined, just before its block ends.

how stacks are formed and value from a method return when the method has TWO recursive calls of itself from within itself

I have tried creating stacks for recursive inorder,preorder,postoreder traversal for binary tree and I was doing it pretty well. In other cases like, for example, for a test case my answer should be 'true',say.And, for example,
boolean method(root)
{
// more code
method(root.left());
method(root.right());
}
,somewhere,the call of method(root.left()) returns false and a call of method(root.right()) returns true that should be our answer. But since call of method(root.left() ) completes first and somewhere, in between it's execution, it might have returned false. then how do we get our result true from method(root.right())?? I think it is related to how stacks are formed and values from a method are returned when recursive calls ,in this way, happen.Explain it and correct me if I am wrong.
You need to return values. The method need to make use of the returned values in its logic to stop/continue the search.
You need to have that the base cases return either true of false. Then when doing the first recursive call you need only do the first if the result is true. The second recursive call would be the result of the method if it's needed. Thus you are looking at something like this:
boolean method(root)
{
if( root == null ) { // base case 1
return false;
}
if( root.value == someValue ) { // base case 2, what should be a positive
return true;
}
// default search left first and return true if true
if( method(root.left()) ) {
return true;
}
// default search right and return true if true
if( method(root.right()) ){
return true;
}
// return false since neither recursive calls were true
return false;
}
This is very verbose and can be written like this instead:
boolean method(root)
{
return root != null && ( root.value == someValue ||
method(root.left()) ||
method(root.right()));
}
I find the last more readable but novices might find the more verbose first one to be more clear.
In both the callee resumes operation after the first recursive call (which might have had it's share of calls as well) and continues it's logic and recurses on the right side if needed.
Don't care about the system stack. Care about the base case and test them. Then do the simplest of added complexity to do the default case so that you see the problem becoming smaller in the recursive call(s). It's much better going from simple to more complex than to try figuring this stuff out by starting at a large tree looking at whats happening with a very deep recursive round.

if {...} else {...} : Does the line break between "}" and "else" really matters?

I write my if {...} else {...} statement in R in the following way as I find it more readable.
Testifelse = function(number1)
{
if(number1>1 & number1<=5)
{
number1 =1
}
else if ((number1>5 & number1 < 10))
{
number1 =2
}
else
{
number1 =3
}
return(number1)
}
According to ?Control:
... In particular, you should not have a newline between } and else to avoid a syntax error in entering a if ... else construct at the keyboard or via source ...
the function above will cause syntax error, but actually it works! What's going on here?
Thanks for your help.
Original question and answer
If we put in R console:
if (1 > 0) {
cat("1\n");
}
else {
cat("0\n");
}
why does it not work?
R is an interpreted language, so R code is parsed line by line. (Remark by #JohnColeman: This judgement is too broad. Any modern interpreter does some parsing, and an interpreted language like Python has no problem analogous to R's problem here. It is a design decision that the makers of R made, but it wasn't a decision that was forced on them in virtue of the fact that it is interpreted (though doubtless it made the interpreter somewhat easier to write).)
Since
if (1 > 0) {
cat("1\n");
}
makes a complete, legal statement, the parser will treat it as a complete code block. Then, the following
else {
cat("0\n");
}
will run into error, as it is seen as a new code block, while there is no control statement starting with else.
Therefore, we really should do:
if (1 > 0) {
cat("1\n");
} else {
cat("0\n");
}
so that the parser will have no difficulty in identifying them as a whole block.
In compiled language like C, there is no such issue. Because at compilation time, the compiler can "see" all lines of your code.
Final update related to what's going on inside a function
There is really no magic here! The key is the use of {} to manually indicate a code block. We all know that in R,
{statement_1; statement_2; ...; statement_n;}
is treated as a single expression, whose value is statement_n.
Now, let's do:
{
if (1 > 0) {
cat("1\n");
}
else {
cat("0\n");
}
}
It works and prints 1.
Here, the outer {} is a hint to the parser that everything inside is a single expression, so parsing and interpreting should not terminate till reaching the final }. This is exactly what happens in a function, as a function body has {}.

Backtracking recursively with multiple solutions

function BACKTRACKING-SEARCH(csp) returns a solution, or failure
return RECURSIVE- BACKTRACKING({ }, csp)
function RECURSIVE-BACKTRACKING(assignment,csp) returns a solution, or failure
if assignment is complete then
return assignment
var ←SELECT-UNASSIGNED-VARIABLE(VARIABLES[csp],assignment,csp)
for each value in ORDER-DOMAIN-VALUES(var,assignment,csp) do
if value is consistent with assignment according to CONSTRAINTS[csp] then
add {var = value} to assignment
result ← RECURSIVE-BACKTRACKING(assignment, csp)
if result ̸= failure then
return result
remove {var = value} from assignment
return failure
This is a backtracking recursion algorythm pseudocode from AIMA. However, I don't understand if it returns ALL possible solutions or just first one found. In case it is the last option, could you please help me modify it to return a list of possible solutions instead (or at least updating some global list).
EDIT: I implemented this algorithm in Java. However, there is one problem:
if I don't return assignment, but save it in result instead, the recursion stop condition fails (i.e. it doesn't exist anymore). How can I implement another stop-condition? Maybe I should return true in the end?
Here is my code :
/**
* The actual backtracking. Unfortunately, I don't have time to implement LCV or MCV,
* therefore it will be just ordinary variable-by-variable search.
* #param line
* #param onePossibleSituation
* #param result
*/
public static boolean recursiveBacktrack(Line line, ArrayList<Integer> onePossibleSituation, ArrayList<ArrayList<Integer>> result){
if (onePossibleSituation.size() == line.getNumOfVars()){
// instead of return(assignment)
ArrayList<Integer> situationCopy = new ArrayList<Integer>();
situationCopy.addAll(onePossibleSituation);
result.add(situationCopy);
onePossibleSituation.clear();
}
Block variableToAssign = null;
// iterate through all variables and choose one unassigned
for(int i = 0; i < line.getNumOfVars(); i++){
if(!line.getCspMiniTaskVariables().get(i).isAssigned()){
variableToAssign = line.getCspMiniTaskVariables().get(i);
break;
}
}
// for each domain value for given block
for (int i = line.getCspMiniTaskDomains().get(variableToAssign.getID())[0];
i <= line.getCspMiniTaskDomains().get(variableToAssign.getID())[0]; i++){
if(!areThereConflicts(line, onePossibleSituation)){
//complete the assignment
variableToAssign.setStartPositionTemporary(i);
variableToAssign.setAssigned(true);
onePossibleSituation.add(i);
//do backtracking
boolean isPossibleToPlaceIt = recursiveBacktrack(line,onePossibleSituation,result);
if(!isPossibleToPlaceIt){
return(false);
}
}
// unassign
variableToAssign.setStartPositionTemporary(-1);
variableToAssign.setAssigned(false);
onePossibleSituation.remove(i);
}
// end of backtracking
return(false);
}
This code checks if solution found and if it is, returns the solution. Otherwise, continue backtracking. That means, it returns the first solution found.
if result ̸= failure then
return result
remove {var = value} from assignment
You can modify it like that:
if result ̸= failure then
PRINT result // do not return, just save the result
remove {var = value} from assignment
Or, better, modify this part:
if assignment is complete then
print assignment
return assignment // print it and return
About edited question:
First, return true in the first if, so recursion will know that it found a solution. The second step, there is a mistake, probably:
if(!isPossibleToPlaceIt){
return(false);
}
Should be
if(isPossibleToPlaceIt){
return(true);
}
Because if your backtracking has found something, it returns true, which means you don't have to check anything else any longer.
EDIT#2: If you want to continue backtracking to find ALL solutions, just remove the whole previous if section with return:
//if(isPossibleToPlaceIt){
// return(true);
//}
So we will continue the search in any way.

Resources