Prolog binary addition without cuts(!) - binary

I am trying to figure out how to add two binary numbers together which are represented as lists. For example:
addNumbers([1,0,1], [1,1,0,0], X). should return X = [1,0,0,0,1].
We are not aloud to use cuts(!) to solve this problem. So I know I have to implement a adder of sorts. Right now I have adding Digits implemented with its needed predicates:
addDigits(A,B,X,Y) :- myXor(A,B,X), myAnd(A,B,Y).
myAnd(A,B,R) :- A == 1, B == 1, R is 1.
myAnd(A,B,R) :- A == 0, B == 0, R is 0.
myAnd(A,B,R) :- A == 1, B == 0, R is 0.
myAnd(A,B,R) :- A == 0, B == 1, R is 0.
myOr(A,B,R) :- A == 0, B == 0, R is 0.
myOr(A,B,R) :- A == 0, B == 1, R is 1.
myOr(A,B,R) :- A == 1, B == 0, R is 1.
myor(A,B,R) :- A == 1, B == 1, R is 1.
This correctly returns X as the sum of the 2 binary digits and Y as the carry. Now I know I need this for my adder. Now to actually implement addDigits is where I am stuck. This is currently what I have but does not work. NOTE: The hint was the start the the LSB's but I currently don't do that.
addNumbers([HA|TA],[HB|TB],X) :- adder(HA,HB,Cin,Sum,Cout,X),
append(Sum, X, X),
addNumbers(TA,TB,X).
adder(X,Y,Cin,Sum,Cout) :- addDigits(X,Y,Sum1,Carry1),
addDigits(Sum1, Cin, Sum, Carry2),
myOr(Carry1, Carry2, Cout).
Any help/suggestions would be appreciated.
Cheers

You are on a good track. Your major problem is to understand typical Prolog recursion.
But first, your binary functions: They are correct, but it's easier and more readable like this (you are missing this one anyway):
myXor(1,0,1).
myXor(0,1,1).
myXor(1,1,0).
myXor(0,0,0).
There is a typo in your myOr in the fourth case: you spelled it with a lower case "o". With this defined, your adder does indeed work correctly!
Now, about the recursion: You really need to start with the LSB, otherwise you can't even know which bits to add, because the numbers are not necessarily the same length. Fortunately, you can do this easily by wrapping the call in reverses:
addNumbers(N1, N2, Sum) :-
reverse(N1, N12),
reverse(N2, N22),
addNumbers(N12, N22, 0, [], Sum0),
reverse(Sum0, Sum).
This is quite a common pattern in Prolog: addNumbers/3 calling addNumbers/5 with more parameters needed for the recursion. The "0" is the initial carry, the [] is the accumulator for the result.
Here is addNumbers/5, with some changes from your version:
addNumbers([HA|TA],[HB|TB],Cin,X0,X) :-
adder(HA,HB,Cin,Sum,Cout),
append(X0, [Sum], X1),
addNumbers(TA,TB,Cout,X1,X).
First, note that you need to receive Cin as an input parameter here! Also, we have X0 as an "accumulator" variable, that is, it grows longer with each recursive call. The final call will have the result, so it can make it into the output variable. For that, you also need the base cases:
addNumbers([],B,Cin,X0,X) :- % TODO: Respect Cin
append(X0,B,X).
addNumbers(A,[],Cin,X0,X) :- % TODO: Respect Cin
append(X0,A,X).
See how the result of append is not X1 (another intermediate variable) as above, but X? This is because its the final result, and it will be unified with the same X all the way down the call stack, and this way it becomes the output of the whole addNumbers/5 call!
I left it unfinished though, so that there is some (little) work for you left: Also the base cases need to take Cin into account...

Related

Is using base case variable in a recursive function important?

