When you simplify something down into these two, is there really any difference between?
For example:
( (B'C)' * (B'D')' )'
Is this and NAND only? If so, can it be converted to AND and NOT only? Or vice-versa? I'm confused on the difference between the two.
Your formula:
( (B'C)' * (B'D')' )'
Assume ' is negation and * and juxtaposition are used for conjunction; disjunction is not shown but would be denoted +. Let us rewrite the formula using not and and instead:
not (not (not B and C) and not (not B and not D))
Let us also indicate which nots go with which ands:
not (not (not B and C) and not (not B and not D))
^1 ^2 ^2 ^1 ^3 ^3
We can therefore eliminate three nots and replace the corresponding ands with three nands:
(not B nand C) nand (not B nand not D)
We see right away that the original formula was not expressed using only nands since eliminating pairs of nots and ands using the definition of nand did not eliminate non-nand operators.
However, the original formula does consist only of and and not. Because any formula can be written using nands only, this one can. The lazy way is to just use not x = x nand x three times to remove each of the remaining nots.
Is it safe to say that the following dichotomy holds:
Each given function is
either pure
or has side effects
If so, side effects (of a function) are anything that can't be found in a pure function.
This very much depends on the definitions that you choose. It is definitely fair to say that a function is pure or impure. A pure function always returns the same result and does not modify the environment. An impure function can return different results when it is executed repeatedly (which can be caused by doing something to the environment).
Are all impurities side-effects? I would not say so - a function can depend on something in the environment in which it executes. This could be reading some configuration, GPS location or reading data from the internet. These are not really "side-effects" because it does not do anything to the world.
I think there are two different kinds of impurities:
Output impurity is when a function does something to the world. In Haskell, this is modelled using monads - an impure function a -> b is actually a function a -> M b where M captures the other things that it does to the world.
Input impurity is when a function requires something from the environment. An impure function a -> b can be modelled as a function C a -> b where the type C captures other things from the environment that the function may access.
Monads and output impurities are certainly better known, but I think input impurities are equally important. I wrote my PhD thesis about input impurities which I call coeffects, so I this might be a biased answer though.
For a function to be pure it must:
not be affected by side-effects (i.e. always return same value for same arguments)
not cause side-effects
But, you see, this defines functional purity with the property or absence of side-effects. You are trying to apply backwards logic to deduct the definition of side-effects using pure functions, which logically should work, but practically the definition of a side-effect has nothing to do with functional purity.
I don't see problems with the definition of a pure function: a pure function is a function. I.e. it has a domain, a codomain and maps the elements of the former to the elements of the latter. It's defined on all inputs. It doesn't do anything to the environment, because "the environment" at this point doesn't exist: there are no machines that can execute (for some definition of "execute") a given function. There is just a total mapping from something to something.
Then some capitalist decides to invade the world of well-defined functions and enslave such pure creatures, but their fair essence can't survive in our cruel reality, functions become dirty and start to make the CPU warmer.
So it's the environment is responsible for making the CPU warmer and it makes perfect sense to talk about purity before its owner was abused and executed. In the same way referential transparency is a property of a language — it doesn't hold in the environment in general, because there can be a bug in the compiler or a meteorite can fall upon your head and your program will stop producing the same result.
But there are other creatures: the dark inhabitants of the underworld. They look like functions, but they are aware of the environment and can interact with it: read variables, send messages and launch missiles. We call these fallen relatives of functions "impure" or "effectful" and avoid as much as possible, because their nature is so dark that it's impossible to reason about them.
So there is clearly a big difference between those functions which can interact with the outside and those which doesn't. However the definition of "outside" can vary too. The State monad is modeled using only pure tools, but we think about f : Int -> State Int Int as about effectful computation. Moreover, non-termination and exceptions (error "...") are effects, but haskellers usually don't consider them so.
Summarizing, a pure function is a well-defined mathematical concept, but we usually consider functions in programming languages and what is pure there depends on your point of view, so it doesn't make much sense to talk about dichotomies when involved concepts are not well-defined.
A way to define purity of a function f is ∀x∀y x = y ⇒ f x = f y, i.e. given the same argument the function returns the same result, or it preserves equality.
This isn't what people usually mean when they talk about "pure functions"; they usually mean "pure" as "does not have side effects". I haven't figured out how to qualify a "side effect" (comments welcome!) so I don't have anything to say about it.
Nonetheless, I'll explore this concept of purity because it might offer some related insight. I'm no expert here; this is mostly me just rambling. I do however hope it sparks some insightful (and corrective!) comments.
To understand purity we have to know what equality we are talking about. What does x = y mean, and what does f x = f y mean?
One choice is the Haskell semantic equality. That is, equality of the semantics Haskell assigns to its terms. As far as I know there are no official denotational semantics for Haskell, but Wikibooks Haskell Denotational Semantics offers a reasonable standard that I think the community more or less agrees to ad-hoc. When Haskell says its functions are pure this is the equality it refers to.
Another choice is a user-defined equality (i.e. (==)) by deriving the Eq class. This is relevant when using denotational design — that is, we are assigning our own semantics to terms. With this choice we can accidentally write functions which are impure; Haskell is not concerned with our semantics.
I will refer to the Haskell semantic equality as = and the user-defined equality as ==. Also I assume that == is an equality relation — this does not hold for some instances of == such as for Float.
When I use x == y as a proposition what I really mean is x == y = True ∨ x == y = ⊥, because x == y :: Bool and ⊥ :: Bool. In other words, when I say x == y is true, I mean that if it computes to something other than ⊥ then it computes to True.
If x and y are equal according to Haskell's semantics then they are equal according to any other semantic we may choose.
Proof: if x = y then x == y ≡ x == x and x == x is true because == is pure (according to =) and reflexive.
Similarly we can prove ∀f∀x∀y x = y ⇒ f x == f y. If x = y then f x = f y (because f is pure), therefore f x == f y ≡ f x == f x and f x == f x is true because == is pure and reflexive.
Here is a silly example of how we can break purity for a user-defined equality.
data Pair a = Pair a a
instance (Eq a) => Eq (Pair a) where
Pair x _ == Pair y _ = x == y
swap :: Pair a -> Pair a
swap (Pair x y) = Pair y x
Now we have:
Pair 0 1 == Pair 0 2
But:
swap (Pair 0 1) /= swap (Pair 0 2)
Note: ¬(Pair 0 1 = Pair 0 2) so we were not guaranteed that our definition of (==) would be okay.
A more compelling example is to consider Data.Set. If x, y, z :: Set A then you would hope this holds, for example:
x == y ⇒ (Set.union z) x == (Set.union z) y
Especially when Set.fromList [1,2,3] and Set.fromList [3,2,1] denote the same set but probably have different (hidden) representations (not equivalent by Haskell's semantics). That is to say we want to be sure that ∀z Set.union z is pure according to (==) for Set.
Here is a type I have played with:
newtype Spry a = Spry [a]
instance (Eq a) => Eq (Spry a) where
Spry xs == Spry ys = fmap head (group xs) == fmap head (group ys)
A Spry is a list which has non-equal adjacent elements. Examples:
Spry [] == Spry []
Spry [1,1] == Spry [1]
Spry [1,2,2,2,1,1,2] == Spry [1,2,1,2]
Given this, what is a pure implementation (according to == for Spry) for flatten :: Spry (Spry a) -> Spry a such that if x is an element of a sub-spry it is also an element of the flattened spry (i.e. something like ∀x∀xs∀i x ∈ xs[i] ⇒ x ∈ flatten xs)? Exercise for the reader.
It is also worth noting that the functions we've been talking about are across the same domain, so they have type A → A. That is except for when we proved ∀f∀x∀y x = y ⇒ f x == f y which crosses from Haskell's semantic domain to our own. This might be a homomorphism of some sorts… maybe a category theorist could weigh in here (and please do!).
Side effects are part of the definition of the language. In the expression
f e
the side effects of e are all the parts of e's behavior that are 'moved out' and become part of the behavior of the application expression, rather than being passed into f as part of the value of e.
For a concrete example, consider this program:
f x = x; x
f (print 3)
where conceptually the syntax x; x means 'run x, then run it again and return the result'.
In a language where print writes to stdout as a side effect, this writes
3
because the output is part of the semantics of the application expression.
In a language where the output of print is not a side effect, this writes
3
3
because the output is part of the semantics of the x variable inside the definition of f.
I am trying to create a 2-input NOR Gate only from XOR and AND Gates. however I am stuck. The output must be NOT X AND NOT Y as the definition of a NOR GATE but I can not seem to understand how to get it.
I think this will work.
(A XOR 1) AND (B XOR 1)
I'm trying to teach basic set theory to Prover9. The following definition of membership seems to work very well (the second axiom is just to make lists unordered):
member(x,[x:y]).
[x,y]=[y,x].
With this, I can have Prover9 prove 'complicated' things like member([A,B],[C,[A,B]]) and others.
However, I must be doing something wrong when I use it to define subsets:
subset(x,y) <-> (member(z,x) -> member(z,y)).
Prover9 clausifies this as subset(x,y) | -member(z,y) and uses it to prove false clauses, like subset([A],[B,C]).
What am I missing?
Your "second axiom ... just to make lists unordered" looks suspicious.
Note [x,y] is a two-element list. So your axiom is saying nothing about lists in general. Your 'complicated' examples, are still 2-element lists. So not very complicated. I think you'll be unable to prove member(A, [C, B, A])
Contrast that [x:y] in your first axiom is a 1-or-more-element list. The y might be nil, or might be any number of elements. IOW y is a list, whereas in [x,y], y is an element of a list.
See http://www.cs.unm.edu/~mccune/prover9/manual/2009-11A/, 'Clauses & Formulas' at 'list notation'.
I'd go:
member(x, [x:y]).
member(x, z) -> member(x, [y:z]).
(But that defines a bag, not a set.)
I think the quantification over variables is a red herring.
Edit: Errk. I'm wrong. So I don't know why I got this result:
The example that #Doug points to doesn't need to quant z 'inside'
the rhs of equivalence. You can just remove all the explicit
quantification, and the proof still works.
OK. Let's apply the rewrite rules per the Manual 'Clauses & Formulas' at "If non-clausal formulas are entered ...".
That definition of subset is an equivalence (aka bi-implication); rewrite as two separate axioms: 'forwards' and backwards' implications; rewrite each of those using p -> q ==> -p | q.
In the 'forwards' direction we get:
-subset(x, y) | (member(z, x) -> member(z, y)).
Doesn't matter whether the z is quantified narrow or wide.
In the 'backwards' direction:
-(member(z, x) -> member(z, y)) | subset(x, y).
Here if we quantify z narrowly around the implication, that's inside the scope of negation; and so different to quantifying across the whole formula.
Conclusion: both your definition of member( ) and of subset( ) are wrong.
BTW Are you sure you need to define member? The proof #Doug points to just takes member(x,y) as primitive.
I am trying to understand with boolean algebra how using 4 NAND Gates can be equivalen to 1 XOR gate.
If we look at this picture from wikipedia http://en.wikipedia.org/wiki/XOR_gate#Alternatives
There is a schematic of the gate.
This is the large expression I came up with to express the schematic. Perhaps it is wrong and that may be my issue? But still I cannot see how to transform the equation into the XOR expression I expect.
I have: !X!Y + X(!X!Y) + Y(!X!Y) + XY(!X!Y)
I know XOR logic looks like this: X!Y + !XY.
Can anyone clear up my confusion?
Your translation of the schematic on Wikipedia is a little bit off. I translated it into
!(!(A!(AB))!(B!(AB)))
Notice that !(XY) and !X!Y are different and that the schematic does not have any or gates (so no + operators). From there we can simplify using various boolean logic:
(!(!(A!(AB))) + !(!(B!(AB))))
(A!(AB) + B!(AB))
(A(!A + !B) + B(!A + !B))
(A!B + B!A)