US10817467B2 - Parallel materialisation of a set of logical rules on a logical database - Google Patents

Parallel materialisation of a set of logical rules on a logical database Download PDF

Info

Publication number
US10817467B2
US10817467B2 US15/033,583 US201415033583A US10817467B2 US 10817467 B2 US10817467 B2 US 10817467B2 US 201415033583 A US201415033583 A US 201415033583A US 10817467 B2 US10817467 B2 US 10817467B2
Authority
US
United States
Prior art keywords
logical
facts
fact
constants
rules
Prior art date
Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
Active, expires
Application number
US15/033,583
Other versions
US20160259796A1 (en
Inventor
Boris Motik
Yavor Nenov
Ian Horrocks
Current Assignee (The listed assignees may be inaccurate. Google has not performed a legal analysis and makes no representation or warranty as to the accuracy of the list.)
University of Oxford
Oxford Semantic Technologies Ltd
Original Assignee
University of Oxford
Oxford University Innovation Ltd
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Priority claimed from GBGB1319252.1A external-priority patent/GB201319252D0/en
Priority claimed from GB201416133A external-priority patent/GB201416133D0/en
Application filed by University of Oxford, Oxford University Innovation Ltd filed Critical University of Oxford
Publication of US20160259796A1 publication Critical patent/US20160259796A1/en
Assigned to OXFORD UNIVERSITY INNOVATION LIMITED reassignment OXFORD UNIVERSITY INNOVATION LIMITED CHANGE OF NAME (SEE DOCUMENT FOR DETAILS). Assignors: ISIS INNOVATION LIMITED
Assigned to ISIS INNOVATION LIMITED reassignment ISIS INNOVATION LIMITED ASSIGNMENT OF ASSIGNORS INTEREST (SEE DOCUMENT FOR DETAILS). Assignors: UNIVERSITY OF OXFORD
Assigned to UNIVERSITY OF OXFORD reassignment UNIVERSITY OF OXFORD ASSIGNMENT OF ASSIGNORS INTEREST (SEE DOCUMENT FOR DETAILS). Assignors: HORROCKS, IAN, MOTIK, BORIS, NENOV, Yavor
Application granted granted Critical
Publication of US10817467B2 publication Critical patent/US10817467B2/en
Assigned to OXFORD SEMANTIC TECHNOLOGIES LIMITED reassignment OXFORD SEMANTIC TECHNOLOGIES LIMITED ASSIGNMENT OF ASSIGNORS INTEREST (SEE DOCUMENT FOR DETAILS). Assignors: OXFORD UNIVERSITY INNOVATION LIMITED
Active legal-status Critical Current
Adjusted expiration legal-status Critical

Links

Images

Classifications

    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F16/00Information retrieval; Database structures therefor; File system structures therefor
    • G06F16/10File systems; File servers
    • G06F16/11File system administration, e.g. details of archiving or snapshots
    • G06F16/122File system administration, e.g. details of archiving or snapshots using management policies
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F16/00Information retrieval; Database structures therefor; File system structures therefor
    • G06F16/20Information retrieval; Database structures therefor; File system structures therefor of structured data, e.g. relational data
    • G06F16/24Querying
    • G06F16/245Query processing
    • G06F16/24569Query processing with adaptation to specific hardware, e.g. adapted for using GPUs or SSDs
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F16/00Information retrieval; Database structures therefor; File system structures therefor
    • G06F16/90Details of database functions independent of the retrieved data types
    • G06F16/901Indexing; Data structures therefor; Storage structures
    • G06F16/9024Graphs; Linked lists
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06NCOMPUTING ARRANGEMENTS BASED ON SPECIFIC COMPUTATIONAL MODELS
    • G06N5/00Computing arrangements using knowledge-based models
    • G06N5/04Inference or reasoning models

Definitions

  • the present invention concerns the materialisation of a set of logical rules on a logical database, such as a Resource Description Framework (RDF) database. More particularly, but not exclusively, the invention concerns computer-implemented methods of providing the materialisation of a set of logical rules on a logical database that are particularly amenable to parallel execution. The invention also concerns methods of storing data in computer memory when executing such methods.
  • RDF Resource Description Framework
  • Linked data on the Internet is commonly stored in the form of logical databases containing logical “facts”, such as RDF databases.
  • Data in an RDF is stored in “triples” ⁇ subject, predicate, object>, which is intuitively intended to record that the subject is related to the object according to the relation given by the predicate.
  • an RDF database containing data relating to television might have person_X, person_Y and programme_Z as items that can be subjects and/or objects, and relations such as appeared_in and was_directed_by as predicates, allowing such triples as ⁇ person_X, appeared_in, programme_Z> and ⁇ programme_Z, was_directed_by, person_Y> to be stored.
  • RDF databases A feature of RDF databases is that the items used as subjects and objects, and the relations used as predicates, are represented using standardised Uniform Resource
  • URIs Identifiers
  • RDF databases can also have associated with them datalog rules, which describe how new data can be derived from existing data in an RDF database.
  • Datalog is a declarative logical programming language, which is a subset of the logical programming language Prolog.
  • a well-known technique for handling databases incorporating equality predicates is rewriting, in which a representative term for a set of equal terms is selected, and the other terms in the set are replaced with the selected representative.
  • a problem with known techniques is that they cannot be efficiently performed using parallel processing.
  • the present invention seeks to mitigate the above-mentioned problems.
  • the present invention seeks to provide improved computer-implemented methods of materialisation which are amenable to parallel processing, and methods of storing data in computer memory when executing such methods.
  • the present invention seeks to provide improved computer-implemented methods of materialisation of databases incorporating equality predicates which are amenable to parallel processing, and computer-implemented methods of answering queries on materialised databases incorporating equality predicates.
  • the set of logical facts is provided as the materialisation of the set of logical rules on the logical database.
  • each thread is able to receive a logical fact from the set of logical facts, and then finds any new logical facts implied by applying the logical rules to the received logical fact or any previously received logical facts. Any new facts are added to the set of logical facts. As any thread is only considering its received logical fact or any previously received facts, it does not matter if any new logical facts are added to set of logical facts, as these would not be processed by the thread while considering the current logical fact. This allows all the threads to process the logical facts in parallel, asking for a new logical fact when the processing of the current logical fact has been completed.
  • any threads find that there are no further logical facts in the set of logical facts, they wait until new logical facts are added by another thread, at which point they can begin processing the newly added facts. Finally, if all threads are waiting it is not possible for any new logical facts to be added, and so the materialisation process has completed.
  • step 4b of the method further comprises checking if the number of waiting threads is the same as the number of total threads, and if so providing notification to all threads that the materialisation is complete.
  • the number of waiting threads may be stored in a global variable, which is incremented/decremented by a thread when it begins/stops waiting respectively.
  • each thread provides notification to any waiting threads that a new logical fact has been added.
  • the thread waits for notification from another thread that a new logical fact has been added. This means each thread does not need to monitor the set of logical facts for any additions.
  • step 1 the new logical fact is received from an iterator which selects the new logical fact from among the logical facts in the set of logical facts that have not previously been selected by the iterator.
  • the iterator may return logical facts in the order they are added to the set of logical facts.
  • the iterator may return logical facts in a different order from the order they are added to the set of logical facts.
  • step 2 the determination may be performed using index nested loops.
  • the logical database may be an RDF database.
  • the logical facts will be RDF triples.
  • the set of logical rules may be a datalog program.
  • the logical rules may be ontologies, data dependencies, or anything other type of rule that can be applied to logical facts in a logical database.
  • the set of logical rules is pre-processed to determine a join ordering.
  • the set of logical facts includes at least one logical fact incorporating an equality predicate indicating that two constants are equal, a mapping of constants to representative constants is maintained, and the method includes the steps of:
  • the representative constant can be used in all logical facts meaning that multiple logical facts for each equal constant are not required.
  • the representative constant is selected the other constant is added to a queue of constants, and wherein the logical facts are rewritten by replacing occurrences they contain of the constants in the queue of constants with their representative constants.
  • the rewriting of the logical facts is performed in a parallel processing thread.
  • the method further comprises the step of rewriting the logical rules in the set of logical rules using the mapping to replace occurrences of other constants with their representative constants.
  • the rewriting of the logical rules is performed in a parallel processing thread.
  • the method further comprises the steps of:
  • the logical rules that are rewritten are the logical rules in the queue of logical rules.
  • the steps are performed when all parallel processing threads have finished processing.
  • the method further comprising the steps of:
  • step 1) a logical fact is received from the set of logical facts only if a marker has not been added to the logical fact.
  • a method of storing data in computer memory when performing any method described above wherein the computer memory comprises a table of logical facts, and wherein each logical fact in the set of logical facts is stored as an entry in the table of logical facts.
  • the table will be a table of RDF triples.
  • each entry in the table of logical facts further comprises at least one pointer for each logical fact to a second logical fact in the table of logical facts sharing one or more properties with the first logical fact.
  • the pointers define linked lists of logical facts, which can be used to efficiently find logical facts in the list.
  • the pointers may be between logical facts sharing subjects, predicates and/or objects.
  • the linked lists defined by the pointers may group the logical facts on a further property of the logical fact.
  • the computer memory further comprises at least one index for locating a logical fact in the table of logical facts from one or more properties of the logical fact.
  • the at least one index can be used to efficiently find logical facts in the list.
  • the indexed properties of the logical facts may be subjects, predicates and/or objects.
  • At least one index may be a hash table.
  • the hash table is resized.
  • the threshold may be 70% of buckets being filled, for example.
  • the resizing is performed by each thread that attempts to access the index while it is being resized. This means the resizing can be done by any thread that would in any case not otherwise be able to continue processing (as it requires use of the index being resized in order to do so), while allowing threads that do not need to use the index to continue processing.
  • each entry in the table of logical facts comprises a status flag indicating whether the logical fact in the entry has been added to the at least one index.
  • the status flag indicates when the new logical fact has been added to all relevant indexes.
  • each thread has associated with it a reserved area of the table of logical facts, and each thread adds logical facts only to its associated reserved area. This allows threads to add logical facts to the table in parallel without concurrency issues arising due to the same area of the table being used by more than one thread.
  • a computer program product arranged, when executed on a computer system, to perform the steps of any method described above.
  • a method of storing data in computer memory for a logical database comprising a set of logical facts
  • the computer memory comprises a table of logical facts
  • each logical fact in the set of logical facts is stored as an entry in the table of logical facts
  • each entry in the table of logical facts further comprises at least one pointer for each logical fact to a second logical fact in the table of logical facts sharing one or more properties with the first logical fact.
  • This provides a particularly convenient data structure in which to store the logical facts, in which triples can be efficiently found, and that allows parallel processing by the threads while minimising concurrency issues.
  • the pointers define linked lists of logical facts, which can be used to efficiently find logical facts in the list.
  • the data structure is particularly advantageous when materialisation of the logical database is being performed, but is also advantageous for storing new logical facts in the logical database, querying the logical database, and performing other operations on the logical database.
  • the table will be a table of RDF triples.
  • the pointers may be between logical facts sharing subjects, predicates and/or objects.
  • the linked lists defined by the pointers may group the logical facts on a further property of the logical fact.
  • the computer memory further comprises at least one index for locating a logical fact in the table of logical facts from one or more properties of the logical fact.
  • the at least one index can be used to efficiently find logical facts in the list.
  • the indexed properties of the logical facts may be subjects, predicates and/or objects.
  • At least one index may be a hash table.
  • the hash table is resized.
  • the threshold may be 70% of buckets being filled, for example.
  • the resizing is performed by each thread that attempts to access the index while it is being resized. This means the resizing can be done by any thread that would in any case not otherwise be able to continue processing (as it requires use of the index being resized in order to do so), while allowing threads that do not need to use the index to continue processing.
  • each entry in the table of logical facts comprises a status flag indicating whether the logical fact in the entry has been added to the at least one index.
  • the status flag indicates when the new logical fact has been added to all relevant indexes.
  • each thread has associated with it a reserved area of the table of logical facts, and each thread adds logical facts only to its associated reserved area. This allows threads to add logical facts to the table in parallel without concurrency issues arising due to the same area of the table being used by more than one thread.
  • a computer program product arranged, when executed on a computer system, to perform the steps of the any method described above.
  • the query maybe a SPARQL query.
  • the method further comprises the step of duplicating an answer in the case that another answer to the query is a constant that is a representative of a set of equal constants. This allows answers that are repeated when there are multiple equal constants to be correctly provided.
  • the step of determining answers to the rewritten query comprises the substeps of:
  • a computer system arranged to perform the steps of any of the methods described above.
  • a computer program product arranged, when executed on a computer system, to perform the steps of any of the methods described above.
  • FIG. 1 is a flowchart showing an overall method of materialisation, in accordance with an embodiment of the invention
  • FIG. 2 is a schematic diagram of a data structure for storing data in a computer memory, in accordance with another embodiment of the invention.
  • FIGS. 3 a and 3 b are flowcharts showing a method of resizing hash tables, in accordance with another embodiment of the invention.
  • the database instance I In order for the method to be performed, the database instance I must provide an interface that meets certain concurrency requirements. In other words, it must be possible to query and manipulate I using an interface in ways that are well-behaved when the operations are being performed in parallel.
  • the requirements are as follows.
  • facts I is an iterator that provides in turn each fact in I; that is, facts I .next automatically selects and returns a fact from I that has not yet been returned (or returns ⁇ if there is no next fact to return).
  • the sequence in which facts in I are returned by facts I determines an ordering ⁇ on the facts.
  • I ⁇ F is then defined as the set of facts F′ in I for which F′ ⁇ F (i.e. all facts “before” F), and I ⁇ -F is the set I ⁇ F plus the fact F.
  • I.match(R(x, x), false, R(d, d)) returns an iterator that returns the substitutions ⁇ x ⁇ b ⁇ and ⁇ x ⁇ c ⁇ .
  • R(a, b) is not matched because x cannot be substituted in R(x, x) to give R(a, b);
  • R(d, d) is not matched because it is not in I ⁇ R(d, d) ; and
  • R(e, e) is not matched for the same reason as R(d, d).
  • step 1 A flowchart of the overall method is shown in FIG. 1 .
  • the rules of the program P are pre-processed, to determine a join ordering (step 1). This pre-processing of the rules rearranges their body atoms so that they can be evaluated efficiently during the materialisation process.
  • the rules are obtained as described in B. N. Grosof, I. Horrocks, R. Volz, S. Decker, Description Logic Programs: Combining Logic Programs with Description Logic , World Wide Web Conference, 2003.
  • the hash algorithms then provide an indexing of the rules, which can be used when required to retrieve the rules matching a fact (step 2).
  • P.rulesFor(F) (where F is a fact ⁇ s, p, o>, i.e. with subject s, predicate p and object o).
  • F is a fact ⁇ s, p, o>, i.e. with subject s, predicate p and object o).
  • H 1 [o] is iterated over
  • H 2 [o] is iterated over.
  • s> it is determined whether a substitution r exists for which b 1 (r) ⁇ is F. If so, the rule r matches the fact F and so is returned.
  • N is the total number of threads, so is set to and remains constant at that value.
  • W is the number of “waiting” threads (i.e. threads that have paused while they await the completion of processing by other threads), and is initially set to 0.
  • run is a Boolean variable that indicates whether threads are currently processing, and is initially set to be true.
  • m is a mutex variable which protects a critical section of the processing performed by the threads. (A mutex is a token that can be acquired by only one thread at a time, and can be used to grant a thread exclusive access to certain parts of thread code.
  • the other global values used are the database instance I, program P, and facts iterator facts I .
  • the threads are then created, and local variables for the thread are initialised (step 4).
  • the procedure infer which is shown in Procedure 1, is then run on each thread (step 5). This is described in more detail below.
  • the procedure infer in each thread obtains the facts it operates on from the global iterator facts I , and so in practice the threads share between them the facts from I.
  • the global variable I i.e. the database instance with facts as added by the operation of the infer procedure in each of the threads, is returned as the materialisation of the program P on the (original) database I (step 6).
  • the infer procedure is now described, with reference to Procedure 1.
  • the infer procedure is run on each thread; uses global variable I (the database instance), P (the program), facts I (the iterator over facts in I), N (the total number of threads), and W (the number of waiting threads); and uses local variables run (indicating whether it is running or waiting), and m (a mutex variable).
  • each rule r in P permutation ⁇ of its body atoms, and substitution ⁇ that unifies F with the body atom b ⁇ (1) (r) is retrieved.
  • the substitution o defines a partial instantiation of r (i.e. a portion of the variables of r are replaced with constants), and then a further procedure evaluate shown in Procedure 2 matches the remaining atoms.
  • the procedure evaluate is described in more detail below, but in essence uses index nested loops. However, any other join algorithm could be used. If evaluate determines that the rule r provides a new fact that can be added to I, it adds the fact, and all waiting threads are notified that a new fact has been added (the purpose of this is described below).
  • the procedure evaluate is now described, with reference to Procedure 2.
  • the procedure evaluate is a recursive procedure (i.e. it calls itself).
  • the procedure takes a rule r, permutation ⁇ , fact F, substitution ⁇ , and index j.
  • the rule r is the rule to be matched
  • the permutation ⁇ is the permutation of the body atoms of r
  • the fact F is the fact currently being considered
  • the substitution ⁇ is the substitution for the matched atoms of r
  • j is the index of the permutation ⁇ to be considered (and is initially set as 2 by infer, as the first atom has effectively been considered by P.rulesFor).
  • the method reduces interference of concurrent updates, but also efficiently enumerates matches to RDF atoms.
  • a data structure 100 used by the method is partially shown in FIG. 2 .
  • the data structure records the triples of the database instance I in a six-column triple table 101 .
  • the data structure 100 also comprises indexes I s 102 , I sp 103 , and I spo 104 .
  • the resources used by the database instance I i.e. the items that are used as subjects and objects of triples, and the relations that are used as predicates of triples, are mapped to integers.
  • the mapping is recorded as a lookup dictionary.
  • each triple the subject, predicate and object are stored (as integers) in columns R s , R p and R o respectively. Further, each triple participates in three linked lists, an sp-list, p-list and op-list. To implement these lists, a pointer to the next item in each of the lists is stored in the columns N sp , N p and N op respectively.
  • the sp-list connects all triples with that subject, grouped (but not necessarily sorted) by their predicate.
  • the sp-list consisting of triples ⁇ 1, 3, 2>, ⁇ 1, 3, 4>, ⁇ 1, 1, 2> and ⁇ 1, 1, 1>, containing sp-groups ⁇ 1, 3> and ⁇ 1, 1>.
  • sp-list consisting of triples ⁇ 2, 1, 4> and ⁇ 2, 1, 3>, which are in the same sp-group ⁇ 2, 1>.
  • the index I s 102 associates each subject s with the head (i.e. first triple) I s [s] of the corresponding sp-list.
  • I s 102 is implemented as an array indexed by subjects.
  • I s[s] is looked up and then the entire linked list is traversed.
  • I sp 103 associates each sp-group ⁇ s, p> with its first triple I sp [s, p].
  • I sp 103 is implemented as a hash table. In order to reduce the memory required, each bucket of I sp 103 stores only a pointer to the first triple of the group, as the bucket's key (i.e. the corresponding pair ⁇ s, p>) can be retrieved from the triple table 101 . To match an atom of the form ⁇ s, p, x> (i.e.
  • the subject and predicate in the atom are the constants s and p respectively, but the object is a variable), I sp [s, p] is looked up, and the linked list is traversed until a triple with a predicate other than p is reached, or the linked list ends.
  • the index I spo 104 provides an index for all triples, allowing atoms of the form ⁇ s, p, o> (i.e. atoms where the subject, predicate and object in the atom are the constants s, p and o respectively) to be efficiently matched.
  • I spo 104 is implemented as a hash table, and similarly to I sp 103 each bucket of I spo 103 can store only a pointer to the corresponding triple.
  • the data structure 100 comprises op-lists and associated indexes I o and I op , and p-lists and associated index I p (not shown in FIG. 2 ).
  • the op-lists connect all triples with object o, grouped by predicate p.
  • the index I o associates each object o with the head I o [o] of the corresponding op-list.
  • the index I op associates each op-group ⁇ o, p> with its first triple I op [o, p].
  • I o is implemented as an array indexed by objects and I op is implemented as a hash table, and they are used to match atoms of the form ⁇ x, y, o> and ⁇ x, p, o> respectively.
  • the p-lists connect all triples with the same predicate (without any further grouping).
  • the index I p associates each predicate p with the head I p [p] of the corresponding p-list, is implemented as an array indexed by predicates, and is used to match atoms of the form ⁇ x, p, y>.
  • atoms of the form ⁇ x, y, z> (i.e. for which each of the subject, predicate and object are variables) can be matched by iterating over the triple table 101 , as in this case every triple in the triple table 101 is matched. (Unless two or more of the variables are the same, in which case any triples in the triple table 101 for which the corresponding constants are not the same are skipped over.)
  • indexes can be used, for example others of the six indexes of the form I, that associate pairs of properties of triples with triples in the triple table 101 . Further indexes will increase the speed at which triples can be looked up in the triple table, but at the expense of increased memory consumption.
  • Each triple in the triple table 101 also has a status flag (not shown in FIG. 2 ), which is used to indicate whether a triple has been added to all the relevant indexes.
  • I.match(A, L, F) is implemented by identifying all matches for A as described above, but with any triples occurring in the triple table 101 (i.e. which come after F in the ordering ⁇ ) being skipped over (which can be easily determined by a comparison of their pointers).
  • facts I keeps an index into the triple table 101 , but returns only facts which are fully committed, in other words for which the status flag has been set to indicate that they have been included in all relevant indexes.
  • This allows facts to be added to the triple table 101 without the triple table 101 and all relevant indexes having to be locked. No concurrency issues will arise, as when a fact F is returned by facts I when requested by the infer procedure, in addition to F only facts F′ ⁇ F will be considered by the infer procedure, and these must all have already been fully committed. This means, in particular, that no facts can fail to be derived due to a required fact not being available in the triple table or indexes when queried.
  • I.add(F) The procedure insert-triple that performs the insertion is shown in Procedure 3.
  • I spo .buckets is the array of buckets of the I spo index
  • is the length of that array.
  • the procedure takes as input the subject s, predicate p and object o of a triple ⁇ s, p, o>.
  • the hash code for the triple and the first bucket index are determined (line 1 ). If necessary, the hash table is resized as described in detail below (line 3 ). The buckets are then scanned iteratively (lines 4 to 11 ). For each bucket, the triple stored in the bucket is retrieved (line 6 ). If the bucket contains the triple to be stored the procedure is stopped (line 9 ), as in this case the triple does not need to be (and should not be) added to I. If the bucket is empty (i.e. its contents is null), the loop is exited (line 8 ).
  • the empty bucket is then locked by temporarily storing in it a marker INS (line 12 ); other threads executing the procedure insert-triple then know that if they find a marker INS in a bucket they must wait until the bucket is unlocked by having the marker INS overwritten by a triple (lines 5 to 7 ).
  • the bucket is re-examined, as another thread could have just inserted the same triple. If the CAS operation succeeds, the triple is added to the triple table (line 13 ), and a pointer to the triple is added to the bucket (line 13 ), overwriting INS, and hence unlocking the bucket.
  • index I sp does not contain a bucket for the given sp-group, T new is added to the bucket and made the head of the bucket in the index I s 102 .
  • I op and I o are updated analogously to I sp and I s
  • I p is updated using an analogous procedure to insert-fp-list. Updates to I spo , I sp and I s , I op and I o , and I p are independent (i.e. can be done concurrently without there being any interference between them).
  • the method of resizing hash tables as may be performed in line 3 of procedure insert-triple is now described, with reference to the flowcharts of FIGS. 3 a and 3 b .
  • the hash tables herein are implemented with open addressing.
  • the threshold will conventionally be a percentage of used buckets, so 70% of buckets are used.
  • hash tables with open addressing conventionally store new entries in the next available free bucket after the bucket pointed to by the hash of a new entry. As a hash table fills up, the distance to the next available bucket increases, reducing performance. By doubling the size of the hash table after the threshold is met, performance is improved while avoiding the hash table being significantly larger than is required to store the entries it contains.
  • a single thread temporarily locks the entire index (step 201 ), allocates a new bucket array (step 202 ), sets a flag indicating that resizing is in progress (step 203 ), and unlocks the index (step 203 ).
  • a thread tries to access the index (step 205 ) but sees from the flag that resizing is in progress (step 206 ), it extract a range of buckets from the old array, say 1024 buckets (step 207 ), and transfers them to the new array.
  • step 207 (If the resize flag is not set it continues with its usual procedure (step 207 ).) The transfer can be done without any locking being required, as during resizing no new entries will need to be added to the triple table 101 . The process is repeated until all buckets have been transferred (step 209 ), and the thread that moves the final buckets then de-allocates the old array (step 210 ) and resets the resize flag (step 211 ).
  • each thread is provided with a proxy that provides a thread with “private” insertion points for the insertion of triples. This avoids interference due to the threads all adding triples to the end of the triple table 101 , and triples being added after the first triple in an sp- or op-group, which requires updating of the next-pointer of the first triple.
  • Each proxy reserves a range of space in the triple table 101 , so that different threads write to different areas of the triple table 101 . This allows the locking of buckets of I spo 104 in the procedure insert-triple to be avoided, because as the space for a new triple is reserved for a particular thread before the triple is inserted, the insertion can be done before the index I spo 104 is updated. If when I spo 104 is updated it is seen that the index already contains the triple, it can simply be removed from the triple table.
  • each proxy keeps a local copy of the indexes I sp 103 and I op , to maintain its own insertion points in the sp- and op-lists.
  • the proxy To insert a new triple T new , the proxy first queries the local I sp index for the relevant sp-group. If there is no match, it is inserted into the global indexes as described above, and is also stored in the local I sp index. If on the other hand the local index I sp contains a triple T for the sp-group, T new is added after T; as the index is local to the thread, this can be done without requiring a CAS operation. This ensures threads write to different memory locations, and also reduces the number of CAS operations required.
  • the local I op index is maintained analogously.
  • each proxy counts the number of triples it has encounters for each subject and object, and uses local indexes only where a threshold of triples (say 100 triples) is exceeded.
  • proxies results in the complication that facts I will eventually point to a location in a reserved range that does not yet contain a triple. If this occurs the location cannot simply be skipped over by facts I , as a later insertion of a triple into the location by a proxy would result in the I.match procedure failing to operate correctly.
  • facts I points to an unused location
  • all unused location are marked as unused, and subsequently all new triples are added to the end of the triple table without proxies being used. This typically occurs only very late in the materialisation process, and is a final phase typically taking less than 1% of the overall time, so the reduction in efficiency due to no longer using proxies in negligible.
  • the set of facts facts I is provided with a status marker for each fact it contains, which is used to mark a fact as outdated; facts I .mark(F) applies the marker to the fact F.
  • a queue of constants C is also used to which constants can be queued and dequeued in a corresponding manner is also used.
  • the materialisation procedure can perform one of three actions, which are as follows.
  • the first procedure is to process a fact from the set of facts facts I , similarly to the previous embodiment.
  • the procedure applyRules that performs this is shown in Procedure 5. (Note that facts I is denoted T in following procedures.) However, before a fact F is processed it is checked whether it is marked as outdated. If it is not marked, the constant mapping is applied to F, and if this shows that F is outdated it is marked as such, and the updated fact with the mapping applied is added to the set of facts facts I , and all threads are notified that there has been a change to the set of facts. The operation of the constant mapping is described later below.
  • F is not outdated, if it is of the form ⁇ a, owl:sameAs, b> then if a and b are distinct then the minimum of the two is selected as the representative for the other. (Any arbitrary total ordering of the constants can be used to determine the minimum and maximum.)
  • the substitution for the other is merged into the mapping using a procedure ⁇ .mergeInto which is also described later below, and the other is added to the queue of constants C.
  • the representative will always be a representative that has been chosen on a past occasion, or a newly chosen representative for a set of equal constants the members of which are being substituted for the first time.
  • the second procedure is to evaluate any queued rules by evaluating their bodies and then adding their heads to the set of facts facts I .
  • the queued rules are rules that have been updated by the mapping, and so this procedure applies these updated rules to the facts in facts I . (The process by which rules become queued is described later below.)
  • the procedure evaluateUpdatedRules that performs this is shown in Procedure 6. It will be appreciated that due to the parallel nature of the overall materialisation procedure, an instantiated head that is added to facts I may be outdated. This is why outdated facts in facts I are marked as such rather than being deleted, to prevent outdated facts that have been removed being reintroduced and consequently needing to be checked again to determine if they are outdated.
  • the third procedure is to rewrite the facts in facts I using any newly substituted constants, which as described above are queued in the queue C when their substitution is added to the mapping ⁇ .
  • the procedure rewriteFacts that performs this is shown in Procedure 7. Only facts that are not marked as outdated are rewritten; a fact marked outdated does need to be rewritten because applyRules adds its rewritten version to facts I at the same time as marking it as outdated.
  • Procedure 9 the updated version ⁇ (r) of each outdated rule r in the program is added to the queue R of updated rules, and each rule in the program itself is also updated. If no rules are added to the queue, which is determined by R.isEmpty, the materialisation has completed and the run flag is set accordingly to signal termination. Otherwise, the main loop of execution is repeated by performing again the procedures applyRules, evaluateUpdatedRules and rewriteFacts.
  • mapping ⁇ is implemented using arrays rep ⁇ and next ⁇ which are indexed by constants and initialised with zeros.
  • rep ⁇ [c] is zero if c represents itself, otherwise rep ⁇ [c] is the resource that is the representative for c.
  • next ⁇ defines a linked list of constants that are equal, where next ⁇ [c] is a pointer to the next constant in the list.
  • Procedure 9 The procedure ⁇ (c) to substitute a constant with its representative is shown in Procedure 9.
  • the substitution of constants in facts and rules is then performed in the corresponding manner.
  • rep ⁇ is traversed until a non-merged constant is found, which is then returned. If another thread updates ⁇ by updating rep ⁇ [r], scanning of rep ⁇ continues past r, so that the result is at least as current as ⁇ was when the procedure was begun.
  • Procedure 10 The procedure ⁇ .mergeInto(d,c) to update the mapping so that d is substituted with c is shown in Procedure 10.
  • first rep ⁇ is updated to indicate that d should be replaced with c. If this update is successful, the variable e scans the linked list for the constants replaced by c until the end of the list is found; this is done by the while statement, which is evaluated lazily so that the latter statement CAS(next ⁇ [e], 0, d) is not evaluated to see if it does not equal 0 as long as the former statement next ⁇ [e] does not equal 0.
  • the end of the linked list for c is found, it is updated to point to d; if this update is not successful (due to concurrent updates meaning it e is no longer the end of the list, and consequently it is not equal to zero)
  • the constant e returns to scanning for the end of the list.
  • An embodiment of the invention also provides a method of answering SPARQL queries on materialised databases that include facts that have been rewritten in accordance with the previous embodiment.
  • SPARQL SPARQL Protocol and RDF Query Language
  • SPARQL is a database query language for RDF databases somewhat similar to the SQL query language for relational databases.
  • a query Q could be answered by expanding the set of facts T using the mapping ⁇ , but this would be very inefficient.
  • the mapping ⁇ could be applied to the query Q, and then the answer could be expanded. However, this would not always give the correct answer, for two reasons.
  • the expansion is adapted so that for each variable used in the query, the set of answers for that variable is duplicated where another variable has as an answer a constant that is a representative of a set of equal constants.
  • duplicated answers are returned as required.
  • the second reason is due to built-in functions of SPARQL. For example, if the database includes the additional fact ⁇ USPresident, presidentOf, US>, then evaluating the query:
  • the mapped query applied to the unexpanded materialised database will only return ⁇ ?y ⁇ Obama ⁇ , as the strings Obama and USPresident are not equal, and the subsequent expansion will not provide the missing answer.
  • the answers are expanded before any built-in functions are evaluated; after evaluation the answers are again expanded, however without the answers now being duplicated as the required duplication has already been provided by the initial expansion.

