Rascal: Can a Function return a Function - higher-order-functions

The Rascal documentation has an example of a function that takes a function as an argument:
int f(int x, int (int) multi){ return multi(x); }
Conversely, what is the syntax for a function that returns a function?
I couldn't find an example and tried things along the line:
(int (int)) f() {return (int y) {return y;}}
but got syntax errors in the repl.

Here is an example:
int two(int n) = 2 * n;
int(int) g() = two;
Function two multiplies by 2 and g returns the function two.
Observe that the return type of g is int(int), a type describing a function which returns an int and has one int argument.
A similar effect can be achieved by an inline definition:
int(int) g() = int(int n) { return 2 * n; };
You can also use this same notation inside other functions. For instance, you could create a function which multiplies two numbers:
int mult(int n, int m) = n * m;
If you use it, you would get what you would expect:
rascal>mult(3,4);
int: 12
You can instead return a function that essentially partially applies this function as follows:
int(int) multBy(int n) {
return int(int m) {
return mult(n,m);
};
}
int (int) (int)
So, this returns a function that takes an int and returns an int (int), i.e., a function that takes an int and returns an int. You can then use it as so:
rascal>multBy3 = multBy(3);
int (int)
rascal>multBy3(4);
int: 12
You can find more examples in some of our (many) files with tests:
lang::rascal::tests::basic::Functions
lang::rascal::tests::functionality::FunctionComposition
Thanks for your question, we have more documentation to do!

The short answer to my failed attempt is:
leave out the outermost parens in the return type of f
add the return type int of the anonymous function that is returned by f
don't forget the semi after f's return statement
That gives:
int (int) f() { return int (int y) { return y; } ; }

Related

Function call in a "if" clause to ACSL

Consider the following code
int f(int a, int b){
return 0;
}
/*#
ensures (f(2,3)== 0) ==> \result == 2;
*/
int g() {
if (f(2,3) == 0)
return 2;
return 0;
}
The response of frama-c to the following code is the following error
[kernel:annot-error] fing.c:5: Warning:
unbound function f. Ignoring logic specification of function g
[kernel] User Error: warning annot-error treated as fatal error.
[kernel] User Error: stopping on file "fing.c" that has errors. Add '-kernel-msg-key pp'
for preprocessing command.
[kernel] Frama-C aborted: invalid user input.
Is there a way to write a specification where there's a call of a function inside an "if" clause ?
In ACSL, you cannot use a C function in the specification. If you want to do something like this, the only possibility is to define a logic function (ideally provably) equivalent to the C function and to use this logic function.
/*# logic integer l_f(integer a, integer b) = 0 ; */
//# ensures \result == l_f(a, b);
int f(int a, int b){
return 0;
}
/*#
ensures (l_f(2,3)== 0) ==> \result == 2;
*/
int g() {
if (f(2,3) == 0)
return 2;
return 0;
}

Frama-C - Get function input value through command line

Analysing the code below on GUI, it is possible check the input values of the function div0.
int div0(int x, int y)
{
return (x/y);
}
int main()
{
int res;
int a = 4;
int b = 2;
res = div0(a,b);
return 0;
}
Is it possible get this value through command line?
The simplest approach in your case is to insert calls to Frama_C_show_each, which is a special Frama-C builtin function that prints the internal Eva state for the given expressions, each time the interpreter passes through the program point. For instance:
int div0(int x, int y)
{
Frama_C_show_each_div0(x, y);
return (x/y);
}
Running frama-c -eva on the modified program will print:
[eva] file.c:3: Frama_C_show_each_div0: {4}, {2}
You can choose the suffix after Frama_C_show_each for each line you want. For instance, if you prefer to print each variable separately:
int div0(int x, int y)
{
Frama_C_show_each_x(x);
Frama_C_show_each_y(y);
return (x/y);
}
Will print instead:
[eva] file.c:3: Frama_C_show_each_x: {4}
[eva] file.c:4: Frama_C_show_each_y: {2}
For a more complex situation, or to avoid modifying the source code, other alternatives are possible, but they may require writing some OCaml code, either to modify Eva directly, or to add e.g. a new abstract domain which will print the expressions. But it's overkill for simple cases.
By the way, if you want your code to still compile normally, simply protect the call to Frama_C_show_each with #ifdef __FRAMAC__ guards:
int div0(int x, int y)
{
#ifdef __FRAMAC__
Frama_C_show_each_div0(x, y);
#endif
return (x/y);
}

