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 2 years ago.
Improve this question
Can Someone help me with the code for "finding if a no is armstrong no or not using prolog programming"?
I can't seem to find a solution anywhere.
Narcissistic numbers have different aliases such as Armstrong number, pluperfect digital invariant (PPDI) or plus perfect number.
numberToDigitsR(N,_,[]):-
N < 0, !.
numberToDigitsR(N,B,[N]):-
N < B, !.
numberToDigitsR(N,B,[Mod|R]):-
Mod is N mod B,
Div is N div B,
numberToDigitsR(Div,B,R).
powerList([],_,0).
powerList([H|T],E,Sum):-
powerList(T,E,TT),
Sum is (H**E)+TT.
narcissist(N,B):-
B>1,
numberToDigitsR(N,B,D),
length(D,E),
powerList(D,E,N).
tests:
?- narcissist(54748,10).
true.
?- narcissist(54748,9).
false.
?- narcissist(62,4).
true.
?- member(B,[2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]), narcissist(54748,B).
B = 10 ;
false.
Thanks David for linking the wiki site.
The program first creates a list of the "digits" for a given number N and a given base B. Then it calculates the number of digits E and calculates the sum of each digit to the power of E. If the output equals the number N then this is a narcissistic number. If the base B is not known before, simply state the domain as shown in the last example.
Please note that this algorithm does not work for B=1.
Also note that the number N is given with decimal format. So if you look up numbers from this website, please convert the numbers to base 10 first.
Related
This is my first time asking a question on here. Sorry if I do something incorrectly.
First, I want to be up front; this is a homework question. I am not looking for anyone to do it for me. I just need help getting started.
The problem is-
Table of data
Using above information, Write a prolog program to answer the following queries.
Please note that you cannot simply answer these queries with only facts, you
should answer then using facts and rules.
A. Which country/countries has/have the largest case number?
B. Which country/countries has/have the smallest number of deaths?
C. Which country has the largest case number or the largest number of deaths?
D. Which country has the largest case number less than 5?
E. How many cases are reported for Austria?
F. How many cases are reported for the Asia?
G. How many cases are reported for the Asia and middle east?
H. Which region has the smallest case number?
I. Which region has the largest number of deaths?
J. Which regions have a smaller case number than Europe?
K. Which country/countries has/have a larger number of deaths than Iran?
L. Which country/countries has/have a larger case number and a larger number
of deaths than Iran?
M. Which country/countries has/have a larger case number or a larger number of
deaths than Iran?
N. What is the average case number in this report?
Ok so. I roughly understand how to complete the rules for how many cases are reported in X. That seems easy. But what I don't understand, is how we can traverse data and compare it in Prolog. In java for example, I would just put all the values in an array and sort it. Making this easy.
My question boils down to this:
How would you store the initial data from the table? (facts)
how would you write the rules to find the largest element?
Example for question A, using swi-prolog:
country_cases_deaths('Jordan', 35, 14).
country_cases_deaths('UK', 5, 3).
country_cases_deaths('Someplace Else', 35, 5).
country_cases_deaths('Austria', 2, 1).
country_max_cases(Country, MaxCases) :-
aggregate_all(
% Want the maximum
max(Cases),
% This is the filter
country_cases_deaths(_, Cases, _),
% Variable to put the max in
MaxCases
),
% Lookup country - could be multiple countries having the same max
country_cases_deaths(Country, MaxCases, _).
Result:
?- country_max_cases(Country, MaxCases).
Country = 'Jordan',
MaxCases = 35 ;
Country = 'Someplace Else',
MaxCases = 35.
?- findall(Country, country_max_cases(Country, _), Countries).
Countries = ['Jordan','Someplace Else'].
Some useful links: aggregate_all (click the orange "show source" icon in the top right, to see sourcecode), discussion
% dt.pl
data(japan,10).
data(usa,20).
readDatas(Datas):- findall(dt(Num,Country),data(Country,Num),Datas).
findMax(Datas,Max):-
sort(Datas,SortedDatas),reverse(SortedDatas,RevDatas),
[Max|_]=RevDatas.
:- readDatas(Datas),findMax(Datas,Max),writeln(Max).
:- halt.
$ apt install swi-prolog
$ swipl dt.pl
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 4 years ago.
Improve this question
Define a predicate that converts a number of minutes into the corresponding hours and minutes by recursively subtracting 60 from the number of minutes and incrementing the number of hours. An example of using the rule is:
?- mins_to_hours_and_mins(124, H, M).
H=2 M=4
Try this one :) The main idea is to accumulate number of hours in the predicate min by subtracting 60 from total time and when the total time is lower than 60 we can unify counted hours from accumulator with H variable and rest of time with M variable.
minutes(X,H,M):- %main predicate
min(X,0,H,M).
min(X,H,ResultH,ResultM):- %ending condition of recursion
X<60,
ResultH is H, %unification with counted hours
ResultM is X.
min(X,H,ResultM,ResultH):- %recursive predicate
X >= 60,
X2 is X-60, H2 is H+1, %subtracting from total time
min(X2,H2,ResultM,ResultH).
I would expect that the following should always be true if a comparison backtrack, right? unless it goes into an infinite loop!
?- Y=2 , random:random(1,3,X), X =\= Y.
Y = 2,
X = 1.
?- Y=2 , random:random(1,3,X), X =\= Y.
false.
but I got false!
In general, my question is why doesn't comparison backtrack?
Thanks for all the answers. My confusion seemed to come primarily from my expectation of random keep generating new-random numbers, so I confused that comparison was not backtracking, instead, the reason was that random does its thing only once and fails afterwards.
I was unaware of semi-determinate nature of some predicates.
But now I can be on a lookout ;) for cases like this. thanks again.
In your example, there is nothing to backtrack.
All predicates you are using in these examples ((=)/2, random/3 and (=\=)/2) are semi-deterministic: This means that they either fail, or succeed exactly once.
In other words, they can all succeed at most once.
Therefore, if at least one of these predicates fails, then the query fails.
To generate a succession of pseudo-random numbers on backtracking, use for example repeat/0.
Warning: random/3 is an impure predicate: It may yield different solutions even though the query is exactly the same. It may lead to failure on one invocation, and to success on another. This complicates testing and reasoning about your code considerably.
Prolog works with what are called Horn-clauses. This means that each term individually, for example Y=2, is a separate goal in a question to be answered. The result will be yes or no for each goal, and if all goals answer yes, the question is answered with yes.
What your code asks is as follows:
%Is Y equal to 2 or can it be made equal?
%Yes, Y is a variable and can be assigned the numerical atom 2
Y=2 ,
%Give me a random number between 1 and 3.
%Is X equal to the random number or can it be made equal?
%Yes, X is a variable and can be assigned the outcome atom of random:random
random:random(1,3,X),
%is the term contained within X NOT equivalent to Y?
X =\= Y.
You can check out existing comparison predicates in for example the SWI documentation or on Learn Prolog Now!.
Depending on your implementation you can use trace and write to output the actual atoms in the variables, allowing you to explore how your program actually works.
?- trace, (Y=2 , random:random(1,3,X), write(X),nl, X =\= Y). %SWI-Prolog
SWI-prolog online editor
Infinite recursion looks like p(P) :- p(P).. It has a call to the question it is supposed to solve inside the answer itself, meaning to solve for p(P) it will check p(P), which never ends.
Backtracking only happens when Prolog has choicepoints. Choicepoints are points where in the decision tree, there are MULTIPLE POSSIBLE WAYS to satisfy the question Prolog is currently processing. Prolog works from top to bottom, then left to right.
Think of a cars salesman who gets asked "which car is the best for me?". He has more than one possible car to sell you, so he'll start showing you different cars that meet your criteria. The car needs to have a transport capacity of a volume over 400 liters? All cars that don't satisfy this condition are not presented as a solution.
Prolog does a depth-first search, meaning it goes down to the first answer it finds, then checks whether there's other ways to answer it. If there is no result, the answer is no. If there is at least one solution, the answer is yes and you get all possible answers for your question. This way you only get results that satisfy a whole chain of goals you've set.
I think this will help.
% Generate random value from Min to Max(with backtrack)
rand_backtrack(Min,Max,RandVal):-
create_list(Min,Max,List),
randomize_list(List,Randomized),
length(Randomized,Len),
% Choose one Variable from Randomized (From first element to last).
% When backtrack occured, next element is chosen.
between(1,Len,Idx),
nth1(Idx,Randomized,RandVal).
% create integer order list
% [Min,Min+1,Min+2,....,Max]
create_list(Max,Max,[Max]):-!.
create_list(Min,Max,[Min|Rest]):-
Min1 is Min+1,
create_list(Min1,Max,Rest).
% shuffle List.
% result always changes.
% ex.randomize_list([1,2,3,4,5,6],R) R=[4,2,6,1,3,5]
%
randomize_list([Val],[Val]):-!.
randomize_list(List,[RandVal|RestRandomized]):-
length(List,Len),
random(1,Len,RandIdx),
nth1(RandIdx,List,RandVal),
select(RandVal, List, Rest),
!,
randomize_list(Rest,RestRandomized).
?- rand_backtrack(3,19,A).
A = 6 ;
A = 4 ;
A = 8 ;
A = 13 ;
A = 15 ;
A = 16 ;
A = 9 ;
A = 18 ;
A = 7 ;
A = 3 ;
A = 12 ;
A = 10 ;
A = 17 ;
A = 11 ;
A = 14 ;
A = 5 ;
A = 19.
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)
.