Parsing custom binary function in sympy - python-3.x

I have a string that represents a function, for example
1 + x - 2^x
I am aware I can use sympy to parse this expression with parse_expr.
Suppose now I have another expression with a binary operator not currently in the grammar, for example
1 + x my_custom_operator 2^x
Which should yield
1 + my_custom_operator(x, 2^x)
where my_custom_operator(a, b) = min(a, b)
Is there a way to parse this in sympy or an alternative means. The true expression is far more complicated, so no regex allowed due to things like nested parenthesis.

Related

List comprehension in haskell with let and show, what is it for?

I'm studying project euler solutions and this is the solution of problem 4, which asks to
Find the largest palindrome made from the product of two 3-digit
numbers
problem_4 =
maximum [x | y<-[100..999], z<-[y..999], let x=y*z, let s=show x, s==reverse s]
I understand that this code creates a list such that x is a product of all possible z and y.
However I'm having a problem understanding what does s do here. Looks like everything after | is going to be executed everytime a new element from this list is needed, right?
I don't think I understand what's happening here. Shouldn't everything to the right of | be constraints?
A list comprehension is a rather thin wrapper around a do expression:
problem_4 = maximum $ do
y <- [100..999]
z <- [y..999]
let x = y*z
let s = show x
guard $ s == reverse s
return x
Most pieces translate directly; pieces that aren't iterators (<-) or let expressions are treated as arguments to the guard function found in Control.Monad. The effect of guard is to short-circuit the evaluation; for the list monad, this means not executing return x for the particular value of x that led to the false argument.
I don't think I understand what's happening here. Shouldn't everything to the right of | be constraints?
No, at the right part you see an expression that is a comma-separated (,) list of "parts", and every part is one of the following tree:
an "generator" of the form somevar <- somelist;
a let statement which is an expression that can be used to for instance introduce a variable that stores a subresult; and
expressions of the type boolean that act like a filter.
So it is not some sort of "constraint programming" where one simply can list some constraints and hope that Haskell figures it out (in fact personally that is the difference between a "programming language" and a "specification language": in a programming language you have "control" how the data flows, in a specification language, that is handled by a system that reads your specifications)
Basically an iterator can be compared to a "foreach" loop in many imperative programming languages. A "let" statement can be seen as introducing a temprary variable (but note that in Haskell you do not assign variable, you declare them, so you can not reassign values). The filter can be seen as an if statement.
So the list comprehension would be equivalent to something in Python like:
for y in range(100, 1000):
for z in range(y, 1000):
x = y * z
s = str(x)
if x == x[::-1]:
yield x
We thus first iterate over two ranges in a nested way, then we declare x to be the multiplication of y and z, with let s = show x, we basically convert a number (for example 15129) to its string counterpart (for example "15129"). Finally we use s == reverse s to reverse the string and check if it is equal to the original string.
Note that there are more efficient ways to test Palindromes, especially for multiplications of two numbers.

Haskell Add-Operation

In a Codefights challenge where you have to add two numbers the user kaiochao had a super minimalisic answer
add = (+)
How does it work and has this functionality a own name?
Here's an explicit definition:
add a b = a + b
There is a feature in Haskell that says that we can rewrite a + b as (+) a b, this is due to the fact that operators are functions in Haskell. So we can rewrite:
add a b = (+) a b
But then we're doing nothing extra to the arguments of this function, so we can reduce this function by removing the explicit arguments*. Note that this requires an understanding of how function application in Haskell works:
add = (+)
This is because functions are data in Haskell. This is literally saying that plus and the function of addition are the same thing.
In practice, we can see this by substituting:
add 1 2
= (+) 1 2 -- Since add = (+), this can be read literally.
= 1 + 2 -- This is how operators work in Haskell.
= 3 -- Calculation.
This is known as pointfree style in Haskell.
*As #Benjamin Hodgson mentioned, this is called eta-reduction.
This “functionality” is just variable assignment. It works the same way as writing
three = 3
3 is just a Haskell value, which I can at any point give a new name, refer to it, and get something that's (at least, at runtime) indistinguishable from 3 itself.
The fact that add has a somewhat more complicated type, namely a function type, changes nothing about the way such variable assignments work. I can certainly define
root = sqrt
...and then evaluate root 4 to obtain 2.0 as the result. Or, for any custom function,
foo :: Int -> String
foo n = concat $ replicate n (show n)
bar = foo
GHCi> bar 3
"333"
GHCi> bar 7
"7777777"
All that is really no different from how I can also write
Python 3.5.2 (default, Sep 14 2017, 22:51:06)
Type 'copyright', 'credits' or 'license' for more information
IPython 6.1.0 -- An enhanced Interactive Python. Type '?' for help.
In [1]: import math
In [2]: root = math.sqrt
In [3]: root(4)
Out[3]: 2.0
What's a bit more interesting about add is that + is an infix operator (because it consists of non-letter characters). But Haskell allows using such infix operators pretty much just as liberally as any other variables, including that you can define your own. The only thing that's a bit different are the parsing rules. + can not be a standalone syntactic unit but has to be surrounded on each side with with arguments you want to add, or with parentheses. The latter, (+), is really what the plus operator is from the compiler's point of view: the binary function, not yet applied to any arguments. So, when you want to give this operator a new name, you need to write
add = (+)
Incidentally, you could also give it a new operator-name, like
(⊕) = (+)
...that could then be used like 3 ⊕ 4, just as you can with the standard + operator.

