简体   繁体   中英

How to concatenate strings in Prolog

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM