Prolog - Binary addition? - binary

I need to write a Prolog predicate which calculate the sum of 2 binary numbers represented in list.
The lists are already reversed, for example ([0,1] base 2) = (2 base 10).
It should work with mode binary_plus(+,+,-), for example
?- binary_plus([1,1],[1],X).
X = [0,0,1].
and with mode binary_plus(-,-,+), for example
?- binary_plus(X,X,[0,1]).
X = [1].
Im not allowed using cut sign,findall,negation,or if-then-else.
Here is my code:
is_binary([]).
is_binary([X]):- X is 1.
is_binary([X|Xs]):-
append(_,[1],Xs),
member(X,[0,1]),
is_binary(Xs).
binary_plus([],X,X):-
is_binary(X).
binary_plus(X,[],X):-
is_binary(X).
binary_plus([0|Xs],[Y|Ys],[Y|Zs]):-
binary_plus(Xs,Ys,Zs).
binary_plus([1|Xs],[0|Ys],[1|Zs]):-
binary_plus(Xs,Ys,Zs).
binary_plus([1|Xs],[1|Ys],[0|Zs]):-
binary_plus(Xs,[1],Ws),
binary_plus(Ws,Ys,Zs).
I dont know where i'm wrong because there are some strange issues that i cant solve,
so if someone could help me i would appreciate it.
Thanks.

