In pure functional languages like Haskell, is there an algorithm to get the inverse of a function, (edit) when it is bijective? And is there a specific way to program your function so it is?
In some cases, yes! There's a beautiful paper called Bidirectionalization for Free! which discusses a few cases -- when your function is sufficiently polymorphic -- where it is possible, completely automatically to derive an inverse function. (It also discusses what makes the problem hard when the functions are not polymorphic.)
What you get out in the case your function is invertible is the inverse (with a spurious input); in other cases, you get a function which tries to "merge" an old input value and a new output value.
No, it's not possible in general.
Proof: consider bijective functions of type
type F = [Bit] -> [Bit]
with
data Bit = B0 | B1
Assume we have an inverter inv :: F -> F such that inv f . f ≡ id. Say we have tested it for the function f = id, by confirming that
inv f (repeat B0) -> (B0 : ls)
Since this first B0 in the output must have come after some finite time, we have an upper bound n on both the depth to which inv had actually evaluated our test input to obtain this result, as well as the number of times it can have called f. Define now a family of functions
g j (B1 : B0 : ... (n+j times) ... B0 : ls)
= B0 : ... (n+j times) ... B0 : B1 : ls
g j (B0 : ... (n+j times) ... B0 : B1 : ls)
= B1 : B0 : ... (n+j times) ... B0 : ls
g j l = l
Clearly, for all 0<j≤n, g j is a bijection, in fact self-inverse. So we should be able to confirm
inv (g j) (replicate (n+j) B0 ++ B1 : repeat B0) -> (B1 : ls)
but to fulfill this, inv (g j) would have needed to either
evaluate g j (B1 : repeat B0) to a depth of n+j > n
evaluate head $ g j l for at least n different lists matching replicate (n+j) B0 ++ B1 : ls
Up to that point, at least one of the g j is indistinguishable from f, and since inv f hadn't done either of these evaluations, inv could not possibly have told it apart – short of doing some runtime-measurements on its own, which is only possible in the IO Monad.
⬜
You can look it up on wikipedia, it's called Reversible Computing.
In general you can't do it though and none of the functional languages have that option. For example:
f :: a -> Int
f _ = 1
This function does not have an inverse.
Not in most functional languages, but in logic programming or relational programming, most functions you define are in fact not functions but "relations", and these can be used in both directions. See for example prolog or kanren.
Tasks like this are almost always undecidable. You can have a solution for some specific functions, but not in general.
Here, you cannot even recognize which functions have an inverse. Quoting Barendregt, H. P. The Lambda Calculus: Its Syntax and Semantics. North Holland, Amsterdam (1984):
A set of lambda-terms is nontrivial if it is neither the empty nor the full set. If A and B are two nontrivial, disjoint sets of lambda-terms closed under (beta) equality, then A and B are recursively inseparable.
Let's take A to be the set of lambda terms that represent invertible functions and B the rest. Both are non-empty and closed under beta equality. So it's not possible to decide whether a function is invertible or not.
(This applies to the untyped lambda calculus. TBH I don't know if the argument can be directly adapted to a typed lambda calculus when we know the type of a function that we want to invert. But I'm pretty sure it will be similar.)
If you can enumerate the domain of the function and can compare elements of the range for equality, you can - in a rather straightforward way. By enumerate I mean having a list of all the elements available. I'll stick to Haskell, since I don't know Ocaml (or even how to capitalise it properly ;-)
What you want to do is run through the elements of the domain and see if they're equal to the element of the range you're trying to invert, and take the first one that works:
inv :: Eq b => [a] -> (a -> b) -> (b -> a)
inv domain f b = head [ a | a <- domain, f a == b ]
Since you've stated that f is a bijection, there's bound to be one and only one such element. The trick, of course, is to ensure that your enumeration of the domain actually reaches all the elements in a finite time. If you're trying to invert a bijection from Integer to Integer, using [0,1 ..] ++ [-1,-2 ..] won't work as you'll never get to the negative numbers. Concretely, inv ([0,1 ..] ++ [-1,-2 ..]) (+1) (-3) will never yield a value.
However, 0 : concatMap (\x -> [x,-x]) [1..] will work, as this runs through the integers in the following order [0,1,-1,2,-2,3,-3, and so on]. Indeed inv (0 : concatMap (\x -> [x,-x]) [1..]) (+1) (-3) promptly returns -4!
The Control.Monad.Omega package can help you run through lists of tuples etcetera in a good way; I'm sure there's more packages like that - but I don't know them.
Of course, this approach is rather low-brow and brute-force, not to mention ugly and inefficient! So I'll end with a few remarks on the last part of your question, on how to 'write' bijections. The type system of Haskell isn't up to proving that a function is a bijection - you really want something like Agda for that - but it is willing to trust you.
(Warning: untested code follows)
So can you define a datatype of Bijection s between types a and b:
data Bi a b = Bi {
apply :: a -> b,
invert :: b -> a
}
along with as many constants (where you can say 'I know they're bijections!') as you like, such as:
notBi :: Bi Bool Bool
notBi = Bi not not
add1Bi :: Bi Integer Integer
add1Bi = Bi (+1) (subtract 1)
and a couple of smart combinators, such as:
idBi :: Bi a a
idBi = Bi id id
invertBi :: Bi a b -> Bi b a
invertBi (Bi a i) = (Bi i a)
composeBi :: Bi a b -> Bi b c -> Bi a c
composeBi (Bi a1 i1) (Bi a2 i2) = Bi (a2 . a1) (i1 . i2)
mapBi :: Bi a b -> Bi [a] [b]
mapBi (Bi a i) = Bi (map a) (map i)
bruteForceBi :: Eq b => [a] -> (a -> b) -> Bi a b
bruteForceBi domain f = Bi f (inv domain f)
I think you could then do invert (mapBi add1Bi) [1,5,6] and get [0,4,5]. If you pick your combinators in a smart way, I think the number of times you'll have to write a Bi constant by hand could be quite limited.
After all, if you know a function is a bijection, you'll hopefully have a proof-sketch of that fact in your head, which the Curry-Howard isomorphism should be able to turn into a program :-)
I've recently been dealing with issues like this, and no, I'd say that (a) it's not difficult in many case, but (b) it's not efficient at all.
Basically, suppose you have f :: a -> b, and that f is indeed a bjiection. You can compute the inverse f' :: b -> a in a really dumb way:
import Data.List
-- | Class for types whose values are recursively enumerable.
class Enumerable a where
-- | Produce the list of all values of type #a#.
enumerate :: [a]
-- | Note, this is only guaranteed to terminate if #f# is a bijection!
invert :: (Enumerable a, Eq b) => (a -> b) -> b -> Maybe a
invert f b = find (\a -> f a == b) enumerate
If f is a bijection and enumerate truly produces all values of a, then you will eventually hit an a such that f a == b.
Types that have a Bounded and an Enum instance can be trivially made RecursivelyEnumerable. Pairs of Enumerable types can also be made Enumerable:
instance (Enumerable a, Enumerable b) => Enumerable (a, b) where
enumerate = crossWith (,) enumerate enumerate
crossWith :: (a -> b -> c) -> [a] -> [b] -> [c]
crossWith f _ [] = []
crossWith f [] _ = []
crossWith f (x0:xs) (y0:ys) =
f x0 y0 : interleave (map (f x0) ys)
(interleave (map (flip f y0) xs)
(crossWith f xs ys))
interleave :: [a] -> [a] -> [a]
interleave xs [] = xs
interleave [] ys = []
interleave (x:xs) ys = x : interleave ys xs
Same goes for disjunctions of Enumerable types:
instance (Enumerable a, Enumerable b) => Enumerable (Either a b) where
enumerate = enumerateEither enumerate enumerate
enumerateEither :: [a] -> [b] -> [Either a b]
enumerateEither [] ys = map Right ys
enumerateEither xs [] = map Left xs
enumerateEither (x:xs) (y:ys) = Left x : Right y : enumerateEither xs ys
The fact that we can do this both for (,) and Either probably means that we can do it for any algebraic data type.
Not every function has an inverse. If you limit the discussion to one-to-one functions, the ability to invert an arbitrary function grants the ability to crack any cryptosystem. We kind of have to hope this isn't feasible, even in theory!
In some cases, it is possible to find the inverse of a bijective function by converting it into a symbolic representation. Based on this example, I wrote this Haskell program to find inverses of some simple polynomial functions:
bijective_function x = x*2+1
main = do
print $ bijective_function 3
print $ inverse_function bijective_function (bijective_function 3)
data Expr = X | Const Double |
Plus Expr Expr | Subtract Expr Expr | Mult Expr Expr | Div Expr Expr |
Negate Expr | Inverse Expr |
Exp Expr | Log Expr | Sin Expr | Atanh Expr | Sinh Expr | Acosh Expr | Cosh Expr | Tan Expr | Cos Expr |Asinh Expr|Atan Expr|Acos Expr|Asin Expr|Abs Expr|Signum Expr|Integer
deriving (Show, Eq)
instance Num Expr where
(+) = Plus
(-) = Subtract
(*) = Mult
abs = Abs
signum = Signum
negate = Negate
fromInteger a = Const $ fromIntegral a
instance Fractional Expr where
recip = Inverse
fromRational a = Const $ realToFrac a
(/) = Div
instance Floating Expr where
pi = Const pi
exp = Exp
log = Log
sin = Sin
atanh = Atanh
sinh = Sinh
cosh = Cosh
acosh = Acosh
cos = Cos
tan = Tan
asin = Asin
acos = Acos
atan = Atan
asinh = Asinh
fromFunction f = f X
toFunction :: Expr -> (Double -> Double)
toFunction X = \x -> x
toFunction (Negate a) = \a -> (negate a)
toFunction (Const a) = const a
toFunction (Plus a b) = \x -> (toFunction a x) + (toFunction b x)
toFunction (Subtract a b) = \x -> (toFunction a x) - (toFunction b x)
toFunction (Mult a b) = \x -> (toFunction a x) * (toFunction b x)
toFunction (Div a b) = \x -> (toFunction a x) / (toFunction b x)
with_function func x = toFunction $ func $ fromFunction x
simplify X = X
simplify (Div (Const a) (Const b)) = Const (a/b)
simplify (Mult (Const a) (Const b)) | a == 0 || b == 0 = 0 | otherwise = Const (a*b)
simplify (Negate (Negate a)) = simplify a
simplify (Subtract a b) = simplify ( Plus (simplify a) (Negate (simplify b)) )
simplify (Div a b) | a == b = Const 1.0 | otherwise = simplify (Div (simplify a) (simplify b))
simplify (Mult a b) = simplify (Mult (simplify a) (simplify b))
simplify (Const a) = Const a
simplify (Plus (Const a) (Const b)) = Const (a+b)
simplify (Plus a (Const b)) = simplify (Plus (Const b) (simplify a))
simplify (Plus (Mult (Const a) X) (Mult (Const b) X)) = (simplify (Mult (Const (a+b)) X))
simplify (Plus (Const a) b) = simplify (Plus (simplify b) (Const a))
simplify (Plus X a) = simplify (Plus (Mult 1 X) (simplify a))
simplify (Plus a X) = simplify (Plus (Mult 1 X) (simplify a))
simplify (Plus a b) = (simplify (Plus (simplify a) (simplify b)))
simplify a = a
inverse X = X
inverse (Const a) = simplify (Const a)
inverse (Mult (Const a) (Const b)) = Const (a * b)
inverse (Mult (Const a) X) = (Div X (Const a))
inverse (Plus X (Const a)) = (Subtract X (Const a))
inverse (Negate x) = Negate (inverse x)
inverse a = inverse (simplify a)
inverse_function x = with_function inverse x
This example only works with arithmetic expressions, but it could probably be generalized to work with lists as well. There are also several implementations of computer algebra systems in Haskell that may be used to find the inverse of a bijective function.
No, not all functions even have inverses. For instance, what would the inverse of this function be?
f x = 1
Im pretty much new to Haskell, so if Im missing key concept, please point it out.
Lets say we have these two functions:
fact n
| n == 0 = 1
| n > 0 = n * (fact (n - 1))
The polymorphic type for fact is (Eq t, Num t) => t -> t Because n is used in the if condition and n must be of valid type to do the == check. Therefor t must be a Number and t can be of any type within class constraint Eq t
fib n
| n == 1 = 1
| n == 2 = 1
| n > 2 = fib (n - 1) + fib (n - 2)
Then why is the polymorphic type of fib is (Eq a, Num a, Num t) => a -> t?
I don't understand, please help.
Haskell always aims to derive the most generic type signature.
Now for fact, we know that the type of the output, should be the same as the type of the input:
fact n | n == 0 = 1
| n > 0 = n * (fact (n - 1))
This is due to the last line. We use n * (fact (n-1)). So we use a multiplication (*) :: a -> a -> a. Multiplication thus takes two members of the same type and returns a member of that type. Since we multiply with n, and n is input, the output is of the same type as the input. Since we use n == 0, we know that (==) :: Eq a => a -> a -> Bool so that means that that input type should have Eq a =>, and furthermore 0 :: Num a => a. So the resulting type is fact :: (Num a, Eq a) => a -> a.
Now for fib, we see:
fib n | n == 1 = 1
| n == 2 = 1
| n > 2 = fib (n - 1) + fib (n - 2)
Now we know that for n, the type constraints are again Eq a, Num a, since we use n == 1, and (==) :: Eq a => a -> a -> Bool and 1 :: Num a => a. But the input n is never directly used in the output. Indeed, the last line has fib (n-1) + fib (n-2), but here we use n-1 and n-2 as input of a new call. So that means we can safely asume that the input type and the output type act independently. The output type, still has a type constraint: Num t: this is since we return 1 for the first two cases, and 1 :: Num t => t, and we also return the addition of two outputs: fib (n-1) + fib (n-2), so again (+) :: Num t => t -> t -> t.
The difference is that in fact, you use the argument directly in an arithmetic expression which makes up the final result:
fact n | ... = n * ...
IOW, if you write out the expanded arithmetic expression, n appears in it:
fact 3 ≡ n * (n-1) * (n-2) * 1
This fixes that the argument must have the same type as the result, because
(*) :: Num n => n -> n -> n
Not so in fib: here the actual result is only composed of literals and of sub-results. IOW, the expanded expression looks like
fib 3 ≡ (1 + 1) + 1
No n in here, so no unification between argument and result required.
Of course, in both cases you also used n to decide how this arithmetic expression looks, but for that you've just used equality comparisons with literals, whose type is not connected to the final result.
Note that you can also give fib a type-preservig signature: (Eq a, Num a, Num t) => a -> t is strictly more general than (Eq t, Num t) => t -> t. Conversely, you can make a fact that doesn't require input- and output to be the same type, by following it with a conversion function:
fact' :: (Eq a, Integral a, Num t) => a -> t
fact' = fromIntegral . fact
This doesn't make a lot of sense though, because Integer is pretty much the only type that can reliably be used in fact, but to achieve that in the above version you need to start out with Integer. Hence if anything, you should do the following:
fact'' :: (Eq t, Integral a, Num t) => a -> t
fact'' = fact . fromIntegral
This can then be used also as Int -> Integer, which is somewhat sensible.
I'd recommend to just keep the signature (Eq t, Num t) => t -> t though, and only add conversion operations where it's actually needed. Or really, what I'd recommend is to not use fact at all – this is a very expensive function that's hardly ever really useful in practice; most applications that naïvely end up with a factorial really just need something like binomial coefficients, and those can be implemented more efficiently without a factorial.
I have this code:
esprimo :: Int->Bool
esPrimo x = if length (div x x) == 2 then True else False
But I pulled the error is above
In addition to what sibi said, I think what you are trying to do is this:
isPrime :: Int -> Bool
isPrime x = if length [d | d <- [1..x], x `mod` d == 0] == 2 then True else False
this is basically the direct translation of the mathematical concept of beeing prime into Haskell.
As you don't need the if as it checks the same == already returns a bit more readable might be:
isPrime :: Int -> Bool
isPrime x = length divisors == 2
where divisors = [d | d <- [1..x], x `isMultipleOf` d]
isMultipleOf m n = m `mod` n == 0
Please note that this is of course not the most performant prime-test.
The exact reason for your error is because of the different cases you have used in the type signature and the type definition:
esprimo :: Int -> Bool -- p should be capital here to work.
esPrimo x = if length (div x x) == 2 then True else False
Haskell is case sensitive, so esprimo and esPrimo are different. That being said there is other type error in your code: the type of div is div :: Integral a => a -> a -> a, so it returns a and you are applying length function on it. But length function only accepts list i.e [a] and not a which will produce you type error.
This is the code:
finde_f x =
if (x-2) mod 3 /= 0
then 1
else x - (x-2)/3
These are the errors during run-time:
*Main> finde_f 6
<interactive>:170:1:
No instance for (Fractional ((a10 -> a10 -> a10) -> a20 -> a0))
arising from a use of `finde_f'
Possible fix:
add an instance declaration for
(Fractional ((a10 -> a10 -> a10) -> a20 -> a0))
In the expression: finde_f 6
In an equation for `it': it = finde_f 6
<interactive>:170:9:
No instance for (Num ((a10 -> a10 -> a10) -> a20 -> a0))
arising from the literal `6'
Possible fix:
add an instance declaration for
(Num ((a10 -> a10 -> a10) -> a20 -> a0))
In the first argument of `finde_f', namely `6'
In the expression: finde_f 6
In an equation for `it': it = finde_f 6
I'm not sure what is happening here. I hope you can help me understand why this (very) simple function doesn't run. Is it because of mod or /? How can I fix this?
Edit: After changing to mod:
*Main> finde_f 3
<interactive>:12:1:
No instance for (Integral a0) arising from a use of `finde_f'
The type variable `a0' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
Note: there are several potential instances:
instance Integral Int -- Defined in `GHC.Real'
instance Integral Integer -- Defined in `GHC.Real'
instance Integral GHC.Types.Word -- Defined in `GHC.Real'
In the expression: finde_f 3
In an equation for `it': it = finde_f 3
<interactive>:12:9:
No instance for (Num a0) arising from the literal `3'
The type variable `a0' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
Note: there are several potential instances:
instance Num Double -- Defined in `GHC.Float'
instance Num Float -- Defined in `GHC.Float'
instance Integral a => Num (GHC.Real.Ratio a)
-- Defined in `GHC.Real'
...plus three others
In the first argument of `finde_f', namely `3'
In the expression: finde_f 3
In an equation for `it': it = finde_f 3
Full-code, with correction:
-- Continuous Fraction -------------------------------------------------------------------
-- A --
cont_frac n d k =
if k == 1
then (n k) / (d k)
else (n k) / ((d k) + (cont_frac n d (k-1)))
-- B --
cont_frac_iter n d k count =
if count == k
then (n count) / (d count)
else (n count) / ((d count) + (cont_frac_iter n d k (count+1)))
-- e-2 Continuous Fraction ---------------------------------------------------------------
finde_cf k =
2 + (cont_frac_iter (\x -> 1) finde_f (k) (1))
-- Auxiliary Function --
finde_f x =
if mod (x-2) 3 /= 0
then 1
else fromIntegral x - (fromIntegral x-2)/3
mod is a prefix function, but you use it as infix.
Use:
mod (x-2) 3 /= 0 --prefix
or
(x-2) `mod` 3 /= 0 --infix
UPDATED
You try to use Integral with Fractional
> :t (/)
(/) :: Fractional a => a -> a -> a
> :t mod
mod :: Integral a => a -> a -> a
So, just convert numerals, like this:
> :t fromIntegral
fromIntegral :: (Integral a, Num b) => a -> b
... else fromIntegral x - (fromIntegral x-2)/3
I want to create Haskell function with different return value from its parameter, example:
I want function isOdd 3 return value either True or False.
I've tried
isOdd :: Integer -> Bool
isOdd x = (if x mod 2 == 0 False else True)
but it returns an error, can anybody help me? Also, is there a tutorial about functions in Haskell? I can't find a good tutorial about function in haskell.
isOdd :: Integer -> Bool
isOdd x = (if x mod 2 == 0 False else True)
You don't need the parens:
isOdd :: Integer -> Bool
isOdd x = if x mod 2 == 0 False else True
You missed out then:
isOdd :: Integer -> Bool
isOdd x = if x mod 2 == 0 then False else True
As you are using mod as an operator, you must surround it with backticks:
isOdd :: Integer -> Bool
isOdd x = if x `mod` 2 == 0 then False else True
That works.
Furthermore, you can write if blah then False else True more simply as not (blah):
isOdd :: Integer -> Bool
isOdd x = not (x `mod` 2 == 0)
Even more simply:
isOdd :: Integer -> Bool
isOdd x = x `mod` 2 /= 0
Please note: this is practically the same as the standard odd function.
Which tutorials have you tried?
Learn You A Haskell has a chapter introducing functions.
The problem here is that mod isn't infix. Additionally, in Haskell if statements work like this
if cond then expr1 else expr2
Notice the then.
You should use mod like this mod x 2. However you can make it infix like this:
x `mod` 2
On a side not
x `mod` 2 /= 0
Is much easier to read than the whole if statement.
As far as tutorials: Learn You a Haskell for Great Good is a good start. For a more in depth coverage Real World Haskell is excellent.
If you just want to find a function then Hoogle is your friend.