How to return multiple values (vector and one int value) through function

I am finding connected components of a graph.
Condition : Those components should not be printed in same function, but they should be printed in calling function ( i.e. int main() )
I have gone through the link but got some error.
Returning multiple values from a C++ function
tuple <vector<int>&, int > connected( vector<int>& store, ...)
{
int component_size = 0;
// code
return make_tuple ( store, component_size);
}
int main()
{
// code
for( int i = 0 ; i < V; i++ )
{
if( !visited[i])
{
tie( ans, compo_size ) = connected(edges,
visited, myQ, store, V, i);
for(int i = 0 ; i < compo_size; i++ )
{
cout<< ans[i] <<" ";
}
}
}
}
There are few errors :
error: could not convert 'std::make_tuple(_Elements&& ...) [with _Elements = {std::vector >&, int&}](component_size)' from 'std::tuple >, int>' to 'std::tuple >&, int>'
return make_tuple ( store, component_size);
^
error: invalid initialization of reference of type 'std::vector&' from expression of type 'std::vector'
tie( ans, compo_size ) = connected(edges, visited, myQ, store, V, i);
How to return multiple values (vector and one int value) through function
A function can have at most one return value.
Returning more objects can be emulated by either
modifying one or more objects that are global or are referenced by arguments through indirection or by
returning an object of class type that has multiple sub objects.
You've attempted the latter approach through the use of tuple class template. The reason it doesn't work is explained in the documentation:
template< class... Types >
tuple<VTypes...> make_tuple( Types&&... args );
For each Ti in Types..., the corresponding type Vi in VTypes... is std::decay<Ti>::type unless application of std::decay results in std::reference_wrapper<X> for some type X, in which case the deduced type is X&.
As such, your invocation of make_tuple is deduced to return tuple <vector<int>, int > which is wrong because the function is supposed to return tuple <vector<int>&, int > instead. This can be fixed using std::ref so that the correct type is deduced:
std::make_tuple(std::ref(store), component_size);
As eerorika mentioned, you could use std::ref() as follow:
std::tuple <std::vector<int>&, int > connected( std::vector<int>& store, ...)
{
int component_size = 0;
// code
return std::make_tuple ( std::ref(store), component_size);
}
However, there is really no point in returning a reference to the input vector since it is already a non-const reference on input. So changing the vector in place is going to be enough. On return you get a modified version. However, that's probably not what you are looking to do (i.e. you probably wanted to make a copy of store and return the copy with the other arrays appended...)
That also means you're going to have yet another copy when you create the tuple:
std::tuple <std::vector<int>, int > connected( std::vector<int>& store, ...)
{
int component_size = 0;
std::vector<int> result;
// or maybe a straight copy, depends on your needs in "code"
//std::vector<int> result(store);
// code
return std::make_tuple ( result, component_size);
}
As mentioned by others, having a result in the list of arguments is probably your best bet:
int connected( std::vector<int> & result, std::vector<int> const & store, ...)
{
int component_size = 0;
// code
return component_size;
}
Also, wouldn't component_size == result.size() be true? If so, you should not return anything because it's going to be more confusing.
That simplifies the function to this point:
void connected( std::vector<int> & result, std::vector<int> const & store, ...)
{
// code
}

Recursive Linear Search