When describing lists, always consider using DCG notation. For example, in your case, consider writing this as:
:- use_module(library(clpfd)).
binary_addition(Xs, Ys, As) :-
phrase(binary_addition_(Xs, Ys, 0), As).
binary_addition_([], [], 0) --> [].
binary_addition_([], [], 1) --> [1].
binary_addition_([X|Xs], [], C) --> binary_addition_([X|Xs], [C], 0).
binary_addition_([], [Y|Ys], C) --> binary_addition_([C], [Y|Ys], 0).
binary_addition_([X|Xs], [Y|Ys], C0) -->
{ [X,Y] ins 0..1,
Sum #= X + Y + C0 },
sum_carry(Sum, C),
binary_addition_(Xs, Ys, C).
sum_carry(0, 0) --> [0].
sum_carry(1, 0) --> [1].
sum_carry(2, 1) --> [0].
Example queries and their solutions:
?- binary_addition([1,0],[0,1,1], Sum).
Sum = [1, 1, 1] .
?- binary_addition([1,1],[1,0,1], Sum).
Sum = [0, 0, 0, 1] .
?- binary_addition([0,1],[1,1], Sum).
Sum = [1, 0, 1] .
Notice that it also works in the other direction:
?- binary_addition(Xs, Ys, [1,1]).
Xs = [1, 1],
Ys = [] ;
Xs = [],
Ys = [1, 1] ;
Xs = [_G2510, 1],
Ys = [_G2522],
_G2510 in 0..1,
_G2510+_G2522#=1,
_G2522 in 0..1 ;
etc.
You can simply add a reverse/2 goal to binary_addition/3 if you want the reverse list.

Here my take on binary-addition-without-anything. I understand that you are not to use clpfd:
binary_plus(A,B,C) :- binary_plus_0(A,B,C).
binary_plus_0([], [], []).
binary_plus_0([], [B|Bs],[B|Bs]).
binary_plus_0([A|As],[], [A|As]).
binary_plus_0([A|As],[B|Bs],[C|Cs]) :- binary_plus_0(A,B,C,As,Bs,Cs).
binary_plus_0(0,0,0,As,Bs,Cs) :- binary_plus_0(As,Bs,Cs).
binary_plus_0(0,1,1,As,Bs,Cs) :- binary_plus_0(As,Bs,Cs).
binary_plus_0(1,0,1,As,Bs,Cs) :- binary_plus_0(As,Bs,Cs).
binary_plus_0(1,1,0,As,Bs,Cs) :- binary_plus_1(As,Bs,Cs).
binary_plus_1([], [], [1]).
binary_plus_1([], [B|Bs],Cs) :- binary_plus_0([1],[B|Bs],Cs).
binary_plus_1([A|As],[], Cs) :- binary_plus_0([A|As],[1],Cs).
binary_plus_1([A|As],[B|Bs],[C|Cs]) :- binary_plus_1(A,B,C,As,Bs,Cs).
binary_plus_1(0,0,1,As,Bs,Cs) :- binary_plus_0(As,Bs,Cs).
binary_plus_1(0,1,0,As,Bs,Cs) :- binary_plus_1(As,Bs,Cs).
binary_plus_1(1,0,0,As,Bs,Cs) :- binary_plus_1(As,Bs,Cs).
binary_plus_1(1,1,1,As,Bs,Cs) :- binary_plus_1(As,Bs,Cs).

Related

Python: about [:] and its behavior in a function

def call(nums):
nums[:] = [x for x in nums if x != 4]
numbers = [4, 5]
print(numbers)
call(numbers)
print(numbers)
The output for the above code is:
[4, 5]
[5]
But if you remove the "[:]", the output becomes the following:
[4, 5]
[4, 5]
I know that [:] makes a copy of the full list, but why the function argument is modified in one case and not in the other?
As you suspected the issue is hiding in the slicer in line:
nums[:] = [x for x in nums if x != 4]
Python is "pass by value" which means that you're not passing the pointer numbers into the function, but a copy of it. So re-assigning a value to a copy of the reference will not change the original reference.
But, when you use the slicer, you're accessing the object behind the reference and changing it directly which is why you see the side effect after you exit the function - when using the "slice".
As Python passes objects by reference, when you execute your function with nums[:] = ... line, you change actual list that you've passed from outside, numbers. When you change line to nums = ..., you just overwrite local variable called nums, without affecting numbers array.
In Python, you can not only slice collections to read them, but you can assign to slices, replacing sliced content.
For example:
>>> a = [0, 1, 2, 3, 4, 5]
>>> a[1:4]
[1, 2, 3]
If you assign to slice, it will replace part of original array:
>>> a[1:4] = ['z']
>>> a
[0, 'z', 4, 5]
But when assigning to slices, array remains the same:
>>> a = [0, 1, 2, 3, 4, 5]
>>> b = a
>>> a[:] = ['z']
>>> a
['z']
>>> b
['z']
As you can see, a and b change at the same time, because when assigning to slice, you don't change object's identity, you only change its contents.
>>> a = [0, 1, 2, 3, 4, 5]
>>> b = a
>>> a = ['z']
>>> a
['z']
>>> b
[0, 1, 2, 3, 4, 5]
This is not the case when you just assign to variable, dropping older array out of scope.
def call(nums):
nums = [x for x in nums if x != 4]
Would only change the value of the name nums function parameter which would accomplish nothing.
def call(nums):
nums[:] = [x for x in nums if x != 4]
Changes the actual value of the list passed in as an argument.

Binary to decimal - prolog

I found this on stack: reversible "binary to number" predicate
But I don't understand
:- use_module(library(clpfd)).
binary_number(Bs0, N) :-
reverse(Bs0, Bs),
binary_number(Bs, 0, 0, N).
binary_number([], _, N, N).
binary_number([B|Bs], I0, N0, N) :-
B in 0..1,
N1 #= N0 + (2^I0)*B,
I1 #= I0 + 1,
binary_number(Bs, I1, N1, N).
Example queries:
?- binary_number([1,0,1], N).
N = 5.
?- binary_number(Bs, 5).
Bs = [1, 0, 1] .
Could somebody explain me the code
Especialy this : binary_number([], _, N, N). (The _ )
Also what does library(clpfd) do ?
And why reverse(Bs0, Bs) ? I took it away it still works fine...
thx in advance
In the original, binary_number([], _, N, N)., the _ means you don't care what the value of the variable is. If you used, binary_number([], X, N, N). (not caring what X is), Prolog would issue a singleton variable warning. Also, what this predicate clause says is that when the first argument is [] (the empty list), then the 3rd and 4th arguments are unified.
As explained in the comments, use_module(library(clpfd)) causes Prolog to use the library for Constraint Logic Programming over Finite Domains. You can also find lots of good info on it via Google search of "prolog clpfd".
Normally, in Prolog, arithmetic expressions of comparison require that the expressions be fully instantiated:
X + Y =:= Z + 2. % Requires X, Y, and Z to be instantiated
Prolog would evaluate and do the comparison and yield true or false. It would throw an error if any of these variables were not instantiated. Likewise, for assignment, the is/2 predicate requires that the right hand side expression be fully evaluable with specific variables all instantiated:
Z is X + Y. % Requires X and Y to be instantiated
Using CLPFD you can have Prolog "explore" solutions for you. And you can further specify what domain you'd like to restrict the variables to. So, you can say X + Y #= Z + 2 and Prolog can enumerate possible solutions in X, Y, and Z.
As an aside, the original implementation could be refactored a little to avoid the exponentiation each time and to eliminate the reverse:
:- use_module(library(clpfd)).
binary_number(Bin, N) :-
binary_number(Bin, 0, N).
binary_number([], N, N).
binary_number([Bit|Bits], Acc, N) :-
Bit in 0..1,
Acc1 #= Acc*2 + Bit,
binary_number(Bits, Acc1, N).
This works well for queries such as:
| ?- binary_number([1,0,1,0], N).
N = 10 ? ;
no
| ?- binary_number(B, 10).
B = [1,0,1,0] ? ;
B = [0,1,0,1,0] ? ;
B = [0,0,1,0,1,0] ? ;
...
But it has termination issues, as pointed out in the comments, for cases such as, Bs = [1|_], N #=< 5, binary_number(Bs, N). A solution was presented by #false which simply modifies the above helps solve those termination issues. I'll reiterate that solution here for convenience:
:- use_module(library(clpfd)).
binary_number(Bits, N) :-
binary_number_min(Bits, 0,N, N).
binary_number_min([], N,N, _M).
binary_number_min([Bit|Bits], N0,N, M) :-
Bit in 0..1,
N1 #= N0*2 + Bit,
M #>= N1,
binary_number_min(Bits, N1,N, M).

Recursive definition of a vector

I would like to define a list using a for loop and I need to do it using a function of the n-iterate.
I have:
Initialization
In[176]: Subscript[y, 0] = {1, 2, 3}
Out[180]: {1,2,3}
The function:
In[181]: F[n_] := For[l = 1, l++, l <= 3, Subscript[y, n + 1][[l]] :=Subscript[y, n][[l]]+ n]
I call the function
F[0]
and I get:
In[183]: Subscript[y, 1]
Out[183]: Subscript[0, 1]
I should have {1,2,3}.
Anyone know why it isn't working as it should?
I have troubles recreating your error, problem.
I understand you want to add n to your vector, where n is the number of the subscript.
Here's another way to have a go at your question, avoiding the loop and the subscripts:
Clear#y;
y[0] = {1, 2, 3};
y[n_Integer] : =y[n - 1] + n
(as Plus is Listable, you can just add n to the vector, avoiding the For)
and then call it using, e.g.
y[0]
{1,2,3}
or
y[5]
{16,17,18}
Alternatively, using memoization, you could define y as follows:
y[n_Integer] := y[n] = y[n - 1] + n
This will then store already calculated values (check ?y after executing e.g. y[5]). Don't forget to Clear y, if y changes.
Obviously, for a function as this one, you might want to consider:
y[n_Integer] := y[0] + Total[Range[n]]

prolog all binary numbers

i need a predicate that will produce all the binary number of N digits .
For instance the predicate binary(2,L)
will return L = [[0, 0], [0, 1], [1, 0], [1, 1]].
please do not use findall ....
Once you have a list representing all the numbers with N bits, generating all the numbers of N+1 bits is just a matter of unfolding every N-number [a,b,c,...] into two N+1-numbers: [0,a,b,c,...] and [1,a,b,c,...].
Update:
unfold([], []).
unfold([H|T], [[0|H], [1|H]|L]) :-
unfold(T, L).
bn(N, L) :-
( N = 0
-> L = [[]]
; N1 is N - 1,
bn(N1, L1),
unfold(L1, L)
).
If you need to avoid findall/3, then you need an aggregator to collect the binary numbers:
binary(N, L) :-
collect_binaries(N, [], L).
You then generate one binary at a time and check whether it's already present in the aggregated list:
collect_binaries(N, R, L) :-
length(B, N),
make_binary(B), % make binary of length N
\+ memberchk(B, R),
!,
collect_binaries(N, [B|R], L).
If generating another binary fails, you are done:
collect_binaries(_, L, L).
Generating binaries is simple (I'm using the format you gave in your question: a list of 0/1 values). You iterate over all positions in the list and use either 1 or 0:
make_binary([]).
make_binary([H|T]) :-
member(H, [1,0]),
make_binary(T).
Result:
?- binary(2, L).
L = [[0, 0], [0, 1], [1, 0], [1, 1]]
Yes (0.00s cpu)

plotting on the y-axis in Mathematica

I have another question about Wolfram Mathematica. Is there someone that knows how I can plot a graphic on the y axis?
I hope that the figure helps.
ParametricPlot[{5 Sin[y], y}, {y, -2 \[Pi], 2 \[Pi]},
Frame -> True, AxesLabel -> {"x", "y"}]
EDIT
None of the answers given thus far can work with Plot's Filling option. Plot's output contains a GraphicsComplex in that case (which, incidentally, breaks Mr.Wizard's replacements). To get the filling capability (it doesn't work for a standard plot without filling) you could use the following:
Plot[Sin[x], {x, 0, 2 \[Pi]}, Filling -> Axis] /. List[x_, y_] -> List[y, x]
Plot[{Sin[x], .5 Sin[2 x]}, {x, 0, 2 \[Pi]}, Filling -> {1 -> {2}}]
/. List[x_, y_] -> List[y, x]
You can flip the axes after plotting with Reverse:
g = Plot[Sin[x], {x, 0, 9}];
Show[g /. x_Line :> Reverse[x, 3], PlotRange -> Automatic]
With a minor change this works for plots using Filling as well:
g1 = Plot[{Sin[x], .5 Sin[2 x]}, {x, 0, 2 \[Pi]}];
g2 = Plot[{Sin[x], .5 Sin[2 x]}, {x, 0, 2 \[Pi]}, Filling -> {1 -> {2}}];
Show[# /. x_Line | x_GraphicsComplex :> x~Reverse~3,
PlotRange -> Automatic] & /# {g1, g2}
(It may be more robust to replace the RHS of :> with MapAt[#~Reverse~2 &, x, 1])
As a Function
Here is the form I recommend one use. It includes flipping of the original PlotRange rather than forcing PlotRange -> All:
axisFlip = # /. {
x_Line | x_GraphicsComplex :>
MapAt[#~Reverse~2 &, x, 1],
x : (PlotRange -> _) :>
x~Reverse~2 } &;
To be used like: axisFlip # g1 or axisFlip # {g1, g2}
A different effect can be had with Rotate:
Show[g /. x_Line :> Rotate[x, Pi/2, {0,0}], PlotRange -> Automatic]
One possibility is to use a ParametricPlot like this:
ParametricPlot[
{-y*Exp[-y^2], y}, {y, -0.3, 4},
PlotRange -> {{-2, 2}, All},
AxesLabel -> {"x", "y"},
AspectRatio -> 1/4
]
Just for fun:
ContourPlot is another alternative.
Using Thies function:
ContourPlot[-y*Exp[-y^2/2] - x == 0,
{x, -2, 2}, {y, 0, 4},
Axes -> True, Frame -> None]
RegionPlot is another
RegionPlot[-y*Exp[-y^2/2] > x,
{x, -2.1, 2.1}, {y, -.1, 4.1},
Axes -> True, Frame -> None, PlotStyle -> White,
PlotRange -> {{-2, 2}, {0, 4}}]
And finally, a REALLY convoluted way using ListCurvePathPlot and Solve:
Off[Solve::ifun, FindMaxValue::fmgz];
ListCurvePathPlot[
Join ##
Table[
{x, y} /. Solve[-y*Exp[-y^2/2] == x, y],
{x, FindMaxValue[-y*Exp[-y^2/2], y], 0, .01}],
PlotRange -> {{-2, 2}, {0, 4}}]
On[Solve::ifun, FindMaxValue::fmgz];
Off Topic
Answer to Sjoerd's None of the answers given thus far can work with Plot's Filling option.
Reply: Not necessary
f={.5 Sin[2 y],Sin[y]};
RegionPlot[Min#f<=x<=Max#f,{x,-1,1},{y,-0.1,2.1 Pi},
Axes->True,Frame->None,
PlotRange->{{-2,2},{0,2 Pi}},
PlotPoints->500]
Depending on how you wanted the axis labels to show, you could just wrap the code for the original Plot in the Rotate function.