Function recursion, what happens in the SAS? - declarative

I have this scenario: a recursive procedure (or function) is called like
{DoSomething Data C}
and C is the variable that should store the final result, the function prototype is
proc {DoSomething Data N}
%..
%..
{DoSomething Data M}
N = 1 + M
end
and N is the variable that should store the final result too but in the local scope of the procedure.
Now it was told to me that at first, when the procedure is called, the SAS is:
Notice equivalence sets between C and N (both unbound for the moment)
then after all recursions have been completed, the SAS is
notice that both C and N are bound to a value (6)
After exiting the procedure the SAS is left with
because you destroy the N variable. And that's fine.
My question is: what happens during the procedure recursions? Does the C variable link to a partial value structure 1 + M ? And then next time M links to 1 + M2 ?

No, there are no partial structures in Oz, as long as we talk about simple integer arithmetics.
This statement:
N = 1 + M
will block until M is fully determined, i.e. is bound to an integer.
To really understand what is going on, I would have to see the full code.
But I assume that there is a base case that returns a concrete value. Once the base case is reached, the recursion will "bubble up", adding 1 to the result of the inner call.
In other words, the binding of C will only change at the end of the outermost procedure call, where M is 5 and C is therefore bound to 6.

Related

Lua | Count Occurences of Each Item in a Table

hi I'm trying to convert this python code to Lua
names=['Deepak','Reema','John','Deepak','Munna','Reema','Deepak','Amit','John','Reema']
d={}
for i in range(len(names)-1):
x=names[i]
c=0
for j in range(i,len(names)):
if names[j]==names[i]:
c=c+1
count=dict({x:c})
if x not in d.keys():
d.update(count)
print (d)
I got all the other parts working from top but I couldn't figure out how to convert this part into Lua
if x not in d.keys():
d.update(count)
would be really great if someone can help me make sense of this conversion
if x not in d.keys():
d.update(count)
x is the name currently indexed in that loop cycle
d is a dictionary that is used to store the count of each name
c is a dictionary with a single entry, the count c of x in names
So that line basically says:
if the current name x has not been counted yet (is not in our dictionary), add its count c to d using the name in x as key.
This code is not very efficient as it counts the names every time, even if that name has already been counted. The order should be changed so you only count if there is no count in d, yet.
There is also no need to iterate over the whole array for each entry. That nested loop is nonsense. You can count that in one go.
You shouldn't learn from whatever resource that is.
In Lua the snippet above would look something like:
if not d[x] then d[x] = c end
or simply
d[x] = d[x] or c
This is how you could implement it in Lua efficiently.
local names= {'Deepak','Reema','John','Deepak','Munna','Reema','Deepak',
'Amit','John','Reema'}
local counts = {}
for _, v in ipairs(names) do
counts[v] = counts[v] and counts[v] + 1 or 1
end

How to prove a thereom about a type class outside the original type class definition?

I was trying alternative ways to write the below proof from this question and Isabelle 2020's Rings.thy. (In particular, I added the note div_mult_mod_eq[of a b] line to test the use of the note command:
lemma mod_div_decomp:
fixes a b
obtains q r where "q = a div b" and "r = a mod b"
and "a = q * b + r"
proof -
from div_mult_mod_eq have "a = a div b * b + a mod b" by simp
note div_mult_mod_eq[of a b]
moreover have "a div b = a div b" ..
moreover have "a mod b = a mod b" ..
note that ultimately show thesis by blast
qed
However, if I write it in a separate .thy file, there is an error about type unification at the note line:
Type unification failed: Variable 'a::{plus,times} not of sort semiring_modulo
Failed to meet type constraint:
Term: a :: 'a
Type: ??'a
The problem goes way if I enclose the whole proof in a pair of type class class begin ... end as follows:
theory "test"
imports Main
HOL.Rings
begin
...
class semiring_modulo = comm_semiring_1_cancel + divide + modulo +
assumes div_mult_mod_eq: "a div b * b + a mod b = a"
begin
(* ... inserted proof here *)
end
...
end
My questions are:
Is this the correct way to prove a theorem about a type class? i.e. to write a separate class definition in a different file?
Is it always necessary to duplicate type class definitions as I did?
If not, what is the proper way to prove a theorem about a type class outside of its original place of definition?
There are two ways to prove things in type classes (basically sort = typeclass for Isabelle/HOL):
Proving in the context of the typeclass
context semiring_modulo
begin
...
end
(slightly less clean) Add the sort constraints to the type:
lemma mod_div_decomp:
fixes a b :: "'a :: {semiring_modulo}"
obtains q r where "q = a div b" and "r = a mod b"
and "a = q * b + r"
semiring_modulo subsumes plus and times, but you can also type {semiring_modulo,plus,times} to really have all of them.
The documentation of classes contains more examples.
The issue you ran into is related to how Isabelle implements polymorphism. Sorts represent a subset of all types, and we characterize them by a set of intersected classes. By attaching a sort to a variable, we restrict the space of terms with which that variable can be instantiated with. One way of looking at this is an assumption that the variable belongs to a certain sort. In your case, type inference (+) (*) div mod apparently gives you {plus,times}, which is insufficient for div_mult_mod_eq. To restrict the variable further you can make an explicit type annotation as Mathias explained.
Note that the simp in the line above should run into the same problem.

