Comparing RDF literals in AllegroGraph Prolog in Common Lisp - lisp

I am trying to compare the objects of two triples in a knowledgebase. I have connected the knowledgebase through ACL client (Allegro CL Enterprise edition 9.0) and written the following code:
(select (?s ?threshold ?NameMatch)
(q- ?s !mynamespace:hasNameMatch ?NameMatch)
(q- !mynamespace:hasNameMatch !mynamespace:hasThresholdValue ?threshold)
(setq return (if (>= (?NameMatch ?threshold "true" "false")))
(pprint ret))
My Knowledgebase includes the following triples
Subject Predicate Object
ns:hasAddressMatch ns:hasThresholdValue "60"
<../729277> :hasNameMatch "70"^^xsd:double
I am trying to compare the ?threshold with value "60" and ?NameMatch with value "70"^^xsd:double, and I expect the result "true". How can I do this?

In RDF data, things that aren't blank nodes or IRIs are literals. Literals may be a plain literal (a string with no additional information), a string with a language tag, or a lexical form (string part) with a datatype (an IRI).
In your data, the literal with lexical form "70" has a datatype which you've censored, but I assume is supposed to be xsd:double. I.e., the value is "70"^^xsd:double, which is the double precision floating point number 70. Your other literal value "60" is just a plain literal. It doesn't really make sense to compare those two values, since one is a number and one is a string.
You have two options though:
You could do a string comparison with the plain literal "60" and the lexical form of "70"^^xsd:double, in which case you'd use string< or string-lessp, depending on whether you want case sensitivity or not (since these are strings of digit characters, it probably doesn't matter).
You could assume that the plain literal "60" has a lexical form that's legal for an xsd:double, do the appropriate conversion, and then compare "60"^^xsd:double and "70"^^xsd:double as numbers with <.
I'd suggest that, if possible, you clean up your data (but this might not be an option if it's coming from somewhere else) so that you can do a numeric comparison with < as in (2), but without needing to do the conversion at comparison time.
In addition to those RDF concerns, your Lisp code also has some issues. if takes three arguments (the third is optional, though). The first is a test condition, and the second and third are forms that get evaluated depending on whether the first evalutes to true or not. In your code, if is only getting one argument:
(if (>= (?NameMatch ?threshold "true" "false")))
-------------------------------------------
This is trying to call >= with one argument, and that's the
(?NameMatch ?threshold "true" "false")
which would be a function call to the function named ?NameMatch with three arguments (?threshold, "true" and "false"). What you probably want here is:
(if (>= ?NameMatch ?threshold) "true" "false")
(Of course, you may still need to modify the test as described above.)

Related

What do elisp expression (1+ (buffer-size)) and (+ 1 (buffer-size)) mean?

I'm very very new in elisp and just started learning it. I have seen the following expressions in the document:
(1+ (buffer-size))
(+ 1 (buffer-size))
What do they mean? As I know elisp use prefix notation, so the second one should be correct one. But both of them can be executed without any errors. The first one is from the documentation of point-max function.
Thanks.
The token 1+ is an identifier which denotes a symbol. This symbol has a binding as a function, and so (1+ arg) means "call the 1+ function, with the value of arg as its argument). The 1+ function returns 1 plus the value of its argument.
The syntax (+ 1 arg) is a different way to achieve that effect. Here the function is named by the symbol +. The + function receives two arguments which it adds together.
In many mainstream programming languages popular today, the tokenization rules are such that there is no difference between 1+ and 1 +: both of these denote a numeric constant followed by a + token. Lisp tokenization is different. Languages in the Lisp family usually support tokens that can contain can contain digits and non-alpha-numeric characters. I'm looking at the Emacs Lisp reference manual and do not see a section about the logic which the read function uses to convert printed representations to objects. Typically, "Lispy" tokenizing behavior is something like this: token is scanned first without regard for what kind of token it is based on accumulating characters which are valid token constituents, stopping at a character which is not a token constituent. For instance when the input is abcde(f, the token that will be extracted is abcde. The ( character terminates the token (and stays in the input stream). Then, the resulting clump of characters abcde is re-examined and classified, converted to an object based on what it looks like, according to the rules of the given Lisp dialect. Across Lisp dialects, we can broadly depend on a token of all alphabetic characters to denote a symbol, and a token of all digits (possibly with a leading sign) to denote an integer. 1+ has a trailing + though, which is different!

multiple-value hash common lisp

How can I hash pairs or triples of 'eq-able objects like symbols or ints?
In python I can use tuples as dictionary keys, is there a way to do this in lisp without resorting to an 'equal test?
While some implementations might provide provisions for custom hash table functions, the standard only defines four:
18.1.1 Hash-Table Operations
There are four kinds of hash tables: those whose keys are compared with eq, those whose keys are compared with eql, those whose keys are
compared with equal, and those whose keys are compared with equalp.
That means that if you want to use the standard hash tables, then you'll probably need to use an equal or equalp hash table. I do notice that you wrote:
How can I hash pairs or triples of 'eq-able objects like symbols or
ints?
While symbols can be compared reliably with eq, you shouldn't compare numbers with eq. The documentation of eq says:
numbers with the same value need not be eq, … An implementation is permitted to make "copies" of characters and numbers at any time. The effect is that Common Lisp makes no guarantee that eq is true even when both its arguments are "the same thing" if that thing is a character or number.
and gives this example:
(eq 3 3)
; => true
; OR=> false
However, if you are working with (small) tuples of integers, you could easily hash on a function of them. E.g., the tuple (a,b,c) could be mapped to 2a×3b×5c. Since a function like that would generate unique numbers which are comparable with eql, you could use an eql hash table.
Another option for such a mapping function (that would work with symbols, too) would be to use sxhash. It's a standard hashing function that should produce identical values for equal values. How it works, and what exactly it does is not really specified at all, but it has the advantage that it's stable across Lisp images of the same implementation (e.g., run one version of SBCL today and tomorrow, and sxhash will return the same result for an equal object). Of course, it's possible that an equal-hash-table is just doing this for you already, so your mileage might vary.

