What are hybrid inference engines? - artificial-intelligence

I've tried searching a lot for this, even so, if a similar post has been made I apologize.
I understand that a rule engine has basically two methods of inferences, forward and backward chaining. I also believe I understand how both work individually, however how will an engine with mixed inference function, will it first perform forward chaining then backwards or vice versa? Or is there a possibility for the engine to decide on which inference to use based on the knowledge base and facts in the working memory?
Also, if i'd like to build an engine with both methods of inference, is enhancing the matching algorithm being used(Rete, Treat etc) the way to start?
I know I asked a lot of questions and if any one can answer or refer me to some literature with reference to any part I'd really be grateful.
Thanks!

I'd suggest taking a look at Jess and Drools. Both of these tools implement forward and backward chaining, so you can take a look at how this is practically implemented.
One way to implement backward chaining in a forward chaining tool is to implement automatic goal generation in conjunction with providing patterns that can match these goals. For example, here are some rule excerpts from an automotive repair program written in CLIPS (that only supports forward chaining):
(defrule determine-engine-state ""
(not (engine-starts ?))
(not (repair ?))
=>
(assert (engine-starts (yes-or-no-p "Does the engine start (yes/no)? "))))
(defrule determine-rotation-state ""
(engine-starts no)
(not (repair ?))
=>
(assert (engine-rotates (yes-or-no-p "Does the engine rotate (yes/no)? "))))
(defrule determine-gas-level ""
(engine-starts no)
(engine-rotates yes)
(not (repair ?))
=>
(assert (tank-has-gas
(yes-or-no-p "Does the tank have any gas in it (yes/no)? "))))
(defrule tank-out-of-gas ""
(tank-has-gas no)
(not (repair ?))
=>
(assert (repair "Add gas.")))
The rules for asking questions have the prerequisite information contained within the conditions which is more difficult to maintain.
With automatic goal generation, the rules could be rewritten like this:
(defrule determine-engine-state ""
(goal (engine-starts ?))
=>
(assert (engine-starts (yes-or-no-p "Does the engine start (yes/no)? "))))
(defrule determine-rotation-state ""
(goal (engine-rotates ?))
=>
(assert (engine-rotates (yes-or-no-p "Does the engine rotate (yes/no)? "))))
(defrule determine-gas-level ""
(goal (tank-has-gas ?))
=>
(assert (tank-has-gas
(yes-or-no-p "Does the tank have any gas in it (yes/no)? "))))
(defrule tank-out-of-gas ""
(not (repair ?))
(engine-starts no)
(engine-rotates yes)
(tank-has-gas no)
=>
(assert (repair "Add gas.")))
In this case, the rules asking questions are simplified and much easier to maintain. Whenever there is a goal for a specific type of fact, the user is queried for its value. There's no need to encode prerequisite information for the questions. Automatic goal generation allows the tank-out-of-gas rule to drive the rules containing goals. If a repair has not yet been determined, then the (engine-starts no) pattern automatically generates a goal if an engine-starts fact is not present (the rule engine can determine that there's another rule, determine-engine-state, that matches on this goal fact). If the user responds no, then the (engine-starts no) pattern will be matched causing a goal to be generated for the engine-rotates fact (triggering the determine-rotation-state rule). If the user had responded yes, then the (engine-starts no) pattern would not have been matched and since no other rules are applicable, execution would stop.
With this methodology of goal generation, backward chaining is basically used to fetch data needed by forward chaining rules.

Related

Z3 Forall with array