Array product given a dynamic number of arguments

I have a function that does an array product:
arrayProduct(l1,l2,l3) = [[a, b, c] |
a := l1[_]
b := l2[_]
c := l3[_]
]
If I have three arrays defined as follows:
animals1 = ["hippo", "giraffe"]
animals2 = ["lion", "zebra"]
animals3 = ["deer", "bear"]
Then the output of arrayProduct(animals1, animals2, animals3) would be:
[["hippo","lion","deer"],["hippo","lion","bear"],["hippo","zebra","deer"],["hippo","zebra","bear"],["giraffe","lion","deer"],["giraffe","lion","bear"],["giraffe","zebra","deer"],["giraffe","zebra","bear"]]
If I can guarantee that the inputs will always be lists is there away I could make a function that would do the same thing except it could accept a dynamic number of lists as input instead of just 3?
I'm also exploring if it would also be possible to do this with only one argument containing all the arrays within it as opposed to accepting multiple arguments. For example:
[["hippo", "giraffe"], ["lion", "zebra"], ["deer", "bear"], ["ostrich", "flamingo"]]
Any insight into a solution with either approach would be appreciated.
There's no known way to compute an arbitrary N-way cross product in Rego without a builtin.
Why something can't be written in a language can be tricky to explain because it amounts to a proof-sketch. We need to make the argument that there is no policy in Rego that computes an N-way cross product. The formal proofs of expressiveness/complexity have not been worked out, so the best we can do is try to articulate why it might not be possible.
For the N-way cross product, it boils down to the fact that Rego guarantees termination for all policies on all inputs, and to do that it restricts how deeply nested iteration can be. In your example (using some and indentation for clarity) you have 3 nested loops with indexes i, j, k.
arrayProduct(l1,l2,l3) = [[a, b, c] |
some i
a := l1[i]
some j
b := l2[j]
some k
c := l3[k]
]
To implement an N-way cross product arrayProduct([l1, l2, ..., ln]) you would need something equivalent to N nested loops:
# NOT valid Rego
arrayProduct([l1,l2,...,ln]) = [[a, b, ..., n] |
some i1
a := l1[i1]
some i2
b := l2[i2]
...
n := ln[in]
]
where importantly the degree of nested iteration N depends on the input.
To guarantee termination, Rego restricts the degree of nested iteration in a policy. You can only nest iteration as many times as you have some (or more properly variables) appearing in your policy. This is analogous to SQL restricting the number of JOINs to those that appear in the query and view definitions.
Since the degree of nesting required for an N-way cross product is N, and N can be larger than the number of somes in the policy, there is no way to implement the N-way cross product.
As a point of contrast, the number of keys or values that are iterated over inside any one loop CAN and usually DO depend on the input. It's the number of loops that cannot depend on the input.
It's not possible to compute an n-ary product of lists/arrays (or sets or objects) in Rego without adding a built-in function.
In the scenario described above, providing a dynamic number of arrays as input to the function would be equivalent to passing an array of arrays (like you mentioned at the end):
arrayProduct([arr1, arr2, ..., arrN])
This works, except that when we try to implement arrayProduct we get stuck because Rego does not permit recursion and iteration only occurs when you inject a variable into a reference. In your original example l1[_] is a reference to the elements in the first list and _ is a unique variable referring to the array indices in that list.
OPA/Rego evaluates that expression by finding assignments to each _ that satisfy the query. The "problem" is that this requires one variable for each list in the input. If the length of the array of arrays is unknown, we would need an infinite number of variables.
If you really need an n-ary product function I would suggest you implement a custom built-in function for now.

Why the output differs in these two erlang expression sequence in shell?