Landscapes

  • Engineering & Computer Science (AREA)
  • Theoretical Computer Science (AREA)
  • Databases & Information Systems (AREA)
  • General Physics & Mathematics (AREA)
  • Physics & Mathematics (AREA)
  • General Engineering & Computer Science (AREA)
  • Data Mining & Analysis (AREA)
  • Computational Linguistics (AREA)
  • Software Systems (AREA)
  • Artificial Intelligence (AREA)
  • Evolutionary Computation (AREA)
  • Computing Systems (AREA)
  • Mathematical Physics (AREA)
  • Information Retrieval, Db Structures And Fs Structures Therefor (AREA)

Abstract

A computer-implemented method of providing a materialisation of a set of logical rules on a logical database comprising a set of logical facts. Each of a plurality of parallel processing threads performs the following steps. A logical fact that has not previously been received by any thread is received by the thread. By applying any of the logical rules to the received logical fact and/or any of the logical facts received by any thread prior to the received logical fact, the thread determines whether a new logical fact is implied, and if so the new logical fact is added to the set of logical facts. The thread then repeats the above steps on any further logical facts in the set of logical facts that have not previously been received by any thread. When all threads are waiting for a new logical fact, the method has completed.

Description

This application claims priority to International Patent Application No. PCT/GB2014/053230 filed on Oct. 30, 2014, which claims priority to GB Patent Application Nos. 1319252.1 filed on Oct. 31, 2013 and 1416133.5 filed Sep. 12, 2014.
FIELD OF THE INVENTION
The present invention concerns the materialisation of a set of logical rules on a logical database, such as a Resource Description Framework (RDF) database. More particularly, but not exclusively, the invention concerns computer-implemented methods of providing the materialisation of a set of logical rules on a logical database that are particularly amenable to parallel execution. The invention also concerns methods of storing data in computer memory when executing such methods.
BACKGROUND OF THE INVENTION
Linked data on the Internet is commonly stored in the form of logical databases containing logical “facts”, such as RDF databases. Data in an RDF is stored in “triples” <subject, predicate, object>, which is intuitively intended to record that the subject is related to the object according to the relation given by the predicate. So for example, an RDF database containing data relating to television might have person_X, person_Y and programme_Z as items that can be subjects and/or objects, and relations such as appeared_in and was_directed_by as predicates, allowing such triples as <person_X, appeared_in, programme_Z> and <programme_Z, was_directed_by, person_Y> to be stored.
A feature of RDF databases is that the items used as subjects and objects, and the relations used as predicates, are represented using standardised Uniform Resource
Identifiers (URIs), which can be used by any creator of a database. So for example, the following URIs are provided for use in RDF databases about wine:
http://www.w3.org/TR/2004/REC-owl-guide-20040210 wine#Merlot
http://www.w3.org/TR/2004/REC-owl-guide-20040210/wine#MerlotGrape
http://www.w3.org/TR/2004/REC-owl-guide-20040210/#winemadeFromGrape
As the same URIs can be used in different databases, this allows different databases to be easily combined.
RDF databases can also have associated with them datalog rules, which describe how new data can be derived from existing data in an RDF database. (“Datalog” is a declarative logical programming language, which is a subset of the logical programming language Prolog.) For example, in the example above of a database about television, a rule could be:
<X, appeared_in, Y> and <Y, was_directed_by, Z>→<Z, has_directed, X>
Thus, in our example above this allows the new triple <person_Y, has_directed, person_X> to be derived.
In order to be able to answer queries over an RDF database (which may have been obtained by combining multiple existing RDF databases from different sources) and datalog rules, it is common for a database to undergo “materialisation”, by which all triples that can be derived from the existing data and rules are added to the database. While materialisation is computationally intensive, it is nevertheless commonly used. A well-known method of materialisation is the “seminaïve algorithm”, as described in S. Abiteboul, R. Hull, V. Vianu, Foundations of Databases, Addison Wesley, 1995.
In order to improve the speed of materialisation, it is common for it to be performed using parallel processing. However, a disadvantage of the seminaïve algorithm, and of other known methods of materialisation, is that they cannot be efficiently performed by parallel processing, due to need for threads to wait for others to complete before they can continue processing. Another disadvantage is that the memory use by such methods does not support parallel processing.
It is also common for RDF databases to use an “equality” predicate owl:sameAs in facts, terms and so on. Intuitively, an equality predicate indicates that a subject and object in a fact refer to the same underlying “thing”, i.e. that they are equal. For example, facts such as <USA, owl:sameAs, US> and <US, owl:sameAs, America> that indicate that the different terms USA, US and America all refer to the same thing (country). A rule using the predicate might for example be:
<Obama, presidentOf, x>→<x, owl:sameAs, USA>
which indicates that if Obama is the president of something, that something must be the same as the USA, even if a different term (such as US or America) is used for it. A corresponding predicate owl:differentFrom to indicate that a subject and object do not refer to the same underlying thing may also be used.
A well-known technique for handling databases incorporating equality predicates is rewriting, in which a representative term for a set of equal terms is selected, and the other terms in the set are replaced with the selected representative. However, a problem with known techniques is that they cannot be efficiently performed using parallel processing.
The present invention seeks to mitigate the above-mentioned problems. In particular, the present invention seeks to provide improved computer-implemented methods of materialisation which are amenable to parallel processing, and methods of storing data in computer memory when executing such methods. In addition, the present invention seeks to provide improved computer-implemented methods of materialisation of databases incorporating equality predicates which are amenable to parallel processing, and computer-implemented methods of answering queries on materialised databases incorporating equality predicates.
SUMMARY OF THE INVENTION
In accordance with a first aspect of the invention, there is provided a computer-implemented method of providing a materialisation of a set of logical rules on a logical database comprising a set of logical facts, wherein each of a plurality of parallel processing threads performs the following steps:
1) receiving a logical fact from the set of logical facts, wherein the received logical fact has not previously been received by any thread;
2) determining if a new logical fact is implied, by applying any of the logical rules to the received logical fact and/or any of the logical facts received by any thread prior to the received logical fact;
3) in the case that a new logical fact is implied, adding the new logical fact to the set of logical facts;
4) determining if there are further logical facts in the set of logical facts that have not previously been received by any thread; and
    • 4a) in the case that there are further logical facts, repeating steps 1 to 4 of the method;
    • 4b) in the case that there are no further logical facts, waiting until a new logical fact is added to the set of logical facts, and when a new logical fact is added, repeating steps 1 to 4 of the method;
