Groups keyboard shortcuts have been updated
Dismiss
See shortcuts

introspection & calls

49 views
Skip to first unread message

Nartoo Meon

unread,
Jun 14, 2024, 6:58:40 PM6/14/24
to Picat
Hello everyone!

I have one problem, but I dont know how to realise it with Picat. It based on counting number of args of a function and calling it with right amout of arguments.
Here is the problem:
—With given function fnc/n and a list Lst and length(Lst)=L, return a list, contains first L elements of sequence Sq, defined as follows:

Sq[ 1 ] = Lst[ 1 ],
Sq[ 2 ] = Lst[ 2 ],
...
Sqn–1 ] = Lst[ n–1 ],
Sq] = fnc( Sq[ 1 ] ,  Sq[ 2 ] , ... , Sqn–1 ] ,  Lst),
...
Sqi ] = fnc( Sqin+1 ] ,  Sqin+2 ] , ... , Sqi–1 ] ,  Lst) in general.

With n=2 it equal to the .accumulate() method from python module itertools.

Yes, it completely uselles with n=3 or more, but is interesting to program it.

This problem started in my head as an explanation of the .accumulate() method that I read in some telegram channel about Python. Unfortunately, I was wrong because it only uses binary operations or 2-argument functions.

I read in the guide about the number_vars() function, but it accepts a term, and if I write fnc(...) — it's not a term, it's a function call. I can find a solution - the parse_term() function. Again, this is not a good solution because it accepts the term as a string that is independent of my function, I can write anything I want to that string.
Im not sure to use that, becose I need to find my function by name from their position in the code, and it can live in other file, module. Is not simple.

The other challenge is to put the right number of args. Maybe I can do it with a lazy evaluation... But I'm confused about that too.
Maybe if I know the number of args, it could be easy. But it seems like I'm adding more closes to the function, kind of rewriting it.
      In JavaScript we can use an operator "..." (rest) to "unpack" a list of values inside a function call and call a function with this arguments.

Currently I'm thinking of the following method: put a value in a function and check if it is called without error. If an error appears, then place a second value and repeat the process until the function is called normally. But how to do this?
Maybe call_cleanup() can help...

Hakan Kjellerstrand

unread,
Jun 15, 2024, 4:39:33 AM6/15/24
to Picat
I'm not sure I understand this. The main problem seems to be how to call a function with variable arguments, but the part to generate all the parameters/values is not a problem. Is that correct?

If so, here are some answers/hints.

First, there's no "unpack" function in Picat which corresponds to Javascript's "...". I'm not sure how you define fnc/1,,m, but I assume that it's defined for all possible values.

One way might be to use Picat's "=.." (univ) function and then apply/1.

Here's a simple example where fnc/1..n is to simply sum all the arguments.
"""
main ?=>
 foreach(I in 1..8)
   L = 1..I,
   println(L),
   F =.. [fnc] ++ L,
   println(F),
   println(apply(F)),

 end,
 nl.
main => true.

fnc(A) = A.
fnc(A,B) = A+B.
fnc(A,B,C) = A+B+C.
fnc(A,B,C,D) = A+B+C+D.
fnc(A,B,C,D,E) = A+B+C+D+E.
fnc(A,B,C,D,E,F) = A+B+C+D+E+F.
fnc(A,B,C,D,E,F,G) = A+B+C+D+E+F+G.
fnc(A,B,C,D,E,F,G,H) = A+B+C+D+E+F+G+H.
"""

The output:
"""
[1]
fnc(1)
1
[1,2]
fnc(1,2)
3
[1,2,3]
fnc(1,2,3)
6
[1,2,3,4]
fnc(1,2,3,4)
10
[1,2,3,4,5]
fnc(1,2,3,4,5)
15
[1,2,3,4,5,6]
fnc(1,2,3,4,5,6)
21
[1,2,3,4,5,6,7]
fnc(1,2,3,4,5,6,7)
28
[1,2,3,4,5,6,7,8]
fnc(1,2,3,4,5,6,7,8)
36
"""

Explanations:
- F =.. [fnc] ++ L:  This converts the list L into a function fnc(L[1],L[2],..)
- apply(F): This calls the created function F and returns the value.

That being said, a better approach might be to have a single function fcn(L) where L is the list of the values, and then to generate the result from that list. Since you don't give any details about what fnc/1..n does, it's hard to give some more details on this.

Hope this helps. If not, please give some more details, and perhaps also some small examples.

/Hakan

Nartoo Meon

unread,
Jun 15, 2024, 1:29:46 PM6/15/24
to Picat
"... the part to generate all the parameters/values is not a problem. Is that correct? ..."
Yes, the input list of values is given and "fully instantiated".

Huh! I could guess it myself, but I didn't! The "=.." operator may cover all my needs quite well.
I can call a function properly, even without number_vars(), becose it possible to backtrack, if we give fnc not proper amount of args. If I understand you.
It sad, if it impossible without backtracking, and then we can`t use a function, predicates only.

"... you don't give any details about what fnc/1..n does, it's hard to give some more details ..."
Its becose I want to solve a general case, where fnc/n can be almost any n-argument function. Such tasks probably can't occur to a programmer, more like a mathematician.
It might be useful if fnc was a number-valued  function. That's my first idea.

The next text is what I'm thinking about and a few examples.

Sq sequence is like a memoization of complicated recursion of some function. It also like calling a function with more than required number of args.
The binary operations in fact, do it every time!  (may becose many of good ones is assotiative) So, its the way to applying the high arity operation on arbitrary "product" of elements without problems.
But length can`t be less than n. If such appear we return the last element of Sq list, as usual, and without any fnc actions.
For example, if we have a ternary operation (abc) -> e, then we cant done the "product" of 4 elements with it: (abc)d = ed , too small. But my version can do it:
abcd -> [a,b,c,d] -> Sq=[ab(abc)(b(abc)d) ] -> (b(abc)d) = Result.
And yeah, here is not one way to use n-ary operation for any "list" of elements. As example: abcd ab(bcd) (ab(bcd)) .
Conclusion: probably, Sq came out as a way to compute the n-ary operation(fnc) on any ordered set of elements (with size>n–1). Thus, if fnc is addition, we get the sum of the given numbers at the end of Sq, no matter how many there are.
We also get list of calls with the same length as input list... if that's important...
субота, 15 червня 2024 р. о 11:39:33 UTC+3 Hakan Kjellerstrand пише:
Reply all
Reply to author
Forward
0 new messages