What are the logical and arithmetical functions from the 74LS181 - boolean-logic

i want to use the 74ls181 in an Project of mine but i can not understand all of the functions of it mentioned in its datasheet.
Could someone please explain this boolean-mess?
EDIT:
Based on the very helpful answer from Axel Kemper i created this:

Your table was taken from the Texas Instruments 74ls181 datasheet?
Assuming from your question tags that you are asking about the logical functions
(explained from top to bottom as in the table):
F = NOT(A) set output to inverse of all A bits
F = NAND(A, B) inverse AND of inputs
F = OR(NOT(A), B)
F = 1 set all output bits to 1
F = NOR(A, B)
F = NOT(B) feed inverse B bits to output
F = NOT(EXOR(A, B))
F = OR(A, NOT(B))
F = AND(NOT(A), B)
F = EXOR(A, B) output is exclusive or of inputs
F = B feed B inputs bits to outputs
F = OR(A, B) bitwise disjunction
F = 0 set all output bits to 0
F = AND(A, NOT(B))
F = AND(A, B) bitwise conjuction
F = A
All functions are implemented 4-bit parallel.
A, B and F each have four signal lines.
A and B are the four-bit inputs. F is the four-bit output.
So, A=0 for example means A0=0, A1=0, A2=0, A3=0
There is a total of 16 different logical functions possible to implement with two inputs and one output. 74ls181 implements all of them.
A truth-table with two inputs and one output has four rows.
Each of the rows has output value 0 or 1. Therefore, a four-bit number defines the function described by the truth-table.
With four bits, 16 functions are possible.
There is a very instructive YouTube video available on the 74ls181.

Related

How does Unison compute the hashes of recursive functions?

In Unison, functions are identified by the hashes of their ASTs instead of by their names.
Their documentation and their FAQs have given some explanations of the mechanism.
However, the example presented in the link is not clear to me how the hashing actually works:
They used an example
f x = g (x - 1)
g x = f (x / 2)
which in the first step of their hashing is converted to the following:
$0 =
f x = $0 (x - 1)
g x = $0 (x / 2)
Doesn't this lose information about the definitions.
For the two following recursively-defined functions, how can the hashing distinguish them:
# definition 1
f x = g (x / 2)
g x = h (x + 1)
h x = f (x * 2 - 7)
# definition 2
f x = h (x / 2)
g x = f (x + 1)
h x = g (x * 2 - 7)
In my understanding, brutally converting all calling of f g and h to $0 would make the two definitions undistinguishable from each other. What am I missing?
The answer is that the form in the example (with $0) is not quite accurate. But in short, there's a special kind of hash (a "cycle hash") which is has the form #h.n where h is the hash of all the mutually recursive definitions taken together, and n is a number from 0 to the number of terms in the cycle. Each definition in the cycle gets the same hash, plus an index.
The long answer:
Upon seeing cyclical definitions, Unison captures them in a binding form called Cycle. It's a bit like a lambda, but introduces one bound variable for each definition in the cycle. References within the cycle are then replaced with those variables. So:
f x = g (x - 1)
g x = f (x / 2)
Internally becomes more like (this is not valid Unison syntax):
$0 = Cycle f g ->
letrec
[ x -> g (x - 1)
, x -> f (x / 2) ]
It then hashes each of the lambdas inside the letrec and sorts them by that hash to get a canonical order. Then the whole cycle is hashed. Then these "cycle hashes" of the form #h.n get introduced at the top level for each lambda (where h is the hash of the whole cycle and n is the canonical index of each term), and the bound variables get replaced with the cycle hashes:
#h.0 = x -> #h.1 (x - 1)
#h.1 = x -> #h.0 (x / 2)
f = #h.0
g = #h.1

Haskell - Join two functions with the same input

