We have moved this blog site to a new location - https://allegro-cl.blogspot.com
Please see this new site for more information on Allegro CL v11.0
We have moved this blog site to a new location - https://allegro-cl.blogspot.com
Please see this new site for more information on Allegro CL v11.0
Welcome Allegro CL 10 Express Edition Users
(defun foo (x) (declare (optimize (speed 3) (safety 0) (debug 0)) (double-float x)) (round (* x x)))
cl-user(10): (compile 'foo) foo nil nil cl-user(11): (disassemble 'foo) ;; disassembly of #<Function foo> ;; formals: x ;; constant vector: 0: round ;; code start: #x10003508c80: 0: 48 83 ec 68 sub rsp,$104 4: 4c 89 74 24 08 movq [rsp+8],r14 9: f2 44 0f 10 6f movsd xmm13,[rdi-10] f6 15: f2 45 0f 59 ed mulsd xmm13,xmm13 20: f2 45 0f 10 fd movsd xmm15,xmm13 25: 31 c0 xorl eax,eax 27: 41 ff 97 d7 03 call *[r15+983] ; sys::new-double-float 00 00 34: 4c 89 7c 24 18 movq [rsp+24],r15 39: 48 8d 64 24 68 leaq rsp,[rsp+104] 44: 49 8b 6e 36 movq rbp,[r14+54] ; round 48: b0 08 movb al,$8 50: ff e3 jmp *rbx cl-user(11):
- Access control: It is possible to instruct AllegroGraph to prevent an user from accessing triples with certain attributes.
- Sharding: Attributes can be used to ensure that related triples are always placed in the same shard when AllegroGraph acts as a distributed triple store.
from franz.openrdf.connect import ag_connect
conn = ag_connect('python-tutorial', create=True, clear=True)
AttributeDefinition
objects. Each definition has a name, which must be unique, and a few optional properties (that can also be passed as constructor arguments):
allowed_values
: a list of strings. If this property is set then only the values from this list can be used for the defined attribute.ordered
: a boolean. If true then attribute value comparisons will use the ordering defined byallowed_values
. The default is false.minimum_number
,maximum_number
: integers that can be used to constrain the cardinality of an attribute. By default there are no limits.
setAttributeDefinition()
method of the connection object.from franz.openrdf.repository.attributes import AttributeDefinition
# A simple attribute with no constraints governing the set
# of legal values or the number of values that can be
# associated with a triple.
tag = AttributeDefinition(name='tag')
# An attribute with a limited set of legal values.
# Every bit of data can come from multiple sources.
# We encode this information in triple attributes,
# since it refers to the tripe as a whole. Another
# way of achieving this would be to use triple ids
# or RDF reification.
source = AttributeDefinition(
name='source',
allowed_values=['sonar', 'radar', 'esm', 'visual'])
# Security level - notice that the values are ordered
# and each triple *must* have exactly one value for
# this attribute. We will use this to prevent some
# users from accessing classified data.
level = AttributeDefinition(
name='level',
allowed_values=['low', 'medium', 'high'],
ordered=True,
minimum_number=1,
maximum_number=1)
# An attribute like this could be used for sharding.
# That would ensure that data related to a particular
# contact is never partitioned across multiple shards.
# Note that this attribute is required, since without
# it an attribute-sharded triple store would not know
# what to do with a triple.
contact = AttributeDefinition(
name='contact',
minimum_number=1,
maximum_number=1)
# So far we have created definition objects, but we
# have not yet sent those definitions to the server.
# Let's do this now.
conn.setAttributeDefinition(tag)
conn.setAttributeDefinition(source)
conn.setAttributeDefinition(level)
conn.setAttributeDefinition(contact)
# This line is not strictly necessary, because our
# connection operates in autocommit mode.
# However, it is important to note that attribute
# definitions have to be committed before they can
# be used by other sessions.
conn.commit()
getAttributeDefinitions()
method:for attr in conn.getAttributeDefinitions():
print('Name: {0}'.format(attr.name))
if attr.allowed_values:
print('Allowed values: {0}'.format(
', '.join(attr.allowed_values)))
print('Ordered: {0}'.format(
'Y' if attr.ordered else 'N'))
print('Min count: {0}'.format(attr.minimum_number))
print('Max count: {0}'.format(attr.maximum_number))
print()
Name: tag
Min count: 0
Max count: 1152921504606846975
Name: source
Allowed values: sonar, radar, esm, visual
Min count: 0
Max count: 1152921504606846975
Ordered: N
Name: level
Allowed values: low, medium, high
Ordered: Y
Min count: 1
Max count: 1
Name: contact
Min count: 1
Max count: 1
deleteAttributeDefinition()
:conn.deleteAttributeDefinition('tag')
defs = conn.getAttributeDefinitions()
print(', '.join(sorted(a.name for a in defs)))
contact, level, source
addTriple()
is used it is possible to pass attributes in a keyword parameter, as shown below:ex = conn.namespace('ex://')
conn.addTriple(ex.S1, ex.cls, ex.Udaloy, attributes={
'source': 'sonar',
'level': 'low',
'contact': 'S1'
})
addStatement()
method works in similar way. Note that it is not possible to include attributes in the Statement
object itself.from franz.openrdf.model import Statement
s = Statement(ex.M1, ex.cls, ex.Zumwalt)
conn.addStatement(s, attributes={
'source': ['sonar', 'esm'],
'level': 'medium',
'contact': 'M1'
})
addTriples()
one can add a fifth element to each tuple to represent attributes. Let us illustrate this by adding an aircraft to our dataset.conn.addTriples(
[(ex.R1, ex.cls, ex['Ka-27'], None,
{'source': 'radar',
'level': 'low',
'contact': 'R1'}),
(ex.R1, ex.altitude, 200, None,
{'source': 'radar',
'level': 'medium',
'contact': 'R1'})])
attributes
keyword parameter. This provides default values, but is completely ignored for all tuples that already contain attributes (the dictionaries are not merged). In the example below we add a triple representing an aircraft carrier and a few more triples that specify its position. Notice that the first triple has a lower security level and multiple sources. The common ‘contact’ attribute could be used to ensure that all this data will remain on a single shard.conn.addTriples(
[(ex.M2, ex.cls, ex.Kuznetsov, None, {
'source': ['sonar', 'radar', 'visual'],
'contact': 'M2',
'level': 'low',
}),
(ex.M2, ex.position, ex.pos343),
(ex.pos343, ex.x, 430.0),
(ex.pos343, ex.y, 240.0)],
attributes={
'contact': 'M2',
'source': 'radar',
'level': 'medium'
})
addFile()
and addData()
(illustrated below):from franz.openrdf.rio.rdfformat import RDFFormat
conn.addData('''
<ex://S2> <ex://cls> <ex://Alpha> \
{"source": "sonar", "level": "medium", "contact": "S2"} .
<ex://S2> <ex://depth> "300" \
{"source": "sonar", "level": "medium", "contact": "S2"} .
<ex://S2> <ex://speed_kn> "15.0" \
{"source": "sonar", "level": "medium", "contact": "S2"} .
''', rdf_format=RDFFormat.NQX)
from franz.openrdf.rio.rdfformat import RDFFormat
conn.addData('''
<ex://V1> <ex://cls> <ex://Walrus> ;
<ex://altitude> 100 ;
<ex://speed_kn> 12.0e+8 .
<ex://V2> <ex://cls> <ex://Walrus> ;
<ex://altitude> 200 ;
<ex://speed_kn> 12.0e+8 .
<ex://V3> <ex://cls> <ex://Walrus> ;
<ex://altitude> 300;
<ex://speed_kn> 12.0e+8 .
<ex://V4> <ex://cls> <ex://Walrus> ;
<ex://altitude> 400 ;
<ex://speed_kn> 12.0e+8 .
<ex://V5> <ex://cls> <ex://Walrus> ;
<ex://altitude> 500 ;
<ex://speed_kn> 12.0e+8 .
<ex://V6> <ex://cls> <ex://Walrus> ;
<ex://altitude> 600 ;
<ex://speed_kn> 12.0e+8 .
''', attributes={
'source': 'visual',
'level': 'high',
'contact': 'a therapist'})
import json
r = conn.executeTupleQuery('''
PREFIX attr: <http://franz.com/ns/allegrograph/6.2.0/>
SELECT ?s ?p ?o ?a {
?s ?p ?o .
?a attr:attributes (?s ?p ?o) .
} ORDER BY ?s ?p ?o''')
with r:
for row in r:
print(row['s'], row['p'], row['o'])
print(json.dumps(json.loads(row['a'].label),
sort_keys=True,
indent=4))
<ex://M1> <ex://cls> <ex://Zumwalt>
{
"contact": "M1",
"level": "medium",
"source": [
"esm",
"sonar"
]
}
<ex://M2> <ex://cls> <ex://Kuznetsov>
{
"contact": "M2",
"level": "low",
"source": [
"visual",
"radar",
"sonar"
]
}
<ex://M2> <ex://position> <ex://pos343>
{
"contact": "M2",
"level": "medium",
"source": "radar"
}
<ex://R1> <ex://altitude> "200"^^...
{
"contact": "R1",
"level": "medium",
"source": "radar"
}
<ex://R1> <ex://cls> <ex://Ka-27>
{
"contact": "R1",
"level": "low",
"source": "radar"
}
<ex://S1> <ex://cls> <ex://Udaloy>
{
"contact": "S1",
"level": "low",
"source": "sonar"
}
<ex://S2> <ex://cls> <ex://Alpha>
{
"contact": "S2",
"level": "medium",
"source": "sonar"
}
<ex://S2> <ex://depth> "300"
{
"contact": "S2",
"level": "medium",
"source": "sonar"
}
<ex://S2> <ex://speed_kn> "15.0"
{
"contact": "S2",
"level": "medium",
"source": "sonar"
}
<ex://V1> <ex://altitude> "100"^^...
{
"contact": "a therapist",
"level": "high",
"source": "visual"
}
<ex://V1> <ex://cls> <ex://Walrus>
{
"contact": "a therapist",
"level": "high",
"source": "visual"
}
<ex://V1> <ex://speed_kn> "1.2E9"^^...
{
"contact": "a therapist",
"level": "high",
"source": "visual"
}
...
<ex://pos343> <ex://x> "4.3E2"^^...
{
"contact": "M2",
"level": "medium",
"source": "radar"
}
<ex://pos343> <ex://y> "2.4E2"^^...
{
"contact": "M2",
"level": "medium",
"source": "radar"
}
setAttributeFilter()
. The values passed to this method must be either strings (the syntax is described in the documentation of static attribute filters) or filter objects.
- a string or a list of strings: represents a constant set of values.
- TripleAttribute.name: represents the value of the name attribute associated with the currently inspected triple.
- UserAttribute.name: represents the value of the name attribute associated with current query. User attributes will be discussed in more detail later.
franz.openrdf.repository.attributes
package:Syntax | Meaning |
---|---|
Empty(x) | True if the specified attribute set is empty. |
Overlap(x, y) | True if there is at least one matching value between the two attribute sets. |
Subset(x, y) , x << y | True if every element of x can be found in y |
Superset(x, y) , x >> y | True if every element of y can be found in x |
Equal(x, y) , x == y | True if x and y have exactly the same contents. |
Lt(x, y) , x < y | True if both sets are singletons, at least one of the sets refers to a triple or user attribute, the attribute is ordered and the value of the single element of x occurs before the single value of y in the lowed_values list of the attribute. |
Le(x, y) , x <= y | True if y < x is false. |
Eq(x, y) | True if both x < y and y < x are false. Note that using the == Python operator translates toEqauls, not Eq. |
Ge(x, y) , x >= y | True if x < y is false. |
Gt(x, y) , x > y | True if y < x. |
UserAttribute
or TripleAttribute
reference - if both arguments are strings or lists of strings the default Python semantics for each operator are used. The prefix syntax always produces filters.Syntax | Meaning |
---|---|
Not(x) , ~x | Negates the meaning of the filter. |
And(x, y, ...) , x & y | True if all subfilters are true. |
Or(x, y, ...) , x | y | True if at least one subfilter is true. |
from franz.openrdf.repository.attributes import *
conn.setAttributeFilter(TripleAttribute.source >> 'sonar')
conn.executeTupleQuery(
'select ?class { ?s <ex://cls> ?class } order by ?class',
output=True)
------------------
| class |
==================
| ex://Alpha |
| ex://Kuznetsov |
| ex://Udaloy |
| ex://Zumwalt |
------------------
conn.setUserAttributes({'level': 'low'})
conn.setAttributeFilter(
TripleAttribute.level <= UserAttribute.level)
conn.executeTupleQuery(
'select ?class { ?s <ex://cls> ?class } order by ?class',
output=True)
------------------
| class |
==================
| ex://Ka-27 |
| ex://Kuznetsov |
| ex://Udaloy |
------------------
clearAttributeFilter()
method.conn.clearAttributeFilter()
temporaryUserAttributes()
method, which returns a context manager. The example below illustrates its use. It also shows how to use getUserAttributes()
to inspect user attributes.with conn.temporaryUserAttributes({'level': 'high'}):
print('User attributes inside the block:')
for k, v in conn.getUserAttributes().items():
print('{0}: {1}'.format(k, v))
print()
print('User attributes outside the block:')
for k, v in conn.getUserAttributes().items():
print('{0}: {1}'.format(k, v))
User attributes inside the block:
level: high
User attributes outside the block:
level: low »