Z3 provides unknown for the simple problem:
(assert
(forall ((y (Array Int Int)))
(= (select y 1) 0))
)
(check-sat)
I've found that it becomes sat if negate the forall, but this seems like a particularly simple thing to be unable to solve.
This is causing issues because the class of problems I want to solve are more like,
(declare-fun u () Int)
(assert
(forall ((y (Array Int Int)) )
(=>
(= u 0) (<= (select y 1) 0))
)
)
(check-sat)
Where negating the forall alone is not the same problem, so that cannot be done here. Is there some way to pose this style of problem to Z3 to get an un/sat result?
Problems with quantifiers are always problematic with SMT solvers, especially if they involve arrays and alternating quantifiers like in your example. You essentially have exits u. forall y. P(u, y). Z3, or any other SMT solver, will have hard time dealing with these sorts of problems.
When you have a quantified assertion like you do where you have forall's either at the top-level or nested with exists, the logic becomes semi-decidable. Z3 uses MBQI (model-based quantifier instantiation) to heuristically solve such problems, but it more often than not fails to do so. The issue isn't merely that z3 is not capable: There's no decision procedure for such problems, and z3 does its best.
You can try giving quantifier patterns for such problems to help z3, but I don't see an easy way to apply that in your problem. (Quantifier patterns apply when you have uninterpreted functions and quantified axioms. See https://rise4fun.com/z3/tutorialcontent/guide#h28). So, I don't think it'll work for you. Even if it did, patterns are very finicky to program with, and not robust with respect to changes in your specification that might otherwise look innocuous.
If you're dealing with such quantifiers, SMT solvers are probably just not a good fit. Look into semi-automated theorem provers such as Lean, Isabelle, Coq, etc., which are designed to deal with quantifiers in a much more disciplined way. Of course, you lose full automation, but most of these tools can use an SMT solver to discharge subgoals that are "easy" enough. That way, you still do the "heavy-lifting" manually, but most subgoals are automatically handled by z3. (Especially in the case of Lean, see here: https://leanprover.github.io/)
There's one extra closing (right) parentheses, which needs to be removed. Also, add assert before the forall statement.
(assert ( forall ( (y (Array Int Int) ) )
(= (select y 1) 0)
))
(check-sat)
Run the above code and you should get unsat as the answer.
For the second program, alias' answer may be useful to you.

Horst (pD*) compared to OWL2-RL

