Cannot give Idris proof with function which uses SnocList - proof

I have the following function which uses SnocList
import Data.List.Views
takeLast : (n : Nat) -> List a -> List a
takeLast n xs with (snocList xs)
takeLast Z [] | Empty = []
takeLast Z (ys ++ [x]) | (Snoc rec) = []
takeLast (S k) [] | Empty = []
takeLast (S k) (ys ++ [x]) | (Snoc rec) = takeLast k ys ++ [x] | rec
It takes the last n elements from the given List. I want to so that it is equivalent to the following function.
takeLast' : (n : Nat) -> (xs : List a) -> List a
takeLast' n xs = reverse $ take n $ reverse xs
When I try the following example proof
takeLastsAreEquivalent : takeLast' 2 [1, 2, 3] = takeLast 2 [1, 2, 3]
takeLastsAreEquivalent = Refl
I get the following error from the type checker.
When checking right hand side of takeLastsAreEquivalent with expected type
takeLast' 2 [1, 2, 3] = takeLast 2 [1, 2, 3]
Type mismatch between
with block in Main.takeLast Integer 2 [1, 2, 3] (snocList [1, 2, 3]) =
with block in Main.takeLast Integer 2 [1, 2, 3] (snocList [1, 2, 3]) (Type of Refl)
and
[2, 3] = with block in Main.takeLast Integer 2 [1, 2, 3] (snocList [1, 2, 3]) (Expected type)
Specifically:
Type mismatch between
with block in Main.takeLast Integer 2 [1, 2, 3] (snocList [1, 2, 3])
and
[2, 3]
Holes: Main.takeLastsAreEquivalent
When I run these in the REPL everything seems fine.
*/Example> takeLast' 2 [1, 2, 3]
[2, 3] : List Integer
*/Example> :t takeLast' 2 [1, 2, 3]
takeLast' 2 [1, 2, 3] : List Integer
*/Example> takeLast 2 [1, 2, 3]
[2, 3] : List Integer
*/Example> :t takeLast 2 [1, 2, 3]
takeLast 2 [1, 2, 3] : List Integer
I know this not an actual proof but I just want to show how these work for an example I am working on.

Related

lambda function and sets

I need to remove all elements from set that satisfy the lambda function, is there a way to make it continue when the fisrt part of the statement returns error?
f = lambda x : x < "t" or x % 2 == 0
s = {"a", 2, "u", 4, 3}
def sort(fun, s):
l = []
for element in s:
try:
if (fun(element)) == True:
l.append(element)
except:
pass
for element in l:
s.remove(element)
my code returns:
s = {2, 3, 4, 'u'}
but I need it to return:
s = { 3, 'u'}
Maybe you can adjust a lambda function to check the type of the element.
Also, to remove values from set use set-comprehension:
f = lambda x: (isinstance(x, str) and x < "t") or (
isinstance(x, int) and x % 2 == 0
)
s = {"a", 2, "u", 4, 3}
s = {v for v in s if not f(v)}
print(s)
Prints:
{'u', 3}

Problems with sub2ind function in Octave

I am new to Octave, so I was reading documentation and I found sub2ind function. I started to test it, but sometimes it works weird or I just don't understand how it must work.
So this is how subscripts must be converted to linear indices. (Example from documentation)
[(1,1), (1,2), (1,3)] [1, 4, 7]
[(2,1), (2,2), (2,3)] ==> [2, 5, 8]
[(3,1), (3,2), (3,3)] [3, 6, 9]
And this is another example from documentation
s1 = [2, 2];
s2 = [1, 3];
ind = sub2ind ([3, 3], s1, s2)
⇒ ind = 2 8
So if we look at the first example the (2, 2) == 5, but second example says [2, 2] == 2.
The (1, 3) has different results too.
Practically It works as the second example shows.
If I try to use this function with only 1 pair it return the same pair
sub2ind([3, 3], [2, 2])
# ans = [2, 2]
In this test I can't see any relation between input and output
sub2ind([3, 3], [2, 2], [3, 3])
# ans = [8, 8]
Function works this strange(maybe not) way only when it gets 1 pair or when one of pairs is pair kind [x, x](two same values).
But otherwise it works fine, so this test returns that it should:
sub2ind([3, 3], [2, 1], [1, 3])
# ans = [2, 7]
Also it works fine when this variant is used sub2ind (dims, i, j).
How does the function works?
You misunderstand the input format.
Change
s1 = [2, 2];
s2 = [1, 3];
ind = sub2ind ([3, 3], s1, s2)
⇒ ind = 2 8
to this:
row = [2, 2]; % x1 and x2
col = [1, 3]; % y1 and y2
ind = sub2ind ([3, 3], row, col)
⇒ ind = 2 8
You have two inputs that you convert to linear indices:
[x1, y1] = [2, 1] = 2 and [x2 y2] = [2, 3] = 8.
This:
sub2ind([3, 3], [2, 2])
# ans = [2, 2]
appears to be equivalent to:
sub2ind([3, 3], [2, 2], [1, 1])
even though it's not in the documentation.

Define a polynomial function in Julia

I want to create the function using Polynomials package in Julia, while c is a Vector and n is the length of the Vector. I can make it in JuMP package but not in Polynomials.
Any idea how to create this function?
Just call Polynomial on this vector c.
julia> c = [1, 2, 3, 4]
4-element Vector{Int64}:
1
2
3
4
julia> p = Polynomial(c)
Polynomial(1 + 2*x + 3*x^2 + 4*x^3)
julia> c = [2, 4, -8, 0, 0, 1];
julia> p = Polynomial(c)
Polynomial(2 + 4*x - 8*x^2 + x^5)
julia> p(2) #evaluate the polynomial at x = 2
10

How many elements from one list are present in the other list

I can't seem to be able to create a function that takes two lists as arguments and returns how many elements there are common in both lists.
e.g. f [1, 2, 4, 2] [2, 3, 4, 4] returning 2 (repetitions are ignored).
Any suggestions? I tried this
*Main> a = [1, 2, 3]
*Main> b = [2, 3, 4]
*Main> [x | x <- a, x <- b]
[2,3,4,2,3,4,2,3,4]
Then I was planning to use the length function to know how many item there are in common.
You don't want to extract an x from both lists; extract from one list, and check if it is present in the other.
> a = [1,2,3]
> b = [4,3,2]
> [x | x <- a, x `elem` b]
[2,3]
> [x | x <- b, x `elem` a]
[3,2]
Note that the order in which items appear in the result depends on the order in which they appear in the list you pull from.

Modifying global variable from within function that have the same parameter name in python

I have this function:
def applychange(L):
result=3+2
L=[4,5,6]
return result
L = [1,2,3]
print(applychange(L))
print(L)
and the result is :
5
[1, 2, 3]
how to change the L variable to new value to have this result:
5
[4, 5, 6]
If your goal is to modify L as global variable you need to declare it as such.
For your code to run as intended, insert global L after the result assignment in your function.
Additionally, there is no need to pass L to the function in order to modify L.
def applychange():
result = 3 + 2
global L
L = [4, 5, 6]
return result
L = [1, 2, 3]
print(applychange())
print(L)
Your code written this way will result in the intended output:
5
[4, 5, 6]
The problem is that you overwrite the variable L, instead of modifying it. You can use
L[:] = [4,5,6]
instead of
L = [4,5,6]