I'm currently learning about recursion, it's pretty hard to understand. I found a very common example for it:
function factorial(N)
local Value
if N == 0 then
Value = 1
else
Value = N * factorial(N - 1)
end
return Value
end
print(factorial(3))
N == 0 is the base case. But when i changed it into N == 1, the result is still remains the same. (it will print 6).
Is using the base case important? (will it break or something?)
What's the difference between using N == 0 (base case) and N == 1?
That's just a coincidence, since 1 * 1 = 1, so it ends up working either way.
But consider the edge-case where N = 0, if you check for N == 1, then you'd go into the else branch and calculate 0 * factorial(-1), which would lead to an endless loop.
The same would happen in both cases if you just called factorial(-1) directly, which is why you should either check for > 0 instead (effectively treating every negative value as 0 and returning 1, or add another if condition and raise an error when N is negative.
EDIT: As pointed out in another answer, your implementation is not tail-recursive, meaning it accumulates memory for every recursive functioncall until it finishes or runs out of memory.
You can make the function tail-recursive, which allows Lua to treat it pretty much like a normal loop that could run as long as it takes to calculate its result:
local function factorial(n, acc)
acc = acc or 1
if n <= 0 then
return acc
else
return factorial(n-1, acc*n)
end
return Value
end
print(factorial(3))
Note though, that in the case of factorial, it would take you way longer to run out of stack memory than to overflow Luas number data type at around 21!, so making it tail-recursive is really just a matter of training yourself to write better code.
As the above answer and comments have pointed out, it is essential to have a base-case in a recursive function; otherwise, one ends up with an infinite loop.
Also, in the case of your factorial function, it is probably more efficient to use a helper function to perform the recursion, so as to take advantage of Lua's tail-call optimizations. Since Lua conveniently allows for local functions, you can define a helper within the scope of your factorial function.
Note that this example is not meant to handle the factorials of negative numbers.
-- Requires: n is an integer greater than or equal to 0.
-- Effects : returns the factorial of n.
function fact(n)
-- Local function that will actually perform the recursion.
local function fact_helper(n, i)
-- This is the base case.
if (i == 1) then
return n
end
-- Take advantage of tail calls.
return fact_helper(n * i, i - 1)
end
-- Check for edge cases, such as fact(0) and fact(1).
if ((n == 0) or (n == 1)) then
return 1
end
return fact_helper(n, n - 1)
end

bidirectional and deterministic binary decrement

I am wondering whether its possible to implement in pure Prolog alone a binary decrementer which is bidirectional and deterministic. Example runs include and for mode (-,+):
?- dec(X,[0,0,1]).
X = [1,0,1]
?- dec(X,[1,1,1]).
X = [0,0,0,1]
And for mode (+,-):
?- dec([1,0,1],X).
X = [0,0,1]
?- dec([0,0,0,1],X).
X = [1,1,1]
Optionally none of the modes should leave any choice points. But mandatorily the implementation must be in pure Prolog alone, so no cut, no findall, no var, etc...
I already tried a definition as follows dec(X,Y) :- binary_plus([1],Y,X). using the binary adder here. But it doesn't pass the last test case, since I get dec([0,0,0,1],X). X = [1, 1, 1]; X = [1, 1, 1, 0] ; false..
The following two queries test for determinism. They do not succeed. Both run infinitely as is ; and fail with a given N. To indicate that non-termination is intended, the queries are prefixed with :/-&.
:/-& length(Bs,N), dec(Bs, Ds1), dif(Ds1, Ds2), dec(Bs, Ds2).
:/-& length(Ds,N), dec(Bs1, Ds), dif(Bs1, Bs2), dec(Bs2, Ds).
dec([1|Bs],[0|Bs]) :-
nil_or_ends_with_one(Bs).
dec([0|Bs],[1|Ds]) :-
deci(Bs, Ds).
nil_or_ends_with_one([]).
nil_or_ends_with_one([E|Es]) :-
ends_with_one(Es, E).
ends_with_one([], 1).
ends_with_one([E|Es], _) :-
ends_with_one(Es, E).
deci([1],[]).
deci([1|Bs],[0|Bs]) :-
Bs = [B|_],
ends_with_one(Bs, B).
deci([0|Bs],[1|Ds]) :-
deci(Bs, Ds).
The solution is still a bit too general, in that it accepts
?- dec([1,non_digit,1],[0,non_digit,1]).
This can be easily fixed but does not seem to be worth the cost.
I got a different solution which is not targeted towards a deep indexing Prolog, rather a flat indexing Prolog. So far all 4 test cases do not leave any choice point in Jekejeke Prolog which has full flat indexing. :-)
% check binary number
num([]).
num([X|Y]) :- dig(X, Y).
dig(1, []).
dig(T, [X|Y]) :- aux(T, X, Y).
aux(0, X, Y) :- dig(X, Y).
aux(1, X, Y) :- dig(X, Y).
% check binary number and its pseudo decrement
dec([X|Y], Z) :- dig(X, Y, Z).
dig(1, [], []).
dig(T, [X|Y], [U|V]) :- aux(T, U, V, X, Y).
aux(0, 1, Z, X, Y) :- dig(X, Y, Z).
aux(1, 0, [X|Y], X, Y) :- dig(X, Y).
https://gist.github.com/jburse/649f828c330ff3c770834ee8bca250a8#file-tarai-p
But the drawback of full flat indexing is the additional overhead when coding a predicate, to bring it into flat form. Flat form is also popular as the binary_plus/3 example shows. But the best would possibly be to have both flat and deep, and the later in a way that there exists a
deep dec/2 version which never leaves choice points.

Piecewise functions in the Octave symbolic package?