We are using GraphDB 8.4.0 as a triple store for a large data integration project. We want to make use of the reasoning capabilities, and are trying to decide between using HORST (pD*) and OWL2-RL.
However, the literature describing these is quite dense. I think I understand that OWL2-RL is more "powerful", but I am unsure how so. Can anyone provide some examples of the differences between the two reasoners? What kinds of statements are inferred by OWL2-RL, but not HORST (and vice versa)?
Brill, inside there GraphDB there is a single rule engine, which supports different reasoning profiles, depending on the rule-set which was selected. The predefined rule-sets are part of the distribution - look at the PIE files in folder configs/rules. One can also take one of the existing profiles and tailor it to her needs (e.g. remove a rule, which is not necessary).
The fundamental difference between OWL2 RL and what we call OWL-Horst (pD*) is that OWL2RL pushes the limits of which OWL constructs can be supported using this type of entailment rules. OWL Horst is limited to RDFS (subClassOf, subSpropertyOf, domain and range) plus what was popular in the past as OWL Lite: sameAs, equivalentClass, equivalentProperty, SymmetricProperty, TransitiveProperty, inverseOf, FunctionalProperty, InverseFunctionalProperty. There is also partial support for: intersectionOf, someValuesFrom, hasValue, allValuesFrom.
What OWL 2 RL adds on top is support for AsymmetricProperty, IrreflexiveProperty, propertyChainAxiom, AllDisjointProperties, hasKey, unionOf, complementOf, oneOf, differentFrom, AllDisjointClasses and all the property cardinality primitives. It also adds more complete support for intersectionOf, someValuesFrom, hasValue, allValuesFrom. Be aware that there are limitations to the inference supported by OWL 2 RL for some of these properties, e.g. what type of inferences should or should not be done for specific class expressions (OWL restrictions). If you chose OWL 2 RL, check Tables 5-8 in the spec, https://www.w3.org/TR/owl2-profiles/#OWL_2_RL. GraphDB's owl-2-rl data set is fully compliant with it. GraphDB is the only major triplestore with full OWL 2 RL compliance - see the this table (https://www.w3.org/2001/sw/wiki/OWL/Implementations) it appears with its former name OWLIM.
My suggestion would be to go with OWL Horst for a large dataset, as reasoning with OWL 2 RL could be much slower. It depends on your ontology and data patterns, but as a rule of thumb you can expect loading/updates to be 2 times slower with OWL 2 RL, even if you don't use extensively its "expensive" primitives (e.g. property chains). See the difference between loading speeds with RDFS+ and OWL 2 RL benchmarked here: http://graphdb.ontotext.com/documentation/standard/benchmark.html
Finally, I would recommend you to use the "optimized" versions of the pre-defined rule-sets. These versions exclude some RDFS reasoning rules, which are not useful for most of the applications, but add substantial reasoning overheads, e.g. the one that infers that the subject, the predicate and the object of a statement are instances of rdfs:Resource
Id: rdf1_rdfs4a_4b
x a y
-------------------------------
x <rdf:type> <rdfs:Resource>
a <rdf:type> <rdfs:Resource>
y <rdf:type> <rdfs:Resource>
If you want to stay 100% compliant with the W3C spec, you should stay with the non-optimized versions.
If you need further assistance, please, write to support#ontotext.com
In addition to what Atanas (our CEO) wrote and your excellent example, http://graphdb.ontotext.com/documentation/enterprise/rules-optimisations.html provides some ideas how to optimize your rulesets to make them faster.
Two of the ideas are:
ptop:transitiveOver is faster than owl:TransitiveProperty: quadratic vs cubic complexity over the length of transitive chains
ptop:PropChain (a 2-place chain) is faster than general owl:propertyChainAxiom (n-place chain) because it doesn't need to unroll the rdf:List underlying the representation of owl:propertyChainAxiom.
Under some conditions you can translate the standard OWL constructs to these custom constructs, to have both standards compliance and faster speed:
use rule TransitiveUsingStep; if every TransitiveProperty p (eg skos:broaderTransitive) is defined over a step property s (eg skos:broader) and you don't insert p directly
if you use only 2-step owl:propertyChainAxiom then translate them to custom using the following rule, and infer using rule ptop_PropChain:
Id: ptop_PropChain_from_propertyChainAxiom
q <owl:propertyChainAxiom> l1
l1 <rdf:first> p1
l1 <rdf:rest> l2
l2 <rdf:first> p2
l2 <rdf:rest> <rdf:nil>
----------------------
t <ptop:premise1> p1
t <ptop:premise2> p2
t <ptop:conclusion> q
t <rdf:type> <ptop:PropChain>
http://rawgit2.com/VladimirAlexiev/my/master/pubs/extending-owl2/index.html describes further ideas for extended property constructs, and has illustrations.
Let us know if we can help further.
After thinking this for bit, I came up with a concrete example. The Oral Health and Disease Ontology (http://purl.obolibrary.org/obo/ohd.owl) contains three interrelated entities:
a restored tooth
a restored tooth surface that is part of the restored tooth
a tooth restoration procedure that creates the restored tooth surface (e.g., when you have a filling placed in your tooth)
The axioms that define these entities are (using pseudo Manchester syntax):
restored tooth equivalent to Tooth and has part some dental restoration material
restored tooth surface subclass of part of restored tooth
filling procedure has specified output some restored tooth surface
The has specified output relation is a subproperty of the has participant relation, and the has participant relation contains the property chain:
has_specified_input o 'is part of'
The reason for this property chain is for reasoner to infer that if a tooth surface participates in a procedure, then the whole tooth that the surface is part of participates in the procedure, and, furthermore, the patient that the tooth is part of also participates in the procedure (due to the transitivity of part of).
As a concrete example, let define some individuals (using pseudo rdf):
:patient#1 a :patient .
:tooth#1 a :tooth; :part-of :patient#1
:restored-occlusal#1 a :restored-occlusal-surface; :part-of tooth#1 .
:procedure#1 :has-specified-output :restored-occlusal#1 .
Suppose you want to query for all restored teeth:
select ?tooth where {?tooth a :restored-tooth}
RDFS-Plus reasoning will not find any restored teeth b/c it doesn't reason over equivalent classes. But, OWL-Horst and OWL2-RL will find such teeth.
Now, suppose you want to find all patients that underwent (i.e. participated in) a tooth restoration procedure:
select ?patient where {
?patient a patient: .
?proc a tooth_restoration_procedure:; has_participant: ?patient .
}
Again, RDFS-Plus will not find any patients, and neither will OWL-Horst b/c this inference requires reasoning over the has participant property chain. OWL2-RL is needed in order to make this inference.
I hope this example is helpful for the interested reader :).
I welcome comments to improve the example. Please keep any comments within the scope of trying to make the example clearer. Its purpose is to give insight into what these different levels of reasoning do and not to give advice about which reasoner is most appropriate.