wherein when all threads are waiting for a new logical fact to be added, the set of logical facts is provided as the materialisation of the set of logical rules on the logical database.
In this way, each thread is able to receive a logical fact from the set of logical facts, and then finds any new logical facts implied by applying the logical rules to the received logical fact or any previously received logical facts. Any new facts are added to the set of logical facts. As any thread is only considering its received logical fact or any previously received facts, it does not matter if any new logical facts are added to set of logical facts, as these would not be processed by the thread while considering the current logical fact. This allows all the threads to process the logical facts in parallel, asking for a new logical fact when the processing of the current logical fact has been completed. If any threads find that there are no further logical facts in the set of logical facts, they wait until new logical facts are added by another thread, at which point they can begin processing the newly added facts. Finally, if all threads are waiting it is not possible for any new logical facts to be added, and so the materialisation process has completed.
Advantageously, step 4b of the method further comprises checking if the number of waiting threads is the same as the number of total threads, and if so providing notification to all threads that the materialisation is complete. This provides a particularly convenient way of determining if the processing has completed and terminating all threads. The number of waiting threads may be stored in a global variable, which is incremented/decremented by a thread when it begins/stops waiting respectively.
Advantageously, in step 3 each thread provides notification to any waiting threads that a new logical fact has been added. In this case, preferably in step 4b, the thread waits for notification from another thread that a new logical fact has been added. This means each thread does not need to monitor the set of logical facts for any additions.
Advantageously, in step 1 the new logical fact is received from an iterator which selects the new logical fact from among the logical facts in the set of logical facts that have not previously been selected by the iterator. The iterator may return logical facts in the order they are added to the set of logical facts. Alternatively, the iterator may return logical facts in a different order from the order they are added to the set of logical facts.
In step 2 the determination may be performed using index nested loops.
The logical database may be an RDF database. In this case, the logical facts will be RDF triples. The set of logical rules may be a datalog program. Alternatively, the logical rules may be ontologies, data dependencies, or anything other type of rule that can be applied to logical facts in a logical database.
Preferably, prior to performing any steps in the threads, the set of logical rules is pre-processed to determine a join ordering.
Advantageously, the set of logical facts includes at least one logical fact incorporating an equality predicate indicating that two constants are equal, a mapping of constants to representative constants is maintained, and the method includes the steps of:
selecting a representative constant from the two constants;
updating the mapping to map the other constant to the representative constant;
rewriting logical facts in the set of logical facts using the mapping to replace occurrences of the other constant with the representative constant. This allows sets of logical facts that include constants that are equal to be efficiently processed, as by selecting one constant as the representative, the representative constant can be used in all logical facts meaning that multiple logical facts for each equal constant are not required. Advantageously, when the representative constant is selected the other constant is added to a queue of constants, and wherein the logical facts are rewritten by replacing occurrences they contain of the constants in the queue of constants with their representative constants. This is a convenient method for keeping a list of the constants that need to be replaced in the logical facts with their representative constants. Advantageously, the rewriting of the logical facts is performed in a parallel processing thread.
Preferably, the method further comprises the step of rewriting the logical rules in the set of logical rules using the mapping to replace occurrences of other constants with their representative constants. Advantageously, the rewriting of the logical rules is performed in a parallel processing thread.
Preferably, the method further comprises the steps of:
determining if a logical rule from the set of logical rules contains any constants that are mapped by the mapping to representative constants; and
in the case that a logical rule contains constants that are mapped, adding the logical rule to a queue of logical rules
and wherein the logical rules that are rewritten are the logical rules in the queue of logical rules. Preferably the steps are performed when all parallel processing threads have finished processing.
Advantageously, the method further comprising the steps of:
determining if a logical fact from the set of logical facts contains any constants that are mapped by the mapping to representative constants; and
in the case that a logical fact contains constants that are mapped, adding a marker to the logical fact. This means that when a logical fact containing constants that are mapped is implied by the logical rules that were already present in the set of facts, it does not need to be determined again if it contains any constants that are mapped. Advantageously, in step 1) a logical fact is received from the set of logical facts only if a marker has not been added to the logical fact.
In accordance with a second aspect of the invention, there is provided a method of storing data in computer memory when performing any method described above, wherein the computer memory comprises a table of logical facts, and wherein each logical fact in the set of logical facts is stored as an entry in the table of logical facts. This provides a particularly convenient data structure in which to store the logical facts, that allows parallel processing by the threads while minimising concurrency issues. In the case that the logical database is an RDF database, the table will be a table of RDF triples.
Advantageously, each entry in the table of logical facts further comprises at least one pointer for each logical fact to a second logical fact in the table of logical facts sharing one or more properties with the first logical fact. The pointers define linked lists of logical facts, which can be used to efficiently find logical facts in the list. In the case the logical facts are RDF triples, the pointers may be between logical facts sharing subjects, predicates and/or objects. The linked lists defined by the pointers may group the logical facts on a further property of the logical fact.
Advantageously, the computer memory further comprises at least one index for locating a logical fact in the table of logical facts from one or more properties of the logical fact. The at least one index can be used to efficiently find logical facts in the list. In the case the logical facts are RDF triples, the indexed properties of the logical facts may be subjects, predicates and/or objects.
At least one index may be a hash table. Advantageously in that case, when the number of filled buckets in the hash table exceeds a pre-determined threshold, the hash table is resized. The threshold may be 70% of buckets being filled, for example. Advantageously, the resizing is performed by each thread that attempts to access the index while it is being resized. This means the resizing can be done by any thread that would in any case not otherwise be able to continue processing (as it requires use of the index being resized in order to do so), while allowing threads that do not need to use the index to continue processing.
Advantageously, each entry in the table of logical facts comprises a status flag indicating whether the logical fact in the entry has been added to the at least one index. This allows new logical facts to be added to table and indexed, without requiring all other threads to stop processing while that is occurring. Preferably, the status flag indicates when the new logical fact has been added to all relevant indexes.
Advantageously, each thread has associated with it a reserved area of the table of logical facts, and each thread adds logical facts only to its associated reserved area. This allows threads to add logical facts to the table in parallel without concurrency issues arising due to the same area of the table being used by more than one thread.
In accordance with a third aspect of the invention, there is provided a computer system arranged to perform the steps of any method described above.
In accordance with a fourth aspect of the invention, there is provided a computer program product arranged, when executed on a computer system, to perform the steps of any method described above.
In accordance with a fifth aspect of the invention, there is provided a method of storing data in computer memory for a logical database comprising a set of logical facts, wherein the computer memory comprises a table of logical facts, each logical fact in the set of logical facts is stored as an entry in the table of logical facts, and wherein each entry in the table of logical facts further comprises at least one pointer for each logical fact to a second logical fact in the table of logical facts sharing one or more properties with the first logical fact.
This provides a particularly convenient data structure in which to store the logical facts, in which triples can be efficiently found, and that allows parallel processing by the threads while minimising concurrency issues. The pointers define linked lists of logical facts, which can be used to efficiently find logical facts in the list. The data structure is particularly advantageous when materialisation of the logical database is being performed, but is also advantageous for storing new logical facts in the logical database, querying the logical database, and performing other operations on the logical database.
In the case that the logical database is an RDF database, the table will be a table of RDF triples. In this case, the pointers may be between logical facts sharing subjects, predicates and/or objects. The linked lists defined by the pointers may group the logical facts on a further property of the logical fact. Preferably, there are pointers that define sp-lists connecting triples with the same subject, grouped (but not necessarily sorted) by their predicate. Preferably, there are pointers that define op-lists connecting triples with the same object, grouped (but not necessarily sorted) by their predicate. Preferably, there are pointers that define p-lists connecting triples with the same predicate (without any further grouping).
Advantageously, the computer memory further comprises at least one index for locating a logical fact in the table of logical facts from one or more properties of the logical fact. The at least one index can be used to efficiently find logical facts in the list. In the case the logical facts are RDF triples, the indexed properties of the logical facts may be subjects, predicates and/or objects. Preferably, when there are pointers that define sp-lists, there is an index that associates each subject with the head (i.e. first triple) of the first sp-list with that subject. Preferably, there is also an index that associates each pair of subject and object with the first triple in the sp-list with that subject and object. Preferably, when there are pointers that define op-lists, there is an index that associates each object with the head of the first op-list with that object. Preferable, there is also an index that associates each pair of predicate and object with the first triple in the op-list with that predicate and object. Preferably, when there are pointers that define p-lists, there is an index that associates each predicate with the head of p-list with that predicate. Preferably, there is an index which associates each triple of subject, predicate and object with the triple in the table of logical facts with that subject, predicate and object.
At least one index may be a hash table. Advantageously in that case, when the number of filled buckets in the hash table exceeds a pre-determined threshold, the hash table is resized. The threshold may be 70% of buckets being filled, for example. Advantageously, the resizing is performed by each thread that attempts to access the index while it is being resized. This means the resizing can be done by any thread that would in any case not otherwise be able to continue processing (as it requires use of the index being resized in order to do so), while allowing threads that do not need to use the index to continue processing.
Advantageously, each entry in the table of logical facts comprises a status flag indicating whether the logical fact in the entry has been added to the at least one index. This allows new logical facts to be added to table and indexed, without requiring all other threads to stop processing while that is occurring. Preferably, the status flag indicates when the new logical fact has been added to all relevant indexes.
Advantageously, each thread has associated with it a reserved area of the table of logical facts, and each thread adds logical facts only to its associated reserved area. This allows threads to add logical facts to the table in parallel without concurrency issues arising due to the same area of the table being used by more than one thread.
In accordance with a sixth aspect of the invention, there is provided a computer system arranged to perform the steps of any method described above.
In accordance with a seventh aspect of the invention, there is provided a computer program product arranged, when executed on a computer system, to perform the steps of the any method described above.
In accordance with an eighth aspect of the invention, there is provided a computer-implemented method of answering a query over a set of logical facts obtained using a method described above where the set of logical facts includes at least one logical fact incorporating an equality predicate indicating that two constants are equal, comprising the steps of:
rewriting the query using the mapping to replace occurrences of other constants with their representative constants;
determining answers to the rewritten query on the set of logical facts; and
expanding the answers by replacing representative constants in the answers with other constants that map to them.
This allows the query to be efficiently answered, as only the representative constants need to be considered. The query maybe a SPARQL query.
Preferably, the method further comprises the step of duplicating an answer in the case that another answer to the query is a constant that is a representative of a set of equal constants. This allows answers that are repeated when there are multiple equal constants to be correctly provided.
Preferably, the step of determining answers to the rewritten query comprises the substeps of:
determining the answers without evaluating any built-in functions;
expanding the answers by replacing representative constants in the answers with other constants that map to them; and
evaluating any built-in functions. This allows built-in functions to be correctly handled.
In accordance with a ninth aspect of the invention, there is provided a computer system arranged to perform the steps of any of the methods described above.
In accordance with a tenth aspect of the invention, there is provided a computer program product arranged, when executed on a computer system, to perform the steps of any of the methods described above.
It will of course be appreciated that features described in relation to one aspect of the present invention may be incorporated into other aspects of the present invention.
DESCRIPTION OF THE DRAWINGS
Embodiments of the present invention will now be described by way of example only with reference to the accompanying schematic drawings of which:
FIG. 1 is a flowchart showing an overall method of materialisation, in accordance with an embodiment of the invention;
FIG. 2 is a schematic diagram of a data structure for storing data in a computer memory, in accordance with another embodiment of the invention; and
FIGS. 3a and 3b are flowcharts showing a method of resizing hash tables, in accordance with another embodiment of the invention.
DETAILED DESCRIPTION
There is now described a method of materialisation of a set of logical rules on a logical database in accordance with an embodiment of the invention. Following the logical perspective on databases described in S. Abiteboul, R. Hull, V. Vianu, Foundations of Databases, Addison Wesley, 1995, it is assumed that the database has countably many relation names, constants and variables. The following terminology is used. A “term” is a constant or variable. An “atom” is a relation applied to a set of terms, i.e. R(t1, . . . tn). If the terms of an atom are all constants, it is a “fact”. A “database instance” I is a set of facts. A (datalog) “rule” is of the form:
    • B1 and . . . and Bn→H
      where B1 to Bn are “body” atoms, and H is the “head” atom. Such a rule must be “safe”, which means that every variable that occurs in the head atom H occurs in at least one body atom Bi. A (datalog) program P is a set of rules. A “substitution” σ is a partial mapping of variables to terms, and for any term, atom or rule A, Aσ is the result of replacing the variables in A with the terms given by the substitution, where defined.
