Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 10 years ago.
Improve this question
Mathematica is giving me a weird output when I am asking for a specific element of a nested list.
I have:
testroots = {{0, 0, 0}, {0, 0, 0}}
When I ask for
testroots[[0,0]]
which should give me a 0, instead Mathematica says
Symbol
I don't understand why this is or what I've done wrong.
Thanks!
Mathematica indices start with 1, not zero. So the [[0,0]] entry of testroots doesn't exist. You can get the first element using
testroots[[1, 1]]
As b.gatessucks and bill s already wrote, Mathematica lists start at Index 1. However the index 0 is also allowed and gives the Head of the expression. Now what does that mean?
Well, a list {a,b,c} in Mathematica is internally an expression of the Form List[a, b, c]. You can see that by applying FullForm to it:
FullForm[{a, b, c}]
(*
==> List[a, b, c]
*)
Thhe part in front of the opening bracket, here List, is called the head of the expression. And testroots[[0]] is equivalent to Head[testroots] which gives List for a list. Which makes sense, given that in the complete expression, the List precedes the elements.
However what about your expression testroots[[0,0]]? It accesses the head of the head of your list. The head of your list is List. But what is the head of List? After all, it doesn't have the form Head[arg1, arg2, ...].
For atomic expressions, Mathematica gives a symbol describing the type of the atom. For example Head[1] is Integer, Head["Hello"] is String and Head[foo] is Symbol (assuming foo has not been assigned to). Note that the head of an expression of the above form also can be considered the type of the expression. The type of a list is List, and the type of a+b, full form Plus[a, b] is Plus, that is, a sum.
Now List is a symbol, and therefore Head[List] is Symbol. Therefore for any list, like your testroots, testroots[[0,0]] will evaluate to Symbol.
To get the first element of the first element of the list, use testroots[[1,1]].
Related
I am currently practicing Prolog for an exam and when I studied old exams I came across a problem, where one had to define a predicate which returns the length of a list. (Example: lengthof([a,b,c,d,e,f],Length). evaluates to Length=6.)
My approach was the following:
lengthof([],0).
lengthof(List,LengthNew) :- lengthof([_|List],Length),LengthNew is Length-1.
But it always threw a stack overflow error. I didn't know what I could have done wrong, so I took a look into the solutions. The solution for this problem is the following:
lengthof([],0).
lengthof([_|List],LengthNew) :- lengthof(List,Length),LengthNew is Length+1.
I am now wondering why my approach did not work out. What is wrong with this one? Logically and at first look, I think, that both approaches are equivalent.
lengthof([],0).
this string means that legth of empty list is zero.
lengthof([_|List],LengthNew) :-
lengthof(List,Length),LengthNew is Length+1.
in the rule you say, that no empty list has to consider as first element (_) and other elements (List). And that length of the all list is length of "List" plus one.
But in this rule:
lengthof(List,LengthNew) :-
lengthof([_|List],Length),LengthNew is Length-1.
you say that length of initial list ("List") is length of more big list minus one.
It is true for any list, but it is no solution of your problem, because your code does not calculate length of initial list - instead of this you inclrease initial list endlessly.
Your first rule that process empty list desribes condition of recursion exit. So your second rule must decrease size of list, but you try increase it, so you receive "stack overflow" error.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 9 years ago.
Improve this question
I have to write a rule square(S) in Prolog that tests if a number S is the square of an integer returning false (ex. square(3)) or true (ex. square(4)).
I used already a rule that generates all integers between 0 and M:
isInteger(X,M) :- between(0,M,X).
Using this generator I have to write the rule square(S). How can I do it?
Thanks
This probably will not work as a solution for your homework, but here is one of many ways to do it using constraint logic programming in ECLiPSe CLP Prolog:
:- lib(gfd).
square(S) :-
sqr(_) #= S.
It means: S is a square if it's an integer and some other value (we don't care what value, so we use "throw-out" variable _) squared equals S.
All modern Prolog systems supports constraint logic programming, and the code will be similar to above.
To solve it your way, you just need to check if S is the product of your generated integer multiplied by itself. So you could do it like this:
isInteger(X,M) :- between(0,M,X).
square(N) :-
isInteger(X, N),
N is X * X.
I came up with another possible solution, using the sqrt arithmetical function from SWI-Prolog but I think there must be a more elegant one.
I initially expected it would be as simple as X is sqrt(4), integer(X). However, this doesn't work (at least not in SWI-Prolog 7.1.4), because X is unified with the float 2.0 and integer(2.0) is false (since integer is checking the data type, not the value of the number). But this works:
square_of_integer(N) :-
Int is rationalize(sqrt(N)),
integer(Int).
It depends on first giving a representation of N as a rational (which, in SWI-Prolog, 'are represented by the compound term rdiv(N,M)'). 2 is rationalize(2.0), i.e., rationalize evaluates to an integer for round numbers.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
Prolog how to add numbers in a list in a loop?
I have the loop and I would need to add the numbers into a list and render it in the end.
Prolog is a logical language and not a imperative one. You may need to formulate the problem a bit differently. By formulating what you want and not how you want it.
This is a recursive version:
the list of numbers between A and B is empty if A >= B or else
the list of numbers between A ans B is A and the list of numbers between A+1 and B
This is a version with some of prologs features.
find all numbers X between A and B
These two versions can be transferred into prolog quite directly. There is no 'loop' because prolog is not about commands (do this! do that! put that value there! increase!) but about formulating the problem.
I don't know what you mean by rendering, but you can create a list of number easily via recursion, since prolog doesn't have loops:
range_list(M,M,[M]).
range_list(M,N,[M|R]) :-
M < N ,
M1 is M+1 ,
range_list(M1,N,R)
.
range_list(M,N,[M|R]) :-
M > N ,
M1 is M-1 ,
range_list(M1,N,R)
.
You could also use built-in predicates to get what you want:
range_list(From,To,Result) :-
findall(X,between(From,To,X),Result)
.
This question already has answers here:
Flatten a list in Prolog
(7 answers)
Closed 9 years ago.
How can i combine all of the list elements from list in lists?
example
combine([[a,b,c],[d,[e,f],g],h],X).
return X = [a,b,c,d,e,f,g,h]
This is what i had try
flat([], []).
flat([First|Rest], _X):-
flat(Rest, First).
Recursively.
Define your base cases first - if you have no lists to combine you have an empty list.
combine([],[]).
and if you have a single element you have a singleton list
combine(X,[X]).
Then we define the general case - a non-empty list
combine([X|Xs], Y) :-
First we want to recursively flatten the head
combine(X,XX),
then the tail
combine(XS,XXs),
then we put these together
append(XX,XXs,Y).
We have to think carefully about how we put this together. The base case for the singleton element wants to appear last. When matching rules Prolog will match the first that applies - the base case with a singleton element will match a list, so we put this after this case to stop it matching in this case. Finally giving us:
combine([],[]).
combine([X|Xs],Y) :- combine(X,XX), combine(Xs,XXs), append(XX,XXs,Y).
combine(X,[X]).
While learning Prolog, I'm trying to solve the following problem, using accumulators:
Write a predicate addone2/ whose first argument is a list of integers, and whose second argument is the list of integers obtained by adding 1 to each integer in the first list. For example, the query
addone([1,2,7,2],X).
should give
X = [2,3,8,3].
I created the following code:
addone([], _).
addone([E|Tail], [R|Rs]) :-
NewE is E+1,
append([R|Rs], [NewE], NewRs),
addone(Tail, NewRs).
But it's not working. Can someone tell me why? So, how do I use accumulators in Prolog?
Thanks!
anthares is correct in that you have to refine your base case. However, you are also making things very inefficiently with your append calls. In Prolog, it takes some time to get used to the power of unification, but for example, in this case it helps you to immediately set up your result list. Try the following:
addone([E|Tail], [E1|Rs]) :-
E1 is E+1,
addone(Tail, Rs).
That's really all there is to it. By immediately placing E1 in your second argument's pattern, you have already created the first element of your result list. The remaining elements Rs will be created during the recursion. A very typical Prolog pattern.
The bottom of your recursion should be addone([],[]). in order NewRs to be connected with the []