Unlike Matlab, Octave Symbolic has no piecewise function. Is there a work around? I would like to do something like this:
syms x
y = piecewise(x0, 1)
Relatedly, how does one get pieces of a piecewise function? I ran the following:
>> int (exp(-a*x), x, 0, t)
And got the following correct answer displayed and stored in a variable:
t for a = 0
-a*t
1 e
- - ----- otherwise
a a
But now I would like to access the "otherwise" part of the answer so I can factor it. How do I do that?
(Yes, I can factor it in my head, but I am practicing for when more complicated expressions come along. I am also only really looking for an approach using symbolic expressions -- even though in any single case numerics may work fine, I want to understand the symbolic approach.)
Thanks!
Matlab's piecewise function seems to be fairly new (introduced in 2016b), but it basically just looks like a glorified ternary operator. Unfortunately I don't have 2016 to check if it performs any checks on the inputs or not, but in general you can recreate a 'ternary' operator in octave by indexing into a cell using logical indexing. E.g.
{#() return_A(), #() return_B(), #() return_default()}([test1, test2, true]){1}()
Explanation:
Step 1: You put all the values of interest in a cell array. Wrap them in function handles if you want to prevent them being evaluated at the time of parsing (e.g. if you wanted the output of the ternary operator to be to produce an error)
Step 2: Index this cell array using logical indexing, where at each index you perform a logical test
Step 3: If you need a 'default' case, use a 'true' test for the last element.
Step 4: From the cell (sub)array that results from above, select the first element and 'run' the resulting function handle. Selecting the first element has the effect that if more than one tests succeed, you only pick the first result; given the 'default' test will always succeed, this also makes sure that this is not picked unless it's the first and only test that succeeds (which it does so by default).
Here are the above steps implemented into a function (appropriate sanity checks omitted here for brevity), following the same syntax as matlab's piecewise:
function Out = piecewise (varargin)
Conditions = varargin(1:2:end); % Select all 'odd' inputs
Values = varargin(2:2:end); % Select all 'even' inputs
N = length (Conditions);
if length (Values) ~= N % 'default' case has been provided
Values{end+1} = Conditions{end}; % move default return-value to 'Values'
Conditions{end} = true; % replace final (ie. default) test with true
end
% Wrap return-values into function-handles
ValFuncs = cell (1, N);
for n = 1 : N; ValFuncs{n} = #() Values{n}; end
% Grab funhandle for first successful test and call it to return its value
Out = ValFuncs([Conditions{:}]){1}();
end
Example use:
>> syms x t;
>> F = #(a) piecewise(a == 0, t, (1/a)*exp(-a*t)/a);
>> F(0)
ans = (sym) t
>> F(3)
ans = (sym)
-3⋅t
ℯ
─────
9

Call by value, name/reference, need in ML

I am studying for a final, and I have a practice problem here.
The question asks for the result of
val y = ref 1;
fun f x = (!y) + (x + x);
(f (y := (!y)+1; !y)) + (!y);
under the following parameter passing techniques:
Call by value
Call by name
Call by need.
It seems to me that for call by value, the answer is 8.
However, I believe the answer for call by name is also 8, but I would expect it to be different. The reason I think it is 8:
y := (!y)+1 derefs y as 1, adds 1, and then sets y to 2
!y in line 3 serves as the argument to f, and since it is being dereferenced it is
passed as a value rather than as a reference (this may be where I am
going wrong?)
The function call returns 6, but does not set y as y was passed in as a value from the previous step
6 is added to the dereferenced value of y, which is 2.
This returns 8
Is this the correct answer, and if not, can someone please point out where I have gone wrong? Also, can someone explain to me how call by need would work in this situation also?
Many thanks.
I found out how it works:
(y := (!y)+1; !y) is the parameter passed to f.
f then looks like:
fun f x = (!y) + ((y:= (!y)+1; !y) + (y:= (!y)+1; !y));
so this ends up being 1+2+3, and the final step + (!y) adds 3 as this is the current value of y, giving 9.
Thanks for pointing out that I was still doing call-by-value.

Bitwise comparison for 16 bitstrings

I have 16 unrelated binary strings (of the same length). eg. 100000001010, 010100010010 and so on, and I need to find out a bitstring in which position x is a 1 IF position x is 1 for ATLEAST 2 bitstrings out of the 16.
Initially, I tries using bitwise XOR and this works great as long as even number of strings contain a 1, but when odd number of strings contain 1, the answer given is reverse.
A simple example (with 3 strings) would be:
A: 10101010
B: 01010111
C: 11011011
f(A,B,C)= answer
Expected answer: 11011011
Answer I'm getting right now: 11011001
I know I'm wrong somewhere but I'm at a loss on how to proceed
Help much appreciated
You can do something like
unsigned once = x[0], twice = 0;
for (int i = 1; i < 16; ++i) {
twice |= once & x[i];
once |= x[i];
}
(A AND B) OR (A AND C) OR (B AND C)
This is higher complexity than what you had originally.