OWLAPI : Performance impact while dealing with update/delete of axioms

I want to update/delete the axioms from a OWL Class (e.g SubclassOf axioms).
I have following two approaches :
1) Delete all old axioms then create all new axioms.
2) Delete selective axioms by comparing it with new axioms.
Note :- Due to some limitations I have to treat update cases as delete + create
Q. Which is the best strategy to go aheas in terms of performance for OWLAPI ?
E.g.
I have following SubclassOF axioms for Class X -
1) A or B
2) name exactly 1 xsd:string
3) P and not Q
and I want to update/delete these axioms with -
1) A [Update]
2) name min 1 xsd:string [Update]
3) Axiom is deleted [Delete]
The performance of axiom removals is equivalent to axiomatization additions. The main actions are searches through maps to find existing elements or add new ones.
The structures involved are O(Constant) for the input, so the total complexity is mostly independent of the ontology size (this might not hold true for very large ontologies, but it's accurate for most ontologies).
In short there is no performance issue with your proposed solution (2).
I would not suggest recreating axioms - this is likely to be expensive in terms of memory use. Axioms are immutable, so the new and old objects behave exactly the same.

What is supported in First Order Logics which is not supported in Description Logic?

While studying description logics (DL), it is very common to read that it is a fragment of first order logics (FOL), but it is hard to read something explicitely on what is excluded from DL which is part of FOL, which makes DL (with all its dialects ALC, SHOIN etc...) decidable.
Or in another words, could you provide me some examples in FOL which are not expressible
through DL (and which are the reason for semi/non-decidability in FOL) ?
The following facts about description logics are closely related to decidability:
(a form of) tree-model property — this property is important for tableu methods;
embeddability into multimodal systems — which are known to be "robustly decidable";
embeddability into the so-called guarded fragments of FOL — see below;
embeddability into two-variables FOL fragments — which are decidable;
locality — see below.
Some of these facts are syntactical, while some are semantical. Here below are two interesting, decidability-related, and more or less syntactical characteristics of description logics:
Locality (from The Description Logic Handbook, 2nd edition, section 3.6):
One of the main reasons why satisfiability and subsumption in many Description Logics are decidable – although highly complex – is that
most of the concept constructors can express only local properties
about an element 〈...〉 Intuitively, this implies that
a constraint regarding x will not “talk about” elements which are
arbitrarily far (w.r.t. role links) from x. This also means that in
ALC, and in many Description Logics, an assertion on an individual
cannot state properties about a whole structure satisfying it.
However, not every Description Logic satisfies locality.
Guarded fragment (from The Description Logic Handbook, 2nd edition, section 4.2.3)
Guarded fragments are obtained from first-order logic by allowing the
use of quantified variables only if these variables are guarded by
appropriate atoms before they are used in the body of a formula.
More precisely, quantifiers are restricted to appear only in the form
     ∃y(P(x,y) ∧ Φ(y))
        or      ∀y(P(x,y) ⊃ Φ(y))
              (First Guarded Fragment)
     ∃y(P(x,y) ∧ Φ(x,y))
     or      ∀y(P(x,y) ⊃ Φ(x,y))
           (Guarded Fragment)
for atoms P, vectors of variables x and y and (first) guarded fragment
formulae Φ with free variables in y and x (resp. in y).
From these points of view, analyze the examples from #JoshuaTaylor's comments:
∀x.(C(X) ↔ ∃y.(likes(x,y) ∧ ∃z.(likes(y,z) ∧ likes(z,x))))
∀x.(C(x) ↔ ∃z.(favoriteTeacher(x,z) ∧ firstGradeTeacherOf(x,z)))
The reasons why DL is preferred to FOL for knowledge representation are not only decidability or computational complexity related. Look at the slide called "FOL as Semantic Web Language?" in this lecture.
As shown by Turing and Church, FOL is undecidable, because there is no algorithm for deciding if a FOL formula is valid. Many description logics are decidable fragments of first-order logic, however, some description logics have more features than FOL, and many spatial, temporal, and fuzzy description logics are undecidable as well.

Logic programming with integer or even floating point domains

I am reading a lot about logic programming - ASP (Answer Set Programming) is one example or this. They (logic programs) are usually in the form:
[Program 1]
Rule1: a <- a1, a2, ..., not am, am+1;
Rule2: ...
This set of rules is called the logic program and the s.c. model is the result of such computation - some kind of assignment of True/False values to each of a1, a2, ...
There is lot of research going on - e.g. how such kind of programs (rules) can be integrated with the (semantic web) ontologies to build knowledge bases that contain both - rules and ontologies (some kind of constraints/behaviour and data); there is lot of research about ASP itself - like parallel extensions, extensions for probabilistic logic, for temporal logic and so on.
My question is - is there some kind of research and maybe some proof-of-concept projects where this analysis is extended from Boolean variables to variables with integer and maybe even float domains? Currently I have not found any research that could address the following programs:
[Program 2]
Rule1 a1:=5 <- a2=5, a3=7, a4<8, ...
Rule2 ...
...
[the final assignment of values to a1, a2, etc., is the solution of this program]
Currently - as I understand - if one could like to perform some kind of analysis on Program-2 (e.g. to find if this program is correct in some sense - e.g. if it satisfies some properties, if it terminates, what domains are allowed not to violate some kind of properties and so on), then he or she must restate Program-2 in terms of Program-1 and then proceed in way which seems to be completely unexplored - to my knowledge (and I don't believe that is it unexplored, simply - I don't know some sources or trend). There is constraint logic programming that allow the use of statements with inequalities in Program-1, but it is too focused on Boolean variables as well. Actually - Programm-2 is of kind that can be fairly common in business rules systems, that was the cause of my interest in logic programming.
SO - my question has some history - my practical experience has led me to appreciate business rules systems/engines, especially - JBoss project Drools and it was my intention to do some kind of research of theory underlying s.c. production rules systems (I was and I am planning to do my thesis about them - if I would spot what can be done here), but I can say that there is little to do - after going over the literature (e.g. http://www.computer.org/csdl/trans/tk/2010/11/index.html was excellent IEEE TKDE special issues with some articles about them, one of them was writter by Drools leader) one can see that there is some kind of technical improvements of the decades old Rete algorithm but there is no theory of Drools or other production rule systems that could help with to do some formal analysis about them. So - the other question is - is there theory of production rule systems (for rule engines like Drools, Jess, CLIPS and so on) and is there practical need for such theory and what are the practical issues of using Drools and other systems that can be addressed by the theory of production rule systems.
p.s. I know - all these are questions that should be directed to thesis advisor, but my current position is that there is no (up to my knowledge) person in department where I am enrolled with who could fit to answer them, so - I am reading journals and also conference proceedings (there are nice conference series series of Lecture Notes in Computer Science - RuleML and RR)...
Thanks for any hint in advance!
In a sense the boolean systems already do what you suggest.
to ensure A=5 is part of your solution, consider the rules (I forget my ASP syntax so bear with me)
integer 1..100 //integers 1 to 100 exist
1{A(X) : integer(X)}1 //there is one A(X) that is true, where X is an integer
A(5) //A(5) is true
and I think your clause would require:
integer 1..100 //integers 1 to 100 exist
1{A(X) : integer(X)}1 //A1 can take only one value and must take a value
1{B(X) : integer(X)}1 //A2 ``
1{C(X) : integer(X)}1 //A3 ``
1{D(X) : integer(X)}1 //A4 ``
A(5) :- B(5), C(7), D(8) //A2=5, A3=7, A4=8 ==> A1=5
I hope I've understood the question correctly.
Recent versions of Clojure core.logic (since 0.8) include exactly this kind of support, based on cKanren
See an example here: https://gist.github.com/4229449

Resources