I have 2 different very simple functions with the same input-output structure (Both return a count(*) when avg of 3 notes is >= 4 (function1) and the other a count(*) when avg of 3 notes is < 4 (function2)), They both work properly in separate but now i need to join both into just one function with 2 outputs, I now maybe is a very easy question but i am only getting started with Haskell:
function1::[(String, Int,Int,Int)]->Int
function1 ((name,note1,note2,note3):xs) =
if (note1+note2+note3) `div` 3 >=4 then length xs else length xs
function2::[(String, Int,Int,Int)]->Int
function2 ((name,note1,note2,note3):xs) =
if (note1+note2+note3) `div` 3 <4 then length xs else length xs
Thanks!
You can use &&& from Control.Arrow.
combineFunctions f1 f2 = f1 &&& f2
Then use it like this :
combinedFunc = combineFunctions function1 function2
(res1,res2) = combinedFunc sharedArg
You already use tuples (name,note1,note2,note3) in your input data, so you must be familiar with the concept.
The simplest way to produce two outputs simultaneously is to put the two into one tuple:
combinedFunction f1 f2 input = (out1, out2)
where
out1 = f1 input
out2 = f2 input
It so happens that this can be written shorter as combinedFunction f1 f2 = f1 &&& f2 and even combinedFunction = (&&&), but that's less important for now.
A more interesting way to produce two outputs simultaneously is to redefine what it means to produce an output:
combinedFunWith k f1 f2 input = k out1 out2
where
out1 = f1 input
out2 = f2 input
Here instead of just returning them in a tuple, we pass them as arguments to some other user-specified function k. Let it decide what to do with the two outputs!
As can also be readily seen, our first version can be expressed with the second, as combinedFunction = combinedFunWith (,), so the second one seems to be more general ((,) is just a shorter way of writing a function foo x y = (x,y), without giving it a name).

How to find maximum of function outputs with multipe inputs in one function?

I want a function maxfunct, with input f (a function) and input n (int), that computes all outputs of function f with inputs 0 to n, and checks for the max value of the output.
I am quite new to haskell, what I tried is something like that:
maxfunct f n
| n < 0 = 0
| otherwise = maximum [k | k <- [\(f, x)-> f x], x<- [0..n]]
Idea is that I store every output of f in a list, and check for the maximum in this list.
How can I achieve that?
You're close. First, let's note the type of the function we're trying to write. Starting with the type, in addition to helping you get a better feel for the function, also lets the compiler give us better error messages. It looks like you're expecting a function and an integer. The result of the function should be compatible with maximum (i.e. should satisfy Ord) and also needs to have a reasonable "zero" value (so we'll just say it needs Num, for simplicity's sake; in reality, we might consider using Bounded or Monoid or something, depending on your needs, but Num will suffice for now).
So here's what I propose as the type signature.
maxfunct :: (Num a, Ord a) => (Int -> a) -> Int -> a
Technically, we could generalize a bit more and make the Int a type argument as well (requires Num, Enum, and Ord), but that's probably overkill. Now, let's look at your implementation.
maxfunct f n
| n < 0 = 0
| otherwise = maximum [k | k <- [\(f, x)-> f x], x<- [0..n]]
Not bad. The first case is definitely good. But I think you may have gotten a bit confused in the list comprehension syntax. What we want to say is: take every value from 0 to n, apply f to it, and then maximize.
maxfunct :: (Num a, Ord a) => (Int -> a) -> Int -> a
maxfunct f n
| n < 0 = 0
| otherwise = maximum [f x | x <- [0..n]]
and there you have it. For what it's worth, you can also do this with map pretty easily.
maxfunct :: (Num a, Ord a) => (Int -> a) -> Int -> a
maxfunct f n
| n < 0 = 0
| otherwise = maximum $ map f [0..n]
It's just a matter of which you find more easily readable. I'm a map / filter guy myself, but lots of folks prefer list comprehensions, so to each his own.

MIPS Programming instruction count issue