Given the above definitions, the materialisation of a program P on a database instance I can be formally defined as follows. Given a rule r in P, let r(I) be the smallest set containing Hσ for every substitution σ such that for all i, Biσ is in I. Let P(I) be the union of all r(I); let P0(I)=I, and let Pi(I) be the union of pi−1(I) and P(Pi−1(I)). The union of Pi(I) for all i is then the materialisation of P on I.
In order for the method to be performed, the database instance I must provide an interface that meets certain concurrency requirements. In other words, it must be possible to query and manipulate I using an interface in ways that are well-behaved when the operations are being performed in parallel. The requirements are as follows.
Adding a fact F to I is written I.add(F), and if F already occurs in I, I should not be changed (there is “eager duplicate elimination”). It must be possible to check at a particular instance whether F exists in I, and if not F becomes “committed” to I. (While this may seem unlikely to be an issue, it need not be possible to perform this check on a database where facts can be added in parallel.)
factsI is an iterator that provides in turn each fact in I; that is, factsI.next automatically selects and returns a fact from I that has not yet been returned (or returns ε if there is no next fact to return). factsI.hasNext returns true if there is a next fact to return, or false otherwise. The sequence in which facts in I are returned by factsI determines an ordering <on the facts. I<F is then defined as the set of facts F′ in I for which F′<F (i.e. all facts “before” F), and I<-F is the set I<F plus the fact F.
I.match(A, L, F) takes an atom A, Boolean value (i.e. true or false) L, and fact F, and returns an iterator it. If L is false, it returns each substitution σ for which Aσ is in I<F. If L is true, it returns each substitution σ for which Aσ is in I<=F. In other words, atom A describes a pattern which is matched against I<F or I<=F, depending on L. it.next returns the next substitution, and it.hasNext is true if there is a next substitution, and false if there is not.
To give an example of the above, suppose I contains:
R(a, b)<R(b, b)<R(c, c)<R(d, d)<R(e, e)
Then I.match(R(x, x), false, R(d, d)) returns an iterator that returns the substitutions {x→b} and {x→c}. In particular, R(a, b) is not matched because x cannot be substituted in R(x, x) to give R(a, b); R(d, d) is not matched because it is not in I<R(d, d); and R(e, e) is not matched for the same reason as R(d, d).
A flowchart of the overall method is shown in FIG. 1. First, the rules of the program P are pre-processed, to determine a join ordering (step 1). This pre-processing of the rules rearranges their body atoms so that they can be evaluated efficiently during the materialisation process.
In the present embodiment, the rules are obtained as described in B. N. Grosof, I. Horrocks, R. Volz, S. Decker, Description Logic Programs: Combining Logic Programs with Description Logic, World Wide Web Conference, 2003. This means that all atoms are of the form <t, rdf:type, C>, where rdf:type is a placeholder used to indicate that the object is not required (i.e. the atom is simply associating t to C), or of the form <t1, R, t1> with R not equal to rdf:type. This means hash algorithms can be used to associate each constant c with sets H1[c] and H2[c] of pairs of rules and body atom permutations. Given a rule r and permutation π, if the π(i)th body atom Bπ(1) of r is of the first form above, <r, π> is added to H1[C], otherwise it is added to H2[R].
The hash algorithms then provide an indexing of the rules, which can be used when required to retrieve the rules matching a fact (step 2). This is written P.rulesFor(F) (where F is a fact <s, p, o>, i.e. with subject s, predicate p and object o). In order to retrieve the rules, if p is rdf:type then H1[o] is iterated over, otherwise H2[o] is iterated over. In each case, for each pair <r, s> it is determined whether a substitution r exists for which b1(r)τ is F. If so, the rule r matches the fact F and so is returned.
Next, global variables W, N, run and m are initialised (step 3). N is the total number of threads, so is set to and remains constant at that value. W is the number of “waiting” threads (i.e. threads that have paused while they await the completion of processing by other threads), and is initially set to 0. run is a Boolean variable that indicates whether threads are currently processing, and is initially set to be true. m is a mutex variable which protects a critical section of the processing performed by the threads. (A mutex is a token that can be acquired by only one thread at a time, and can be used to grant a thread exclusive access to certain parts of thread code. Once a thread acquires a mutex, the thread can release the mutex, wait for notification from other threads, and acquire the mutex again. Accordingly, a thread can signal other threads that are waiting for notification.) The other global values used are the database instance I, program P, and facts iterator factsI.
The threads are then created, and local variables for the thread are initialised (step 4).
The procedure infer, which is shown in Procedure 1, is then run on each thread (step 5). This is described in more detail below. The procedure infer in each thread obtains the facts it operates on from the global iterator factsI, and so in practice the threads share between them the facts from I.
Once the infer procedure has completed for each thread, the global variable I, i.e. the database instance with facts as added by the operation of the infer procedure in each of the threads, is returned as the materialisation of the program P on the (original) database I (step 6).
The infer procedure is now described, with reference to Procedure 1. As noted above, the infer procedure is run on each thread; uses global variable I (the database instance), P (the program), factsI (the iterator over facts in I), N (the total number of threads), and W (the number of waiting threads); and uses local variables run (indicating whether it is running or waiting), and m (a mutex variable).
As can be seen, infer iterates over the facts in I, and matches the relevant rules (line 2 to 6). In particular, after retrieving a fact F from I (line 2), each rule r in P, permutation π of its body atoms, and substitution σ that unifies F with the body atom bπ(1)(r) is retrieved. The substitution o defines a partial instantiation of r (i.e. a portion of the variables of r are replaced with constants), and then a further procedure evaluate shown in Procedure 2 matches the remaining atoms. The procedure evaluate is described in more detail below, but in essence uses index nested loops. However, any other join algorithm could be used. If evaluate determines that the rule r provides a new fact that can be added to I, it adds the fact, and all waiting threads are notified that a new fact has been added (the purpose of this is described below).
Once all facts in I have been evaluated, i.e. factsI.next=ε, infer increments W as it is now waiting (line 7), and as it is entering a critical section it acquires a mutex m. It then waits to be notified by any other threads that they have added any more facts to I, in which case it decrements W (line 17), releases the mutex m (line 18), and resumes operation on the new facts (line 19 looping back to line 1). If, on the other hand, all threads are waiting (W=N in line 10), it cannot be the case that any more facts will be added to I (as all threads have added all possible facts). The thread that encounters this situation sets run to false (line 11), indicating to all other threads that the materialisation process has completed. It then notifies all other threads of the change (line 12). (The other threads will be waiting at line 14 of the infer procedure.) All threads will then, as run=false, exit the infer procedure (line 1 of infer). I is returned as the materialisation of P on (the original database instance) I.
 1: while run do
 2:  while F := factsI.next and F ≠ ε do
 3:   for all (r, π, σ) ε P.rulesFor(F) do
 4:    evaluate(r, π, F, σ, 2)
 5:   end for
 6:  end while
 7:  increment W atomically
 8:  acquire m
 9:   while factsI.hasNext = false and run do
10:    if W = N then
11:     run := false
12:     notify all waiting threads
13:    else
14:     release m, wait for notification, acquire m
15:    end if
16:   end while
17:   decrement W atomically
18:  release m
19: end while
The procedure evaluate is now described, with reference to Procedure 2. The procedure evaluate is a recursive procedure (i.e. it calls itself). The procedure takes a rule r, permutation π, fact F, substitution σ, and index j. When called by infer, the rule r is the rule to be matched, the permutation π is the permutation of the body atoms of r, the fact F is the fact currently being considered, the substitution σ is the substitution for the matched atoms of r, and j is the index of the permutation π to be considered (and is initially set as 2 by infer, as the first atom has effectively been considered by P.rulesFor).
If j is greater than len(r) (the number of body atoms in r), this indicates that all body atoms have been successfully considered, and so the appropriate fact is added to I (line 21). This fact is h(r)σ, the head atom of the rule r with variables substituted by constants as defined by σ. (σ must substitute all variables in h with constants, as every variable in h must occurs in a body atom bi, and I.match would not have returned σ unless it substituted all variable in bi with constants.)
If j is not greater than the number of body atoms of r, the iterator it of substitutions matching body atom bπ(j) (r)σ with F is obtained, for facts in I<=F if the permuted index π(j) is bigger than the first permuted index π(1), and for facts in I<F otherwise (line 24). The procedure evaluate is then recursively called for the next index of the permutation π, for each substitution τ from it, with the combination of the current substitution σ and new substitution τ (line 27).
Thus, it can be seen that the procedure evaluate moves through the body atoms of the rule r, considering every possible valid substitution and adding the consequence of any matched rule when found.
Importantly, I.match is only ever called with facts returned by factsI.next, and so the ordering of facts F does not need to be predetermined, but can be determined on the fly as the next fact is requested. In other words, factsI.next can simply return any fact F not previously returned, and this determines the position of F in the ordering <; as the ordering < is not predetermined, nothing needs to be done to ensure that a fact returned by factsI.next can be safely returned as the “next”, and I.match will always have sufficient knowledge of the ordering <(i.e. when called with a fact F it will know the identity of all the facts F′<F it requires in order to operate, and it will know that for any other facts F″ not yet returned it must be the case that F<F″).
20: if j > len(r) then
21:  I.add(h(r)σ)
22:  if W > 0 then notify all waiting threads
23: else
24:  it := I.match(bπ(j)(r)σ, π(j) > π(1), F)
25:  while it.hasNext do
26:   τ := it.next
27:   evaluate(r, π, F, σ ∪ τ, j + 1)
28:  end while
29: end if
There is now described a method of storing data in computer memory in accordance with another first embodiment of the invention. The method reduces interference of concurrent updates, but also efficiently enumerates matches to RDF atoms.
A data structure 100 used by the method is partially shown in FIG. 2. The data structure records the triples of the database instance I in a six-column triple table 101. The data structure 100 also comprises indexes Is 102, Isp 103, and Ispo 104.
The resources used by the database instance I, i.e. the items that are used as subjects and objects of triples, and the relations that are used as predicates of triples, are mapped to integers. The mapping is recorded as a lookup dictionary.
For each triple, the subject, predicate and object are stored (as integers) in columns Rs, Rp and Ro respectively. Further, each triple participates in three linked lists, an sp-list, p-list and op-list. To implement these lists, a pointer to the next item in each of the lists is stored in the columns Nsp, Np and Nop respectively.
For each distinct subject occurring in the triple table 101, the sp-list connects all triples with that subject, grouped (but not necessarily sorted) by their predicate. For example, in FIG. 1 there is an sp-list consisting of triples <1, 3, 2>, <1, 3, 4>, <1, 1, 2> and <1, 1, 1>, containing sp-groups <1, 3> and <1, 1>. There is also an sp-list consisting of triples <2, 1, 4> and <2, 1, 3>, which are in the same sp-group <2, 1>.
To allow efficient access to the triples in the triple table 101, the index Is 102 associates each subject s with the head (i.e. first triple) Is[s] of the corresponding sp-list. Is 102 is implemented as an array indexed by subjects. To match an RDF atom of the form <s, x, y> (i.e. the subject in the atom is the constant s, but the predicate and object are variables), Is[s] is looked up and then the entire linked list is traversed. (If x=y then any triples which do not have the same predicate and object can simply be skipped over.) Further, the index Isp 103 associates each sp-group <s, p> with its first triple Isp[s, p]. Isp 103 is implemented as a hash table. In order to reduce the memory required, each bucket of Isp 103 stores only a pointer to the first triple of the group, as the bucket's key (i.e. the corresponding pair <s, p>) can be retrieved from the triple table 101. To match an atom of the form <s, p, x> (i.e. the subject and predicate in the atom are the constants s and p respectively, but the object is a variable), Isp[s, p] is looked up, and the linked list is traversed until a triple with a predicate other than p is reached, or the linked list ends.
Further, the index Ispo 104 provides an index for all triples, allowing atoms of the form <s, p, o> (i.e. atoms where the subject, predicate and object in the atom are the constants s, p and o respectively) to be efficiently matched. Ispo 104 is implemented as a hash table, and similarly to Isp 103 each bucket of Ispo 103 can store only a pointer to the corresponding triple.
In addition to the triple table 101 and associated indexes 102 to 104, the data structure 100 comprises op-lists and associated indexes Io and Iop, and p-lists and associated index Ip (not shown in FIG. 2). The op-lists connect all triples with object o, grouped by predicate p. The index Io associates each object o with the head Io[o] of the corresponding op-list. The index Iop associates each op-group <o, p> with its first triple Iop[o, p]. Similarly to above, Io is implemented as an array indexed by objects and Iop is implemented as a hash table, and they are used to match atoms of the form <x, y, o> and <x, p, o> respectively. The p-lists connect all triples with the same predicate (without any further grouping). The index Ip associates each predicate p with the head Ip[p] of the corresponding p-list, is implemented as an array indexed by predicates, and is used to match atoms of the form <x, p, y>.
To look up atoms of the form <s, x, o>, either Is[s] is looked up, and triples whose object is different from o are skipped over; or Io[o] is looked up, and triple whose subject is different from s are skipped over. In order to determined which index should be used, with each entry in Is and Io is recorded the number of items in the lists Is[s] and Io[o] respectively, and the index with the smaller number of items is used.
Finally, atoms of the form <x, y, z> (i.e. for which each of the subject, predicate and object are variables) can be matched by iterating over the triple table 101, as in this case every triple in the triple table 101 is matched. (Unless two or more of the variables are the same, in which case any triples in the triple table 101 for which the corresponding constants are not the same are skipped over.)
In alternative embodiments other indexes can be used, for example others of the six indexes of the form I, that associate pairs of properties of triples with triples in the triple table 101. Further indexes will increase the speed at which triples can be looked up in the triple table, but at the expense of increased memory consumption.
Each triple in the triple table 101 also has a status flag (not shown in FIG. 2), which is used to indicate whether a triple has been added to all the relevant indexes.
Using the data structure 100, I.match(A, L, F) is implemented by identifying all matches for A as described above, but with any triples occurring in the triple table 101 (i.e. which come after F in the ordering <) being skipped over (which can be easily determined by a comparison of their pointers).
Further, factsI keeps an index into the triple table 101, but returns only facts which are fully committed, in other words for which the status flag has been set to indicate that they have been included in all relevant indexes. This allows facts to be added to the triple table 101 without the triple table 101 and all relevant indexes having to be locked. No concurrency issues will arise, as when a fact F is returned by factsI when requested by the infer procedure, in addition to F only facts F′<F will be considered by the infer procedure, and these must all have already been fully committed. This means, in particular, that no facts can fail to be derived due to a required fact not being available in the triple table or indexes when queried.
The insertion of triples into the triple table 101, as performed by I.add(F), is now described. The procedure insert-triple that performs the insertion is shown in Procedure 3. In the procedure, Ispo.buckets is the array of buckets of the Ispo index, and |Ispo.buckets| is the length of that array. The procedure takes as input the subject s, predicate p and object o of a triple <s, p, o>.
First, the hash code for the triple and the first bucket index are determined (line 1). If necessary, the hash table is resized as described in detail below (line 3). The buckets are then scanned iteratively (lines 4 to 11). For each bucket, the triple stored in the bucket is retrieved (line 6). If the bucket contains the triple to be stored the procedure is stopped (line 9), as in this case the triple does not need to be (and should not be) added to I. If the bucket is empty (i.e. its contents is null), the loop is exited (line 8). The empty bucket is then locked by temporarily storing in it a marker INS (line 12); other threads executing the procedure insert-triple then know that if they find a marker INS in a bucket they must wait until the bucket is unlocked by having the marker INS overwritten by a triple (lines 5 to 7). The bucket is then locked using the conventional compare-and-set operation CAS (line 12). (CAS(loc, exp, new) retrieves the value old stored at location loc; stores new into loc if old=exp; and returns old; modern hardware ensures these steps are performed atomically without interference from any concurrent operations in other threads.) If the CAS operation fails, i.e. the contents of the bucket is no longer null, the bucket is re-examined, as another thread could have just inserted the same triple. If the CAS operation succeeds, the triple is added to the triple table (line 13), and a pointer to the triple is added to the bucket (line 13), overwriting INS, and hence unlocking the bucket.
 1: h := hash(s, p, o), i := h & (|Ispo.buckets| − 1)
 2: do
 3:  Handle resize if needed
 4:  loop
 5:   do
 6:    T := Ispo.buckets[i]
 7:   while T = INS
 8:   if T = null then break
 9:   if T.Rs = s 
