Convert to dot notation in prolog

I have to present [[fruits],[ ] ] as a dotted notation in Prolog, and below is how I did it, but something tells me it's wrong because I also expanded [[ ]] , this is not true?

 .([fruits],[[ ]] ) .(.(fruits, []),.([],[]) 
+8
list syntax prolog
source share
3 answers

In addition to what Willem wrote, you can always use write_canonical/1 to get a canonical representation of any term

For example, in your case:

 |  ? - write_canonical ([[fruits], []]).
 '.' ('.' (fruits, []), '.' ([], []))

This solves the problem and shows that you have correctly painted the list [[]] .

In particular, we have:

 |  ? - write_canonical ([[]]).
 '.' ([], [])

That's right: this is a list with one element that is equal to [] , as indicated by the first argument of the '.'/2 member '.'/2 Since this is the only element, the second argument is also [] .

+6
source share

Well, ./2 is what is in Lisp, known as cons . It contains two parameters: element head and tail. The tail may be an empty list [] or other cons .

Let's first look at the term we need to convert:

 X = [ [fruits] , [] ] 

We see an external list with two elements (for now, we will ignore these elements). This means that we have a structure like:

 X = .( Item1, .( Item2, []) ). 

Now, of course, we still need to populate Item1 and Item2 . Item2 not complicated: this is an empty list [] like this:

 Item2 = []. 

Item1 On the other hand, it is a list with one element, therefore the structure:

 Item1 = .( Item11, [] ). 

With Item11 item is this sublist. This element is fruits , so this means that:

 Item11 = fruits. 

If we put all this together, we get:

 X = .( .(fruits,[]), .([],[]) ). 

If we introduce this into the GNU-Prolog ( gprolog ), we get:

 $ gprolog GNU Prolog 1.4.5 (64 bits) Compiled Feb 5 2017, 10:30:08 with gcc By Daniel Diaz Copyright (C) 1999-2016 Daniel Diaz | ?- X = .( .(fruits,[]), .([],[]) ). X = [[fruits],[]] yes 

gprolog can thus be a validation tool, as it converts dot notation to syntactic sugar for a list.

+5
source share

Initially, there was no [] in the prologue, but vector always built using . .

Here is an example from a 1979 article by David Warren [* 36'footnote]:

  ([user]) . :- (op(1,'xfy','.')) . concatenated(nil,L,L) . concatenated((X.L1),L2,(X.L3)) :- concatenated(L1,L2,L3) . %^D 

testing and demonstration ...

  /* ((concatenated((nil),(nil),Z)) , Z == (nil)) . ((concatenated((abnil),(cdnil),Z)) , Z == (abcdnil)) . */ ?- ((concatenated((nil),(nil),Z)) , Z == (nil)) . %@ Z = nil ?- ((concatenated((abnil),(cdnil),Z)) , Z == (abcdnil)) . %@ Z = [a,b,c,d|nil] 

The above work is done in yap, eclipse, gprolog, xsb. However, this does not work in swipl (see Appendix).

concatenated , as presented in this article, is exactly the same as the implementation of the typical modern time append run, but with a different name and different end marker.

A common pattern is that each element is separated from it by a neighbor through . .

The last element is a marker indicating the end. In Warren's example, nil is a marker that indicates the end. Using nil apparently a convention, but not a requirement. Subsequent developments in the prologue replaced the use of nil as an end marker, using [] as an end marker.

Warren's example can be minimally rewritten to use [] instead of nil ...

  ([user]) . ((append([] , L , L))) . ( (append((X.L1) , L2 , (X.L3))) ) :- ( (append(L1 , L2 , L3)) ) . %^D /* ((append(([]) , ([]) , Z)) , (Z == [])) . ((append((ab[]),(cd[]),Z)) , Z == (abcd[])) . ((append((ab[]),(cd[]),Z)) , Z == [a,b,c,d]) . ((append(([a,b]),([c,d]),Z)) , Z == [a,b,c,d]) . */ ?- ((append(([]) , ([]) , Z)) , (Z == [])) . %@ Z = [] ?- ((append((ab[]),(cd[]),Z)) , Z == (abcd[])) . %@ Z = [a,b,c,d] ?- ((append((ab[]),(cd[]),Z)) , Z == [a,b,c,d]) . %@ Z = [a,b,c,d] ?- ((append(([a,b]),([c,d]),Z)) , Z == [a,b,c,d]) . %@ Z = [a,b,c,d] 

Warren continues ...

... where the list is either the atom 'nil' or a term derived from the binary functor '.' the second argument of which is a list ... we write a functor as the right operator-associative infix, so for example, the first list mentioned by [ed: (abcdnil) ] is equivalent to the standard form .(a,.(b,.(c,.(d,nil))))' (abcdnil) .(a,.(b,.(c,.(d,nil))))'

Warren provides this example ...

  ([user]) . list(nil) . list(.(X,L)) :- list(L) . %^D 

testing and demonstration ...

  /* ((List = (nil)) , (list(List))) . (\+ ((List = (a)) , (list(List)))) . ((List = (a.nil)) , (list(List))) . (\+ ((List = (nil.a)) , (list(List)))) . ((List = (nil.nil)) , (list(List))) . */ ?- ((List = (nil)) , (list(List))) . %@ List = nil ?- (\+ ((List = (a)) , (list(List)))) . %@ true ?- ((List = (a.nil)) , (list(List))) . %@ List = [a|nil] ?- (\+ ((List = (nil.a)) , (list(List)))) . %@ true ?- ((List = (nil.nil)) , (list(List))) . %@ List = [nil|nil] 

This implementation (list(L)) , now 40 years ago, does not meet the current expectations of the β€œlogical” program ...

  % does it provide a useful answer in the general case ? ?- ((List = _) , (list(List))) . %@ List = nil ? ; %@ List = [_A|nil] ? ; %@ List = [_A,_B|nil] ? ; %@ List = [_A,_B,_C|nil] ? ; %@ List = [_A,_B,_C,_D|nil] ? ; %@ !! etc ... non-terminating !! %@ ^CAction (h for help): a % is it steadfast ? ?- ((list(List)) , (List = (nil))) . %@ List = nil ? ; %@ !! hang , non-terminating !! %@ ^CAction (h for help): a 

... I do not know how to fix these problems.

When Warren writes ...

we write the functor as a right -associative infix operator, so ...

... I think that he has in mind this peculiar and useful feature of the xfy prologue ...

  ([user]) . :- ((op(10'1,'xfy','~'))) . %^D /* (((Left ~ Rest) = (a ~ b ~ c ~ d ~ e)) , (Left == a) , (Rest == (b~c~d~e))) . (((Left_1 ~ Left_2 ~ Rest) = (a ~ b ~ c ~ d ~ e)) , (Left_1 == a) , (Left_2 == b) , (Rest == (c ~ d ~ e))) . */ ?- (((Left ~ Rest) = (a ~ b ~ c ~ d ~ e)) , (Left == a) , (Rest == (b~c~d~e))) . %@ Left = a, %@ Rest = b~c~d~e ?- (((Left_1 ~ Left_2 ~ Rest) = (a ~ b ~ c ~ d ~ e)) , (Left_1 == a) , (Left_2 == b) , (Rest == (c ~ d ~ e))) . %@ Left_1 = a, %@ Left_2 = b, %@ Rest = c~d~e 

It is reasonable to expect that the yfx operator will behave in the opposite way; while xfy allows xfy to capture elements on the left and ignore the rest to the right, perhaps yfx allows yfx to capture elements on the right and ignore the rest to the left ...

  :- ((op(10'1,'yfx','~'))) . %^D /* (((Rest ~ Right) = (a ~ b ~ c ~ d ~ e)) , (Rest == a~b~c~d) , (Right == e)) . (((Rest ~ Right_2 ~ Right_1) = (a ~ b ~ c ~ d ~ e)) , (Rest == a ~ b ~ c) , (Right_2 == d) , (Right_1 == e)) . */ ?- (((Rest ~ Right) = (a ~ b ~ c ~ d ~ e)) , (Rest == a~b~c~d) , (Right == e)) . %@ Rest = a~b~c~d, %@ Right = e ?- (((Rest ~ Right_2 ~ Right_1) = (a ~ b ~ c ~ d ~ e)) , (Rest == a ~ b ~ c) , (Right_2 == d) , (Right_1 == e)) . %@ Rest = a~b~c, %@ Right_1 = e, %@ Right_2 = d 

[* 36'footnote] --- https://www.era.lib.ed.ac.uk/bitstream/handle/1842/6648/Warren1978.pdf

application

Do not try to play with . or [] in swipl, nor . nor [] do not function as described.

I reported an error for swipl about . ; assuming a mismatch with the traditional and of interest were standard prolog systems. It seems that this is not so.

https://github.com/SWI-Prolog/issues/issues/55

The author of swipl proposes the use of term_expansion , but neither the use of term_expansion nor goal_expansion can fix the following major compatibility issues.

  /* (ab[]) =[a,b] . A ={ foo:abnil } . [a,b|[c,d]] = [a,b,..[c,d]] . */ $ yap + yap YAP 6.2.2 (x86_64-linux): Wed Sep 7 07:48:47 PDT 2016 MYDDAS version MYDDAS-0.9.1 ?- (ab[]) =[a,b] . %@ yes ?- A ={ foo:abnil } . %@ A = {[foo:a,b|nil]} ?- [a,b|[c,d]] = [a,b,..[c,d]] . %@ yes ?- (halt) . % YAP execution halted $ swipl + swipl Welcome to SWI-Prolog (Multi-threaded, 64 bits, Version 7.3.27) Copyright (c) 1990-2016 University of Amsterdam, VU Amsterdam SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is LGPL free software, and you are welcome to redistribute it under certain conditions. For help, use ?- help(Topic). or ?- apropos(Word). ?- (ab[]) =[a,b] . ERROR: Type error: `dict' expected, found `a' (an atom) ?- A ={ foo:abnil } . ERROR: Type error: `dict' expected, found `a' (an atom) ?- [a,b|[c,d]] = [a,b,..[c,d]] . ERROR: Syntax error: Operator expected ERROR: [a,b|[c,d]] = [a,b,. ERROR: ** here ** ERROR: .[c,d]] . ?- (end_of_file) . % halt 

... suggesting to me that perhaps the author of swipl does not know the prolog very well (term_expansion?! ??!) or is not interested in prolog matching or is interested in setting the provider lock.

+1
source share

All Articles