I wrote this mips code to find the gcf but I am confused on getting the number of instructions executed for this code. I need to find a linear function as a function of number of times the remainder must be calculated before an answer. i tried running this code using Single step with Qtspim but not sure on how to proceed.
gcf:
addiu $sp,$sp,-4 # adjust the stack for an item
sw $ra,0($sp) # save return address
rem $t4,$a0,$a1 # r = a % b
beq $t4,$zero,L1 # if(r==0) go to L1
add $a0,$zero,$a1 # a = b
add $a1,$zero,$t4 # b = r
jr gcf
L1:
add $v0,$zero,$a1 # return b
addiu $sp,$sp,4 # pop 2 items
jr $ra # return to caller
There is absolutely nothing new to show here, the algorithm you just implemented is the Euclidean algorithm and it is well known in the literature1.
I will nonetheless write an informal analysis here as link only questions are evil.
First lets rewrite the code in an high level formulation:
unsigned int gcd(unsigned int a, unsigned int b)
{
if (a % b == 0)
return b;
return gcd(b, a % b);
}
The choice of unsigned int vs int was dicated by the MIPS ISA that makes rem undefined for negative operands.
Out goal is to find a function T(a, b) that gives the number of step the algorithm requires to compute the GDC of a and b.
Since a direct approach leads to nothing, we try by inverting the problem.
What pairs (a, b) makes T(a, b) = 1, in other words what pairs make gcd(a, b) terminates in one step?
We clearly must have that a % b = 0, which means that a must be a multiple of b.
There are actually an (countable) infinite number of pairs, we can limit our selves to pairs with the smallest, a and b2.
To recap, to have T(a, b) = 1 we need a = nb and we pick the pair (a, b) = (1, 1).
Now, given a pair (c, d) that requires N steps, how do we find a new pair (a, b) such that T(a, b) = T(c, d) + 1?
Since gcd(a, b) must take one step further then gcd(c, d) and since starting from gcd(a, b) the next step is gcd(b, a % b) we must have:
c = b => b = c
d = a % b => d = a % c => a = c + d
The step d = a % c => a = c + d comes from the minimality of a, we need the smallest a that when divided by c gives d, so we can take a = c + d since (c + d) % c = c % c d % c = 0 + d = d.
For d % c = d to be true we need that d < c.
Our base pair was (1, 1) which doesn't satisfy this hypothesis, luckily we can take (2, 1) as the base pair (convince your self that T(2, 1) = 1).
Then we have:
gcd(3, 2) = gcd(2, 1) = 1
T(3, 2) = 1 + T(2, 1) = 1 + 1 = 2
gcd(5, 3) = gcd(3, 2) = 1
T(5, 3) = 1 + T(3, 2) = 1 + 2 = 3
gcd(8, 5) = gcd(5, 3) = 1
T(8, 5) = 1 + T(5, 3) = 1 + 3 = 4
...
If we look at the pair (2, 1), (3, 2), (5, 3), (8, 5), ... we see that the n-th pair (starting from 1) is made by the number (Fn+1, Fn).
Where Fn is the n-th Fibonacci number.
We than have:
T(Fn+1, Fn) = n
Regarding Fibonacci number we know that Fn ∝ φn.
We are now going to use all the trickery of asymptotic analysis, particularly in the limit of the big-O notation considering φn or φn + 1 is the same.
Also we won't use the big-O symbol explicitly, we rather assume that each equality is true in the limit. This is an abuse, but makes the analysis more compact.
We can assume without loss of generality that N is an upper bound for both number in the pair and that it is proportional to φn.
We have N ∝ φn that gives logφ N = n, this ca be rewritten as log(N)/log(φ) = n (where logs are in base 10 and log(φ) can be taken to be 1/5).
Thus we finally have 5logN = n or written in reverse order
n = 5 logN
Where n is the number of step taken by gcd(a, b) where 0 < b < a < N.
We can further show that if a = ng and b = mg with n, m coprimes, than T(a, b) = T(n, m) thus the restriction of taking the minimal pairs is not bounding.
1 In the eventuality that you rediscovered such algorithm, I strongly advice against continue with reading this answer. You surely have a sharp mind that would benefit the most from a challenge than from an answer.
2 We'll later see that this won't give rise to a loss of generality.