Figure US10817467-20201027-P00001
 T.Rp = p 
Figure US10817467-20201027-P00001
 T.Ro = o then stop
10:   i := (i + 1) & (|Ispo.buckets| − 1)
11:  end loop
12: while CAS(Ispo.buckets[i], null, INS ≠ null
13: Add a new triple Tnew =
Figure US10817467-20201027-P00002
 s, p, o 
Figure US10817467-20201027-P00003
 to the triple table
14: Ispo.buckets[i] := Tnew
When a new triple Tnew is added to the triple table 101, all the indexes must be updated. To update the index Isp 103, its buckets are scanned as in the steps of the procedure insert-triple. If a bucket is found containing a triple T, Tnew is added using the procedure insert-fp-list shown in Procedure 4. First, the triple Tnext that follows T in the sp-list is found (line 2), and made the next triple for Tnew (line 3). T.Nsp is updated to T if it has not been updated by another thread (line 4); if it has been updated, the entire procedure is simply repeated. This allows the new triple Tnew to be inserted without any locking being required.
1: do
2:  Tnext := T.Nsp
3:  Tnew.Nsp := Tnext
4: while CAS(T.Nsp,Tnext,Tnew) ≠ Tnext
If the index Isp does not contain a bucket for the given sp-group, Tnew is added to the bucket and made the head of the bucket in the index I s 102. This requires two CAS operations, and local locking; in other words, INS is stored into the bucket of Isp, Is is updated using an analogous procedure to insert-fp-list, and then Inew is stored in Isp, unlocking the bucket.
Iop and Io are updated analogously to Isp and Is, and Ip is updated using an analogous procedure to insert-fp-list. Updates to Ispo, Isp and Is, Iop and Io, and Ip are independent (i.e. can be done concurrently without there being any interference between them).
The method of resizing hash tables as may be performed in line 3 of procedure insert-triple is now described, with reference to the flowcharts of FIGS. 3a and 3b . The hash tables herein are implemented with open addressing. The threshold will conventionally be a percentage of used buckets, so 70% of buckets are used. (As is well-known, hash tables with open addressing conventionally store new entries in the next available free bucket after the bucket pointed to by the hash of a new entry. As a hash table fills up, the distance to the next available bucket increases, reducing performance. By doubling the size of the hash table after the threshold is met, performance is improved while avoiding the hash table being significantly larger than is required to store the entries it contains.)
As shown in FIG. 3a , once the threshold is reached (step 200), a single thread temporarily locks the entire index (step 201), allocates a new bucket array (step 202), sets a flag indicating that resizing is in progress (step 203), and unlocks the index (step 203). Subsequently, as shown in FIG. 3b , whenever a thread tries to access the index (step 205) but sees from the flag that resizing is in progress (step 206), it extract a range of buckets from the old array, say 1024 buckets (step 207), and transfers them to the new array. (If the resize flag is not set it continues with its usual procedure (step 207).) The transfer can be done without any locking being required, as during resizing no new entries will need to be added to the triple table 101. The process is repeated until all buckets have been transferred (step 209), and the thread that moves the final buckets then de-allocates the old array (step 210) and resets the resize flag (step 211).
In an embodiment of the invention, to avoid interference between threads each thread is provided with a proxy that provides a thread with “private” insertion points for the insertion of triples. This avoids interference due to the threads all adding triples to the end of the triple table 101, and triples being added after the first triple in an sp- or op-group, which requires updating of the next-pointer of the first triple.
Each proxy reserves a range of space in the triple table 101, so that different threads write to different areas of the triple table 101. This allows the locking of buckets of Ispo 104 in the procedure insert-triple to be avoided, because as the space for a new triple is reserved for a particular thread before the triple is inserted, the insertion can be done before the index Ispo 104 is updated. If when Ispo 104 is updated it is seen that the index already contains the triple, it can simply be removed from the triple table.
Further, each proxy keeps a local copy of the indexes Isp 103 and Iop, to maintain its own insertion points in the sp- and op-lists. To insert a new triple Tnew, the proxy first queries the local Isp index for the relevant sp-group. If there is no match, it is inserted into the global indexes as described above, and is also stored in the local Isp index. If on the other hand the local index Isp contains a triple T for the sp-group, Tnew is added after T; as the index is local to the thread, this can be done without requiring a CAS operation. This ensures threads write to different memory locations, and also reduces the number of CAS operations required. The local Iop index is maintained analogously.
As maintaining local indexes is an overhead, each proxy counts the number of triples it has encounters for each subject and object, and uses local indexes only where a threshold of triples (say 100 triples) is exceeded.
The use of proxies results in the complication that factsI will eventually point to a location in a reserved range that does not yet contain a triple. If this occurs the location cannot simply be skipped over by factsI, as a later insertion of a triple into the location by a proxy would result in the I.match procedure failing to operate correctly. To solve this problem, when it is detected that factsI points to an unused location, all unused location are marked as unused, and subsequently all new triples are added to the end of the triple table without proxies being used. This typically occurs only very late in the materialisation process, and is a final phase typically taking less than 1% of the overall time, so the reduction in efficiency due to no longer using proxies in negligible.
An embodiment of the invention in which the database being materialised incorporates the equality predicate owl:sameAs is now described. The embodiment uses a procedure similar to the infer procedure described above. However, in addition a mapping ρ of constants to constants is maintained; this maps a constant to a constant with which it is equal, and which is the selected representative for all such equal constants. A fact F is “outdated” if ρ(F) is not equal to F, and similarly for a rule R, where the substitution is applied to facts and rules by substituting the constants they contain. Further, the procedures use a queue of rules; R.enqueue(r) adds the rule r to the queue, and R.dequeue obtains a rule from the queue. Finally, the set of facts factsI is provided with a status marker for each fact it contains, which is used to mark a fact as outdated; factsI.mark(F) applies the marker to the fact F. A queue of constants C is also used to which constants can be queued and dequeued in a corresponding manner is also used.
In each main loop of execution, the materialisation procedure can perform one of three actions, which are as follows.
The first procedure is to process a fact from the set of facts factsI, similarly to the previous embodiment. The procedure applyRules that performs this is shown in Procedure 5. (Note that factsI is denoted T in following procedures.) However, before a fact F is processed it is checked whether it is marked as outdated. If it is not marked, the constant mapping is applied to F, and if this shows that F is outdated it is marked as such, and the updated fact with the mapping applied is added to the set of facts factsI, and all threads are notified that there has been a change to the set of facts. The operation of the constant mapping is described later below.
If F is not outdated, if it is of the form <a, owl:sameAs, b> then if a and b are distinct then the minimum of the two is selected as the representative for the other. (Any arbitrary total ordering of the constants can be used to determine the minimum and maximum.) The substitution for the other is merged into the mapping using a procedure ρ.mergeInto which is also described later below, and the other is added to the queue of constants C. As it is always the minimum constant that is chosen as the representative, and it has been determined that F is not outdated, the representative will always be a representative that has been chosen on a past occasion, or a newly chosen representative for a set of equal constants the members of which are being substituted for the first time.
If F is of the form <a, owl:differentFrom, a> then the set of rules must be internally contradictory, and so this is notified to all threads.
Finally, when F is of any other form it is evaluated similarly to the previous embodiment. In addition, the reflexive fact <c, owl:sameAs, c> is added to the set of facts factsI for each constant c in F.
Procedure 5 - applyRules
 1: F := T.next
 2: if F ≠ ε and F is not marked as outdated then
 3:  G := ρ(F)
 4:  if F ≠ G then
 5:   if T.mark(F) and T.add(G) then notify all waiting threads
 6:  else if F is of the form (a, owl:sameAs, b) then
 7:   if a and b are distinct then
 8:    c := min{a, b}; d := max{a, b}
 9:    if ρ.mergeInto(d, c) then C.enqueue(d) and notify all waiting
   threads
10:  else if F is of the form (a, owl:differentFrom, a) then
11:   derive a contradiction and notify all waiting threads
12:  else
13:   for each (r, Q, σ) ε P′.rules(F) and each τ ε T.evaluate(Q, F, σ) do
14:    if T.add(h(r)r) then notify all waiting threads
15:   for each resource c occurring in F do
16:    if T.add((c, owl:sameAs, c)) then notify all waiting threads
17: return F ≠ ε
The second procedure is to evaluate any queued rules by evaluating their bodies and then adding their heads to the set of facts factsI. The queued rules are rules that have been updated by the mapping, and so this procedure applies these updated rules to the facts in factsI. (The process by which rules become queued is described later below.) The procedure evaluateUpdatedRules that performs this is shown in Procedure 6. It will be appreciated that due to the parallel nature of the overall materialisation procedure, an instantiated head that is added to factsI may be outdated. This is why outdated facts in factsI are marked as such rather than being deleted, to prevent outdated facts that have been removed being reintroduced and consequently needing to be checked again to determine if they are outdated.
1: r := R.dequeue
2: if r ≠ ε then
3:  for each τ ε T.evaluate(b(r) 
Figure US10817467-20201027-P00004
 , L, ∅) do
4:   if T.add(h(r)r) then notify all waiting threads
5: return r ≠ ε
The third procedure is to rewrite the facts in factsI using any newly substituted constants, which as described above are queued in the queue C when their substitution is added to the mapping ρ. The procedure rewriteFacts that performs this is shown in Procedure 7. Only facts that are not marked as outdated are rewritten; a fact marked outdated does need to be rewritten because applyRules adds its rewritten version to factsI at the same time as marking it as outdated.
1: c := C.dequeue
2: if c ≠ ε then
3:  for each unmarked fact F ε T that contains c do
4:   if T.mark(F) and T.add(ρ(F)) then notify all waiting threads
5: return c ≠ ε
The three procedures above are performed until there is no more work that they can do. This is shown below in the overall procedure materialise, shown in Procedure 9. Once they are all waiting, the updated version ρ(r) of each outdated rule r in the program is added to the queue R of updated rules, and each rule in the program itself is also updated. If no rules are added to the queue, which is determined by R.isEmpty, the materialisation has completed and the run flag is set accordingly to signal termination. Otherwise, the main loop of execution is repeated by performing again the procedures applyRules, evaluateUpdatedRules and rewriteFacts.
Procedure 8 - materialise
 1: while run do
 2:  if -evaluateUpdatedRules( ) and -rewriteFacts( ) and -applyRules( )
 then
 3:   increment W atomically
 4:   acquire m
 5:    while R.isEmpty and C.isEmpty and -(T.hasNext and run do
 6:     if W = N then
 7:      for each r ε P′ such that r ≠ ρ(r) and ρ(r) ∉ P′ ∪ R do
 8:       R.enqueue(ρ(r))
 9:      L := T.last
10:      P′ := ρ(P)
11:      run := R.isEmpty
12:      notify all waiting threads
13:     else
14:      release m, wait for notification, acquire m
15:    decrement W atomically
16:   release m
The implementation of the mapping of constants is now described. The mapping ρ is implemented using arrays repρ and nextρ which are indexed by constants and initialised with zeros. repρ[c] is zero if c represents itself, otherwise repρ[c] is the resource that is the representative for c. nextρ defines a linked list of constants that are equal, where nextρ[c] is a pointer to the next constant in the list.
The procedure ρ(c) to substitute a constant with its representative is shown in Procedure 9. The substitution of constants in facts and rules is then performed in the corresponding manner. repρ is traversed until a non-merged constant is found, which is then returned. If another thread updates ρ by updating repρ[r], scanning of repρ continues past r, so that the result is at least as current as ρ was when the procedure was begun.
1: r := c
2: loop
3:  r′ := repρ[r]
4:  if r′ = 0 then
5:   return r
6:  else
7:   r := r′
The procedure ρ.mergeInto(d,c) to update the mapping so that d is substituted with c is shown in Procedure 10. The procedure uses a compare-and-set primitive CAS that prevents thread interference; CAS(loc, exp, new) atomically loads the value stored at location loc into a temporary variable old, stores new into loc if old=exp, and returns old.
In the procedure, first repρ is updated to indicate that d should be replaced with c. If this update is successful, the variable e scans the linked list for the constants replaced by c until the end of the list is found; this is done by the while statement, which is evaluated lazily so that the latter statement CAS(nextρ[e], 0, d) is not evaluated to see if it does not equal 0 as long as the former statement nextρ[e] does not equal 0. Once the end of the linked list for c is found, it is updated to point to d; if this update is not successful (due to concurrent updates meaning it e is no longer the end of the list, and consequently it is not equal to zero), the constant e returns to scanning for the end of the list.
1: if CAS(repρ[d], 0, c) = 0 then
2:  e := c
3:  while nextρ[e] ≠ 0 or CAS(nextρ[e], 0, d) ≠ 0 do
4:   e := nextρ[e]
5:  return true
6: else
7:  return false
An embodiment of the invention also provides a method of answering SPARQL queries on materialised databases that include facts that have been rewritten in accordance with the previous embodiment. SPARQL (SPARQL Protocol and RDF Query Language) is a database query language for RDF databases somewhat similar to the SQL query language for relational databases.
Given a set of facts T and a mapping ρ, a query Q could be answered by expanding the set of facts T using the mapping ρ, but this would be very inefficient. Alternatively, the mapping ρ could be applied to the query Q, and then the answer could be expanded. However, this would not always give the correct answer, for two reasons.
The first reason is due to the “bag” semantics of SPARQL, for which repeated answers matter. For example, in a set of facts:
<Obama, presidentOf, USA>, <Obama, presidentOf, US>,
<USA, owl:sameAs, US>
the query:
SELECT ?x WHERE {?x presidentOf ?y}
will return the result:
{?x→Obama}, {?x→Obama}.
In other words, the answer is repeated, once for the fact <Obama, presidentOf, USA> and once for the fact <Obama, presidentOf, US>. However, as these constants are equal, in a database materialised according to the above embodiment only one of the facts would appear. As a result, if the mapping were applied to the query, the answer on the materialised database would not be repeated, nor would it be once expanded.
To solve this problem, the expansion is adapted so that for each variable used in the query, the set of answers for that variable is duplicated where another variable has as an answer a constant that is a representative of a set of equal constants. Thus, duplicated answers are returned as required.
The second reason is due to built-in functions of SPARQL. For example, if the database includes the additional fact <USPresident, presidentOf, US>, then evaluating the query:
SELECT ?y WHERE {?x presidentOf US.BIND(STR(?y) AS?x)} will return on the expanded materialised database the result:
{?y →Obama} and {?y-→USPresident}.
However, the mapped query applied to the unexpanded materialised database will only return {?y→Obama}, as the strings Obama and USPresident are not equal, and the subsequent expansion will not provide the missing answer.
To solve this problem, the answers are expanded before any built-in functions are evaluated; after evaluation the answers are again expanded, however without the answers now being duplicated as the required duplication has already been provided by the initial expansion.
Whilst the present invention has been described and illustrated with reference to particular embodiments, it will be appreciated by those of ordinary skill in the art that the invention lends itself to many different variations not specifically illustrated herein.

Claims (9)

The invention claimed is:
1. A computer-implemented method, performed by a computer system,
the computer system including i) a logical database including a set of logical facts and at least one index that includes a pointer for locating a logical fact in the set of logical facts, and ii) a plurality of parallel processing threads, wherein each of the plurality of parallel processing threads has an associated reserved area in the logical database for adding a new logical fact to the set of logical facts,
the method including providing, by the computer system, a materialisation of a set of logical rules on the logical database, wherein each of the plurality of parallel processing threads of the computer system performs steps comprising:
1) retrieving a logical fact from the set of logical facts, wherein the retrieved logical fact has not previously been retrieved by any thread;
2) applying at least one logical rule from the set of logical rules to the retrieved logical fact and any of the logical facts previously retrieved by any thread to derive a new logical fact;
3) adding the new logical fact to the set of logical facts and updating the at least one index; and
4) repeating steps 1 to 3 of the method while there are logical facts in the set of logical facts that have not previously been retrieved by any thread;
wherein the set of logical facts includes at least one logical fact incorporating an equality predicate indicating that two constants are equal, and a mapping of constants to representative constants is maintained, the method further including the steps of:
selecting a representative constant from the two constants;
updating the mapping to map an other constant of the two constants to the representative constant; and
rewriting logical facts in the set of logical facts using the mapping to replace occurrences of the other constant with the representative constant,
wherein, when adding the new logical fact to the set of logical facts and updating the at least one index:
each thread of the plurality of parallel processing threads adds the new logical fact only to its associated reserved area in the logical database without locking the associated reserved areas of the other parallel processing threads; and
each thread of the plurality of parallel processing threads performs an index update process to update the at least one index with the new logical fact without locking the at least one index, sets a status flag to indicate whether the at least one index has been successfully updated, and repeats the update index process in a case where the status flag indicates that the at least one index has not been successfully updated.
2. The method as claimed in claim 1, wherein in step 3, each thread provides notification to any waiting threads that a new logical fact has been added.
3. The method as claimed in claim 1, wherein in step 1 the retrieved logical fact is received from an iterator which selects the retrieved logical fact from among the logical facts in the set of logical facts that have not previously been selected by the iterator.
4. The method as claimed in claim 1, further comprising the step, prior to performing materialisation of the set of logical rules on the logical database, of pre-processing the set of logical rules to determine a join ordering.
5. The method as claimed in claim 1, wherein, when the representative constant is selected, the other constant is added to a queue of constants, and wherein the logical facts are rewritten by replacing occurrences of constants contained in the logical facts in a queue of constants with respective representative constants.
6. The method as claimed in claim 1, further comprising the step of rewriting the logical rules in the set of logical rules using the mapping to replace occurrences of other constants with their representative constants.
7. The method as claimed in claim 1, further comprising the steps of:
determining if a logical rule from the set of logical rules contains any constants that are mapped by the mapping to representative constants; and
in a case where the logical rule contains constants that are mapped, adding the logical rule to a queue of logical rules,
wherein the logical rules that are rewritten are the logical rules in the queue of logical rules.
8. The method as claimed in claim 1, further comprising the steps of:
determining if a logical fact from the set of logical facts contains any constants that are mapped by the mapping to representative constants; and
in a case where the logical fact contains constants that are mapped, adding a marker to the logical fact.
9. The method as claimed in claim 8, wherein in step 1a logical fact is retrieved from the set of logical facts only if a marker has not been added to the logical fact.
US15/033,583 2013-10-31 2014-10-30 Parallel materialisation of a set of logical rules on a logical database Active 2036-10-09 US10817467B2 (en)