Why is the null predicate called null, not nullp?

Basically, the title says it all: In Common Lisp, why is the null predicate called null. not nullp (to conform to other predicates such as evenp or oddp)? Is there a special reason for this?
First of all, null is not the only one. See atom.
Second, I think these predicates are fundamental ones and thus, very old. I don't think the 'end with p' agreement was introduced from the very beginning of LISP.
Also interesting info on the topic:
By convention, the names of predicates usually end in the letter p (which stands for 'predicate'). Common Lisp uses a uniform convention in hyphenating names of predicates. If the name of the predicate is formed by adding a p to an existing name, such as the name of a data type, a hyphen is placed before the final p if and only if there is a hyphen in the existing name. For example, number begets numberp but standard-char begets standard-char-p. On the other hand, if the name of a predicate is formed by adding a prefixing qualifier to the front of an existing predicate name, the two names are joined with a hyphen and the presence or absence of a hyphen before the final p is not changed. For example, the predicate string-lessp has no hyphen before the p because it is the string version of lessp (a MacLisp function that has been renamed < in Common Lisp). The name string-less-p would incorrectly imply that it is a predicate that tests for a kind of object called a string-less, and the name stringlessp would connote a predicate that tests whether something has no strings (is ``stringless'')!
Source: http://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node69.html
The predicate NULL is very old. It's called NULL in Common Lisp in the hope of encouraging the conversion of legacy Lisp code into Common Lisp
Gosh! It appears in the March 1959 version, and possibly earlier, of McCarthy's original memos (see page 3 of the pdf found here: http://dspace.mit.edu/handle/1721.1/6096 ) as one of the three basic predicates.
Amusingly this is before the introduction of car and cdr. Fascinating - in that memo elements in lists are separated by commas.

gethash doesn't work for string keys

Studying hash tables in elisp, I tried to write a simple example:
(setq animals (make-hash-table))
(puthash "tiger" 120 animals)
(gethash "tiger" animals)
When I execute them line by line, call to gethash returns nil, despite the fact, that when I evaluate animals symbol, emacs prints this:
#s(hash-table size 65 test eql rehash-size 1.5 rehash-threshold
0.8 data ("tiger" 120 ...))
So, "tiger" is there, but gethash doesn't return it for some reason.
What's wrong?
docs for hash table functions
The default test for a hash table is eql. Each time you type the string, you're creating a different string, so they're not eql to each other.
(eql "tiger" "tiger") => nil
You need to use equal as the test:
(setq animals (make-hash-table :test 'equal))
Or use symbols instead of strings as the keys in your table; since symbols are interned, typing the same symbol name twice results in the eql objects.
The thing is that when Emacs prints the hash table and you can see "tiger" in there, it's only showing you the printed representation of the real lisp objects in that structure, and printed representations can be ambiguous.
The printed representation of a string object is its value, so two string objects with the same value have the same printed representation and hence, once printed, it's impossible to distinguish them.
You're seeing the printed representation of the "tiger" string object you added to the table, but that's not the same string object that you queried it with in the next line.
The lisp reader creates these objects when it reads the code, and each time it reads a string it creates a new string object. As Barmar points out, symbols behave differently because they are interned by the lisp reader, so that it always 'reads' the same object. The situation with strings is similar to that with uninterned symbols -- you may find this related discussion useful.
It follows, of course, that lisp has many different forms of equality. You should familiarise yourself with at least eq, eql, equal, =, and string-equal (alias string=).

Why can't CASE be used on string values and only symbol values?

In book 'land of lisp' I read
Because the case command uses eq for comparisons, it is usually used
only for branching on symbol values. It cannot be used to branch on
string values, among other things.
Please explain why?
The other two excellent answers do answer the question asked. I will try to answer the natural next question - why does case use eql?
The reason is actually the same as in C (where the corresponding switch statement uses numeric comparison): the case forms in Lisp are usually compiled to something like goto, so (case x (1 ...) (2 ...) (3 ...)) is much more efficient than the corresponding cond. This is often accomplished by compiling case to a hash table lookup which maps the value being compared to the clause directly.
That said, the next question would be - why not have a case variant with equal hash table clause lookup instead of eql? Well, this is not in the ANSI standard, but implementations can provide such extensions, e.g., ext:fcase in CLISP.
See also why eql is the default comparison.
Two strings with the same content "foo" and "foo" are not EQL. CASE uses EQL as a comparison (not EQ as in your question). Usually one might want different tests: string comparison case and case insensitive, for example. But for CASE on cannot use another test. EQL is built-in. EQL compares for pointer equality, numbers and characters. But not string contents. You can test if two strings are the identical data objects, though.
So, two strings "FOO" and "FOO" are usually two different objects.
But two symbols FOO and FOO are usually really the same object. That's a basic feature of Lisp. Thus they are EQL and CASE can be used to compare them.
Because (eq "foo" "foo") is not necessarily true. Each time you type a string literal, it may create a fresh, unique string. So when CASE is comparing the value with the literals in the cases with EQ, they won't match.