In Erlang shell why the following produces different result?
1> Total=15.
2> Calculate=fun(Number)-> Total=2*Number end.
3> Calculate(6).
exception error: no match of right hand side value 12
1> Calculate=fun(Number)-> Total=2*Number end.
2> Total=15.
3> Calculate(6).
12
In Erlang the = operator is both assignment and assertion.
If I do this:
A = 1,
A = 2,
my program will crash. I just told it that A = 1 which, when A is unbound (doesn't yet exist as a label) it now is assigned the value 1 forever and ever -- until the scope of execution changes. So then when I tell it that A = 2 it tries to assert that the value of A is 2, which it is not. So we get a crash on a bad match.
Scope in Erlang is defined by two things:
Definition of the current function. This scope is absolute for the duration of the function definition.
Definition of the current lambda or list comprehension. This scope is local to the lambda but also closes over whatever values from the outer scope are referenced.
These scopes are always superceded at the time they are declared by whatever is in the outer scope. That is how we make closures with anonymous functions. For example, let's say I had have a socket I want to send a list of data through. The socket is already bound to the variable name Socket in the head of the function, and we want to use a list operation to map the list of values to send to a side effect of being sent over that specific socket. I can close over the value of the socket within the body of a lambda, which has the effect of currying that value out of the more general operation of "sending some data":
send_stuff(Socket, ListOfMessages) ->
Send = fun(Message) -> ok = gen_tcp:send(Socket, Message) end,
lists:foreach(Send, ListOfMessages).
Each iteration of the list operation lists:foreach/2 can only accept a function of arity 1 as its first argument. We have created a closure that captures the value of Socket internally already (because that was already bound in the outer scope) and combines it with the unbound, inner variable Message. Note also that we are checking whether gen_tcp:send/2 worked each time within the lambda by asserting that the return value of gen_tcp:send/2 was really ok.
This is a super useful property.
So with that in mind, let's look at your code:
1> Total = 15.
2> Calculate = fun(Number)-> Total = 2 * Number end.
3> Calculate(6).
In the code above you've just assigned a value to Total, meaning you have created a label for that value (just like we had assigned Socket in the above example). Then later you are asserting that the value of Total is whatever the result of 2 * Number might be -- which can never be true since Total was an integer so 2 * 7.5 wouldn't cut it either, because the result would be 15.0, not 15.
1> Calculate = fun(Number)-> Total = 2 * Number end.
2> Total = 15.
3> Calculate(6).
In this example, though, you've got an inner variable called Total which does not close over any value declared in the outer scope. Later, you are declaring a label in the outer scope called Total, but by this time the lambda definition on the first line has been converted to an abstract function and the label Total as used there has been completely given over to the immutable space of the new function definition the assignment to Calculate represented. Thus, no conflict.
Consider what happens, for example, with trying to reference an inner value from a list comprehension:
1> A = 2.
2
2> [A * B || B <- lists:seq(1,3)].
[2,4,6]
3> A.
2
4> B.
* 1: variable 'B' is unbound
This is not what you would expect from, say, Python 2:
>>> a = 2
>>> a
2
>>> [a * b for b in range(1,4)]
[2, 4, 6]
>>> b
3
Incidentally, this has been fixed in Python 3:
>>> a = 2
>>> a
2
>>> [a * b for b in range(1,4)]
[2, 4, 6]
>>> b
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'b' is not defined
(And I would provide a JavaScript example for comparison as well, but the scoping rules there are just so absolutely insane it doesn't even matter...)
In the first case you have bound Total to 15. In Erlang, variable are unmutable, but in the shell when you write Total = 15. you do not really create the variable Total, the shell does its best to mimic the behavior you will have if you were running an application, and it stores in a table the couple {"Total",15}.
On the next line you define the fun Calculate. the Parser find the expression Total=2*Number, and it goes through its table to detect that Total was previously defined. The evaluation is turned into something equivalent to 15 = 2*Number.
So, in the third line, when you ask to evaluate Calculate(6), it goes to calculate and evaluates 15 = 2*6 and issues the error message
exception error: no match of right hand side value 12
In the second example, Total is not yet defined when you define the function. The function is stored without assignment (Total is not used anymore), at least no assignment to a global variable. So there is no conflict when you define Total, and no error when you evaluate Calculate(6).
The behavior would be exactly the same in a compiled module.
The variable 'Total' is already assigned a value 15, so you can NOT using the same variable name Total in the second line. You should change to the other name Total1 or Total2...

Wrong value calculated by Delphi

I have a record declared as
T3DVector = record
X,Y,Z: Integer;
end;
One variable V of type T3DVector holds:
V.X= -25052
V.Y= 34165
V.Z= 37730
I then try to the following line. D is declared as Double.
D:= (V.X*V.X) + (V.Y*V.Y) + (V.Z*V.Z);
The return value is: -1076564467 (0xFFFFFFFFBFD4EE0D)
The following code should be equivalent:
D:= (V.X*V.X);
D:= D + (V.Y*V.Y);
D:= D + (V.Z*V.Z);
But this,however, returns 3218402829 (0x00000000BFD4EE0D), which actually is the correct value.
By looking at the high bits, I thought this was an overflow problem. When I turned on overflow checking, the first line halted with the exception "Integer overflow". This is even more confusing to me because D is Double, and I am only storing values into D
Can anyone clarify please ?
The target of an assignment statement has no bearing on how the right side is evaluated. On the right side, all you have are of type Integer, so the expression is evaluated as that type.
If you want the right side evaluated as some other type, then at least one operand must have that type. You witnessed this when you broke the statement into multiple steps, incorporating D into the right side of the expression. The value of V.Y * V.Y is still evaluated as type Integer, but the result is promoted to have type Double so that it matches the type of the other operand in the addition term (D).
The fact that D is a double doesn't affect the type of X, Y and Z. Those are Integers, and are apparently not large enough to store the squares of such large numbers, and their multiplication is what overflows. Why don't you declare them as doubles, too?

Resources