Count number of vowels in a string using Prolog - count

I am new in prolog, so i have to explain these code to my class teacher.
can someone please explain this code. Thanks
vowel(X):- member(X,[a,e,i,o,u]).
nr_vowel([],0).
nr_vowel([X|T],N):- vowel(X),nr_vowel(T,N1), N is N1+1,!.
nr_vowel([X|T],N):- nr_vowel(T,N).
output:
1 ?- nr_vowel([a,t,i,k],X).
X = 2.
https://i.stack.imgur.com/dGfU5.jpg

An explanation is indeed highly appropriate.
For example, let us ask the simplest question:
Which solutions are there at all?
Try out out, by posting the most general query where all arguments are fresh variables:
?- nr_vowel(Ls, N).
Ls = [],
N = 0 ;
Ls = [a],
N = 1.
Hm! That's probably not what you wanted to describe!
So I change your code to:
nr_vowel([], 0).
nr_vowel([X|T], N):-
vowel(X),
nr_vowel(T,N1),
N #= N1+1.
nr_vowel([X|T], N):-
nr_vowel(T,N).
Then we get:
?- nr_vowel(Ls, N).
Ls = [],
N = 0 ;
Ls = [a],
N = 1 ;
Ls = [a, a],
N = 2 ;
Ls = [a, a, a],
N = 3 ;
etc.
Looks better!
How about fair enumeration? Let's see:
?- length(Ls, _), nr_vowel(Ls, N).
Ls = [],
N = 0 ;
Ls = [a],
N = 1 ;
Ls = [e],
N = 1 ;
Ls = [i],
N = 1 ;
Ls = [o],
N = 1 ;
Ls = [u],
N = 1 ;
Ls = [_2006],
N = 0 ;
Ls = [a, a],
N = 2 ;
Ls = [a, e],
N = 2 .
The first few answers all look promising, but what about Ls = [_2006], N = 0?
This is clearly too general!
You must make your program more specific to avoid this overly general answer.
Here is the problem in a nutshell:
?- nr_vowel([X], N), X = a.
X = a,
N = 1 ;
X = a,
N = 0.
Whaaat? a is a vowel, so why is N = 0??
Here is it in a smaller nutshell:
?- nr_vowel([a], 0).
true.
Whaaaaat??
I leave adding suitable constraints to the predicate as an exercise for you.

