2

I have to write a predicate to do work like following:

  ?- cat(north,south,X).
  X = northsouth

  ?- cat(alley,'91',Y).
  X = alley91

  ?-cat(7,uthah,H).
    Bad Input
    H = H

Please Help..

ela
  • 67
  • 1
  • 1
  • 6
  • Your predicates are writing out the desired result, but also showing , for example, `X = X` since 3rd argument serves no purpose and you are not using it (thus, you have `_` for the argument in your predicate clauses). So, `cat(X, G) :- ...`. Also note that you'd need `nl` after your last write to output a new line. – lurker Oct 31 '15 at 12:29
  • I have to make it Ternary, can not make it binary. That problem is not going away, hence asking for help. – ela Oct 31 '15 at 19:45
  • Then don't use `write` but use third argument for the result as the given answers show. – lurker Oct 31 '15 at 22:03

2 Answers2

1

atom_codes/2 it's the ISO approved predicate to convert between an atom and a list of codes. When you have 2 lists corresponding to first two arguments, append/3 (alas, not ISO approved, but AFAIK available in every Prolog), will get the list corresponding to third argument, then, convert that list to atom...

Note that, while append/3 is a 'pure' Prolog predicate, and can work with any instantiation pattern, atom_codes/2 requires at least one of it's argument instantiated. Here is a SWI-Prolog implementation of cat/3, 'working' a bit more generally. I hope it will inspire you to read more about Prolog...

ac(X,Xs) :-  when((ground(X);ground(Xs)), atom_codes(X,Xs)).
cat(X,Y,Z) :- maplist(ac, [X,Y,Z],[Xs,Ys,Zs]), append(Xs,Ys,Zs).

edit

as noted by @false I was wrong about append/3. Now I'll try to understand better what append/3 does... wow, a so simple predicate, so behaviour rich!

CapelliC
  • 59,646
  • 5
  • 47
  • 90
  • 1
    See the Prolog prologue for [`append/3`](http://www.complang.tuwien.ac.at/ulrich/iso-prolog/prologue#append). – false Oct 31 '15 at 12:33
  • 2
    `append/3` does **not** work with any instantiation pattern. As an example, consider: `append(Xs,[a],Xs)` which should fail but loops. Also `append/3` requires the first or the last argument to be instantiated (actually, a bit more than that). Otherwise it does not terminate. – false Oct 31 '15 at 13:01
  • 1
    @false: what about Xs being an attribute variable? could we control somehow the behaviour ? could be useful ? – CapelliC Oct 31 '15 at 15:59
  • 2
    All this has been experimented in MU/NU-Prolog 30 years ago and the result, I dare to say, was not very encouraging: Floundering goals all over. I am not a friend of non-termination, but it appears often preferable to floundering. If you **really** want to solve the problem you will have to study [Makanin](https://en.wikipedia.org/wiki/Unification_%28computer_science%29#cite_ref-31): General associative unification - horribly difficult to understand and implement. No way (as of today) how this can be fitted into Prolog's superfast DCG parsing. ... but maybe the problem is waiting for you :-). – false Oct 31 '15 at 16:19
  • 1
    Another attempt in that direction were some structures to this end in Prolog III, neamoins it didn't do left-recursion.... – false Oct 31 '15 at 16:25
  • 1
    Do you see where `append/3` terminates with both the first and the last argument being partial lists? – false Oct 31 '15 at 18:00
1
atom_concat_redefined(A1, A2, A3) :-
   ( nonvar(A1) -> atom_chars(A1, Chs1) ; true ),
   ( nonvar(A2) -> atom_chars(A2, Chs2) ; true ),
   ( nonvar(A1), nonvar(A2) -> true ; atom_chars(A3, Chs3) ),
   append(Chs1, Chs2, Chs3),
   atom_chars(A1, Chs1),
   atom_chars(A2, Chs2),
   atom_chars(A3, Chs3).

This definition produces the same errors in a standard conforming implementation like SICStus or GNU - there should be no other differences, apart from performance. To compare the errors use the goal:

?- catch(atom_concat_redefined(A,B,abc+1), error(E,_), true).
   E = type_error(atom,abc+1).

Note the underscore in error(E,_), which hides the implementation defined differences. Implementations provide additional information in this argument, in particular, they would reveal that atom_chars/2 or atom_concat/3 produced the error.

false
  • 10,264
  • 13
  • 101
  • 209
  • Thanks. Its working in SWI-Prolog. But in the in my compiler, its giving the error like - Undefined predicate: atom_chars/2. Any predefined predicates can not be used which is making it complex to write such a functor which can only use some basic Prolog commands. Please help.. – ela Oct 31 '15 at 19:28
  • @ela: What kind of system is this? What kind of atom-related built-ins do you have? – false Oct 31 '15 at 19:29
  • This is NU-Prolog. The source from where I am learning this language is teaching using this compiler. I am trying my code on both SWI-Prolog and NU-Prolog. Many codes seems working on SWI-Prolog , but fails on NU-Prolog. Please help.. – ela Oct 31 '15 at 19:32
  • 1
    @ela: Good gracious! That system has not been updated in the last quarter century! – false Oct 31 '15 at 19:41
  • Use `name/2` in place of `atom_chars/2`. That is not correct by a 100%, but I think that's what you can get. Alternatively use `atomToString/2` but this one delays. Not sure what you are expected to do. Maybe just: remove the nonvar part and state `atomToString` 3x first and then append. – false Oct 31 '15 at 19:45
  • Thanks a lot for your help . Finally , I got it to work. Thanks again. – ela Oct 31 '15 at 23:23