Convert relation to BCNF - relational-database

I am given the relation R = {C, SN, OD, CH, CL, I, S, Y, D, RM, NS}.
The following functional dependencies hold:
{C} -> {OD, CH, CL}
{C, SN, S, Y} -> {D, RM, NS, I}
{RM, D, S, Y} -> {I, C, SN}
I need to convert this to BCNF.
I split this into 2 sub relations R1 = {C,OD,CH,CL} and R2={C,S,Y,D,RM,SN,I,NS}
Now I can see that R1 is in BCNF but I'm not sure about R2. This comes from the idea that {C, SN, S, Y} -> {D, RM, NS, I} so it seems like some non key attributes are determining part of the key. But the non-key attributes also need S,Y which are key attributes so I'm not sure if BCNF rule holds.
So is R2 in BCNF?

Assuming that the functional dependencies that you have given are a cover of all the functional dependencies of R, the candidate keys of the relation are {C, S, SN, Y} and {D, RM, S, Y}. This can be checked by computing the closure of both the sets of attributes, which contains all the attributes of R, while the closure obtained by removing any attribute from them does not contain all the attributes.
Your decomposition is in BCNF, and R2 is in BCNF. In fact, a cover of the dependencies of R2 is:
{D, RM, S, Y} -> {C, I, SN}
{C, S, SN, Y} -> {D, NS, RM}
and we can see that in both of them the determinant is a candidate key.

Related

Finding inverse functions [duplicate]

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

Implement primitive recursive factorial in haskell

I am currently trying to implement primitive recursive factorial in Haskell.
I'm using the function recNat, as a recursor. That is:
recNat :: a -> (Nat -> a -> a) -> Nat -> a
recNat a _ Zero = a
recNat a h (Succ n) = h n (recNat a h n)
This is our attempt, but can't quite figure out what's wrong
factR :: Nat -> Nat
factR Zero = Succ Zero
factR (Succ m) = recNat (Succ m) (\ _ y -> y) (factR m)
I was also trying to implement the exponential function, but it seems even more confusing.
In order to implement a factorial, we can implement a function for multiplication. For the multiplication function, we need the addition function
data Nat = Zero | Succ Nat
add :: Nat -> Nat -> Nat
add a Zero = a
add a (Succ b) = Succ (add a b)
mul :: Nat -> Nat -> Nat
mul a Zero = Zero
mul a (Succ b) = add a (mul a b)
Then the factorial function just comes down to:
fac :: Nat -> Nat
fac Zero = Succ Zero
fac (Succ a) = mul (Succ a) (fac a)

How do we know all Coq constructors are injective and disjoint?

According to this course, all constructors (for inductive types) are injective and disjoint:
...Similar principles apply to all inductively defined types: all
constructors are injective, and the values built from distinct
constructors are never equal. For lists, the cons constructor is
injective and nil is different from every non-empty list. For
booleans, true and false are unequal.
(And the inversion tactic based on this assumption)
I am just wondering how do we know this assumption holds?
How do we know that, e.g., we cannot define natural numbers based on
1) a Successor and maybe a "Double" constructor like this:
Inductive num: Type :=
| O : num
| S : num -> num
| D : num -> num.
and
2) some plus function so that one number 2 can be reached via two different sequences/routes of constructors, S (S O) and D (S O)?
What's the mechanism in Coq that ensures the above will never happen?
P.S.
I am not suggesting the above num example is possible. I am just wondering what makes it impossible.
Thanks
When you define an inductive data type in Coq, you are essentially
defining a tree type. Each constructor gives a kind of node that is
allowed to occur in your tree, and its arguments determine the
children and elements that that node can have. Finally, functions
defined on inductive types (with the match clause) can check the
constructors that were used to produce a value of that type in
arbitrary ways. This makes Coq constructors very different from
constructors you see in an OO language, for instance. An object
constructor is implemented as a regular function that initializes a
value of a given type; Coq constructors, on the other hand, are
enumerating the possible values that the representation of our type
allows. To understand this difference better, we can compare the
different functions we can define on an object in a traditional OO
language, and on an element of an inductive type in Coq. Let's use
your num type as an example. Here's an object-oriented definition:
class Num {
int val;
private Num(int v) {
this.val = v;
}
/* These are the three "constructors", even though they
wouldn't correspond to what is called a "constructor" in
Java, for instance */
public static zero() {
return new Num(0);
}
public static succ(Num n) {
return new Num(n.val + 1);
}
public static doub(Num n) {
return new Num(2 * n.val);
}
}
And here's a definition in Coq:
Inductive num : Type :=
| zero : num
| succ : num -> num
| doub : num -> num.
In the OO example, when we write a function that takes a Num
argument, there's no way of knowing which "constructor" was used to
produce that value, because this information is not stored in the
val field. In particular Num.doub(Num.succ(Num.zero())) and
Num.succ(Num.succ(Num.zero())) would be equal values.
In the Coq example, on the other hand, things change, because we can
determine which constructor was used to form a num value, thanks to
the match statement. For instance, using Coq strings, we could write
a function like this:
Require Import Coq.Strings.String.
Open Scope string_scope.
Definition cons_name (n : num) : string :=
match n with
| zero => "zero"
| succ _ => "succ"
| doub _ => "doub"
end.
In particular, even though your intended meaning for the constructors
implies that succ (succ zero) and doub (succ zero) should be
"morally" equal, we can distinguish them by applying the cons_name
function to them:
Compute cons_name (doub (succ zero)). (* ==> "doub" *)
Compute cons_name (succ (succ zero)). (* ==> "succ" *)
As a matter of fact, we can use match to distinguish between succ
and doub in arbitrary ways:
match n with
| zero => false
| succ _ => false
| doub _ => true
end
Now, a = b in Coq means that there is no possible way we can
distinguish between a and b. The above examples show why doub
(succ zero) and succ (succ zero) cannot be equal, because we can
write functions that don't respect the meaning that we had in mind
when we wrote that type.
This explains why constructors are disjoint. That they are injective
is actually also a consequence of pattern-matching. For instance,
suppose that we wanted to prove the following statement:
forall n m, succ n = succ m -> n = m
We can begin the proof with
intros n m H.
Leading us to
n, m : num
H : succ n = succ m
===============================
n = m
Notice that this goal is by simplification equivalent to
n, m : num
H : succ n = succ m
===============================
match succ n with
| succ n' => n' = m
| _ => True
end
If we do rewrite H, we obtain
n, m : num
H : succ n = succ m
===============================
match succ m with
| succ n' => n' = m
| _ => True
end
which simplifies to
n, m : num
H : succ n = succ m
===============================
m = m
At this point, we can conclude with reflexivity. This technique is
quite general, and is actually at the core of what inversion does.
There is none: the constructors O, S and D are indeed disjoint and injective but the semantics for nums you have in your head is not, as a function, injective.
That is why num would usually be considered to be a bad representation of the natural numbers: working up-to equivalence is quite annoying.

Haskell - apply tuple of functions to tuple of values?

I have a tuple of values representing some state, and want to translate it by an addition (shift). My values are a longer version of ( Int, [Int], Int), and I want something conceptually (but not literally) like this:
shift n = ??? (+n) (id, map, id) -- simple(?)
which would be equivalent to:
shift n (a, b, c) = (a+n, map (+n) b, c+n)
I am happy to just go with this explicit function usage, but wondered it there was a more idiomatic point-free version using Applicative or Arrows or ..., or if they would just end-up obfuscating things. I thought that the point-free version shows the basic structure of the operation more clearly.
You can just write
shift n (a,b,c) = (a+n, map (+n) b, c+n)
Or define new combinators similar to Arrow's (***) and (&&&),
prod3 (f,g,h) (a,b,c) = (f a, g b, h c) -- cf. (***)
call3 (f,g,h) x = (f x, g x, h x) -- cf. (&&&)
ap3 f (a,b,c) = (f a, f b, f c)
uncurry3 f (a,b,c) = f a b c
and then call
prod3 ( (+n), map (+n), (+n) ) (a,b,c)
or even (with appropriately set operator precedences)
ap3 ($ (+n)) (id, map, id) `prod3` (a,b,c)
Or, if you'd write your triples as nested pairs, you could use
Prelude Control.Arrow> ( (+5) *** map (+5) *** (+5) ) (1,([2,3],4))
(6,([7,8],9))
So for nested pairs,
shift' :: (Num b) => b -> (b, ([b], b)) -> (b, ([b], b))
shift' n = ( (+n) *** map (+n) *** (+n) )
(see also Multiple folds in one pass using generic tuple function)
With the DeriveFunctor language extension you can write
data MyState a = MyState a [a] a
deriving (Functor)
The derived instance looks like
instance Functor MyState where
fmap f (MyState a bs c) = MyState (f a) (map f bs) (f c)
Now you can define
shift :: MyState Int -> MyState Int
shift n = fmap (+n)
(You say your tuple is even longer than (Int, [Int], Int), so you may want to define your state type using record syntax.)
Applying a list of functions to a list of values is simply
zipWith ($)
Since tuples of different sizes are each their own type, you will have to write a function explicitly for 3-tuples. A general function to apply a 3-tuple of functions to a 3-tuple of values is
apply (f, g, h) (a, b, c) = (f a, g b, h c)
You have to explicitly write each function application because tuples don't have the recursive property of lists.

passing a function with an arbitrary amount of parameters

I've recently been learning haskell from this awesome site, and I just learned about passing functions as parameters in the Higher Order Functions chapter. I can see how passing functions as parameters can be extremely useful, but from my current(lowley) understanding you need to specify the amount of parameters in this function, which can be quite limited given this function:
--takes a function and returns a function that has flipped arguments
flip' :: (a -> b -> c) -> (b -> a -> c) --very limited
flip' f = g
where g x y = f y x
useful, but only to the point of functions taking two parameters, is there a way to write a function definition that accepts functions with an arbitrary amount of parameters? My guess would have to be some sort of parameter list, but I can't seem to find any information on it. Thanks!
Actually flip works with functions with more than two parameters, but might not be exactly what you need:
Prelude> :t (,,,)
(,,,) :: a -> b -> c -> d -> (a, b, c, d)
Prelude> :t flip (,,,)
flip (,,,) :: b -> a -> c -> d -> (a, b, c, d)
since
(,,,) :: a -> b -> c -> d -> (a, b, c, d)
is
(,,,) :: a -> (b -> (c -> (d -> (a, b, c, d))))
the first two parameters get flipped. Here a is a, b is b, but c is c -> d -> (a, b, c, d).
And then again, what do you expect to achieve by flipping a 3 parameter function like in this example?
EDIT: And also, there are vararg functions - one example is printf. This Haskell.org page is pretty nice. In short, some typeclass magic could be used to achieve this effect.