0

I want to append one list element in nested list:

predicates  
  append(li,li,li).

clauses 
 append([X|Y],Z,[X|W]):- append(Y,Z,W).
 append([],X,X).  

For example:

append([ [1],[2],[3] ],[4],A)
Solution: A = [ [1],[2],[3],[4] ]

Turbo Prolog said: Type Error.

How can I do this?

Fred Foo
  • 355,277
  • 75
  • 744
  • 836
azh
  • 13
  • 1
  • 1
  • 4

2 Answers2

1

The problem is that you are defining the domains wrong, and that you are also appending two different domains (a list of list of integers with a list of integers).

If what you want is to append lists of lists of integers (as it seems from your example) the code should be

domains
li = integer*
lili = li*

predicates
  append(lili, lili, lili).

clauses
append([X|Y],Z,[X|W]):- append(Y,Z,W).
append([],X,X).

and then in the example the second list should be a list of a lists two, yielding:

append([ [1],[2],[3] ],[[4]],A).
Solution: A = [ [1],[2],[3],[4] ]

Note that the second list is [[4]] instead of [4].

gusbro
  • 22,357
  • 35
  • 46
  • Shouldn't that be `li = integer*`, `lili = li*`? – Fred Foo Apr 29 '11 at 13:52
  • @larsmans: Well, I'm no Turbo Prolog expert, but the way I see my definition, the domain li is a list of lili, and lili is a list of integers, so the append predicate uses li (that is a list of lists of integers). Besides, I tried it on a Turbo Prolog system and it works fine :) – gusbro Apr 29 '11 at 13:58
  • 1
    @larsmans: I reversed the names of the domains (that is, now lili is a list of li and li is a list of integers instead of the opposite), because I reread your comment and I guess you where talking about the semantics of the name (not the definition). – gusbro Apr 29 '11 at 14:01
  • but how create from [4] => [[4]]? – azh Apr 29 '11 at 17:15
  • Just enclose the term in square brackets. ie. if you have a variable MyVar that has the list [4], use [MyVar] instead of MyVar when calling append. – gusbro Apr 29 '11 at 17:27
  • I use [x] in append([],X,[X]) TP said error. How can I change my source to use []? – azh Apr 29 '11 at 18:01
  • @user701154. Not in the definition of append. You have to enclose in square brackets if want to *call* append. For example: append( [[1], [2], [3]], [[4]], A). Look that both arguments are lists of lists of integers. – gusbro Apr 29 '11 at 18:04
  • The definition of append is right, don't change it. What is wrong is when you are trying to call append, you have to use a list of lists in each argument. – gusbro Apr 29 '11 at 18:05
0

Try this.

clauses
 append([X|Y],Z,[X|W]):- append(Y,Z,W).
 append([],X,[X]). 

The result you expect is list of list's. So if the code steps into second predicate it should form right type - in your code it was simple argument transaction. The right thing is to wrap it into another list to fill later with items from first 'argument'.

Mark Huk
  • 2,379
  • 21
  • 28