How do I create Haskell functions that return functions?

I would like to create three Haskell functions: a, b, and c.
Each function is to have one argument. The argument is one of the three functions.
I would like function a to have this behavior:
if the argument is function a then return function a.
if the argument is function b then return function b.
if the argument is function c then return function a.
Here's a recap of the behavior I desire for function a:
a a = a
a b = c
a c = a
And here's the behavior I desire for the other two functions:
b a = a
b b = a
b c = c
c a = c
c b = b
c c = c
Once created, I would like to be able to compose the functions in various ways, for example:
a (c b)
= a (b)
= c
How do I create these functions?
Since you have given no criteria for how you are going to observe the results, then a = b = c = id satisfies your criteria. But of course that is not what you want. But the idea is important: it doesn't just matter what behavior you want your functions to have, but how you are going to observe that behavior.
There is a most general model if you allow some freedom in the notation, and you get this by using an algebraic data type:
data F = A | B | C
deriving (Eq, Show) -- ability to compare for equality and print
infixl 1 %
(%) :: F -> F -> F
A % A = A
A % B = C
A % C = A
B % A = A
...
and so on. Instead of saying a b, you have to say A % B, but that is the only difference. You can compose them:
A % (C % B)
= A % B
= B
and you can turn them into functions by partially applying (%):
a :: F -> F
a = (A %)
But you cannot compare this a, as ehird says. This model is equivalent to the one you specified, it just looks a little different.
This is impossible; you can't compare functions to each other, so there's no way to check if your argument is a, b, c or something else.
Indeed, it would be impossible for Haskell to let you check whether two functions are the same: since Haskell is referentially transparent, substituting two different implementations of the same function should have no effect. That is, as long as you give the same input for every output, the exact implementation of a function shouldn't matter, and although proving that \x -> x+x and \x -> x*2 are the same function is easy, it's undecidable in general.
Additionally, there's no possible type that a could have if it's to take itself as an argument (sure, id id types, but id can take anything as its first argument — which means it can't examine it in the way you want to).
If you're trying to achieve something with this (rather than just playing with it out of curiosity — which is fine, of course), then you'll have to do it some other way. It's difficult to say exactly what way that would be without concrete details.
Well, you can do it like this:
{-# LANGUAGE MagicHash #-}
import GHC.Prim
import Unsafe.Coerce
This function is from ehird's answer here:
equal :: a -> a -> Bool
equal x y = x `seq` y `seq`
case reallyUnsafePtrEquality# x y of
1# -> True
_ -> False
Now, let's get to business. Notice that you need to coerce the arguments and the return values as there is no possible type these functions can really have, as ehird pointed out.
a,b,c :: x -> y
a x | unsafeCoerce x `equal` a = unsafeCoerce a
| unsafeCoerce x `equal` b = unsafeCoerce c
| unsafeCoerce x `equal` c = unsafeCoerce a
b x | unsafeCoerce x `equal` a = unsafeCoerce a
| unsafeCoerce x `equal` b = unsafeCoerce a
| unsafeCoerce x `equal` c = unsafeCoerce c
c x | unsafeCoerce x `equal` a = unsafeCoerce c
| unsafeCoerce x `equal` b = unsafeCoerce b
| unsafeCoerce x `equal` c = unsafeCoerce c
Finally, some tests:
test = a (c b) `equal` c -- Evaluates to True
test' = a (c b) `equal` a -- Evaluates to False
Ehh...
As noted, functions can't be compared for equality. If you simply want functions that satisfy the algebraic laws in your specificiation, making them all equal to the identity function will do nicely.
I hope you are aware that if you post a homework-related question to Stack Overflow, the community expects you to identify it as such.