6.2 Relations

Below is a simple example of using =? on lists.

| ?? [a,b] =? X <> Y::(#Y=1) <> Z.

X = [] : list(_)
Y = [a] : list(atom)
Z = [b] : list(atom)
...
X = [a] : list(atom)
Y = [b] : list(atom)
Z = [] : list(_)

The query is asking to split the list [a,b] into 3 lists with the middle being of length 1. There are 2 solutions to this query and both are shown.

Semantically, QuLog tries all ways of splitting up the list into sublists that match the patterns and for which the tests are true.

Below is an example using =? on strings from examples/introduction/qlexamples.qlg.

rel words2(string, ?list(string))
words2(Str,[WStr]) :: Str  =? WStr/"\\w*" ++ _End/"[.?!]"    
words2(Str,[W|Words]) :: 
    Str =? 
        W/"\\w*" ++ 
        _Seps/"([,;:]?\\s+)|(\\s+)" ++ 
        RStr::words2(RStr,Words)  

words2 is a relation that takes an English sentence terminated by ., ?, ! and unifies its second argument with the strings representing the words of the sentence, ignoring punctuation.

The first rule deals with the word at the end of the sentence - the first substring must match the RE "\\w*" and the second substring must match the RE "[.?!]".

The second rule extracts the first word, consumes spaces and punctuation, and recursively calls words2 to process the rest of the sentence.

Semantically, QuLog tries all ways of splitting up the string into substring that match the patterns and for which the regular expressions match (if present) and the tests are true.

Note that each RE does a maximal length match (although we could have used lazy matching to get the shortest match) and so we get

| ?? "abc" =? A/".*" ++ B/".*".

A = "abc" : string
B = "" : string

| ?? "abc" =? A/".*" ++ B/".".

no

In both cases ".*" matches the entire list. Also note that in

| ?? "abc" =? A/".*"::(#A=1) ++ B/".*".

no

the RE matches the entire list, making A = "abc", which is not of length 1.


On This Site