I can't figure out how to create an array variable, that has x indices, and for each index it has a random number from some given range. How can this be done in TLA+ or PlusCal?
Let's say I want an array with 10 indices. On each index, for example on x[1], I want it's value to be a random number between 1-10.
Update December 2022
The RandomElement operator in the TLA+ Standard Modules supports selecting a "random element" from a set and can be used to assign a random value to each index of the array with the following code:
--------------------------- MODULE ArrayRandomV2 ---------------------------
EXTENDS Integers, Sequences, TLC
(****
--algorithm ArrayRandomV2 {
\* define a variables, inp as initial array of 10 with all values set to 0, set of the domain (1 - 10), and index for loop
variables inp \in [1..10 -> 0..0], seed \in {1..10}, i = 1;
{
while (i <= Len(inp)) {
inp[i] := RandomElement(seed);
i := i + 1;
};
assert \A n \in 1..Len(inp) : inp[n] >= 1 /\ inp[n] <= 10;
print inp;
}
}
****)
=============================================================================
The output of running this in the TCL Model Checker would be something like:
<<5, 8, 10, 5, 10, 1, 3, 4, 10, 1>>
However, please keep in mind that TLA+/PlusCal specifications are intended to be mathematical proofs and "randomness" is not math. There may be use cases where it is helpful but when creating algorithm specifications it would probably not be practical since each run of the TLC Model Checker would produce different results and would therefore not be verifiable.
Some further reading regarding using randomness in TLA+:
RandomElement fails with TLC bug
TLC choose a new unique element everytime
Original Answer
TLA+/PlusCal is designed to test algorithm behaviors so, taking that into consideration if your algorithm needs to test an array of 10 where each index is a value in the domain of 1 to 10 you could define a variable that is a tuple of count 10 with a domain of 1..10:
inp \in [1..10 -> 1..10]
When running the TLC model checker on the above variable it would test every combination of values in the domain for the array (this will take a very long time).
Here's a full sample of the code (I've adjusted the array size and domain to be 3 with a domain of 1..3 since using a large array with a large domain size will take a long time to test and a lot of memory to store):
---------------------------- MODULE ArrayRandom ----------------------------
EXTENDS Integers, Sequences, TLC
(*
--algorithm ArrayRandom {
\* define a variable, inp, as an array (a 3-tuple) whose domain is from 1 to 3
variables inp \in [1..3 -> 1..3];
{
assert \A n \in 1..Len(inp) : inp[n] >= 1 /\ inp[n] <= 3;
print inp;
}
}
*)
=============================================================================
Running the TLC model checker on the above code will print the following:
<<1, 1, 3>>
<<1, 2, 1>>
<<1, 1, 1>>
<<1, 1, 2>>
<<1, 2, 3>>
<<1, 3, 1>>
<<1, 2, 2>>
<<1, 3, 2>>
<<1, 3, 3>>
<<2, 1, 1>>
<<2, 1, 2>>
<<2, 1, 3>>
<<2, 2, 1>>
<<2, 3, 1>>
<<2, 2, 3>>
<<2, 3, 2>>
<<2, 2, 2>>
<<2, 3, 3>>
<<3, 1, 1>>
<<3, 1, 2>>
<<3, 1, 3>>
<<3, 2, 2>>
<<3, 2, 3>>
<<3, 2, 1>>
<<3, 3, 3>>
<<3, 3, 1>>
<<3, 3, 2>>
Related
I have a list with 10 numerical values. I want to return all possible combination of this list such that each element can take value +/- element value.
The approach I had in mind was to take a binary variable which takes in value from 0 to 1023. 1 in this variable corresponds to positive d[i] and 0 to negative d[i].
e.g. for bin(8) = 0000001000 implies that d7 will take value -d7 and rest will be positive. Repeat this for all 0 to 1023 to get all combinations.
For example, if D = [d1,d2,...d10], we will have 1024 (2^10) combinations such that:
D1 = [-d1,d2,d3,....d10]
D2 = [-d1,-d2,d3,....d10]
D3 = [d1,-d2,d3,....d10] ...
D1024 = [-d1,-d1,-d3,....-d10]
Thank You!
you can just use the builtin itertools.product to make all combinations of positive and negative values.
from itertools import product
inputs = list(range(10)) # [1,2,3,4,5,6,7,8,9]
outputs = []
choices = [(x,-x) for x in inputs]
for item in product(*choices):
outputs.append(item)
print(outputs[:3])
print(len(outputs))
# [(0, 1, 2, 3, 4, 5, 6, 7, 8, 9), (0, 1, 2, 3, 4, 5, 6, 7, 8, -9), (0, 1, 2, 3, 4, 5, 6, 7, -8, 9)]
# 1024
in a compressed form:
outputs = [item for item in product(*[(x,-x) for x in inputs])]
I'm wondering if there's a way of getting multiple outputs from a function into a list. I'm not interested in creating a list inside of a function for reasons I'm not going to waste your time going into.
I know how many output variables I am expecting, but only through using the annotations["return"] expression (or whatever you call that, sorry for the noobish terminology) and this changes from case to case, which is why I need this to be dynamic.
I know I can use lists as multiple variables using function(*myList), but I'm interested in if there's a way of doing the equivalent when receiving return values from a function.
Cheers!
Pseudocode:
function():
x = 1
y = 2
return x, y
variables = function()
print(variables[0], " and ", variables[1]
result should be = "1 and 2"
yes, with the unpacking assignments expression ex a,b,c= myfunction(...), you can put * in one of those to make it take a variable number of arguments
>>> a,b,c=range(3) #if you know that the thing contains exactly 3 elements you can do this
>>> a,b,c
(0, 1, 2)
>>> a,b,*c=range(10) #for when you know that there at least 2 or more the first 2 will be in a and b, and whatever else in c which will be a list
>>> a,b,c
(0, 1, [2, 3, 4, 5, 6, 7, 8, 9])
>>> a,*b,c=range(10)
>>> a,b,c
(0, [1, 2, 3, 4, 5, 6, 7, 8], 9)
>>> *a,b,c=range(10)
>>> a,b,c
([0, 1, 2, 3, 4, 5, 6, 7], 8, 9)
>>>
additionally you can return from a function whatever you want, a list, a tuple, a dict, etc, but only one thing
>>> def fun():
return 1,"boo",[1,2,3],{1:10,3:23}
>>> fun()
(1, 'boo', [1, 2, 3], {1: 10, 3: 23})
>>>
in this example it return a tuple with all that stuff because , is the tuple constructor, so it make a tuple first (your one thing) and return it
I have the following Python dict:
[(2, [3, 4, 5]), (3, [1, 0, 0, 0, 1]), (4, [-1]), (10, [1, 2, 3])]
Now I want to sort them on the basis of sum of values of the values of dictionary, so for the first key the sum of values is 3+4+5=12.
I have written the following code that does the job:
def myComparator(a,b):
print "Values(a,b): ",(a,b)
sum_a=sum(a[1])
sum_b=sum(b[1])
print sum_a,sum_b
print "Comparision Returns:",cmp(sum_a,sum_b)
return cmp(sum_a,sum_b)
items.sort(myComparator)
print items
This is what the output that I get after running above:
Values(a,b): ((3, [1, 0, 0, 0, 1]), (2, [3, 4, 5]))
2 12
Comparision Returns: -1
Values(a,b): ((4, [-1]), (3, [1, 0, 0, 0, 1]))
-1 2
Comparision Returns: -1
Values(a,b): ((10, [1, 2, 3]), (4, [-1]))
6 -1
Comparision Returns: 1
Values(a,b): ((10, [1, 2, 3]), (3, [1, 0, 0, 0, 1]))
6 2
Comparision Returns: 1
Values(a,b): ((10, [1, 2, 3]), (2, [3, 4, 5]))
6 12
Comparision Returns: -1
[(4, [-1]), (3, [1, 0, 0, 0, 1]), (10, [1, 2, 3]), (2, [3, 4, 5])]
Now I am unable to understand as to how the comparator is working, which two values are being passed and how many such comparisons would happen? Is it creating a sorted list of keys internally where it keeps track of each comparison made? Also the behavior seems to be very random. I am confused, any help would be appreciated.
The number and which comparisons are done is not documented and in fact, it can freely change from different implementations. The only guarantee is that if the comparison function makes sense the method will sort the list.
CPython uses the Timsort algorithm to sort lists, so what you see is the order in which that algorithm is performing the comparisons (if I'm not mistaken for very short lists Timsort just uses insertion sort)
Python is not keeping track of "keys". It just calls your comparison function every time a comparison is made. So your function can be called many more than len(items) times.
If you want to use keys you should use the key argument. In fact you could do:
items.sort(key=lambda x: sum(x[1]))
This will create the keys and then sort using the usual comparison operator on the keys. This is guaranteed to call the function passed by key only len(items) times.
Given that your list is:
[a,b,c,d]
The sequence of comparisons you are seeing is:
b < a # -1 true --> [b, a, c, d]
c < b # -1 true --> [c, b, a, d]
d < c # 1 false
d < b # 1 false
d < a # -1 true --> [c, b, d, a]
how the comparator is working
This is well documented:
Compare the two objects x and y and return an integer according to the outcome. The return value is negative if x < y, zero if x == y and strictly positive if x > y.
Instead of calling the cmp function you could have written:
sum_a=sum(a[1])
sum_b=sum(b[1])
if sum_a < sum_b:
return -1
elif sum_a == sum_b:
return 0
else:
return 1
which two values are being passed
From your print statements you can see the two values that are passed. Let's look at the first iteration:
((3, [1, 0, 0, 0, 1]), (2, [3, 4, 5]))
What you are printing here is a tuple (a, b), so the actual values passed into your comparison functions are
a = (3, [1, 0, 0, 0, 1])
b = (2, [3, 4, 5]))
By means of your function, you then compare the sum of the two lists in each tuple, which you denote sum_a and sum_b in your code.
and how many such comparisons would happen?
I guess what you are really asking: How does the sort work, by just calling a single function?
The short answer is: it uses the Timsort algorithm, and it calls the comparison function O(n * log n) times (note that the actual number of calls is c * n * log n, where c > 0).
To understand what is happening, picture yourself sorting a list of values, say v = [4,2,6,3]. If you go about this systematically, you might do this:
start at the first value, at index i = 0
compare v[i] with v[i+1]
If v[i+1] < v[i], swap them
increase i, repeat from 2 until i == len(v) - 2
start at 1 until no further swaps occurred
So you get, i =
0: 2 < 4 => [2, 4, 6, 3] (swap)
1: 6 < 4 => [2, 4, 6, 3] (no swap)
2: 3 < 6 => [2, 4, 3, 6] (swap)
Start again:
0: 4 < 2 => [2, 4, 3, 6] (no swap)
1: 3 < 4 => [2, 3, 4, 6] (swap)
2: 6 < 4 => [2, 3, 4, 6] (no swap)
Start again - there will be no further swaps, so stop. Your list is sorted. In this example we have run through the list 3 times, and there were 3 * 3 = 9 comparisons.
Obviously this is not very efficient -- the sort() method only calls your comparator function 5 times. The reason is that it employs a more efficient sort algorithm than the simple one explained above.
Also the behavior seems to be very random.
Note that the sequence of values passed to your comparator function is not, in general, defined. However, the sort function does all the necessary comparisons between any two values of the iterable it receives.
Is it creating a sorted list of keys internally where it keeps track of each comparison made?
No, it is not keeping a list of keys internally. Rather the sorting algorithm essentially iterates over the list you give it. In fact it builds subsets of lists to avoid doing too many comparisons - there is a nice visualization of how the sorting algorithm works at Visualising Sorting Algorithms: Python's timsort by Aldo Cortesi
Basically, for the simple list such as [2, 4, 6, 3, 1] and the complex list you provided, the sorting algorithms are the same.
The only differences are the complexity of elements in the list and the comparing scheme that how to compare any tow elements (e.g. myComparator you provided).
There is a good description for Python Sorting: https://wiki.python.org/moin/HowTo/Sorting
First, the cmp() function:
cmp(...)
cmp(x, y) -> integer
Return negative if x<y, zero if x==y, positive if x>y.
You are using this line: items.sort(myComparator) which is equivalent to saying: items.sort(-1) or items.sort(0) or items.sort(1)
Since you want to sort based on the sum of each tuples list, you could do this:
mylist = [(2, [3, 4, 5]), (3, [1, 0, 0, 0, 1]), (4, [-1]), (10, [1, 2, 3])]
sorted(mylist, key=lambda pair: sum(pair[1]))
What this is doing is, I think, exactly what you wanted. Sorting mylist based on the sum() of each tuples list
Lets say I have a list of numbers [1, 2, 3, ..., 100]. Now I want to select numbers from the list where each number is either accepted or rejected with a given probability 0 < p < 1 . The accepted numbers are then stored in a separate list. How can I do that?
The main problem is choosing the number with probability p. Is there an inbuilt function for that?
The value of p is given by the user.
You can use random.random() and a list comprehension:
import random
l = [1,2,3,4,5,6,7,8,9]
k = [x for x in l if random.random() > 0.23] # supply user input value here as 0.23
print(l)
print(k)
Output:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
[2, 3, 4, 5, 6, 7]
to check each element of the list if it has a probability of > 0.23 of staying in the list.
Sidenote:
random.choices() has the ability to accept weights:
random.choices(population, weights=None, *, cum_weights=None, k=1)
but those only change the probability inside the given list for drawing one of the elements (absolute or relative weights are possible) - thats not working for "independent" probabilities though.
I am trying to write a python 3 function that finds all numbers in a list (unspecified length) that are not part of a pair.
For example, given the list [1, 2, 1, 3, 2], the function will return 3; and given the list [0, 1, 1, 7, 8, 3, 9, 3, 9], the function will return 0, 7, and 8.
Thanks for your help!
You can use the following function :
>>> def find(l):
... return (i for i in l if l.count(i)==1)
>>> l= [0, 1, 1, 7, 8, 3, 9, 3, 9]
>>> list(find(l))
[0, 7, 8]
This function will return a generator that is contain the elements in list which those count is equal to 1.
I can tell you how I would do it. What does it mean a "pair"?
You should say, find all the numbers repeated oddly in the array.
First plan: (more efficient!)
Sort the list and then a single loop through your list should be enough to find how many numbers of each there are inside and you can generate awhile another list that you will return.
Second plan (nicer in python, but also more expensive because of the number of evaluations though the hole list):
Try the solution of Kasra. 'count' function from 'list' type helps our code but not our efficiency. It counts the number of times that appears the value 'i' on the list 'l', obviously.
If the pair need to be "closed pair" I mean, if you have three 1 (ones), do you have one pair and one single 1? or do you have all the 1 paired? If the second one, the solution of Kasra is Ok. Else you should compare:
if l.count(i) % 2 == 1
This can be easily and efficiently done in 3 lines with collections.Counter.
from collections import Counter
def unpaired(numbers):
for key, count in Counter(numbers).items():
if count % 2:
yield key
print(list(unpaired([1, 2, 1, 3, 2])))
# [3]
print(list(unpaired([0, 1, 1, 7, 8, 3, 9, 3, 9])))
# [0, 7, 8]
My answer comport if you have three equals numbers or if you have one pair and one single number without pair.
def name(array):
o = sorted(array)
c = []
d = []
for i in o:
if o.count(i) % 2 == 1:
c.append(i)
for j in c:
if j not in d:
d.append(j)
return d
or do not use for j in c and use directly:
return list(set(c))
for example:
array = [0, 1, 1, 7, 8, 3, 9, 3, 9, 9]
output: [0, 7, 8, 9]