I'm trying to make an IO-related exercise in Prolog but find it difficult working with strings.
The task is to take an input (an integer 1<=n<=180) and write is as a sum of three terms k*d where k=1,2, or 3 and 1<=d<=20.
For instance:
input: 180
output: triple 20, triple 20, triple 20
input: 96
output: triple 19, double 15, single 9
My problem is that I get error message:
"[some predicate I have tried]: Arguments are not sufficiently instantiated".
Last thing I tried was a concatenate-predicate I found on another thread at StackOverflow Concatenation of Strings in Prolog . I think it looks nice but I still have the same problem. See my code below.
Before I used string_concat/3 instead.
main :-
repeat,
read(X),
(
X == end_of_file
;
integer(X),
dart_scores(X,N),
write(N),
fail
).
dart_scores(X,N) :-
concatenate([A1,B1,C1],N),
concatenate(["single", A], A1),
concatenate(["double", B], B1),
concatenate(["triple", C], C1),
find_values(X,A,B,C).
find_values(X,A,B,C) :-
X is A+B*2+C*3,
in_domain(A),
in_domain(B),
in_domain(C).
in_domain(D) :-
integer(D),
D>=1,
20>=D.
concatenate(StringList, StringResult) :-
maplist(atom_chars, StringList, Lists),
append(Lists, List),
atom_chars(StringResult, List).
The error you have has nothing to with string concatenation. I have modified your find_values
and in_domain
predicate to get rid of the error. The problem with your in_domain
predicate is that it does not "generate" integers. As for the find_values
predicate, you need to unify first A
, B
, and C
with some integers before checking X is A+B*2+C*3
, and generate integer for "single", "double", and "triple". Hope this will help you!
main :-
repeat,
read(X),
(
X == end_of_file
;
integer(X),
dart_scores(X,N),
write(N) /*,
fail */
).
dart_scores(R,N) :-
find_values(R,A,B,C,X,Y,Z),
mult(X, A1),
mult(Y, B1),
mult(Z, C1),
concatenate([A1,A], A2),
concatenate([B1,B], B2),
concatenate([C1,C], C2),
concatenate([A2,B2,C2],N).
mult(1, "single").
mult(2, "double").
mult(3, "triple").
find_values(R,A,B,C,X,Y,Z) :-
in_domain(A),
in_domain(B),
in_domain(C),
range(X,1,3),
range(Y,1,3),
range(Z,1,3),
R is A*X+B*Y+C*Z.
in_domain(D) :-
range(D, 1, 20).
range(Low, Low, _).
range(Out, Low, High) :- NewLow is Low+1, NewLow =< High, range(Out, NewLow, High).
concatenate(StringList, StringResult) :-
maplist(atom_chars, StringList, Lists),
append(Lists, List),
atom_chars(StringResult, List).
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.