The code shown below works fine. It prints the position of the element found inside the if clause and exits. Whenever the element is not found, the function runs to max and returns 0 to calling function to indicate no elements has been found.
However, I was pondering about returning the position of the element found, to the calling function rather than printing it. Since returning the position would just return to earlier instance of the function and not to the calling function, I am struck. How to achieve this ?
#include <stdio.h>
#include <stdlib.h>
int RLinearSearch(int A[],int n,int key)
{
if(n<1)
return 0;
else
{
RLinearSearch(A,n-1,key);
if(A[n-1]==key)
{
printf("found %d at %d",key,n);
exit(0);
}
}
return 0;
}
int main(void)
{
int A[5]={23,41,22,15,32}; // Array Of 5 Elements
int pos,n=5;
pos=RLinearSearch(A,n,23);
if(pos==0)
printf("Not found");
return 0;
}
Since returning the position would just return to earlier instance of the function and not to the calling function, I am struck.
You can solve this problem by returning the result of recursive invocation from the recursive call itself:
int RLinearSearch(int A[], int n, int key) {
if(n<0) { // Base case - not found
return -1;
}
if(A[n]==key) { // Base case - found
return n;
}
// Recursive case
return RLinearSearch(A, n-1, key);
}
Since this implementation treats n as the index of the current element, the caller should pass 4, not 5, in your example.
Demo 1.
Note: you can further simplify the code by joining the base cases together:
int RLinearSearch(int A[], int n, int key) {
return (n<0 || A[n]==key) ? n : RLinearSearch(A, n-1, key);
}
Demo 2.
start with your problem: linear search returning the index of where the key is found the function has three perameters, the array, the starting index of search n and the search key k.
so you have:
int RLinearSearch(int[] A, int n, int k)
{
if (n=>A.length()) return (-1);//base case(k not found in A)
else if (A[n]==k) return n; //found case
else return RLinearSearch(A, n+1, key); //continue case(keep looking through array)
}
int main(void){
int A[5]={23,41,22,15,32}; // Array Of 5 Elements
int pos,n=0;
pos=RLinearSearch(A,n,23);
if (pos == -1) printf("Not Found");
return 0;
}
you could also change it so that you just returned n-1 and you would have the right index.
You could use tail recursion :
int LSearch(int a[],int n,int key,int i)
{
if(n==0) return -1;
if(a[0]==key) return i;
LSearch(a+1,n-1,key,++i);
}
while calling use the function call:
LSeacrh(a,n,key,0);
public static int recursiveLinearSearch(int[] data, int index, int key){
if(index==data.length)
return -1;
if(data[index]==key)
return index;
return recursiveLinearSearch(data, index+1, key);
}

Changing this from recursion to iteration

Some pseudocode:
func F(int x. int y, array p){
p[x] = 1;
if (x<=y){
for each item in getItems(x,p){
p = F(item,y,p);
}
}
return p;
}
getItems() returns an array of numbers based on x and p, and isn't important for the sake of this question, but it returns a few numbers that are above and below x. However this means if x is too big then I blow up recursion stack since it'll dig down deep below x.
How can I change this to iteration?
You can do it by emulating the call stack:
struct stackentry {
int x;
Item item; // see exercise for reader, below
};
func F(int x, int y, array p){
dynamic_list_of_stackentry mystack;
start:
p[x] = 1;
if (x<=y){
for each item in getItems(x,p){
mystack.push(stackentry(x, item));
x = item
goto start
resume:
x = mystack.top().x;
item = mystack.top().item;
mystack.pop();
}
}
if mystack.size() > 0:
goto resume
return p;
}
Left as an exercise: change the iteration so that you can store, as part of the stack entry, the collection that you're currently iterating over (from getItems()) and your current position in it.
I'm not claiming this is elegant code, but you can refactor from this starting point of a non-recursive function that does the same as your recursive one. For example your next step might be:
func F(int x, int y, array p){
dynamic_list_of_int mystack;
mystack.push(x)
while not mystack.empty() {
x = mystack.top();
mystack.pop();
p[x] = 1;
if (x <= y) {
for each item in reversed(getItems(x,p)) {
mystack.push(item);
}
}
}
return p;
}
You might be able to keep the recursive version (without the stack overflow) by adding a guard that prevents you from double-processing x values
func F(int x. int y, array p){
if(p[x] != 1) {
p[x] = 1;
if (x<=y){
for each item in getItems(x,p){
p = F(item,y,p);
}
}
}
return p;
}
If some of your array values might have been initialized to 1, then change this to something like
if(p[x] != null) {
p[x] = null;
i.e. assign a value that you know isn't used in the initial array. Then when the function completes its processing, iterate through the array and set all null values to 1.

Resources