Writing an expression using only NAND, OR, XNOR - boolean-logic

I have a 2-1 mux and I'm trying to write z = s'd0 + sd1
using only NAND, XNOR, and OR gates (not necessarily all of them).
I tried simplifying it and what I ended up with is z = NAND(NAND(s', d0), NAND(s, d1)), but I can't use NOT ('), so is there a way to write NAND(s', d0) without the NOT?

You can build NOT from NAND:
NAND(X,X) == NOT(X)

NAND gate is an universal gate; you can use it to make any other gate.
s' = nand(s,s)

Simple solution
Full version of the solution proposed by others is (A NAND S) NAND (B NAND (S NAND S)) .
By the way, NOT X could also be expressed as X NAND 1, not only as X NAND X.
Advanced solution
(S OR (A XNOR B)) XNOR A
The latter solution is definitely more interesting:
It uses a fewer number of gates (though of two different types).
It uses not functionally complete set of gates (thereby is less trivial).
How to find the latter solution?
Construct the Zhegalkin polynomial of 2:1 mux and simplify it slightly: (S AND (A XOR B)) XOR B.
Note that the boolean function dual to 2:1 mux is also 2:1 mux, but for swapped input signals.
Now "dualize" the polynomial (replace AND and XOR with OR and XNOR respectively) and swap A with B.

Related

Is there an ignore function in Racket?

In other words, does there exist a function f such that f x does not evaluate x and just returns void? I tried to implement something similar by using (define (ignore x) (if true void x)) but it still evaluates x.
You can also use
(when #f x)
which does not require a macro definition. This has the advantage that someone reading your code does not have to look at the definition of your macro.
Racket has the #; reader macro to comment out expressions; consider whether this might make sense. For instance,
> (+ 1 2 #;3 4)
7

What is the name of this property of a function?

Suppose that you have a function f: List a -> a such that f is associative and f(x, y, z) === f(x, f(y, z)). Is there a conventional name for this latter property?
Examples of functions with this property are AND, XOR, sum, product, and GCD. Examples of associative functions without this property are NAND and XNOR.
I believe that the property is equivalent to saying that f(xs) === reduce(f, xs).
It looks like this is also equivalent to saying that f is a catamorphism of an associative binary function and its neutral element. Doesn't exactly roll off the tongue.
(Also, NAND is not associative. My bad.)

Automatic TCO in Clojure

Is there a way to define a function in Clojure that is automatically tail-call-optimized?
e.g.
(defrecur fact [x]
(if (= x 1)
1
(* x (fact (dec x)))))
would be translated internally to something like:
(defn fact [x]
(loop [n x f 1]
(if (= n 1)
f
(recur (dec n) (* f n)))))
Can you tell me if something like this already exists?
The short answer is "No".
The slightly longer answer is that Clojure is deliberately designed to require explicit indication where Tail Call Optimisation is desired, because the JVM doesn't support it natively.
Incidentally, you can use recur without loop, so there's no more typing required, e.g.:
(defn func [x]
(if (= x 1000000)
x
(recur (inc x))))
Update, April 29:
Chris Frisz has been working on a Clojure TCO research project with Dan Friedman, and whilst nobody is claiming it to be 'the answer' at this time, the project is both interesting and promising. Chris recently gave an informal talk about this project, and he's posted it on his blog.
To the best of my knowledge, there is no automatic way to generate tail recursion in Clojure.
There are examples of functions that use recursion without using loop .. recur that work without overflowing the stack. That is because those functions have been carefully written to use lazy sequences.
Here is an example of replacing flatten with a hand-written function. This example came from http://yyhh.org/blog/2011/05/my-solutions-first-50-problems-4clojure-com
(fn flt [coll]
(let [l (first coll) r (next coll)]
(concat
(if (sequential? l)
(flt l)
[l])
(when (sequential? r)
(flt r)))))
One of the guiding principals behind this decision was to make the special part look special. that way it is obvious where tail calls are in use and where they are not. This was a deliberate design decision on which some people have strong opinions though in practice I rarely see recur used in idomatic Clojure anyway so In practice it's not a common problem.

The difference between +1 and -1

> :t (+1)
(+1) :: Num a => a -> a
> :t (-1)
(-1) :: Num a => a
How come the second one is not a function? Do I have to write (+(-1)) or is there a better way?
This is because (-1) is interpreted as negative one, however (+1) is interpreted as the curried function (\x->1+x).
In haskell, (a **) is syntactic sugar for (**) a, and (** a) is (\x -> x ** a). However (-) is a special case since it is both a unary operator (negate) and a binary operator (minus). Therefore this syntactic sugar cannot be applied unambiguously here. When you want (\x -> a - x) you can write (-) a, and, as already answered in Currying subtraction, you can use the functions negate and subtract to disambiguate between the unary and binary - functions.
Do I have to write (+(-1)) or is there a better way?
I just found a function called subtract, so I can also say subtract 1. I find that quite readable :-)
(-1) is negative one, as others have noted. The subtract one function is \x -> x-1, flip (-) 1 or indeed (+ (-1)).
- is treated as a special case in the expression grammar. + is not, presumably because positive literals don't need the leading plus and allowing it would lead to even more confusion.
Edit: I got it wrong the first time. ((-) 1) is the function "subtract from one", or (\x -> 1-x).

What type systems can prevent goal suspension in logical languages?

From section 3.13.3 of the curry tutorial:
Operations that residuate are called rigid , whereas operations that narrow are called flexible. All defined operations are flexible whereas most primitive operations, like arithmetic operations, are rigid since guessing is not a reasonable option for them. For example, the prelude defines a list concatenation operation as follows:
infixr 5 ++
...
(++) :: [a] -> [a] -> [a]
[] ++ ys = ys
(x:xs) ++ ys = x : xs ++ ys
Since the operation “++” is flexible, we can use it to search for a list satisfying a particular property:
Prelude> x ++ [3,4] =:= [1,2,3,4] where x free
Free variables in goal: x
Result: success
Bindings:
x=[1,2] ?
On the other hand, predefined arithmetic operations like the addition “+” are rigid. Thus, a
call to “+” with a logic variable as an argument flounders:
Prelude> x + 2 =:= 4 where x free
Free variables in goal: x
*** Goal suspended!
Curry does not appear to guard against writing goals that will be suspended. What type systems can detect ahead of time whether a goal is going to be suspended?
What you've described sounds like mode checking, which generally checks what outputs will be available for a certain set of inputs. You may want to check the language Mercury which takes mode checking quite seriously.