The code is simplistic in itself, all it does is count the number of vowels in a list (Guess that's quite evident to you).
Let's take your input as an example, the list is [a,t,i,k]
When you call nr_vowel([a,t,i,k],Z), prolog searches for and unifies the query with the second nr_vowel clause, this is because it is the first clause with a non-empty list input.
Now, vowel(a) returns true, so prolog moves on to the next predicate, which calls nr_vowel([t,i,k],Z). However this time, when prolog tries to unify it with the second nr_vowel, vowel(t) returns false, so it unifies it with the third clause and behaves similarly until the list is empty.
As soon as the list is empty, prolog unifies Z with 0 and starts coming up the recursion levels and does N=N+1 depending on if the caller predicate had a vowel or not, and as soon as it reaches the top of the recursive chain, Z is unified with the final value of N.
In short -
N=N+1 happens if the head of the list is a vowel
N=N i.e. no change occurs if head of list is NOT a vowel.

Related

how iterate on an empty input in prolog?

i want to know if there are any methods to achieve an iteration in Prolog passing an empty input. For example I would like to have 0 on the first iteration, 1 on the next one, 2 on the second one and so on.
From your comment:
Example: iterate() is my query and every time i call it i want that the output is 0 first time 1 second time and so on.
Shouldn't be any more difficult than this:
increment(N) :- inc(0,1,N).
inc(C , _ , C ) .
inc(C , S , N ) :- C1 is C+S, inc(C1,S,N).
To break it down, a very common idiom in Prolog programming is the use of helper predicates. Since prolog doesn't have any sort of iteration construct, it just has recursion and backtracking, often to do something useful, you'll need to carry additional state as you go: things like the current value of a counter, etc.
So . . .
We have our increment/1 predicate. All it does is invoke a helper predicate, inc/3. It carries, in addition to the variable from the calling predicate (N), two additional pieces of state:
The current value (C) of a counter, and
The step value (S), that value by which the counter should be incremented in each recursive call.
Those bits of state are initialized with 0 and 1 respectively.
inc/3, our helper predicate has just two clauses:
inc(C , _ , C ) .
inc(C , S , N ) :- C1 is C+S, inc(C1,S,N).
What it does is this:
On initial entry to the predicate, the 1st clause of the predicate is entered, and current value of the counter is unified with N, the desired value, and succeeds.
On backtracking, that unification is undone, and the 2nd clause of the predicate is entered. That does the following:
The next value (C1) is computed as the sum of the current and step values.
inc/3 is recursively invoked, passing C1, S, and N.
You might note that this predicate is non-terminating: If you were to run inc(0,1,N), writeln(N), fail, your CPU would spin to 100% as it started writing to the console
0
1
2
3
4
. . .
Similar question
With succ/2:
nat(N) :-
nat(0, N).
nat(N, N).
nat(N0, N) :-
succ(N0, N1),
nat(N1, N).
Or with call_nth/2:
nat(0).
nat(N) :-
call_nth(repeat, N).
Now, all natural numbers:
?- nat(N).
Example: iterate() is my query and every time i call it i want that the output is 0 first time 1 second time and so on.
If you store the state in the Prolog database and don't mind the output being by side effect and can deal with not using () when calling it, then:
:- dynamic(iterate_counter/1).
iterate_counter(0).
iterate() :-
iterate_counter(X),
writeln(X),
succ(X, Y),
retract(iterate_counter(X)),
assert(iterate_counter(Y)).
?- iterate, iterate, iterate.
0
1
2
incrementing(Lower, Increment, N) :-
integer(Lower),
integer(Increment),
% Fast integer comparison
Increment #>= 1,
incrementing_(Lower, Increment, N).
incrementing_(Lower, Increment, N) :-
nonvar(N), !,
integer(N),
% Can calculate, faster than iterating
N #>= Lower,
Diff is N - Lower,
divmod(Diff, Increment, _, 0).
incrementing_(Lower, Increment, N) :-
incrementing_loop_(Lower, Increment, N).
incrementing_loop_(Lower, _Increment, Lower).
incrementing_loop_(Lower, Increment, N) :-
Lower1 is Lower + Increment,
incrementing_loop_(Lower1, Increment, N).
Results in swi-prolog:
?- incrementing(5, 3, N).
N = 5 ;
N = 8 ;
N = 11 ;
N = 14 ...
?- incrementing(5, 3, 11).
true.
?- incrementing(5, 3, 12).
false.
Could wrap this, for convenience, e.g.:
iterate(N) :-
incrementing(0, 1, N).
Results:
?- iterate(-1).
false.
?- iterate(2).
true.
?- iterate(N).
N = 0 ;
N = 1 ;
N = 2 ;
N = 3 ...

How to reverse integer in Prolog using tail-recursion?

I would like to make a predicat reverse(N,Result) in Prolog.
For example:
reverse(12345,Result).
Result = 54321.
I have to use tail-recursion. I can use *, +, - and divmod/4 and that's all.I can't use list.
I can reverse a number < 100 but I don't find how to finish my code, I can't complete my code to reverse integers bigger than 100 correctly.
reverse(N,N):-
N <10,
N>0.
reverse(N,Result):-
N > 9,
iter(N,0,Result).
iter(N,Ac,Result):-
N < 100, !,
divmod(N,10,Q,R),
R1 is R*10,
Result is Q + R1.
Can I have some help please ?
Thanks you in advance.
I suggest the use of CLP(FD), since it offers declarative reasoning over integer arithmetic and a lot of Prolog systems provide it. Concerning the digit-reversal, I recommend you take a look at entry A004086 in The On-Line Encyclopedia of Integer Sequences. In the paragraph headed FORMULA, you'll find, among others, the following formulae:
a(n) = d(n,0) with d(n,r) = if n=0 then r else d(floor(n/10),r*10+(n mod 10))
These can be translated into a predicates by adding an additional argument for the reversed number. First let's give it a nice declarative name, say digits_reversed/2. Then the relation can be expressed using #>/2, #=/2, (/)/2, +/2, mod/2 and tail-recursion:
:- use_module(library(clpfd)).
digits_reversed(N,X) :-
digits_reversed_(N,X,0).
digits_reversed_(0,R,R).
digits_reversed_(N,X,R) :-
N #> 0,
N0 #= N/10,
R1 #= R*10 + (N mod 10),
digits_reversed_(N0,X,R1).
Note that digits_reversed/2 correspond to a(n) and digits_reversed_/3 corresponds to d(n,r) in the above formulae. Now let's query the predicate with the example from your post:
?- digits_reversed(12345,R).
R = 54321 ;
false.
The predicate can also be used in the other direction, that is ask What number has been reversed to obtain 54321? However, since leading zeros of numbers are omitted one reversed number has infinitely many original numbers:
?- digits_reversed(N,54321).
N = 12345 ;
N = 123450 ;
N = 1234500 ;
N = 12345000 ;
N = 123450000 ;
N = 1234500000 ;
N = 12345000000 ;
N = 123450000000 ;
.
.
.
Even the most general query yields solutions but you'll get residual goals as an answer for numbers with more than one digit:
?- digits_reversed(N,R).
N = R, R = 0 ; % <- zero
N = R,
R in 1..9 ; % <- other one-digit numbers
N in 10..99, % <- numbers with two digits
N mod 10#=_G3123,
N/10#=_G3135,
_G3123 in 0..9,
_G3123*10#=_G3159,
_G3159 in 0..90,
_G3159+_G3135#=R,
_G3135 in 1..9,
R in 1..99 ;
N in 100..999, % <- numbers with three digits
N mod 10#=_G4782,
N/10#=_G4794,
_G4782 in 0..9,
_G4782*10#=_G4818,
_G4818 in 0..90,
_G4818+_G4845#=_G4842,
_G4845 in 0..9,
_G4794 mod 10#=_G4845,
_G4794 in 10..99,
_G4794/10#=_G4890,
_G4890 in 1..9,
_G4916+_G4890#=R,
_G4916 in 0..990,
_G4842*10#=_G4916,
_G4842 in 0..99,
R in 1..999 ;
.
.
.
To get actual numbers with the query above, you have to restrict the range of N and label it after the predicate has posted the arithmetic constraints:
?- N in 10..20, digits_reversed(N,R), label([N]).
N = 10,
R = 1 ;
N = R, R = 11 ;
N = 12,
R = 21 ;
N = 13,
R = 31 ;
N = 14,
R = 41 ;
N = 15,
R = 51 ;
N = 16,
R = 61 ;
N = 17,
R = 71 ;
N = 18,
R = 81 ;
N = 19,
R = 91 ;
N = 20,
R = 2 ;
false.
If for some reason you don't want a constraints based solution, or if you using a Prolog system not supporting constraints, an alternative solution is:
reverse_digits(N, M) :-
( integer(N) ->
reverse_digits(N, 0, M)
; integer(M),
reverse_digits(M, 0, N)
).
reverse_digits(0, M, M) :- !.
reverse_digits(N, M0, M) :-
N > 0,
R is N div 10,
M1 is M0 * 10 + N mod 10,
reverse_digits(R, M1, M).
This solution can be used with either argument bound to an integer and leaves no spurious choice-points:
?- reverse_digits(12345, M).
M = 54321.
?- reverse_digits(N, 12345).
N = 54321.
?- reverse_digits(12345, 54321).
true.
But note that this solution, unlike the constraints based solution, cannot be used as a generator of pairs of integers that satisfy the relation:
?- reverse_digits(N, M).
false.
reverseNumber(N,R):-reverse_acc(N,0,R).
reverse_acc(0,Acc,Acc).
reverse_acc(N,Acc,R):- C is N mod 10, N1 is N div 10,
Acc1 is Acc * 10 + C,
reverse_acc(N1, Acc1,R).

put a Prolog goal as input in the first argument position and returns the number of times this goal succeeds in the second argument position

As the title says I want to write a program that does this.
an example would be:
?- count(member(X,[1,2,3]), N).
N = 3
Yes
But not only for the build in member, but also for some operators like:
?- count(17 =:= 12 + 5, N).
N = 1
Yes
Can someone help me get started?
Try this:
?- findall(., Goal, Ls), length(Ls, L).
Example:
?- findall(., member(X,[1,2,3]), Ls), length(Ls, L).
L = 3,
... .
library(aggregate) has been implemented to provide solutions for your problem, and much more...
?- aggregate(count, X^member(X,[1,2,3]), N).
N = 3.
?- aggregate(count, 17 =:= 12 + 5, N).
N = 1.

Decompression of a list in prolog

I need to decompress a list in prolog , like in the example below :
decode([[a,1],[b,2],[c,1],[d,3]],L).
L = [a, b, b, c, d, d, d] ;
I made this code :
divide(L,X,Y):-length(X,1),append(X,Y,L).
divide2(L,X,Y):-divide(L,[X|_],[Y|_]).
makelist(_,N,[]):- N =< 0 .
makelist(X,Y,[X|Result]):-Y1 is Y-1,makelist(X,Y1,Result).
makelist2(L,L2):-divide2(L,X,Y),makelist(X,Y,L2).
decode([],[]).
decode([H|T],L):-makelist2(H,H2),append(H2,L,L2),decode(T,L2).
and when i call
makelist2([a,3],L2).
L2 = [a,a,a].
but when i call
decode([[a,3],[b,1],[c,4]],L)
runs continuously. What am i doing wrong ?
Another variation of the theme, using a slightly modified version of Boris' repeat/3 predicate:
% True when L is a list with N repeats of X
repeat([X, N], L) :-
length(L, N),
maplist(=(X), L).
decode(Encoded, Decoded) :-
maplist(repeat, Encoded, Expanded),
flatten(Expanded, Decoded).
If Encode = [[a,1],[b,2],[c,1],[d,3]], then in the above decode/2, the maplist/3 call will yield Expanded = [[a],[b,b],[c],[d,d,d]], and then the flatten/2 call results in Decoded = [a,b,b,c,d,d,d].
In SWI Prolog, instead of flatten/2, you can use append/2 since you only need a "flattening" at one level.
EDIT: Adding a "bidirectional" version, using a little CLPFD:
rle([], []).
rle([X], [[1,X]]).
rle([X,Y|T], [[1,X]|R]) :-
X \== Y, % use dif(X, Y) here, if available
rle([Y|T], R).
rle([X,X|T], [[N,X]|R]) :-
N #= N1 + 1,
rle([X|T], [[N1,X]|R]).
This will yield:
| ?- rle([a,a,a,b,b], L).
L = [[3,a],[2,b]] ? ;
(1 ms) no
| ?- rle(L, [[3,a],[2,b]]).
L = [a,a,a,b,b] ? ;
no
| ?- rle([a,a,a,Y,Y,Z], [X, [N,b],[M,c]]).
M = 1
N = 2
X = [3,a]
Y = b
Z = c ? a
no
| ?- rle([A,B,C], D).
D = [[1,A],[1,B],[1,C]] ? ;
C = B
D = [[1,A],[2,B]] ? ;
B = A
D = [[2,A],[1,C]] ? ;
B = A
C = A
D = [[3,A]] ? ;
(2 ms) no
| ?- rle(A, [B,C]).
A = [D,E]
B = [1,D]
C = [1,E] ? ;
A = [D,E,E]
B = [1,D]
C = [2,E] ? ;
A = [D,E,E,E]
B = [1,D]
C = [3,E] ? ;
...
| ?- rle(A, B).
A = []
B = [] ? ;
A = [C]
B = [[1,C]] ? ;
A = [C,D]
B = [[1,C],[1,D]] ? ;
...
As #mat suggests in his comment, in Prolog implementations that have dif/2, then dif(X,Y) is preferable to X \== Y above.
The problem is in the order of your append and decode in the last clause of decode. Try tracing it, or even better, trace it "by hand" to see what happens.
Another approach: see this answer. So, with repeat/3 defined as:
% True when L is a list with N repeats of X
repeat(X, N, L) :-
length(L, N),
maplist(=(X), L).
You can write your decode/2 as:
decode([], []).
decode([[X,N]|XNs], Decoded) :-
decode(XNs, Decoded_rest),
repeat(X, N, L),
append(L, Decoded_rest, Decoded).
But this is a slightly roundabout way to do it. You could define a difference-list version of repeat/3, called say repeat/4:
repeat(X, N, Reps, Reps_back) :-
( succ(N0, N)
-> Reps = [X|Reps0],
repeat(X, N0, Reps0, Reps_back)
; Reps = Reps_back
).
And then you can use a difference-list version of decode/2, decode_1/3
decode(Encoded, Decoded) :-
decode_1(Encoded, Decoded, []).
decode_1([], Decoded, Decoded).
decode_1([[X,N]|XNs], Decoded, Decoded_back) :-
repeat(X, N, Decoded, Decoded_rest),
decode_1(XNs, Decoded_rest, Decoded_back).
?- decode([[a,1],[b,2],[c,1],[d,3]],L).
L = [a, b, b, c, d, d, d].
?- decode([[a,3],[b,1],[c,0],[d,3]],L).
L = [a, a, a, b, d, d, d].
?- decode([[a,3]],L).
L = [a, a, a].
?- decode([],L).
L = [].
You can deal with both direction with this code :
:- use_module(library(lambda)).
% code from Pascal Bourguignon
packRuns([],[]).
packRuns([X],[[X]]).
packRuns([X|Rest],[XRun|Packed]):-
run(X,Rest,XRun,RRest),
packRuns(RRest,Packed).
run(Var,[],[Var],[]).
run(Var,[Var|LRest],[Var|VRest],RRest):-
run(Var,LRest,VRest,RRest).
run(Var,[Other|RRest],[Var],[Other|RRest]):-
dif(Var,Other).
%end code
pack_1(In, Out) :-
maplist(\X^Y^(X = [V|_],
Y = [V, N],
length(X, N),
maplist(=(V), X)),
In, Out).
decode(In, Out) :-
when((ground(In); ground(Out1)),pack_1(Out1, In)),
packRuns(Out, Out1).
Output :
?- decode([[a,1],[b,2],[c,1],[d,3]],L).
L = [a, b, b, c, d, d, d] .
?- decode(L, [a,b,b,c,d,d,d]).
L = [[a, 1], [b, 2], [c, 1], [d, 3]] .
a compact way:
decode(L,D) :- foldl(expand,L,[],D).
expand([S,N],L,E) :- findall(S,between(1,N,_),T), append(L,T,E).
findall/3 it's the 'old fashioned' Prolog list comprehension facility
decode is a poor name for your predicate: properly done, you predicate should be bi-directional — if you say
decode( [[a,1],[b,2],[c,3]] , L )
You should get
L = [a,b,b,c,c,c].
And if you say
decode( L , [a,b,b,c,c,c] ) .
You should get
L = [[a,1],[b,2],[c,3]].
So I'd use a different name, something like run_length_encoding/2. I might also not use a list to represent individual run lengths as [a,1] is this prolog term: .(a,.(1,[]). Just use a simple term with arity 2 — myself, I like using :/2 since it's defined as an infix operator, so you can simply say a:1.
Try this on for size:
run_length_encoding( [] , [] ) . % the run-length encoding of the empty list is the empty list.
run_length_encoding( [X|Xs] , [R|Rs] ) :- % the run-length encoding of a non-empty list is computed by
rle( Xs , X:1 , T , R ) , % - run-length encoding the prefix of the list
run_length_encoding( T , Rs ) % - and recursively run-length encoding the remainder
. % Easy!
rle( [] , C:N , [] , C:N ) . % - the run is complete when the list is exhausted.
rle( [X|Xs] , C:N , [X|Xs] , C:N ) :- % - the run is complete,
X \= C % - when we encounter a break
. %
rle( [X|Xs] , X:N , T , R ) :- % - the run continues if we haven't seen a break, so....
N1 is N+1 , % - increment the run length,
rle( Xs, X:N1, T, R ) % - and recurse down.
. % Easy!
In direct answer to the original question of, What am I doing wrong?...
When I ran the original code, any expected use case "ran indefinitely" without yielding a result.
Reading through the main predicate:
decode([],[]).
This says that [] is the result of decoding []. Sounds right.
decode([H|T],L) :- makelist2(H,H2), append(H2,L,L2), decode(T,L2).
This says that L is the result of decoding [H|T] if H2 is an expansion of H (which is what makelist2 does... perhaps - we'll go over that below), and H2 appended to this result gives another list L2 which is the decoded form of the original tail T. That doesn't sound correct. If I decode [H|T], I should (1) expand H, (2) decode T giving L2, then (3) append H to L2 giving L.
So the corrected second clause is:
decode([H|T], L) :- makelist2(H, H2), decode(T, L2), append(H2, L2, L).
Note the argument order of append/3 and that the call occurs after the decode of the tail. As Boris pointed out previously, the incorrect order of append and the recursive decode can cause the continuous running without any output as append with more uninstantiated arguments generates a large number of unneeded possibilities before decode can succeed.
But now the result is:
| ?- decode([[a,3]], L).
L = [a,a,a] ? ;
L = [a,a,a,a] ? ;
...
If you try out our other predicates by hand in the Prolog interpreter, you'll find that makelist2/2 has an issue:
It produces the correct result, but also a bunch of incorrect results. Let's have a look at makelist2/2. We can try this predicate by itself and see what happens:
| ?- makelist2([a,3], L).
L = [a,a,a] ? ;
L = [a,a,a,a] ? ;
...
There's an issue: makelist2/2 should only give the first solution, but it keeps going, giving incorrect solutions. Let's look closer at makelist/2:
makelist2(L,L2) :- divide2(L,X,Y), makelist(X,Y,L2).
It takes a list L of the form [A,N], divides it (via divide2/3) into X = A and Y = N, then calls an auxiliary, makelist(X, Y, L2).
makelist(_,N,[]):- N =< 0 .
makelist(X,Y,[X|Result]):-Y1 is Y-1,makelist(X,Y1,Result).
makelist/3 is supposed to generate a list (the third argument) by replicating the first argument the number of times given in the second argument. The second, recursive clause appears to be OK, but has one important flaw: it will succeed even if the value of Y is less than or equal to 0. Therefore, even though a correct solution is found, it keeps succeeding on incorrect solutions because the base case allows the count to be =< 0:
| ?- makelist(a,2,L).
L = [a,a] ? ;
L = [a,a,a] ? ;
We can fix makelist/2 as follows:
makelist(_,N,[]):- N =< 0 .
makelist(X,Y,[X|Result]):- Y > 0, Y1 is Y-1, makelist(X,Y1,Result).
Now the code will generate a correct result. We just needed to fix the second clause of decode/2, and the second clause of makelist/3.
| ?- decode([[a,3],[b,4]], L).
L = [a,a,a,b,b,b,b]
yes
The complete, original code with just these couple of corrections looks like this:
divide(L, X, Y) :- length(X, 1), append(X, Y, L).
divide2(L, X, Y) :- divide(L, [X|_], [Y|_]).
makelist(_, N, []) :- N =< 0 .
makelist(X, Y, [X|Result]) :- Y > 0, Y1 is Y-1, makelist(X,Y1,Result).
makelist2(L, L2) :- divide2(L, X, Y), makelist(X, Y, L2).
decode([], []).
decode([H|T], L) :- makelist2(H,H2), decode(T,L2), append(H2,L2,L).
Note some simple, direct improvements. The predicate, divide2(L, X, Y) takes a list L of two elements and yields each, individual element, X and Y. This predicate is unnecessary because, in Prolog, you can obtain these elements by simple unification: L = [X, Y]. You can try this right in the Prolog interpreter:
| ?- L = [a,3], L = [X,Y].
L = [a,3]
X = a
Y = 3
yes
We can then completely remove the divide/3 and divide2/3 predicates, and replace a call to divide2(L, X, Y) with L = [X,Y] and reduce makelist2/2 to:
makelist2(L, L2) :- L = [X, Y], makelist(X, Y, L2).
Or more simply (because we can do the unification right in the head of the clause):
makelist2([X,Y], L2) :- makelist(X, Y, L2).
You could just remove makelist2/2 and call makelist/2 directly from decode/2 by unifying H directly with its two elements, [X, N]. So the original code simplifies to:
makelist(_, N, []) :- N =< 0 .
makelist(X, Y, [X|Result]) :- Y > 0, Y1 is Y-1, makelist(X,Y1,Result).
decode([], []).
decode([[X,N]|T], L) :- makelist(X, N, H2), decode(T, L2), append(H2, L2, L).
And makelist/3 can be performed a bit more clearly using one of the methods provided in the other answers (e.g., see Boris' repeat/3 predicate).

Complex iterations in haskell

I have this complex iterations program I wrote in TI Basic to perform a basic iteration on a complex number and then give the magnitude of the result:
INPUT “SEED?”, C
INPUT “ITERATIONS?”, N
C→Z
For (I,1,N)
Z^2 + C → Z
DISP Z
DISP “MAGNITUDE”, sqrt ((real(Z)^2 + imag(Z)^2))
PAUSE
END
What I would like to do is make a Haskell version of this to wow my teacher in an assignment. I am still only learning and got this far:
fractal ::(RealFloat a) =>
(Complex a) -> (Integer a) -> [Complex a]
fractal c n | n == a = z : fractal (z^2 + c)
| otherwise = error "Finished"
What I don't know how to do is how to make it only iterate n times, so I wanted to have it count up a and then compare it to n to see if it had finished.
How would I go about this?
Newacct's answer shows the way:
fractal c n = take n $ iterate (\z -> z^2 + c) c
Iterate generates the infinite list of repeated applications.
Ex:
iterate (2*) 1 == [1, 2, 4, 8, 16, 32, ...]
Regarding the IO, you'll have to do some monadic computations.
import Data.Complex
import Control.Monad
fractal c n = take n $ iterate (\z -> z^2 + c) c
main :: IO ()
main = do
-- Print and read (you could even omit the type signatures here)
putStr "Seed: "
c <- readLn :: IO (Complex Double)
putStr "Number of iterations: "
n <- readLn :: IO Int
-- Working with each element the result list
forM_ (fractal c n) $ \current -> do
putStrLn $ show current
putStrLn $ "Magnitude: " ++ (show $ magnitude current)
Since Complex is convertible from and to strings by default, you can use readLn to read them from the console (format is Re :+ Im).
Edit: Just for fun, one could desugar the monadic syntax and type signatures which would compress the whole programm to this:
main =
(putStr "Seed: ") >> readLn >>= \c ->
(putStr "Number of iterations: ") >> readLn >>= \n ->
forM_ (take n $ iterate (\z -> z^2 + c) c) $ \current ->
putStrLn $ show current ++ "\nMagnitude: " ++ (show $ magnitude current)
Edit #2: Some Links related to plotting and Mandelbrot's sets.
Fractal plotter
Plotting with
Graphics.UI
Simplest solution
(ASCII-ART)
Well you can always generate an infinite list of results of repeated applications and take the first n of them using take. And the iterate function is useful for generating an infinite list of results of repeated applications.
If you'd like a list of values:
fractalList c n = fractalListHelper c c n
where
fractalListHelper z c 0 = []
fractalListHelper z c n = z : fractalListHelper (z^2 + c) c (n-1)
If you only care about the last result:
fractal c n = fractalHelper c c n
where
fractalHelper z c 0 = z
fractalHelper z c n = fractalHelper (z^2 + c) c (n-1)
Basically, in both cases you need a helper function to the counting and accumulation. Now I'm sure there's a better/less verbose way to do this, but I'm pretty much a Haskell newbie myself.
Edit: just for kicks, a foldr one-liner:
fractalFold c n = foldr (\c z -> z^2 + c) c (take n (repeat c))
(although, the (take n (repeat c)) thing seems kind of unnecessary, there has to be an even better way)

Resources