Applications Claiming Priority (5)

Application Number Priority Date Filing Date Title
GBGB1319252.1A GB201319252D0 (en) 2013-10-31 2013-10-31 Parallel materialisation of a set of logical rules on a logical database
GB1319252.1 2013-10-31
GB1416133.5 2014-09-12
GB201416133A GB201416133D0 (en) 2014-09-12 2014-09-12 Parallel materialisation of a set of logical rules on a logical database
PCT/GB2014/053230 WO2015063491A2 (en) 2013-10-31 2014-10-30 Parallel materialisation of a set of logical rules on a logical database

Related Parent Applications (1)

Application Number Title Priority Date Filing Date
PCT/GB2014/053230 A-371-Of-International WO2015063491A2 (en) 2013-10-31 2014-10-30 Parallel materialisation of a set of logical rules on a logical database

Related Child Applications (1)

Application Number Title Priority Date Filing Date
US17/025,192 Continuation US11409698B2 (en) 2013-10-31 2020-09-18 Parallel materialisation of a set of logical rules on a logical database

Publications (2)

Publication Number Publication Date
US20160259796A1 US20160259796A1 (en) 2016-09-08
US10817467B2 true US10817467B2 (en) 2020-10-27

Family

ID=51846708

Family Applications (2)

Application Number Title Priority Date Filing Date
US15/033,583 Active 2036-10-09 US10817467B2 (en) 2013-10-31 2014-10-30 Parallel materialisation of a set of logical rules on a logical database
US17/025,192 Active 2035-01-21 US11409698B2 (en) 2013-10-31 2020-09-18 Parallel materialisation of a set of logical rules on a logical database