What is this expression in Haskell, and how do I interpret it?

I'm learning basic Haskell so I can configure Xmonad, and I ran into this code snippet:
newKeys x = myKeys x `M.union` keys def x
Now I understand what the M.union in backticks is and means. Here's how I'm interpreting it:
newKeys(x) = M.union(myKeys(x),???)
I don't know what to make of the keys def x. Is it like keys(def(x))? Or keys(def,x)? Or is def some sort of other keyword?
It's keys(def,x).
This is basic Haskell syntax for function application: first the function itself, then its arguments separated by spaces. For example:
f x y = x + y
z = f 5 6
-- z = 11
However, it is not clear what def is without larger context.
In response to your comment: no, def couldn't be a function that takes x as argument, and then the result of that is passed to keys. This is because function application is left-associative, which basically means that in any bunch of things separated by spaces, only the first one is the function being applied, and the rest are its arguments. In order to express keys(def(x)), one would have to write keys (def x).
If you want to be super technical, then the right way to think about it is that all functions have exactly one parameter. When we declare a function of two parameters, e.g. f x y = x + y, what we really mean is that it's a function of one parameter, which returns another function, to which we can then pass the remaining parameter. In other words, f 5 6 means (f 5) 6.
This idea is kind of one of the core things in Haskell (and any ML offshoot) syntax. It's so important that it has its own name - "currying" (after Haskell Curry, the mathematician).

Conversion from decimal to binary in Ocaml

I am trying to convert a given decimal value its corresponding binary form. I am using Ocaml about which I don't know much and am quite confused. So far I have the following code
let dec_to_bin_helper function 1->'T' | 0->'F'
let dec_to_bin x =
List.fold_left(fun a z -> z mod 2 dec_to_bin_helper a) [] a ;;
I must include here that I want my output to be in the form of a list of T's and F's where T's represent the binary 1's and F's represent binary 0's
If I try to run the above code it gives me an error saying "Error: This expression is not a function; it cannot be applied"
I understand that the part where I am calling the helper function is wrong... Any help in the matter would be appreciated!
I don't really understand your second function at all. You are folding an empty list, and your function takes an argument x which it never uses. Am I correct in assuming that you want to take a number and return a list of 'T's and 'F's which represent the binary? If that is the case, this code should work:
let dec_to_bin x =
let rec d2b y lst = match y with 0 -> lst
| _ -> d2b (y/2) ((dec_to_bin_helper (y mod 2))::lst)
in
d2b x [];;
This function inserts (x mod 2) converted into a T/F into a list, then recursively calls the function on x/2 and the list. When x = 0 the list is returned. If call it on 0 an empty list will be returned (I'm not sure if that's what you want or not).
I think the problem that you had is that you are treating lists as if they are mutable and thinking that fold mutates the list. That is not the case, fold just goes through each element in a list and applies a function to it. Since your list is empty it didn't do anything.

Why doesn't my Haskell function accept negative numbers?

I am fairly new to Haskell but do get most of the basics. However there is one thing that I just cannot figure out. Consider my example below:
example :: Int -> Int
example (n+1) = .....
The (n+1) part of this example somehow prevents the input of negative numbers but I cannot understand how. For example.. If the input were (-5) I would expect n to just be (-6) since (-6 + 1) is (-5). The output when testing is as follows:
Program error: pattern match failure: example (-5)
Can anyone explain to me why this does not accept negative numbers?
That's just how n+k patterns are defined to work:
Matching an n+k pattern (where n is a variable and k is a positive integer literal) against a value v succeeds if x >= k, resulting in the binding of n to x - k, and fails otherwise.
The point of n+k patterns is to perform induction, so you need to complete the example with a base case (k-1, or 0 in this case), and decide whether a parameter less than that would be an error or not. Like this:
example (n+1) = ...
example 0 = ...
The semantics that you're essentially asking for would be fairly pointless and redundant — you could just say
example n = let n' = n-1 in ...
to achieve the same effect. The point of a pattern is to fail sometimes.

Resources