mndrix / golog

Prolog interpreter in Go
MIT License
374 stars 39 forks source link

Fix printing list of ints #25

Closed kuba-- closed 4 years ago

kuba-- commented 4 years ago

There is an issue in printing list of ints, because Compound's String method first checks if term is a String and later if it's a List. Unfortunately for list of ints, e.g. [1, 2, 3] the function func IsString(t Term) bool returns true, because it loops over ints unless we get an empty list:

//...
        args := c.Arguments()
        if !IsInteger(args[0]) {
            return false
        }
        if IsCompound(args[1]) {
            c = args[1].(*Compound)
        } else if IsEmptyList(args[1]) {
            break
        } 

And of course printing the Compound [1,2,3] as a String gives us wrong result. For instance:

append([65], [66,67], List).

gives [ABC], instead of [65,66,67].

Anyway, I'm not sure if this is 100% correct fix (maybe there is a more elegant way to do it), but so far it works fine if I replace in func (self *Compound) String() string an order of if-checks. First check if the term is a List and later if it's a String.

mndrix commented 4 years ago

Thanks for investigating this and for the patch. Unfortunately, this is a quirk of Prolog. Strings and lists of integers are indistinguishable at the language level so you have to use heuristics to guess whether a list of integers should be displayed as a string or not.

Your example is an excellent one:

append([65], [66,67], List).

Unfortunately, good arguments can be made for both List="ABC" and List=[65,66,67]. In the end, it's a weakness in the language design, so I'm going to favor the status quo and leave the code as is. Sorry.