Family Applications After (1)

Application Number Title Priority Date Filing Date
US17/025,192 Active 2035-01-21 US11409698B2 (en) 2013-10-31 2020-09-18 Parallel materialisation of a set of logical rules on a logical database

Country Status (3)

Country Link
US (2) US10817467B2 (en)
EP (1) EP3063670A2 (en)
WO (1) WO2015063491A2 (en)

Families Citing this family (3)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
JP6855401B2 (en) * 2018-02-08 2021-04-07 ヤフー株式会社 Generation device, generation method, and generation program
US20200379820A1 (en) * 2019-05-29 2020-12-03 Advanced Micro Devices, Inc. Synchronization mechanism for workgroups
US11216456B1 (en) * 2020-08-26 2022-01-04 Oxford Semantic Technologies Limited Complex query evaluation using sideways information passing

Citations (16)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US5560006A (en) 1991-05-15 1996-09-24 Automated Technology Associates, Inc. Entity-relation database
US20050055330A1 (en) 2001-05-15 2005-03-10 Britton Colin P. Surveillance, monitoring and real-time events platform
US20060235837A1 (en) * 2005-04-18 2006-10-19 Oracle International Corporation Rewriting table functions as SQL strings
US20070038651A1 (en) * 2005-08-15 2007-02-15 Microsoft Corporation Interactive schema translation with instance-level mapping
US20070194957A1 (en) 2004-03-31 2007-08-23 Shinpei Watanabe Search apparatus and search management method for fixed-length data
EP1990741A1 (en) 2007-05-10 2008-11-12 Ontoprise GmbH Reasoning architecture
US20100169966A1 (en) 2008-12-30 2010-07-01 Oracle International Corporation Resource description framework security
US20100217784A1 (en) 2009-02-26 2010-08-26 Raytheon Company Information Viewing System
US7809752B1 (en) 2005-04-14 2010-10-05 AudienceScience Inc. Representing user behavior information
US20110082829A1 (en) * 2009-10-06 2011-04-07 Oracle International Corporation hybrid approach for equivalence reasoning
US20110125696A1 (en) 2009-11-20 2011-05-26 Oracle International Corporation Data source for parallel inference
US20120271787A1 (en) * 2009-11-27 2012-10-25 Korea Institute Of Science & Technology Information Rule reasoner, and dynamic materialization method for wild pattern rules including the same
WO2013137903A1 (en) 2012-03-16 2013-09-19 Orbis Technologies, Inc. Systems and methods for semantic inference and reasoning
US20130262443A1 (en) * 2012-03-30 2013-10-03 Khalifa University of Science, Technology, and Research Method and system for processing data queries
US20130346354A1 (en) * 2012-06-21 2013-12-26 David Mizell Forward inferencing of facts in parallel
US20140156587A1 (en) * 2012-06-19 2014-06-05 Ontotext AD Rdf data warehouse via partitioning and replication

Family Cites Families (3)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US6438562B1 (en) * 1999-08-24 2002-08-20 Oracle Corporation Parallel index maintenance
US20060112121A1 (en) * 2004-11-23 2006-05-25 Mckenney Paul E Atomically moving list elements between lists using read-copy update
US9519668B2 (en) * 2013-05-06 2016-12-13 International Business Machines Corporation Lock-free creation of hash tables in parallel

Patent Citations (17)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US5560006A (en) 1991-05-15 1996-09-24 Automated Technology Associates, Inc. Entity-relation database
US20050055330A1 (en) 2001-05-15 2005-03-10 Britton Colin P. Surveillance, monitoring and real-time events platform
US20070194957A1 (en) 2004-03-31 2007-08-23 Shinpei Watanabe Search apparatus and search management method for fixed-length data
US7809752B1 (en) 2005-04-14 2010-10-05 AudienceScience Inc. Representing user behavior information
US20060235837A1 (en) * 2005-04-18 2006-10-19 Oracle International Corporation Rewriting table functions as SQL strings
US20070038651A1 (en) * 2005-08-15 2007-02-15 Microsoft Corporation Interactive schema translation with instance-level mapping
EP1990741A1 (en) 2007-05-10 2008-11-12 Ontoprise GmbH Reasoning architecture
US20100138698A1 (en) * 2007-05-10 2010-06-03 Onotprise Gmbh Reasoning architecture
US20100169966A1 (en) 2008-12-30 2010-07-01 Oracle International Corporation Resource description framework security
US20100217784A1 (en) 2009-02-26 2010-08-26 Raytheon Company Information Viewing System
US20110082829A1 (en) * 2009-10-06 2011-04-07 Oracle International Corporation hybrid approach for equivalence reasoning
US20110125696A1 (en) 2009-11-20 2011-05-26 Oracle International Corporation Data source for parallel inference
US20120271787A1 (en) * 2009-11-27 2012-10-25 Korea Institute Of Science & Technology Information Rule reasoner, and dynamic materialization method for wild pattern rules including the same
WO2013137903A1 (en) 2012-03-16 2013-09-19 Orbis Technologies, Inc. Systems and methods for semantic inference and reasoning
US20130262443A1 (en) * 2012-03-30 2013-10-03 Khalifa University of Science, Technology, and Research Method and system for processing data queries
US20140156587A1 (en) * 2012-06-19 2014-06-05 Ontotext AD Rdf data warehouse via partitioning and replication
US20130346354A1 (en) * 2012-06-21 2013-12-26 David Mizell Forward inferencing of facts in parallel

Non-Patent Citations (11)

* Cited by examiner, † Cited by third party
Title
"Microsoft SQL Server Development Customer Advisory Team: Load 1TB in less than 1 hour." Dec. 13, 2007. 5 pages. Web Mar. 6, 2020. URL:https://web.archive.org/web/20071213231828/http://blogs.msdn.com/sqlcat/archive/2006/05/19/602142.aspx. Cited in NPL 1.
"Thread (computing)", "retrieved from Internet at: http://en.eikipedia.org/w/index.php?title=Thread_%28computing%29&oldid=578888975 [retrieved on Apr. 15, 2013]", Oct. 26, 2013, pp. 1-14.
GB Intellectual Property Office, "Search Report from GB Application No. 1319252.1 dated Jan. 23, 2015", Jan. 23, 2015, pp. 1-2, Published in: GB.
GB Patent Office, "Search Report from GB Application No. 1319252.1 dated Mar. 31, 2014", Mar. 31, 2014, pp. 1-4, Published in: GB.
Incrementalmaintenanceofmaterializedviewswithouterjoins (Anisoara Nica, Sybase) (Year: 2011). *
International Searching Authority, "International Search Report and Written Opinion from PCT Application No. PCT/FB2014/053230 dated Apr. 29, 2015", Apr. 29, 2015, pp. 1-14, Published in: WO.
Representing Facts and Rules in RDF (Graham Klyne) (Year: 2002). *
Summons to Attend Oral Proceedings issued in European Appln. No. 14793259.4 dated Mar. 20, 2020.
Urbani et al., "DynamiTW: Parallel Materialization of Dynamic RDF Data", "The Semantic Web-ISWC 2013. 12th International Semantic Web Conference Proceedings", pp. 657-672, Publisher: Springer-Verlag.
Urbani et al., "DynamiTW: Parallel Materialization of Dynamic RDF Data", "The Semantic Web—ISWC 2013. 12th International Semantic Web Conference Proceedings", pp. 657-672, Publisher: Springer-Verlag.
Volz et al., "Incremental Maintenance of Materialized Ontologies", "Lecture Notes in Computer Science", Jan. 1, 2003, pp. 1-19.

Also Published As

Publication number Publication date
US20160259796A1 (en) 2016-09-08
US11409698B2 (en) 2022-08-09
EP3063670A2 (en) 2016-09-07
US20210004351A1 (en) 2021-01-07
WO2015063491A2 (en) 2015-05-07
WO2015063491A3 (en) 2015-06-25

Similar Documents

Publication Publication Date Title
US11409698B2 (en) Parallel materialisation of a set of logical rules on a logical database
US6990503B1 (en) Rescheduling transactions in a database system
US10846278B2 (en) Dynamic updates to a semantic database using fine-grain locking
US6751617B1 (en) Method, system, and data structures for implementing nested databases
US7962693B1 (en) Cache management system providing improved page latching methodology
US20050102255A1 (en) Computer-implemented system and method for handling stored data
AU2016244128B2 (en) Processing database transactions in a distributed computing system
Antova et al. Fast and simple relational processing of uncertain data
US7376674B2 (en) Storage of multiple pre-modification short duration copies of database information in short term memory
US7149737B1 (en) Locking mechanism using a predefined lock for materialized views in a database system
US6339777B1 (en) Method and system for handling foreign key update in an object-oriented database environment
US20040225673A1 (en) Range-clustered tables in a database management system
US9460143B2 (en) Methods, systems, and computer readable media for a multi-view data construct for lock-free operations and direct access
CN103886109B (en) Method and device for realizing row lock of database
JP2001523367A (en) Database management system and method for combining metadata for conditional contention serializability of transactions and varying degrees of reliability
Taniar et al. A taxonomy of indexing schemes for parallel database systems
CN107665255B (en) Method, device, equipment and storage medium for key value database data change
CN104123356A (en) Method for increasing webpage response speed under large data volume condition
CN112867999B (en) Version-based table locking
US8095731B2 (en) Mutable object caching
US20040107200A1 (en) Database constraint enforcer
Lomet et al. Locking key ranges with unbundled transaction services
AU2001272863A1 (en) Method, system and data structures for implementing nested databases
EP1323071A2 (en) Method, system and data structures for implementing nested databases
Chirigati et al. Virtual lightweight snapshots for consistent analytics in NoSQL stores

Legal Events

Date Code Title Description
STPP Information on status: patent application and granting procedure in general

Free format text: NON FINAL ACTION MAILED

AS Assignment

Owner name: UNIVERSITY OF OXFORD, UNITED KINGDOM

Free format text: ASSIGNMENT OF ASSIGNORS INTEREST;ASSIGNORS:MOTIK, BORIS;NENOV, YAVOR;HORROCKS, IAN;REEL/FRAME:048620/0897

Effective date: 20190307

Owner name: OXFORD UNIVERSITY INNOVATION LIMITED, UNITED KINGD

Free format text: CHANGE OF NAME;ASSIGNOR:ISIS INNOVATION LIMITED;REEL/FRAME:048621/0112

Effective date: 20160616

Owner name: ISIS INNOVATION LIMITED, UNITED KINGDOM

Free format text: ASSIGNMENT OF ASSIGNORS INTEREST;ASSIGNOR:UNIVERSITY OF OXFORD;REEL/FRAME:048621/0037

Effective date: 20131118

Owner name: OXFORD UNIVERSITY INNOVATION LIMITED, UNITED KINGDOM

Free format text: CHANGE OF NAME;ASSIGNOR:ISIS INNOVATION LIMITED;REEL/FRAME:048621/0112

Effective date: 20160616

STPP Information on status: patent application and granting procedure in general

Free format text: RESPONSE TO NON-FINAL OFFICE ACTION ENTERED AND FORWARDED TO EXAMINER

STPP Information on status: patent application and granting procedure in general

Free format text: FINAL REJECTION MAILED

STPP Information on status: patent application and granting procedure in general

Free format text: ADVISORY ACTION MAILED

STPP Information on status: patent application and granting procedure in general

Free format text: DOCKETED NEW CASE - READY FOR EXAMINATION

STPP Information on status: patent application and granting procedure in general

Free format text: NON FINAL ACTION MAILED

STPP Information on status: patent application and granting procedure in general

Free format text: RESPONSE TO NON-FINAL OFFICE ACTION ENTERED AND FORWARDED TO EXAMINER

STPP Information on status: patent application and granting procedure in general

Free format text: NOTICE OF ALLOWANCE MAILED -- APPLICATION RECEIVED IN OFFICE OF PUBLICATIONS

STCF Information on status: patent grant

Free format text: PATENTED CASE

MAFP Maintenance fee payment

Free format text: PAYMENT OF MAINTENANCE FEE, 4TH YEAR, LARGE ENTITY (ORIGINAL EVENT CODE: M1551); ENTITY STATUS OF PATENT OWNER: LARGE ENTITY

Year of fee payment: 4